aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/xen/enlighten.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2015-03-11 10:49:56 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2015-03-16 10:49:15 -0400
commit628c28eefd6f2cef03b212081b466ae43fd093a3 (patch)
treeedcde5040badd2068efe925f8253961e0ca71c48 /arch/arm/xen/enlighten.c
parentb3b06c7eb7820cea5c15f9faa4964044284c5399 (diff)
xen: unify foreign GFN map/unmap for auto-xlated physmap guests
Auto-translated physmap guests (arm, arm64 and x86 PVHVM/PVH) map and unmap foreign GFNs using the same method (updating the physmap). Unify the two arm and x86 implementations into one commont one. Note that on arm and arm64, the correct error code will be returned (instead of always -EFAULT) and map/unmap failure warnings are no longer printed. These changes are required if the foreign domain is paging (-ENOENT failures are expected and must be propagated up to the caller). Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'arch/arm/xen/enlighten.c')
-rw-r--r--arch/arm/xen/enlighten.c90
1 files changed, 3 insertions, 87 deletions
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 263a2044c65b..5c04389fc9ef 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -53,105 +53,21 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
53 53
54static __read_mostly int xen_events_irq = -1; 54static __read_mostly int xen_events_irq = -1;
55 55
56/* map fgmfn of domid to lpfn in the current domain */
57static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
58 unsigned int domid)
59{
60 int rc;
61 struct xen_add_to_physmap_range xatp = {
62 .domid = DOMID_SELF,
63 .foreign_domid = domid,
64 .size = 1,
65 .space = XENMAPSPACE_gmfn_foreign,
66 };
67 xen_ulong_t idx = fgmfn;
68 xen_pfn_t gpfn = lpfn;
69 int err = 0;
70
71 set_xen_guest_handle(xatp.idxs, &idx);
72 set_xen_guest_handle(xatp.gpfns, &gpfn);
73 set_xen_guest_handle(xatp.errs, &err);
74
75 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
76 if (rc || err) {
77 pr_warn("Failed to map pfn to mfn rc:%d:%d pfn:%lx mfn:%lx\n",
78 rc, err, lpfn, fgmfn);
79 return 1;
80 }
81 return 0;
82}
83
84struct remap_data {
85 xen_pfn_t fgmfn; /* foreign domain's gmfn */
86 pgprot_t prot;
87 domid_t domid;
88 struct vm_area_struct *vma;
89 int index;
90 struct page **pages;
91 struct xen_remap_mfn_info *info;
92};
93
94static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
95 void *data)
96{
97 struct remap_data *info = data;
98 struct page *page = info->pages[info->index++];
99 unsigned long pfn = page_to_pfn(page);
100 pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));
101
102 if (map_foreign_page(pfn, info->fgmfn, info->domid))
103 return -EFAULT;
104 set_pte_at(info->vma->vm_mm, addr, ptep, pte);
105
106 return 0;
107}
108
109int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 56int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
110 unsigned long addr, 57 unsigned long addr,
111 xen_pfn_t mfn, int nr, 58 xen_pfn_t mfn, int nr,
112 pgprot_t prot, unsigned domid, 59 pgprot_t prot, unsigned domid,
113 struct page **pages) 60 struct page **pages)
114{ 61{
115 int err; 62 return xen_xlate_remap_gfn_range(vma, addr, mfn, nr,
116 struct remap_data data; 63 prot, domid, pages);
117
118 /* TBD: Batching, current sole caller only does page at a time */
119 if (nr > 1)
120 return -EINVAL;
121
122 data.fgmfn = mfn;
123 data.prot = prot;
124 data.domid = domid;
125 data.vma = vma;
126 data.index = 0;
127 data.pages = pages;
128 err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
129 remap_pte_fn, &data);
130 return err;
131} 64}
132EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); 65EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
133 66
134int xen_unmap_domain_mfn_range(struct vm_area_struct *vma, 67int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
135 int nr, struct page **pages) 68 int nr, struct page **pages)
136{ 69{
137 int i; 70 return xen_xlate_unmap_gfn_range(vma, nr, pages);
138
139 for (i = 0; i < nr; i++) {
140 struct xen_remove_from_physmap xrp;
141 unsigned long rc, pfn;
142
143 pfn = page_to_pfn(pages[i]);
144
145 xrp.domid = DOMID_SELF;
146 xrp.gpfn = pfn;
147 rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
148 if (rc) {
149 pr_warn("Failed to unmap pfn:%lx rc:%ld\n",
150 pfn, rc);
151 return rc;
152 }
153 }
154 return 0;
155} 71}
156EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); 72EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
157 73