x86/ibt,kexec: Disable CET on kexec
authorPeter Zijlstra <peterz@infradead.org>
Tue, 8 Mar 2022 15:30:36 +0000 (16:30 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Tue, 15 Mar 2022 09:32:39 +0000 (10:32 +0100)
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/r/20220308154318.641454603@infradead.org
arch/x86/include/asm/cpu.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/machine_kexec_64.c
arch/x86/kernel/relocate_kernel_64.S

index a60025f..86e5e4e 100644 (file)
@@ -73,4 +73,7 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
 #else
 static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}
 #endif
+
+extern __noendbr void cet_disable(void);
+
 #endif /* _ASM_X86_CPU_H */
index db1f149..709acab 100644 (file)
@@ -535,6 +535,12 @@ static __always_inline void setup_cet(struct cpuinfo_x86 *c)
        }
 }
 
+__noendbr void cet_disable(void)
+{
+       if (cpu_feature_enabled(X86_FEATURE_IBT))
+               wrmsrl(MSR_IA32_S_CET, 0);
+}
+
 /*
  * Some CPU features depend on higher CPUID levels, which may not always
  * be available due to CPUID level capping or broken virtualization
index f5da4a1..566bb8e 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/kexec-bzimage64.h>
 #include <asm/setup.h>
 #include <asm/set_memory.h>
+#include <asm/cpu.h>
 
 #ifdef CONFIG_ACPI
 /*
@@ -310,6 +311,7 @@ void machine_kexec(struct kimage *image)
        /* Interrupts aren't acceptable while we reboot */
        local_irq_disable();
        hw_breakpoint_disable();
+       cet_disable();
 
        if (image->preserve_context) {
 #ifdef CONFIG_X86_IO_APIC
@@ -325,7 +327,7 @@ void machine_kexec(struct kimage *image)
        }
 
        control_page = page_address(image->control_code_page) + PAGE_SIZE;
-       memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
+       __memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
 
        page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
        page_list[VA_CONTROL_PAGE] = (unsigned long)control_page;
index 399f075..5b65f6e 100644 (file)
@@ -115,6 +115,14 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped)
        pushq   %rdx
 
        /*
+        * Clear X86_CR4_CET (if it was set) such that we can clear CR0_WP
+        * below.
+        */
+       movq    %cr4, %rax
+       andq    $~(X86_CR4_CET), %rax
+       movq    %rax, %cr4
+
+       /*
         * Set cr0 to a known state:
         *  - Paging enabled
         *  - Alignment check disabled