Files
linux/arch/x86/virt/vmx/tdx/tdx.h
Kai Huang 6f5c71cc42 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 <kai.huang@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/fc0e8ab7-86d4-4428-be31-82e1ece6dd21@intel.com/ [1]
Link: https://lore.kernel.org/all/76ae5025502c84d799e3a56a6fc4f69a82da8f93.1734188033.git.kai.huang%40intel.com
2024-12-18 14:36:02 -08:00

90 lines
2.1 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _X86_VIRT_TDX_H
#define _X86_VIRT_TDX_H
#include <linux/bits.h>
#include "tdx_global_metadata.h"
/*
* This file contains both macros and data structures defined by the TDX
* architecture and Linux defined software data structures and functions.
* The two should not be mixed together for better readability. The
* architectural definitions come first.
*/
/*
* TDX module SEAMCALL leaf functions
*/
#define TDH_PHYMEM_PAGE_RDMD 24
#define TDH_SYS_KEY_CONFIG 31
#define TDH_SYS_INIT 33
#define TDH_SYS_RD 34
#define TDH_SYS_LP_INIT 35
#define TDH_SYS_TDMR_INIT 36
#define TDH_SYS_CONFIG 45
/* TDX page types */
#define PT_NDA 0x0
#define PT_RSVD 0x1
struct tdmr_reserved_area {
u64 offset;
u64 size;
} __packed;
#define TDMR_INFO_ALIGNMENT 512
#define TDMR_INFO_PA_ARRAY_ALIGNMENT 512
struct tdmr_info {
u64 base;
u64 size;
u64 pamt_1g_base;
u64 pamt_1g_size;
u64 pamt_2m_base;
u64 pamt_2m_size;
u64 pamt_4k_base;
u64 pamt_4k_size;
/*
* The actual number of reserved areas depends on the value of
* field MD_FIELD_ID_MAX_RESERVED_PER_TDMR in the TDX module
* global metadata.
*/
DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas);
} __packed __aligned(TDMR_INFO_ALIGNMENT);
/* Bit definitions of TDX_FEATURES0 metadata field */
#define TDX_FEATURES0_NO_RBP_MOD BIT(18)
/*
* Do not put any hardware-defined TDX structure representations below
* this comment!
*/
/* Kernel defined TDX module status during module initialization. */
enum tdx_module_status_t {
TDX_MODULE_UNINITIALIZED,
TDX_MODULE_INITIALIZED,
TDX_MODULE_ERROR
};
struct tdx_memblock {
struct list_head list;
unsigned long start_pfn;
unsigned long end_pfn;
int nid;
};
/* Warn if kernel has less than TDMR_NR_WARN TDMRs after allocation */
#define TDMR_NR_WARN 4
struct tdmr_info_list {
void *tdmrs; /* Flexible array to hold 'tdmr_info's */
int nr_consumed_tdmrs; /* How many 'tdmr_info's are in use */
/* Metadata for finding target 'tdmr_info' and freeing @tdmrs */
int tdmr_sz; /* Size of one 'tdmr_info' */
int max_tdmrs; /* How many 'tdmr_info's are allocated */
};
#endif