aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-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