From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6DF48246786 for ; Thu, 21 Aug 2025 01:44:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755740666; cv=none; b=crhK7m+wE2D4XYLPJn7lfearTR5lBVDPIKka0yz8w7jpPgQoDGcE58aPJoOVY5RmbzCMQW6qaCO9Hi/CeIAfl4cjc+gz0iLpkTlj095BG3EusFD3qIqp0Xnb1zlMQQAk4BMOmu2dVJgKGkUCeeeym6qWnub9Kjp7g7X9WWR5lf4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755740666; c=relaxed/simple; bh=pLQg269TfdCVaD9lGtWIua8jPvdmfueDTx/b93nQE2Q=; h=Date:From:To:CC:Subject:In-Reply-To:References:Message-ID: MIME-Version:Content-Type; b=WKwt9wzJL3ulismG4//5G+ldS2Bqqp85ipWBwEZDQ6ABlMpXg0weWwHYJWHhIKTlfPoPoLsxLUXGyA13ccXf5GwmsXnL7csQ+1ZIwflK+qz5LBBc8Z980t70SigeA8KSjPLrnLkBItHGkGclMCUYL8m+sBaBPIQeZQUM5c6Qtpg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=KDFEDnU6; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="KDFEDnU6" Received: from [127.0.0.1] (c-76-133-66-138.hsd1.ca.comcast.net [76.133.66.138]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 57L1hcn3019985 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NO); Wed, 20 Aug 2025 18:43:39 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 57L1hcn3019985 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1755740620; bh=6R6baGc7vDkaqNJuT5B7LJhMdkDSAFTZII1u9c00wH8=; h=Date:From:To:CC:Subject:In-Reply-To:References:From; b=KDFEDnU60Y1Ba/jQD+Y5a0Gsv0MS8i0uNJwjv9NaQsIxa/jQP6iUbtBmx4y6kT2HX LkZyxkIoV+KSaN6s3+NJWr6FCw0RWt8FowuLZrX0+O0jQlmyUbf7vGOMaMwcVoRUAx nW2N66I8De0kaeUYlU+CinR7owdVzDVTQRdSnuSm/1r6jEZiQFUOsaZC5QjveauA/6 fsNH7dKiRqUm/deAQf5r9YlujOUInzzHsBsW+UvbH7s47abX4jdAEqg93NjoChSpsj ThFloSgaS7n/I00myQjtdWm1rPFI3Kn6ld92/+IUhwpVhTldjWX/TGo4DOK65VPOV/ 3Yv+ClVC4kMvA== Date: Wed, 20 Aug 2025 18:43:35 -0700 From: "H. Peter Anvin" To: Marcos Del Sol Vives , linux-kernel@vger.kernel.org CC: marcos@orca.pet, Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Brian Gerst , Uros Bizjak , Ard Biesheuvel , David Kaplan , "Ahmed S. Darwish" , Kees Cook , "Peter Zijlstra (Intel)" , Andrew Cooper , Oleg Nesterov , "Xin Li (Intel)" , Sabyrzhan Tasbolatov Subject: Re: [PATCH] x86: add hintable NOPs emulation User-Agent: K-9 Mail for Android In-Reply-To: <20250820013452.495481-1-marcos@orca.pet> References: <20250820013452.495481-1-marcos@orca.pet> Message-ID: <08A1B314-C015-4EE9-A13D-3D712FD274C4@zytor.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On August 19, 2025 6:34:46 PM PDT, Marcos Del Sol Vives = wrote: >Hintable NOPs are a series of instructions introduced by Intel with the >Pentium Pro (i686), and described in US patent US5701442A=2E > >These instructions were reserved to allow backwards-compatible changes >in the instruction set possible, by having old processors treat them as >variable-length NOPs, while having other semantics in modern processors= =2E > >Some modern uses are: > - Multi-byte/long NOPs > - Indirect Branch Tracking (ENDBR32) > - Shadow Stack (part of CET) > >Some processors advertising i686 compatibility lack full support for >them, which may cause #UD to be incorrectly triggered, crashing software >that uses then with an unexpected SIGILL=2E > >One such software is sudo in Debian bookworm, which is compiled with >GCC -fcf-protection=3Dbranch and contains ENDBR32 instructions=2E It cras= hes >on my Vortex86DX3 processor and VIA C3 Nehalem processors [1]=2E > >This patch is a much simplified version of my previous patch for x86 >instruction emulation [2], that only emulates hintable NOPs=2E > >When #UD is raised, it checks if the opcode corresponds to a hintable NOP >in user space=2E If true, it warns the user via the dmesg and advances th= e >instruction pointer, thus emulating its expected NOP behaviour=2E > >[1]: https://lists=2Edebian=2Eorg/debian-devel/2023/10/msg00118=2Ehtml >[2]: https://lore=2Ekernel=2Eorg/all/20210626130313=2E1283485-1-marcos@or= ca=2Epet/ > >Signed-off-by: Marcos Del Sol Vives >--- > arch/x86/Kconfig | 29 +++++++++++++++++++++++++ > arch/x86/include/asm/processor=2Eh | 4 ++++ > arch/x86/kernel/process=2Ec | 3 +++ > arch/x86/kernel/traps=2Ec | 36 ++++++++++++++++++++++++++++++++ > 4 files changed, 72 insertions(+) > >diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig >index 58d890fe2100=2E=2Ea6daebdc2573 100644 >--- a/arch/x86/Kconfig >+++ b/arch/x86/Kconfig >@@ -1286,6 +1286,35 @@ config X86_IOPL_IOPERM > ability to disable interrupts from user space which would be > granted if the hardware IOPL mechanism would be used=2E >=20 >+config X86_HNOP_EMU >+ bool "Hintable NOPs emulation" >+ depends on X86_32 >+ default y >+ help >+ Hintable NOPs are a series of instructions introduced by Intel with >+ the Pentium Pro (i686), and described in US patent US5701442A=2E >+ >+ These instructions were reserved to allow backwards-compatible >+ changes in the instruction set possible, by having old processors >+ treat them as variable-length NOPs, while having other semantics in >+ modern processors=2E >+ >+ Some modern uses are: >+ - Multi-byte/long NOPs >+ - Indirect Branch Tracking (ENDBR32) >+ - Shadow Stack (part of CET) >+ >+ Some processors advertising i686 compatibility (such as Cyrix MII, >+ VIA C3 Nehalem or DM&P Vortex86DX3) lack full support for them, >+ which may cause SIGILL to be incorrectly raised in user space when >+ a hintable NOP is encountered=2E >+ >+ Say Y here if you want the kernel to emulate them, allowing programs >+ that make use of them to run transparently on such processors=2E >+ >+ This emulation has no performance penalty for processors that >+ properly support them, so if unsure, enable it=2E >+ > config TOSHIBA > tristate "Toshiba Laptop support" > depends on X86_32 >diff --git a/arch/x86/include/asm/processor=2Eh b/arch/x86/include/asm/pr= ocessor=2Eh >index bde58f6510ac=2E=2Ec34fb678c4de 100644 >--- a/arch/x86/include/asm/processor=2Eh >+++ b/arch/x86/include/asm/processor=2Eh >@@ -499,6 +499,10 @@ struct thread_struct { >=20 > unsigned int iopl_warn:1; >=20 >+#ifdef CONFIG_X86_HNOP_EMU >+ unsigned int hnop_warn:1; >+#endif >+ > /* > * Protection Keys Register for Userspace=2E Loaded immediately on > * context switch=2E Store it in thread_struct to avoid a lookup in >diff --git a/arch/x86/kernel/process=2Ec b/arch/x86/kernel/process=2Ec >index 1b7960cf6eb0=2E=2E6ec8021638d0 100644 >--- a/arch/x86/kernel/process=2Ec >+++ b/arch/x86/kernel/process=2Ec >@@ -178,6 +178,9 @@ int copy_thread(struct task_struct *p, const struct k= ernel_clone_args *args) > p->thread=2Eio_bitmap =3D NULL; > clear_tsk_thread_flag(p, TIF_IO_BITMAP); > p->thread=2Eiopl_warn =3D 0; >+#ifdef CONFIG_X86_HNOP_EMU >+ p->thread=2Ehnop_warn =3D 0; >+#endif > memset(p->thread=2Eptrace_bps, 0, sizeof(p->thread=2Eptrace_bps)); >=20 > #ifdef CONFIG_X86_64 >diff --git a/arch/x86/kernel/traps=2Ec b/arch/x86/kernel/traps=2Ec >index 36354b470590=2E=2E2dcb7d7edf8a 100644 >--- a/arch/x86/kernel/traps=2Ec >+++ b/arch/x86/kernel/traps=2Ec >@@ -295,12 +295,48 @@ DEFINE_IDTENTRY(exc_overflow) > do_error_trap(regs, 0, "overflow", X86_TRAP_OF, SIGSEGV, 0, NULL); > } >=20 >+#ifdef CONFIG_X86_HNOP_EMU >+static bool handle_hnop(struct pt_regs *regs) >+{ >+ struct thread_struct *t =3D ¤t->thread; >+ unsigned char buf[MAX_INSN_SIZE]; >+ unsigned long nr_copied; >+ struct insn insn; >+ >+ nr_copied =3D insn_fetch_from_user(regs, buf); >+ if (nr_copied <=3D 0) >+ return false; >+ >+ if (!insn_decode_from_regs(&insn, regs, buf, nr_copied)) >+ return false; >+ >+ /* Hintable NOPs cover 0F 18 to 0F 1F */ >+ if (insn=2Eopcode=2Ebytes[0] !=3D 0x0F || >+ insn=2Eopcode=2Ebytes[1] < 0x18 || insn=2Eopcode=2Ebytes[1] > 0x1F) >+ return false; >+ >+ if (!t->hnop_warn) { >+ pr_warn_ratelimited("%s[%d] emulating hintable NOP, ip:%lx\n", >+ current->comm, task_pid_nr(current), regs->ip); >+ t->hnop_warn =3D 1; >+ } >+ >+ regs->ip +=3D insn=2Elength; >+ return true; >+} >+#endif >+ > #ifdef CONFIG_X86_F00F_BUG > void handle_invalid_op(struct pt_regs *regs) > #else > static inline void handle_invalid_op(struct pt_regs *regs) > #endif > { >+#ifdef CONFIG_X86_HNOP_EMU >+ if (user_mode(regs) && handle_hnop(regs)) >+ return; >+#endif >+ > do_error_trap(regs, 0, "invalid opcode", X86_TRAP_UD, SIGILL, > ILL_ILLOPN, error_get_trap_addr(regs)); > } Do those processors support FCOMI?