- Fix CPU feature dependencies of GFNI, VAES, and VPCLMULQDQ
- Print the correct error code when FRED reports a bad event type - Add a FRED-specific INT80 handler without the special dances that need to happen in the current one - Enable the using-the-default-return-thunk-but-you-should-not warning only on configs which actually enable those special return thunks - Check the proper feature flags when selecting BHI retpoline mitigation -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmYk0HUACgkQEsHwGGHe VUr7LQ//SZAd9Gcww794BP54TelXnrOWv7A5VZrzt1W3vknQCavKVdsY4seUVkT/ mSzg0GPXMUNf5SA11y41k9ZxpuBp3J1rF/NG/x0tkB7mIxP6Lmuseaun9gQQd00e 9YzyK9Da9J9svQvWFd3cPDHiQT6vwz/05f2iyc7xVgSqnatRs/xl/BYZkJm6xl9w nSOjD4XEy5pydP1W0mH4/g+rWG5rBTzhPkbehX+aRFhC+fSEYv0g9TJpMwWs82vv RJwbUaSxHBtycZ9x77WoBJOvtEVISO35JQuJfYzK82MUiZS5pND4dpzjyF/0mQjQ kfVTOqWnE1jtDX+QaqCmwEVrGfEGw2aratQDXIcahqhpNUX269X4XuFSH5vhVF+V yblOx8zX4og4/g0mQ9ijddc2Jr9fbGPNAZwFQztiK+uGaua/S6E/smtte0YOyV5D qZD1DXtDg4WjjxRY2tPQTuIEBGicb6xDY7rby7kXzAwIgZO/rcVL3/kWDMzBffIK In0Khlu33dezzvpQVWgkQcoK/mGVywJyyOxpYwuiLRZVfarMt304/i7FbCGSAf+4 hGVdl+gfa8+j2vjveQe3a2QeCfjo1XkYwVJYJdzWmTnoU90mAzQbeFm3u+didEqE kj1ObMlKNbrsv70M805Vmequ5VwKTxPyHcbxI+tjKGS/TC8Gy+0= =53Ih -----END PGP SIGNATURE----- Merge tag 'x86_urgent_for_v6.9_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 fixes from Borislav Petkov: - Fix CPU feature dependencies of GFNI, VAES, and VPCLMULQDQ - Print the correct error code when FRED reports a bad event type - Add a FRED-specific INT80 handler without the special dances that need to happen in the current one - Enable the using-the-default-return-thunk-but-you-should-not warning only on configs which actually enable those special return thunks - Check the proper feature flags when selecting BHI retpoline mitigation * tag 'x86_urgent_for_v6.9_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ x86/fred: Fix incorrect error code printout in fred_bad_type() x86/fred: Fix INT80 emulation for FRED x86/retpolines: Enable the default thunk warning only on relevant configs x86/bugs: Fix BHI retpoline check
This commit is contained in:
commit
d07a0b861d
|
@ -255,6 +255,71 @@ __visible noinstr void do_int80_emulation(struct pt_regs *regs)
|
||||||
instrumentation_end();
|
instrumentation_end();
|
||||||
syscall_exit_to_user_mode(regs);
|
syscall_exit_to_user_mode(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_FRED
|
||||||
|
/*
|
||||||
|
* A FRED-specific INT80 handler is warranted for the follwing reasons:
|
||||||
|
*
|
||||||
|
* 1) As INT instructions and hardware interrupts are separate event
|
||||||
|
* types, FRED does not preclude the use of vector 0x80 for external
|
||||||
|
* interrupts. As a result, the FRED setup code does not reserve
|
||||||
|
* vector 0x80 and calling int80_is_external() is not merely
|
||||||
|
* suboptimal but actively incorrect: it could cause a system call
|
||||||
|
* to be incorrectly ignored.
|
||||||
|
*
|
||||||
|
* 2) It is called only for handling vector 0x80 of event type
|
||||||
|
* EVENT_TYPE_SWINT and will never be called to handle any external
|
||||||
|
* interrupt (event type EVENT_TYPE_EXTINT).
|
||||||
|
*
|
||||||
|
* 3) FRED has separate entry flows depending on if the event came from
|
||||||
|
* user space or kernel space, and because the kernel does not use
|
||||||
|
* INT insns, the FRED kernel entry handler fred_entry_from_kernel()
|
||||||
|
* falls through to fred_bad_type() if the event type is
|
||||||
|
* EVENT_TYPE_SWINT, i.e., INT insns. So if the kernel is handling
|
||||||
|
* an INT insn, it can only be from a user level.
|
||||||
|
*
|
||||||
|
* 4) int80_emulation() does a CLEAR_BRANCH_HISTORY. While FRED will
|
||||||
|
* likely take a different approach if it is ever needed: it
|
||||||
|
* probably belongs in either fred_intx()/ fred_other() or
|
||||||
|
* asm_fred_entrypoint_user(), depending on if this ought to be done
|
||||||
|
* for all entries from userspace or only system
|
||||||
|
* calls.
|
||||||
|
*
|
||||||
|
* 5) INT $0x80 is the fast path for 32-bit system calls under FRED.
|
||||||
|
*/
|
||||||
|
DEFINE_FREDENTRY_RAW(int80_emulation)
|
||||||
|
{
|
||||||
|
int nr;
|
||||||
|
|
||||||
|
enter_from_user_mode(regs);
|
||||||
|
|
||||||
|
instrumentation_begin();
|
||||||
|
add_random_kstack_offset();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FRED pushed 0 into regs::orig_ax and regs::ax contains the
|
||||||
|
* syscall number.
|
||||||
|
*
|
||||||
|
* User tracing code (ptrace or signal handlers) might assume
|
||||||
|
* that the regs::orig_ax contains a 32-bit number on invoking
|
||||||
|
* a 32-bit syscall.
|
||||||
|
*
|
||||||
|
* Establish the syscall convention by saving the 32bit truncated
|
||||||
|
* syscall number in regs::orig_ax and by invalidating regs::ax.
|
||||||
|
*/
|
||||||
|
regs->orig_ax = regs->ax & GENMASK(31, 0);
|
||||||
|
regs->ax = -ENOSYS;
|
||||||
|
|
||||||
|
nr = syscall_32_enter(regs);
|
||||||
|
|
||||||
|
local_irq_enable();
|
||||||
|
nr = syscall_enter_from_user_mode_work(regs, nr);
|
||||||
|
do_syscall_32_irqs_on(regs, nr);
|
||||||
|
|
||||||
|
instrumentation_end();
|
||||||
|
syscall_exit_to_user_mode(regs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else /* CONFIG_IA32_EMULATION */
|
#else /* CONFIG_IA32_EMULATION */
|
||||||
|
|
||||||
/* Handles int $0x80 on a 32bit kernel */
|
/* Handles int $0x80 on a 32bit kernel */
|
||||||
|
|
|
@ -28,9 +28,9 @@ static noinstr void fred_bad_type(struct pt_regs *regs, unsigned long error_code
|
||||||
if (regs->fred_cs.sl > 0) {
|
if (regs->fred_cs.sl > 0) {
|
||||||
pr_emerg("PANIC: invalid or fatal FRED event; event type %u "
|
pr_emerg("PANIC: invalid or fatal FRED event; event type %u "
|
||||||
"vector %u error 0x%lx aux 0x%lx at %04x:%016lx\n",
|
"vector %u error 0x%lx aux 0x%lx at %04x:%016lx\n",
|
||||||
regs->fred_ss.type, regs->fred_ss.vector, regs->orig_ax,
|
regs->fred_ss.type, regs->fred_ss.vector, error_code,
|
||||||
fred_event_data(regs), regs->cs, regs->ip);
|
fred_event_data(regs), regs->cs, regs->ip);
|
||||||
die("invalid or fatal FRED event", regs, regs->orig_ax);
|
die("invalid or fatal FRED event", regs, error_code);
|
||||||
panic("invalid or fatal FRED event");
|
panic("invalid or fatal FRED event");
|
||||||
} else {
|
} else {
|
||||||
unsigned long flags = oops_begin();
|
unsigned long flags = oops_begin();
|
||||||
|
@ -38,10 +38,10 @@ static noinstr void fred_bad_type(struct pt_regs *regs, unsigned long error_code
|
||||||
|
|
||||||
pr_alert("BUG: invalid or fatal FRED event; event type %u "
|
pr_alert("BUG: invalid or fatal FRED event; event type %u "
|
||||||
"vector %u error 0x%lx aux 0x%lx at %04x:%016lx\n",
|
"vector %u error 0x%lx aux 0x%lx at %04x:%016lx\n",
|
||||||
regs->fred_ss.type, regs->fred_ss.vector, regs->orig_ax,
|
regs->fred_ss.type, regs->fred_ss.vector, error_code,
|
||||||
fred_event_data(regs), regs->cs, regs->ip);
|
fred_event_data(regs), regs->cs, regs->ip);
|
||||||
|
|
||||||
if (__die("Invalid or fatal FRED event", regs, regs->orig_ax))
|
if (__die("Invalid or fatal FRED event", regs, error_code))
|
||||||
sig = 0;
|
sig = 0;
|
||||||
|
|
||||||
oops_end(flags, regs, sig);
|
oops_end(flags, regs, sig);
|
||||||
|
@ -66,7 +66,7 @@ static noinstr void fred_intx(struct pt_regs *regs)
|
||||||
/* INT80 */
|
/* INT80 */
|
||||||
case IA32_SYSCALL_VECTOR:
|
case IA32_SYSCALL_VECTOR:
|
||||||
if (ia32_enabled())
|
if (ia32_enabled())
|
||||||
return int80_emulation(regs);
|
return fred_int80_emulation(regs);
|
||||||
fallthrough;
|
fallthrough;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1652,7 +1652,8 @@ static void __init bhi_select_mitigation(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
|
/* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
|
||||||
if (cpu_feature_enabled(X86_FEATURE_RETPOLINE)) {
|
if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
|
||||||
|
!boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
|
||||||
spec_ctrl_disable_kernel_rrsba();
|
spec_ctrl_disable_kernel_rrsba();
|
||||||
if (rrsba_disabled)
|
if (rrsba_disabled)
|
||||||
return;
|
return;
|
||||||
|
@ -2804,11 +2805,13 @@ static const char *spectre_bhi_state(void)
|
||||||
{
|
{
|
||||||
if (!boot_cpu_has_bug(X86_BUG_BHI))
|
if (!boot_cpu_has_bug(X86_BUG_BHI))
|
||||||
return "; BHI: Not affected";
|
return "; BHI: Not affected";
|
||||||
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
|
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
|
||||||
return "; BHI: BHI_DIS_S";
|
return "; BHI: BHI_DIS_S";
|
||||||
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
|
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
|
||||||
return "; BHI: SW loop, KVM: SW loop";
|
return "; BHI: SW loop, KVM: SW loop";
|
||||||
else if (boot_cpu_has(X86_FEATURE_RETPOLINE) && rrsba_disabled)
|
else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
|
||||||
|
!boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE) &&
|
||||||
|
rrsba_disabled)
|
||||||
return "; BHI: Retpoline";
|
return "; BHI: Retpoline";
|
||||||
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
|
else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
|
||||||
return "; BHI: Vulnerable, KVM: SW loop";
|
return "; BHI: Vulnerable, KVM: SW loop";
|
||||||
|
|
|
@ -44,7 +44,10 @@ static const struct cpuid_dep cpuid_deps[] = {
|
||||||
{ X86_FEATURE_F16C, X86_FEATURE_XMM2, },
|
{ X86_FEATURE_F16C, X86_FEATURE_XMM2, },
|
||||||
{ X86_FEATURE_AES, X86_FEATURE_XMM2 },
|
{ X86_FEATURE_AES, X86_FEATURE_XMM2 },
|
||||||
{ X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 },
|
{ X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 },
|
||||||
|
{ X86_FEATURE_GFNI, X86_FEATURE_XMM2 },
|
||||||
{ X86_FEATURE_FMA, X86_FEATURE_AVX },
|
{ X86_FEATURE_FMA, X86_FEATURE_AVX },
|
||||||
|
{ X86_FEATURE_VAES, X86_FEATURE_AVX },
|
||||||
|
{ X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX },
|
||||||
{ X86_FEATURE_AVX2, X86_FEATURE_AVX, },
|
{ X86_FEATURE_AVX2, X86_FEATURE_AVX, },
|
||||||
{ X86_FEATURE_AVX512F, X86_FEATURE_AVX, },
|
{ X86_FEATURE_AVX512F, X86_FEATURE_AVX, },
|
||||||
{ X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F },
|
{ X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F },
|
||||||
|
@ -56,9 +59,6 @@ static const struct cpuid_dep cpuid_deps[] = {
|
||||||
{ X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F },
|
{ X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F },
|
||||||
{ X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F },
|
{ X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F },
|
||||||
{ X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL },
|
{ X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL },
|
||||||
{ X86_FEATURE_GFNI, X86_FEATURE_AVX512VL },
|
|
||||||
{ X86_FEATURE_VAES, X86_FEATURE_AVX512VL },
|
|
||||||
{ X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX512VL },
|
|
||||||
{ X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL },
|
{ X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL },
|
||||||
{ X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL },
|
{ X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL },
|
||||||
{ X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F },
|
{ X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F },
|
||||||
|
|
|
@ -382,8 +382,15 @@ SYM_FUNC_END(call_depth_return_thunk)
|
||||||
SYM_CODE_START(__x86_return_thunk)
|
SYM_CODE_START(__x86_return_thunk)
|
||||||
UNWIND_HINT_FUNC
|
UNWIND_HINT_FUNC
|
||||||
ANNOTATE_NOENDBR
|
ANNOTATE_NOENDBR
|
||||||
|
#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || \
|
||||||
|
defined(CONFIG_MITIGATION_SRSO) || \
|
||||||
|
defined(CONFIG_MITIGATION_CALL_DEPTH_TRACKING)
|
||||||
ALTERNATIVE __stringify(ANNOTATE_UNRET_SAFE; ret), \
|
ALTERNATIVE __stringify(ANNOTATE_UNRET_SAFE; ret), \
|
||||||
"jmp warn_thunk_thunk", X86_FEATURE_ALWAYS
|
"jmp warn_thunk_thunk", X86_FEATURE_ALWAYS
|
||||||
|
#else
|
||||||
|
ANNOTATE_UNRET_SAFE
|
||||||
|
ret
|
||||||
|
#endif
|
||||||
int3
|
int3
|
||||||
SYM_CODE_END(__x86_return_thunk)
|
SYM_CODE_END(__x86_return_thunk)
|
||||||
EXPORT_SYMBOL(__x86_return_thunk)
|
EXPORT_SYMBOL(__x86_return_thunk)
|
||||||
|
|
Loading…
Reference in New Issue