On 12/26/2023 3:44 PM, Zeng Guang wrote: > > On 12/18/2023 3:22 PM, Qian Wen wrote: >> From: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> >> >> Detect TDX during at start of efi setup. And define a dummy is_tdx_guest() >> if CONFIG_EFI is undefined as this function will be used globally in the >> future. >> >> In addition, it is fine to use the print function even before the #VE >> handler of the unit test has complete configuration. >> >> TDVF provides the default #VE exception handler, which will convert some >> of the forbidden instructions to TDCALL [TDG.VP.VMCALL] <INSTRUCTION>, >> e.g., IO => TDCALL [TDG.VP.VMCALL] <Instruction.IO> (see “10 Exception >> Handling” in TDVF spec [1]). >> >> [1] TDVF spec: https://cdrdv2.intel.com/v1/dl/getContent/733585 >> >> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> >> Reviewed-by: Yu Zhang <yu.c.zhang@xxxxxxxxx> >> Link: https://lore.kernel.org/r/20220303071907.650203-2-zhenzhong.duan@xxxxxxxxx >> Co-developed-by: Qian Wen <qian.wen@xxxxxxxxx> >> Signed-off-by: Qian Wen <qian.wen@xxxxxxxxx> >> --- >> lib/x86/asm/setup.h | 1 + >> lib/x86/setup.c | 6 ++++++ >> lib/x86/tdx.c | 39 +++++++++++++++++++++++++++++++++++++++ >> lib/x86/tdx.h | 9 +++++++++ >> 4 files changed, 55 insertions(+) >> >> diff --git a/lib/x86/asm/setup.h b/lib/x86/asm/setup.h >> index 458eac85..1deed1cd 100644 >> --- a/lib/x86/asm/setup.h >> +++ b/lib/x86/asm/setup.h >> @@ -15,6 +15,7 @@ unsigned long setup_tss(u8 *stacktop); >> efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo); >> void setup_5level_page_table(void); >> #endif /* CONFIG_EFI */ >> +#include "x86/tdx.h" >> void save_id(void); >> void bsp_rest_init(void); >> diff --git a/lib/x86/setup.c b/lib/x86/setup.c >> index d509a248..97d9e896 100644 >> --- a/lib/x86/setup.c >> +++ b/lib/x86/setup.c >> @@ -308,6 +308,12 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo) >> efi_status_t status; >> const char *phase; >> + status = setup_tdx(); >> + if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) { >> + printf("INTEL TDX setup failed, error = 0x%lx\n", status); >> + return status; >> + } >> + >> status = setup_memory_allocator(efi_bootinfo); >> if (status != EFI_SUCCESS) { >> printf("Failed to set up memory allocator: "); >> diff --git a/lib/x86/tdx.c b/lib/x86/tdx.c >> index 1f1abeff..a01bfcbb 100644 >> --- a/lib/x86/tdx.c >> +++ b/lib/x86/tdx.c >> @@ -276,3 +276,42 @@ static int handle_io(struct ex_regs *regs, struct ve_info *ve) >> return ve_instr_len(ve); >> } >> + >> +bool is_tdx_guest(void) >> +{ >> + static int tdx_guest = -1; >> + struct cpuid c; >> + u32 sig[3]; >> + >> + if (tdx_guest >= 0) >> + goto done; >> + >> + if (cpuid(0).a < TDX_CPUID_LEAF_ID) { >> + tdx_guest = 0; >> + goto done; >> + } >> + >> + c = cpuid(TDX_CPUID_LEAF_ID); >> + sig[0] = c.b; >> + sig[1] = c.d; >> + sig[2] = c.c; >> + >> + tdx_guest = !memcmp(TDX_IDENT, sig, sizeof(sig)); >> + >> +done: >> + return !!tdx_guest; >> +} >> + >> +efi_status_t setup_tdx(void) >> +{ >> + if (!is_tdx_guest()) >> + return EFI_UNSUPPORTED; >> + >> + /* The printf can work here. Since TDVF default exception handler > Comments need start at another new line with leading asterisk. Ooh, good catch, thanks! Thanks, Qian >> + * can handle the #VE caused by IO read/write during printf() before >> + * finalizing configuration of the unit test's #VE handler. >> + */ >> + printf("Initialized TDX.\n"); >> + >> + return EFI_SUCCESS; >> +} >> diff --git a/lib/x86/tdx.h b/lib/x86/tdx.h >> index cf0fc917..45350b70 100644 >> --- a/lib/x86/tdx.h >> +++ b/lib/x86/tdx.h >> @@ -21,6 +21,9 @@ >> #define TDX_HYPERCALL_STANDARD 0 >> +#define TDX_CPUID_LEAF_ID 0x21 >> +#define TDX_IDENT "IntelTDX " >> + >> /* TDX module Call Leaf IDs */ >> #define TDG_VP_VMCALL 0 >> @@ -136,6 +139,12 @@ struct ve_info { >> u32 instr_info; >> }; >> +bool is_tdx_guest(void); >> +efi_status_t setup_tdx(void); >> + >> +#else >> +inline bool is_tdx_guest(void) { return false; } >> + >> #endif /* CONFIG_EFI */ >> #endif /* _ASM_X86_TDX_H */ >