]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.6/x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch
b53d7ad5c8245ca2a824f3397738ad8777f84388
[thirdparty/kernel/stable-queue.git] / queue-6.6 / x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch
1 From cd0d9d92c8bb46e77de62efd7df13069ddd61e7d Mon Sep 17 00:00:00 2001
2 From: Ard Biesheuvel <ardb@kernel.org>
3 Date: Tue, 27 Feb 2024 16:19:14 +0100
4 Subject: x86/boot: Move mem_encrypt= parsing to the decompressor
5
6 From: Ard Biesheuvel <ardb@kernel.org>
7
8 commit cd0d9d92c8bb46e77de62efd7df13069ddd61e7d upstream.
9
10 The early SME/SEV code parses the command line very early, in order to
11 decide whether or not memory encryption should be enabled, which needs
12 to occur even before the initial page tables are created.
13
14 This is problematic for a number of reasons:
15 - this early code runs from the 1:1 mapping provided by the decompressor
16 or firmware, which uses a different translation than the one assumed by
17 the linker, and so the code needs to be built in a special way;
18 - parsing external input while the entire kernel image is still mapped
19 writable is a bad idea in general, and really does not belong in
20 security minded code;
21 - the current code ignores the built-in command line entirely (although
22 this appears to be the case for the entire decompressor)
23
24 Given that the decompressor/EFI stub is an intrinsic part of the x86
25 bootable kernel image, move the command line parsing there and out of
26 the core kernel. This removes the need to build lib/cmdline.o in a
27 special way, or to use RIP-relative LEA instructions in inline asm
28 blocks.
29
30 This involves a new xloadflag in the setup header to indicate
31 that mem_encrypt=on appeared on the kernel command line.
32
33 Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
34 Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
35 Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
36 Link: https://lore.kernel.org/r/20240227151907.387873-17-ardb+git@google.com
37 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38 ---
39 arch/x86/boot/compressed/misc.c | 15 +++++++++++++++
40 arch/x86/include/uapi/asm/bootparam.h | 1 +
41 arch/x86/lib/Makefile | 13 -------------
42 arch/x86/mm/mem_encrypt_identity.c | 32 +++-----------------------------
43 drivers/firmware/efi/libstub/x86-stub.c | 3 +++
44 5 files changed, 22 insertions(+), 42 deletions(-)
45
46 --- a/arch/x86/boot/compressed/misc.c
47 +++ b/arch/x86/boot/compressed/misc.c
48 @@ -359,6 +359,19 @@ unsigned long decompress_kernel(unsigned
49 }
50
51 /*
52 + * Set the memory encryption xloadflag based on the mem_encrypt= command line
53 + * parameter, if provided.
54 + */
55 +static void parse_mem_encrypt(struct setup_header *hdr)
56 +{
57 + int on = cmdline_find_option_bool("mem_encrypt=on");
58 + int off = cmdline_find_option_bool("mem_encrypt=off");
59 +
60 + if (on > off)
61 + hdr->xloadflags |= XLF_MEM_ENCRYPTION;
62 +}
63 +
64 +/*
65 * The compressed kernel image (ZO), has been moved so that its position
66 * is against the end of the buffer used to hold the uncompressed kernel
67 * image (VO) and the execution environment (.bss, .brk), which makes sure
68 @@ -388,6 +401,8 @@ asmlinkage __visible void *extract_kerne
69 /* Clear flags intended for solely in-kernel use. */
70 boot_params->hdr.loadflags &= ~KASLR_FLAG;
71
72 + parse_mem_encrypt(&boot_params->hdr);
73 +
74 sanitize_boot_params(boot_params);
75
76 if (boot_params->screen_info.orig_video_mode == 7) {
77 --- a/arch/x86/include/uapi/asm/bootparam.h
78 +++ b/arch/x86/include/uapi/asm/bootparam.h
79 @@ -38,6 +38,7 @@
80 #define XLF_EFI_KEXEC (1<<4)
81 #define XLF_5LEVEL (1<<5)
82 #define XLF_5LEVEL_ENABLED (1<<6)
83 +#define XLF_MEM_ENCRYPTION (1<<7)
84
85 #ifndef __ASSEMBLY__
86
87 --- a/arch/x86/lib/Makefile
88 +++ b/arch/x86/lib/Makefile
89 @@ -14,19 +14,6 @@ ifdef CONFIG_KCSAN
90 CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE)
91 endif
92
93 -# Early boot use of cmdline; don't instrument it
94 -ifdef CONFIG_AMD_MEM_ENCRYPT
95 -KCOV_INSTRUMENT_cmdline.o := n
96 -KASAN_SANITIZE_cmdline.o := n
97 -KCSAN_SANITIZE_cmdline.o := n
98 -
99 -ifdef CONFIG_FUNCTION_TRACER
100 -CFLAGS_REMOVE_cmdline.o = -pg
101 -endif
102 -
103 -CFLAGS_cmdline.o := -fno-stack-protector -fno-jump-tables
104 -endif
105 -
106 inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
107 inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
108 quiet_cmd_inat_tables = GEN $@
109 --- a/arch/x86/mm/mem_encrypt_identity.c
110 +++ b/arch/x86/mm/mem_encrypt_identity.c
111 @@ -44,7 +44,6 @@
112 #include <asm/init.h>
113 #include <asm/setup.h>
114 #include <asm/sections.h>
115 -#include <asm/cmdline.h>
116 #include <asm/coco.h>
117 #include <asm/sev.h>
118
119 @@ -96,9 +95,6 @@ struct sme_populate_pgd_data {
120 */
121 static char sme_workarea[2 * PMD_SIZE] __section(".init.scratch");
122
123 -static char sme_cmdline_arg[] __initdata = "mem_encrypt";
124 -static char sme_cmdline_on[] __initdata = "on";
125 -
126 static void __head sme_clear_pgd(struct sme_populate_pgd_data *ppd)
127 {
128 unsigned long pgd_start, pgd_end, pgd_size;
129 @@ -496,11 +492,9 @@ void __head sme_encrypt_kernel(struct bo
130
131 void __head sme_enable(struct boot_params *bp)
132 {
133 - const char *cmdline_ptr, *cmdline_arg, *cmdline_on;
134 unsigned int eax, ebx, ecx, edx;
135 unsigned long feature_mask;
136 unsigned long me_mask;
137 - char buffer[16];
138 bool snp;
139 u64 msr;
140
141 @@ -543,6 +537,9 @@ void __head sme_enable(struct boot_param
142
143 /* Check if memory encryption is enabled */
144 if (feature_mask == AMD_SME_BIT) {
145 + if (!(bp->hdr.xloadflags & XLF_MEM_ENCRYPTION))
146 + return;
147 +
148 /*
149 * No SME if Hypervisor bit is set. This check is here to
150 * prevent a guest from trying to enable SME. For running as a
151 @@ -562,31 +559,8 @@ void __head sme_enable(struct boot_param
152 msr = __rdmsr(MSR_AMD64_SYSCFG);
153 if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT))
154 return;
155 - } else {
156 - /* SEV state cannot be controlled by a command line option */
157 - goto out;
158 }
159
160 - /*
161 - * Fixups have not been applied to phys_base yet and we're running
162 - * identity mapped, so we must obtain the address to the SME command
163 - * line argument data using rip-relative addressing.
164 - */
165 - asm ("lea sme_cmdline_arg(%%rip), %0"
166 - : "=r" (cmdline_arg)
167 - : "p" (sme_cmdline_arg));
168 - asm ("lea sme_cmdline_on(%%rip), %0"
169 - : "=r" (cmdline_on)
170 - : "p" (sme_cmdline_on));
171 -
172 - cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
173 - ((u64)bp->ext_cmd_line_ptr << 32));
174 -
175 - if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0 ||
176 - strncmp(buffer, cmdline_on, sizeof(buffer)))
177 - return;
178 -
179 -out:
180 RIP_REL_REF(sme_me_mask) = me_mask;
181 physical_mask &= ~me_mask;
182 cc_vendor = CC_VENDOR_AMD;
183 --- a/drivers/firmware/efi/libstub/x86-stub.c
184 +++ b/drivers/firmware/efi/libstub/x86-stub.c
185 @@ -897,6 +897,9 @@ void __noreturn efi_stub_entry(efi_handl
186 }
187 }
188
189 + if (efi_mem_encrypt > 0)
190 + hdr->xloadflags |= XLF_MEM_ENCRYPTION;
191 +
192 status = efi_decompress_kernel(&kernel_entry);
193 if (status != EFI_SUCCESS) {
194 efi_err("Failed to decompress kernel\n");