aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/xenfs/privcmd.c
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2009-05-21 05:09:46 -0400
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-10-20 19:22:34 -0400
commitde1ef2065c4675ab1062ebc8d1cb6c5f42b61d04 (patch)
tree8091769ae22659277e43df69a7101c17e19530fa /drivers/xen/xenfs/privcmd.c
parentf020e2905166e12f9a8f109fe968cb5a9db887e9 (diff)
xen/privcmd: move remap_domain_mfn_range() to core xen code and export.
This allows xenfs to be built as a module, previously it required flush_tlb_all and arbitrary_virt_to_machine to be exported. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'drivers/xen/xenfs/privcmd.c')
-rw-r--r--drivers/xen/xenfs/privcmd.c81
1 files changed, 8 insertions, 73 deletions
diff --git a/drivers/xen/xenfs/privcmd.c b/drivers/xen/xenfs/privcmd.c
index 438223ae0fc3..f80be7f6eb95 100644
--- a/drivers/xen/xenfs/privcmd.c
+++ b/drivers/xen/xenfs/privcmd.c
@@ -31,76 +31,12 @@
31#include <xen/interface/xen.h> 31#include <xen/interface/xen.h>
32#include <xen/features.h> 32#include <xen/features.h>
33#include <xen/page.h> 33#include <xen/page.h>
34 34#include <xen/xen-ops.h>
35#define REMAP_BATCH_SIZE 16
36 35
37#ifndef HAVE_ARCH_PRIVCMD_MMAP 36#ifndef HAVE_ARCH_PRIVCMD_MMAP
38static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma); 37static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
39#endif 38#endif
40 39
41struct remap_data {
42 unsigned long mfn;
43 pgprot_t prot;
44 struct mmu_update *mmu_update;
45};
46
47static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
48 unsigned long addr, void *data)
49{
50 struct remap_data *rmd = data;
51 pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
52
53 rmd->mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr;
54 rmd->mmu_update->val = pte_val_ma(pte);
55 rmd->mmu_update++;
56
57 return 0;
58}
59
60static int remap_domain_mfn_range(struct vm_area_struct *vma,
61 unsigned long addr,
62 unsigned long mfn, int nr,
63 pgprot_t prot, unsigned domid)
64{
65 struct remap_data rmd;
66 struct mmu_update mmu_update[REMAP_BATCH_SIZE];
67 int batch;
68 unsigned long range;
69 int err = 0;
70
71 prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
72
73 vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
74
75 rmd.mfn = mfn;
76 rmd.prot = prot;
77
78 while (nr) {
79 batch = min(REMAP_BATCH_SIZE, nr);
80 range = (unsigned long)batch << PAGE_SHIFT;
81
82 rmd.mmu_update = mmu_update;
83 err = apply_to_page_range(vma->vm_mm, addr, range,
84 remap_area_mfn_pte_fn, &rmd);
85 if (err)
86 goto out;
87
88 err = -EFAULT;
89 if (HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid) < 0)
90 goto out;
91
92 nr -= batch;
93 addr += range;
94 }
95
96 err = 0;
97out:
98
99 flush_tlb_all();
100
101 return err;
102}
103
104static long privcmd_ioctl_hypercall(void __user *udata) 40static long privcmd_ioctl_hypercall(void __user *udata)
105{ 41{
106 struct privcmd_hypercall hypercall; 42 struct privcmd_hypercall hypercall;
@@ -233,11 +169,11 @@ static int mmap_mfn_range(void *data, void *state)
233 ((msg->va+(msg->npages<<PAGE_SHIFT)) > vma->vm_end)) 169 ((msg->va+(msg->npages<<PAGE_SHIFT)) > vma->vm_end))
234 return -EINVAL; 170 return -EINVAL;
235 171
236 rc = remap_domain_mfn_range(vma, 172 rc = xen_remap_domain_mfn_range(vma,
237 msg->va & PAGE_MASK, 173 msg->va & PAGE_MASK,
238 msg->mfn, msg->npages, 174 msg->mfn, msg->npages,
239 vma->vm_page_prot, 175 vma->vm_page_prot,
240 st->domain); 176 st->domain);
241 if (rc < 0) 177 if (rc < 0)
242 return rc; 178 return rc;
243 179
@@ -315,9 +251,8 @@ static int mmap_batch_fn(void *data, void *state)
315 xen_pfn_t *mfnp = data; 251 xen_pfn_t *mfnp = data;
316 struct mmap_batch_state *st = state; 252 struct mmap_batch_state *st = state;
317 253
318 if (remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, 254 if (xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
319 *mfnp, 1, 255 st->vma->vm_page_prot, st->domain) < 0) {
320 st->vma->vm_page_prot, st->domain) < 0) {
321 *mfnp |= 0xf0000000U; 256 *mfnp |= 0xf0000000U;
322 st->err++; 257 st->err++;
323 } 258 }