[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 2/2] x86/dom0: only disable SMAP for the PV dom0 build



The PVH dom0 builder doesn't switch page tables and has no need to run with
SMAP disabled.

Use stac() and clac(), as that's safe to use even if events would hit in the
middle of the region with SMAP disabled.  Nesting stac() and clac() calls is
not safe, so the stac() call is done strictly after elf_load_binary() because
that uses raw_{copy_to,clear}_guest() accessors which toggle SMAP.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/arch/x86/pv/dom0_build.c | 13 +++++++++++++
 xen/arch/x86/setup.c         | 17 -----------------
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
index 57e58a02e707..ad804579cb6f 100644
--- a/xen/arch/x86/pv/dom0_build.c
+++ b/xen/arch/x86/pv/dom0_build.c
@@ -830,6 +830,15 @@ int __init dom0_construct_pv(struct domain *d,
         printk("Failed to load the kernel binary\n");
         goto out;
     }
+
+    /*
+     * Disable SMAP to allow user-accesses when running on dom0 page-tables.
+     * Note this must be done after elf_load_binary(), as such helper uses
+     * raw_{copy_to,clear}_guest() helpers which internally call stac()/clac()
+     * and those calls would otherwise nest with the ones here.
+     */
+    stac();
+
     bootstrap_map(NULL);
 
     if ( UNSET_ADDR != parms.virt_hypercall )
@@ -837,6 +846,7 @@ int __init dom0_construct_pv(struct domain *d,
         if ( (parms.virt_hypercall < v_start) ||
              (parms.virt_hypercall >= v_end) )
         {
+            clac();
             mapcache_override_current(NULL);
             switch_cr3_cr4(current->arch.cr3, read_cr4());
             printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
@@ -978,6 +988,9 @@ int __init dom0_construct_pv(struct domain *d,
                                     : XLAT_start_info_console_dom0);
 #endif
 
+    /* Possibly re-enable SMAP. */
+    clac();
+
     /* Return to idle domain's page tables. */
     mapcache_override_current(NULL);
     switch_cr3_cr4(current->arch.cr3, read_cr4());
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index eee20bb1753c..bc387d96b519 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -955,26 +955,9 @@ static struct domain *__init create_dom0(const module_t 
*image,
         }
     }
 
-    /*
-     * Temporarily clear SMAP in CR4 to allow user-accesses in 
construct_dom0().
-     * This saves a large number of corner cases interactions with
-     * copy_from_user().
-     */
-    if ( cpu_has_smap )
-    {
-        cr4_pv32_mask &= ~X86_CR4_SMAP;
-        write_cr4(read_cr4() & ~X86_CR4_SMAP);
-    }
-
     if ( construct_dom0(d, image, headroom, initrd, cmdline) != 0 )
         panic("Could not construct domain 0\n");
 
-    if ( cpu_has_smap )
-    {
-        write_cr4(read_cr4() | X86_CR4_SMAP);
-        cr4_pv32_mask |= X86_CR4_SMAP;
-    }
-
     return d;
 }
 
-- 
2.45.2




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.