// SPDX-License-Identifier: GPL-2.0
/*
 * Secure pages management: Migration of pages between normal and secure
 * memory of KVM guests.
 *
 * Copyright 2018 Bharata B Rao, IBM Corp. <bharata@linux.ibm.com>
 */

/*
 * A pseries guest can be run as secure guest on Ultravisor-enabled
 * POWER platforms. On such platforms, this driver will be used to manage
 * the movement of guest pages between the normal memory managed by
 * hypervisor (HV) and secure memory managed by Ultravisor (UV).
 *
 * The page-in or page-out requests from UV will come to HV as hcalls and
 * HV will call back into UV via ultracalls to satisfy these page requests.
 *
 * Private ZONE_DEVICE memory equal to the amount of secure memory
 * available in the platform for running secure guests is hotplugged.
 * Whenever a page belonging to the guest becomes secure, a page from this
 * private device memory is used to represent and track that secure page
 * on the HV side. Some pages (like virtio buffers, VPA pages etc) are
 * shared between UV and HV. However such pages aren't represented by
 * device private memory and mappings to shared memory exist in both
 * UV and HV page tables.
 */

/*
 * Notes on locking
 *
 * kvm->arch.uvmem_lock is a per-guest lock that prevents concurrent
 * page-in and page-out requests for the same GPA. Concurrent accesses
 * can either come via UV (guest vCPUs requesting for same page)
 * or when HV and guest simultaneously access the same page.
 * This mutex serializes the migration of page from HV(normal) to
 * UV(secure) and vice versa. So the serialization points are around
 * migrate_vma routines and page-in/out routines.
 *
 * Per-guest mutex comes with a cost though. Mainly it serializes the
 * fault path as page-out can occur when HV faults on accessing secure
 * guest pages. Currently UV issues page-in requests for all the guest
 * PFNs one at a time during early boot (UV_ESM uvcall), so this is
 * not a cause for concern. Also currently the number of page-outs caused
 * by HV touching secure pages is very very low. If an when UV supports
 * overcommitting, then we might see concurrent guest driven page-outs.
 *
 * Locking order
 *
 * 1. kvm->srcu - Protects KVM memslots
 * 2. kvm->mm->mmap_lock - find_vma, migrate_vma_pages and helpers, ksm_madvise
 * 3. kvm->arch.uvmem_lock - protects read/writes to uvmem slots thus acting
 *			     as sync-points for page-in/out
 */

/*
 * Notes on page size
 *
 * Currently UV uses 2MB mappings internally, but will issue H_SVM_PAGE_IN
 * and H_SVM_PAGE_OUT hcalls in PAGE_SIZE(64K) granularity. HV tracks
 * secure GPAs at 64K page size and maintains one device PFN for each
 * 64K secure GPA. UV_PAGE_IN and UV_PAGE_OUT calls by HV are also issued
 * for 64K page at a time.
 *
 * HV faulting on secure pages: When HV touches any secure page, it
 * faults and issues a UV_PAGE_OUT request with 64K page size. Currently
 * UV splits and remaps the 2MB page if necessary and copies out the
 * required 64K page contents.
 *
 * Shared pages: Whenever guest shares a secure page, UV will split and
 * remap the 2MB page if required and issue H_SVM_PAGE_IN with 64K page size.
 *
 * HV invalidating a page: When a regular page belonging to secure
 * guest gets unmapped, HV informs UV with UV_PAGE_INVAL of 64K
 * page size. Using 64K page size is correct here because any non-secure
 * page will essentially be of 64K page size. Splitting by UV during sharing
 * and page-out ensures this.
 *
 * Page fault handling: When HV handles page fault of a page belonging
 * to secure guest, it sends that to UV with a 64K UV_PAGE_IN request.
 * Using 64K size is correct here too as UV would have split the 2MB page
 * into 64k mappings and would have done page-outs earlier.
 *
 * In summary, the current secure pages handling code in HV assumes
 * 64K page size and in fact fails any page-in/page-out requests of
 * non-64K size upfront. If and when UV starts supporting multiple
 * page-sizes, we need to break this assumption.
 */

#include <linux/pagemap.h>
#include <linux/migrate.h>
#include <linux/kvm_host.h>
#include <linux/ksm.h>
#include <linux/of.h>
#include <linux/memremap.h>
#include <asm/ultravisor.h>
#include <asm/mman.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s_uvmem.h>

static struct dev_pagemap kvmppc_uvmem_pgmap;
static unsigned long *kvmppc_uvmem_bitmap;
static DEFINE_SPINLOCK(kvmppc_uvmem_bitmap_lock);

/*
 * States of a GFN
 * ---------------
 * The GFN can be in one of the following states.
 *
 * (a) Secure - The GFN is secure. The GFN is associated with
 *	a Secure VM, the contents of the GFN is not accessible
 *	to the Hypervisor.  This GFN can be backed by a secure-PFN,
 *	or can be backed by a normal-PFN with contents encrypted.
 *	The former is true when the GFN is paged-in into the
 *	ultravisor. The latter is true when the GFN is paged-out
 *	of the ultravisor.
 *
 * (b) Shared - The GFN is shared. The GFN is associated with a
 *	a secure VM. The contents of the GFN is accessible to
 *	Hypervisor. This GFN is backed by a normal-PFN and its
 *	content is un-encrypted.
 *
 * (c) Normal - The GFN is a normal. The GFN is associated with
 *	a normal VM. The contents of the GFN is accessible to
 *	the Hypervisor. Its content is never encrypted.
 *
 * States of a VM.
 * ---------------
 *
 * Normal VM:  A VM whose contents are always accessible to
 *	the hypervisor.  All its GFNs are normal-GFNs.
 *
 * Secure VM: A VM whose contents are not accessible to the
 *	hypervisor without the VM's consent.  Its GFNs are
 *	either Shared-GFN or Secure-GFNs.
 *
 * Transient VM: A Normal VM that is transitioning to secure VM.
 *	The transition starts on successful return of
 *	H_SVM_INIT_START, and ends on successful return
 *	of H_SVM_INIT_DONE. This transient VM, can have GFNs
 *	in any of the three states; i.e Secure-GFN, Shared-GFN,
 *	and Normal-GFN.	The VM never executes in this state
 *	in supervisor-mode.
 *
 * Memory slot State.
 * -----------------------------
 *	The state of a memory slot mirrors the state of the
 *	VM the memory slot is associated with.
 *
 * VM State transition.
 * --------------------
 *
 *  A VM always starts in Normal Mode.
 *
 *  H_SVM_INIT_START moves the VM into transient state. During this
 *  time the Ultravisor may request some of its GFNs to be shared or
 *  secured. So its GFNs can be in one of the three GFN states.
 *
 *  H_SVM_INIT_DONE moves the VM entirely from transient state to
 *  secure-state. At this point any left-over normal-GFNs are
 *  transitioned to Secure-GFN.
 *
 *  H_SVM_INIT_ABORT moves the transient VM back to normal VM.
 *  All its GFNs are moved to Normal-GFNs.
 *
 *  UV_TERMINATE transitions the secure-VM back to normal-VM. All
 *  the secure-GFN and shared-GFNs are tranistioned to normal-GFN
 *  Note: The contents of the normal-GFN is undefined at this point.
 *
 * GFN state implementation:
 * -------------------------
 *
 * Secure GFN is associated with a secure-PFN; also called uvmem_pfn,
 * when the GFN is paged-in. Its pfn[] has KVMPPC_GFN_UVMEM_PFN flag
 * set, and contains the value of the secure-PFN.
 * It is associated with a normal-PFN; also called mem_pfn, when
 * the GFN is pagedout. Its pfn[] has KVMPPC_GFN_MEM_PFN flag set.
 * The value of the normal-PFN is not tracked.
 *
 * Shared GFN is associated with a normal-PFN. Its pfn[] has
 * KVMPPC_UVMEM_SHARED_PFN flag set. The value of the normal-PFN
 * is not tracked.
 *
 * Normal GFN is associated with normal-PFN. Its pfn[] has
 * no flag set. The value of the normal-PFN is not tracked.
 *
 * Life cycle of a GFN
 * --------------------
 *
 * --------------------------------------------------------------
 * |        |     Share  |  Unshare | SVM       |H_SVM_INIT_DONE|
 * |        |operation   |operation | abort/    |               |
 * |        |            |          | terminate |               |
 * -------------------------------------------------------------
 * |        |            |          |           |               |
 * | Secure |     Shared | Secure   |Normal     |Secure         |
 * |        |            |          |           |               |
 * | Shared |     Shared | Secure   |Normal     |Shared         |
 * |        |            |          |           |               |
 * | Normal |     Shared | Secure   |Normal     |Secure         |
 * --------------------------------------------------------------
 *
 * Life cycle of a VM
 * --------------------
 *
 * --------------------------------------------------------------------
 * |         |  start    |  H_SVM_  |H_SVM_   |H_SVM_     |UV_SVM_    |
 * |         |  VM       |INIT_START|INIT_DONE|INIT_ABORT |TERMINATE  |
 * |         |           |          |         |           |           |
 * --------- ----------------------------------------------------------
 * |         |           |          |         |           |           |
 * | Normal  | Normal    | Transient|Error    |Error      |Normal     |
 * |         |           |          |         |           |           |
 * | Secure  |   Error   | Error    |Error    |Error      |Normal     |
 * |         |           |          |         |           |           |
 * |Transient|   N/A     | Error    |Secure   |Normal     |Normal     |
 * --------------------------------------------------------------------
 */

#define KVMPPC_GFN_UVMEM_PFN	(1UL << 63)
#define KVMPPC_GFN_MEM_PFN	(1UL << 62)
#define KVMPPC_GFN_SHARED	(1UL << 61)
#define KVMPPC_GFN_SECURE	(KVMPPC_GFN_UVMEM_PFN | KVMPPC_GFN_MEM_PFN)
#define KVMPPC_GFN_FLAG_MASK	(KVMPPC_GFN_SECURE | KVMPPC_GFN_SHARED)
#define KVMPPC_GFN_PFN_MASK	(~KVMPPC_GFN_FLAG_MASK)

struct kvmppc_uvmem_slot {
	struct list_head list;
	unsigned long nr_pfns;
	unsigned long base_pfn;
	unsigned long *pfns;
};
struct kvmppc_uvmem_page_pvt {
	struct kvm *kvm;
	unsigned long gpa;
	bool skip_page_out;
	bool remove_gfn;
};

bool kvmppc_uvmem_available(void)
{
	/*
	 * If kvmppc_uvmem_bitmap != NULL, then there is an ultravisor
	 * and our data structures have been initialized successfully.
	 */
	return !!kvmppc_uvmem_bitmap;
}

int kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot)
{
	struct kvmppc_uvmem_slot *p;

	p = kzalloc(sizeof(*p), GFP_KERNEL);
	if (!p)
		return -ENOMEM;
	p->pfns = vcalloc(slot->npages, sizeof(*p->pfns));
	if (!p->pfns) {
		kfree(p);
		return -ENOMEM;
	}
	p->nr_pfns = slot->npages;
	p->base_pfn = slot->base_gfn;

	mutex_lock(&kvm->arch.uvmem_lock);
	list_add(&p->list, &kvm->arch.uvmem_pfns);
	mutex_unlock(&kvm->arch.uvmem_lock);

	return 0;
}

/*
 * All device PFNs are already released by the time we come here.
 */
void kvmppc_uvmem_slot_free(struct kvm *kvm, const struct kvm_memory_slot *slot)
{
	struct kvmppc_uvmem_slot *p, *next;

	mutex_lock(&kvm->arch.uvmem_lock);
	list_for_each_entry_safe(p, next, &kvm->arch.uvmem_pfns, list) {
		if (p->base_pfn == slot->base_gfn) {
			vfree(p->pfns);
			list_del(&p->list);
			kfree(p);
			break;
		}
	}
	mutex_unlock(&kvm->arch.uvmem_lock);
}

static void kvmppc_mark_gfn(unsigned long gfn, struct kvm *kvm,
			unsigned long flag, unsigned long uvmem_pfn)
{
	struct kvmppc_uvmem_slot *p;

	list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) {
		if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) {
			unsigned long index = gfn - p->base_pfn;

			if (flag == KVMPPC_GFN_UVMEM_PFN)
				p->pfns[index] = uvmem_pfn | flag;
			else
				p->pfns[index] = flag;
			return;
		}
	}
}

/* mark the GFN as secure-GFN associated with @uvmem pfn device-PFN. */
static void kvmppc_gfn_secure_uvmem_pfn(unsigned long gfn,
			unsigned long uvmem_pfn, struct kvm *kvm)
{
	kvmppc_mark_gfn(gfn, kvm, KVMPPC_GFN_UVMEM_PFN, uvmem_pfn);
}

/* mark the GFN as secure-GFN associated with a memory-PFN. */
static void kvmppc_gfn_secure_mem_pfn(unsigned long gfn, struct kvm *kvm)
{
	kvmppc_mark_gfn(gfn, kvm, KVMPPC_GFN_MEM_PFN, 0);
}

/* mark the GFN as a shared GFN. */
static void kvmppc_gfn_shared(unsigned long gfn, struct kvm *kvm)
{
	kvmppc_mark_gfn(gfn, kvm, KVMPPC_GFN_SHARED, 0);
}

/* mark the GFN as a non-existent GFN. */
static void kvmppc_gfn_remove(unsigned long gfn, struct kvm *kvm)
{
	kvmppc_mark_gfn(gfn, kvm, 0, 0);
}

/* return true, if the GFN is a secure-GFN backed by a secure-PFN */
static bool kvmppc_gfn_is_uvmem_pfn(unsigned long gfn, struct kvm *kvm,
				    unsigned long *uvmem_pfn)
{
	struct kvmppc_uvmem_slot *p;

	list_for_each_entry(p, &kvm->arch.uvmem_pfns, list) {
		if (gfn >= p->base_pfn && gfn < p->base_pfn + p->nr_pfns) {
			unsigned long index = gfn - p->base_pfn;

			if (p->pfns[index] & KVMPPC_GFN_UVMEM_PFN) {
				if (uvmem_pfn)
					*uvmem_pfn = p->pfns[index] &
						     KVMPPC_GFN_PFN_MASK;
				return true;
			} else
				return false;
		}
	}
	return false;
}

/*
 * starting from *gfn search for the next available GFN that is not yet
 * transitioned to a secure GFN.  return the value of that GFN in *gfn.  If a
 * GFN is found, return true, else return false
 *
 * Must be called with kvm->arch.uvmem_lock  held.
 */
static bool kvmppc_next_nontransitioned_gfn(const struct kvm_memory_slot *memslot,
		struct kvm *kvm, unsigned long *gfn)
{
	struct kvmppc_uvmem_slot *p = NULL, *iter;
	bool ret = false;
	unsigned long i;

	list_for_each_entry(iter, &kvm->arch.uvmem_pfns, list)
		if (*gfn >= iter->base_pfn && *gfn < iter->base_pfn + iter->nr_pfns) {
			p = iter;
			break;
		}
	if (!p)
		return ret;
	/*
	 * The code below assumes, one to one correspondence between
	 * kvmppc_uvmem_slot and memslot.
	 */
	for (i = *gfn; i < p->base_pfn + p->nr_pfns; i++) {
		unsigned long index = i - p->base_pfn;

		if (!(p->pfns[index] & KVMPPC_GFN_FLAG_MASK)) {
			*gfn = i;
			ret = true;
			break;
		}
	}
	return ret;
}

static int kvmppc_memslot_page_merge(struct kvm *kvm,
		const struct kvm_memory_slot *memslot, bool merge)
{
	unsigned long gfn = memslot->base_gfn;
	unsigned long end, start = gfn_to_hva(kvm, gfn);
	unsigned long vm_flags;
	int ret = 0;
	struct vm_area_struct *vma;
	int merge_flag = (merge) ? MADV_MERGEABLE : MADV_UNMERGEABLE;

	if (kvm_is_error_hva(start))
		return H_STATE;

	end = start + (memslot->npages << PAGE_SHIFT);

	mmap_write_lock(kvm->mm);
	do {
		vma = find_vma_intersection(kvm->mm, start, end);
		if (!vma) {
			ret = H_STATE;
			break;
		}
		vma_start_write(vma);
		/* Copy vm_flags to avoid partial modifications in ksm_madvise */
		vm_flags = vma->vm_flags;
		ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
			  merge_flag, &vm_flags);
		if (ret) {
			ret = H_STATE;
			break;
		}
		vm_flags_reset(vma, vm_flags);
		start = vma->vm_end;
	} while (end > vma->vm_end);

	mmap_write_unlock(kvm->mm);
	return ret;
}

static void __kvmppc_uvmem_memslot_delete(struct kvm *kvm,
		const struct kvm_memory_slot *memslot)
{
	uv_unregister_mem_slot(kvm->arch.lpid, memslot->id);
	kvmppc_uvmem_slot_free(kvm, memslot);
	kvmppc_memslot_page_merge(kvm, memslot, true);
}

static int __kvmppc_uvmem_memslot_create(struct kvm *kvm,
		const struct kvm_memory_slot *memslot)
{
	int ret = H_PARAMETER;

	if (kvmppc_memslot_page_merge(kvm, memslot, false))
		return ret;

	if (kvmppc_uvmem_slot_init(kvm, memslot))
		goto out1;

	ret = uv_register_mem_slot(kvm->arch.lpid,
				   memslot->base_gfn << PAGE_SHIFT,
				   memslot->npages * PAGE_SIZE,
				   0, memslot->id);
	if (ret < 0) {
		ret = H_PARAMETER;
		goto out;
	}
	return 0;
out:
	kvmppc_uvmem_slot_free(kvm, memslot);
out1:
	kvmppc_memslot_page_merge(kvm, memslot, true);
	return ret;
}

unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
{
	struct kvm_memslots *slots;
	struct kvm_memory_slot *memslot, *m;
	int ret = H_SUCCESS;
	int srcu_idx, bkt;

	kvm->arch.secure_guest = KVMPPC_SECURE_INIT_START;

	if (!kvmppc_uvmem_bitmap)
		return H_UNSUPPORTED;

	/* Only radix guests can be secure guests */
	if (!kvm_is_radix(kvm))
		return H_UNSUPPORTED;

	/* NAK the transition to secure if not enabled */
	if (!kvm->arch.svm_enabled)
		return H_AUTHORITY;

	srcu_idx = srcu_read_lock(&kvm->srcu);

	/* register the memslot */
	slots = kvm_memslots(kvm);
	kvm_for_each_memslot(memslot, bkt, slots) {
		ret = __kvmppc_uvmem_memslot_create(kvm, memslot);
		if (ret)
			break;
	}

	if (ret) {
		slots = kvm_memslots(kvm);
		kvm_for_each_memslot(m, bkt, slots) {
			if (m == memslot)
				break;
			__kvmppc_uvmem_memslot_delete(kvm, memslot);
		}
	}

	srcu_read_unlock(&kvm->srcu, srcu_idx);
	return ret;
}

/*
 * Provision a new page on HV side and copy over the contents
 * from secure memory using UV_PAGE_OUT uvcall.
 * Caller must held kvm->arch.uvmem_lock.
 */
static int __kvmppc_svm_page_out(struct vm_area_struct *vma,
		unsigned long start,
		unsigned long end, unsigned long page_shift,
		struct kvm *kvm, unsigned long gpa, struct page *fault_page)
{
	unsigned long src_pfn, dst_pfn = 0;
	struct migrate_vma mig = { 0 };
	struct page *dpage, *spage;
	struct kvmppc_uvmem_page_pvt *pvt;
	unsigned long pfn;
	int ret = U_SUCCESS;

	memset(&mig, 0, sizeof(mig));
	mig.vma = vma;
	mig.start = start;
	mig.end = end;
	mig.src = &src_pfn;
	mig.dst = &dst_pfn;
	mig.pgmap_owner = &kvmppc_uvmem_pgmap;
	mig.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
	mig.fault_page = fault_page;

	/* The requested page is already paged-out, nothing to do */
	if (!kvmppc_gfn_is_uvmem_pfn(gpa >> page_shift, kvm, NULL))
		return ret;

	ret = migrate_vma_setup(&mig);
	if (ret)
		return -1;

	spage = migrate_pfn_to_page(*mig.src);
	if (!spage || !(*mig.src & MIGRATE_PFN_MIGRATE))
		goto out_finalize;

	if (!is_zone_device_page(spage))
		goto out_finalize;

	dpage = alloc_page_vma(GFP_HIGHUSER, vma, start);
	if (!dpage) {
		ret = -1;
		goto out_finalize;
	}

	lock_page(dpage);
	pvt = spage->zone_device_data;
	pfn = page_to_pfn(dpage);

	/*
	 * This function is used in two cases:
	 * - When HV touches a secure page, for which we do UV_PAGE_OUT
	 * - When a secure page is converted to shared page, we *get*
	 *   the page to essentially unmap the device page. In this
	 *   case we skip page-out.
	 */
	if (!pvt->skip_page_out)
		ret = uv_page_out(kvm->arch.lpid, pfn << page_shift,
				  gpa, 0, page_shift);

	if (ret == U_SUCCESS)
		*mig.dst = migrate_pfn(pfn);
	else {
		unlock_page(dpage);
		__free_page(dpage);
		goto out_finalize;
	}

	migrate_vma_pages(&mig);

out_finalize:
	migrate_vma_finalize(&mig);
	return ret;
}

static inline int kvmppc_svm_page_out(struct vm_area_struct *vma,
				      unsigned long start, unsigned long end,
				      unsigned long page_shift,
				      struct kvm *kvm, unsigned long gpa,
				      struct page *fault_page)
{
	int ret;

	mutex_lock(&kvm->arch.uvmem_lock);
	ret = __kvmppc_svm_page_out(vma, start, end, page_shift, kvm, gpa,
				fault_page);
	mutex_unlock(&kvm->arch.uvmem_lock);

	return ret;
}

/*
 * Drop device pages that we maintain for the secure guest
 *
 * We first mark the pages to be skipped from UV_PAGE_OUT when there
 * is HV side fault on these pages. Next we *get* these pages, forcing
 * fault on them, do fault time migration to replace the device PTEs in
 * QEMU page table with normal PTEs from newly allocated pages.
 */
void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *slot,
			     struct kvm *kvm, bool skip_page_out)
{
	int i;
	struct kvmppc_uvmem_page_pvt *pvt;
	struct page *uvmem_page;
	struct vm_area_struct *vma = NULL;
	unsigned long uvmem_pfn, gfn;
	unsigned long addr;

	mmap_read_lock(kvm->mm);

	addr = slot->userspace_addr;

	gfn = slot->base_gfn;
	for (i = slot->npages; i; --i, ++gfn, addr += PAGE_SIZE) {

		/* Fetch the VMA if addr is not in the latest fetched one */
		if (!vma || addr >= vma->vm_end) {
			vma = vma_lookup(kvm->mm, addr);
			if (!vma) {
				pr_err("Can't find VMA for gfn:0x%lx\n", gfn);
				break;
			}
		}

		mutex_lock(&kvm->arch.uvmem_lock);

		if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) {
			uvmem_page = pfn_to_page(uvmem_pfn);
			pvt = uvmem_page->zone_device_data;
			pvt->skip_page_out = skip_page_out;
			pvt->remove_gfn = true;

			if (__kvmppc_svm_page_out(vma, addr, addr + PAGE_SIZE,
						  PAGE_SHIFT, kvm, pvt->gpa, NULL))
				pr_err("Can't page out gpa:0x%lx addr:0x%lx\n",
				       pvt->gpa, addr);
		} else {
			/* Remove the shared flag if any */
			kvmppc_gfn_remove(gfn, kvm);
		}

		mutex_unlock(&kvm->arch.uvmem_lock);
	}

	mmap_read_unlock(kvm->mm);
}

unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm)
{
	int srcu_idx, bkt;
	struct kvm_memory_slot *memslot;

	/*
	 * Expect to be called only after INIT_START and before INIT_DONE.
	 * If INIT_DONE was completed, use normal VM termination sequence.
	 */
	if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
		return H_UNSUPPORTED;

	if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
		return H_STATE;

	srcu_idx = srcu_read_lock(&kvm->srcu);

	kvm_for_each_memslot(memslot, bkt, kvm_memslots(kvm))
		kvmppc_uvmem_drop_pages(memslot, kvm, false);

	srcu_read_unlock(&kvm->srcu, srcu_idx);

	kvm->arch.secure_guest = 0;
	uv_svm_terminate(kvm->arch.lpid);

	return H_PARAMETER;
}

/*
 * Get a free device PFN from the pool
 *
 * Called when a normal page is moved to secure memory (UV_PAGE_IN). Device
 * PFN will be used to keep track of the secure page on HV side.
 *
 * Called with kvm->arch.uvmem_lock held
 */
static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm)
{
	struct page *dpage = NULL;
	unsigned long bit, uvmem_pfn;
	struct kvmppc_uvmem_page_pvt *pvt;
	unsigned long pfn_last, pfn_first;

	pfn_first = kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT;
	pfn_last = pfn_first +
		   (range_len(&kvmppc_uvmem_pgmap.range) >> PAGE_SHIFT);

	spin_lock(&kvmppc_uvmem_bitmap_lock);
	bit = find_first_zero_bit(kvmppc_uvmem_bitmap,
				  pfn_last - pfn_first);
	if (bit >= (pfn_last - pfn_first))
		goto out;
	bitmap_set(kvmppc_uvmem_bitmap, bit, 1);
	spin_unlock(&kvmppc_uvmem_bitmap_lock);

	pvt = kzalloc(sizeof(*pvt), GFP_KERNEL);
	if (!pvt)
		goto out_clear;

	uvmem_pfn = bit + pfn_first;
	kvmppc_gfn_secure_uvmem_pfn(gpa >> PAGE_SHIFT, uvmem_pfn, kvm);

	pvt->gpa = gpa;
	pvt->kvm = kvm;

	dpage = pfn_to_page(uvmem_pfn);
	dpage->zone_device_data = pvt;
	zone_device_page_init(dpage);
	return dpage;
out_clear:
	spin_lock(&kvmppc_uvmem_bitmap_lock);
	bitmap_clear(kvmppc_uvmem_bitmap, bit, 1);
out:
	spin_unlock(&kvmppc_uvmem_bitmap_lock);
	return NULL;
}

/*
 * Alloc a PFN from private device memory pool. If @pagein is true,
 * copy page from normal memory to secure memory using UV_PAGE_IN uvcall.
 */
static int kvmppc_svm_page_in(struct vm_area_struct *vma,
		unsigned long start,
		unsigned long end, unsigned long gpa, struct kvm *kvm,
		unsigned long page_shift,
		bool pagein)
{
	unsigned long src_pfn, dst_pfn = 0;
	struct migrate_vma mig = { 0 };
	struct page *spage;
	unsigned long pfn;
	struct page *dpage;
	int ret = 0;

	memset(&mig, 0, sizeof(mig));
	mig.vma = vma;
	mig.start = start;
	mig.end = end;
	mig.src = &src_pfn;
	mig.dst = &dst_pfn;
	mig.flags = MIGRATE_VMA_SELECT_SYSTEM;

	ret = migrate_vma_setup(&mig);
	if (ret)
		return ret;

	if (!(*mig.src & MIGRATE_PFN_MIGRATE)) {
		ret = -1;
		goto out_finalize;
	}

	dpage = kvmppc_uvmem_get_page(gpa, kvm);
	if (!dpage) {
		ret = -1;
		goto out_finalize;
	}

	if (pagein) {
		pfn = *mig.src >> MIGRATE_PFN_SHIFT;
		spage = migrate_pfn_to_page(*mig.src);
		if (spage) {
			ret = uv_page_in(kvm->arch.lpid, pfn << page_shift,
					gpa, 0, page_shift);
			if (ret)
				goto out_finalize;
		}
	}

	*mig.dst = migrate_pfn(page_to_pfn(dpage));
	migrate_vma_pages(&mig);
out_finalize:
	migrate_vma_finalize(&mig);
	return ret;
}

static int kvmppc_uv_migrate_mem_slot(struct kvm *kvm,
		const struct kvm_memory_slot *memslot)
{
	unsigned long gfn = memslot->base_gfn;
	struct vm_area_struct *vma;
	unsigned long start, end;
	int ret = 0;

	mmap_read_lock(kvm->mm);
	mutex_lock(&kvm->arch.uvmem_lock);
	while (kvmppc_next_nontransitioned_gfn(memslot, kvm, &gfn)) {
		ret = H_STATE;
		start = gfn_to_hva(kvm, gfn);
		if (kvm_is_error_hva(start))
			break;

		end = start + (1UL << PAGE_SHIFT);
		vma = find_vma_intersection(kvm->mm, start, end);
		if (!vma || vma->vm_start > start || vma->vm_end < end)
			break;

		ret = kvmppc_svm_page_in(vma, start, end,
				(gfn << PAGE_SHIFT), kvm, PAGE_SHIFT, false);
		if (ret) {
			ret = H_STATE;
			break;
		}

		/* relinquish the cpu if needed */
		cond_resched();
	}
	mutex_unlock(&kvm->arch.uvmem_lock);
	mmap_read_unlock(kvm->mm);
	return ret;
}

unsigned long kvmppc_h_svm_init_done(struct kvm *kvm)
{
	struct kvm_memslots *slots;
	struct kvm_memory_slot *memslot;
	int srcu_idx, bkt;
	long ret = H_SUCCESS;

	if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
		return H_UNSUPPORTED;

	/* migrate any unmoved normal pfn to device pfns*/
	srcu_idx = srcu_read_lock(&kvm->srcu);
	slots = kvm_memslots(kvm);
	kvm_for_each_memslot(memslot, bkt, slots) {
		ret = kvmppc_uv_migrate_mem_slot(kvm, memslot);
		if (ret) {
			/*
			 * The pages will remain transitioned.
			 * Its the callers responsibility to
			 * terminate the VM, which will undo
			 * all state of the VM. Till then
			 * this VM is in a erroneous state.
			 * Its KVMPPC_SECURE_INIT_DONE will
			 * remain unset.
			 */
			ret = H_STATE;
			goto out;
		}
	}

	kvm->arch.secure_guest |= KVMPPC_SECURE_INIT_DONE;
	pr_info("LPID %lld went secure\n", kvm->arch.lpid);

out:
	srcu_read_unlock(&kvm->srcu, srcu_idx);
	return ret;
}

/*
 * Shares the page with HV, thus making it a normal page.
 *
 * - If the page is already secure, then provision a new page and share
 * - If the page is a normal page, share the existing page
 *
 * In the former case, uses dev_pagemap_ops.migrate_to_ram handler
 * to unmap the device page from QEMU's page tables.
 */
static unsigned long kvmppc_share_page(struct kvm *kvm, unsigned long gpa,
		unsigned long page_shift)
{

	int ret = H_PARAMETER;
	struct page *uvmem_page;
	struct kvmppc_uvmem_page_pvt *pvt;
	unsigned long pfn;
	unsigned long gfn = gpa >> page_shift;
	int srcu_idx;
	unsigned long uvmem_pfn;

	srcu_idx = srcu_read_lock(&kvm->srcu);
	mutex_lock(&kvm->arch.uvmem_lock);
	if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) {
		uvmem_page = pfn_to_page(uvmem_pfn);
		pvt = uvmem_page->zone_device_data;
		pvt->skip_page_out = true;
		/*
		 * do not drop the GFN. It is a valid GFN
		 * that is transitioned to a shared GFN.
		 */
		pvt->remove_gfn = false;
	}

retry:
	mutex_unlock(&kvm->arch.uvmem_lock);
	pfn = gfn_to_pfn(kvm, gfn);
	if (is_error_noslot_pfn(pfn))
		goto out;

	mutex_lock(&kvm->arch.uvmem_lock);
	if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, &uvmem_pfn)) {
		uvmem_page = pfn_to_page(uvmem_pfn);
		pvt = uvmem_page->zone_device_data;
		pvt->skip_page_out = true;
		pvt->remove_gfn = false; /* it continues to be a valid GFN */
		kvm_release_pfn_clean(pfn);
		goto retry;
	}

	if (!uv_page_in(kvm->arch.lpid, pfn << page_shift, gpa, 0,
				page_shift)) {
		kvmppc_gfn_shared(gfn, kvm);
		ret = H_SUCCESS;
	}
	kvm_release_pfn_clean(pfn);
	mutex_unlock(&kvm->arch.uvmem_lock);
out:
	srcu_read_unlock(&kvm->srcu, srcu_idx);
	return ret;
}

/*
 * H_SVM_PAGE_IN: Move page from normal memory to secure memory.
 *
 * H_PAGE_IN_SHARED flag makes the page shared which means that the same
 * memory in is visible from both UV and HV.
 */
unsigned long kvmppc_h_svm_page_in(struct kvm *kvm, unsigned long gpa,
		unsigned long flags,
		unsigned long page_shift)
{
	unsigned long start, end;
	struct vm_area_struct *vma;
	int srcu_idx;
	unsigned long gfn = gpa >> page_shift;
	int ret;

	if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
		return H_UNSUPPORTED;

	if (page_shift != PAGE_SHIFT)
		return H_P3;

	if (flags & ~H_PAGE_IN_SHARED)
		return H_P2;

	if (flags & H_PAGE_IN_SHARED)
		return kvmppc_share_page(kvm, gpa, page_shift);

	ret = H_PARAMETER;
	srcu_idx = srcu_read_lock(&kvm->srcu);
	mmap_read_lock(kvm->mm);

	start = gfn_to_hva(kvm, gfn);
	if (kvm_is_error_hva(start))
		goto out;

	mutex_lock(&kvm->arch.uvmem_lock);
	/* Fail the page-in request of an already paged-in page */
	if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL))
		goto out_unlock;

	end = start + (1UL << page_shift);
	vma = find_vma_intersection(kvm->mm, start, end);
	if (!vma || vma->vm_start > start || vma->vm_end < end)
		goto out_unlock;

	if (kvmppc_svm_page_in(vma, start, end, gpa, kvm, page_shift,
				true))
		goto out_unlock;

	ret = H_SUCCESS;

out_unlock:
	mutex_unlock(&kvm->arch.uvmem_lock);
out:
	mmap_read_unlock(kvm->mm);
	srcu_read_unlock(&kvm->srcu, srcu_idx);
	return ret;
}


/*
 * Fault handler callback that gets called when HV touches any page that
 * has been moved to secure memory, we ask UV to give back the page by
 * issuing UV_PAGE_OUT uvcall.
 *
 * This eventually results in dropping of device PFN and the newly
 * provisioned page/PFN gets populated in QEMU page tables.
 */
static vm_fault_t kvmppc_uvmem_migrate_to_ram(struct vm_fault *vmf)
{
	struct kvmppc_uvmem_page_pvt *pvt = vmf->page->zone_device_data;

	if (kvmppc_svm_page_out(vmf->vma, vmf->address,
				vmf->address + PAGE_SIZE, PAGE_SHIFT,
				pvt->kvm, pvt->gpa, vmf->page))
		return VM_FAULT_SIGBUS;
	else
		return 0;
}

/*
 * Release the device PFN back to the pool
 *
 * Gets called when secure GFN tranistions from a secure-PFN
 * to a normal PFN during H_SVM_PAGE_OUT.
 * Gets called with kvm->arch.uvmem_lock held.
 */
static void kvmppc_uvmem_page_free(struct page *page)
{
	unsigned long pfn = page_to_pfn(page) -
			(kvmppc_uvmem_pgmap.range.start >> PAGE_SHIFT);
	struct kvmppc_uvmem_page_pvt *pvt;

	spin_lock(&kvmppc_uvmem_bitmap_lock);
	bitmap_clear(kvmppc_uvmem_bitmap, pfn, 1);
	spin_unlock(&kvmppc_uvmem_bitmap_lock);

	pvt = page->zone_device_data;
	page->zone_device_data = NULL;
	if (pvt->remove_gfn)
		kvmppc_gfn_remove(pvt->gpa >> PAGE_SHIFT, pvt->kvm);
	else
		kvmppc_gfn_secure_mem_pfn(pvt->gpa >> PAGE_SHIFT, pvt->kvm);
	kfree(pvt);
}

static const struct dev_pagemap_ops kvmppc_uvmem_ops = {
	.page_free = kvmppc_uvmem_page_free,
	.migrate_to_ram	= kvmppc_uvmem_migrate_to_ram,
};

/*
 * H_SVM_PAGE_OUT: Move page from secure memory to normal memory.
 */
unsigned long
kvmppc_h_svm_page_out(struct kvm *kvm, unsigned long gpa,
		      unsigned long flags, unsigned long page_shift)
{
	unsigned long gfn = gpa >> page_shift;
	unsigned long start, end;
	struct vm_area_struct *vma;
	int srcu_idx;
	int ret;

	if (!(kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START))
		return H_UNSUPPORTED;

	if (page_shift != PAGE_SHIFT)
		return H_P3;

	if (flags)
		return H_P2;

	ret = H_PARAMETER;
	srcu_idx = srcu_read_lock(&kvm->srcu);
	mmap_read_lock(kvm->mm);
	start = gfn_to_hva(kvm, gfn);
	if (kvm_is_error_hva(start))
		goto out;

	end = start + (1UL << page_shift);
	vma = find_vma_intersection(kvm->mm, start, end);
	if (!vma || vma->vm_start > start || vma->vm_end < end)
		goto out;

	if (!kvmppc_svm_page_out(vma, start, end, page_shift, kvm, gpa, NULL))
		ret = H_SUCCESS;
out:
	mmap_read_unlock(kvm->mm);
	srcu_read_unlock(&kvm->srcu, srcu_idx);
	return ret;
}

int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
{
	unsigned long pfn;
	int ret = U_SUCCESS;

	pfn = gfn_to_pfn(kvm, gfn);
	if (is_error_noslot_pfn(pfn))
		return -EFAULT;

	mutex_lock(&kvm->arch.uvmem_lock);
	if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL))
		goto out;

	ret = uv_page_in(kvm->arch.lpid, pfn << PAGE_SHIFT, gfn << PAGE_SHIFT,
			 0, PAGE_SHIFT);
out:
	kvm_release_pfn_clean(pfn);
	mutex_unlock(&kvm->arch.uvmem_lock);
	return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT;
}

int kvmppc_uvmem_memslot_create(struct kvm *kvm, const struct kvm_memory_slot *new)
{
	int ret = __kvmppc_uvmem_memslot_create(kvm, new);

	if (!ret)
		ret = kvmppc_uv_migrate_mem_slot(kvm, new);

	return ret;
}

void kvmppc_uvmem_memslot_delete(struct kvm *kvm, const struct kvm_memory_slot *old)
{
	__kvmppc_uvmem_memslot_delete(kvm, old);
}

static u64 kvmppc_get_secmem_size(void)
{
	struct device_node *np;
	int i, len;
	const __be32 *prop;
	u64 size = 0;

	/*
	 * First try the new ibm,secure-memory nodes which supersede the
	 * secure-memory-ranges property.
	 * If we found some, no need to read the deprecated ones.
	 */
	for_each_compatible_node(np, NULL, "ibm,secure-memory") {
		prop = of_get_property(np, "reg", &len);
		if (!prop)
			continue;
		size += of_read_number(prop + 2, 2);
	}
	if (size)
		return size;

	np = of_find_compatible_node(NULL, NULL, "ibm,uv-firmware");
	if (!np)
		goto out;

	prop = of_get_property(np, "secure-memory-ranges", &len);
	if (!prop)
		goto out_put;

	for (i = 0; i < len / (sizeof(*prop) * 4); i++)
		size += of_read_number(prop + (i * 4) + 2, 2);

out_put:
	of_node_put(np);
out:
	return size;
}

int kvmppc_uvmem_init(void)
{
	int ret = 0;
	unsigned long size;
	struct resource *res;
	void *addr;
	unsigned long pfn_last, pfn_first;

	size = kvmppc_get_secmem_size();
	if (!size) {
		/*
		 * Don't fail the initialization of kvm-hv module if
		 * the platform doesn't export ibm,uv-firmware node.
		 * Let normal guests run on such PEF-disabled platform.
		 */
		pr_info("KVMPPC-UVMEM: No support for secure guests\n");
		goto out;
	}

	res = request_free_mem_region(&iomem_resource, size, "kvmppc_uvmem");
	if (IS_ERR(res)) {
		ret = PTR_ERR(res);
		goto out;
	}

	kvmppc_uvmem_pgmap.type = MEMORY_DEVICE_PRIVATE;
	kvmppc_uvmem_pgmap.range.start = res->start;
	kvmppc_uvmem_pgmap.range.end = res->end;
	kvmppc_uvmem_pgmap.nr_range = 1;
	kvmppc_uvmem_pgmap.ops = &kvmppc_uvmem_ops;
	/* just one global instance: */
	kvmppc_uvmem_pgmap.owner = &kvmppc_uvmem_pgmap;
	addr = memremap_pages(&kvmppc_uvmem_pgmap, NUMA_NO_NODE);
	if (IS_ERR(addr)) {
		ret = PTR_ERR(addr);
		goto out_free_region;
	}

	pfn_first = res->start >> PAGE_SHIFT;
	pfn_last = pfn_first + (resource_size(res) >> PAGE_SHIFT);
	kvmppc_uvmem_bitmap = bitmap_zalloc(pfn_last - pfn_first, GFP_KERNEL);
	if (!kvmppc_uvmem_bitmap) {
		ret = -ENOMEM;
		goto out_unmap;
	}

	pr_info("KVMPPC-UVMEM: Secure Memory size 0x%lx\n", size);
	return ret;
out_unmap:
	memunmap_pages(&kvmppc_uvmem_pgmap);
out_free_region:
	release_mem_region(res->start, size);
out:
	return ret;
}

void kvmppc_uvmem_free(void)
{
	if (!kvmppc_uvmem_bitmap)
		return;

	memunmap_pages(&kvmppc_uvmem_pgmap);
	release_mem_region(kvmppc_uvmem_pgmap.range.start,
			   range_len(&kvmppc_uvmem_pgmap.range));
	bitmap_free(kvmppc_uvmem_bitmap);
}
