]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - queue-4.19/x86-apic-force-native_apic_mem_read-to-use-the-mov-instruction.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.19 / x86-apic-force-native_apic_mem_read-to-use-the-mov-instruction.patch
CommitLineData
7a3a66c7
GKH
1From 5ce344beaca688f4cdea07045e0b8f03dc537e74 Mon Sep 17 00:00:00 2001
2From: Adam Dunlap <acdunlap@google.com>
3Date: Mon, 18 Mar 2024 16:09:27 -0700
4Subject: x86/apic: Force native_apic_mem_read() to use the MOV instruction
5
6From: Adam Dunlap <acdunlap@google.com>
7
8commit 5ce344beaca688f4cdea07045e0b8f03dc537e74 upstream.
9
10When done from a virtual machine, instructions that touch APIC memory
11must be emulated. By convention, MMIO accesses are typically performed
12via io.h helpers such as readl() or writeq() to simplify instruction
13emulation/decoding (ex: in KVM hosts and SEV guests) [0].
14
15Currently, native_apic_mem_read() does not follow this convention,
16allowing the compiler to emit instructions other than the MOV
17instruction generated by readl(). In particular, when the kernel is
18compiled with clang and run as a SEV-ES or SEV-SNP guest, the compiler
19would emit a TESTL instruction which is not supported by the SEV-ES
20emulator, causing a boot failure in that environment. It is likely the
21same problem would happen in a TDX guest as that uses the same
22instruction emulator as SEV-ES.
23
24To make sure all emulators can emulate APIC memory reads via MOV, use
25the readl() function in native_apic_mem_read(). It is expected that any
26emulator would support MOV in any addressing mode as it is the most
27generic and is what is usually emitted currently.
28
29The TESTL instruction is emitted when native_apic_mem_read() is inlined
30into apic_mem_wait_icr_idle(). The emulator comes from
31insn_decode_mmio() in arch/x86/lib/insn-eval.c. It's not worth it to
32extend insn_decode_mmio() to support more instructions since, in theory,
33the compiler could choose to output nearly any instruction for such
34reads which would bloat the emulator beyond reason.
35
36 [0] https://lore.kernel.org/all/20220405232939.73860-12-kirill.shutemov@linux.intel.com/
37
38 [ bp: Massage commit message, fix typos. ]
39
40Signed-off-by: Adam Dunlap <acdunlap@google.com>
41Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
42Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
43Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
44Tested-by: Kevin Loughlin <kevinloughlin@google.com>
45Cc: <stable@vger.kernel.org>
46Link: https://lore.kernel.org/r/20240318230927.2191933-1-acdunlap@google.com
47Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48---
49 arch/x86/include/asm/apic.h | 3 ++-
50 1 file changed, 2 insertions(+), 1 deletion(-)
51
52--- a/arch/x86/include/asm/apic.h
53+++ b/arch/x86/include/asm/apic.h
54@@ -11,6 +11,7 @@
55 #include <asm/mpspec.h>
56 #include <asm/msr.h>
57 #include <asm/hardirq.h>
58+#include <asm/io.h>
59
60 #define ARCH_APICTIMER_STOPS_ON_C3 1
61
62@@ -110,7 +111,7 @@ static inline void native_apic_mem_write
63
64 static inline u32 native_apic_mem_read(u32 reg)
65 {
66- return *((volatile u32 *)(APIC_BASE + reg));
67+ return readl((void __iomem *)(APIC_BASE + reg));
68 }
69
70 extern void native_apic_wait_icr_idle(void);