Skip to content

Commit 4b05f81

Browse files
Kuppuswamy Sathyanarayananhansendc
Kuppuswamy Sathyanarayanan
authored andcommittedApr 7, 2022
x86/tdx: Detect TDX at early kernel decompression time
The early decompression code does port I/O for its console output. But, handling the decompression-time port I/O demands a different approach from normal runtime because the IDT required to support #VE based port I/O emulation is not yet set up. Paravirtualizing I/O calls during the decompression step is acceptable because the decompression code doesn't have a lot of call sites to IO instruction. To support port I/O in decompression code, TDX must be detected before the decompression code might do port I/O. Detect whether the kernel runs in a TDX guest. Add an early_is_tdx_guest() interface to query the cached TDX guest status in the decompression code. TDX is detected with CPUID. Make cpuid_count() accessible outside boot/cpuflags.c. TDX detection in the main kernel is very similar. Move common bits into <asm/shared/tdx.h>. The actual port I/O paravirtualization will come later in the series. Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Tony Luck <tony.luck@intel.com> Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://lkml.kernel.org/r/20220405232939.73860-13-kirill.shutemov@linux.intel.com
1 parent 31d58c4 commit 4b05f81

File tree

9 files changed

+51
-5
lines changed

9 files changed

+51
-5
lines changed
 

‎arch/x86/boot/compressed/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ ifdef CONFIG_X86_64
101101
endif
102102

103103
vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o
104+
vmlinux-objs-$(CONFIG_INTEL_TDX_GUEST) += $(obj)/tdx.o
104105

105106
vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o
106107
efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a

‎arch/x86/boot/compressed/misc.c

+8
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,14 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
371371
lines = boot_params->screen_info.orig_video_lines;
372372
cols = boot_params->screen_info.orig_video_cols;
373373

374+
/*
375+
* Detect TDX guest environment.
376+
*
377+
* It has to be done before console_init() in order to use
378+
* paravirtualized port I/O operations if needed.
379+
*/
380+
early_tdx_detect();
381+
374382
console_init();
375383

376384
/*

‎arch/x86/boot/compressed/misc.h

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <asm/bootparam.h>
2929
#include <asm/desc_defs.h>
3030

31+
#include "tdx.h"
32+
3133
#define BOOT_CTYPE_H
3234
#include <linux/acpi.h>
3335

‎arch/x86/boot/compressed/tdx.c

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include "../cpuflags.h"
4+
#include "../string.h"
5+
6+
#include <asm/shared/tdx.h>
7+
8+
void early_tdx_detect(void)
9+
{
10+
u32 eax, sig[3];
11+
12+
cpuid_count(TDX_CPUID_LEAF_ID, 0, &eax, &sig[0], &sig[2], &sig[1]);
13+
14+
if (memcmp(TDX_IDENT, sig, sizeof(sig)))
15+
return;
16+
}

‎arch/x86/boot/compressed/tdx.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef BOOT_COMPRESSED_TDX_H
3+
#define BOOT_COMPRESSED_TDX_H
4+
5+
#include <linux/types.h>
6+
7+
#ifdef CONFIG_INTEL_TDX_GUEST
8+
void early_tdx_detect(void);
9+
#else
10+
static inline void early_tdx_detect(void) { };
11+
#endif
12+
13+
#endif /* BOOT_COMPRESSED_TDX_H */

‎arch/x86/boot/cpuflags.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ int has_eflag(unsigned long mask)
7171
# define EBX_REG "=b"
7272
#endif
7373

74-
static inline void cpuid_count(u32 id, u32 count,
75-
u32 *a, u32 *b, u32 *c, u32 *d)
74+
void cpuid_count(u32 id, u32 count, u32 *a, u32 *b, u32 *c, u32 *d)
7675
{
7776
asm volatile(".ifnc %%ebx,%3 ; movl %%ebx,%3 ; .endif \n\t"
7877
"cpuid \n\t"

‎arch/x86/boot/cpuflags.h

+1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ extern u32 cpu_vendor[3];
1717

1818
int has_eflag(unsigned long mask);
1919
void get_cpuflags(void);
20+
void cpuid_count(u32 id, u32 count, u32 *a, u32 *b, u32 *c, u32 *d);
2021

2122
#endif

‎arch/x86/include/asm/shared/tdx.h

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _ASM_X86_SHARED_TDX_H
3+
#define _ASM_X86_SHARED_TDX_H
4+
5+
#define TDX_CPUID_LEAF_ID 0x21
6+
#define TDX_IDENT "IntelTDX "
7+
8+
#endif /* _ASM_X86_SHARED_TDX_H */

‎arch/x86/include/asm/tdx.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
#include <linux/init.h>
88
#include <linux/bits.h>
99
#include <asm/ptrace.h>
10-
11-
#define TDX_CPUID_LEAF_ID 0x21
12-
#define TDX_IDENT "IntelTDX "
10+
#include <asm/shared/tdx.h>
1311

1412
#define TDX_HYPERCALL_STANDARD 0
1513

0 commit comments

Comments
 (0)
Please sign in to comment.