Add the build-time check to ensure the manually input field mappings have consistent size definitions. I.e. for each mapping entry, the size code in field_id should match the corresponding struct member type. This type safe check prevents wrong interpretation of the readout value. Cc: Adrian Hunter Cc: Kai Huang Signed-off-by: Xu Yilun --- arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 24 ++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c index 3db87c4accd6..836d97166a7a 100644 --- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c @@ -13,10 +13,32 @@ struct field_mapping { int size; }; +/* + * Size of field abstracted from field ID. + * + * See Table "MD_FIELD_ID (Metadata Field Identifier / Sequence Header) + * Definition", TDX module 1.5 ABI spec. + * + * - Bit 33:32: ELEMENT_SIZE_CODE -- size of a single element of metadata + * + * 0: 8 bits + * 1: 16 bits + * 2: 32 bits + * 3: 64 bits + */ +#define MD_FIELD_SIZE_CODE(_field_id) \ + (((_field_id) & GENMASK_ULL(33, 32)) >> 32) + +#define MD_FIELD_SIZE(_field_id) (1 << MD_FIELD_SIZE_CODE(_field_id)) + +#define TD_SYSINFO_CHECK_SIZE(_field_id, _size) \ + __builtin_choose_expr(MD_FIELD_SIZE(_field_id) == (_size), _size, (void)0) + #define TD_SYSINFO_MAP(_field_id, _member) \ { .field_id = _field_id, \ .offset = offsetof(struct tdx_sys_info, _member), \ - .size = sizeof_field(struct tdx_sys_info, _member) } + .size = TD_SYSINFO_CHECK_SIZE(_field_id, \ + sizeof_field(struct tdx_sys_info, _member)) } /* Map TD_SYSINFO fields into 'struct tdx_sys_info': */ static const struct field_mapping mappings[] = { -- 2.25.1