# --- T2-COPYRIGHT-NOTE-BEGIN --- # T2 SDE: package/*/linux/hotfix-i686-detect-nopl.patch # Copyright (C) 2024 The T2 SDE Project # # This Copyright note is generated by scripts/Create-CopyPatch, # more information can be found in the files COPYING and README. # # This patch file is dual-licensed. It is available under the license the # patched project is licensed under, as long as it is an OpenSource license # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms # of the GNU General Public License version 2 as used by the T2 SDE. # --- T2-COPYRIGHT-NOTE-END --- While removed upstream, we do not really care about decade old broken commercial virtualizers. Check for real hw and potentially use it. --- linux-6.8/arch/x86/kernel/cpu/common.c.vanilla 2024-03-26 20:38:26.748240700 +0100 +++ linux-6.8/arch/x86/kernel/cpu/common.c 2024-03-26 20:43:34.183225214 +0100 @@ -1488,16 +1488,30 @@ /* * The NOPL instruction is supposed to exist on all CPUs of family >= 6; * unfortunately, that's not true in practice because of early VIA - * chips and (more importantly) broken virtualizers that are not easy - * to detect. In the latter case it doesn't even *fail* reliably, so - * probing for it doesn't even work. Disable it completely on 32-bit - * unless we can find a reliable way to detect all the broken cases. - * Enable it explicitly on 64-bit for non-constant inputs of cpu_has(). + * chips and broken virtualizers. Instead, probe for NOPL directly by + * executing a NOPL instruction and see if we get #UD. */ static void detect_nopl(void) { #ifdef CONFIG_X86_32 - setup_clear_cpu_cap(X86_FEATURE_NOPL); + const u32 nopl_signature = 0x888c53b1; /* Random number */ + u32 has_nopl = nopl_signature; + + setup_clear_cpu_cap(X86_FEATURE_NOPL); + if (boot_cpu_data.x86 >= 6) { + asm volatile("\n" + "1: .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */ + "2:\n" + " .section .fixup,\"ax\"\n" + "3: xor %0,%0\n" + " jmp 2b\n" + " .previous\n" + _ASM_EXTABLE(1b,3b) + : "+a" (has_nopl)); + + if (has_nopl == nopl_signature) + setup_force_cpu_cap(X86_FEATURE_NOPL); + } #else setup_force_cpu_cap(X86_FEATURE_NOPL); #endif