Revert "xen/grant-table: Avoid m2p_override during mapping"
[deliverable/linux.git] / drivers / xen / grant-table.c
index 028387192b608b04a9fd9483a9916404cb861f76..b84e3ab839aa06650f98e39da40343f26644532d 100644 (file)
 
 static grant_ref_t **gnttab_list;
 static unsigned int nr_grant_frames;
-static unsigned int boot_max_nr_grant_frames;
 static int gnttab_free_count;
 static grant_ref_t gnttab_free_head;
 static DEFINE_SPINLOCK(gnttab_list_lock);
-unsigned long xen_hvm_resume_frames;
-EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
+struct grant_frames xen_auto_xlat_grant_frames;
 
 static union {
        struct grant_entry_v1 *v1;
@@ -827,6 +825,11 @@ static unsigned int __max_nr_grant_frames(void)
 unsigned int gnttab_max_grant_frames(void)
 {
        unsigned int xen_max = __max_nr_grant_frames();
+       static unsigned int boot_max_nr_grant_frames;
+
+       /* First time, initialize it properly. */
+       if (!boot_max_nr_grant_frames)
+               boot_max_nr_grant_frames = __max_nr_grant_frames();
 
        if (xen_max > boot_max_nr_grant_frames)
                return boot_max_nr_grant_frames;
@@ -834,6 +837,51 @@ unsigned int gnttab_max_grant_frames(void)
 }
 EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
 
+int gnttab_setup_auto_xlat_frames(phys_addr_t addr)
+{
+       xen_pfn_t *pfn;
+       unsigned int max_nr_gframes = __max_nr_grant_frames();
+       unsigned int i;
+       void *vaddr;
+
+       if (xen_auto_xlat_grant_frames.count)
+               return -EINVAL;
+
+       vaddr = xen_remap(addr, PAGE_SIZE * max_nr_gframes);
+       if (vaddr == NULL) {
+               pr_warn("Failed to ioremap gnttab share frames (addr=%pa)!\n",
+                       &addr);
+               return -ENOMEM;
+       }
+       pfn = kcalloc(max_nr_gframes, sizeof(pfn[0]), GFP_KERNEL);
+       if (!pfn) {
+               xen_unmap(vaddr);
+               return -ENOMEM;
+       }
+       for (i = 0; i < max_nr_gframes; i++)
+               pfn[i] = PFN_DOWN(addr) + i;
+
+       xen_auto_xlat_grant_frames.vaddr = vaddr;
+       xen_auto_xlat_grant_frames.pfn = pfn;
+       xen_auto_xlat_grant_frames.count = max_nr_gframes;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gnttab_setup_auto_xlat_frames);
+
+void gnttab_free_auto_xlat_frames(void)
+{
+       if (!xen_auto_xlat_grant_frames.count)
+               return;
+       kfree(xen_auto_xlat_grant_frames.pfn);
+       xen_unmap(xen_auto_xlat_grant_frames.vaddr);
+
+       xen_auto_xlat_grant_frames.pfn = NULL;
+       xen_auto_xlat_grant_frames.count = 0;
+       xen_auto_xlat_grant_frames.vaddr = NULL;
+}
+EXPORT_SYMBOL_GPL(gnttab_free_auto_xlat_frames);
+
 /* Handling of paged out grant targets (GNTST_eagain) */
 #define MAX_DELAY 256
 static inline void
@@ -1060,10 +1108,11 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
        unsigned int nr_gframes = end_idx + 1;
        int rc;
 
-       if (xen_hvm_domain()) {
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
                struct xen_add_to_physmap xatp;
                unsigned int i = end_idx;
                rc = 0;
+               BUG_ON(xen_auto_xlat_grant_frames.count < nr_gframes);
                /*
                 * Loop backwards, so that the first hypercall has the largest
                 * index, ensuring that the table will grow only once.
@@ -1072,7 +1121,7 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
                        xatp.domid = DOMID_SELF;
                        xatp.idx = i;
                        xatp.space = XENMAPSPACE_grant_table;
-                       xatp.gpfn = (xen_hvm_resume_frames >> PAGE_SHIFT) + i;
+                       xatp.gpfn = xen_auto_xlat_grant_frames.pfn[i];
                        rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
                        if (rc != 0) {
                                pr_warn("grant table add_to_physmap failed, err=%d\n",
@@ -1135,10 +1184,8 @@ static void gnttab_request_version(void)
        int rc;
        struct gnttab_set_version gsv;
 
-       if (xen_hvm_domain())
-               gsv.version = 1;
-       else
-               gsv.version = 2;
+       gsv.version = 1;
+
        rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1);
        if (rc == 0 && gsv.version == 2) {
                grant_table_version = 2;
@@ -1169,21 +1216,15 @@ static int gnttab_setup(void)
        if (max_nr_gframes < nr_grant_frames)
                return -ENOSYS;
 
-       if (xen_pv_domain())
-               return gnttab_map(0, nr_grant_frames - 1);
-
-       if (gnttab_shared.addr == NULL) {
-               gnttab_shared.addr = xen_remap(xen_hvm_resume_frames,
-                                               PAGE_SIZE * max_nr_gframes);
+       if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) {
+               gnttab_shared.addr = xen_auto_xlat_grant_frames.vaddr;
                if (gnttab_shared.addr == NULL) {
-                       pr_warn("Failed to ioremap gnttab share frames!\n");
+                       pr_warn("gnttab share frames (addr=0x%08lx) is not mapped!\n",
+                               (unsigned long)xen_auto_xlat_grant_frames.vaddr);
                        return -ENOMEM;
                }
        }
-
-       gnttab_map(0, nr_grant_frames - 1);
-
-       return 0;
+       return gnttab_map(0, nr_grant_frames - 1);
 }
 
 int gnttab_resume(void)
@@ -1226,13 +1267,12 @@ int gnttab_init(void)
 
        gnttab_request_version();
        nr_grant_frames = 1;
-       boot_max_nr_grant_frames = __max_nr_grant_frames();
 
        /* Determine the maximum number of frames required for the
         * grant reference free list on the current hypervisor.
         */
        BUG_ON(grefs_per_grant_frame == 0);
-       max_nr_glist_frames = (boot_max_nr_grant_frames *
+       max_nr_glist_frames = (gnttab_max_grant_frames() *
                               grefs_per_grant_frame / RPP);
 
        gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *),
@@ -1285,5 +1325,6 @@ static int __gnttab_init(void)
 
        return gnttab_init();
 }
-
-core_initcall(__gnttab_init);
+/* Starts after core_initcall so that xen_pvh_gnttab_setup can be called
+ * beforehand to initialize xen_auto_xlat_grant_frames. */
+core_initcall_sync(__gnttab_init);
This page took 0.066475 seconds and 5 git commands to generate.