]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
x86: Enable CET Indirect Branch Tracking
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 1 Nov 2021 15:17:20 +0000 (15:17 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 23 Feb 2022 15:33:43 +0000 (15:33 +0000)
With all the pieces now in place, turn CET-IBT on when available.

MSR_S_CET, like SMEP/SMAP, controls Ring1 meaning that ENDBR_EN can't be
enabled for Xen independently of PV32 kernels.  As we already disable PV32 for
CET-SS, extend this to all CET, adjusting the documentation/comments as
appropriate.

Introduce a cet=no-ibt command line option to allow the admin to disable IBT
even when everything else is configured correctly.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
docs/misc/xen-command-line.pandoc
xen/arch/x86/cpu/common.c
xen/arch/x86/setup.c

index 321a9abfc1683183ec21444bdab264ce623b29b1..efda335652730d34f112fe532bd2470dad12d148 100644 (file)
@@ -271,7 +271,7 @@ enough. Setting this to a high value may cause boot failure, particularly if
 the NMI watchdog is also enabled.
 
 ### cet
-    = List of [ shstk=<bool> ]
+    = List of [ shstk=<bool>, ibt=<bool> ]
 
     Applicability: x86
 
@@ -279,6 +279,10 @@ Controls for the use of Control-flow Enforcement Technology.  CET is group a
 of hardware features designed to combat Return-oriented Programming (ROP, also
 call/jmp COP/JOP) attacks.
 
+CET is incompatible with 32bit PV guests.  If any CET sub-options are active,
+they will override the `pv=32` boolean to `false`.  Backwards compatibility
+can be maintained with the pv-shim mechanism.
+
 *   The `shstk=` boolean controls whether Xen uses Shadow Stacks for its own
     protection.
 
@@ -287,9 +291,13 @@ call/jmp COP/JOP) attacks.
     `cet=no-shstk` will cause Xen not to use Shadow Stacks even when support
     is available in hardware.
 
-    Shadow Stacks are incompatible with 32bit PV guests.  This option will
-    override the `pv=32` boolean to false.  Backwards compatibility can be
-    maintained with the `pv-shim` mechanism.
+*   The `ibt=` boolean controls whether Xen uses Indirect Branch Tracking for
+    its own protection.
+
+    The option is available when `CONFIG_XEN_IBT` is compiled in, and defaults
+    to `true` on hardware supporting CET-IBT.  Specifying `cet=no-ibt` will
+    cause Xen not to use Indirect Branch Tracking even when support is
+    available in hardware.
 
 ### clocksource (x86)
 > `= pit | hpet | acpi | tsc`
index 2429818e6033dcc97df2351735effb21fd401cf6..bfedc99b9244e2a14307e0480bdf51a53b349569 100644 (file)
@@ -348,6 +348,7 @@ void __init early_cpu_init(void)
        if (c->cpuid_level >= 7) {
                cpuid_count(7, 0, &eax, &ebx, &ecx, &edx);
                c->x86_capability[cpufeat_word(X86_FEATURE_CET_SS)] = ecx;
+               c->x86_capability[cpufeat_word(X86_FEATURE_CET_IBT)] = edx;
        }
 
        eax = cpuid_eax(0x80000000);
index bc11be5ba7c57edd0b5b7e7d3381d7b2844e515a..22a9885dee5cf830d01dc5cf650fc42fdee56951 100644 (file)
@@ -102,6 +102,12 @@ static bool __initdata opt_xen_shstk = true;
 #define opt_xen_shstk false
 #endif
 
+#ifdef CONFIG_XEN_IBT
+static bool __initdata opt_xen_ibt = true;
+#else
+#define opt_xen_ibt false
+#endif
+
 static int __init cf_check parse_cet(const char *s)
 {
     const char *ss;
@@ -118,6 +124,14 @@ static int __init cf_check parse_cet(const char *s)
             opt_xen_shstk = val;
 #else
             no_config_param("XEN_SHSTK", "cet", s, ss);
+#endif
+        }
+        else if ( (val = parse_boolean("ibt", s, ss)) >= 0 )
+        {
+#ifdef CONFIG_XEN_IBT
+            opt_xen_ibt = val;
+#else
+            no_config_param("XEN_IBT", "cet", s, ss);
 #endif
         }
         else
@@ -1118,11 +1132,33 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         printk("Enabling Supervisor Shadow Stacks\n");
 
         setup_force_cpu_cap(X86_FEATURE_XEN_SHSTK);
+    }
+
+    if ( opt_xen_ibt && boot_cpu_has(X86_FEATURE_CET_IBT) )
+    {
+        printk("Enabling Indirect Branch Tracking\n");
+
+        setup_force_cpu_cap(X86_FEATURE_XEN_IBT);
+
+        if ( efi_enabled(EFI_RS) )
+            printk("  - IBT disabled in UEFI Runtime Services\n");
+
+        /*
+         * Enable IBT now.  Only require the endbr64 on callees, which is
+         * entirely build-time arrangements.
+         */
+        wrmsrl(MSR_S_CET, CET_ENDBR_EN);
+    }
+
+    if ( cpu_has_xen_shstk || cpu_has_xen_ibt )
+    {
+        set_in_cr4(X86_CR4_CET);
+
 #ifdef CONFIG_PV32
         if ( opt_pv32 )
         {
             opt_pv32 = 0;
-            printk("  - Disabling PV32 due to Shadow Stacks\n");
+            printk("  - Disabling PV32 due to CET\n");
         }
 #endif
     }
@@ -1847,10 +1883,6 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     alternative_branches();
 
-    /* Defer CR4.CET until alternatives have finished playing with CR0.WP */
-    if ( cpu_has_xen_shstk )
-        set_in_cr4(X86_CR4_CET);
-
     /*
      * NB: when running as a PV shim VCPUOP_up/down is wired to the shim
      * physical cpu_add/remove functions, so launch the guest with only