Taken from rev 1.4b of the spec, following the SMCC register layout and constant names.
Signed-off-by: Jason Gunthorpe <[email protected]> --- arch/arm64/include/asm/drtm.h | 196 ++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 arch/arm64/include/asm/drtm.h diff --git a/arch/arm64/include/asm/drtm.h b/arch/arm64/include/asm/drtm.h new file mode 100644 index 00000000000000..d6dd04a4ebcea5 --- /dev/null +++ b/arch/arm64/include/asm/drtm.h @@ -0,0 +1,196 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES + * + * Definitions from ARM DEN 0113 "DRTM Architecture for Arm" + */ +#ifndef __ASM_DRTM_H +#define __ASM_DRTM_H + +#include <linux/arm-smccc.h> +#include <linux/bits.h> + +/* Offset 0x02 is reserved by DEN0113. */ +#define ARM_DRTM_SMC_FN_BASE \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD, 0x110) +#define ARM_DRTM_SMC_VERSION (ARM_DRTM_SMC_FN_BASE + 0x00) +#define ARM_DRTM_SMC_FEATURES (ARM_DRTM_SMC_FN_BASE + 0x01) +#define ARM_DRTM_SMC_UNPROTECT_MEMORY (ARM_DRTM_SMC_FN_BASE + 0x03) +#define ARM_DRTM_SMC_DYNAMIC_LAUNCH (ARM_DRTM_SMC_FN_BASE + 0x04) +#define ARM_DRTM_SMC_CLOSE_LOCALITY (ARM_DRTM_SMC_FN_BASE + 0x05) +#define ARM_DRTM_SMC_GET_ERROR (ARM_DRTM_SMC_FN_BASE + 0x06) +#define ARM_DRTM_SMC_SET_ERROR (ARM_DRTM_SMC_FN_BASE + 0x07) +#define ARM_DRTM_SMC_SET_TCB_HASH (ARM_DRTM_SMC_FN_BASE + 0x08) +#define ARM_DRTM_SMC_LOCK_TCB_HASHES (ARM_DRTM_SMC_FN_BASE + 0x09) +#define ARM_DRTM_SMC_ENABLE_SECURE_INTERRUPTS (ARM_DRTM_SMC_FN_BASE + 0x0a) + +#define ARM_DRTM_FEATURE_SELECTOR BIT_U64(63) +#define ARM_DRTM_FEATURE_TPM 0x01 +#define ARM_DRTM_FEATURE_MIN_MEMORY 0x02 +#define ARM_DRTM_FEATURE_DMA_PROTECTION 0x03 +#define ARM_DRTM_FEATURE_BOOT_PE 0x04 +#define ARM_DRTM_FEATURE_TCB_HASH 0x05 +#define ARM_DRTM_FEATURE_IMAGE_AUTH 0x06 + +#define ARM_DRTM_VERSION_MAJOR_MASK GENMASK_U32(30, 16) +#define ARM_DRTM_VERSION_MINOR_MASK GENMASK_U32(15, 0) +#define ARM_DRTM_VERSION_MAJOR 1 +#define ARM_DRTM_VERSION_MIN_MINOR 1 + +#define ARM_DRTM_TPM_ALG_MASK GENMASK_U64(15, 0) +#define ARM_DRTM_TPM_HASHING BIT_U64(32) +#define ARM_DRTM_PCR_SCHEMA_MASK GENMASK_U64(36, 33) +#define ARM_DRTM_PCR_SCHEMA_DEFAULT BIT_U64(33) +#define ARM_DRTM_PCR_SCHEMA_AUTHORITIES BIT_U64(34) + +#define ARM_DRTM_DLME_DATA_PAGES_MASK GENMASK_U64(31, 0) +#define ARM_DRTM_NW_DCE_PAGES_MASK GENMASK_U64(63, 32) +#define ARM_DRTM_PAGE_SIZE 4096 + +#define ARM_DRTM_DMA_PROTECTION_MASK GENMASK_U64(7, 0) +#define ARM_DRTM_DMA_PROTECTION_COMPLETE BIT_U64(0) +#define ARM_DRTM_DMA_PROTECTION_REGION BIT_U64(1) +#define ARM_DRTM_MAX_REGIONS_MASK GENMASK_U64(23, 8) +#define ARM_DRTM_TCB_HASH_COUNT_MASK GENMASK_U64(7, 0) +#define ARM_DRTM_IMAGE_AUTH_SUPPORTED BIT_U64(0) + +#define ARM_DRTM_LAUNCH_HASH_FIRMWARE 0 +#define ARM_DRTM_LAUNCH_HASH_TPM BIT_U32(0) +#define ARM_DRTM_LAUNCH_PCR_DEFAULT 0 +#define ARM_DRTM_LAUNCH_PCR_AUTHORITIES BIT_U32(1) +#define ARM_DRTM_LAUNCH_DMA_COMPLETE 0 +#define ARM_DRTM_LAUNCH_DMA_REGION BIT_U32(3) +#define ARM_DRTM_LAUNCH_NO_AUTH 0 +#define ARM_DRTM_LAUNCH_AUTH BIT_U32(6) +#define ARM_DRTM_LAUNCH_KEEP_SECURE_IRQS 0 +#define ARM_DRTM_LAUNCH_DISABLE_SECURE_IRQS BIT_U32(7) + +#define ARM_DRTM_SUCCESS 0 +#define ARM_DRTM_NOT_SUPPORTED -1 +#define ARM_DRTM_INVALID_PARAMETERS -2 +#define ARM_DRTM_DENIED -3 +#define ARM_DRTM_NOT_FOUND -4 +#define ARM_DRTM_INTERNAL_ERROR -5 +#define ARM_DRTM_MEM_PROTECT_INVALID -6 +#define ARM_DRTM_OUT_OF_RESOURCES -8 +#define ARM_DRTM_INVALID_DATA -9 +#define ARM_DRTM_SECONDARY_PE_NOT_OFF -10 +#define ARM_DRTM_ALREADY_CLOSED -11 +#define ARM_DRTM_TPM_ERROR -12 + +/* Algorthim IDs are defined by TCG, in the kernel they are TPM_ALG_* */ + +#define ARM_DRTM_PARAMETERS_REVISION 2 + +#ifndef __ASSEMBLY__ + +#include <linux/bitfield.h> +#include <linux/build_bug.h> +#include <linux/stddef.h> +#include <linux/types.h> + +struct arm_drtm_parameters { + __le16 revision; + __le16 reserved; + __le32 launch_features; + __le64 dlme_region_address; + __le64 dlme_region_size; + __le64 dlme_image_start; + __le64 dlme_entry_point_offset; + __le64 dlme_image_size; + __le64 dlme_data_offset; + __le64 nw_dce_region_address; + __le64 nw_dce_region_size; + __le64 protection_table_address; + __le64 protection_table_size; +}; +static_assert(sizeof(struct arm_drtm_parameters) == 88); + +static inline s32 arm_drtm_version(u16 *major, u16 *minor) +{ + struct arm_smccc_res res; + u32 version; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_VERSION, 0, 0, 0, 0, 0, 0, 0, + &res); + version = res.a0; + /* + * For this command only the output is specified as w0 a 32 bit value. + * All others use x0 a 64 bit value. The -ve error and version are + * overlayed together with the 32 bit sign bit telling them apart. + */ + if (version & BIT(31)) + return version; + + *major = FIELD_GET(ARM_DRTM_VERSION_MAJOR_MASK, version); + *minor = FIELD_GET(ARM_DRTM_VERSION_MINOR_MASK, version); + return ARM_DRTM_SUCCESS; +} + +static inline s64 arm_drtm_features(u64 function_or_feature, u64 *value) +{ + struct arm_smccc_res res; + s64 status; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_FEATURES, function_or_feature, + 0, 0, 0, 0, 0, 0, &res); + status = res.a0; + if (status >= 0 && value) + *value = res.a1; + return status; +} + +static inline s64 arm_drtm_unprotect_memory(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_UNPROTECT_MEMORY, 0, 0, 0, 0, 0, 0, 0, + &res); + return res.a0; +} + +static inline s64 +arm_drtm_dynamic_launch(struct arm_drtm_parameters *params_addr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_DYNAMIC_LAUNCH, + (unsigned long)params_addr, 0, 0, 0, 0, 0, 0, &res); + return res.a0; +} + +static inline s64 arm_drtm_close_locality(u32 locality) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_CLOSE_LOCALITY, locality, + 0, 0, 0, 0, 0, 0, &res); + return res.a0; +} + +static inline s64 arm_drtm_get_error(s64 *error_code) +{ + struct arm_smccc_res res; + s64 status; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_GET_ERROR, 0, 0, 0, 0, 0, 0, 0, + &res); + status = res.a0; + if (status != ARM_DRTM_SUCCESS) + return status; + + *error_code = res.a1; + return ARM_DRTM_SUCCESS; +} + +static inline s64 arm_drtm_enable_secure_interrupts(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_smc(ARM_DRTM_SMC_ENABLE_SECURE_INTERRUPTS, + 0, 0, 0, 0, 0, 0, 0, &res); + return res.a0; +} + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_DRTM_H */ -- 2.43.0
