History

Merge tag 'x86_core_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull more x86 updates from Borislav Petkov: - Remove a bunch of asm implementing condition flags testing in KVM's emulator in favor of int3_emulate_jcc() which is written in C - Replace KVM fastops with C-based stubs which avoids problems with the fastop infra related to latter not adhering to the C ABI due to their special calling convention and, more importantly, bypassing compiler control-flow integrity checking because they're written in asm - Remove wrongly used static branches and other ugliness accumulated over time in hyperv's hypercall implementation with a proper static function call to the correct hypervisor call variant - Add some fixes and modifications to allow running FRED-enabled kernels in KVM even on non-FRED hardware - Add kCFI improvements like validating indirect calls and prepare for enabling kCFI with GCC. Add cmdline params documentation and other code cleanups - Use the single-byte 0xd6 insn as the official #UD single-byte undefined opcode instruction as agreed upon by both x86 vendors - Other smaller cleanups and touchups all over the place * tag 'x86_core_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86,retpoline: Optimize patch_retpoline() x86,ibt: Use UDB instead of 0xEA x86/cfi: Remove __noinitretpoline and __noretpoline x86/cfi: Add "debug" option to "cfi=" bootparam x86/cfi: Standardize on common "CFI:" prefix for CFI reports x86/cfi: Document the "cfi=" bootparam options x86/traps: Clarify KCFI instruction layout compiler_types.h: Move __nocfi out of compiler-specific header objtool: Validate kCFI calls x86/fred: KVM: VMX: Always use FRED for IRQs when CONFIG_X86_FRED=y x86/fred: Play nice with invoking asm_fred_entry_from_kvm() on non-FRED hardware x86/fred: Install system vector handlers even if FRED isn't fully enabled x86/hyperv: Use direct call to hypercall-page x86/hyperv: Clean up hv_do_hypercall() KVM: x86: Remove fastops KVM: x86: Convert em_salc() to C KVM: x86: Introduce EM_ASM_3WCL KVM: x86: Introduce EM_ASM_1SRC2 KVM: x86: Introduce EM_ASM_2CL KVM: x86: Introduce EM_ASM_2W ...

Linus Torvalds committed 1 year ago

Commit 9591fdb2 parents 2f0a750 4a1e02b36 files · +728 −665Browse files

Unified · Split

36 files
  1. Documentation/admin-guide/kernel-parameters.txt +18 −0
  2. arch/x86/entry/calling.h +5 −6
  3. arch/x86/entry/entry_64_fred.S +26 −7
  4. arch/x86/hyperv/hv_init.c +44 −25
  5. arch/x86/hyperv/ivm.c +15 −0
  6. arch/x86/include/asm/bug.h +7 −2
  7. arch/x86/include/asm/cfi.h +6 −8
  8. arch/x86/include/asm/ibt.h +3 −7
  9. arch/x86/include/asm/idtentry.h +2 −7
  10. arch/x86/include/asm/mshyperv.h +41 −96
  11. arch/x86/include/asm/text-patching.h +13 −7
  12. arch/x86/kernel/alternative.c +176 −116
  13. arch/x86/kernel/asm-offsets.c +1 −0
  14. arch/x86/kernel/cfi.c +1 −1
  15. arch/x86/kernel/cpu/mshyperv.c +13 −6
  16. arch/x86/kernel/irqinit.c +4 −2
  17. arch/x86/kernel/machine_kexec_64.c +4 −0
  18. arch/x86/kernel/traps.c +4 −4
  19. arch/x86/kvm/Kconfig +1 −0
  20. arch/x86/kvm/emulate.c +232 −318
  21. arch/x86/kvm/vmx/vmenter.S +4 −0
  22. arch/x86/kvm/vmx/vmx.c +7 −1
  23. arch/x86/lib/bhi.S +29 −29
  24. arch/x86/lib/retpoline.S +2 −2
  25. arch/x86/net/bpf_jit_comp.c +3 −3
  26. arch/x86/platform/efi/efi_stub_64.S +4 −0
  27. drivers/misc/lkdtm/perms.c +5 −0
  28. include/linux/compiler-clang.h +0 −5
  29. include/linux/compiler-gcc.h +0 −4
  30. include/linux/compiler_types.h +3 −1
  31. include/linux/init.h +0 −8
  32. include/linux/objtool.h +10 −0
  33. include/linux/objtool_types.h +1 −0
  34. tools/include/linux/objtool_types.h +1 −0
  35. tools/objtool/check.c +42 −0
  36. tools/objtool/include/objtool/elf.h +1 −0
Documentation/admin-guide/kernel-parameters.txt+18−0
@@ -608,6 +608,24 @@ · 607 unmodified lines
608608 ccw_timeout_log [S390]
609609 See Documentation/arch/s390/common_io.rst for details.
610610
611+ cfi= [X86-64] Set Control Flow Integrity checking features
612+ when CONFIG_FINEIBT is enabled.
613+ Format: feature[,feature...]
614+ Default: auto
615+
616+ auto: Use FineIBT if IBT available, otherwise kCFI.
617+ Under FineIBT, enable "paranoid" mode when
618+ FRED is not available.
619+ off: Turn off CFI checking.
620+ kcfi: Use kCFI (disable FineIBT).
621+ fineibt: Use FineIBT (even if IBT not available).
622+ norand: Do not re-randomize CFI hashes.
623+ paranoid: Add caller hash checking under FineIBT.
624+ bhi: Enable register poisoning to stop speculation
625+ across FineIBT. (Disabled by default.)
626+ warn: Do not enforce CFI checking: warn only.
627+ debug: Report CFI initialization details.
628+
611629 cgroup_disable= [KNL] Disable a particular controller or optional feature
612630 Format: {name of the controller(s) or feature(s) to disable}
613631 The effects of cgroup_disable=foo are:
arch/x86/entry/calling.h+5−6
@@ -99,7 +99,7 @@ For 32-bit we have the following conventions - kernel is built with · 98 unmodified lines
9999 .endif
100100 .endm
101101
102−.macro CLEAR_REGS clear_bp=1
102+.macro CLEAR_REGS clear_callee=1
103103 /*
104104 * Sanitize registers of values that a speculation attack might
105105 * otherwise want to exploit. The lower registers are likely clobbered
@@ -113,20 +113,19 @@ For 32-bit we have the following conventions - kernel is built with · 7 unmodified lines
113113 xorl %r9d, %r9d /* nospec r9 */
114114 xorl %r10d, %r10d /* nospec r10 */
115115 xorl %r11d, %r11d /* nospec r11 */
116+ .if \clear_callee
116117 xorl %ebx, %ebx /* nospec rbx */
117− .if \clear_bp
118118 xorl %ebp, %ebp /* nospec rbp */
119− .endif
120119 xorl %r12d, %r12d /* nospec r12 */
121120 xorl %r13d, %r13d /* nospec r13 */
122121 xorl %r14d, %r14d /* nospec r14 */
123122 xorl %r15d, %r15d /* nospec r15 */
124−
123+ .endif
125124 .endm
126125
127−.macro PUSH_AND_CLEAR_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0 clear_bp=1 unwind_hint=1
126+.macro PUSH_AND_CLEAR_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0 clear_callee=1 unwind_hint=1
128127 PUSH_REGS rdx=\rdx, rcx=\rcx, rax=\rax, save_ret=\save_ret unwind_hint=\unwind_hint
129− CLEAR_REGS clear_bp=\clear_bp
128+ CLEAR_REGS clear_callee=\clear_callee
130129 .endm
131130
132131 .macro POP_REGS pop_rdi=1
arch/x86/entry/entry_64_fred.S+26−7
@@ -111,18 +111,37 @@ SYM_FUNC_START(asm_fred_entry_from_kvm) · 110 unmodified lines
111111 push %rax /* Return RIP */
112112 push $0 /* Error code, 0 for IRQ/NMI */
113113
114− PUSH_AND_CLEAR_REGS clear_bp=0 unwind_hint=0
114+ PUSH_AND_CLEAR_REGS clear_callee=0 unwind_hint=0
115+
115116 movq %rsp, %rdi /* %rdi -> pt_regs */
117+ /*
118+ * At this point: {rdi, rsi, rdx, rcx, r8, r9}, {r10, r11}, {rax, rdx}
119+ * are clobbered, which corresponds to: arguments, extra caller-saved
120+ * and return. All registers a C function is allowed to clobber.
121+ *
122+ * Notably, the callee-saved registers: {rbx, r12, r13, r14, r15}
123+ * are untouched, with the exception of rbp, which carries the stack
124+ * frame and will be restored before exit.
125+ *
126+ * Further calling another C function will not alter this state.
127+ */
116128 call __fred_entry_from_kvm /* Call the C entry point */
117− POP_REGS
118− ERETS
119−1:
129+
120130 /*
121− * Objtool doesn't understand what ERETS does, this hint tells it that
122− * yes, we'll reach here and with what stack state. A save/restore pair
123− * isn't strictly needed, but it's the simplest form.
131+ * When FRED, use ERETS to potentially clear NMIs, otherwise simply
132+ * restore the stack pointer.
133+ */
134+ ALTERNATIVE "nop; nop; mov %rbp, %rsp", \
135+ __stringify(add $C_PTREGS_SIZE, %rsp; ERETS), \
136+ X86_FEATURE_FRED
137+
138+1: /*
139+ * Objtool doesn't understand ERETS, and the cfi register state is
140+ * different from initial_func_cfi due to PUSH_REGS. Tell it the state
141+ * is similar to where UNWIND_HINT_SAVE is.
124142 */
125143 UNWIND_HINT_RESTORE
144+
126145 pop %rbp
127146 RET
128147
arch/x86/hyperv/hv_init.c+44−25
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717 #include <asm/desc.h>
1818 #include <asm/e820/api.h>
1919 #include <asm/sev.h>
20−#include <asm/ibt.h>
2120 #include <asm/hypervisor.h>
2221 #include <hyperv/hvhdk.h>
2322 #include <asm/mshyperv.h>
@@ -37,7 +36,45 @@ · 13 unmodified lines
3736 #include <linux/export.h>
3837
3938 void *hv_hypercall_pg;
39+
40+#ifdef CONFIG_X86_64
41+static u64 __hv_hyperfail(u64 control, u64 param1, u64 param2)
42+{
43+ return U64_MAX;
44+}
45+
46+DEFINE_STATIC_CALL(__hv_hypercall, __hv_hyperfail);
47+
48+u64 hv_std_hypercall(u64 control, u64 param1, u64 param2)
49+{
50+ u64 hv_status;
51+
52+ register u64 __r8 asm("r8") = param2;
53+ asm volatile ("call " STATIC_CALL_TRAMP_STR(__hv_hypercall)
54+ : "=a" (hv_status), ASM_CALL_CONSTRAINT,
55+ "+c" (control), "+d" (param1), "+r" (__r8)
56+ : : "cc", "memory", "r9", "r10", "r11");
57+
58+ return hv_status;
59+}
60+
61+typedef u64 (*hv_hypercall_f)(u64 control, u64 param1, u64 param2);
62+
63+static inline void hv_set_hypercall_pg(void *ptr)
64+{
65+ hv_hypercall_pg = ptr;
66+
67+ if (!ptr)
68+ ptr = &__hv_hyperfail;
69+ static_call_update(__hv_hypercall, (hv_hypercall_f)ptr);
70+}
71+#else
72+static inline void hv_set_hypercall_pg(void *ptr)
73+{
74+ hv_hypercall_pg = ptr;
75+}
4076 EXPORT_SYMBOL_GPL(hv_hypercall_pg);
77+#endif
4178
4279 union hv_ghcb * __percpu *hv_ghcb_pg;
4380
@@ -330,7 +367,7 @@ static int hv_suspend(void) · 286 unmodified lines
330367 * pointer is restored on resume.
331368 */
332369 hv_hypercall_pg_saved = hv_hypercall_pg;
333− hv_hypercall_pg = NULL;
370+ hv_set_hypercall_pg(NULL);
334371
335372 /* Disable the hypercall page in the hypervisor */
336373 rdmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -356,7 +393,7 @@ static void hv_resume(void) · 19 unmodified lines
356393 vmalloc_to_pfn(hv_hypercall_pg_saved);
357394 wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
358395
359− hv_hypercall_pg = hv_hypercall_pg_saved;
396+ hv_set_hypercall_pg(hv_hypercall_pg_saved);
360397 hv_hypercall_pg_saved = NULL;
361398
362399 /*
@@ -476,8 +513,8 @@ void __init hyperv_init(void) · 113 unmodified lines
476513 if (hv_isolation_type_tdx() && !ms_hyperv.paravisor_present)
477514 goto skip_hypercall_pg_init;
478515
479− hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START,
480− VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_ROX,
516+ hv_hypercall_pg = __vmalloc_node_range(PAGE_SIZE, 1, MODULES_VADDR,
517+ MODULES_END, GFP_KERNEL, PAGE_KERNEL_ROX,
481518 VM_FLUSH_RESET_PERMS, NUMA_NO_NODE,
482519 __builtin_return_address(0));
483520 if (hv_hypercall_pg == NULL)
@@ -515,27 +552,9 @@ void __init hyperv_init(void) · 31 unmodified lines
515552 wrmsrq(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
516553 }
517554
518−skip_hypercall_pg_init:
519− /*
520− * Some versions of Hyper-V that provide IBT in guest VMs have a bug
521− * in that there's no ENDBR64 instruction at the entry to the
522− * hypercall page. Because hypercalls are invoked via an indirect call
523− * to the hypercall page, all hypercall attempts fail when IBT is
524− * enabled, and Linux panics. For such buggy versions, disable IBT.
525− *
526− * Fixed versions of Hyper-V always provide ENDBR64 on the hypercall
527− * page, so if future Linux kernel versions enable IBT for 32-bit
528− * builds, additional hypercall page hackery will be required here
529− * to provide an ENDBR32.
530− */
531−#ifdef CONFIG_X86_KERNEL_IBT
532− if (cpu_feature_enabled(X86_FEATURE_IBT) &&
533− *(u32 *)hv_hypercall_pg != gen_endbr()) {
534− setup_clear_cpu_cap(X86_FEATURE_IBT);
535− pr_warn("Disabling IBT because of Hyper-V bug\n");
536− }
537−#endif
555+ hv_set_hypercall_pg(hv_hypercall_pg);
538556
557+skip_hypercall_pg_init:
539558 /*
540559 * hyperv_init() is called before LAPIC is initialized: see
541560 * apic_intr_mode_init() -> x86_platform.apic_post_init() and
arch/x86/hyperv/ivm.c+15−0
@@ -385,9 +385,23 @@ int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu) · 384 unmodified lines
385385 return ret;
386386 }
387387
388+u64 hv_snp_hypercall(u64 control, u64 param1, u64 param2)
389+{
390+ u64 hv_status;
391+
392+ register u64 __r8 asm("r8") = param2;
393+ asm volatile("vmmcall"
394+ : "=a" (hv_status), ASM_CALL_CONSTRAINT,
395+ "+c" (control), "+d" (param1), "+r" (__r8)
396+ : : "cc", "memory", "r9", "r10", "r11");
397+
398+ return hv_status;
399+}
400+
388401 #else
389402 static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
390403 static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
404+u64 hv_snp_hypercall(u64 control, u64 param1, u64 param2) { return U64_MAX; }
391405 #endif /* CONFIG_AMD_MEM_ENCRYPT */
392406
393407 #ifdef CONFIG_INTEL_TDX_GUEST
@@ -437,6 +451,7 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2) · 43 unmodified lines
437451 #else
438452 static inline void hv_tdx_msr_write(u64 msr, u64 value) {}
439453 static inline void hv_tdx_msr_read(u64 msr, u64 *value) {}
454+u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2) { return U64_MAX; }
440455 #endif /* CONFIG_INTEL_TDX_GUEST */
441456
442457 #if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
arch/x86/include/asm/bug.h+7−2
@@ -5,14 +5,19 @@ · 4 unmodified lines
55 #include <linux/stringify.h>
66 #include <linux/instrumentation.h>
77 #include <linux/objtool.h>
8+#include <asm/asm.h>
89
910 /*
1011 * Despite that some emulators terminate on UD2, we use it for WARN().
1112 */
12−#define ASM_UD2 ".byte 0x0f, 0x0b"
13+#define ASM_UD2 _ASM_BYTES(0x0f, 0x0b)
1314 #define INSN_UD2 0x0b0f
1415 #define LEN_UD2 2
1516
17+#define ASM_UDB _ASM_BYTES(0xd6)
18+#define INSN_UDB 0xd6
19+#define LEN_UDB 1
20+
1621 /*
1722 * In clang we have UD1s reporting UBSAN failures on X86, 64 and 32bit.
1823 */
@@ -26,7 +31,7 @@ · 7 unmodified lines
2631 #define BUG_UD2 0xfffe
2732 #define BUG_UD1 0xfffd
2833 #define BUG_UD1_UBSAN 0xfffc
29−#define BUG_EA 0xffea
34+#define BUG_UDB 0xffd6
3035 #define BUG_LOCK 0xfff0
3136
3237 #ifdef CONFIG_GENERIC_BUG
arch/x86/include/asm/cfi.h+6−8
@@ -71,12 +71,10 @@ · 70 unmodified lines
7171 *
7272 * __cfi_foo:
7373 * endbr64
74− * subl 0x12345678, %r10d
75− * jz foo
76− * ud2
77− * nop
74+ * subl 0x12345678, %eax
75+ * jne.32,pn foo+3
7876 * foo:
79− * osp nop3 # was endbr64
77+ * nopl -42(%rax) # was endbr64
8078 * ... code here ...
8179 * ret
8280 *
@@ -86,9 +84,9 @@ · 3 unmodified lines
8684 * indirect caller:
8785 * lea foo(%rip), %r11
8886 * ...
89− * movl $0x12345678, %r10d
90− * subl $16, %r11
91− * nop4
87+ * movl $0x12345678, %eax
88+ * lea -0x10(%r11), %r11
89+ * nop5
9290 * call *%r11
9391 *
9492 */
arch/x86/include/asm/ibt.h+3−7
@@ -59,10 +59,10 @@ static __always_inline __attribute_const__ u32 gen_endbr(void) · 58 unmodified lines
5959 static __always_inline __attribute_const__ u32 gen_endbr_poison(void)
6060 {
6161 /*
62− * 4 byte NOP that isn't NOP4 (in fact it is OSP NOP3), such that it
63− * will be unique to (former) ENDBR sites.
62+ * 4 byte NOP that isn't NOP4, such that it will be unique to (former)
63+ * ENDBR sites. Additionally it carries UDB as immediate.
6464 */
65− return 0x001f0f66; /* osp nopl (%rax) */
65+ return 0xd6401f0f; /* nopl -42(%rax) */
6666 }
6767
6868 static inline bool __is_endbr(u32 val)
@@ -70,10 +70,6 @@ static inline bool __is_endbr(u32 val) · 1 unmodified line
7070 if (val == gen_endbr_poison())
7171 return true;
7272
73− /* See cfi_fineibt_bhi_preamble() */
74− if (IS_ENABLED(CONFIG_FINEIBT_BHI) && val == 0x001f0ff5)
75− return true;
76−
7773 val &= ~0x01000000U; /* ENDBR32 -> ENDBR64 */
7874 return val == gen_endbr();
7975 }
arch/x86/include/asm/idtentry.h+2−7
@@ -460,17 +460,12 @@ __visible noinstr void func(struct pt_regs *regs, \ · 459 unmodified lines
460460 #endif
461461
462462 void idt_install_sysvec(unsigned int n, const void *function);
463−
464−#ifdef CONFIG_X86_FRED
465463 void fred_install_sysvec(unsigned int vector, const idtentry_t function);
466−#else
467−static inline void fred_install_sysvec(unsigned int vector, const idtentry_t function) { }
468−#endif
469464
470465 #define sysvec_install(vector, function) { \
471− if (cpu_feature_enabled(X86_FEATURE_FRED)) \
466+ if (IS_ENABLED(CONFIG_X86_FRED)) \
472467 fred_install_sysvec(vector, function); \
473− else \
468+ if (!cpu_feature_enabled(X86_FEATURE_FRED)) \
474469 idt_install_sysvec(vector, asm_##function); \
475470 }
476471
arch/x86/include/asm/mshyperv.h+41−96
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/nmi.h>
77 #include <linux/msi.h>
88 #include <linux/io.h>
9+#include <linux/static_call.h>
910 #include <asm/nospec-branch.h>
1011 #include <asm/paravirt.h>
1112 #include <asm/msr.h>
@@ -39,16 +40,21 @@ static inline unsigned char hv_get_nmi_reason(void) · 27 unmodified lines
3940 return 0;
4041 }
4142
42−#if IS_ENABLED(CONFIG_HYPERV)
43−extern bool hyperv_paravisor_present;
43+extern u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
44+extern u64 hv_snp_hypercall(u64 control, u64 param1, u64 param2);
45+extern u64 hv_std_hypercall(u64 control, u64 param1, u64 param2);
4446
47+#if IS_ENABLED(CONFIG_HYPERV)
4548 extern void *hv_hypercall_pg;
4649
4750 extern union hv_ghcb * __percpu *hv_ghcb_pg;
4851
4952 bool hv_isolation_type_snp(void);
5053 bool hv_isolation_type_tdx(void);
51−u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
54+
55+#ifdef CONFIG_X86_64
56+DECLARE_STATIC_CALL(hv_hypercall, hv_std_hypercall);
57+#endif
5258
5359 /*
5460 * DEFAULT INIT GPAT and SEGMENT LIMIT value in struct VMSA
@@ -65,37 +71,15 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) · 10 unmodified lines
6571 {
6672 u64 input_address = input ? virt_to_phys(input) : 0;
6773 u64 output_address = output ? virt_to_phys(output) : 0;
68− u64 hv_status;
6974
7075 #ifdef CONFIG_X86_64
71− if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
72− return hv_tdx_hypercall(control, input_address, output_address);
73−
74− if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
75− __asm__ __volatile__("mov %[output_address], %%r8\n"
76− "vmmcall"
77− : "=a" (hv_status), ASM_CALL_CONSTRAINT,
78− "+c" (control), "+d" (input_address)
79− : [output_address] "r" (output_address)
80− : "cc", "memory", "r8", "r9", "r10", "r11");
81− return hv_status;
82− }
83−
84− if (!hv_hypercall_pg)
85− return U64_MAX;
86−
87− __asm__ __volatile__("mov %[output_address], %%r8\n"
88− CALL_NOSPEC
89− : "=a" (hv_status), ASM_CALL_CONSTRAINT,
90− "+c" (control), "+d" (input_address)
91− : [output_address] "r" (output_address),
92− THUNK_TARGET(hv_hypercall_pg)
93− : "cc", "memory", "r8", "r9", "r10", "r11");
76+ return static_call_mod(hv_hypercall)(control, input_address, output_address);
9477 #else
9578 u32 input_address_hi = upper_32_bits(input_address);
9679 u32 input_address_lo = lower_32_bits(input_address);
9780 u32 output_address_hi = upper_32_bits(output_address);
9881 u32 output_address_lo = lower_32_bits(output_address);
82+ u64 hv_status;
9983
10084 if (!hv_hypercall_pg)
10185 return U64_MAX;
@@ -108,48 +92,30 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output) · 6 unmodified lines
10892 "D"(output_address_hi), "S"(output_address_lo),
10993 THUNK_TARGET(hv_hypercall_pg)
11094 : "cc", "memory");
111−#endif /* !x86_64 */
11295 return hv_status;
96+#endif /* !x86_64 */
11397 }
11498
11599 /* Fast hypercall with 8 bytes of input and no output */
116100 static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
117101 {
118− u64 hv_status;
119−
120102 #ifdef CONFIG_X86_64
121− if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
122− return hv_tdx_hypercall(control, input1, 0);
123−
124− if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
125− __asm__ __volatile__(
126− "vmmcall"
127− : "=a" (hv_status), ASM_CALL_CONSTRAINT,
128− "+c" (control), "+d" (input1)
129− :: "cc", "r8", "r9", "r10", "r11");
130− } else {
131− __asm__ __volatile__(CALL_NOSPEC
132− : "=a" (hv_status), ASM_CALL_CONSTRAINT,
133− "+c" (control), "+d" (input1)
134− : THUNK_TARGET(hv_hypercall_pg)
135− : "cc", "r8", "r9", "r10", "r11");
136− }
103+ return static_call_mod(hv_hypercall)(control, input1, 0);
137104 #else
138− {
139− u32 input1_hi = upper_32_bits(input1);
140− u32 input1_lo = lower_32_bits(input1);
141−
142− __asm__ __volatile__ (CALL_NOSPEC
143− : "=A"(hv_status),
144− "+c"(input1_lo),
145− ASM_CALL_CONSTRAINT
146− : "A" (control),
147− "b" (input1_hi),
148− THUNK_TARGET(hv_hypercall_pg)
149− : "cc", "edi", "esi");
150− }
151−#endif
105+ u32 input1_hi = upper_32_bits(input1);
106+ u32 input1_lo = lower_32_bits(input1);
107+ u64 hv_status;
108+
109+ __asm__ __volatile__ (CALL_NOSPEC
110+ : "=A"(hv_status),
111+ "+c"(input1_lo),
112+ ASM_CALL_CONSTRAINT
113+ : "A" (control),
114+ "b" (input1_hi),
115+ THUNK_TARGET(hv_hypercall_pg)
116+ : "cc", "edi", "esi");
152117 return hv_status;
118+#endif
153119 }
154120
155121 static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
@@ -162,45 +128,24 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) · 6 unmodified lines
162128 /* Fast hypercall with 16 bytes of input */
163129 static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
164130 {
165− u64 hv_status;
166−
167131 #ifdef CONFIG_X86_64
168− if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
169− return hv_tdx_hypercall(control, input1, input2);
170−
171− if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
172− __asm__ __volatile__("mov %[input2], %%r8\n"
173− "vmmcall"
174− : "=a" (hv_status), ASM_CALL_CONSTRAINT,
175− "+c" (control), "+d" (input1)
176− : [input2] "r" (input2)
177− : "cc", "r8", "r9", "r10", "r11");
178− } else {
179− __asm__ __volatile__("mov %[input2], %%r8\n"
180− CALL_NOSPEC
181− : "=a" (hv_status), ASM_CALL_CONSTRAINT,
182− "+c" (control), "+d" (input1)
183− : [input2] "r" (input2),
184− THUNK_TARGET(hv_hypercall_pg)
185− : "cc", "r8", "r9", "r10", "r11");
186− }
132+ return static_call_mod(hv_hypercall)(control, input1, input2);
187133 #else
188− {
189− u32 input1_hi = upper_32_bits(input1);
190− u32 input1_lo = lower_32_bits(input1);
191− u32 input2_hi = upper_32_bits(input2);
192− u32 input2_lo = lower_32_bits(input2);
193−
194− __asm__ __volatile__ (CALL_NOSPEC
195− : "=A"(hv_status),
196− "+c"(input1_lo), ASM_CALL_CONSTRAINT
197− : "A" (control), "b" (input1_hi),
198− "D"(input2_hi), "S"(input2_lo),
199− THUNK_TARGET(hv_hypercall_pg)
200− : "cc");
201− }
202−#endif
134+ u32 input1_hi = upper_32_bits(input1);
135+ u32 input1_lo = lower_32_bits(input1);
136+ u32 input2_hi = upper_32_bits(input2);
137+ u32 input2_lo = lower_32_bits(input2);
138+ u64 hv_status;
139+
140+ __asm__ __volatile__ (CALL_NOSPEC
141+ : "=A"(hv_status),
142+ "+c"(input1_lo), ASM_CALL_CONSTRAINT
143+ : "A" (control), "b" (input1_hi),
144+ "D"(input2_hi), "S"(input2_lo),
145+ THUNK_TARGET(hv_hypercall_pg)
146+ : "cc");
203147 return hv_status;
148+#endif
204149 }
205150
206151 static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
arch/x86/include/asm/text-patching.h+13−7
@@ -178,9 +178,9 @@ void int3_emulate_ret(struct pt_regs *regs) · 177 unmodified lines
178178 }
179179
180180 static __always_inline
181−void int3_emulate_jcc(struct pt_regs *regs, u8 cc, unsigned long ip, unsigned long disp)
181+bool __emulate_cc(unsigned long flags, u8 cc)
182182 {
183− static const unsigned long jcc_mask[6] = {
183+ static const unsigned long cc_mask[6] = {
184184 [0] = X86_EFLAGS_OF,
185185 [1] = X86_EFLAGS_CF,
186186 [2] = X86_EFLAGS_ZF,
@@ -193,15 +193,21 @@ void int3_emulate_jcc(struct pt_regs *regs, u8 cc, unsigned long ip, unsigned lo · 6 unmodified lines
193193 bool match;
194194
195195 if (cc < 0xc) {
196− match = regs->flags & jcc_mask[cc >> 1];
196+ match = flags & cc_mask[cc >> 1];
197197 } else {
198− match = ((regs->flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^
199− ((regs->flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT);
198+ match = ((flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^
199+ ((flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT);
200200 if (cc >= 0xe)
201− match = match || (regs->flags & X86_EFLAGS_ZF);
201+ match = match || (flags & X86_EFLAGS_ZF);
202202 }
203203
204− if ((match && !invert) || (!match && invert))
204+ return (match && !invert) || (!match && invert);
205+}
206+
207+static __always_inline
208+void int3_emulate_jcc(struct pt_regs *regs, u8 cc, unsigned long ip, unsigned long disp)
209+{
210+ if (__emulate_cc(regs->flags, cc))
205211 ip += disp;
206212
207213 int3_emulate_jmp(regs, ip);
arch/x86/kernel/alternative.c+176−116
@@ -147,10 +147,10 @@ static void *its_init_thunk(void *thunk, int reg) · 146 unmodified lines
147147 /*
148148 * When ITS uses indirect branch thunk the fineibt_paranoid
149149 * caller sequence doesn't fit in the caller site. So put the
150− * remaining part of the sequence (<ea> + JNE) into the ITS
150+ * remaining part of the sequence (UDB + JNE) into the ITS
151151 * thunk.
152152 */
153− bytes[i++] = 0xea; /* invalid instruction */
153+ bytes[i++] = 0xd6; /* UDB */
154154 bytes[i++] = 0x75; /* JNE */
155155 bytes[i++] = 0xfd;
156156
@@ -163,7 +163,7 @@ static void *its_init_thunk(void *thunk, int reg) · 6 unmodified lines
163163 reg -= 8;
164164 }
165165 bytes[i++] = 0xff;
166− bytes[i++] = 0xe0 + reg; /* jmp *reg */
166+ bytes[i++] = 0xe0 + reg; /* JMP *reg */
167167 bytes[i++] = 0xcc;
168168
169169 return thunk + offset;
@@ -713,20 +713,33 @@ static inline bool is_jcc32(struct insn *insn) · 543 unmodified lines
713713 #if defined(CONFIG_MITIGATION_RETPOLINE) && defined(CONFIG_OBJTOOL)
714714
715715 /*
716− * CALL/JMP *%\reg
716+ * [CS]{,3} CALL/JMP *%\reg [INT3]*
717717 */
718−static int emit_indirect(int op, int reg, u8 *bytes)
718+static int emit_indirect(int op, int reg, u8 *bytes, int len)
719719 {
720+ int cs = 0, bp = 0;
720721 int i = 0;
721722 u8 modrm;
722723
724+ /*
725+ * Set @len to the excess bytes after writing the instruction.
726+ */
727+ len -= 2 + (reg >= 8);
728+ WARN_ON_ONCE(len < 0);
729+
723730 switch (op) {
724731 case CALL_INSN_OPCODE:
725732 modrm = 0x10; /* Reg = 2; CALL r/m */
733+ /*
734+ * Additional NOP is better than prefix decode penalty.
735+ */
736+ if (len <= 3)
737+ cs = len;
726738 break;
727739
728740 case JMP32_INSN_OPCODE:
729741 modrm = 0x20; /* Reg = 4; JMP r/m */
742+ bp = len;
730743 break;
731744
732745 default:
@@ -734,6 +747,9 @@ static int emit_indirect(int op, int reg, u8 *bytes) · 1 unmodified line
734747 return -1;
735748 }
736749
750+ while (cs--)
751+ bytes[i++] = 0x2e; /* CS-prefix */
752+
737753 if (reg >= 8) {
738754 bytes[i++] = 0x41; /* REX.B prefix */
739755 reg -= 8;
@@ -745,6 +761,9 @@ static int emit_indirect(int op, int reg, u8 *bytes) · 5 unmodified lines
745761 bytes[i++] = 0xff; /* opcode */
746762 bytes[i++] = modrm;
747763
764+ while (bp--)
765+ bytes[i++] = 0xcc; /* INT3 */
766+
748767 return i;
749768 }
750769
@@ -918,20 +937,11 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes) · 167 unmodified lines
918937 return emit_its_trampoline(addr, insn, reg, bytes);
919938 #endif
920939
921− ret = emit_indirect(op, reg, bytes + i);
940+ ret = emit_indirect(op, reg, bytes + i, insn->length - i);
922941 if (ret < 0)
923942 return ret;
924943 i += ret;
925944
926− /*
927− * The compiler is supposed to EMIT an INT3 after every unconditional
928− * JMP instruction due to AMD BTC. However, if the compiler is too old
929− * or MITIGATION_SLS isn't enabled, we still need an INT3 after
930− * indirect JMPs even on Intel.
931− */
932− if (op == JMP32_INSN_OPCODE && i < insn->length)
933− bytes[i++] = INT3_INSN_OPCODE;
934−
935945 for (; i < insn->length;)
936946 bytes[i++] = BYTES_NOP1;
937947
@@ -970,7 +980,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) · 32 unmodified lines
970980 case JMP32_INSN_OPCODE:
971981 /* Check for cfi_paranoid + ITS */
972982 dest = addr + insn.length + insn.immediate.value;
973− if (dest[-1] == 0xea && (dest[0] & 0xf0) == 0x70) {
983+ if (dest[-1] == 0xd6 && (dest[0] & 0xf0) == 0x70) {
974984 WARN_ON_ONCE(cfi_mode != CFI_FINEIBT);
975985 continue;
976986 }
@@ -1177,6 +1187,7 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { } · 200 unmodified lines
11771187 #endif
11781188
11791189 enum cfi_mode cfi_mode __ro_after_init = __CFI_DEFAULT;
1190+static bool cfi_debug __ro_after_init;
11801191
11811192 #ifdef CONFIG_FINEIBT_BHI
11821193 bool cfi_bhi __ro_after_init = false;
@@ -1259,6 +1270,8 @@ static __init int cfi_parse_cmdline(char *str) · 76 unmodified lines
12591270 } else if (!strcmp(str, "off")) {
12601271 cfi_mode = CFI_OFF;
12611272 cfi_rand = false;
1273+ } else if (!strcmp(str, "debug")) {
1274+ cfi_debug = true;
12621275 } else if (!strcmp(str, "kcfi")) {
12631276 cfi_mode = CFI_KCFI;
12641277 } else if (!strcmp(str, "fineibt")) {
@@ -1266,26 +1279,26 @@ static __init int cfi_parse_cmdline(char *str) · 1 unmodified line
12661279 } else if (!strcmp(str, "norand")) {
12671280 cfi_rand = false;
12681281 } else if (!strcmp(str, "warn")) {
1269− pr_alert("CFI mismatch non-fatal!\n");
1282+ pr_alert("CFI: mismatch non-fatal!\n");
12701283 cfi_warn = true;
12711284 } else if (!strcmp(str, "paranoid")) {
12721285 if (cfi_mode == CFI_FINEIBT) {
12731286 cfi_paranoid = true;
12741287 } else {
1275− pr_err("Ignoring paranoid; depends on fineibt.\n");
1288+ pr_err("CFI: ignoring paranoid; depends on fineibt.\n");
12761289 }
12771290 } else if (!strcmp(str, "bhi")) {
12781291 #ifdef CONFIG_FINEIBT_BHI
12791292 if (cfi_mode == CFI_FINEIBT) {
12801293 cfi_bhi = true;
12811294 } else {
1282− pr_err("Ignoring bhi; depends on fineibt.\n");
1295+ pr_err("CFI: ignoring bhi; depends on fineibt.\n");
12831296 }
12841297 #else
1285− pr_err("Ignoring bhi; depends on FINEIBT_BHI=y.\n");
1298+ pr_err("CFI: ignoring bhi; depends on FINEIBT_BHI=y.\n");
12861299 #endif
12871300 } else {
1288− pr_err("Ignoring unknown cfi option (%s).", str);
1301+ pr_err("CFI: Ignoring unknown option (%s).", str);
12891302 }
12901303
12911304 str = next;
@@ -1300,9 +1313,9 @@ early_param("cfi", cfi_parse_cmdline); · 8 unmodified lines
13001313 *
13011314 * __cfi_\func: __cfi_\func:
13021315 * movl $0x12345678,%eax // 5 endbr64 // 4
1303− * nop subl $0x12345678,%r10d // 7
1304− * nop jne __cfi_\func+6 // 2
1305− * nop nop3 // 3
1316+ * nop subl $0x12345678,%eax // 5
1317+ * nop jne.d32,pn \func+3 // 7
1318+ * nop
13061319 * nop
13071320 * nop
13081321 * nop
@@ -1311,34 +1324,44 @@ early_param("cfi", cfi_parse_cmdline); · 2 unmodified lines
13111324 * nop
13121325 * nop
13131326 * nop
1327+ * \func: \func:
1328+ * endbr64 nopl -42(%rax)
13141329 *
13151330 *
13161331 * caller: caller:
1317− * movl $(-0x12345678),%r10d // 6 movl $0x12345678,%r10d // 6
1332+ * movl $(-0x12345678),%r10d // 6 movl $0x12345678,%eax // 5
13181333 * addl $-15(%r11),%r10d // 4 lea -0x10(%r11),%r11 // 4
1319− * je 1f // 2 nop4 // 4
1334+ * je 1f // 2 nop5 // 5
13201335 * ud2 // 2
13211336 * 1: cs call __x86_indirect_thunk_r11 // 6 call *%r11; nop3; // 6
13221337 *
1338+ *
1339+ * Notably, the FineIBT sequences are crafted such that branches are presumed
1340+ * non-taken. This is based on Agner Fog's optimization manual, which states:
1341+ *
1342+ * "Make conditional jumps most often not taken: The efficiency and throughput
1343+ * for not-taken branches is better than for taken branches on most
1344+ * processors. Therefore, it is good to place the most frequent branch first"
13231345 */
13241346
13251347 /*
13261348 * <fineibt_preamble_start>:
13271349 * 0: f3 0f 1e fa endbr64
1328− * 4: 41 81 <ea> 78 56 34 12 sub $0x12345678, %r10d
1329− * b: 75 f9 jne 6 <fineibt_preamble_start+0x6>
1330− * d: 0f 1f 00 nopl (%rax)
1350+ * 4: 2d 78 56 34 12 sub $0x12345678, %eax
1351+ * 9: 2e 0f 85 03 00 00 00 jne,pn 13 <fineibt_preamble_start+0x13>
1352+ * 10: 0f 1f 40 d6 nopl -0x2a(%rax)
13311353 *
1332− * Note that the JNE target is the 0xEA byte inside the SUB, this decodes as
1333− * (bad) on x86_64 and raises #UD.
1354+ * Note that the JNE target is the 0xD6 byte inside the NOPL, this decodes as
1355+ * UDB on x86_64 and raises #UD.
13341356 */
13351357 asm( ".pushsection .rodata \n"
13361358 "fineibt_preamble_start: \n"
13371359 " endbr64 \n"
1338− " subl $0x12345678, %r10d \n"
1360+ " subl $0x12345678, %eax \n"
13391361 "fineibt_preamble_bhi: \n"
1340− " jne fineibt_preamble_start+6 \n"
1341− ASM_NOP3
1362+ " cs jne.d32 fineibt_preamble_start+0x13 \n"
1363+ "#fineibt_func: \n"
1364+ " nopl -42(%rax) \n"
13421365 "fineibt_preamble_end: \n"
13431366 ".popsection\n"
13441367 );
@@ -1349,20 +1372,20 @@ extern u8 fineibt_preamble_end[]; · 4 unmodified lines
13491372
13501373 #define fineibt_preamble_size (fineibt_preamble_end - fineibt_preamble_start)
13511374 #define fineibt_preamble_bhi (fineibt_preamble_bhi - fineibt_preamble_start)
1352−#define fineibt_preamble_ud 6
1353−#define fineibt_preamble_hash 7
1375+#define fineibt_preamble_ud 0x13
1376+#define fineibt_preamble_hash 5
13541377
13551378 /*
13561379 * <fineibt_caller_start>:
1357− * 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d
1358− * 6: 4d 8d 5b f0 lea -0x10(%r11), %r11
1359− * a: 0f 1f 40 00 nopl 0x0(%rax)
1380+ * 0: b8 78 56 34 12 mov $0x12345678, %eax
1381+ * 5: 4d 8d 5b f0 lea -0x10(%r11), %r11
1382+ * 9: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
13601383 */
13611384 asm( ".pushsection .rodata \n"
13621385 "fineibt_caller_start: \n"
1363− " movl $0x12345678, %r10d \n"
1386+ " movl $0x12345678, %eax \n"
13641387 " lea -0x10(%r11), %r11 \n"
1365− ASM_NOP4
1388+ ASM_NOP5
13661389 "fineibt_caller_end: \n"
13671390 ".popsection \n"
13681391 );
@@ -1371,7 +1394,7 @@ extern u8 fineibt_caller_start[]; · 2 unmodified lines
13711394 extern u8 fineibt_caller_end[];
13721395
13731396 #define fineibt_caller_size (fineibt_caller_end - fineibt_caller_start)
1374−#define fineibt_caller_hash 2
1397+#define fineibt_caller_hash 1
13751398
13761399 #define fineibt_caller_jmp (fineibt_caller_size - 2)
13771400
@@ -1388,9 +1411,9 @@ extern u8 fineibt_caller_end[]; · 10 unmodified lines
13881411 * of adding a load.
13891412 *
13901413 * <fineibt_paranoid_start>:
1391− * 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d
1392− * 6: 45 3b 53 f7 cmp -0x9(%r11), %r10d
1393− * a: 4d 8d 5b <f0> lea -0x10(%r11), %r11
1414+ * 0: b8 78 56 34 12 mov $0x12345678, %eax
1415+ * 5: 41 3b 43 f5 cmp -0x11(%r11), %eax
1416+ * 9: 2e 4d 8d 5b <f0> cs lea -0x10(%r11), %r11
13941417 * e: 75 fd jne d <fineibt_paranoid_start+0xd>
13951418 * 10: 41 ff d3 call *%r11
13961419 * 13: 90 nop
@@ -1402,13 +1425,13 @@ extern u8 fineibt_caller_end[]; · 5 unmodified lines
14021425 */
14031426 asm( ".pushsection .rodata \n"
14041427 "fineibt_paranoid_start: \n"
1405− " movl $0x12345678, %r10d \n"
1406− " cmpl -9(%r11), %r10d \n"
1407− " lea -0x10(%r11), %r11 \n"
1428+ " mov $0x12345678, %eax \n"
1429+ " cmpl -11(%r11), %eax \n"
1430+ " cs lea -0x10(%r11), %r11 \n"
1431+ "#fineibt_caller_size: \n"
14081432 " jne fineibt_paranoid_start+0xd \n"
14091433 "fineibt_paranoid_ind: \n"
1410− " call *%r11 \n"
1411− " nop \n"
1434+ " cs call *%r11 \n"
14121435 "fineibt_paranoid_end: \n"
14131436 ".popsection \n"
14141437 );
@@ -1520,51 +1543,67 @@ static int cfi_rand_preamble(s32 *start, s32 *end) · 105 unmodified lines
15201543 return 0;
15211544 }
15221545
1546+/*
1547+ * Inline the bhi-arity 1 case:
1548+ *
1549+ * __cfi_foo:
1550+ * 0: f3 0f 1e fa endbr64
1551+ * 4: 2d 78 56 34 12 sub $0x12345678, %eax
1552+ * 9: 49 0f 45 fa cmovne %rax, %rdi
1553+ * d: 2e 75 03 jne,pn foo+0x3
1554+ *
1555+ * foo:
1556+ * 10: 0f 1f 40 <d6> nopl -42(%rax)
1557+ *
1558+ * Notably, this scheme is incompatible with permissive CFI
1559+ * because the CMOVcc is unconditional and RDI will have been
1560+ * clobbered.
1561+ */
1562+asm( ".pushsection .rodata \n"
1563+ "fineibt_bhi1_start: \n"
1564+ " cmovne %rax, %rdi \n"
1565+ " cs jne fineibt_bhi1_func + 0x3 \n"
1566+ "fineibt_bhi1_func: \n"
1567+ " nopl -42(%rax) \n"
1568+ "fineibt_bhi1_end: \n"
1569+ ".popsection \n"
1570+);
1571+
1572+extern u8 fineibt_bhi1_start[];
1573+extern u8 fineibt_bhi1_end[];
1574+
1575+#define fineibt_bhi1_size (fineibt_bhi1_end - fineibt_bhi1_start)
1576+
15231577 static void cfi_fineibt_bhi_preamble(void *addr, int arity)
15241578 {
1579+ u8 bytes[MAX_INSN_SIZE];
1580+
15251581 if (!arity)
15261582 return;
15271583
15281584 if (!cfi_warn && arity == 1) {
1529− /*
1530− * Crazy scheme to allow arity-1 inline:
1531− *
1532− * __cfi_foo:
1533− * 0: f3 0f 1e fa endbr64
1534− * 4: 41 81 <ea> 78 56 34 12 sub 0x12345678, %r10d
1535− * b: 49 0f 45 fa cmovne %r10, %rdi
1536− * f: 75 f5 jne __cfi_foo+6
1537− * 11: 0f 1f 00 nopl (%rax)
1538− *
1539− * Code that direct calls to foo()+0, decodes the tail end as:
1540− *
1541− * foo:
1542− * 0: f5 cmc
1543− * 1: 0f 1f 00 nopl (%rax)
1544− *
1545− * which clobbers CF, but does not affect anything ABI
1546− * wise.
1547− *
1548− * Notably, this scheme is incompatible with permissive CFI
1549− * because the CMOVcc is unconditional and RDI will have been
1550− * clobbered.
1551− */
1552− const u8 magic[9] = {
1553− 0x49, 0x0f, 0x45, 0xfa,
1554− 0x75, 0xf5,
1555− BYTES_NOP3,
1556− };
1557−
1558− text_poke_early(addr + fineibt_preamble_bhi, magic, 9);
1559−
1585+ text_poke_early(addr + fineibt_preamble_bhi,
1586+ fineibt_bhi1_start, fineibt_bhi1_size);
15601587 return;
15611588 }
15621589
1563− text_poke_early(addr + fineibt_preamble_bhi,
1564− text_gen_insn(CALL_INSN_OPCODE,
1565− addr + fineibt_preamble_bhi,
1566− __bhi_args[arity]),
1567− CALL_INSN_SIZE);
1590+ /*
1591+ * Replace the bytes at fineibt_preamble_bhi with a CALL instruction
1592+ * that lines up exactly with the end of the preamble, such that the
1593+ * return address will be foo+0.
1594+ *
1595+ * __cfi_foo:
1596+ * 0: f3 0f 1e fa endbr64
1597+ * 4: 2d 78 56 34 12 sub $0x12345678, %eax
1598+ * 9: 2e 2e e8 DD DD DD DD cs cs call __bhi_args[arity]
1599+ */
1600+ bytes[0] = 0x2e;
1601+ bytes[1] = 0x2e;
1602+ __text_gen_insn(bytes + 2, CALL_INSN_OPCODE,
1603+ addr + fineibt_preamble_bhi + 2,
1604+ __bhi_args[arity], CALL_INSN_SIZE);
1605+
1606+ text_poke_early(addr + fineibt_preamble_bhi, bytes, 7);
15681607 }
15691608
15701609 static int cfi_rewrite_preamble(s32 *start, s32 *end)
@@ -1655,8 +1694,6 @@ static int cfi_rewrite_callers(s32 *start, s32 *end) · 84 unmodified lines
16551694 {
16561695 s32 *s;
16571696
1658− BUG_ON(fineibt_paranoid_size != 20);
1659−
16601697 for (s = start; s < end; s++) {
16611698 void *addr = (void *)s + *s;
16621699 struct insn insn;
@@ -1696,8 +1733,9 @@ static int cfi_rewrite_callers(s32 *start, s32 *end) · 33 unmodified lines
16961733 emit_paranoid_trampoline(addr + fineibt_caller_size,
16971734 &insn, 11, bytes + fineibt_caller_size);
16981735 } else {
1699− ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind);
1700− if (WARN_ON_ONCE(ret != 3))
1736+ int len = fineibt_paranoid_size - fineibt_paranoid_ind;
1737+ ret = emit_indirect(op, 11, bytes + fineibt_paranoid_ind, len);
1738+ if (WARN_ON_ONCE(ret != len))
17011739 continue;
17021740 }
17031741
@@ -1707,13 +1745,20 @@ static int cfi_rewrite_callers(s32 *start, s32 *end) · 3 unmodified lines
17071745 return 0;
17081746 }
17091747
1748+#define pr_cfi_debug(X...) if (cfi_debug) pr_info(X)
1749+
1750+#define FINEIBT_WARN(_f, _v) \
1751+ WARN_ONCE((_f) != (_v), "FineIBT: " #_f " %ld != %d\n", _f, _v)
1752+
17101753 static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,
17111754 s32 *start_cfi, s32 *end_cfi, bool builtin)
17121755 {
17131756 int ret;
17141757
1715− if (WARN_ONCE(fineibt_preamble_size != 16,
1716− "FineIBT preamble wrong size: %ld", fineibt_preamble_size))
1758+ if (FINEIBT_WARN(fineibt_preamble_size, 20) ||
1759+ FINEIBT_WARN(fineibt_preamble_bhi + fineibt_bhi1_size, 20) ||
1760+ FINEIBT_WARN(fineibt_caller_size, 14) ||
1761+ FINEIBT_WARN(fineibt_paranoid_size, 20))
17171762 return;
17181763
17191764 if (cfi_mode == CFI_AUTO) {
@@ -1734,6 +1779,7 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, · 14 unmodified lines
17341779 * rewrite them. This disables all CFI. If this succeeds but any of the
17351780 * later stages fails, we're without CFI.
17361781 */
1782+ pr_cfi_debug("CFI: disabling all indirect call checking\n");
17371783 ret = cfi_disable_callers(start_retpoline, end_retpoline);
17381784 if (ret)
17391785 goto err;
@@ -1744,43 +1790,53 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, · 4 unmodified lines
17441790 cfi_bpf_hash = cfi_rehash(cfi_bpf_hash);
17451791 cfi_bpf_subprog_hash = cfi_rehash(cfi_bpf_subprog_hash);
17461792 }
1793+ pr_cfi_debug("CFI: cfi_seed: 0x%08x\n", cfi_seed);
17471794
1795+ pr_cfi_debug("CFI: rehashing all preambles\n");
17481796 ret = cfi_rand_preamble(start_cfi, end_cfi);
17491797 if (ret)
17501798 goto err;
17511799
1800+ pr_cfi_debug("CFI: rehashing all indirect calls\n");
17521801 ret = cfi_rand_callers(start_retpoline, end_retpoline);
17531802 if (ret)
17541803 goto err;
1804+ } else {
1805+ pr_cfi_debug("CFI: rehashing disabled\n");
17551806 }
17561807
17571808 switch (cfi_mode) {
17581809 case CFI_OFF:
17591810 if (builtin)
1760− pr_info("Disabling CFI\n");
1811+ pr_info("CFI: disabled\n");
17611812 return;
17621813
17631814 case CFI_KCFI:
1815+ pr_cfi_debug("CFI: re-enabling all indirect call checking\n");
17641816 ret = cfi_enable_callers(start_retpoline, end_retpoline);
17651817 if (ret)
17661818 goto err;
17671819
17681820 if (builtin)
1769− pr_info("Using kCFI\n");
1821+ pr_info("CFI: Using %sretpoline kCFI\n",
1822+ cfi_rand ? "rehashed " : "");
17701823 return;
17711824
17721825 case CFI_FINEIBT:
1826+ pr_cfi_debug("CFI: adding FineIBT to all preambles\n");
17731827 /* place the FineIBT preamble at func()-16 */
17741828 ret = cfi_rewrite_preamble(start_cfi, end_cfi);
17751829 if (ret)
17761830 goto err;
17771831
17781832 /* rewrite the callers to target func()-16 */
1833+ pr_cfi_debug("CFI: rewriting indirect call sites to use FineIBT\n");
17791834 ret = cfi_rewrite_callers(start_retpoline, end_retpoline);
17801835 if (ret)
17811836 goto err;
17821837
17831838 /* now that nobody targets func()+0, remove ENDBR there */
1839+ pr_cfi_debug("CFI: removing old endbr insns\n");
17841840 cfi_rewrite_endbr(start_cfi, end_cfi);
17851841
17861842 if (builtin) {
@@ -1823,11 +1879,11 @@ static void poison_cfi(void *addr) · 36 unmodified lines
18231879
18241880 /*
18251881 * __cfi_\func:
1826− * osp nopl (%rax)
1827− * subl $0, %r10d
1828− * jz 1f
1829− * ud2
1830− * 1: nop
1882+ * nopl -42(%rax)
1883+ * sub $0, %eax
1884+ * jne \func+3
1885+ * \func:
1886+ * nopl -42(%rax)
18311887 */
18321888 poison_endbr(addr);
18331889 poison_hash(addr + fineibt_preamble_hash);
@@ -1853,12 +1909,14 @@ static void poison_cfi(void *addr) · 19 unmodified lines
18531909 }
18541910 }
18551911
1912+#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE)
1913+
18561914 /*
1857− * When regs->ip points to a 0xEA byte in the FineIBT preamble,
1915+ * When regs->ip points to a 0xD6 byte in the FineIBT preamble,
18581916 * return true and fill out target and type.
18591917 *
18601918 * We check the preamble by checking for the ENDBR instruction relative to the
1861− * 0xEA instruction.
1919+ * UDB instruction.
18621920 */
18631921 static bool decode_fineibt_preamble(struct pt_regs *regs, unsigned long *target, u32 *type)
18641922 {
@@ -1868,10 +1926,10 @@ static bool decode_fineibt_preamble(struct pt_regs *regs, unsigned long *target, · 3 unmodified lines
18681926 if (!exact_endbr((void *)addr))
18691927 return false;
18701928
1871− *target = addr + fineibt_preamble_size;
1929+ *target = addr + fineibt_prefix_size;
18721930
18731931 __get_kernel_nofault(&hash, addr + fineibt_preamble_hash, u32, Efault);
1874− *type = (u32)regs->r10 + hash;
1932+ *type = (u32)regs->ax + hash;
18751933
18761934 /*
18771935 * Since regs->ip points to the middle of an instruction; it cannot
@@ -1909,12 +1967,12 @@ static bool decode_fineibt_bhi(struct pt_regs *regs, unsigned long *target, u32 · 31 unmodified lines
19091967 __get_kernel_nofault(&addr, regs->sp, unsigned long, Efault);
19101968 *target = addr;
19111969
1912− addr -= fineibt_preamble_size;
1970+ addr -= fineibt_prefix_size;
19131971 if (!exact_endbr((void *)addr))
19141972 return false;
19151973
19161974 __get_kernel_nofault(&hash, addr + fineibt_preamble_hash, u32, Efault);
1917− *type = (u32)regs->r10 + hash;
1975+ *type = (u32)regs->ax + hash;
19181976
19191977 /*
19201978 * The UD2 sites are constructed with a RET immediately following,
@@ -1931,7 +1989,7 @@ static bool is_paranoid_thunk(unsigned long addr) · 10 unmodified lines
19311989 u32 thunk;
19321990
19331991 __get_kernel_nofault(&thunk, (u32 *)addr, u32, Efault);
1934− return (thunk & 0x00FFFFFF) == 0xfd75ea;
1992+ return (thunk & 0x00FFFFFF) == 0xfd75d6;
19351993
19361994 Efault:
19371995 return false;
@@ -1939,8 +1997,7 @@ Efault: · 1 unmodified line
19391997
19401998 /*
19411999 * regs->ip points to a LOCK Jcc.d8 instruction from the fineibt_paranoid_start[]
1942− * sequence, or to an invalid instruction (0xea) + Jcc.d8 for cfi_paranoid + ITS
1943− * thunk.
2000+ * sequence, or to UDB + Jcc.d8 for cfi_paranoid + ITS thunk.
19442001 */
19452002 static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, u32 *type)
19462003 {
@@ -1950,8 +2007,8 @@ static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, · 3 unmodified lines
19502007 return false;
19512008
19522009 if (is_cfi_trap(addr + fineibt_caller_size - LEN_UD2)) {
1953− *target = regs->r11 + fineibt_preamble_size;
1954− *type = regs->r10;
2010+ *target = regs->r11 + fineibt_prefix_size;
2011+ *type = regs->ax;
19552012
19562013 /*
19572014 * Since the trapping instruction is the exact, but LOCK prefixed,
@@ -1963,14 +2020,14 @@ static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, · 5 unmodified lines
19632020 /*
19642021 * The cfi_paranoid + ITS thunk combination results in:
19652022 *
1966− * 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d
1967− * 6: 45 3b 53 f7 cmp -0x9(%r11), %r10d
1968− * a: 4d 8d 5b f0 lea -0x10(%r11), %r11
2023+ * 0: b8 78 56 34 12 mov $0x12345678, %eax
2024+ * 5: 41 3b 43 f7 cmp -11(%r11), %eax
2025+ * a: 2e 3d 8d 5b f0 cs lea -0x10(%r11), %r11
19692026 * e: 2e e8 XX XX XX XX cs call __x86_indirect_paranoid_thunk_r11
19702027 *
19712028 * Where the paranoid_thunk looks like:
19722029 *
1973− * 1d: <ea> (bad)
2030+ * 1d: <d6> udb
19742031 * __x86_indirect_paranoid_thunk_r11:
19752032 * 1e: 75 fd jne 1d
19762033 * __x86_indirect_its_thunk_r11:
@@ -1979,8 +2036,8 @@ static bool decode_fineibt_paranoid(struct pt_regs *regs, unsigned long *target, · 2 unmodified lines
19792036 *
19802037 */
19812038 if (is_paranoid_thunk(regs->ip)) {
1982− *target = regs->r11 + fineibt_preamble_size;
1983− *type = regs->r10;
2039+ *target = regs->r11 + fineibt_prefix_size;
2040+ *type = regs->ax;
19842041
19852042 regs->ip = *target;
19862043 return true;
@@ -2005,6 +2062,8 @@ bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type) · 18 unmodified lines
20052062 static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,
20062063 s32 *start_cfi, s32 *end_cfi, bool builtin)
20072064 {
2065+ if (IS_ENABLED(CONFIG_CFI) && builtin)
2066+ pr_info("CFI: Using standard kCFI\n");
20082067 }
20092068
20102069 #ifdef CONFIG_X86_KERNEL_IBT
@@ -2321,6 +2380,7 @@ void __init alternative_instructions(void) · 310 unmodified lines
23212380
23222381 __apply_fineibt(__retpoline_sites, __retpoline_sites_end,
23232382 __cfi_sites, __cfi_sites_end, true);
2383+ cfi_debug = false;
23242384
23252385 /*
23262386 * Rewrite the retpolines, must be done before alternatives since
arch/x86/kernel/asm-offsets.c+1−0
@@ -102,6 +102,7 @@ static void __used common(void) · 101 unmodified lines
102102
103103 BLANK();
104104 DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
105+ OFFSET(C_PTREGS_SIZE, pt_regs, orig_ax);
105106
106107 /* TLB state for the entry code */
107108 OFFSET(TLB_STATE_user_pcid_flush_mask, tlb_state, user_pcid_flush_mask);
arch/x86/kernel/cfi.c+1−1
@@ -27,7 +27,7 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target, · 26 unmodified lines
2727 * for indirect call checks:
2828 *
2929 *   movl -<id>, %r10d ; 6 bytes
30− * addl -4(%reg), %r10d ; 4 bytes
30+ * addl -<pos>(%reg), %r10d; 4 bytes
3131 * je .Ltmp1 ; 2 bytes
3232 * ud2 ; <- regs->ip
3333 * .Ltmp1:
arch/x86/kernel/cpu/mshyperv.c+13−6
@@ -38,10 +38,6 @@ · 37 unmodified lines
3838 bool hv_nested;
3939 struct ms_hyperv_info ms_hyperv;
4040
41−/* Used in modules via hv_do_hypercall(): see arch/x86/include/asm/mshyperv.h */
42−bool hyperv_paravisor_present __ro_after_init;
43−EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
44−
4541 #if IS_ENABLED(CONFIG_HYPERV)
4642 static inline unsigned int hv_get_nested_msr(unsigned int reg)
4743 {
@@ -288,8 +284,18 @@ static void __init x86_setup_ops_for_tsc_pg_clock(void) · 240 unmodified lines
288284 old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
289285 x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
290286 }
287+
288+#ifdef CONFIG_X86_64
289+DEFINE_STATIC_CALL(hv_hypercall, hv_std_hypercall);
290+EXPORT_STATIC_CALL_TRAMP_GPL(hv_hypercall);
291+#define hypercall_update(hc) static_call_update(hv_hypercall, hc)
292+#endif
291293 #endif /* CONFIG_HYPERV */
292294
295+#ifndef hypercall_update
296+#define hypercall_update(hc) (void)hc
297+#endif
298+
293299 static uint32_t __init ms_hyperv_platform(void)
294300 {
295301 u32 eax;
@@ -484,14 +490,14 @@ static void __init ms_hyperv_init_platform(void) · 188 unmodified lines
484490 ms_hyperv.shared_gpa_boundary =
485491 BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
486492
487− hyperv_paravisor_present = !!ms_hyperv.paravisor_present;
488−
489493 pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
490494 ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
491495
492496
493497 if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) {
494498 static_branch_enable(&isolation_type_snp);
499+ if (!ms_hyperv.paravisor_present)
500+ hypercall_update(hv_snp_hypercall);
495501 } else if (hv_get_isolation_type() == HV_ISOLATION_TYPE_TDX) {
496502 static_branch_enable(&isolation_type_tdx);
497503
@@ -499,6 +505,7 @@ static void __init ms_hyperv_init_platform(void) · 1 unmodified line
499505 ms_hyperv.hints &= ~HV_X64_APIC_ACCESS_RECOMMENDED;
500506
501507 if (!ms_hyperv.paravisor_present) {
508+ hypercall_update(hv_tdx_hypercall);
502509 /*
503510 * Mark the Hyper-V TSC page feature as disabled
504511 * in a TDX VM without paravisor so that the
arch/x86/kernel/irqinit.c+4−2
@@ -97,9 +97,11 @@ void __init native_init_IRQ(void) · 96 unmodified lines
9797 /* Execute any quirks before the call gates are initialised: */
9898 x86_init.irqs.pre_vector_init();
9999
100− if (cpu_feature_enabled(X86_FEATURE_FRED))
100+ /* FRED's IRQ path may be used even if FRED isn't fully enabled. */
101+ if (IS_ENABLED(CONFIG_X86_FRED))
101102 fred_complete_exception_setup();
102− else
103+
104+ if (!cpu_feature_enabled(X86_FEATURE_FRED))
103105 idt_setup_apic_and_irq_gates();
104106
105107 lapic_assign_system_vectors();
arch/x86/kernel/machine_kexec_64.c+4−0
@@ -479,6 +479,10 @@ void __nocfi machine_kexec(struct kimage *image) · 478 unmodified lines
479479
480480 __ftrace_enabled_restore(save_ftrace_enabled);
481481 }
482+/*
483+ * Handover to the next kernel, no CFI concern.
484+ */
485+ANNOTATE_NOCFI_SYM(machine_kexec);
482486
483487 /* arch-dependent functionality related to kexec file-based syscall */
484488
arch/x86/kernel/traps.c+4−4
@@ -97,7 +97,7 @@ __always_inline int is_valid_bugaddr(unsigned long addr) · 96 unmodified lines
9797 * Check for UD1 or UD2, accounting for Address Size Override Prefixes.
9898 * If it's a UD1, further decode to determine its use:
9999 *
100− * FineIBT: ea (bad)
100+ * FineIBT: d6 udb
101101 * FineIBT: f0 75 f9 lock jne . - 6
102102 * UBSan{0}: 67 0f b9 00 ud1 (%eax),%eax
103103 * UBSan{10}: 67 0f b9 40 10 ud1 0x10(%eax),%eax
@@ -130,9 +130,9 @@ __always_inline int decode_bug(unsigned long addr, s32 *imm, int *len) · 26 unmodified lines
130130 WARN_ON_ONCE(!lock);
131131 return BUG_LOCK;
132132
133− case 0xea:
133+ case 0xd6:
134134 *len = addr - start;
135− return BUG_EA;
135+ return BUG_UDB;
136136
137137 case OPCODE_ESCAPE:
138138 break;
@@ -341,7 +341,7 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 202 unmodified lines
341341 }
342342 fallthrough;
343343
344− case BUG_EA:
344+ case BUG_UDB:
345345 case BUG_LOCK:
346346 if (handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) {
347347 handled = true;
arch/x86/kvm/Kconfig+1−0
@@ -96,6 +96,7 @@ config KVM_SW_PROTECTED_VM · 95 unmodified lines
9696 config KVM_INTEL
9797 tristate "KVM for Intel (and compatible) processors support"
9898 depends on KVM && IA32_FEAT_CTL
99+ select X86_FRED if X86_64
99100 help
100101 Provides support for KVM on processors equipped with Intel's VT
101102 extensions, a.k.a. Virtual Machine Extensions (VMX).
arch/x86/kvm/emulate.c+232−318
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626 #include <asm/debugreg.h>
2727 #include <asm/nospec-branch.h>
2828 #include <asm/ibt.h>
29+#include <asm/text-patching.h>
2930
3031 #include "x86.h"
3132 #include "tss.h"
@@ -166,7 +167,6 @@ · 134 unmodified lines
166167 #define Unaligned ((u64)2 << 41) /* Explicitly unaligned (e.g. MOVDQU) */
167168 #define Avx ((u64)3 << 41) /* Advanced Vector Extensions */
168169 #define Aligned16 ((u64)4 << 41) /* Aligned to 16 byte boundary (e.g. FXSAVE) */
169−#define Fastop ((u64)1 << 44) /* Use opcode::u.fastop */
170170 #define NoWrite ((u64)1 << 45) /* No writeback */
171171 #define SrcWrite ((u64)1 << 46) /* Write back src operand */
172172 #define NoMod ((u64)1 << 47) /* Mod field is ignored */
@@ -203,7 +203,6 @@ struct opcode { · 30 unmodified lines
203203 const struct escape *esc;
204204 const struct instr_dual *idual;
205205 const struct mode_dual *mdual;
206− void (*fastop)(struct fastop *fake);
207206 } u;
208207 int (*check_perm)(struct x86_emulate_ctxt *ctxt);
209208 };
@@ -267,186 +266,130 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) · 57 unmodified lines
267266 X86_EFLAGS_PF|X86_EFLAGS_CF)
268267
269268 #ifdef CONFIG_X86_64
270−#define ON64(x) x
269+#define ON64(x...) x
271270 #else
272−#define ON64(x)
271+#define ON64(x...)
273272 #endif
274273
275−/*
276− * fastop functions have a special calling convention:
277− *
278− * dst: rax (in/out)
279− * src: rdx (in/out)
280− * src2: rcx (in)
281− * flags: rflags (in/out)
282− * ex: rsi (in:fastop pointer, out:zero if exception)
283− *
284− * Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for
285− * different operand sizes can be reached by calculation, rather than a jump
286− * table (which would be bigger than the code).
287− *
288− * The 16 byte alignment, considering 5 bytes for the RET thunk, 3 for ENDBR
289− * and 1 for the straight line speculation INT3, leaves 7 bytes for the
290− * body of the function. Currently none is larger than 4.
291− */
292−static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
293−
294−#define FASTOP_SIZE 16
295−
296−#define __FOP_FUNC(name) \
297− ".align " __stringify(FASTOP_SIZE) " \n\t" \
298− ".type " name ", @function \n\t" \
299− name ":\n\t" \
300− ASM_ENDBR \
301− IBT_NOSEAL(name)
302−
303−#define FOP_FUNC(name) \
304− __FOP_FUNC(#name)
305−
306−#define __FOP_RET(name) \
307− "11: " ASM_RET \
308− ".size " name ", .-" name "\n\t"
309−
310−#define FOP_RET(name) \
311− __FOP_RET(#name)
312−
313−#define __FOP_START(op, align) \
314− extern void em_##op(struct fastop *fake); \
315− asm(".pushsection .text, \"ax\" \n\t" \
316− ".global em_" #op " \n\t" \
317− ".align " __stringify(align) " \n\t" \
318− "em_" #op ":\n\t"
319−
320−#define FOP_START(op) __FOP_START(op, FASTOP_SIZE)
321−
322−#define FOP_END \
323− ".popsection")
324−
325−#define __FOPNOP(name) \
326− __FOP_FUNC(name) \
327− __FOP_RET(name)
328−
329−#define FOPNOP() \
330− __FOPNOP(__stringify(__UNIQUE_ID(nop)))
331−
332−#define FOP1E(op, dst) \
333− __FOP_FUNC(#op "_" #dst) \
334− "10: " #op " %" #dst " \n\t" \
335− __FOP_RET(#op "_" #dst)
336−
337−#define FOP1EEX(op, dst) \
338− FOP1E(op, dst) _ASM_EXTABLE_TYPE_REG(10b, 11b, EX_TYPE_ZERO_REG, %%esi)
339−
340−#define FASTOP1(op) \
341− FOP_START(op) \
342− FOP1E(op##b, al) \
343− FOP1E(op##w, ax) \
344− FOP1E(op##l, eax) \
345− ON64(FOP1E(op##q, rax)) \
346− FOP_END
347−
348−/* 1-operand, using src2 (for MUL/DIV r/m) */
349−#define FASTOP1SRC2(op, name) \
350− FOP_START(name) \
351− FOP1E(op, cl) \
352− FOP1E(op, cx) \
353− FOP1E(op, ecx) \
354− ON64(FOP1E(op, rcx)) \
355− FOP_END
356−
357−/* 1-operand, using src2 (for MUL/DIV r/m), with exceptions */
358−#define FASTOP1SRC2EX(op, name) \
359− FOP_START(name) \
360− FOP1EEX(op, cl) \
361− FOP1EEX(op, cx) \
362− FOP1EEX(op, ecx) \
363− ON64(FOP1EEX(op, rcx)) \
364− FOP_END
365−
366−#define FOP2E(op, dst, src) \
367− __FOP_FUNC(#op "_" #dst "_" #src) \
368− #op " %" #src ", %" #dst " \n\t" \
369− __FOP_RET(#op "_" #dst "_" #src)
370−
371−#define FASTOP2(op) \
372− FOP_START(op) \
373− FOP2E(op##b, al, dl) \
374− FOP2E(op##w, ax, dx) \
375− FOP2E(op##l, eax, edx) \
376− ON64(FOP2E(op##q, rax, rdx)) \
377− FOP_END
378−
379−/* 2 operand, word only */
380−#define FASTOP2W(op) \
381− FOP_START(op) \
382− FOPNOP() \
383− FOP2E(op##w, ax, dx) \
384− FOP2E(op##l, eax, edx) \
385− ON64(FOP2E(op##q, rax, rdx)) \
386− FOP_END
387−
388−/* 2 operand, src is CL */
389−#define FASTOP2CL(op) \
390− FOP_START(op) \
391− FOP2E(op##b, al, cl) \
392− FOP2E(op##w, ax, cl) \
393− FOP2E(op##l, eax, cl) \
394− ON64(FOP2E(op##q, rax, cl)) \
395− FOP_END
396−
397−/* 2 operand, src and dest are reversed */
398−#define FASTOP2R(op, name) \
399− FOP_START(name) \
400− FOP2E(op##b, dl, al) \
401− FOP2E(op##w, dx, ax) \
402− FOP2E(op##l, edx, eax) \
403− ON64(FOP2E(op##q, rdx, rax)) \
404− FOP_END
405−
406−#define FOP3E(op, dst, src, src2) \
407− __FOP_FUNC(#op "_" #dst "_" #src "_" #src2) \
408− #op " %" #src2 ", %" #src ", %" #dst " \n\t"\
409− __FOP_RET(#op "_" #dst "_" #src "_" #src2)
410−
411−/* 3-operand, word-only, src2=cl */
412−#define FASTOP3WCL(op) \
413− FOP_START(op) \
414− FOPNOP() \
415− FOP3E(op##w, ax, dx, cl) \
416− FOP3E(op##l, eax, edx, cl) \
417− ON64(FOP3E(op##q, rax, rdx, cl)) \
418− FOP_END
419−
420−/* Special case for SETcc - 1 instruction per cc */
421−#define FOP_SETCC(op) \
422− FOP_FUNC(op) \
423− #op " %al \n\t" \
424− FOP_RET(op)
425−
426−FOP_START(setcc)
427−FOP_SETCC(seto)
428−FOP_SETCC(setno)
429−FOP_SETCC(setc)
430−FOP_SETCC(setnc)
431−FOP_SETCC(setz)
432−FOP_SETCC(setnz)
433−FOP_SETCC(setbe)
434−FOP_SETCC(setnbe)
435−FOP_SETCC(sets)
436−FOP_SETCC(setns)
437−FOP_SETCC(setp)
438−FOP_SETCC(setnp)
439−FOP_SETCC(setl)
440−FOP_SETCC(setnl)
441−FOP_SETCC(setle)
442−FOP_SETCC(setnle)
443−FOP_END;
444−
445−FOP_START(salc)
446−FOP_FUNC(salc)
447−"pushf; sbb %al, %al; popf \n\t"
448−FOP_RET(salc)
449−FOP_END;
274+#define EM_ASM_START(op) \
275+static int em_##op(struct x86_emulate_ctxt *ctxt) \
276+{ \
277+ unsigned long flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF; \
278+ int bytes = 1, ok = 1; \
279+ if (!(ctxt->d & ByteOp)) \
280+ bytes = ctxt->dst.bytes; \
281+ switch (bytes) {
282+
283+#define __EM_ASM(str) \
284+ asm("push %[flags]; popf \n\t" \
285+ "10: " str \
286+ "pushf; pop %[flags] \n\t" \
287+ "11: \n\t" \
288+ : "+a" (ctxt->dst.val), \
289+ "+d" (ctxt->src.val), \
290+ [flags] "+D" (flags), \
291+ "+S" (ok) \
292+ : "c" (ctxt->src2.val))
293+
294+#define __EM_ASM_1(op, dst) \
295+ __EM_ASM(#op " %%" #dst " \n\t")
296+
297+#define __EM_ASM_1_EX(op, dst) \
298+ __EM_ASM(#op " %%" #dst " \n\t" \
299+ _ASM_EXTABLE_TYPE_REG(10b, 11f, EX_TYPE_ZERO_REG, %%esi))
300+
301+#define __EM_ASM_2(op, dst, src) \
302+ __EM_ASM(#op " %%" #src ", %%" #dst " \n\t")
303+
304+#define __EM_ASM_3(op, dst, src, src2) \
305+ __EM_ASM(#op " %%" #src2 ", %%" #src ", %%" #dst " \n\t")
306+
307+#define EM_ASM_END \
308+ } \
309+ ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); \
310+ return !ok ? emulate_de(ctxt) : X86EMUL_CONTINUE; \
311+}
312+
313+/* 1-operand, using "a" (dst) */
314+#define EM_ASM_1(op) \
315+ EM_ASM_START(op) \
316+ case 1: __EM_ASM_1(op##b, al); break; \
317+ case 2: __EM_ASM_1(op##w, ax); break; \
318+ case 4: __EM_ASM_1(op##l, eax); break; \
319+ ON64(case 8: __EM_ASM_1(op##q, rax); break;) \
320+ EM_ASM_END
321+
322+/* 1-operand, using "c" (src2) */
323+#define EM_ASM_1SRC2(op, name) \
324+ EM_ASM_START(name) \
325+ case 1: __EM_ASM_1(op##b, cl); break; \
326+ case 2: __EM_ASM_1(op##w, cx); break; \
327+ case 4: __EM_ASM_1(op##l, ecx); break; \
328+ ON64(case 8: __EM_ASM_1(op##q, rcx); break;) \
329+ EM_ASM_END
330+
331+/* 1-operand, using "c" (src2) with exception */
332+#define EM_ASM_1SRC2EX(op, name) \
333+ EM_ASM_START(name) \
334+ case 1: __EM_ASM_1_EX(op##b, cl); break; \
335+ case 2: __EM_ASM_1_EX(op##w, cx); break; \
336+ case 4: __EM_ASM_1_EX(op##l, ecx); break; \
337+ ON64(case 8: __EM_ASM_1_EX(op##q, rcx); break;) \
338+ EM_ASM_END
339+
340+/* 2-operand, using "a" (dst), "d" (src) */
341+#define EM_ASM_2(op) \
342+ EM_ASM_START(op) \
343+ case 1: __EM_ASM_2(op##b, al, dl); break; \
344+ case 2: __EM_ASM_2(op##w, ax, dx); break; \
345+ case 4: __EM_ASM_2(op##l, eax, edx); break; \
346+ ON64(case 8: __EM_ASM_2(op##q, rax, rdx); break;) \
347+ EM_ASM_END
348+
349+/* 2-operand, reversed */
350+#define EM_ASM_2R(op, name) \
351+ EM_ASM_START(name) \
352+ case 1: __EM_ASM_2(op##b, dl, al); break; \
353+ case 2: __EM_ASM_2(op##w, dx, ax); break; \
354+ case 4: __EM_ASM_2(op##l, edx, eax); break; \
355+ ON64(case 8: __EM_ASM_2(op##q, rdx, rax); break;) \
356+ EM_ASM_END
357+
358+/* 2-operand, word only (no byte op) */
359+#define EM_ASM_2W(op) \
360+ EM_ASM_START(op) \
361+ case 1: break; \
362+ case 2: __EM_ASM_2(op##w, ax, dx); break; \
363+ case 4: __EM_ASM_2(op##l, eax, edx); break; \
364+ ON64(case 8: __EM_ASM_2(op##q, rax, rdx); break;) \
365+ EM_ASM_END
366+
367+/* 2-operand, using "a" (dst) and CL (src2) */
368+#define EM_ASM_2CL(op) \
369+ EM_ASM_START(op) \
370+ case 1: __EM_ASM_2(op##b, al, cl); break; \
371+ case 2: __EM_ASM_2(op##w, ax, cl); break; \
372+ case 4: __EM_ASM_2(op##l, eax, cl); break; \
373+ ON64(case 8: __EM_ASM_2(op##q, rax, cl); break;) \
374+ EM_ASM_END
375+
376+/* 3-operand, using "a" (dst), "d" (src) and CL (src2) */
377+#define EM_ASM_3WCL(op) \
378+ EM_ASM_START(op) \
379+ case 1: break; \
380+ case 2: __EM_ASM_3(op##w, ax, dx, cl); break; \
381+ case 4: __EM_ASM_3(op##l, eax, edx, cl); break; \
382+ ON64(case 8: __EM_ASM_3(op##q, rax, rdx, cl); break;) \
383+ EM_ASM_END
384+
385+static int em_salc(struct x86_emulate_ctxt *ctxt)
386+{
387+ /*
388+ * Set AL 0xFF if CF is set, or 0x00 when clear.
389+ */
390+ ctxt->dst.val = 0xFF * !!(ctxt->eflags & X86_EFLAGS_CF);
391+ return X86EMUL_CONTINUE;
392+}
450393
451394 /*
452395 * XXX: inoutclob user must know where the argument is being expanded.
@@ -1007,56 +950,55 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, · 554 unmodified lines
1007950 return rc;
1008951 }
1009952
1010−FASTOP2(add);
1011−FASTOP2(or);
1012−FASTOP2(adc);
1013−FASTOP2(sbb);
1014−FASTOP2(and);
1015−FASTOP2(sub);
1016−FASTOP2(xor);
1017−FASTOP2(cmp);
1018−FASTOP2(test);
1019−
1020−FASTOP1SRC2(mul, mul_ex);
1021−FASTOP1SRC2(imul, imul_ex);
1022−FASTOP1SRC2EX(div, div_ex);
1023−FASTOP1SRC2EX(idiv, idiv_ex);
1024−
1025−FASTOP3WCL(shld);
1026−FASTOP3WCL(shrd);
1027−
1028−FASTOP2W(imul);
1029−
1030−FASTOP1(not);
1031−FASTOP1(neg);
1032−FASTOP1(inc);
1033−FASTOP1(dec);
1034−
1035−FASTOP2CL(rol);
1036−FASTOP2CL(ror);
1037−FASTOP2CL(rcl);
1038−FASTOP2CL(rcr);
1039−FASTOP2CL(shl);
1040−FASTOP2CL(shr);
1041−FASTOP2CL(sar);
1042−
1043−FASTOP2W(bsf);
1044−FASTOP2W(bsr);
1045−FASTOP2W(bt);
1046−FASTOP2W(bts);
1047−FASTOP2W(btr);
1048−FASTOP2W(btc);
1049−
1050−FASTOP2(xadd);
1051−
1052−FASTOP2R(cmp, cmp_r);
953+EM_ASM_2(add);
954+EM_ASM_2(or);
955+EM_ASM_2(adc);
956+EM_ASM_2(sbb);
957+EM_ASM_2(and);
958+EM_ASM_2(sub);
959+EM_ASM_2(xor);
960+EM_ASM_2(cmp);
961+EM_ASM_2(test);
962+EM_ASM_2(xadd);
963+
964+EM_ASM_1SRC2(mul, mul_ex);
965+EM_ASM_1SRC2(imul, imul_ex);
966+EM_ASM_1SRC2EX(div, div_ex);
967+EM_ASM_1SRC2EX(idiv, idiv_ex);
968+
969+EM_ASM_3WCL(shld);
970+EM_ASM_3WCL(shrd);
971+
972+EM_ASM_2W(imul);
973+
974+EM_ASM_1(not);
975+EM_ASM_1(neg);
976+EM_ASM_1(inc);
977+EM_ASM_1(dec);
978+
979+EM_ASM_2CL(rol);
980+EM_ASM_2CL(ror);
981+EM_ASM_2CL(rcl);
982+EM_ASM_2CL(rcr);
983+EM_ASM_2CL(shl);
984+EM_ASM_2CL(shr);
985+EM_ASM_2CL(sar);
986+
987+EM_ASM_2W(bsf);
988+EM_ASM_2W(bsr);
989+EM_ASM_2W(bt);
990+EM_ASM_2W(bts);
991+EM_ASM_2W(btr);
992+EM_ASM_2W(btc);
993+
994+EM_ASM_2R(cmp, cmp_r);
1053995
1054996 static int em_bsf_c(struct x86_emulate_ctxt *ctxt)
1055997 {
1056998 /* If src is zero, do not writeback, but update flags */
1057999 if (ctxt->src.val == 0)
10581000 ctxt->dst.type = OP_NONE;
1059− return fastop(ctxt, em_bsf);
1001+ return em_bsf(ctxt);
10601002 }
10611003
10621004 static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
@@ -1064,18 +1006,12 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt) · 1 unmodified line
10641006 /* If src is zero, do not writeback, but update flags */
10651007 if (ctxt->src.val == 0)
10661008 ctxt->dst.type = OP_NONE;
1067− return fastop(ctxt, em_bsr);
1009+ return em_bsr(ctxt);
10681010 }
10691011
10701012 static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
10711013 {
1072− u8 rc;
1073− void (*fop)(void) = (void *)em_setcc + FASTOP_SIZE * (condition & 0xf);
1074−
1075− flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
1076− asm("push %[flags]; popf; " CALL_NOSPEC
1077− : "=a"(rc), ASM_CALL_CONSTRAINT : [thunk_target]"r"(fop), [flags]"r"(flags));
1078− return rc;
1014+ return __emulate_cc(flags, condition & 0xf);
10791015 }
10801016
10811017 static void fetch_register_operand(struct operand *op)
@@ -2325,7 +2261,7 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt) · 1243 unmodified lines
23252261 ctxt->dst.val = reg_read(ctxt, VCPU_REGS_RAX);
23262262 ctxt->src.orig_val = ctxt->src.val;
23272263 ctxt->src.val = ctxt->dst.orig_val;
2328− fastop(ctxt, em_cmp);
2264+ em_cmp(ctxt);
23292265
23302266 if (ctxt->eflags & X86_EFLAGS_ZF) {
23312267 /* Success: write back to memory; no update of EAX */
@@ -3090,7 +3026,7 @@ static int em_das(struct x86_emulate_ctxt *ctxt) · 758 unmodified lines
30903026 ctxt->src.type = OP_IMM;
30913027 ctxt->src.val = 0;
30923028 ctxt->src.bytes = 1;
3093− fastop(ctxt, em_or);
3029+ em_or(ctxt);
30943030 ctxt->eflags &= ~(X86_EFLAGS_AF | X86_EFLAGS_CF);
30953031 if (cf)
30963032 ctxt->eflags |= X86_EFLAGS_CF;
@@ -3116,7 +3052,7 @@ static int em_aam(struct x86_emulate_ctxt *ctxt) · 19 unmodified lines
31163052 ctxt->src.type = OP_IMM;
31173053 ctxt->src.val = 0;
31183054 ctxt->src.bytes = 1;
3119− fastop(ctxt, em_or);
3055+ em_or(ctxt);
31203056
31213057 return X86EMUL_CONTINUE;
31223058 }
@@ -3134,7 +3070,7 @@ static int em_aad(struct x86_emulate_ctxt *ctxt) · 11 unmodified lines
31343070 ctxt->src.type = OP_IMM;
31353071 ctxt->src.val = 0;
31363072 ctxt->src.bytes = 1;
3137− fastop(ctxt, em_or);
3073+ em_or(ctxt);
31383074
31393075 return X86EMUL_CONTINUE;
31403076 }
@@ -3225,7 +3161,7 @@ static int em_xchg(struct x86_emulate_ctxt *ctxt) · 84 unmodified lines
32253161 static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
32263162 {
32273163 ctxt->dst.val = ctxt->src2.val;
3228− return fastop(ctxt, em_imul);
3164+ return em_imul(ctxt);
32293165 }
32303166
32313167 static int em_cwd(struct x86_emulate_ctxt *ctxt)
@@ -4004,7 +3940,6 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt) · 772 unmodified lines
40043940 #define MD(_f, _m) { .flags = ((_f) | ModeDual), .u.mdual = (_m) }
40053941 #define E(_f, _e) { .flags = ((_f) | Escape | ModRM), .u.esc = (_e) }
40063942 #define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
4007−#define F(_f, _e) { .flags = (_f) | Fastop, .u.fastop = (_e) }
40083943 #define II(_f, _e, _i) \
40093944 { .flags = (_f)|Intercept, .u.execute = (_e), .intercept = x86_intercept_##_i }
40103945 #define IIP(_f, _e, _i, _p) \
@@ -4019,9 +3954,9 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt) · 8 unmodified lines
40193954 #define I2bvIP(_f, _e, _i, _p) \
40203955 IIP((_f) | ByteOp, _e, _i, _p), IIP(_f, _e, _i, _p)
40213956
4022−#define F6ALU(_f, _e) F2bv((_f) | DstMem | SrcReg | ModRM, _e), \
4023− F2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \
4024− F2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e)
3957+#define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e), \
3958+ I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \
3959+ I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e)
40253960
40263961 static const struct opcode group7_rm0[] = {
40273962 N,
@@ -4059,14 +3994,14 @@ static const struct opcode group7_rm7[] = { · 31 unmodified lines
40593994 };
40603995
40613996 static const struct opcode group1[] = {
4062− F(Lock, em_add),
4063− F(Lock | PageTable, em_or),
4064− F(Lock, em_adc),
4065− F(Lock, em_sbb),
4066− F(Lock | PageTable, em_and),
4067− F(Lock, em_sub),
4068− F(Lock, em_xor),
4069− F(NoWrite, em_cmp),
3997+ I(Lock, em_add),
3998+ I(Lock | PageTable, em_or),
3999+ I(Lock, em_adc),
4000+ I(Lock, em_sbb),
4001+ I(Lock | PageTable, em_and),
4002+ I(Lock, em_sub),
4003+ I(Lock, em_xor),
4004+ I(NoWrite, em_cmp),
40704005 };
40714006
40724007 static const struct opcode group1A[] = {
@@ -4074,36 +4009,36 @@ static const struct opcode group1A[] = { · 1 unmodified line
40744009 };
40754010
40764011 static const struct opcode group2[] = {
4077− F(DstMem | ModRM, em_rol),
4078− F(DstMem | ModRM, em_ror),
4079− F(DstMem | ModRM, em_rcl),
4080− F(DstMem | ModRM, em_rcr),
4081− F(DstMem | ModRM, em_shl),
4082− F(DstMem | ModRM, em_shr),
4083− F(DstMem | ModRM, em_shl),
4084− F(DstMem | ModRM, em_sar),
4012+ I(DstMem | ModRM, em_rol),
4013+ I(DstMem | ModRM, em_ror),
4014+ I(DstMem | ModRM, em_rcl),
4015+ I(DstMem | ModRM, em_rcr),
4016+ I(DstMem | ModRM, em_shl),
4017+ I(DstMem | ModRM, em_shr),
4018+ I(DstMem | ModRM, em_shl),
4019+ I(DstMem | ModRM, em_sar),
40854020 };
40864021
40874022 static const struct opcode group3[] = {
4088− F(DstMem | SrcImm | NoWrite, em_test),
4089− F(DstMem | SrcImm | NoWrite, em_test),
4090− F(DstMem | SrcNone | Lock, em_not),
4091− F(DstMem | SrcNone | Lock, em_neg),
4092− F(DstXacc | Src2Mem, em_mul_ex),
4093− F(DstXacc | Src2Mem, em_imul_ex),
4094− F(DstXacc | Src2Mem, em_div_ex),
4095− F(DstXacc | Src2Mem, em_idiv_ex),
4023+ I(DstMem | SrcImm | NoWrite, em_test),
4024+ I(DstMem | SrcImm | NoWrite, em_test),
4025+ I(DstMem | SrcNone | Lock, em_not),
4026+ I(DstMem | SrcNone | Lock, em_neg),
4027+ I(DstXacc | Src2Mem, em_mul_ex),
4028+ I(DstXacc | Src2Mem, em_imul_ex),
4029+ I(DstXacc | Src2Mem, em_div_ex),
4030+ I(DstXacc | Src2Mem, em_idiv_ex),
40964031 };
40974032
40984033 static const struct opcode group4[] = {
4099− F(ByteOp | DstMem | SrcNone | Lock, em_inc),
4100− F(ByteOp | DstMem | SrcNone | Lock, em_dec),
4034+ I(ByteOp | DstMem | SrcNone | Lock, em_inc),
4035+ I(ByteOp | DstMem | SrcNone | Lock, em_dec),
41014036 N, N, N, N, N, N,
41024037 };
41034038
41044039 static const struct opcode group5[] = {
4105− F(DstMem | SrcNone | Lock, em_inc),
4106− F(DstMem | SrcNone | Lock, em_dec),
4040+ I(DstMem | SrcNone | Lock, em_inc),
4041+ I(DstMem | SrcNone | Lock, em_dec),
41074042 I(SrcMem | NearBranch | IsBranch | ShadowStack, em_call_near_abs),
41084043 I(SrcMemFAddr | ImplicitOps | IsBranch | ShadowStack, em_call_far),
41094044 I(SrcMem | NearBranch | IsBranch, em_jmp_abs),
@@ -4139,10 +4074,10 @@ static const struct group_dual group7 = { { · 29 unmodified lines
41394074
41404075 static const struct opcode group8[] = {
41414076 N, N, N, N,
4142− F(DstMem | SrcImmByte | NoWrite, em_bt),
4143− F(DstMem | SrcImmByte | Lock | PageTable, em_bts),
4144− F(DstMem | SrcImmByte | Lock, em_btr),
4145− F(DstMem | SrcImmByte | Lock | PageTable, em_btc),
4077+ I(DstMem | SrcImmByte | NoWrite, em_bt),
4078+ I(DstMem | SrcImmByte | Lock | PageTable, em_bts),
4079+ I(DstMem | SrcImmByte | Lock, em_btr),
4080+ I(DstMem | SrcImmByte | Lock | PageTable, em_btc),
41464081 };
41474082
41484083 /*
@@ -4279,31 +4214,31 @@ static const struct instr_dual instr_dual_8d = { · 130 unmodified lines
42794214
42804215 static const struct opcode opcode_table[256] = {
42814216 /* 0x00 - 0x07 */
4282− F6ALU(Lock, em_add),
4217+ I6ALU(Lock, em_add),
42834218 I(ImplicitOps | Stack | No64 | Src2ES, em_push_sreg),
42844219 I(ImplicitOps | Stack | No64 | Src2ES, em_pop_sreg),
42854220 /* 0x08 - 0x0F */
4286− F6ALU(Lock | PageTable, em_or),
4221+ I6ALU(Lock | PageTable, em_or),
42874222 I(ImplicitOps | Stack | No64 | Src2CS, em_push_sreg),
42884223 N,
42894224 /* 0x10 - 0x17 */
4290− F6ALU(Lock, em_adc),
4225+ I6ALU(Lock, em_adc),
42914226 I(ImplicitOps | Stack | No64 | Src2SS, em_push_sreg),
42924227 I(ImplicitOps | Stack | No64 | Src2SS, em_pop_sreg),
42934228 /* 0x18 - 0x1F */
4294− F6ALU(Lock, em_sbb),
4229+ I6ALU(Lock, em_sbb),
42954230 I(ImplicitOps | Stack | No64 | Src2DS, em_push_sreg),
42964231 I(ImplicitOps | Stack | No64 | Src2DS, em_pop_sreg),
42974232 /* 0x20 - 0x27 */
4298− F6ALU(Lock | PageTable, em_and), N, N,
4233+ I6ALU(Lock | PageTable, em_and), N, N,
42994234 /* 0x28 - 0x2F */
4300− F6ALU(Lock, em_sub), N, I(ByteOp | DstAcc | No64, em_das),
4235+ I6ALU(Lock, em_sub), N, I(ByteOp | DstAcc | No64, em_das),
43014236 /* 0x30 - 0x37 */
4302− F6ALU(Lock, em_xor), N, N,
4237+ I6ALU(Lock, em_xor), N, N,
43034238 /* 0x38 - 0x3F */
4304− F6ALU(NoWrite, em_cmp), N, N,
4239+ I6ALU(NoWrite, em_cmp), N, N,
43054240 /* 0x40 - 0x4F */
4306− X8(F(DstReg, em_inc)), X8(F(DstReg, em_dec)),
4241+ X8(I(DstReg, em_inc)), X8(I(DstReg, em_dec)),
43074242 /* 0x50 - 0x57 */
43084243 X8(I(SrcReg | Stack, em_push)),
43094244 /* 0x58 - 0x5F */
@@ -4327,7 +4262,7 @@ static const struct opcode opcode_table[256] = { · 17 unmodified lines
43274262 G(DstMem | SrcImm, group1),
43284263 G(ByteOp | DstMem | SrcImm | No64, group1),
43294264 G(DstMem | SrcImmByte, group1),
4330− F2bv(DstMem | SrcReg | ModRM | NoWrite, em_test),
4265+ I2bv(DstMem | SrcReg | ModRM | NoWrite, em_test),
43314266 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_xchg),
43324267 /* 0x88 - 0x8F */
43334268 I2bv(DstMem | SrcReg | ModRM | Mov | PageTable, em_mov),
@@ -4348,12 +4283,12 @@ static const struct opcode opcode_table[256] = { · 14 unmodified lines
43484283 I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
43494284 I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov),
43504285 I2bv(SrcSI | DstDI | Mov | String | TwoMemOp, em_mov),
4351− F2bv(SrcSI | DstDI | String | NoWrite | TwoMemOp, em_cmp_r),
4286+ I2bv(SrcSI | DstDI | String | NoWrite | TwoMemOp, em_cmp_r),
43524287 /* 0xA8 - 0xAF */
4353− F2bv(DstAcc | SrcImm | NoWrite, em_test),
4288+ I2bv(DstAcc | SrcImm | NoWrite, em_test),
43544289 I2bv(SrcAcc | DstDI | Mov | String, em_mov),
43554290 I2bv(SrcSI | DstAcc | Mov | String, em_mov),
4356− F2bv(SrcAcc | DstDI | String | NoWrite, em_cmp_r),
4291+ I2bv(SrcAcc | DstDI | String | NoWrite, em_cmp_r),
43574292 /* 0xB0 - 0xB7 */
43584293 X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)),
43594294 /* 0xB8 - 0xBF */
@@ -4378,7 +4313,7 @@ static const struct opcode opcode_table[256] = { · 18 unmodified lines
43784313 G(Src2CL | ByteOp, group2), G(Src2CL, group2),
43794314 I(DstAcc | SrcImmUByte | No64, em_aam),
43804315 I(DstAcc | SrcImmUByte | No64, em_aad),
4381− F(DstAcc | ByteOp | No64, em_salc),
4316+ I(DstAcc | ByteOp | No64, em_salc),
43824317 I(DstAcc | SrcXLat | ByteOp, em_mov),
43834318 /* 0xD8 - 0xDF */
43844319 N, E(0, &escape_d9), N, E(0, &escape_db), N, E(0, &escape_dd), N, N,
@@ -4463,32 +4398,32 @@ static const struct opcode twobyte_table[256] = { · 78 unmodified lines
44634398 /* 0xA0 - 0xA7 */
44644399 I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg),
44654400 II(ImplicitOps, em_cpuid, cpuid),
4466− F(DstMem | SrcReg | ModRM | BitOp | NoWrite, em_bt),
4467− F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shld),
4468− F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
4401+ I(DstMem | SrcReg | ModRM | BitOp | NoWrite, em_bt),
4402+ I(DstMem | SrcReg | Src2ImmByte | ModRM, em_shld),
4403+ I(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
44694404 /* 0xA8 - 0xAF */
44704405 I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
44714406 II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
4472− F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
4473− F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
4474− F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
4475− GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul),
4407+ I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
4408+ I(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
4409+ I(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
4410+ GD(0, &group15), I(DstReg | SrcMem | ModRM, em_imul),
44764411 /* 0xB0 - 0xB7 */
44774412 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable | SrcWrite, em_cmpxchg),
44784413 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
4479− F(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
4414+ I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
44804415 I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
44814416 I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg),
44824417 D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
44834418 /* 0xB8 - 0xBF */
44844419 N, N,
44854420 G(BitOp, group8),
4486− F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
4421+ I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
44874422 I(DstReg | SrcMem | ModRM, em_bsf_c),
44884423 I(DstReg | SrcMem | ModRM, em_bsr_c),
44894424 D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
44904425 /* 0xC0 - 0xC7 */
4491− F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd),
4426+ I2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd),
44924427 N, ID(0, &instr_dual_0f_c3),
44934428 N, N, N, GD(0, &group9),
44944429 /* 0xC8 - 0xCF */
@@ -5198,24 +5133,6 @@ static void fetch_possible_mmx_operand(struct operand *op) · 703 unmodified lines
51985133 kvm_read_mmx_reg(op->addr.mm, &op->mm_val);
51995134 }
52005135
5201−static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop)
5202−{
5203− ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF;
5204−
5205− if (!(ctxt->d & ByteOp))
5206− fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE;
5207−
5208− asm("push %[flags]; popf; " CALL_NOSPEC " ; pushf; pop %[flags]\n"
5209− : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags),
5210− [thunk_target]"+S"(fop), ASM_CALL_CONSTRAINT
5211− : "c"(ctxt->src2.val));
5212−
5213− ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
5214− if (!fop) /* exception is returned in fop variable */
5215− return emulate_de(ctxt);
5216− return X86EMUL_CONTINUE;
5217−}
5218−
52195136 void init_decode_cache(struct x86_emulate_ctxt *ctxt)
52205137 {
52215138 /* Clear fields that are set conditionally but read without a guard. */
@@ -5379,10 +5296,7 @@ special_insn: · 157 unmodified lines
53795296 ctxt->eflags &= ~X86_EFLAGS_RF;
53805297
53815298 if (ctxt->execute) {
5382− if (ctxt->d & Fastop)
5383− rc = fastop(ctxt, ctxt->fop);
5384− else
5385− rc = ctxt->execute(ctxt);
5299+ rc = ctxt->execute(ctxt);
53865300 if (rc != X86EMUL_CONTINUE)
53875301 goto done;
53885302 goto writeback;
arch/x86/kvm/vmx/vmenter.S+4−0
@@ -361,6 +361,10 @@ SYM_FUNC_END(vmread_error_trampoline) · 360 unmodified lines
361361
362362 .section .text, "ax"
363363
364+#ifndef CONFIG_X86_FRED
365+
364366 SYM_FUNC_START(vmx_do_interrupt_irqoff)
365367 VMX_DO_EVENT_IRQOFF CALL_NOSPEC _ASM_ARG1
366368 SYM_FUNC_END(vmx_do_interrupt_irqoff)
369+
370+#endif
arch/x86/kvm/vmx/vmx.c+7−1
@@ -7021,8 +7021,14 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu, · 7020 unmodified lines
70217021 "unexpected VM-Exit interrupt info: 0x%x", intr_info))
70227022 return;
70237023
7024+ /*
7025+ * Invoke the kernel's IRQ handler for the vector. Use the FRED path
7026+ * when it's available even if FRED isn't fully enabled, e.g. even if
7027+ * FRED isn't supported in hardware, in order to avoid the indirect
7028+ * CALL in the non-FRED path.
7029+ */
70247030 kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ);
7025− if (cpu_feature_enabled(X86_FEATURE_FRED))
7031+ if (IS_ENABLED(CONFIG_X86_FRED))
70267032 fred_entry_from_kvm(EVENT_TYPE_EXTINT, vector);
70277033 else
70287034 vmx_do_interrupt_irqoff(gate_offset((gate_desc *)host_idt_base + vector));
arch/x86/lib/bhi.S+29−29
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 #include <asm/nospec-branch.h>
66
77 /*
8− * Notably, the FineIBT preamble calling these will have ZF set and r10 zero.
8+ * Notably, the FineIBT preamble calling these will have ZF set and eax zero.
99 *
1010 * The very last element is in fact larger than 32 bytes, but since its the
1111 * last element, this does not matter,
@@ -36,7 +36,7 @@ SYM_INNER_LABEL(__bhi_args_1, SYM_L_LOCAL) · 24 unmodified lines
3636 ANNOTATE_NOENDBR
3737 UNWIND_HINT_FUNC
3838 jne .Lud_1
39− cmovne %r10, %rdi
39+ cmovne %rax, %rdi
4040 ANNOTATE_UNRET_SAFE
4141 ret
4242 int3
@@ -53,8 +53,8 @@ SYM_INNER_LABEL(__bhi_args_2, SYM_L_LOCAL) · 10 unmodified lines
5353 ANNOTATE_NOENDBR
5454 UNWIND_HINT_FUNC
5555 jne .Lud_1
56− cmovne %r10, %rdi
57− cmovne %r10, %rsi
56+ cmovne %rax, %rdi
57+ cmovne %rax, %rsi
5858 ANNOTATE_UNRET_SAFE
5959 ret
6060 int3
@@ -64,9 +64,9 @@ SYM_INNER_LABEL(__bhi_args_3, SYM_L_LOCAL) · 3 unmodified lines
6464 ANNOTATE_NOENDBR
6565 UNWIND_HINT_FUNC
6666 jne .Lud_1
67− cmovne %r10, %rdi
68− cmovne %r10, %rsi
69− cmovne %r10, %rdx
67+ cmovne %rax, %rdi
68+ cmovne %rax, %rsi
69+ cmovne %rax, %rdx
7070 ANNOTATE_UNRET_SAFE
7171 ret
7272 int3
@@ -76,10 +76,10 @@ SYM_INNER_LABEL(__bhi_args_4, SYM_L_LOCAL) · 3 unmodified lines
7676 ANNOTATE_NOENDBR
7777 UNWIND_HINT_FUNC
7878 jne .Lud_2
79− cmovne %r10, %rdi
80− cmovne %r10, %rsi
81− cmovne %r10, %rdx
82− cmovne %r10, %rcx
79+ cmovne %rax, %rdi
80+ cmovne %rax, %rsi
81+ cmovne %rax, %rdx
82+ cmovne %rax, %rcx
8383 ANNOTATE_UNRET_SAFE
8484 ret
8585 int3
@@ -89,11 +89,11 @@ SYM_INNER_LABEL(__bhi_args_5, SYM_L_LOCAL) · 3 unmodified lines
8989 ANNOTATE_NOENDBR
9090 UNWIND_HINT_FUNC
9191 jne .Lud_2
92− cmovne %r10, %rdi
93− cmovne %r10, %rsi
94− cmovne %r10, %rdx
95− cmovne %r10, %rcx
96− cmovne %r10, %r8
92+ cmovne %rax, %rdi
93+ cmovne %rax, %rsi
94+ cmovne %rax, %rdx
95+ cmovne %rax, %rcx
96+ cmovne %rax, %r8
9797 ANNOTATE_UNRET_SAFE
9898 ret
9999 int3
@@ -110,12 +110,12 @@ SYM_INNER_LABEL(__bhi_args_6, SYM_L_LOCAL) · 10 unmodified lines
110110 ANNOTATE_NOENDBR
111111 UNWIND_HINT_FUNC
112112 jne .Lud_2
113− cmovne %r10, %rdi
114− cmovne %r10, %rsi
115− cmovne %r10, %rdx
116− cmovne %r10, %rcx
117− cmovne %r10, %r8
118− cmovne %r10, %r9
113+ cmovne %rax, %rdi
114+ cmovne %rax, %rsi
115+ cmovne %rax, %rdx
116+ cmovne %rax, %rcx
117+ cmovne %rax, %r8
118+ cmovne %rax, %r9
119119 ANNOTATE_UNRET_SAFE
120120 ret
121121 int3
@@ -125,13 +125,13 @@ SYM_INNER_LABEL(__bhi_args_7, SYM_L_LOCAL) · 3 unmodified lines
125125 ANNOTATE_NOENDBR
126126 UNWIND_HINT_FUNC
127127 jne .Lud_2
128− cmovne %r10, %rdi
129− cmovne %r10, %rsi
130− cmovne %r10, %rdx
131− cmovne %r10, %rcx
132− cmovne %r10, %r8
133− cmovne %r10, %r9
134− cmovne %r10, %rsp
128+ cmovne %rax, %rdi
129+ cmovne %rax, %rsi
130+ cmovne %rax, %rdx
131+ cmovne %rax, %rcx
132+ cmovne %rax, %r8
133+ cmovne %rax, %r9
134+ cmovne %rax, %rsp
135135 ANNOTATE_UNRET_SAFE
136136 ret
137137 int3
arch/x86/lib/retpoline.S+2−2
@@ -134,10 +134,10 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array) · 133 unmodified lines
134134 .macro ITS_THUNK reg
135135
136136 /*
137− * If CFI paranoid is used then the ITS thunk starts with opcodes (0xea; jne 1b)
137+ * If CFI paranoid is used then the ITS thunk starts with opcodes (1: udb; jne 1b)
138138 * that complete the fineibt_paranoid caller sequence.
139139 */
140−1: .byte 0xea
140+1: ASM_UDB
141141 SYM_INNER_LABEL(__x86_indirect_paranoid_thunk_\reg, SYM_L_GLOBAL)
142142 UNWIND_HINT_UNDEFINED
143143 ANNOTATE_NOENDBR
arch/x86/net/bpf_jit_comp.c+3−3
@@ -420,12 +420,12 @@ static void emit_fineibt(u8 **pprog, u8 *ip, u32 hash, int arity) · 419 unmodified lines
420420 u8 *prog = *pprog;
421421
422422 EMIT_ENDBR();
423− EMIT3_off32(0x41, 0x81, 0xea, hash); /* subl $hash, %r10d */
423+ EMIT1_off32(0x2d, hash); /* subl $hash, %eax */
424424 if (cfi_bhi) {
425+ EMIT2(0x2e, 0x2e); /* cs cs */
425426 emit_call(&prog, __bhi_args[arity], ip + 11);
426427 } else {
427− EMIT2(0x75, 0xf9); /* jne.d8 .-7 */
428− EMIT3(0x0f, 0x1f, 0x00); /* nop3 */
428+ EMIT3_off32(0x2e, 0x0f, 0x85, 3); /* jne.d32,pn 3 */
429429 }
430430 EMIT_ENDBR_POISON();
431431
arch/x86/platform/efi/efi_stub_64.S+4−0
@@ -11,6 +11,10 @@ · 10 unmodified lines
1111 #include <asm/nospec-branch.h>
1212
1313 SYM_FUNC_START(__efi_call)
14+ /*
15+ * The EFI code doesn't have any CFI, annotate away the CFI violation.
16+ */
17+ ANNOTATE_NOCFI_SYM
1418 pushq %rbp
1519 movq %rsp, %rbp
1620 and $~0xf, %rsp
drivers/misc/lkdtm/perms.c+5−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <linux/vmalloc.h>
1010 #include <linux/mman.h>
1111 #include <linux/uaccess.h>
12+#include <linux/objtool.h>
1213 #include <asm/cacheflush.h>
1314 #include <asm/sections.h>
1415
@@ -86,6 +87,10 @@ static noinline __nocfi void execute_location(void *dst, bool write) · 71 unmodified lines
8687 func();
8788 pr_err("FAIL: func returned\n");
8889 }
90+/*
91+ * Explicitly doing the wrong thing for testing.
92+ */
93+ANNOTATE_NOCFI_SYM(execute_location);
8994
9095 static void execute_user_location(void *dst)
9196 {
include/linux/compiler-clang.h+0−5
@@ -115,11 +115,6 @@ · 114 unmodified lines
115115 # define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
116116 #endif
117117
118−#if __has_feature(kcfi)
119−/* Disable CFI checking inside a function. */
120−#define __nocfi __attribute__((__no_sanitize__("kcfi")))
121−#endif
122−
123118 /*
124119 * Turn individual warnings and errors on and off locally, depending
125120 * on version.
include/linux/compiler-gcc.h+0−4
@@ -35,10 +35,6 @@ · 34 unmodified lines
3535 (typeof(ptr)) (__ptr + (off)); \
3636 })
3737
38−#ifdef CONFIG_MITIGATION_RETPOLINE
39−#define __noretpoline __attribute__((__indirect_branch__("keep")))
40−#endif
41−
4238 #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
4339 #define __latent_entropy __attribute__((latent_entropy))
4440 #endif
include/linux/compiler_types.h+3−1
@@ -455,7 +455,9 @@ struct ftrace_likely_data { · 454 unmodified lines
455455 # define __noscs
456456 #endif
457457
458−#ifndef __nocfi
458+#if defined(CONFIG_CFI)
459+# define __nocfi __attribute__((__no_sanitize__("kcfi")))
460+#else
459461 # define __nocfi
460462 #endif
461463
include/linux/init.h+0−8
@@ -7,13 +7,6 @@ · 6 unmodified lines
77 #include <linux/stringify.h>
88 #include <linux/types.h>
99
10−/* Built-in __init functions needn't be compiled with retpoline */
11−#if defined(__noretpoline) && !defined(MODULE)
12−#define __noinitretpoline __noretpoline
13−#else
14−#define __noinitretpoline
15−#endif
16−
1710 /* These macros are used to mark some functions or
1811 * initialized data (doesn't apply to uninitialized data)
1912 * as `initialization' functions. The kernel can take this
@@ -50,7 +43,6 @@ · 30 unmodified lines
5043 /* These are for everybody (although not all archs will actually
5144 discard it in modules) */
5245 #define __init __section(".init.text") __cold __latent_entropy \
53− __noinitretpoline \
5446 __no_kstack_erase
5547 #define __initdata __section(".init.data")
5648 #define __initconst __section(".init.rodata")
include/linux/objtool.h+10−0
@@ -184,6 +184,15 @@ · 183 unmodified lines
184184 * WARN using UD2.
185185 */
186186 #define ANNOTATE_REACHABLE(label) __ASM_ANNOTATE(label, ANNOTYPE_REACHABLE)
187+/*
188+ * This should not be used; it annotates away CFI violations. There are a few
189+ * valid use cases like kexec handover to the next kernel image, and there is
190+ * no security concern there.
191+ *
192+ * There are also a few real issues annotated away, like EFI because we can't
193+ * control the EFI code.
194+ */
195+#define ANNOTATE_NOCFI_SYM(sym) asm(__ASM_ANNOTATE(sym, ANNOTYPE_NOCFI))
187196
188197 #else
189198 #define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR
@@ -194,6 +203,7 @@ · 4 unmodified lines
194203 #define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
195204 #define ANNOTATE_UNRET_BEGIN ANNOTATE type=ANNOTYPE_UNRET_BEGIN
196205 #define ANNOTATE_REACHABLE ANNOTATE type=ANNOTYPE_REACHABLE
206+#define ANNOTATE_NOCFI_SYM ANNOTATE type=ANNOTYPE_NOCFI
197207 #endif
198208
199209 #if defined(CONFIG_NOINSTR_VALIDATION) && \
include/linux/objtool_types.h+1−0
@@ -65,5 +65,6 @@ struct unwind_hint { · 64 unmodified lines
6565 #define ANNOTYPE_IGNORE_ALTS 6
6666 #define ANNOTYPE_INTRA_FUNCTION_CALL 7
6767 #define ANNOTYPE_REACHABLE 8
68+#define ANNOTYPE_NOCFI 9
6869
6970 #endif /* _LINUX_OBJTOOL_TYPES_H */
tools/include/linux/objtool_types.h+1−0
@@ -65,5 +65,6 @@ struct unwind_hint { · 64 unmodified lines
6565 #define ANNOTYPE_IGNORE_ALTS 6
6666 #define ANNOTYPE_INTRA_FUNCTION_CALL 7
6767 #define ANNOTYPE_REACHABLE 8
68+#define ANNOTYPE_NOCFI 9
6869
6970 #endif /* _LINUX_OBJTOOL_TYPES_H */
tools/objtool/check.c+42−0
@@ -2392,6 +2392,8 @@ static int __annotate_ifc(struct objtool_file *file, int type, struct instructio · 2391 unmodified lines
23922392
23932393 static int __annotate_late(struct objtool_file *file, int type, struct instruction *insn)
23942394 {
2395+ struct symbol *sym;
2396+
23952397 switch (type) {
23962398 case ANNOTYPE_NOENDBR:
23972399 /* early */
@@ -2433,6 +2435,15 @@ static int __annotate_late(struct objtool_file *file, int type, struct instructi · 35 unmodified lines
24332435 insn->dead_end = false;
24342436 break;
24352437
2438+ case ANNOTYPE_NOCFI:
2439+ sym = insn->sym;
2440+ if (!sym) {
2441+ ERROR_INSN(insn, "dodgy NOCFI annotation");
2442+ return -1;
2443+ }
2444+ insn->sym->nocfi = 1;
2445+ break;
2446+
24362447 default:
24372448 ERROR_INSN(insn, "Unknown annotation type: %d", type);
24382449 return -1;
@@ -3994,6 +4005,37 @@ static int validate_retpoline(struct objtool_file *file) · 1555 unmodified lines
39944005 warnings++;
39954006 }
39964007
4008+ if (!opts.cfi)
4009+ return warnings;
4010+
4011+ /*
4012+ * kCFI call sites look like:
4013+ *
4014+ * movl $(-0x12345678), %r10d
4015+ * addl -4(%r11), %r10d
4016+ * jz 1f
4017+ * ud2
4018+ * 1: cs call __x86_indirect_thunk_r11
4019+ *
4020+ * Verify all indirect calls are kCFI adorned by checking for the
4021+ * UD2. Notably, doing __nocfi calls to regular (cfi) functions is
4022+ * broken.
4023+ */
4024+ list_for_each_entry(insn, &file->retpoline_call_list, call_node) {
4025+ struct symbol *sym = insn->sym;
4026+
4027+ if (sym && (sym->type == STT_NOTYPE ||
4028+ sym->type == STT_FUNC) && !sym->nocfi) {
4029+ struct instruction *prev =
4030+ prev_insn_same_sym(file, insn);
4031+
4032+ if (!prev || prev->type != INSN_BUG) {
4033+ WARN_INSN(insn, "no-cfi indirect call!");
4034+ warnings++;
4035+ }
4036+ }
4037+ }
4038+
39974039 return warnings;
39984040 }
39994041
tools/objtool/include/objtool/elf.h+1−0
@@ -70,6 +70,7 @@ struct symbol { · 69 unmodified lines
7070 u8 local_label : 1;
7171 u8 frame_pointer : 1;
7272 u8 ignore : 1;
73+ u8 nocfi : 1;
7374 struct list_head pv_target;
7475 struct reloc *relocs;
7576 struct section *group_sec;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t