diff options
Diffstat (limited to 'arch/x86/xen/mmu.c')
| -rw-r--r-- | arch/x86/xen/mmu.c | 188 | 
1 files changed, 2 insertions, 186 deletions
| diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 96fc2f0fdbfe..60e9c37fd79f 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 +  #include <linux/pfn.h>  #include <asm/xen/page.h>  #include <asm/xen/hypercall.h> @@ -6,12 +8,6 @@  #include "multicalls.h"  #include "mmu.h" -/* - * Protects atomic reservation decrease/increase against concurrent increases. - * Also protects non-atomic updates of current_pages and balloon lists. - */ -DEFINE_SPINLOCK(xen_reservation_lock); -  unsigned long arbitrary_virt_to_mfn(void *vaddr)  {  	xmaddr_t maddr = arbitrary_virt_to_machine(vaddr); @@ -42,186 +38,6 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr)  }  EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine); -static noinline void xen_flush_tlb_all(void) -{ -	struct mmuext_op *op; -	struct multicall_space mcs; - -	preempt_disable(); - -	mcs = xen_mc_entry(sizeof(*op)); - -	op = mcs.args; -	op->cmd = MMUEXT_TLB_FLUSH_ALL; -	MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); - -	xen_mc_issue(PARAVIRT_LAZY_MMU); - -	preempt_enable(); -} - -#define REMAP_BATCH_SIZE 16 - -struct remap_data { -	xen_pfn_t *pfn; -	bool contiguous; -	bool no_translate; -	pgprot_t prot; -	struct mmu_update *mmu_update; -}; - -static int remap_area_pfn_pte_fn(pte_t *ptep, pgtable_t token, -				 unsigned long addr, void *data) -{ -	struct remap_data *rmd = data; -	pte_t pte = pte_mkspecial(mfn_pte(*rmd->pfn, rmd->prot)); - -	/* -	 * If we have a contiguous range, just update the pfn itself, -	 * else update pointer to be "next pfn". -	 */ -	if (rmd->contiguous) -		(*rmd->pfn)++; -	else -		rmd->pfn++; - -	rmd->mmu_update->ptr = virt_to_machine(ptep).maddr; -	rmd->mmu_update->ptr |= rmd->no_translate ? -		MMU_PT_UPDATE_NO_TRANSLATE : -		MMU_NORMAL_PT_UPDATE; -	rmd->mmu_update->val = pte_val_ma(pte); -	rmd->mmu_update++; - -	return 0; -} - -static int do_remap_pfn(struct vm_area_struct *vma, -			unsigned long addr, -			xen_pfn_t *pfn, int nr, -			int *err_ptr, pgprot_t prot, -			unsigned int domid, -			bool no_translate, -			struct page **pages) -{ -	int err = 0; -	struct remap_data rmd; -	struct mmu_update mmu_update[REMAP_BATCH_SIZE]; -	unsigned long range; -	int mapped = 0; - -	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO))); - -	rmd.pfn = pfn; -	rmd.prot = prot; -	/* -	 * We use the err_ptr to indicate if there we are doing a contiguous -	 * mapping or a discontigious mapping. -	 */ -	rmd.contiguous = !err_ptr; -	rmd.no_translate = no_translate; - -	while (nr) { -		int index = 0; -		int done = 0; -		int batch = min(REMAP_BATCH_SIZE, nr); -		int batch_left = batch; -		range = (unsigned long)batch << PAGE_SHIFT; - -		rmd.mmu_update = mmu_update; -		err = apply_to_page_range(vma->vm_mm, addr, range, -					  remap_area_pfn_pte_fn, &rmd); -		if (err) -			goto out; - -		/* We record the error for each page that gives an error, but -		 * continue mapping until the whole set is done */ -		do { -			int i; - -			err = HYPERVISOR_mmu_update(&mmu_update[index], -						    batch_left, &done, domid); - -			/* -			 * @err_ptr may be the same buffer as @gfn, so -			 * only clear it after each chunk of @gfn is -			 * used. -			 */ -			if (err_ptr) { -				for (i = index; i < index + done; i++) -					err_ptr[i] = 0; -			} -			if (err < 0) { -				if (!err_ptr) -					goto out; -				err_ptr[i] = err; -				done++; /* Skip failed frame. */ -			} else -				mapped += done; -			batch_left -= done; -			index += done; -		} while (batch_left); - -		nr -= batch; -		addr += range; -		if (err_ptr) -			err_ptr += batch; -		cond_resched(); -	} -out: - -	xen_flush_tlb_all(); - -	return err < 0 ? err : mapped; -} - -int xen_remap_domain_gfn_range(struct vm_area_struct *vma, -			       unsigned long addr, -			       xen_pfn_t gfn, int nr, -			       pgprot_t prot, unsigned domid, -			       struct page **pages) -{ -	if (xen_feature(XENFEAT_auto_translated_physmap)) -		return -EOPNOTSUPP; - -	return do_remap_pfn(vma, addr, &gfn, nr, NULL, prot, domid, false, -			    pages); -} -EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range); - -int xen_remap_domain_gfn_array(struct vm_area_struct *vma, -			       unsigned long addr, -			       xen_pfn_t *gfn, int nr, -			       int *err_ptr, pgprot_t prot, -			       unsigned domid, struct page **pages) -{ -	if (xen_feature(XENFEAT_auto_translated_physmap)) -		return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr, -						 prot, domid, pages); - -	/* We BUG_ON because it's a programmer error to pass a NULL err_ptr, -	 * and the consequences later is quite hard to detect what the actual -	 * cause of "wrong memory was mapped in". -	 */ -	BUG_ON(err_ptr == NULL); -	return do_remap_pfn(vma, addr, gfn, nr, err_ptr, prot, domid, -			    false, pages); -} -EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array); - -int xen_remap_domain_mfn_array(struct vm_area_struct *vma, -			       unsigned long addr, -			       xen_pfn_t *mfn, int nr, -			       int *err_ptr, pgprot_t prot, -			       unsigned int domid, struct page **pages) -{ -	if (xen_feature(XENFEAT_auto_translated_physmap)) -		return -EOPNOTSUPP; - -	return do_remap_pfn(vma, addr, mfn, nr, err_ptr, prot, domid, -			    true, pages); -} -EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array); -  /* Returns: 0 success */  int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,  			       int nr, struct page **pages) |