|
@@ -125,3 +125,65 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
|
|
|
apply_to_page_range(&init_mm, (unsigned long)shared,
|
|
|
PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL);
|
|
|
}
|
|
|
+#ifdef CONFIG_XEN_PVH
|
|
|
+#include <xen/balloon.h>
|
|
|
+#include <xen/events.h>
|
|
|
+#include <linux/slab.h>
|
|
|
+static int __init xlated_setup_gnttab_pages(void)
|
|
|
+{
|
|
|
+ struct page **pages;
|
|
|
+ xen_pfn_t *pfns;
|
|
|
+ int rc;
|
|
|
+ unsigned int i;
|
|
|
+ unsigned long nr_grant_frames = gnttab_max_grant_frames();
|
|
|
+
|
|
|
+ BUG_ON(nr_grant_frames == 0);
|
|
|
+ pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
|
|
|
+ if (!pages)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
|
|
|
+ if (!pfns) {
|
|
|
+ kfree(pages);
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+ rc = alloc_xenballooned_pages(nr_grant_frames, pages, 0 /* lowmem */);
|
|
|
+ if (rc) {
|
|
|
+ pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
|
|
|
+ nr_grant_frames, rc);
|
|
|
+ kfree(pages);
|
|
|
+ kfree(pfns);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+ for (i = 0; i < nr_grant_frames; i++)
|
|
|
+ pfns[i] = page_to_pfn(pages[i]);
|
|
|
+
|
|
|
+ rc = arch_gnttab_map_shared(pfns, nr_grant_frames, nr_grant_frames,
|
|
|
+ &xen_auto_xlat_grant_frames.vaddr);
|
|
|
+
|
|
|
+ kfree(pages);
|
|
|
+ if (rc) {
|
|
|
+ pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
|
|
|
+ nr_grant_frames, rc);
|
|
|
+ free_xenballooned_pages(nr_grant_frames, pages);
|
|
|
+ kfree(pfns);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ xen_auto_xlat_grant_frames.pfn = pfns;
|
|
|
+ xen_auto_xlat_grant_frames.count = nr_grant_frames;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int __init xen_pvh_gnttab_setup(void)
|
|
|
+{
|
|
|
+ if (!xen_pvh_domain())
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return xlated_setup_gnttab_pages();
|
|
|
+}
|
|
|
+/* Call it _before_ __gnttab_init as we need to initialize the
|
|
|
+ * xen_auto_xlat_grant_frames first. */
|
|
|
+core_initcall(xen_pvh_gnttab_setup);
|
|
|
+#endif
|