diff options
| author | Ian Campbell <ian.campbell@citrix.com> | 2009-05-21 05:09:46 -0400 |
|---|---|---|
| committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2010-10-20 19:22:34 -0400 |
| commit | de1ef2065c4675ab1062ebc8d1cb6c5f42b61d04 (patch) | |
| tree | 8091769ae22659277e43df69a7101c17e19530fa | |
| parent | f020e2905166e12f9a8f109fe968cb5a9db887e9 (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>
| -rw-r--r-- | arch/x86/xen/mmu.c | 66 | ||||
| -rw-r--r-- | drivers/xen/xenfs/privcmd.c | 81 | ||||
| -rw-r--r-- | include/xen/xen-ops.h | 5 |
3 files changed, 79 insertions, 73 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 1ceb0f2fa0af..f08ea045620f 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -2265,6 +2265,72 @@ void __init xen_hvm_init_mmu_ops(void) | |||
| 2265 | } | 2265 | } |
| 2266 | #endif | 2266 | #endif |
| 2267 | 2267 | ||
| 2268 | #define REMAP_BATCH_SIZE 16 | ||
| 2269 | |||
| 2270 | struct remap_data { | ||
| 2271 | unsigned long mfn; | ||
| 2272 | pgprot_t prot; | ||
| 2273 | struct mmu_update *mmu_update; | ||
| 2274 | }; | ||
| 2275 | |||
| 2276 | static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token, | ||
| 2277 | unsigned long addr, void *data) | ||
| 2278 | { | ||
| 2279 | struct remap_data *rmd = data; | ||
| 2280 | pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot)); | ||
| 2281 | |||
| 2282 | rmd->mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr; | ||
| 2283 | rmd->mmu_update->val = pte_val_ma(pte); | ||
| 2284 | rmd->mmu_update++; | ||
| 2285 | |||
| 2286 | return 0; | ||
| 2287 | } | ||
| 2288 | |||
| 2289 | int xen_remap_domain_mfn_range(struct vm_area_struct *vma, | ||
| 2290 | unsigned long addr, | ||
| 2291 | unsigned long mfn, int nr, | ||
| 2292 | pgprot_t prot, unsigned domid) | ||
| 2293 | { | ||
| 2294 | struct remap_data rmd; | ||
| 2295 | struct mmu_update mmu_update[REMAP_BATCH_SIZE]; | ||
| 2296 | int batch; | ||
| 2297 | unsigned long range; | ||
| 2298 | int err = 0; | ||
| 2299 | |||
| 2300 | prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP); | ||
| 2301 | |||
| 2302 | vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; | ||
| 2303 | |||
| 2304 | rmd.mfn = mfn; | ||
| 2305 | rmd.prot = prot; | ||
| 2306 | |||
| 2307 | while (nr) { | ||
| 2308 | batch = min(REMAP_BATCH_SIZE, nr); | ||
| 2309 | range = (unsigned long)batch << PAGE_SHIFT; | ||
| 2310 | |||
| 2311 | rmd.mmu_update = mmu_update; | ||
| 2312 | err = apply_to_page_range(vma->vm_mm, addr, range, | ||
| 2313 | remap_area_mfn_pte_fn, &rmd); | ||
| 2314 | if (err) | ||
| 2315 | goto out; | ||
| 2316 | |||
| 2317 | err = -EFAULT; | ||
| 2318 | if (HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid) < 0) | ||
| 2319 | goto out; | ||
| 2320 | |||
| 2321 | nr -= batch; | ||
| 2322 | addr += range; | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | err = 0; | ||
| 2326 | out: | ||
| 2327 | |||
| 2328 | flush_tlb_all(); | ||
| 2329 | |||
| 2330 | return err; | ||
| 2331 | } | ||
| 2332 | EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); | ||
| 2333 | |||
| 2268 | #ifdef CONFIG_XEN_DEBUG_FS | 2334 | #ifdef CONFIG_XEN_DEBUG_FS |
| 2269 | 2335 | ||
| 2270 | static struct dentry *d_mmu_debug; | 2336 | static struct dentry *d_mmu_debug; |
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 |
| 38 | static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma); | 37 | static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma); |
| 39 | #endif | 38 | #endif |
| 40 | 39 | ||
| 41 | struct remap_data { | ||
| 42 | unsigned long mfn; | ||
| 43 | pgprot_t prot; | ||
| 44 | struct mmu_update *mmu_update; | ||
| 45 | }; | ||
| 46 | |||
| 47 | static 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 | |||
| 60 | static 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; | ||
| 97 | out: | ||
| 98 | |||
| 99 | flush_tlb_all(); | ||
| 100 | |||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | static long privcmd_ioctl_hypercall(void __user *udata) | 40 | static 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 | } |
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 351f4051f6d8..98b92154a264 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h | |||
| @@ -23,4 +23,9 @@ int xen_create_contiguous_region(unsigned long vstart, unsigned int order, | |||
| 23 | 23 | ||
| 24 | void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); | 24 | void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); |
| 25 | 25 | ||
| 26 | int xen_remap_domain_mfn_range(struct vm_area_struct *vma, | ||
| 27 | unsigned long addr, | ||
| 28 | unsigned long mfn, int nr, | ||
| 29 | pgprot_t prot, unsigned domid); | ||
| 30 | |||
| 26 | #endif /* INCLUDE_XEN_OPS_H */ | 31 | #endif /* INCLUDE_XEN_OPS_H */ |
