// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright IBM Corporation, 2018
 * Authors Suraj Jitindar Singh <sjitindarsingh@gmail.com>
 *	   Paul Mackerras <paulus@ozlabs.org>
 *
 * Description: KVM functions specific to running nested KVM-HV guests
 * on Book3S processors (specifically POWER9 and later).
 */

#include <linux/kernel.h>
#include <linux/kvm_host.h>
#include <linux/llist.h>
#include <linux/pgtable.h>

#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
#include <asm/mmu.h>
#include <asm/pgalloc.h>
#include <asm/pte-walk.h>
#include <asm/reg.h>
#include <asm/plpar_wrappers.h>
#include <asm/firmware.h>

static struct patb_entry *pseries_partition_tb;

static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp);
static void kvmhv_free_memslot_nest_rmap(struct kvm_memory_slot *free);

void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	hr->pcr = vc->pcr | PCR_MASK;
	hr->dpdes = vc->dpdes;
	hr->hfscr = vcpu->arch.hfscr;
	hr->tb_offset = vc->tb_offset;
	hr->dawr0 = vcpu->arch.dawr0;
	hr->dawrx0 = vcpu->arch.dawrx0;
	hr->ciabr = vcpu->arch.ciabr;
	hr->purr = vcpu->arch.purr;
	hr->spurr = vcpu->arch.spurr;
	hr->ic = vcpu->arch.ic;
	hr->vtb = vc->vtb;
	hr->srr0 = vcpu->arch.shregs.srr0;
	hr->srr1 = vcpu->arch.shregs.srr1;
	hr->sprg[0] = vcpu->arch.shregs.sprg0;
	hr->sprg[1] = vcpu->arch.shregs.sprg1;
	hr->sprg[2] = vcpu->arch.shregs.sprg2;
	hr->sprg[3] = vcpu->arch.shregs.sprg3;
	hr->pidr = vcpu->arch.pid;
	hr->cfar = vcpu->arch.cfar;
	hr->ppr = vcpu->arch.ppr;
	hr->dawr1 = vcpu->arch.dawr1;
	hr->dawrx1 = vcpu->arch.dawrx1;
}

/* Use noinline_for_stack due to https://bugs.llvm.org/show_bug.cgi?id=49610 */
static noinline_for_stack void byteswap_pt_regs(struct pt_regs *regs)
{
	unsigned long *addr = (unsigned long *) regs;

	for (; addr < ((unsigned long *) (regs + 1)); addr++)
		*addr = swab64(*addr);
}

static void byteswap_hv_regs(struct hv_guest_state *hr)
{
	hr->version = swab64(hr->version);
	hr->lpid = swab32(hr->lpid);
	hr->vcpu_token = swab32(hr->vcpu_token);
	hr->lpcr = swab64(hr->lpcr);
	hr->pcr = swab64(hr->pcr) | PCR_MASK;
	hr->amor = swab64(hr->amor);
	hr->dpdes = swab64(hr->dpdes);
	hr->hfscr = swab64(hr->hfscr);
	hr->tb_offset = swab64(hr->tb_offset);
	hr->dawr0 = swab64(hr->dawr0);
	hr->dawrx0 = swab64(hr->dawrx0);
	hr->ciabr = swab64(hr->ciabr);
	hr->hdec_expiry = swab64(hr->hdec_expiry);
	hr->purr = swab64(hr->purr);
	hr->spurr = swab64(hr->spurr);
	hr->ic = swab64(hr->ic);
	hr->vtb = swab64(hr->vtb);
	hr->hdar = swab64(hr->hdar);
	hr->hdsisr = swab64(hr->hdsisr);
	hr->heir = swab64(hr->heir);
	hr->asdr = swab64(hr->asdr);
	hr->srr0 = swab64(hr->srr0);
	hr->srr1 = swab64(hr->srr1);
	hr->sprg[0] = swab64(hr->sprg[0]);
	hr->sprg[1] = swab64(hr->sprg[1]);
	hr->sprg[2] = swab64(hr->sprg[2]);
	hr->sprg[3] = swab64(hr->sprg[3]);
	hr->pidr = swab64(hr->pidr);
	hr->cfar = swab64(hr->cfar);
	hr->ppr = swab64(hr->ppr);
	hr->dawr1 = swab64(hr->dawr1);
	hr->dawrx1 = swab64(hr->dawrx1);
}

static void save_hv_return_state(struct kvm_vcpu *vcpu,
				 struct hv_guest_state *hr)
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	hr->dpdes = vc->dpdes;
	hr->purr = vcpu->arch.purr;
	hr->spurr = vcpu->arch.spurr;
	hr->ic = vcpu->arch.ic;
	hr->vtb = vc->vtb;
	hr->srr0 = vcpu->arch.shregs.srr0;
	hr->srr1 = vcpu->arch.shregs.srr1;
	hr->sprg[0] = vcpu->arch.shregs.sprg0;
	hr->sprg[1] = vcpu->arch.shregs.sprg1;
	hr->sprg[2] = vcpu->arch.shregs.sprg2;
	hr->sprg[3] = vcpu->arch.shregs.sprg3;
	hr->pidr = vcpu->arch.pid;
	hr->cfar = vcpu->arch.cfar;
	hr->ppr = vcpu->arch.ppr;
	switch (vcpu->arch.trap) {
	case BOOK3S_INTERRUPT_H_DATA_STORAGE:
		hr->hdar = vcpu->arch.fault_dar;
		hr->hdsisr = vcpu->arch.fault_dsisr;
		hr->asdr = vcpu->arch.fault_gpa;
		break;
	case BOOK3S_INTERRUPT_H_INST_STORAGE:
		hr->asdr = vcpu->arch.fault_gpa;
		break;
	case BOOK3S_INTERRUPT_H_FAC_UNAVAIL:
		hr->hfscr = ((~HFSCR_INTR_CAUSE & hr->hfscr) |
			     (HFSCR_INTR_CAUSE & vcpu->arch.hfscr));
		break;
	case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
		hr->heir = vcpu->arch.emul_inst;
		break;
	}
}

static void restore_hv_regs(struct kvm_vcpu *vcpu, const struct hv_guest_state *hr)
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	vc->pcr = hr->pcr | PCR_MASK;
	vc->dpdes = hr->dpdes;
	vcpu->arch.hfscr = hr->hfscr;
	vcpu->arch.dawr0 = hr->dawr0;
	vcpu->arch.dawrx0 = hr->dawrx0;
	vcpu->arch.ciabr = hr->ciabr;
	vcpu->arch.purr = hr->purr;
	vcpu->arch.spurr = hr->spurr;
	vcpu->arch.ic = hr->ic;
	vc->vtb = hr->vtb;
	vcpu->arch.shregs.srr0 = hr->srr0;
	vcpu->arch.shregs.srr1 = hr->srr1;
	vcpu->arch.shregs.sprg0 = hr->sprg[0];
	vcpu->arch.shregs.sprg1 = hr->sprg[1];
	vcpu->arch.shregs.sprg2 = hr->sprg[2];
	vcpu->arch.shregs.sprg3 = hr->sprg[3];
	vcpu->arch.pid = hr->pidr;
	vcpu->arch.cfar = hr->cfar;
	vcpu->arch.ppr = hr->ppr;
	vcpu->arch.dawr1 = hr->dawr1;
	vcpu->arch.dawrx1 = hr->dawrx1;
}

void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu,
				   struct hv_guest_state *hr)
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;

	vc->dpdes = hr->dpdes;
	vcpu->arch.hfscr = hr->hfscr;
	vcpu->arch.purr = hr->purr;
	vcpu->arch.spurr = hr->spurr;
	vcpu->arch.ic = hr->ic;
	vc->vtb = hr->vtb;
	vcpu->arch.fault_dar = hr->hdar;
	vcpu->arch.fault_dsisr = hr->hdsisr;
	vcpu->arch.fault_gpa = hr->asdr;
	vcpu->arch.emul_inst = hr->heir;
	vcpu->arch.shregs.srr0 = hr->srr0;
	vcpu->arch.shregs.srr1 = hr->srr1;
	vcpu->arch.shregs.sprg0 = hr->sprg[0];
	vcpu->arch.shregs.sprg1 = hr->sprg[1];
	vcpu->arch.shregs.sprg2 = hr->sprg[2];
	vcpu->arch.shregs.sprg3 = hr->sprg[3];
	vcpu->arch.pid = hr->pidr;
	vcpu->arch.cfar = hr->cfar;
	vcpu->arch.ppr = hr->ppr;
}

static void kvmhv_nested_mmio_needed(struct kvm_vcpu *vcpu, u64 regs_ptr)
{
	/* No need to reflect the page fault to L1, we've handled it */
	vcpu->arch.trap = 0;

	/*
	 * Since the L2 gprs have already been written back into L1 memory when
	 * we complete the mmio, store the L1 memory location of the L2 gpr
	 * being loaded into by the mmio so that the loaded value can be
	 * written there in kvmppc_complete_mmio_load()
	 */
	if (((vcpu->arch.io_gpr & KVM_MMIO_REG_EXT_MASK) == KVM_MMIO_REG_GPR)
	    && (vcpu->mmio_is_write == 0)) {
		vcpu->arch.nested_io_gpr = (gpa_t) regs_ptr +
					   offsetof(struct pt_regs,
						    gpr[vcpu->arch.io_gpr]);
		vcpu->arch.io_gpr = KVM_MMIO_REG_NESTED_GPR;
	}
}

static int kvmhv_read_guest_state_and_regs(struct kvm_vcpu *vcpu,
					   struct hv_guest_state *l2_hv,
					   struct pt_regs *l2_regs,
					   u64 hv_ptr, u64 regs_ptr)
{
	int size;

	if (kvm_vcpu_read_guest(vcpu, hv_ptr, &l2_hv->version,
				sizeof(l2_hv->version)))
		return -1;

	if (kvmppc_need_byteswap(vcpu))
		l2_hv->version = swab64(l2_hv->version);

	size = hv_guest_state_size(l2_hv->version);
	if (size < 0)
		return -1;

	return kvm_vcpu_read_guest(vcpu, hv_ptr, l2_hv, size) ||
		kvm_vcpu_read_guest(vcpu, regs_ptr, l2_regs,
				    sizeof(struct pt_regs));
}

static int kvmhv_write_guest_state_and_regs(struct kvm_vcpu *vcpu,
					    struct hv_guest_state *l2_hv,
					    struct pt_regs *l2_regs,
					    u64 hv_ptr, u64 regs_ptr)
{
	int size;

	size = hv_guest_state_size(l2_hv->version);
	if (size < 0)
		return -1;

	return kvm_vcpu_write_guest(vcpu, hv_ptr, l2_hv, size) ||
		kvm_vcpu_write_guest(vcpu, regs_ptr, l2_regs,
				     sizeof(struct pt_regs));
}

static void load_l2_hv_regs(struct kvm_vcpu *vcpu,
			    const struct hv_guest_state *l2_hv,
			    const struct hv_guest_state *l1_hv, u64 *lpcr)
{
	struct kvmppc_vcore *vc = vcpu->arch.vcore;
	u64 mask;

	restore_hv_regs(vcpu, l2_hv);

	/*
	 * Don't let L1 change LPCR bits for the L2 except these:
	 */
	mask = LPCR_DPFD | LPCR_ILE | LPCR_TC | LPCR_AIL | LPCR_LD | LPCR_MER;

	/*
	 * Additional filtering is required depending on hardware
	 * and configuration.
	 */
	*lpcr = kvmppc_filter_lpcr_hv(vcpu->kvm,
				      (vc->lpcr & ~mask) | (*lpcr & mask));

	/*
	 * Don't let L1 enable features for L2 which we don't allow for L1,
	 * but preserve the interrupt cause field.
	 */
	vcpu->arch.hfscr = l2_hv->hfscr & (HFSCR_INTR_CAUSE | vcpu->arch.hfscr_permitted);

	/* Don't let data address watchpoint match in hypervisor state */
	vcpu->arch.dawrx0 = l2_hv->dawrx0 & ~DAWRX_HYP;
	vcpu->arch.dawrx1 = l2_hv->dawrx1 & ~DAWRX_HYP;

	/* Don't let completed instruction address breakpt match in HV state */
	if ((l2_hv->ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER)
		vcpu->arch.ciabr = l2_hv->ciabr & ~CIABR_PRIV;
}

long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu)
{
	long int err, r;
	struct kvm_nested_guest *l2;
	struct pt_regs l2_regs, saved_l1_regs;
	struct hv_guest_state l2_hv = {0}, saved_l1_hv;
	struct kvmppc_vcore *vc = vcpu->arch.vcore;
	u64 hv_ptr, regs_ptr;
	u64 hdec_exp, lpcr;
	s64 delta_purr, delta_spurr, delta_ic, delta_vtb;

	if (vcpu->kvm->arch.l1_ptcr == 0)
		return H_NOT_AVAILABLE;

	if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr))
		return H_BAD_MODE;

	/* copy parameters in */
	hv_ptr = kvmppc_get_gpr(vcpu, 4);
	regs_ptr = kvmppc_get_gpr(vcpu, 5);
	kvm_vcpu_srcu_read_lock(vcpu);
	err = kvmhv_read_guest_state_and_regs(vcpu, &l2_hv, &l2_regs,
					      hv_ptr, regs_ptr);
	kvm_vcpu_srcu_read_unlock(vcpu);
	if (err)
		return H_PARAMETER;

	if (kvmppc_need_byteswap(vcpu))
		byteswap_hv_regs(&l2_hv);
	if (l2_hv.version > HV_GUEST_STATE_VERSION)
		return H_P2;

	if (kvmppc_need_byteswap(vcpu))
		byteswap_pt_regs(&l2_regs);
	if (l2_hv.vcpu_token >= NR_CPUS)
		return H_PARAMETER;

	/*
	 * L1 must have set up a suspended state to enter the L2 in a
	 * transactional state, and only in that case. These have to be
	 * filtered out here to prevent causing a TM Bad Thing in the
	 * host HRFID. We could synthesize a TM Bad Thing back to the L1
	 * here but there doesn't seem like much point.
	 */
	if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr)) {
		if (!MSR_TM_ACTIVE(l2_regs.msr))
			return H_BAD_MODE;
	} else {
		if (l2_regs.msr & MSR_TS_MASK)
			return H_BAD_MODE;
		if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_TS_MASK))
			return H_BAD_MODE;
	}

	/* translate lpid */
	l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true);
	if (!l2)
		return H_PARAMETER;
	if (!l2->l1_gr_to_hr) {
		mutex_lock(&l2->tlb_lock);
		kvmhv_update_ptbl_cache(l2);
		mutex_unlock(&l2->tlb_lock);
	}

	/* save l1 values of things */
	vcpu->arch.regs.msr = vcpu->arch.shregs.msr;
	saved_l1_regs = vcpu->arch.regs;
	kvmhv_save_hv_regs(vcpu, &saved_l1_hv);

	/* convert TB values/offsets to host (L0) values */
	hdec_exp = l2_hv.hdec_expiry - vc->tb_offset;
	vc->tb_offset += l2_hv.tb_offset;
	vcpu->arch.dec_expires += l2_hv.tb_offset;

	/* set L1 state to L2 state */
	vcpu->arch.nested = l2;
	vcpu->arch.nested_vcpu_id = l2_hv.vcpu_token;
	vcpu->arch.nested_hfscr = l2_hv.hfscr;
	vcpu->arch.regs = l2_regs;

	/* Guest must always run with ME enabled, HV disabled. */
	vcpu->arch.shregs.msr = (vcpu->arch.regs.msr | MSR_ME) & ~MSR_HV;

	lpcr = l2_hv.lpcr;
	load_l2_hv_regs(vcpu, &l2_hv, &saved_l1_hv, &lpcr);

	vcpu->arch.ret = RESUME_GUEST;
	vcpu->arch.trap = 0;
	do {
		r = kvmhv_run_single_vcpu(vcpu, hdec_exp, lpcr);
	} while (is_kvmppc_resume_guest(r));

	/* save L2 state for return */
	l2_regs = vcpu->arch.regs;
	l2_regs.msr = vcpu->arch.shregs.msr;
	delta_purr = vcpu->arch.purr - l2_hv.purr;
	delta_spurr = vcpu->arch.spurr - l2_hv.spurr;
	delta_ic = vcpu->arch.ic - l2_hv.ic;
	delta_vtb = vc->vtb - l2_hv.vtb;
	save_hv_return_state(vcpu, &l2_hv);

	/* restore L1 state */
	vcpu->arch.nested = NULL;
	vcpu->arch.regs = saved_l1_regs;
	vcpu->arch.shregs.msr = saved_l1_regs.msr & ~MSR_TS_MASK;
	/* set L1 MSR TS field according to L2 transaction state */
	if (l2_regs.msr & MSR_TS_MASK)
		vcpu->arch.shregs.msr |= MSR_TS_S;
	vc->tb_offset = saved_l1_hv.tb_offset;
	/* XXX: is this always the same delta as saved_l1_hv.tb_offset? */
	vcpu->arch.dec_expires -= l2_hv.tb_offset;
	restore_hv_regs(vcpu, &saved_l1_hv);
	vcpu->arch.purr += delta_purr;
	vcpu->arch.spurr += delta_spurr;
	vcpu->arch.ic += delta_ic;
	vc->vtb += delta_vtb;

	kvmhv_put_nested(l2);

	/* copy l2_hv_state and regs back to guest */
	if (kvmppc_need_byteswap(vcpu)) {
		byteswap_hv_regs(&l2_hv);
		byteswap_pt_regs(&l2_regs);
	}
	kvm_vcpu_srcu_read_lock(vcpu);
	err = kvmhv_write_guest_state_and_regs(vcpu, &l2_hv, &l2_regs,
					       hv_ptr, regs_ptr);
	kvm_vcpu_srcu_read_unlock(vcpu);
	if (err)
		return H_AUTHORITY;

	if (r == -EINTR)
		return H_INTERRUPT;

	if (vcpu->mmio_needed) {
		kvmhv_nested_mmio_needed(vcpu, regs_ptr);
		return H_TOO_HARD;
	}

	return vcpu->arch.trap;
}

unsigned long nested_capabilities;

long kvmhv_nested_init(void)
{
	long int ptb_order;
	unsigned long ptcr, host_capabilities;
	long rc;

	if (!kvmhv_on_pseries())
		return 0;
	if (!radix_enabled())
		return -ENODEV;

	rc = plpar_guest_get_capabilities(0, &host_capabilities);
	if (rc == H_SUCCESS) {
		unsigned long capabilities = 0;

		if (cpu_has_feature(CPU_FTR_ARCH_31))
			capabilities |= H_GUEST_CAP_POWER10;
		if (cpu_has_feature(CPU_FTR_ARCH_300))
			capabilities |= H_GUEST_CAP_POWER9;

		nested_capabilities = capabilities & host_capabilities;
		rc = plpar_guest_set_capabilities(0, nested_capabilities);
		if (rc != H_SUCCESS) {
			pr_err("kvm-hv: Could not configure parent hypervisor capabilities (rc=%ld)",
			       rc);
			return -ENODEV;
		}

		static_branch_enable(&__kvmhv_is_nestedv2);
		return 0;
	}

	pr_info("kvm-hv: nestedv2 get capabilities hcall failed, falling back to nestedv1 (rc=%ld)\n",
		rc);
	/* Partition table entry is 1<<4 bytes in size, hence the 4. */
	ptb_order = KVM_MAX_NESTED_GUESTS_SHIFT + 4;
	/* Minimum partition table size is 1<<12 bytes */
	if (ptb_order < 12)
		ptb_order = 12;
	pseries_partition_tb = kmalloc(sizeof(struct patb_entry) << ptb_order,
				       GFP_KERNEL);
	if (!pseries_partition_tb) {
		pr_err("kvm-hv: failed to allocated nested partition table\n");
		return -ENOMEM;
	}

	ptcr = __pa(pseries_partition_tb) | (ptb_order - 12);
	rc = plpar_hcall_norets(H_SET_PARTITION_TABLE, ptcr);
	if (rc != H_SUCCESS) {
		pr_err("kvm-hv: Parent hypervisor does not support nesting (rc=%ld)\n",
		       rc);
		kfree(pseries_partition_tb);
		pseries_partition_tb = NULL;
		return -ENODEV;
	}

	return 0;
}

void kvmhv_nested_exit(void)
{
	/*
	 * N.B. the kvmhv_on_pseries() test is there because it enables
	 * the compiler to remove the call to plpar_hcall_norets()
	 * when CONFIG_PPC_PSERIES=n.
	 */
	if (kvmhv_on_pseries() && pseries_partition_tb) {
		plpar_hcall_norets(H_SET_PARTITION_TABLE, 0);
		kfree(pseries_partition_tb);
		pseries_partition_tb = NULL;
	}
}

static void kvmhv_flush_lpid(u64 lpid)
{
	long rc;

	if (!kvmhv_on_pseries()) {
		radix__flush_all_lpid(lpid);
		return;
	}

	if (!firmware_has_feature(FW_FEATURE_RPT_INVALIDATE))
		rc = plpar_hcall_norets(H_TLB_INVALIDATE, H_TLBIE_P1_ENC(2, 0, 1),
					lpid, TLBIEL_INVAL_SET_LPID);
	else
		rc = pseries_rpt_invalidate(lpid, H_RPTI_TARGET_CMMU,
					    H_RPTI_TYPE_NESTED |
					    H_RPTI_TYPE_TLB | H_RPTI_TYPE_PWC |
					    H_RPTI_TYPE_PAT,
					    H_RPTI_PAGE_ALL, 0, -1UL);
	if (rc)
		pr_err("KVM: TLB LPID invalidation hcall failed, rc=%ld\n", rc);
}

void kvmhv_set_ptbl_entry(u64 lpid, u64 dw0, u64 dw1)
{
	if (!kvmhv_on_pseries()) {
		mmu_partition_table_set_entry(lpid, dw0, dw1, true);
		return;
	}

	if (kvmhv_is_nestedv1()) {
		pseries_partition_tb[lpid].patb0 = cpu_to_be64(dw0);
		pseries_partition_tb[lpid].patb1 = cpu_to_be64(dw1);
		/* L0 will do the necessary barriers */
		kvmhv_flush_lpid(lpid);
	}

	if (kvmhv_is_nestedv2())
		kvmhv_nestedv2_set_ptbl_entry(lpid, dw0, dw1);
}

static void kvmhv_set_nested_ptbl(struct kvm_nested_guest *gp)
{
	unsigned long dw0;

	dw0 = PATB_HR | radix__get_tree_size() |
		__pa(gp->shadow_pgtable) | RADIX_PGD_INDEX_SIZE;
	kvmhv_set_ptbl_entry(gp->shadow_lpid, dw0, gp->process_table);
}

/*
 * Handle the H_SET_PARTITION_TABLE hcall.
 * r4 = guest real address of partition table + log_2(size) - 12
 * (formatted as for the PTCR).
 */
long kvmhv_set_partition_table(struct kvm_vcpu *vcpu)
{
	struct kvm *kvm = vcpu->kvm;
	unsigned long ptcr = kvmppc_get_gpr(vcpu, 4);
	int srcu_idx;
	long ret = H_SUCCESS;

	srcu_idx = srcu_read_lock(&kvm->srcu);
	/* Check partition size and base address. */
	if ((ptcr & PRTS_MASK) + 12 - 4 > KVM_MAX_NESTED_GUESTS_SHIFT ||
	    !kvm_is_visible_gfn(vcpu->kvm, (ptcr & PRTB_MASK) >> PAGE_SHIFT))
		ret = H_PARAMETER;
	srcu_read_unlock(&kvm->srcu, srcu_idx);
	if (ret == H_SUCCESS)
		kvm->arch.l1_ptcr = ptcr;

	return ret;
}

/*
 * Handle the H_COPY_TOFROM_GUEST hcall.
 * r4 = L1 lpid of nested guest
 * r5 = pid
 * r6 = eaddr to access
 * r7 = to buffer (L1 gpa)
 * r8 = from buffer (L1 gpa)
 * r9 = n bytes to copy
 */
long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu)
{
	struct kvm_nested_guest *gp;
	int l1_lpid = kvmppc_get_gpr(vcpu, 4);
	int pid = kvmppc_get_gpr(vcpu, 5);
	gva_t eaddr = kvmppc_get_gpr(vcpu, 6);
	gpa_t gp_to = (gpa_t) kvmppc_get_gpr(vcpu, 7);
	gpa_t gp_from = (gpa_t) kvmppc_get_gpr(vcpu, 8);
	void *buf;
	unsigned long n = kvmppc_get_gpr(vcpu, 9);
	bool is_load = !!gp_to;
	long rc;

	if (gp_to && gp_from) /* One must be NULL to determine the direction */
		return H_PARAMETER;

	if (eaddr & (0xFFFUL << 52))
		return H_PARAMETER;

	buf = kzalloc(n, GFP_KERNEL | __GFP_NOWARN);
	if (!buf)
		return H_NO_MEM;

	gp = kvmhv_get_nested(vcpu->kvm, l1_lpid, false);
	if (!gp) {
		rc = H_PARAMETER;
		goto out_free;
	}

	mutex_lock(&gp->tlb_lock);

	if (is_load) {
		/* Load from the nested guest into our buffer */
		rc = __kvmhv_copy_tofrom_guest_radix(gp->shadow_lpid, pid,
						     eaddr, buf, NULL, n);
		if (rc)
			goto not_found;

		/* Write what was loaded into our buffer back to the L1 guest */
		kvm_vcpu_srcu_read_lock(vcpu);
		rc = kvm_vcpu_write_guest(vcpu, gp_to, buf, n);
		kvm_vcpu_srcu_read_unlock(vcpu);
		if (rc)
			goto not_found;
	} else {
		/* Load the data to be stored from the L1 guest into our buf */
		kvm_vcpu_srcu_read_lock(vcpu);
		rc = kvm_vcpu_read_guest(vcpu, gp_from, buf, n);
		kvm_vcpu_srcu_read_unlock(vcpu);
		if (rc)
			goto not_found;

		/* Store from our buffer into the nested guest */
		rc = __kvmhv_copy_tofrom_guest_radix(gp->shadow_lpid, pid,
						     eaddr, NULL, buf, n);
		if (rc)
			goto not_found;
	}

out_unlock:
	mutex_unlock(&gp->tlb_lock);
	kvmhv_put_nested(gp);
out_free:
	kfree(buf);
	return rc;
not_found:
	rc = H_NOT_FOUND;
	goto out_unlock;
}

/*
 * Reload the partition table entry for a guest.
 * Caller must hold gp->tlb_lock.
 */
static void kvmhv_update_ptbl_cache(struct kvm_nested_guest *gp)
{
	int ret;
	struct patb_entry ptbl_entry;
	unsigned long ptbl_addr;
	struct kvm *kvm = gp->l1_host;

	ret = -EFAULT;
	ptbl_addr = (kvm->arch.l1_ptcr & PRTB_MASK) + (gp->l1_lpid << 4);
	if (gp->l1_lpid < (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4))) {
		int srcu_idx = srcu_read_lock(&kvm->srcu);
		ret = kvm_read_guest(kvm, ptbl_addr,
				     &ptbl_entry, sizeof(ptbl_entry));
		srcu_read_unlock(&kvm->srcu, srcu_idx);
	}
	if (ret) {
		gp->l1_gr_to_hr = 0;
		gp->process_table = 0;
	} else {
		gp->l1_gr_to_hr = be64_to_cpu(ptbl_entry.patb0);
		gp->process_table = be64_to_cpu(ptbl_entry.patb1);
	}
	kvmhv_set_nested_ptbl(gp);
}

void kvmhv_vm_nested_init(struct kvm *kvm)
{
	idr_init(&kvm->arch.kvm_nested_guest_idr);
}

static struct kvm_nested_guest *__find_nested(struct kvm *kvm, int lpid)
{
	return idr_find(&kvm->arch.kvm_nested_guest_idr, lpid);
}

static bool __prealloc_nested(struct kvm *kvm, int lpid)
{
	if (idr_alloc(&kvm->arch.kvm_nested_guest_idr,
				NULL, lpid, lpid + 1, GFP_KERNEL) != lpid)
		return false;
	return true;
}

static void __add_nested(struct kvm *kvm, int lpid, struct kvm_nested_guest *gp)
{
	if (idr_replace(&kvm->arch.kvm_nested_guest_idr, gp, lpid))
		WARN_ON(1);
}

static void __remove_nested(struct kvm *kvm, int lpid)
{
	idr_remove(&kvm->arch.kvm_nested_guest_idr, lpid);
}

static struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int lpid)
{
	struct kvm_nested_guest *gp;
	long shadow_lpid;

	gp = kzalloc(sizeof(*gp), GFP_KERNEL);
	if (!gp)
		return NULL;
	gp->l1_host = kvm;
	gp->l1_lpid = lpid;
	mutex_init(&gp->tlb_lock);
	gp->shadow_pgtable = pgd_alloc(kvm->mm);
	if (!gp->shadow_pgtable)
		goto out_free;
	shadow_lpid = kvmppc_alloc_lpid();
	if (shadow_lpid < 0)
		goto out_free2;
	gp->shadow_lpid = shadow_lpid;
	gp->radix = 1;

	memset(gp->prev_cpu, -1, sizeof(gp->prev_cpu));

	return gp;

 out_free2:
	pgd_free(kvm->mm, gp->shadow_pgtable);
 out_free:
	kfree(gp);
	return NULL;
}

/*
 * Free up any resources allocated for a nested guest.
 */
static void kvmhv_release_nested(struct kvm_nested_guest *gp)
{
	struct kvm *kvm = gp->l1_host;

	if (gp->shadow_pgtable) {
		/*
		 * No vcpu is using this struct and no call to
		 * kvmhv_get_nested can find this struct,
		 * so we don't need to hold kvm->mmu_lock.
		 */
		kvmppc_free_pgtable_radix(kvm, gp->shadow_pgtable,
					  gp->shadow_lpid);
		pgd_free(kvm->mm, gp->shadow_pgtable);
	}
	kvmhv_set_ptbl_entry(gp->shadow_lpid, 0, 0);
	kvmppc_free_lpid(gp->shadow_lpid);
	kfree(gp);
}

static void kvmhv_remove_nested(struct kvm_nested_guest *gp)
{
	struct kvm *kvm = gp->l1_host;
	int lpid = gp->l1_lpid;
	long ref;

	spin_lock(&kvm->mmu_lock);
	if (gp == __find_nested(kvm, lpid)) {
		__remove_nested(kvm, lpid);
		--gp->refcnt;
	}
	ref = gp->refcnt;
	spin_unlock(&kvm->mmu_lock);
	if (ref == 0)
		kvmhv_release_nested(gp);
}

/*
 * Free up all nested resources allocated for this guest.
 * This is called with no vcpus of the guest running, when
 * switching the guest to HPT mode or when destroying the
 * guest.
 */
void kvmhv_release_all_nested(struct kvm *kvm)
{
	int lpid;
	struct kvm_nested_guest *gp;
	struct kvm_nested_guest *freelist = NULL;
	struct kvm_memory_slot *memslot;
	int srcu_idx, bkt;

	spin_lock(&kvm->mmu_lock);
	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
		__remove_nested(kvm, lpid);
		if (--gp->refcnt == 0) {
			gp->next = freelist;
			freelist = gp;
		}
	}
	idr_destroy(&kvm->arch.kvm_nested_guest_idr);
	/* idr is empty and may be reused at this point */
	spin_unlock(&kvm->mmu_lock);
	while ((gp = freelist) != NULL) {
		freelist = gp->next;
		kvmhv_release_nested(gp);
	}

	srcu_idx = srcu_read_lock(&kvm->srcu);
	kvm_for_each_memslot(memslot, bkt, kvm_memslots(kvm))
		kvmhv_free_memslot_nest_rmap(memslot);
	srcu_read_unlock(&kvm->srcu, srcu_idx);
}

/* caller must hold gp->tlb_lock */
static void kvmhv_flush_nested(struct kvm_nested_guest *gp)
{
	struct kvm *kvm = gp->l1_host;

	spin_lock(&kvm->mmu_lock);
	kvmppc_free_pgtable_radix(kvm, gp->shadow_pgtable, gp->shadow_lpid);
	spin_unlock(&kvm->mmu_lock);
	kvmhv_flush_lpid(gp->shadow_lpid);
	kvmhv_update_ptbl_cache(gp);
	if (gp->l1_gr_to_hr == 0)
		kvmhv_remove_nested(gp);
}

struct kvm_nested_guest *kvmhv_get_nested(struct kvm *kvm, int l1_lpid,
					  bool create)
{
	struct kvm_nested_guest *gp, *newgp;

	if (l1_lpid >= (1ul << ((kvm->arch.l1_ptcr & PRTS_MASK) + 12 - 4)))
		return NULL;

	spin_lock(&kvm->mmu_lock);
	gp = __find_nested(kvm, l1_lpid);
	if (gp)
		++gp->refcnt;
	spin_unlock(&kvm->mmu_lock);

	if (gp || !create)
		return gp;

	newgp = kvmhv_alloc_nested(kvm, l1_lpid);
	if (!newgp)
		return NULL;

	if (!__prealloc_nested(kvm, l1_lpid)) {
		kvmhv_release_nested(newgp);
		return NULL;
	}

	spin_lock(&kvm->mmu_lock);
	gp = __find_nested(kvm, l1_lpid);
	if (!gp) {
		__add_nested(kvm, l1_lpid, newgp);
		++newgp->refcnt;
		gp = newgp;
		newgp = NULL;
	}
	++gp->refcnt;
	spin_unlock(&kvm->mmu_lock);

	if (newgp)
		kvmhv_release_nested(newgp);

	return gp;
}

void kvmhv_put_nested(struct kvm_nested_guest *gp)
{
	struct kvm *kvm = gp->l1_host;
	long ref;

	spin_lock(&kvm->mmu_lock);
	ref = --gp->refcnt;
	spin_unlock(&kvm->mmu_lock);
	if (ref == 0)
		kvmhv_release_nested(gp);
}

pte_t *find_kvm_nested_guest_pte(struct kvm *kvm, unsigned long lpid,
				 unsigned long ea, unsigned *hshift)
{
	struct kvm_nested_guest *gp;
	pte_t *pte;

	gp = __find_nested(kvm, lpid);
	if (!gp)
		return NULL;

	VM_WARN(!spin_is_locked(&kvm->mmu_lock),
		"%s called with kvm mmu_lock not held \n", __func__);
	pte = __find_linux_pte(gp->shadow_pgtable, ea, NULL, hshift);

	return pte;
}

static inline bool kvmhv_n_rmap_is_equal(u64 rmap_1, u64 rmap_2)
{
	return !((rmap_1 ^ rmap_2) & (RMAP_NESTED_LPID_MASK |
				       RMAP_NESTED_GPA_MASK));
}

void kvmhv_insert_nest_rmap(struct kvm *kvm, unsigned long *rmapp,
			    struct rmap_nested **n_rmap)
{
	struct llist_node *entry = ((struct llist_head *) rmapp)->first;
	struct rmap_nested *cursor;
	u64 rmap, new_rmap = (*n_rmap)->rmap;

	/* Are there any existing entries? */
	if (!(*rmapp)) {
		/* No -> use the rmap as a single entry */
		*rmapp = new_rmap | RMAP_NESTED_IS_SINGLE_ENTRY;
		return;
	}

	/* Do any entries match what we're trying to insert? */
	for_each_nest_rmap_safe(cursor, entry, &rmap) {
		if (kvmhv_n_rmap_is_equal(rmap, new_rmap))
			return;
	}

	/* Do we need to create a list or just add the new entry? */
	rmap = *rmapp;
	if (rmap & RMAP_NESTED_IS_SINGLE_ENTRY) /* Not previously a list */
		*rmapp = 0UL;
	llist_add(&((*n_rmap)->list), (struct llist_head *) rmapp);
	if (rmap & RMAP_NESTED_IS_SINGLE_ENTRY) /* Not previously a list */
		(*n_rmap)->list.next = (struct llist_node *) rmap;

	/* Set NULL so not freed by caller */
	*n_rmap = NULL;
}

static void kvmhv_update_nest_rmap_rc(struct kvm *kvm, u64 n_rmap,
				      unsigned long clr, unsigned long set,
				      unsigned long hpa, unsigned long mask)
{
	unsigned long gpa;
	unsigned int shift, lpid;
	pte_t *ptep;

	gpa = n_rmap & RMAP_NESTED_GPA_MASK;
	lpid = (n_rmap & RMAP_NESTED_LPID_MASK) >> RMAP_NESTED_LPID_SHIFT;

	/* Find the pte */
	ptep = find_kvm_nested_guest_pte(kvm, lpid, gpa, &shift);
	/*
	 * If the pte is present and the pfn is still the same, update the pte.
	 * If the pfn has changed then this is a stale rmap entry, the nested
	 * gpa actually points somewhere else now, and there is nothing to do.
	 * XXX A future optimisation would be to remove the rmap entry here.
	 */
	if (ptep && pte_present(*ptep) && ((pte_val(*ptep) & mask) == hpa)) {
		__radix_pte_update(ptep, clr, set);
		kvmppc_radix_tlbie_page(kvm, gpa, shift, lpid);
	}
}

/*
 * For a given list of rmap entries, update the rc bits in all ptes in shadow
 * page tables for nested guests which are referenced by the rmap list.
 */
void kvmhv_update_nest_rmap_rc_list(struct kvm *kvm, unsigned long *rmapp,
				    unsigned long clr, unsigned long set,
				    unsigned long hpa, unsigned long nbytes)
{
	struct llist_node *entry = ((struct llist_head *) rmapp)->first;
	struct rmap_nested *cursor;
	unsigned long rmap, mask;

	if ((clr | set) & ~(_PAGE_DIRTY | _PAGE_ACCESSED))
		return;

	mask = PTE_RPN_MASK & ~(nbytes - 1);
	hpa &= mask;

	for_each_nest_rmap_safe(cursor, entry, &rmap)
		kvmhv_update_nest_rmap_rc(kvm, rmap, clr, set, hpa, mask);
}

static void kvmhv_remove_nest_rmap(struct kvm *kvm, u64 n_rmap,
				   unsigned long hpa, unsigned long mask)
{
	struct kvm_nested_guest *gp;
	unsigned long gpa;
	unsigned int shift, lpid;
	pte_t *ptep;

	gpa = n_rmap & RMAP_NESTED_GPA_MASK;
	lpid = (n_rmap & RMAP_NESTED_LPID_MASK) >> RMAP_NESTED_LPID_SHIFT;
	gp = __find_nested(kvm, lpid);
	if (!gp)
		return;

	/* Find and invalidate the pte */
	ptep = find_kvm_nested_guest_pte(kvm, lpid, gpa, &shift);
	/* Don't spuriously invalidate ptes if the pfn has changed */
	if (ptep && pte_present(*ptep) && ((pte_val(*ptep) & mask) == hpa))
		kvmppc_unmap_pte(kvm, ptep, gpa, shift, NULL, gp->shadow_lpid);
}

static void kvmhv_remove_nest_rmap_list(struct kvm *kvm, unsigned long *rmapp,
					unsigned long hpa, unsigned long mask)
{
	struct llist_node *entry = llist_del_all((struct llist_head *) rmapp);
	struct rmap_nested *cursor;
	unsigned long rmap;

	for_each_nest_rmap_safe(cursor, entry, &rmap) {
		kvmhv_remove_nest_rmap(kvm, rmap, hpa, mask);
		kfree(cursor);
	}
}

/* called with kvm->mmu_lock held */
void kvmhv_remove_nest_rmap_range(struct kvm *kvm,
				  const struct kvm_memory_slot *memslot,
				  unsigned long gpa, unsigned long hpa,
				  unsigned long nbytes)
{
	unsigned long gfn, end_gfn;
	unsigned long addr_mask;

	if (!memslot)
		return;
	gfn = (gpa >> PAGE_SHIFT) - memslot->base_gfn;
	end_gfn = gfn + (nbytes >> PAGE_SHIFT);

	addr_mask = PTE_RPN_MASK & ~(nbytes - 1);
	hpa &= addr_mask;

	for (; gfn < end_gfn; gfn++) {
		unsigned long *rmap = &memslot->arch.rmap[gfn];
		kvmhv_remove_nest_rmap_list(kvm, rmap, hpa, addr_mask);
	}
}

static void kvmhv_free_memslot_nest_rmap(struct kvm_memory_slot *free)
{
	unsigned long page;

	for (page = 0; page < free->npages; page++) {
		unsigned long rmap, *rmapp = &free->arch.rmap[page];
		struct rmap_nested *cursor;
		struct llist_node *entry;

		entry = llist_del_all((struct llist_head *) rmapp);
		for_each_nest_rmap_safe(cursor, entry, &rmap)
			kfree(cursor);
	}
}

static bool kvmhv_invalidate_shadow_pte(struct kvm_vcpu *vcpu,
					struct kvm_nested_guest *gp,
					long gpa, int *shift_ret)
{
	struct kvm *kvm = vcpu->kvm;
	bool ret = false;
	pte_t *ptep;
	int shift;

	spin_lock(&kvm->mmu_lock);
	ptep = find_kvm_nested_guest_pte(kvm, gp->l1_lpid, gpa, &shift);
	if (!shift)
		shift = PAGE_SHIFT;
	if (ptep && pte_present(*ptep)) {
		kvmppc_unmap_pte(kvm, ptep, gpa, shift, NULL, gp->shadow_lpid);
		ret = true;
	}
	spin_unlock(&kvm->mmu_lock);

	if (shift_ret)
		*shift_ret = shift;
	return ret;
}

static inline int get_ric(unsigned int instr)
{
	return (instr >> 18) & 0x3;
}

static inline int get_prs(unsigned int instr)
{
	return (instr >> 17) & 0x1;
}

static inline int get_r(unsigned int instr)
{
	return (instr >> 16) & 0x1;
}

static inline int get_lpid(unsigned long r_val)
{
	return r_val & 0xffffffff;
}

static inline int get_is(unsigned long r_val)
{
	return (r_val >> 10) & 0x3;
}

static inline int get_ap(unsigned long r_val)
{
	return (r_val >> 5) & 0x7;
}

static inline long get_epn(unsigned long r_val)
{
	return r_val >> 12;
}

static int kvmhv_emulate_tlbie_tlb_addr(struct kvm_vcpu *vcpu, int lpid,
					int ap, long epn)
{
	struct kvm *kvm = vcpu->kvm;
	struct kvm_nested_guest *gp;
	long npages;
	int shift, shadow_shift;
	unsigned long addr;

	shift = ap_to_shift(ap);
	addr = epn << 12;
	if (shift < 0)
		/* Invalid ap encoding */
		return -EINVAL;

	addr &= ~((1UL << shift) - 1);
	npages = 1UL << (shift - PAGE_SHIFT);

	gp = kvmhv_get_nested(kvm, lpid, false);
	if (!gp) /* No such guest -> nothing to do */
		return 0;
	mutex_lock(&gp->tlb_lock);

	/* There may be more than one host page backing this single guest pte */
	do {
		kvmhv_invalidate_shadow_pte(vcpu, gp, addr, &shadow_shift);

		npages -= 1UL << (shadow_shift - PAGE_SHIFT);
		addr += 1UL << shadow_shift;
	} while (npages > 0);

	mutex_unlock(&gp->tlb_lock);
	kvmhv_put_nested(gp);
	return 0;
}

static void kvmhv_emulate_tlbie_lpid(struct kvm_vcpu *vcpu,
				     struct kvm_nested_guest *gp, int ric)
{
	struct kvm *kvm = vcpu->kvm;

	mutex_lock(&gp->tlb_lock);
	switch (ric) {
	case 0:
		/* Invalidate TLB */
		spin_lock(&kvm->mmu_lock);
		kvmppc_free_pgtable_radix(kvm, gp->shadow_pgtable,
					  gp->shadow_lpid);
		kvmhv_flush_lpid(gp->shadow_lpid);
		spin_unlock(&kvm->mmu_lock);
		break;
	case 1:
		/*
		 * Invalidate PWC
		 * We don't cache this -> nothing to do
		 */
		break;
	case 2:
		/* Invalidate TLB, PWC and caching of partition table entries */
		kvmhv_flush_nested(gp);
		break;
	default:
		break;
	}
	mutex_unlock(&gp->tlb_lock);
}

static void kvmhv_emulate_tlbie_all_lpid(struct kvm_vcpu *vcpu, int ric)
{
	struct kvm *kvm = vcpu->kvm;
	struct kvm_nested_guest *gp;
	int lpid;

	spin_lock(&kvm->mmu_lock);
	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
		spin_unlock(&kvm->mmu_lock);
		kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
		spin_lock(&kvm->mmu_lock);
	}
	spin_unlock(&kvm->mmu_lock);
}

static int kvmhv_emulate_priv_tlbie(struct kvm_vcpu *vcpu, unsigned int instr,
				    unsigned long rsval, unsigned long rbval)
{
	struct kvm *kvm = vcpu->kvm;
	struct kvm_nested_guest *gp;
	int r, ric, prs, is, ap;
	int lpid;
	long epn;
	int ret = 0;

	ric = get_ric(instr);
	prs = get_prs(instr);
	r = get_r(instr);
	lpid = get_lpid(rsval);
	is = get_is(rbval);

	/*
	 * These cases are invalid and are not handled:
	 * r   != 1 -> Only radix supported
	 * prs == 1 -> Not HV privileged
	 * ric == 3 -> No cluster bombs for radix
	 * is  == 1 -> Partition scoped translations not associated with pid
	 * (!is) && (ric == 1 || ric == 2) -> Not supported by ISA
	 */
	if ((!r) || (prs) || (ric == 3) || (is == 1) ||
	    ((!is) && (ric == 1 || ric == 2)))
		return -EINVAL;

	switch (is) {
	case 0:
		/*
		 * We know ric == 0
		 * Invalidate TLB for a given target address
		 */
		epn = get_epn(rbval);
		ap = get_ap(rbval);
		ret = kvmhv_emulate_tlbie_tlb_addr(vcpu, lpid, ap, epn);
		break;
	case 2:
		/* Invalidate matching LPID */
		gp = kvmhv_get_nested(kvm, lpid, false);
		if (gp) {
			kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
			kvmhv_put_nested(gp);
		}
		break;
	case 3:
		/* Invalidate ALL LPIDs */
		kvmhv_emulate_tlbie_all_lpid(vcpu, ric);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

/*
 * This handles the H_TLB_INVALIDATE hcall.
 * Parameters are (r4) tlbie instruction code, (r5) rS contents,
 * (r6) rB contents.
 */
long kvmhv_do_nested_tlbie(struct kvm_vcpu *vcpu)
{
	int ret;

	ret = kvmhv_emulate_priv_tlbie(vcpu, kvmppc_get_gpr(vcpu, 4),
			kvmppc_get_gpr(vcpu, 5), kvmppc_get_gpr(vcpu, 6));
	if (ret)
		return H_PARAMETER;
	return H_SUCCESS;
}

static long do_tlb_invalidate_nested_all(struct kvm_vcpu *vcpu,
					 unsigned long lpid, unsigned long ric)
{
	struct kvm *kvm = vcpu->kvm;
	struct kvm_nested_guest *gp;

	gp = kvmhv_get_nested(kvm, lpid, false);
	if (gp) {
		kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
		kvmhv_put_nested(gp);
	}
	return H_SUCCESS;
}

/*
 * Number of pages above which we invalidate the entire LPID rather than
 * flush individual pages.
 */
static unsigned long tlb_range_flush_page_ceiling __read_mostly = 33;

static long do_tlb_invalidate_nested_tlb(struct kvm_vcpu *vcpu,
					 unsigned long lpid,
					 unsigned long pg_sizes,
					 unsigned long start,
					 unsigned long end)
{
	int ret = H_P4;
	unsigned long addr, nr_pages;
	struct mmu_psize_def *def;
	unsigned long psize, ap, page_size;
	bool flush_lpid;

	for (psize = 0; psize < MMU_PAGE_COUNT; psize++) {
		def = &mmu_psize_defs[psize];
		if (!(pg_sizes & def->h_rpt_pgsize))
			continue;

		nr_pages = (end - start) >> def->shift;
		flush_lpid = nr_pages > tlb_range_flush_page_ceiling;
		if (flush_lpid)
			return do_tlb_invalidate_nested_all(vcpu, lpid,
							RIC_FLUSH_TLB);
		addr = start;
		ap = mmu_get_ap(psize);
		page_size = 1UL << def->shift;
		do {
			ret = kvmhv_emulate_tlbie_tlb_addr(vcpu, lpid, ap,
						   get_epn(addr));
			if (ret)
				return H_P4;
			addr += page_size;
		} while (addr < end);
	}
	return ret;
}

/*
 * Performs partition-scoped invalidations for nested guests
 * as part of H_RPT_INVALIDATE hcall.
 */
long do_h_rpt_invalidate_pat(struct kvm_vcpu *vcpu, unsigned long lpid,
			     unsigned long type, unsigned long pg_sizes,
			     unsigned long start, unsigned long end)
{
	/*
	 * If L2 lpid isn't valid, we need to return H_PARAMETER.
	 *
	 * However, nested KVM issues a L2 lpid flush call when creating
	 * partition table entries for L2. This happens even before the
	 * corresponding shadow lpid is created in HV which happens in
	 * H_ENTER_NESTED call. Since we can't differentiate this case from
	 * the invalid case, we ignore such flush requests and return success.
	 */
	if (!__find_nested(vcpu->kvm, lpid))
		return H_SUCCESS;

	/*
	 * A flush all request can be handled by a full lpid flush only.
	 */
	if ((type & H_RPTI_TYPE_NESTED_ALL) == H_RPTI_TYPE_NESTED_ALL)
		return do_tlb_invalidate_nested_all(vcpu, lpid, RIC_FLUSH_ALL);

	/*
	 * We don't need to handle a PWC flush like process table here,
	 * because intermediate partition scoped table in nested guest doesn't
	 * really have PWC. Only level we have PWC is in L0 and for nested
	 * invalidate at L0 we always do kvm_flush_lpid() which does
	 * radix__flush_all_lpid(). For range invalidate at any level, we
	 * are not removing the higher level page tables and hence there is
	 * no PWC invalidate needed.
	 *
	 * if (type & H_RPTI_TYPE_PWC) {
	 *	ret = do_tlb_invalidate_nested_all(vcpu, lpid, RIC_FLUSH_PWC);
	 *	if (ret)
	 *		return H_P4;
	 * }
	 */

	if (start == 0 && end == -1)
		return do_tlb_invalidate_nested_all(vcpu, lpid, RIC_FLUSH_TLB);

	if (type & H_RPTI_TYPE_TLB)
		return do_tlb_invalidate_nested_tlb(vcpu, lpid, pg_sizes,
						    start, end);
	return H_SUCCESS;
}

/* Used to convert a nested guest real address to a L1 guest real address */
static int kvmhv_translate_addr_nested(struct kvm_vcpu *vcpu,
				       struct kvm_nested_guest *gp,
				       unsigned long n_gpa, unsigned long dsisr,
				       struct kvmppc_pte *gpte_p)
{
	u64 fault_addr, flags = dsisr & DSISR_ISSTORE;
	int ret;

	ret = kvmppc_mmu_walk_radix_tree(vcpu, n_gpa, gpte_p, gp->l1_gr_to_hr,
					 &fault_addr);

	if (ret) {
		/* We didn't find a pte */
		if (ret == -EINVAL) {
			/* Unsupported mmu config */
			flags |= DSISR_UNSUPP_MMU;
		} else if (ret == -ENOENT) {
			/* No translation found */
			flags |= DSISR_NOHPTE;
		} else if (ret == -EFAULT) {
			/* Couldn't access L1 real address */
			flags |= DSISR_PRTABLE_FAULT;
			vcpu->arch.fault_gpa = fault_addr;
		} else {
			/* Unknown error */
			return ret;
		}
		goto forward_to_l1;
	} else {
		/* We found a pte -> check permissions */
		if (dsisr & DSISR_ISSTORE) {
			/* Can we write? */
			if (!gpte_p->may_write) {
				flags |= DSISR_PROTFAULT;
				goto forward_to_l1;
			}
		} else if (vcpu->arch.trap == BOOK3S_INTERRUPT_H_INST_STORAGE) {
			/* Can we execute? */
			if (!gpte_p->may_execute) {
				flags |= SRR1_ISI_N_G_OR_CIP;
				goto forward_to_l1;
			}
		} else {
			/* Can we read? */
			if (!gpte_p->may_read && !gpte_p->may_write) {
				flags |= DSISR_PROTFAULT;
				goto forward_to_l1;
			}
		}
	}

	return 0;

forward_to_l1:
	vcpu->arch.fault_dsisr = flags;
	if (vcpu->arch.trap == BOOK3S_INTERRUPT_H_INST_STORAGE) {
		vcpu->arch.shregs.msr &= SRR1_MSR_BITS;
		vcpu->arch.shregs.msr |= flags;
	}
	return RESUME_HOST;
}

static long kvmhv_handle_nested_set_rc(struct kvm_vcpu *vcpu,
				       struct kvm_nested_guest *gp,
				       unsigned long n_gpa,
				       struct kvmppc_pte gpte,
				       unsigned long dsisr)
{
	struct kvm *kvm = vcpu->kvm;
	bool writing = !!(dsisr & DSISR_ISSTORE);
	u64 pgflags;
	long ret;

	/* Are the rc bits set in the L1 partition scoped pte? */
	pgflags = _PAGE_ACCESSED;
	if (writing)
		pgflags |= _PAGE_DIRTY;
	if (pgflags & ~gpte.rc)
		return RESUME_HOST;

	spin_lock(&kvm->mmu_lock);
	/* Set the rc bit in the pte of our (L0) pgtable for the L1 guest */
	ret = kvmppc_hv_handle_set_rc(kvm, false, writing,
				      gpte.raddr, kvm->arch.lpid);
	if (!ret) {
		ret = -EINVAL;
		goto out_unlock;
	}

	/* Set the rc bit in the pte of the shadow_pgtable for the nest guest */
	ret = kvmppc_hv_handle_set_rc(kvm, true, writing,
				      n_gpa, gp->l1_lpid);
	if (!ret)
		ret = -EINVAL;
	else
		ret = 0;

out_unlock:
	spin_unlock(&kvm->mmu_lock);
	return ret;
}

static inline int kvmppc_radix_level_to_shift(int level)
{
	switch (level) {
	case 2:
		return PUD_SHIFT;
	case 1:
		return PMD_SHIFT;
	default:
		return PAGE_SHIFT;
	}
}

static inline int kvmppc_radix_shift_to_level(int shift)
{
	if (shift == PUD_SHIFT)
		return 2;
	if (shift == PMD_SHIFT)
		return 1;
	if (shift == PAGE_SHIFT)
		return 0;
	WARN_ON_ONCE(1);
	return 0;
}

/* called with gp->tlb_lock held */
static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu,
					  struct kvm_nested_guest *gp)
{
	struct kvm *kvm = vcpu->kvm;
	struct kvm_memory_slot *memslot;
	struct rmap_nested *n_rmap;
	struct kvmppc_pte gpte;
	pte_t pte, *pte_p;
	unsigned long mmu_seq;
	unsigned long dsisr = vcpu->arch.fault_dsisr;
	unsigned long ea = vcpu->arch.fault_dar;
	unsigned long *rmapp;
	unsigned long n_gpa, gpa, gfn, perm = 0UL;
	unsigned int shift, l1_shift, level;
	bool writing = !!(dsisr & DSISR_ISSTORE);
	bool kvm_ro = false;
	long int ret;

	if (!gp->l1_gr_to_hr) {
		kvmhv_update_ptbl_cache(gp);
		if (!gp->l1_gr_to_hr)
			return RESUME_HOST;
	}

	/* Convert the nested guest real address into a L1 guest real address */

	n_gpa = vcpu->arch.fault_gpa & ~0xF000000000000FFFULL;
	if (!(dsisr & DSISR_PRTABLE_FAULT))
		n_gpa |= ea & 0xFFF;
	ret = kvmhv_translate_addr_nested(vcpu, gp, n_gpa, dsisr, &gpte);

	/*
	 * If the hardware found a translation but we don't now have a usable
	 * translation in the l1 partition-scoped tree, remove the shadow pte
	 * and let the guest retry.
	 */
	if (ret == RESUME_HOST &&
	    (dsisr & (DSISR_PROTFAULT | DSISR_BADACCESS | DSISR_NOEXEC_OR_G |
		      DSISR_BAD_COPYPASTE)))
		goto inval;
	if (ret)
		return ret;

	/* Failed to set the reference/change bits */
	if (dsisr & DSISR_SET_RC) {
		ret = kvmhv_handle_nested_set_rc(vcpu, gp, n_gpa, gpte, dsisr);
		if (ret == RESUME_HOST)
			return ret;
		if (ret)
			goto inval;
		dsisr &= ~DSISR_SET_RC;
		if (!(dsisr & (DSISR_BAD_FAULT_64S | DSISR_NOHPTE |
			       DSISR_PROTFAULT)))
			return RESUME_GUEST;
	}

	/*
	 * We took an HISI or HDSI while we were running a nested guest which
	 * means we have no partition scoped translation for that. This means
	 * we need to insert a pte for the mapping into our shadow_pgtable.
	 */

	l1_shift = gpte.page_shift;
	if (l1_shift < PAGE_SHIFT) {
		/* We don't support l1 using a page size smaller than our own */
		pr_err("KVM: L1 guest page shift (%d) less than our own (%d)\n",
			l1_shift, PAGE_SHIFT);
		return -EINVAL;
	}
	gpa = gpte.raddr;
	gfn = gpa >> PAGE_SHIFT;

	/* 1. Get the corresponding host memslot */

	memslot = gfn_to_memslot(kvm, gfn);
	if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) {
		if (dsisr & (DSISR_PRTABLE_FAULT | DSISR_BADACCESS)) {
			/* unusual error -> reflect to the guest as a DSI */
			kvmppc_core_queue_data_storage(vcpu,
					kvmppc_get_msr(vcpu) & SRR1_PREFIXED,
					ea, dsisr);
			return RESUME_GUEST;
		}

		/* passthrough of emulated MMIO case */
		return kvmppc_hv_emulate_mmio(vcpu, gpa, ea, writing);
	}
	if (memslot->flags & KVM_MEM_READONLY) {
		if (writing) {
			/* Give the guest a DSI */
			kvmppc_core_queue_data_storage(vcpu,
					kvmppc_get_msr(vcpu) & SRR1_PREFIXED,
					ea, DSISR_ISSTORE | DSISR_PROTFAULT);
			return RESUME_GUEST;
		}
		kvm_ro = true;
	}

	/* 2. Find the host pte for this L1 guest real address */

	/* Used to check for invalidations in progress */
	mmu_seq = kvm->mmu_invalidate_seq;
	smp_rmb();

	/* See if can find translation in our partition scoped tables for L1 */
	pte = __pte(0);
	spin_lock(&kvm->mmu_lock);
	pte_p = find_kvm_secondary_pte(kvm, gpa, &shift);
	if (!shift)
		shift = PAGE_SHIFT;
	if (pte_p)
		pte = *pte_p;
	spin_unlock(&kvm->mmu_lock);

	if (!pte_present(pte) || (writing && !(pte_val(pte) & _PAGE_WRITE))) {
		/* No suitable pte found -> try to insert a mapping */
		ret = kvmppc_book3s_instantiate_page(vcpu, gpa, memslot,
					writing, kvm_ro, &pte, &level);
		if (ret == -EAGAIN)
			return RESUME_GUEST;
		else if (ret)
			return ret;
		shift = kvmppc_radix_level_to_shift(level);
	}
	/* Align gfn to the start of the page */
	gfn = (gpa & ~((1UL << shift) - 1)) >> PAGE_SHIFT;

	/* 3. Compute the pte we need to insert for nest_gpa -> host r_addr */

	/* The permissions is the combination of the host and l1 guest ptes */
	perm |= gpte.may_read ? 0UL : _PAGE_READ;
	perm |= gpte.may_write ? 0UL : _PAGE_WRITE;
	perm |= gpte.may_execute ? 0UL : _PAGE_EXEC;
	/* Only set accessed/dirty (rc) bits if set in host and l1 guest ptes */
	perm |= (gpte.rc & _PAGE_ACCESSED) ? 0UL : _PAGE_ACCESSED;
	perm |= ((gpte.rc & _PAGE_DIRTY) && writing) ? 0UL : _PAGE_DIRTY;
	pte = __pte(pte_val(pte) & ~perm);

	/* What size pte can we insert? */
	if (shift > l1_shift) {
		u64 mask;
		unsigned int actual_shift = PAGE_SHIFT;
		if (PMD_SHIFT < l1_shift)
			actual_shift = PMD_SHIFT;
		mask = (1UL << shift) - (1UL << actual_shift);
		pte = __pte(pte_val(pte) | (gpa & mask));
		shift = actual_shift;
	}
	level = kvmppc_radix_shift_to_level(shift);
	n_gpa &= ~((1UL << shift) - 1);

	/* 4. Insert the pte into our shadow_pgtable */

	n_rmap = kzalloc(sizeof(*n_rmap), GFP_KERNEL);
	if (!n_rmap)
		return RESUME_GUEST; /* Let the guest try again */
	n_rmap->rmap = (n_gpa & RMAP_NESTED_GPA_MASK) |
		(((unsigned long) gp->l1_lpid) << RMAP_NESTED_LPID_SHIFT);
	rmapp = &memslot->arch.rmap[gfn - memslot->base_gfn];
	ret = kvmppc_create_pte(kvm, gp->shadow_pgtable, pte, n_gpa, level,
				mmu_seq, gp->shadow_lpid, rmapp, &n_rmap);
	kfree(n_rmap);
	if (ret == -EAGAIN)
		ret = RESUME_GUEST;	/* Let the guest try again */

	return ret;

 inval:
	kvmhv_invalidate_shadow_pte(vcpu, gp, n_gpa, NULL);
	return RESUME_GUEST;
}

long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu)
{
	struct kvm_nested_guest *gp = vcpu->arch.nested;
	long int ret;

	mutex_lock(&gp->tlb_lock);
	ret = __kvmhv_nested_page_fault(vcpu, gp);
	mutex_unlock(&gp->tlb_lock);
	return ret;
}

int kvmhv_nested_next_lpid(struct kvm *kvm, int lpid)
{
	int ret = lpid + 1;

	spin_lock(&kvm->mmu_lock);
	if (!idr_get_next(&kvm->arch.kvm_nested_guest_idr, &ret))
		ret = -1;
	spin_unlock(&kvm->mmu_lock);

	return ret;
}
