Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Xen: xlate: Use page_to_xen_pfn instead of page_to_pfn

Make xen_xlate_map_ballooned_pages work with 64K pages. In that case
Kernel pages are 64K in size but Xen pages remain 4K in size. Xen pfns
refer to 4K pages.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Tested-by: Julien Grall <julien.grall@arm.com>

authored by

Shannon Zhao and committed by
David Vrabel
975fac3c 243848fc

+27 -11
+27 -11
drivers/xen/xlate_mmu.c
··· 189 189 } 190 190 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range); 191 191 192 + struct map_balloon_pages { 193 + xen_pfn_t *pfns; 194 + unsigned int idx; 195 + }; 196 + 197 + static void setup_balloon_gfn(unsigned long gfn, void *data) 198 + { 199 + struct map_balloon_pages *info = data; 200 + 201 + info->pfns[info->idx++] = gfn; 202 + } 203 + 192 204 /** 193 205 * xen_xlate_map_ballooned_pages - map a new set of ballooned pages 194 206 * @gfns: returns the array of corresponding GFNs ··· 217 205 struct page **pages; 218 206 xen_pfn_t *pfns; 219 207 void *vaddr; 208 + struct map_balloon_pages data; 220 209 int rc; 221 - unsigned int i; 210 + unsigned long nr_pages; 222 211 223 212 BUG_ON(nr_grant_frames == 0); 224 - pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL); 213 + nr_pages = DIV_ROUND_UP(nr_grant_frames, XEN_PFN_PER_PAGE); 214 + pages = kcalloc(nr_pages, sizeof(pages[0]), GFP_KERNEL); 225 215 if (!pages) 226 216 return -ENOMEM; 227 217 ··· 232 218 kfree(pages); 233 219 return -ENOMEM; 234 220 } 235 - rc = alloc_xenballooned_pages(nr_grant_frames, pages); 221 + rc = alloc_xenballooned_pages(nr_pages, pages); 236 222 if (rc) { 237 - pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__, 238 - nr_grant_frames, rc); 223 + pr_warn("%s Couldn't balloon alloc %ld pages rc:%d\n", __func__, 224 + nr_pages, rc); 239 225 kfree(pages); 240 226 kfree(pfns); 241 227 return rc; 242 228 } 243 - for (i = 0; i < nr_grant_frames; i++) 244 - pfns[i] = page_to_pfn(pages[i]); 245 229 246 - vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL); 230 + data.pfns = pfns; 231 + data.idx = 0; 232 + xen_for_each_gfn(pages, nr_grant_frames, setup_balloon_gfn, &data); 233 + 234 + vaddr = vmap(pages, nr_pages, 0, PAGE_KERNEL); 247 235 if (!vaddr) { 248 - pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__, 249 - nr_grant_frames, rc); 250 - free_xenballooned_pages(nr_grant_frames, pages); 236 + pr_warn("%s Couldn't map %ld pages rc:%d\n", __func__, 237 + nr_pages, rc); 238 + free_xenballooned_pages(nr_pages, pages); 251 239 kfree(pages); 252 240 kfree(pfns); 253 241 return -ENOMEM;