]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
x86/p2m: clear_identity_p2m_entry() must cope with 'relaxed' RDM mode
authorJan Beulich <jbeulich@suse.com>
Thu, 13 Aug 2015 12:44:21 +0000 (14:44 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 13 Aug 2015 12:44:21 +0000 (14:44 +0200)
Tearing down a 1:1 mapping that was never established isn't really nice
(and in fact hits an ASSERT() in p2m_remove_page()). Convert from a
wrapper macro to a proper function which then can take care of the
situation.

Also take the opportunity to remove the 'page_order' parameter of
clear_identity_p2m_entry(), to make it match set_identity_p2m_entry().

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
xen/arch/x86/mm/p2m.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/asm-x86/p2m.h

index 7aafaccc761fb5dbf31229f566f41b2a29c0fd6f..8fa918b827fd1a4a769befe28ba4d5cb34171927 100644 (file)
@@ -1019,6 +1019,38 @@ int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
     return rc;
 }
 
+int clear_identity_p2m_entry(struct domain *d, unsigned long gfn)
+{
+    p2m_type_t p2mt;
+    p2m_access_t a;
+    mfn_t mfn;
+    struct p2m_domain *p2m = p2m_get_hostp2m(d);
+    int ret;
+
+    if ( !paging_mode_translate(d) )
+        return 0;
+
+    gfn_lock(p2m, gfn, 0);
+
+    mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, 0, NULL, NULL);
+    if ( p2mt == p2m_mmio_direct && mfn_x(mfn) == gfn )
+    {
+        ret = p2m_set_entry(p2m, gfn, _mfn(INVALID_MFN), PAGE_ORDER_4K,
+                            p2m_invalid, p2m->default_access);
+        gfn_unlock(p2m, gfn, 0);
+    }
+    else
+    {
+        gfn_unlock(p2m, gfn, 0);
+        printk(XENLOG_G_WARNING
+               "non-identity map d%d:%lx not cleared (mapped to %lx)\n",
+               d->domain_id, gfn, mfn_x(mfn));
+        ret = 0;
+    }
+
+    return ret;
+}
+
 /* Returns: 0 for success, -errno for failure */
 int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 {
index 1dffc40058a7bfbb7e76f90f3e469681976a3682..836aed59602ca7e7768007882ae1a155a0792937 100644 (file)
@@ -1839,7 +1839,7 @@ static int rmrr_identity_mapping(struct domain *d, bool_t map,
 
             while ( base_pfn < end_pfn )
             {
-                if ( clear_identity_p2m_entry(d, base_pfn, 0) )
+                if ( clear_identity_p2m_entry(d, base_pfn) )
                     ret = -ENXIO;
                 base_pfn++;
             }
index f4871787dca9e9cca7cb825c022855e77f7ac0a7..5e99ac61caf03708f753031409e417fdd5d5356f 100644 (file)
@@ -563,9 +563,7 @@ int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
 /* Set identity addresses in the p2m table (for pass-through) */
 int set_identity_p2m_entry(struct domain *d, unsigned long gfn,
                            p2m_access_t p2ma, unsigned int flag);
-
-#define clear_identity_p2m_entry(d, gfn, page_order) \
-                        guest_physmap_remove_page(d, gfn, gfn, page_order)
+int clear_identity_p2m_entry(struct domain *d, unsigned long gfn);
 
 /* Add foreign mapping to the guest's p2m table. */
 int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,