diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/xen/grant-table.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c index 3a5f55d51907..2d719799fd6a 100644 --- a/arch/x86/xen/grant-table.c +++ b/arch/x86/xen/grant-table.c | |||
@@ -125,3 +125,65 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes) | |||
125 | apply_to_page_range(&init_mm, (unsigned long)shared, | 125 | apply_to_page_range(&init_mm, (unsigned long)shared, |
126 | PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); | 126 | PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); |
127 | } | 127 | } |
128 | #ifdef CONFIG_XEN_PVH | ||
129 | #include <xen/balloon.h> | ||
130 | #include <xen/events.h> | ||
131 | #include <linux/slab.h> | ||
132 | static int __init xlated_setup_gnttab_pages(void) | ||
133 | { | ||
134 | struct page **pages; | ||
135 | xen_pfn_t *pfns; | ||
136 | int rc; | ||
137 | unsigned int i; | ||
138 | unsigned long nr_grant_frames = gnttab_max_grant_frames(); | ||
139 | |||
140 | BUG_ON(nr_grant_frames == 0); | ||
141 | pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL); | ||
142 | if (!pages) | ||
143 | return -ENOMEM; | ||
144 | |||
145 | pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL); | ||
146 | if (!pfns) { | ||
147 | kfree(pages); | ||
148 | return -ENOMEM; | ||
149 | } | ||
150 | rc = alloc_xenballooned_pages(nr_grant_frames, pages, 0 /* lowmem */); | ||
151 | if (rc) { | ||
152 | pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__, | ||
153 | nr_grant_frames, rc); | ||
154 | kfree(pages); | ||
155 | kfree(pfns); | ||
156 | return rc; | ||
157 | } | ||
158 | for (i = 0; i < nr_grant_frames; i++) | ||
159 | pfns[i] = page_to_pfn(pages[i]); | ||
160 | |||
161 | rc = arch_gnttab_map_shared(pfns, nr_grant_frames, nr_grant_frames, | ||
162 | &xen_auto_xlat_grant_frames.vaddr); | ||
163 | |||
164 | kfree(pages); | ||
165 | if (rc) { | ||
166 | pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__, | ||
167 | nr_grant_frames, rc); | ||
168 | free_xenballooned_pages(nr_grant_frames, pages); | ||
169 | kfree(pfns); | ||
170 | return rc; | ||
171 | } | ||
172 | |||
173 | xen_auto_xlat_grant_frames.pfn = pfns; | ||
174 | xen_auto_xlat_grant_frames.count = nr_grant_frames; | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int __init xen_pvh_gnttab_setup(void) | ||
180 | { | ||
181 | if (!xen_pvh_domain()) | ||
182 | return -ENODEV; | ||
183 | |||
184 | return xlated_setup_gnttab_pages(); | ||
185 | } | ||
186 | /* Call it _before_ __gnttab_init as we need to initialize the | ||
187 | * xen_auto_xlat_grant_frames first. */ | ||
188 | core_initcall(xen_pvh_gnttab_setup); | ||
189 | #endif | ||