]> xenbits.xensource.com Git - people/andrewcoop/xen.git/commitdiff
x86/alternatives: Factor seal_endbr64() out of _apply_alternatives()
authorAndrew Cooper <andrew.cooper3@citrix.com>
Sun, 20 Apr 2025 00:19:47 +0000 (01:19 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 23 Apr 2025 18:37:57 +0000 (19:37 +0100)
We are going to need to reposition the call in a change with several moving
parts.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/alternative.c

index 9aa591b364a469e47feea93c5cb800f0f9232d9d..4b9f8d86015342ef1cb9978549d5ea7a52672cca 100644 (file)
@@ -162,6 +162,44 @@ text_poke(void *addr, const void *opcode, size_t len)
 extern void *const __initdata_cf_clobber_start[];
 extern void *const __initdata_cf_clobber_end[];
 
+/*
+ * In CET-IBT enabled builds, clobber endbr64 instructions after altcall has
+ * finished optimising all indirect branches to direct ones.
+ */
+static void __init seal_endbr64(void)
+{
+    void *const *val;
+    unsigned int clobbered = 0;
+
+    if ( !cpu_has_xen_ibt )
+        return;
+
+    /*
+     * This is some minor structure (ab)use.  We walk the entire contents
+     * of .init.{ro,}data.cf_clobber as if it were an array of pointers.
+     *
+     * If the pointer points into .text, and at an endbr64 instruction,
+     * nop out the endbr64.  This causes the pointer to no longer be a
+     * legal indirect branch target under CET-IBT.  This is a
+     * defence-in-depth measure, to reduce the options available to an
+     * adversary who has managed to hijack a function pointer.
+     */
+    for ( val = __initdata_cf_clobber_start;
+          val < __initdata_cf_clobber_end;
+          val++ )
+    {
+        void *ptr = *val;
+
+        if ( !is_kernel_text(ptr) || !is_endbr64(ptr) )
+            continue;
+
+        place_endbr64_poison(ptr);
+        clobbered++;
+    }
+
+    printk("altcall: Optimised away %u endbr64 instructions\n", clobbered);
+}
+
 /*
  * Replace instructions with better alternatives for this CPU type.
  * This runs before SMP is initialized to avoid SMP problems with
@@ -344,36 +382,8 @@ static int init_or_livepatch _apply_alternatives(struct alt_instr *start,
      * Clobber endbr64 instructions now that altcall has finished optimising
      * all indirect branches to direct ones.
      */
-    if ( force && cpu_has_xen_ibt && system_state < SYS_STATE_active )
-    {
-        void *const *val;
-        unsigned int clobbered = 0;
-
-        /*
-         * This is some minor structure (ab)use.  We walk the entire contents
-         * of .init.{ro,}data.cf_clobber as if it were an array of pointers.
-         *
-         * If the pointer points into .text, and at an endbr64 instruction,
-         * nop out the endbr64.  This causes the pointer to no longer be a
-         * legal indirect branch target under CET-IBT.  This is a
-         * defence-in-depth measure, to reduce the options available to an
-         * adversary who has managed to hijack a function pointer.
-         */
-        for ( val = __initdata_cf_clobber_start;
-              val < __initdata_cf_clobber_end;
-              val++ )
-        {
-            void *ptr = *val;
-
-            if ( !is_kernel_text(ptr) || !is_endbr64(ptr) )
-                continue;
-
-            place_endbr64_poison(ptr);
-            clobbered++;
-        }
-
-        printk("altcall: Optimised away %u endbr64 instructions\n", clobbered);
-    }
+    if ( force && system_state < SYS_STATE_active )
+        seal_endbr64();
 
     return 0;
 }