aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/grant-table.c57
-rw-r--r--drivers/xen/xlate_mmu.c61
-rw-r--r--include/xen/xen-ops.h2
3 files changed, 69 insertions, 51 deletions
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index e079500b17f3..de4144c24f1c 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared)
111} 111}
112 112
113#ifdef CONFIG_XEN_PVH 113#ifdef CONFIG_XEN_PVH
114#include <xen/balloon.h>
115#include <xen/events.h> 114#include <xen/events.h>
116#include <linux/slab.h> 115#include <xen/xen-ops.h>
117static int __init xlated_setup_gnttab_pages(void)
118{
119 struct page **pages;
120 xen_pfn_t *pfns;
121 void *vaddr;
122 int rc;
123 unsigned int i;
124 unsigned long nr_grant_frames = gnttab_max_grant_frames();
125
126 BUG_ON(nr_grant_frames == 0);
127 pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
128 if (!pages)
129 return -ENOMEM;
130
131 pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
132 if (!pfns) {
133 kfree(pages);
134 return -ENOMEM;
135 }
136 rc = alloc_xenballooned_pages(nr_grant_frames, pages);
137 if (rc) {
138 pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
139 nr_grant_frames, rc);
140 kfree(pages);
141 kfree(pfns);
142 return rc;
143 }
144 for (i = 0; i < nr_grant_frames; i++)
145 pfns[i] = page_to_pfn(pages[i]);
146
147 vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
148 if (!vaddr) {
149 pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
150 nr_grant_frames, rc);
151 free_xenballooned_pages(nr_grant_frames, pages);
152 kfree(pages);
153 kfree(pfns);
154 return -ENOMEM;
155 }
156 kfree(pages);
157
158 xen_auto_xlat_grant_frames.pfn = pfns;
159 xen_auto_xlat_grant_frames.count = nr_grant_frames;
160 xen_auto_xlat_grant_frames.vaddr = vaddr;
161
162 return 0;
163}
164
165static int __init xen_pvh_gnttab_setup(void) 116static int __init xen_pvh_gnttab_setup(void)
166{ 117{
167 if (!xen_pvh_domain()) 118 if (!xen_pvh_domain())
168 return -ENODEV; 119 return -ENODEV;
169 120
170 return xlated_setup_gnttab_pages(); 121 xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
122
123 return xen_xlate_map_ballooned_pages(&xen_auto_xlat_grant_frames.pfn,
124 &xen_auto_xlat_grant_frames.vaddr,
125 xen_auto_xlat_grant_frames.count);
171} 126}
172/* Call it _before_ __gnttab_init as we need to initialize the 127/* Call it _before_ __gnttab_init as we need to initialize the
173 * xen_auto_xlat_grant_frames first. */ 128 * xen_auto_xlat_grant_frames first. */
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 5063c5e796b7..9692656f2fdf 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -29,6 +29,8 @@
29 */ 29 */
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/slab.h>
33#include <linux/vmalloc.h>
32 34
33#include <asm/xen/hypercall.h> 35#include <asm/xen/hypercall.h>
34#include <asm/xen/hypervisor.h> 36#include <asm/xen/hypervisor.h>
@@ -37,6 +39,7 @@
37#include <xen/page.h> 39#include <xen/page.h>
38#include <xen/interface/xen.h> 40#include <xen/interface/xen.h>
39#include <xen/interface/memory.h> 41#include <xen/interface/memory.h>
42#include <xen/balloon.h>
40 43
41typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data); 44typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
42 45
@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
185 return 0; 188 return 0;
186} 189}
187EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range); 190EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
191
192/**
193 * xen_xlate_map_ballooned_pages - map a new set of ballooned pages
194 * @gfns: returns the array of corresponding GFNs
195 * @virt: returns the virtual address of the mapped region
196 * @nr_grant_frames: number of GFNs
197 * @return 0 on success, error otherwise
198 *
199 * This allocates a set of ballooned pages and maps them into the
200 * kernel's address space.
201 */
202int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
203 unsigned long nr_grant_frames)
204{
205 struct page **pages;
206 xen_pfn_t *pfns;
207 void *vaddr;
208 int rc;
209 unsigned int i;
210
211 BUG_ON(nr_grant_frames == 0);
212 pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
213 if (!pages)
214 return -ENOMEM;
215
216 pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
217 if (!pfns) {
218 kfree(pages);
219 return -ENOMEM;
220 }
221 rc = alloc_xenballooned_pages(nr_grant_frames, pages);
222 if (rc) {
223 pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
224 nr_grant_frames, rc);
225 kfree(pages);
226 kfree(pfns);
227 return rc;
228 }
229 for (i = 0; i < nr_grant_frames; i++)
230 pfns[i] = page_to_pfn(pages[i]);
231
232 vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
233 if (!vaddr) {
234 pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
235 nr_grant_frames, rc);
236 free_xenballooned_pages(nr_grant_frames, pages);
237 kfree(pages);
238 kfree(pfns);
239 return -ENOMEM;
240 }
241 kfree(pages);
242
243 *gfns = pfns;
244 *virt = vaddr;
245
246 return 0;
247}
248EXPORT_SYMBOL_GPL(xen_xlate_map_ballooned_pages);
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 86abe07b20ec..072be1c29917 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -85,6 +85,8 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
85 struct page **pages); 85 struct page **pages);
86int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, 86int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
87 int nr, struct page **pages); 87 int nr, struct page **pages);
88int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr,
89 unsigned long nr_grant_frames);
88 90
89bool xen_running_on_version_or_later(unsigned int major, unsigned int minor); 91bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
90 92