// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
 */

#include <linux/highmem.h>
#include <linux/hugetlb.h>
#include <linux/kvm_host.h>
#include <linux/page-flags.h>
#include <linux/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/kvm_mmu.h>

static inline bool kvm_hugepage_capable(struct kvm_memory_slot *slot)
{
	return slot->arch.flags & KVM_MEM_HUGEPAGE_CAPABLE;
}

static inline bool kvm_hugepage_incapable(struct kvm_memory_slot *slot)
{
	return slot->arch.flags & KVM_MEM_HUGEPAGE_INCAPABLE;
}

static inline void kvm_ptw_prepare(struct kvm *kvm, kvm_ptw_ctx *ctx)
{
	ctx->level = kvm->arch.root_level;
	/* pte table */
	ctx->invalid_ptes  = kvm->arch.invalid_ptes;
	ctx->pte_shifts    = kvm->arch.pte_shifts;
	ctx->pgtable_shift = ctx->pte_shifts[ctx->level];
	ctx->invalid_entry = ctx->invalid_ptes[ctx->level];
	ctx->opaque        = kvm;
}

/*
 * Mark a range of guest physical address space old (all accesses fault) in the
 * VM's GPA page table to allow detection of commonly used pages.
 */
static int kvm_mkold_pte(kvm_pte_t *pte, phys_addr_t addr, kvm_ptw_ctx *ctx)
{
	if (kvm_pte_young(*pte)) {
		*pte = kvm_pte_mkold(*pte);
		return 1;
	}

	return 0;
}

/*
 * Mark a range of guest physical address space clean (writes fault) in the VM's
 * GPA page table to allow dirty page tracking.
 */
static int kvm_mkclean_pte(kvm_pte_t *pte, phys_addr_t addr, kvm_ptw_ctx *ctx)
{
	gfn_t offset;
	kvm_pte_t val;

	val = *pte;
	/*
	 * For kvm_arch_mmu_enable_log_dirty_pt_masked with mask, start and end
	 * may cross hugepage, for first huge page parameter addr is equal to
	 * start, however for the second huge page addr is base address of
	 * this huge page, rather than start or end address
	 */
	if ((ctx->flag & _KVM_HAS_PGMASK) && !kvm_pte_huge(val)) {
		offset = (addr >> PAGE_SHIFT) - ctx->gfn;
		if (!(BIT(offset) & ctx->mask))
			return 0;
	}

	/*
	 * Need not split huge page now, just set write-proect pte bit
	 * Split huge page until next write fault
	 */
	if (kvm_pte_dirty(val)) {
		*pte = kvm_pte_mkclean(val);
		return 1;
	}

	return 0;
}

/*
 * Clear pte entry
 */
static int kvm_flush_pte(kvm_pte_t *pte, phys_addr_t addr, kvm_ptw_ctx *ctx)
{
	struct kvm *kvm;

	kvm = ctx->opaque;
	if (ctx->level)
		kvm->stat.hugepages--;
	else
		kvm->stat.pages--;

	*pte = ctx->invalid_entry;

	return 1;
}

/*
 * kvm_pgd_alloc() - Allocate and initialise a KVM GPA page directory.
 *
 * Allocate a blank KVM GPA page directory (PGD) for representing guest physical
 * to host physical page mappings.
 *
 * Returns:	Pointer to new KVM GPA page directory.
 *		NULL on allocation failure.
 */
kvm_pte_t *kvm_pgd_alloc(void)
{
	kvm_pte_t *pgd;

	pgd = (kvm_pte_t *)__get_free_pages(GFP_KERNEL, 0);
	if (pgd)
		pgd_init((void *)pgd);

	return pgd;
}

static void _kvm_pte_init(void *addr, unsigned long val)
{
	unsigned long *p, *end;

	p = (unsigned long *)addr;
	end = p + PTRS_PER_PTE;
	do {
		p[0] = val;
		p[1] = val;
		p[2] = val;
		p[3] = val;
		p[4] = val;
		p += 8;
		p[-3] = val;
		p[-2] = val;
		p[-1] = val;
	} while (p != end);
}

/*
 * Caller must hold kvm->mm_lock
 *
 * Walk the page tables of kvm to find the PTE corresponding to the
 * address @addr. If page tables don't exist for @addr, they will be created
 * from the MMU cache if @cache is not NULL.
 */
static kvm_pte_t *kvm_populate_gpa(struct kvm *kvm,
				struct kvm_mmu_memory_cache *cache,
				unsigned long addr, int level)
{
	kvm_ptw_ctx ctx;
	kvm_pte_t *entry, *child;

	kvm_ptw_prepare(kvm, &ctx);
	child = kvm->arch.pgd;
	while (ctx.level > level) {
		entry = kvm_pgtable_offset(&ctx, child, addr);
		if (kvm_pte_none(&ctx, entry)) {
			if (!cache)
				return NULL;

			child = kvm_mmu_memory_cache_alloc(cache);
			_kvm_pte_init(child, ctx.invalid_ptes[ctx.level - 1]);
			kvm_set_pte(entry, __pa(child));
		} else if (kvm_pte_huge(*entry)) {
			return entry;
		} else
			child = (kvm_pte_t *)__va(PHYSADDR(*entry));
		kvm_ptw_enter(&ctx);
	}

	entry = kvm_pgtable_offset(&ctx, child, addr);

	return entry;
}

/*
 * Page walker for VM shadow mmu at last level
 * The last level is small pte page or huge pmd page
 */
static int kvm_ptw_leaf(kvm_pte_t *dir, phys_addr_t addr, phys_addr_t end, kvm_ptw_ctx *ctx)
{
	int ret;
	phys_addr_t next, start, size;
	struct list_head *list;
	kvm_pte_t *entry, *child;

	ret = 0;
	start = addr;
	child = (kvm_pte_t *)__va(PHYSADDR(*dir));
	entry = kvm_pgtable_offset(ctx, child, addr);
	do {
		next = addr + (0x1UL << ctx->pgtable_shift);
		if (!kvm_pte_present(ctx, entry))
			continue;

		ret |= ctx->ops(entry, addr, ctx);
	} while (entry++, addr = next, addr < end);

	if (kvm_need_flush(ctx)) {
		size = 0x1UL << (ctx->pgtable_shift + PAGE_SHIFT - 3);
		if (start + size == end) {
			list = (struct list_head *)child;
			list_add_tail(list, &ctx->list);
			*dir = ctx->invalid_ptes[ctx->level + 1];
		}
	}

	return ret;
}

/*
 * Page walker for VM shadow mmu at page table dir level
 */
static int kvm_ptw_dir(kvm_pte_t *dir, phys_addr_t addr, phys_addr_t end, kvm_ptw_ctx *ctx)
{
	int ret;
	phys_addr_t next, start, size;
	struct list_head *list;
	kvm_pte_t *entry, *child;

	ret = 0;
	start = addr;
	child = (kvm_pte_t *)__va(PHYSADDR(*dir));
	entry = kvm_pgtable_offset(ctx, child, addr);
	do {
		next = kvm_pgtable_addr_end(ctx, addr, end);
		if (!kvm_pte_present(ctx, entry))
			continue;

		if (kvm_pte_huge(*entry)) {
			ret |= ctx->ops(entry, addr, ctx);
			continue;
		}

		kvm_ptw_enter(ctx);
		if (ctx->level == 0)
			ret |= kvm_ptw_leaf(entry, addr, next, ctx);
		else
			ret |= kvm_ptw_dir(entry, addr, next, ctx);
		kvm_ptw_exit(ctx);
	}  while (entry++, addr = next, addr < end);

	if (kvm_need_flush(ctx)) {
		size = 0x1UL << (ctx->pgtable_shift + PAGE_SHIFT - 3);
		if (start + size == end) {
			list = (struct list_head *)child;
			list_add_tail(list, &ctx->list);
			*dir = ctx->invalid_ptes[ctx->level + 1];
		}
	}

	return ret;
}

/*
 * Page walker for VM shadow mmu at page root table
 */
static int kvm_ptw_top(kvm_pte_t *dir, phys_addr_t addr, phys_addr_t end, kvm_ptw_ctx *ctx)
{
	int ret;
	phys_addr_t next;
	kvm_pte_t *entry;

	ret = 0;
	entry = kvm_pgtable_offset(ctx, dir, addr);
	do {
		next = kvm_pgtable_addr_end(ctx, addr, end);
		if (!kvm_pte_present(ctx, entry))
			continue;

		kvm_ptw_enter(ctx);
		ret |= kvm_ptw_dir(entry, addr, next, ctx);
		kvm_ptw_exit(ctx);
	}  while (entry++, addr = next, addr < end);

	return ret;
}

/*
 * kvm_flush_range() - Flush a range of guest physical addresses.
 * @kvm:	KVM pointer.
 * @start_gfn:	Guest frame number of first page in GPA range to flush.
 * @end_gfn:	Guest frame number of last page in GPA range to flush.
 * @lock:	Whether to hold mmu_lock or not
 *
 * Flushes a range of GPA mappings from the GPA page tables.
 */
static void kvm_flush_range(struct kvm *kvm, gfn_t start_gfn, gfn_t end_gfn, int lock)
{
	int ret;
	kvm_ptw_ctx ctx;
	struct list_head *pos, *temp;

	ctx.ops = kvm_flush_pte;
	ctx.flag = _KVM_FLUSH_PGTABLE;
	kvm_ptw_prepare(kvm, &ctx);
	INIT_LIST_HEAD(&ctx.list);

	if (lock) {
		spin_lock(&kvm->mmu_lock);
		ret = kvm_ptw_top(kvm->arch.pgd, start_gfn << PAGE_SHIFT,
					end_gfn << PAGE_SHIFT, &ctx);
		spin_unlock(&kvm->mmu_lock);
	} else
		ret = kvm_ptw_top(kvm->arch.pgd, start_gfn << PAGE_SHIFT,
					end_gfn << PAGE_SHIFT, &ctx);

	/* Flush vpid for each vCPU individually */
	if (ret)
		kvm_flush_remote_tlbs(kvm);

	/*
	 * free pte table page after mmu_lock
	 * the pte table page is linked together with ctx.list
	 */
	list_for_each_safe(pos, temp, &ctx.list) {
		list_del(pos);
		free_page((unsigned long)pos);
	}
}

/*
 * kvm_mkclean_gpa_pt() - Make a range of guest physical addresses clean.
 * @kvm:	KVM pointer.
 * @start_gfn:	Guest frame number of first page in GPA range to flush.
 * @end_gfn:	Guest frame number of last page in GPA range to flush.
 *
 * Make a range of GPA mappings clean so that guest writes will fault and
 * trigger dirty page logging.
 *
 * The caller must hold the @kvm->mmu_lock spinlock.
 *
 * Returns:	Whether any GPA mappings were modified, which would require
 *		derived mappings (GVA page tables & TLB enties) to be
 *		invalidated.
 */
static int kvm_mkclean_gpa_pt(struct kvm *kvm, gfn_t start_gfn, gfn_t end_gfn)
{
	kvm_ptw_ctx ctx;

	ctx.ops = kvm_mkclean_pte;
	ctx.flag = 0;
	kvm_ptw_prepare(kvm, &ctx);
	return kvm_ptw_top(kvm->arch.pgd, start_gfn << PAGE_SHIFT, end_gfn << PAGE_SHIFT, &ctx);
}

/*
 * kvm_arch_mmu_enable_log_dirty_pt_masked() - write protect dirty pages
 * @kvm:	The KVM pointer
 * @slot:	The memory slot associated with mask
 * @gfn_offset:	The gfn offset in memory slot
 * @mask:	The mask of dirty pages at offset 'gfn_offset' in this memory
 *		slot to be write protected
 *
 * Walks bits set in mask write protects the associated pte's. Caller must
 * acquire @kvm->mmu_lock.
 */
void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
		struct kvm_memory_slot *slot, gfn_t gfn_offset, unsigned long mask)
{
	kvm_ptw_ctx ctx;
	gfn_t base_gfn = slot->base_gfn + gfn_offset;
	gfn_t start = base_gfn + __ffs(mask);
	gfn_t end = base_gfn + __fls(mask) + 1;

	ctx.ops = kvm_mkclean_pte;
	ctx.flag = _KVM_HAS_PGMASK;
	ctx.mask = mask;
	ctx.gfn = base_gfn;
	kvm_ptw_prepare(kvm, &ctx);

	kvm_ptw_top(kvm->arch.pgd, start << PAGE_SHIFT, end << PAGE_SHIFT, &ctx);
}

int kvm_arch_prepare_memory_region(struct kvm *kvm, const struct kvm_memory_slot *old,
				   struct kvm_memory_slot *new, enum kvm_mr_change change)
{
	gpa_t gpa_start;
	hva_t hva_start;
	size_t size, gpa_offset, hva_offset;

	if ((change != KVM_MR_MOVE) && (change != KVM_MR_CREATE))
		return 0;
	/*
	 * Prevent userspace from creating a memory region outside of the
	 * VM GPA address space
	 */
	if ((new->base_gfn + new->npages) > (kvm->arch.gpa_size >> PAGE_SHIFT))
		return -ENOMEM;

	new->arch.flags = 0;
	size = new->npages * PAGE_SIZE;
	gpa_start = new->base_gfn << PAGE_SHIFT;
	hva_start = new->userspace_addr;
	if (IS_ALIGNED(size, PMD_SIZE) && IS_ALIGNED(gpa_start, PMD_SIZE)
			&& IS_ALIGNED(hva_start, PMD_SIZE))
		new->arch.flags |= KVM_MEM_HUGEPAGE_CAPABLE;
	else {
		/*
		 * Pages belonging to memslots that don't have the same
		 * alignment within a PMD for userspace and GPA cannot be
		 * mapped with PMD entries, because we'll end up mapping
		 * the wrong pages.
		 *
		 * Consider a layout like the following:
		 *
		 *    memslot->userspace_addr:
		 *    +-----+--------------------+--------------------+---+
		 *    |abcde|fgh  Stage-1 block  |    Stage-1 block tv|xyz|
		 *    +-----+--------------------+--------------------+---+
		 *
		 *    memslot->base_gfn << PAGE_SIZE:
		 *      +---+--------------------+--------------------+-----+
		 *      |abc|def  Stage-2 block  |    Stage-2 block   |tvxyz|
		 *      +---+--------------------+--------------------+-----+
		 *
		 * If we create those stage-2 blocks, we'll end up with this
		 * incorrect mapping:
		 *   d -> f
		 *   e -> g
		 *   f -> h
		 */
		gpa_offset = gpa_start & (PMD_SIZE - 1);
		hva_offset = hva_start & (PMD_SIZE - 1);
		if (gpa_offset != hva_offset) {
			new->arch.flags |= KVM_MEM_HUGEPAGE_INCAPABLE;
		} else {
			if (gpa_offset == 0)
				gpa_offset = PMD_SIZE;
			if ((size + gpa_offset) < (PMD_SIZE * 2))
				new->arch.flags |= KVM_MEM_HUGEPAGE_INCAPABLE;
		}
	}

	return 0;
}

void kvm_arch_commit_memory_region(struct kvm *kvm,
				   struct kvm_memory_slot *old,
				   const struct kvm_memory_slot *new,
				   enum kvm_mr_change change)
{
	int needs_flush;

	/*
	 * If dirty page logging is enabled, write protect all pages in the slot
	 * ready for dirty logging.
	 *
	 * There is no need to do this in any of the following cases:
	 * CREATE:	No dirty mappings will already exist.
	 * MOVE/DELETE:	The old mappings will already have been cleaned up by
	 *		kvm_arch_flush_shadow_memslot()
	 */
	if (change == KVM_MR_FLAGS_ONLY &&
	    (!(old->flags & KVM_MEM_LOG_DIRTY_PAGES) &&
	     new->flags & KVM_MEM_LOG_DIRTY_PAGES)) {
		spin_lock(&kvm->mmu_lock);
		/* Write protect GPA page table entries */
		needs_flush = kvm_mkclean_gpa_pt(kvm, new->base_gfn,
					new->base_gfn + new->npages);
		spin_unlock(&kvm->mmu_lock);
		if (needs_flush)
			kvm_flush_remote_tlbs(kvm);
	}
}

void kvm_arch_flush_shadow_all(struct kvm *kvm)
{
	kvm_flush_range(kvm, 0, kvm->arch.gpa_size >> PAGE_SHIFT, 0);
}

void kvm_arch_flush_shadow_memslot(struct kvm *kvm, struct kvm_memory_slot *slot)
{
	/*
	 * The slot has been made invalid (ready for moving or deletion), so we
	 * need to ensure that it can no longer be accessed by any guest vCPUs.
	 */
	kvm_flush_range(kvm, slot->base_gfn, slot->base_gfn + slot->npages, 1);
}

bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
{
	kvm_ptw_ctx ctx;

	ctx.flag = 0;
	ctx.ops = kvm_flush_pte;
	kvm_ptw_prepare(kvm, &ctx);
	INIT_LIST_HEAD(&ctx.list);

	return kvm_ptw_top(kvm->arch.pgd, range->start << PAGE_SHIFT,
			range->end << PAGE_SHIFT, &ctx);
}

bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
	unsigned long prot_bits;
	kvm_pte_t *ptep;
	kvm_pfn_t pfn = pte_pfn(range->arg.pte);
	gpa_t gpa = range->start << PAGE_SHIFT;

	ptep = kvm_populate_gpa(kvm, NULL, gpa, 0);
	if (!ptep)
		return false;

	/* Replacing an absent or old page doesn't need flushes */
	if (!kvm_pte_present(NULL, ptep) || !kvm_pte_young(*ptep)) {
		kvm_set_pte(ptep, 0);
		return false;
	}

	/* Fill new pte if write protected or page migrated */
	prot_bits = _PAGE_PRESENT | __READABLE;
	prot_bits |= _CACHE_MASK & pte_val(range->arg.pte);

	/*
	 * Set _PAGE_WRITE or _PAGE_DIRTY iff old and new pte both support
	 * _PAGE_WRITE for map_page_fast if next page write fault
	 * _PAGE_DIRTY since gpa has already recorded as dirty page
	 */
	prot_bits |= __WRITEABLE & *ptep & pte_val(range->arg.pte);
	kvm_set_pte(ptep, kvm_pfn_pte(pfn, __pgprot(prot_bits)));

	return true;
}

bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
	kvm_ptw_ctx ctx;

	ctx.flag = 0;
	ctx.ops = kvm_mkold_pte;
	kvm_ptw_prepare(kvm, &ctx);

	return kvm_ptw_top(kvm->arch.pgd, range->start << PAGE_SHIFT,
				range->end << PAGE_SHIFT, &ctx);
}

bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
{
	gpa_t gpa = range->start << PAGE_SHIFT;
	kvm_pte_t *ptep = kvm_populate_gpa(kvm, NULL, gpa, 0);

	if (ptep && kvm_pte_present(NULL, ptep) && kvm_pte_young(*ptep))
		return true;

	return false;
}

/*
 * kvm_map_page_fast() - Fast path GPA fault handler.
 * @vcpu:		vCPU pointer.
 * @gpa:		Guest physical address of fault.
 * @write:	Whether the fault was due to a write.
 *
 * Perform fast path GPA fault handling, doing all that can be done without
 * calling into KVM. This handles marking old pages young (for idle page
 * tracking), and dirtying of clean pages (for dirty page logging).
 *
 * Returns:	0 on success, in which case we can update derived mappings and
 *		resume guest execution.
 *		-EFAULT on failure due to absent GPA mapping or write to
 *		read-only page, in which case KVM must be consulted.
 */
static int kvm_map_page_fast(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
{
	int ret = 0;
	kvm_pfn_t pfn = 0;
	kvm_pte_t *ptep, changed, new;
	gfn_t gfn = gpa >> PAGE_SHIFT;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_memory_slot *slot;

	spin_lock(&kvm->mmu_lock);

	/* Fast path - just check GPA page table for an existing entry */
	ptep = kvm_populate_gpa(kvm, NULL, gpa, 0);
	if (!ptep || !kvm_pte_present(NULL, ptep)) {
		ret = -EFAULT;
		goto out;
	}

	/* Track access to pages marked old */
	new = *ptep;
	if (!kvm_pte_young(new))
		new = kvm_pte_mkyoung(new);
		/* call kvm_set_pfn_accessed() after unlock */

	if (write && !kvm_pte_dirty(new)) {
		if (!kvm_pte_write(new)) {
			ret = -EFAULT;
			goto out;
		}

		if (kvm_pte_huge(new)) {
			/*
			 * Do not set write permission when dirty logging is
			 * enabled for HugePages
			 */
			slot = gfn_to_memslot(kvm, gfn);
			if (kvm_slot_dirty_track_enabled(slot)) {
				ret = -EFAULT;
				goto out;
			}
		}

		/* Track dirtying of writeable pages */
		new = kvm_pte_mkdirty(new);
	}

	changed = new ^ (*ptep);
	if (changed) {
		kvm_set_pte(ptep, new);
		pfn = kvm_pte_pfn(new);
	}
	spin_unlock(&kvm->mmu_lock);

	/*
	 * Fixme: pfn may be freed after mmu_lock
	 * kvm_try_get_pfn(pfn)/kvm_release_pfn pair to prevent this?
	 */
	if (kvm_pte_young(changed))
		kvm_set_pfn_accessed(pfn);

	if (kvm_pte_dirty(changed)) {
		mark_page_dirty(kvm, gfn);
		kvm_set_pfn_dirty(pfn);
	}
	return ret;
out:
	spin_unlock(&kvm->mmu_lock);
	return ret;
}

static bool fault_supports_huge_mapping(struct kvm_memory_slot *memslot,
				unsigned long hva, bool write)
{
	hva_t start, end;

	/* Disable dirty logging on HugePages */
	if (kvm_slot_dirty_track_enabled(memslot) && write)
		return false;

	if (kvm_hugepage_capable(memslot))
		return true;

	if (kvm_hugepage_incapable(memslot))
		return false;

	start = memslot->userspace_addr;
	end = start + memslot->npages * PAGE_SIZE;

	/*
	 * Next, let's make sure we're not trying to map anything not covered
	 * by the memslot. This means we have to prohibit block size mappings
	 * for the beginning and end of a non-block aligned and non-block sized
	 * memory slot (illustrated by the head and tail parts of the
	 * userspace view above containing pages 'abcde' and 'xyz',
	 * respectively).
	 *
	 * Note that it doesn't matter if we do the check using the
	 * userspace_addr or the base_gfn, as both are equally aligned (per
	 * the check above) and equally sized.
	 */
	return (hva >= ALIGN(start, PMD_SIZE)) && (hva < ALIGN_DOWN(end, PMD_SIZE));
}

/*
 * Lookup the mapping level for @gfn in the current mm.
 *
 * WARNING!  Use of host_pfn_mapping_level() requires the caller and the end
 * consumer to be tied into KVM's handlers for MMU notifier events!
 *
 * There are several ways to safely use this helper:
 *
 * - Check mmu_invalidate_retry_gfn() after grabbing the mapping level, before
 *   consuming it.  In this case, mmu_lock doesn't need to be held during the
 *   lookup, but it does need to be held while checking the MMU notifier.
 *
 * - Hold mmu_lock AND ensure there is no in-progress MMU notifier invalidation
 *   event for the hva.  This can be done by explicit checking the MMU notifier
 *   or by ensuring that KVM already has a valid mapping that covers the hva.
 *
 * - Do not use the result to install new mappings, e.g. use the host mapping
 *   level only to decide whether or not to zap an entry.  In this case, it's
 *   not required to hold mmu_lock (though it's highly likely the caller will
 *   want to hold mmu_lock anyways, e.g. to modify SPTEs).
 *
 * Note!  The lookup can still race with modifications to host page tables, but
 * the above "rules" ensure KVM will not _consume_ the result of the walk if a
 * race with the primary MMU occurs.
 */
static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn,
				const struct kvm_memory_slot *slot)
{
	int level = 0;
	unsigned long hva;
	unsigned long flags;
	pgd_t pgd;
	p4d_t p4d;
	pud_t pud;
	pmd_t pmd;

	/*
	 * Note, using the already-retrieved memslot and __gfn_to_hva_memslot()
	 * is not solely for performance, it's also necessary to avoid the
	 * "writable" check in __gfn_to_hva_many(), which will always fail on
	 * read-only memslots due to gfn_to_hva() assuming writes.  Earlier
	 * page fault steps have already verified the guest isn't writing a
	 * read-only memslot.
	 */
	hva = __gfn_to_hva_memslot(slot, gfn);

	/*
	 * Disable IRQs to prevent concurrent tear down of host page tables,
	 * e.g. if the primary MMU promotes a P*D to a huge page and then frees
	 * the original page table.
	 */
	local_irq_save(flags);

	/*
	 * Read each entry once.  As above, a non-leaf entry can be promoted to
	 * a huge page _during_ this walk.  Re-reading the entry could send the
	 * walk into the weeks, e.g. p*d_large() returns false (sees the old
	 * value) and then p*d_offset() walks into the target huge page instead
	 * of the old page table (sees the new value).
	 */
	pgd = READ_ONCE(*pgd_offset(kvm->mm, hva));
	if (pgd_none(pgd))
		goto out;

	p4d = READ_ONCE(*p4d_offset(&pgd, hva));
	if (p4d_none(p4d) || !p4d_present(p4d))
		goto out;

	pud = READ_ONCE(*pud_offset(&p4d, hva));
	if (pud_none(pud) || !pud_present(pud))
		goto out;

	pmd = READ_ONCE(*pmd_offset(&pud, hva));
	if (pmd_none(pmd) || !pmd_present(pmd))
		goto out;

	if (kvm_pte_huge(pmd_val(pmd)))
		level = 1;

out:
	local_irq_restore(flags);
	return level;
}

/*
 * Split huge page
 */
static kvm_pte_t *kvm_split_huge(struct kvm_vcpu *vcpu, kvm_pte_t *ptep, gfn_t gfn)
{
	int i;
	kvm_pte_t val, *child;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_mmu_memory_cache *memcache;

	memcache = &vcpu->arch.mmu_page_cache;
	child = kvm_mmu_memory_cache_alloc(memcache);
	val = kvm_pte_mksmall(*ptep);
	for (i = 0; i < PTRS_PER_PTE; i++) {
		kvm_set_pte(child + i, val);
		val += PAGE_SIZE;
	}

	/* The later kvm_flush_tlb_gpa() will flush hugepage tlb */
	kvm_set_pte(ptep, __pa(child));

	kvm->stat.hugepages--;
	kvm->stat.pages += PTRS_PER_PTE;

	return child + (gfn & (PTRS_PER_PTE - 1));
}

/*
 * kvm_map_page() - Map a guest physical page.
 * @vcpu:		vCPU pointer.
 * @gpa:		Guest physical address of fault.
 * @write:	Whether the fault was due to a write.
 *
 * Handle GPA faults by creating a new GPA mapping (or updating an existing
 * one).
 *
 * This takes care of marking pages young or dirty (idle/dirty page tracking),
 * asking KVM for the corresponding PFN, and creating a mapping in the GPA page
 * tables. Derived mappings (GVA page tables and TLBs) must be handled by the
 * caller.
 *
 * Returns:	0 on success
 *		-EFAULT if there is no memory region at @gpa or a write was
 *		attempted to a read-only memory region. This is usually handled
 *		as an MMIO access.
 */
static int kvm_map_page(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
{
	bool writeable;
	int srcu_idx, err, retry_no = 0, level;
	unsigned long hva, mmu_seq, prot_bits;
	kvm_pfn_t pfn;
	kvm_pte_t *ptep, new_pte;
	gfn_t gfn = gpa >> PAGE_SHIFT;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_memory_slot *memslot;
	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;

	/* Try the fast path to handle old / clean pages */
	srcu_idx = srcu_read_lock(&kvm->srcu);
	err = kvm_map_page_fast(vcpu, gpa, write);
	if (!err)
		goto out;

	memslot = gfn_to_memslot(kvm, gfn);
	hva = gfn_to_hva_memslot_prot(memslot, gfn, &writeable);
	if (kvm_is_error_hva(hva) || (write && !writeable)) {
		err = -EFAULT;
		goto out;
	}

	/* We need a minimum of cached pages ready for page table creation */
	err = kvm_mmu_topup_memory_cache(memcache, KVM_MMU_CACHE_MIN_PAGES);
	if (err)
		goto out;

retry:
	/*
	 * Used to check for invalidations in progress, of the pfn that is
	 * returned by pfn_to_pfn_prot below.
	 */
	mmu_seq = kvm->mmu_invalidate_seq;
	/*
	 * Ensure the read of mmu_invalidate_seq isn't reordered with PTE reads in
	 * gfn_to_pfn_prot() (which calls get_user_pages()), so that we don't
	 * risk the page we get a reference to getting unmapped before we have a
	 * chance to grab the mmu_lock without mmu_invalidate_retry() noticing.
	 *
	 * This smp_rmb() pairs with the effective smp_wmb() of the combination
	 * of the pte_unmap_unlock() after the PTE is zapped, and the
	 * spin_lock() in kvm_mmu_invalidate_invalidate_<page|range_end>() before
	 * mmu_invalidate_seq is incremented.
	 */
	smp_rmb();

	/* Slow path - ask KVM core whether we can access this GPA */
	pfn = gfn_to_pfn_prot(kvm, gfn, write, &writeable);
	if (is_error_noslot_pfn(pfn)) {
		err = -EFAULT;
		goto out;
	}

	/* Check if an invalidation has taken place since we got pfn */
	spin_lock(&kvm->mmu_lock);
	if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn)) {
		/*
		 * This can happen when mappings are changed asynchronously, but
		 * also synchronously if a COW is triggered by
		 * gfn_to_pfn_prot().
		 */
		spin_unlock(&kvm->mmu_lock);
		kvm_release_pfn_clean(pfn);
		if (retry_no > 100) {
			retry_no = 0;
			schedule();
		}
		retry_no++;
		goto retry;
	}

	/*
	 * For emulated devices such virtio device, actual cache attribute is
	 * determined by physical machine.
	 * For pass through physical device, it should be uncachable
	 */
	prot_bits = _PAGE_PRESENT | __READABLE;
	if (pfn_valid(pfn))
		prot_bits |= _CACHE_CC;
	else
		prot_bits |= _CACHE_SUC;

	if (writeable) {
		prot_bits |= _PAGE_WRITE;
		if (write)
			prot_bits |= __WRITEABLE;
	}

	/* Disable dirty logging on HugePages */
	level = 0;
	if (!fault_supports_huge_mapping(memslot, hva, write)) {
		level = 0;
	} else {
		level = host_pfn_mapping_level(kvm, gfn, memslot);
		if (level == 1) {
			gfn = gfn & ~(PTRS_PER_PTE - 1);
			pfn = pfn & ~(PTRS_PER_PTE - 1);
		}
	}

	/* Ensure page tables are allocated */
	ptep = kvm_populate_gpa(kvm, memcache, gpa, level);
	new_pte = kvm_pfn_pte(pfn, __pgprot(prot_bits));
	if (level == 1) {
		new_pte = kvm_pte_mkhuge(new_pte);
		/*
		 * previous pmd entry is invalid_pte_table
		 * there is invalid tlb with small page
		 * need flush these invalid tlbs for current vcpu
		 */
		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
		++kvm->stat.hugepages;
	}  else if (kvm_pte_huge(*ptep) && write)
		ptep = kvm_split_huge(vcpu, ptep, gfn);
	else
		++kvm->stat.pages;
	kvm_set_pte(ptep, new_pte);
	spin_unlock(&kvm->mmu_lock);

	if (prot_bits & _PAGE_DIRTY) {
		mark_page_dirty_in_slot(kvm, memslot, gfn);
		kvm_set_pfn_dirty(pfn);
	}

	kvm_set_pfn_accessed(pfn);
	kvm_release_pfn_clean(pfn);
out:
	srcu_read_unlock(&kvm->srcu, srcu_idx);
	return err;
}

int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
{
	int ret;

	ret = kvm_map_page(vcpu, gpa, write);
	if (ret)
		return ret;

	/* Invalidate this entry in the TLB */
	kvm_flush_tlb_gpa(vcpu, gpa);

	return 0;
}

void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
{
}

void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
					const struct kvm_memory_slot *memslot)
{
	kvm_flush_remote_tlbs(kvm);
}
