Skip to content

Commit 6f5c71c

Browse files
kaihuanghansendc
authored andcommitted
x86/virt/tdx: Require the module to assert it has the NO_RBP_MOD mitigation
Old TDX modules can clobber RBP in the TDH.VP.ENTER SEAMCALL. However RBP is used as frame pointer in the x86_64 calling convention, and clobbering RBP could result in bad things like being unable to unwind the stack if any non-maskable exceptions (NMI, #MC etc) happens in that gap. A new "NO_RBP_MOD" feature was introduced to more recent TDX modules to not clobber RBP. KVM will need to use the TDH.VP.ENTER SEAMCALL to run TDX guests. It won't be safe to run TDX guests w/o this feature. To prevent it, just don't initialize the TDX module if this feature is not supported [1]. Note the bit definitions of TDX_FEATURES0 are not auto-generated in tdx_global_metadata.h. Manually define a macro for it in "tdx.h". Signed-off-by: Kai Huang <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Nikolay Borisov <[email protected]> Reviewed-by: Adrian Hunter <[email protected]> Reviewed-by: Dan Williams <[email protected]> Link: https://lore.kernel.org/[email protected]/ [1] Link: https://lore.kernel.org/all/76ae5025502c84d799e3a56a6fc4f69a82da8f93.1734188033.git.kai.huang%40intel.com
1 parent fae43b2 commit 6f5c71c

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

arch/x86/virt/vmx/tdx/tdx.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,18 @@ static int read_sys_metadata_field(u64 field_id, u64 *data)
272272

273273
#include "tdx_global_metadata.c"
274274

275+
static int check_features(struct tdx_sys_info *sysinfo)
276+
{
277+
u64 tdx_features0 = sysinfo->features.tdx_features0;
278+
279+
if (!(tdx_features0 & TDX_FEATURES0_NO_RBP_MOD)) {
280+
pr_err("frame pointer (RBP) clobber bug present, upgrade TDX module\n");
281+
return -EINVAL;
282+
}
283+
284+
return 0;
285+
}
286+
275287
/* Calculate the actual TDMR size */
276288
static int tdmr_size_single(u16 max_reserved_per_tdmr)
277289
{
@@ -1055,6 +1067,11 @@ static int init_tdx_module(void)
10551067
if (ret)
10561068
return ret;
10571069

1070+
/* Check whether the kernel can support this module */
1071+
ret = check_features(&sysinfo);
1072+
if (ret)
1073+
return ret;
1074+
10581075
/*
10591076
* To keep things simple, assume that all TDX-protected memory
10601077
* will come from the page allocator. Make sure all pages in the

arch/x86/virt/vmx/tdx/tdx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef _X86_VIRT_TDX_H
33
#define _X86_VIRT_TDX_H
44

5+
#include <linux/bits.h>
56
#include "tdx_global_metadata.h"
67

78
/*
@@ -51,6 +52,9 @@ struct tdmr_info {
5152
DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas);
5253
} __packed __aligned(TDMR_INFO_ALIGNMENT);
5354

55+
/* Bit definitions of TDX_FEATURES0 metadata field */
56+
#define TDX_FEATURES0_NO_RBP_MOD BIT(18)
57+
5458
/*
5559
* Do not put any hardware-defined TDX structure representations below
5660
* this comment!

0 commit comments

Comments
 (0)