Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/sev: Move instruction decoder into separate source file

As a first step towards disentangling the SEV #VC handling code -which
is shared between the decompressor and the core kernel- from the SEV
startup code, move the decompressor's copy of the instruction decoder
into a separate source file.

Code movement only - no functional change intended.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: David Woodhouse <dwmw@amazon.co.uk>
Cc: Dionna Amalie Glaze <dionnaglaze@google.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Kevin Loughlin <kevinloughlin@google.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: linux-efi@vger.kernel.org
Link: https://lore.kernel.org/r/20250504095230.2932860-30-ardb+git@google.com

authored by

Ard Biesheuvel and committed by
Ingo Molnar
ae862964 fae89bbf

+62 -41
+3 -3
arch/x86/boot/compressed/Makefile
··· 44 44 KBUILD_CFLAGS += $(call cc-option,-Wa$(comma)-mrelax-relocations=no) 45 45 KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h 46 46 47 - # sev.c indirectly includes inat-table.h which is generated during 47 + # sev-decode-insn.c indirectly includes inat-table.c which is generated during 48 48 # compilation and stored in $(objtree). Add the directory to the includes so 49 49 # that the compiler finds it even with out-of-tree builds (make O=/some/path). 50 - CFLAGS_sev.o += -I$(objtree)/arch/x86/lib/ 50 + CFLAGS_sev-handle-vc.o += -I$(objtree)/arch/x86/lib/ 51 51 52 52 KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ 53 53 ··· 96 96 vmlinux-objs-y += $(obj)/idt_64.o $(obj)/idt_handlers_64.o 97 97 vmlinux-objs-$(CONFIG_AMD_MEM_ENCRYPT) += $(obj)/mem_encrypt.o 98 98 vmlinux-objs-y += $(obj)/pgtable_64.o 99 - vmlinux-objs-$(CONFIG_AMD_MEM_ENCRYPT) += $(obj)/sev.o 99 + vmlinux-objs-$(CONFIG_AMD_MEM_ENCRYPT) += $(obj)/sev.o $(obj)/sev-handle-vc.o 100 100 endif 101 101 102 102 vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o
+7
arch/x86/boot/compressed/misc.h
··· 136 136 #endif 137 137 138 138 #ifdef CONFIG_AMD_MEM_ENCRYPT 139 + struct es_em_ctxt; 140 + struct insn; 141 + 139 142 void sev_enable(struct boot_params *bp); 140 143 void snp_check_features(void); 141 144 void sev_es_shutdown_ghcb(void); ··· 146 143 void snp_set_page_private(unsigned long paddr); 147 144 void snp_set_page_shared(unsigned long paddr); 148 145 void sev_prep_identity_maps(unsigned long top_level_pgt); 146 + 147 + enum es_result vc_decode_insn(struct es_em_ctxt *ctxt); 148 + bool insn_has_rep_prefix(struct insn *insn); 149 + void sev_insn_decode_init(void); 149 150 #else 150 151 static inline void sev_enable(struct boot_params *bp) 151 152 {
+51
arch/x86/boot/compressed/sev-handle-vc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "misc.h" 4 + 5 + #include <linux/kernel.h> 6 + #include <linux/string.h> 7 + #include <asm/insn.h> 8 + #include <asm/pgtable_types.h> 9 + #include <asm/ptrace.h> 10 + #include <asm/sev.h> 11 + 12 + #define __BOOT_COMPRESSED 13 + 14 + /* Basic instruction decoding support needed */ 15 + #include "../../lib/inat.c" 16 + #include "../../lib/insn.c" 17 + 18 + /* 19 + * Copy a version of this function here - insn-eval.c can't be used in 20 + * pre-decompression code. 21 + */ 22 + bool insn_has_rep_prefix(struct insn *insn) 23 + { 24 + insn_byte_t p; 25 + int i; 26 + 27 + insn_get_prefixes(insn); 28 + 29 + for_each_insn_prefix(insn, i, p) { 30 + if (p == 0xf2 || p == 0xf3) 31 + return true; 32 + } 33 + 34 + return false; 35 + } 36 + 37 + enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) 38 + { 39 + char buffer[MAX_INSN_SIZE]; 40 + int ret; 41 + 42 + memcpy(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE); 43 + 44 + ret = insn_decode(&ctxt->insn, buffer, MAX_INSN_SIZE, INSN_MODE_64); 45 + if (ret < 0) 46 + return ES_DECODE_FAILED; 47 + 48 + return ES_OK; 49 + } 50 + 51 + extern void sev_insn_decode_init(void) __alias(inat_init_tables);
+1 -38
arch/x86/boot/compressed/sev.c
··· 30 30 struct ghcb *boot_ghcb; 31 31 32 32 /* 33 - * Copy a version of this function here - insn-eval.c can't be used in 34 - * pre-decompression code. 35 - */ 36 - static bool insn_has_rep_prefix(struct insn *insn) 37 - { 38 - insn_byte_t p; 39 - int i; 40 - 41 - insn_get_prefixes(insn); 42 - 43 - for_each_insn_prefix(insn, i, p) { 44 - if (p == 0xf2 || p == 0xf3) 45 - return true; 46 - } 47 - 48 - return false; 49 - } 50 - 51 - /* 52 33 * Only a dummy for insn_get_seg_base() - Early boot-code is 64bit only and 53 34 * doesn't use segments. 54 35 */ ··· 53 72 54 73 m.q = val; 55 74 boot_wrmsr(MSR_AMD64_SEV_ES_GHCB, &m); 56 - } 57 - 58 - static enum es_result vc_decode_insn(struct es_em_ctxt *ctxt) 59 - { 60 - char buffer[MAX_INSN_SIZE]; 61 - int ret; 62 - 63 - memcpy(buffer, (unsigned char *)ctxt->regs->ip, MAX_INSN_SIZE); 64 - 65 - ret = insn_decode(&ctxt->insn, buffer, MAX_INSN_SIZE, INSN_MODE_64); 66 - if (ret < 0) 67 - return ES_DECODE_FAILED; 68 - 69 - return ES_OK; 70 75 } 71 76 72 77 static enum es_result vc_write_mem(struct es_em_ctxt *ctxt, ··· 88 121 #define __head 89 122 90 123 #define __BOOT_COMPRESSED 91 - 92 - /* Basic instruction decoding support needed */ 93 - #include "../../lib/inat.c" 94 - #include "../../lib/insn.c" 95 124 96 125 extern struct svsm_ca *boot_svsm_caa; 97 126 extern u64 boot_svsm_caa_pa; ··· 193 230 boot_ghcb = &boot_ghcb_page; 194 231 195 232 /* Initialize lookup tables for the instruction decoder */ 196 - inat_init_tables(); 233 + sev_insn_decode_init(); 197 234 198 235 /* SNP guest requires the GHCB GPA must be registered */ 199 236 if (sev_snp_enabled())