[PATCH v14 04/19] x86: Secure Launch main header file

Ross Philipson posted 19 patches 8 months ago
[PATCH v14 04/19] x86: Secure Launch main header file
Posted by Ross Philipson 8 months ago
Introduce the main Secure Launch header file used in the early SL stub
and the early setup code.

This header file contains the following categories:
 - Secure Launch implementation specific structures and definitions.
 - Intel TXT architecture specific DRTM structures, definitions and functions
used by Secure Launch.
 - DRTM TPM event logging definitions and helper functions.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 include/linux/slaunch.h | 559 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 559 insertions(+)
 create mode 100644 include/linux/slaunch.h

diff --git a/include/linux/slaunch.h b/include/linux/slaunch.h
new file mode 100644
index 000000000000..ae67314c2aad
--- /dev/null
+++ b/include/linux/slaunch.h
@@ -0,0 +1,559 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Main Secure Launch header file.
+ *
+ * Copyright (c) 2025 Apertus Solutions, LLC
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#ifndef _LINUX_SLAUNCH_H
+#define _LINUX_SLAUNCH_H
+
+/*
+ * Secure Launch Defined State Flags
+ */
+#define SL_FLAG_ACTIVE		0x00000001
+#define SL_FLAG_ARCH_TXT	0x00000002
+
+/*
+ * Secure Launch CPU Type
+ */
+#define SL_CPU_INTEL	1
+
+#define __SL32_CS	0x0008
+#define __SL32_DS	0x0010
+
+/*
+ * Intel Safer Mode Extensions (SMX)
+ *
+ * Intel SMX provides a programming interface to establish a Measured Launched
+ * Environment (MLE). The measurement and protection mechanisms supported by the
+ * capabilities of an Intel Trusted Execution Technology (TXT) platform. SMX is
+ * the processor's programming interface in an Intel TXT platform.
+ *
+ * See:
+ *   Intel SDM Volume 2 - 6.1 "Safer Mode Extensions Reference"
+ *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide
+ */
+
+/*
+ * SMX GETSEC Leaf Functions
+ */
+#define SMX_X86_GETSEC_SEXIT	5
+#define SMX_X86_GETSEC_SMCTRL	7
+#define SMX_X86_GETSEC_WAKEUP	8
+
+/*
+ * Intel Trusted Execution Technology MMIO Registers Banks
+ */
+#define TXT_PUB_CONFIG_REGS_BASE	0xfed30000
+#define TXT_PRIV_CONFIG_REGS_BASE	0xfed20000
+#define TXT_NR_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE - \
+				  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
+
+/*
+ * Intel Trusted Execution Technology (TXT) Registers
+ */
+#define TXT_CR_STS			0x0000
+#define TXT_CR_ESTS			0x0008
+#define TXT_CR_ERRORCODE		0x0030
+#define TXT_CR_CMD_RESET		0x0038
+#define TXT_CR_CMD_CLOSE_PRIVATE	0x0048
+#define TXT_CR_DIDVID			0x0110
+#define TXT_CR_VER_EMIF			0x0200
+#define TXT_CR_CMD_UNLOCK_MEM_CONFIG	0x0218
+#define TXT_CR_SINIT_BASE		0x0270
+#define TXT_CR_SINIT_SIZE		0x0278
+#define TXT_CR_MLE_JOIN			0x0290
+#define TXT_CR_HEAP_BASE		0x0300
+#define TXT_CR_HEAP_SIZE		0x0308
+#define TXT_CR_SCRATCHPAD		0x0378
+#define TXT_CR_CMD_OPEN_LOCALITY1	0x0380
+#define TXT_CR_CMD_CLOSE_LOCALITY1	0x0388
+#define TXT_CR_CMD_OPEN_LOCALITY2	0x0390
+#define TXT_CR_CMD_CLOSE_LOCALITY2	0x0398
+#define TXT_CR_CMD_SECRETS		0x08e0
+#define TXT_CR_CMD_NO_SECRETS		0x08e8
+#define TXT_CR_E2STS			0x08f0
+
+/* TXT default register value */
+#define TXT_REGVALUE_ONE		0x1ULL
+
+/* TXTCR_STS status bits */
+#define TXT_SENTER_DONE_STS		BIT(0)
+#define TXT_SEXIT_DONE_STS		BIT(1)
+
+/*
+ * SINIT/MLE Capabilities Field Bit Definitions
+ */
+#define TXT_SINIT_MLE_CAP_WAKE_GETSEC	0
+#define TXT_SINIT_MLE_CAP_WAKE_MONITOR	1
+
+/*
+ * OS/MLE Secure Launch Specific Definitions
+ */
+#define TXT_OS_MLE_STRUCT_VERSION	1
+#define TXT_OS_MLE_MAX_VARIABLE_MTRRS	32
+
+/*
+ * TXT Heap Table Enumeration
+ */
+#define TXT_BIOS_DATA_TABLE		1
+#define TXT_OS_MLE_DATA_TABLE		2
+#define TXT_OS_SINIT_DATA_TABLE		3
+#define TXT_SINIT_MLE_DATA_TABLE	4
+#define TXT_SINIT_TABLE_MAX		TXT_SINIT_MLE_DATA_TABLE
+
+/*
+ * Secure Launch Defined Error Codes used in MLE-initiated TXT resets.
+ *
+ * TXT Specification
+ * Appendix I ACM Error Codes
+ */
+#define SL_ERROR_GENERIC		0xc0008001
+#define SL_ERROR_TPM_INIT		0xc0008002
+#define SL_ERROR_TPM_INVALID_LOG20	0xc0008003
+#define SL_ERROR_TPM_LOGGING_FAILED	0xc0008004
+#define SL_ERROR_REGION_STRADDLE_4GB	0xc0008005
+#define SL_ERROR_TPM_EXTEND		0xc0008006
+#define SL_ERROR_MTRR_INV_VCNT		0xc0008007
+#define SL_ERROR_MTRR_INV_DEF_TYPE	0xc0008008
+#define SL_ERROR_MTRR_INV_BASE		0xc0008009
+#define SL_ERROR_MTRR_INV_MASK		0xc000800a
+#define SL_ERROR_MSR_INV_MISC_EN	0xc000800b
+#define SL_ERROR_INV_AP_INTERRUPT	0xc000800c
+#define SL_ERROR_INTEGER_OVERFLOW	0xc000800d
+#define SL_ERROR_HEAP_WALK		0xc000800e
+#define SL_ERROR_HEAP_MAP		0xc000800f
+#define SL_ERROR_REGION_ABOVE_4GB	0xc0008010
+#define SL_ERROR_HEAP_INVALID_DMAR	0xc0008011
+#define SL_ERROR_HEAP_DMAR_SIZE		0xc0008012
+#define SL_ERROR_HEAP_DMAR_MAP		0xc0008013
+#define SL_ERROR_HI_PMR_BASE		0xc0008014
+#define SL_ERROR_HI_PMR_SIZE		0xc0008015
+#define SL_ERROR_LO_PMR_BASE		0xc0008016
+#define SL_ERROR_LO_PMR_MLE		0xc0008017
+#define SL_ERROR_INITRD_TOO_BIG		0xc0008018
+#define SL_ERROR_HEAP_ZERO_OFFSET	0xc0008019
+#define SL_ERROR_WAKE_BLOCK_TOO_SMALL	0xc000801a
+#define SL_ERROR_MLE_BUFFER_OVERLAP	0xc000801b
+#define SL_ERROR_BUFFER_BEYOND_PMR	0xc000801c
+#define SL_ERROR_OS_SINIT_BAD_VERSION	0xc000801d
+#define SL_ERROR_EVENTLOG_MAP		0xc000801e
+#define SL_ERROR_TPM_INVALID_ALGS	0xc000801f
+#define SL_ERROR_TPM_EVENT_COUNT	0xc0008020
+#define SL_ERROR_TPM_INVALID_EVENT	0xc0008021
+#define SL_ERROR_INVALID_SLRT		0xc0008022
+#define SL_ERROR_SLRT_MISSING_ENTRY	0xc0008023
+#define SL_ERROR_SLRT_MAP		0xc0008024
+
+/*
+ * Secure Launch Defined Limits
+ */
+#define TXT_MAX_CPUS		512
+#define TXT_BOOT_STACK_SIZE	128
+
+/*
+ * Secure Launch event log entry type. The TXT specification defines the
+ * base event value as 0x400 for DRTM values.
+ */
+#define TXT_EVTYPE_BASE			0x400
+#define TXT_EVTYPE_SLAUNCH		(TXT_EVTYPE_BASE + 0x102)
+#define TXT_EVTYPE_SLAUNCH_START	(TXT_EVTYPE_BASE + 0x103)
+#define TXT_EVTYPE_SLAUNCH_END		(TXT_EVTYPE_BASE + 0x104)
+
+/*
+ * MLE scratch area offsets
+ */
+#define SL_SCRATCH_AP_EBX		0
+#define SL_SCRATCH_AP_JMP_OFFSET	4
+#define SL_SCRATCH_AP_STACKS_OFFSET	8
+
+#ifndef __ASSEMBLY__
+
+#include <linux/io.h>
+#include <linux/tpm.h>
+#include <linux/tpm_eventlog.h>
+
+/*
+ * Secure Launch AP stack and monitor block
+ */
+struct sl_ap_stack_and_monitor {
+	u32 monitor;
+	u32 cache_pad[15];
+	u32 stack_pad[15];
+	u32 apicid;
+} __packed;
+
+/*
+ * Secure Launch AP wakeup information fetched in SMP boot code.
+ */
+struct sl_ap_wake_info {
+	u32 ap_wake_block;
+	u32 ap_wake_block_size;
+	u32 ap_jmp_offset;
+	u32 ap_stacks_offset;
+};
+
+/*
+ * TXT heap extended data elements.
+ */
+struct txt_heap_ext_data_element {
+	u32 type;
+	u32 size;
+	/* Data */
+} __packed;
+
+#define TXT_HEAP_EXTDATA_TYPE_END			0
+
+struct txt_heap_end_element {
+	u32 type;
+	u32 size;
+} __packed;
+
+#define TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR		5
+
+struct txt_heap_event_log_element {
+	u64 event_log_phys_addr;
+} __packed;
+
+#define TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1	8
+
+struct txt_heap_event_log_pointer2_1_element {
+	u64 phys_addr;
+	u32 allocated_event_container_size;
+	u32 first_record_offset;
+	u32 next_record_offset;
+} __packed;
+
+/*
+ * Secure Launch defined OS/MLE TXT Heap table
+ */
+struct txt_os_mle_data {
+	u32 version;
+	u32 reserved;
+	u64 slrt;
+	u64 txt_info;
+	u32 ap_wake_block;
+	u32 ap_wake_block_size;
+	u8 mle_scratch[64];
+} __packed;
+
+/*
+ * TXT specification defined BIOS data TXT Heap table
+ */
+struct txt_bios_data {
+	u32 version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */
+	u32 bios_sinit_size;
+	u64 reserved1;
+	u64 reserved2;
+	u32 num_logical_procs;
+	/* Versions >= 5 with updates in version 6 */
+	u32 sinit_flags;
+	u32 mle_flags;
+	/* Versions >= 4 */
+	/* Ext Data Elements */
+} __packed;
+
+/*
+ * TXT specification defined OS/SINIT TXT Heap table
+ */
+struct txt_os_sinit_data {
+	u32 version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */
+	u32 flags;
+	u64 mle_ptab;
+	u64 mle_size;
+	u64 mle_hdr_base;
+	u64 vtd_pmr_lo_base;
+	u64 vtd_pmr_lo_size;
+	u64 vtd_pmr_hi_base;
+	u64 vtd_pmr_hi_size;
+	u64 lcp_po_base;
+	u64 lcp_po_size;
+	u32 capabilities;
+	/* Version = 5 */
+	u64 efi_rsdt_ptr;
+	/* Versions >= 6 */
+	/* Ext Data Elements */
+} __packed;
+
+/*
+ * TXT specification defined SINIT/MLE TXT Heap table
+ */
+struct txt_sinit_mle_data {
+	u32 version;             /* Current values are 6 through 9 */
+	/* Versions <= 8 */
+	u8 bios_acm_id[20];
+	u32 edx_senter_flags;
+	u64 mseg_valid;
+	u8 sinit_hash[20];
+	u8 mle_hash[20];
+	u8 stm_hash[20];
+	u8 lcp_policy_hash[20];
+	u32 lcp_policy_control;
+	/* Versions >= 7 */
+	u32 rlp_wakeup_addr;
+	u32 reserved;
+	u32 num_of_sinit_mdrs;
+	u32 sinit_mdrs_table_offset;
+	u32 sinit_vtd_dmar_table_size;
+	u32 sinit_vtd_dmar_table_offset;
+	/* Versions >= 8 */
+	u32 processor_scrtm_status;
+	/* Versions >= 9 */
+	/* Ext Data Elements */
+} __packed;
+
+/*
+ * TXT data reporting structure for memory types
+ */
+struct txt_sinit_memory_descriptor_record {
+	u64 address;
+	u64 length;
+	u8 type;
+	u8 reserved[7];
+} __packed;
+
+/*
+ * TXT data structure used by a responsive local processor (RLP) to start
+ * execution in response to a GETSEC[WAKEUP].
+ */
+struct smx_rlp_mle_join {
+	u32 rlp_gdt_limit;
+	u32 rlp_gdt_base;
+	u32 rlp_seg_sel;     /* cs (ds, es, ss are seg_sel+8) */
+	u32 rlp_entry_point; /* phys addr */
+} __packed;
+
+/*
+ * TPM event log structures defined in both the TXT specification and
+ * the TCG documentation.
+ */
+#define TPM_EVTLOG_SIGNATURE "TXT Event Container"
+
+struct tpm_event_log_header {
+	char signature[20];
+	char reserved[12];
+	u8 container_ver_major;
+	u8 container_ver_minor;
+	u8 pcr_event_ver_major;
+	u8 pcr_event_ver_minor;
+	u32 container_size;
+	u32 pcr_events_offset;
+	u32 next_event_offset;
+	/* PCREvents[] */
+} __packed;
+
+/*
+ * Functions to extract data from the Intel TXT Heap Memory. The layout
+ * of the heap is as follows:
+ *  +----------------------------+
+ *  | Size Bios Data table (u64) |
+ *  +----------------------------+
+ *  | Bios Data table            |
+ *  +----------------------------+
+ *  | Size OS MLE table (u64)    |
+ *  +----------------------------+
+ *  | OS MLE table               |
+ *  +--------------------------- +
+ *  | Size OS SINIT table (u64)  |
+ *  +----------------------------+
+ *  | OS SINIT table             |
+ *  +----------------------------+
+ *  | Size SINIT MLE table (u64) |
+ *  +----------------------------+
+ *  | SINIT MLE table            |
+ *  +----------------------------+
+ *
+ *  NOTE: the table size fields include the 8 byte size field itself.
+ */
+static inline u64 txt_bios_data_size(void *heap)
+{
+	return *((u64 *)heap);
+}
+
+static inline void *txt_bios_data_start(void *heap)
+{
+	return heap + sizeof(u64);
+}
+
+static inline u64 txt_os_mle_data_size(void *heap)
+{
+	return *((u64 *)(heap + txt_bios_data_size(heap)));
+}
+
+static inline void *txt_os_mle_data_start(void *heap)
+{
+	return heap + txt_bios_data_size(heap) + sizeof(u64);
+}
+
+static inline u64 txt_os_sinit_data_size(void *heap)
+{
+	return *((u64 *)(heap + txt_bios_data_size(heap) +
+			txt_os_mle_data_size(heap)));
+}
+
+static inline void *txt_os_sinit_data_start(void *heap)
+{
+	return heap + txt_bios_data_size(heap) +
+		txt_os_mle_data_size(heap) + sizeof(u64);
+}
+
+static inline u64 txt_sinit_mle_data_size(void *heap)
+{
+	return *((u64 *)(heap + txt_bios_data_size(heap) +
+			txt_os_mle_data_size(heap) +
+			txt_os_sinit_data_size(heap)));
+}
+
+static inline void *txt_sinit_mle_data_start(void *heap)
+{
+	return heap + txt_bios_data_size(heap) +
+		txt_os_mle_data_size(heap) +
+		txt_os_sinit_data_size(heap) + sizeof(u64);
+}
+
+#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
+
+/*
+ * TPM event logging functions.
+ */
+
+/*
+ * Find the TPM v2 event log element in the TXT heap. This element contains
+ * the information about the size and location of the DRTM event log. Note
+ * this is a TXT specific structure.
+ *
+ * See:
+ *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide - Appendix C.
+ */
+static inline struct txt_heap_event_log_pointer2_1_element*
+tpm2_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
+{
+	struct txt_heap_ext_data_element *ext_elem;
+
+	/* The extended element array as at the end of this table */
+	ext_elem = (struct txt_heap_ext_data_element *)
+		((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));
+
+	while (ext_elem->type != TXT_HEAP_EXTDATA_TYPE_END) {
+		if (ext_elem->type == TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1) {
+			return (struct txt_heap_event_log_pointer2_1_element *)
+				((u8 *)ext_elem + sizeof(struct txt_heap_ext_data_element));
+		}
+		ext_elem = (struct txt_heap_ext_data_element *)
+			    ((u8 *)ext_elem + ext_elem->size);
+	}
+
+	return NULL;
+}
+
+/*
+ * Log a TPM v1 formatted event to the given DRTM event log.
+ */
+static inline int tpm_log_event(void *evtlog_base, u32 evtlog_size,
+				u32 event_size, void *event)
+{
+	struct tpm_event_log_header *evtlog =
+		(struct tpm_event_log_header *)evtlog_base;
+
+	if (memcmp(evtlog->signature, TPM_EVTLOG_SIGNATURE,
+		   sizeof(TPM_EVTLOG_SIGNATURE)))
+		return -EINVAL;
+
+	if (evtlog->container_size > evtlog_size)
+		return -EINVAL;
+
+	if (evtlog->next_event_offset + event_size > evtlog->container_size)
+		return -E2BIG;
+
+	memcpy(evtlog_base + evtlog->next_event_offset, event, event_size);
+	evtlog->next_event_offset += event_size;
+
+	return 0;
+}
+
+/*
+ * Log a TPM v2 formatted event to the given DRTM event log.
+ */
+static inline int tpm2_log_event(struct txt_heap_event_log_pointer2_1_element *elem,
+				 void *evtlog_base, u32 evtlog_size,
+				 u32 event_size, void *event)
+{
+	struct tcg_pcr_event *header =
+		(struct tcg_pcr_event *)evtlog_base;
+
+	/* Has to be at least big enough for the signature */
+	if (header->event_size < sizeof(TCG_SPECID_SIG))
+		return -EINVAL;
+
+	if (memcmp((u8 *)header + sizeof(struct tcg_pcr_event),
+		   TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
+		return -EINVAL;
+
+	if (elem->allocated_event_container_size > evtlog_size)
+		return -EINVAL;
+
+	if (elem->next_record_offset + event_size >
+	    elem->allocated_event_container_size)
+		return -E2BIG;
+
+	memcpy(evtlog_base + elem->next_record_offset, event, event_size);
+	elem->next_record_offset += event_size;
+
+	return 0;
+}
+
+/*
+ * External functions available in mainline kernel.
+ */
+void slaunch_setup_txt(void);
+void slaunch_fixup_jump_vector(void);
+u32 slaunch_get_flags(void);
+struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
+struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
+void __noreturn slaunch_txt_reset(void __iomem *txt,
+					 const char *msg, u64 error);
+void slaunch_finalize(int do_sexit);
+
+static inline bool slaunch_is_txt_launch(void)
+{
+	u32 mask = SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
+
+	return (slaunch_get_flags() & mask) == mask;
+}
+
+#else
+
+static inline void slaunch_setup_txt(void)
+{
+}
+
+static inline void slaunch_fixup_jump_vector(void)
+{
+}
+
+static inline u32 slaunch_get_flags(void)
+{
+	return 0;
+}
+
+static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
+{
+	return dmar;
+}
+
+static inline void slaunch_finalize(int do_sexit)
+{
+}
+
+static inline bool slaunch_is_txt_launch(void)
+{
+	return false;
+}
+
+#endif /* !IS_ENABLED(CONFIG_SECURE_LAUNCH) */
+
+#endif /* !__ASSEMBLY */
+
+#endif /* _LINUX_SLAUNCH_H */
-- 
2.39.3
Re: [PATCH v14 04/19] x86: Secure Launch main header file
Posted by Camacho Romero, Michal 5 months, 4 weeks ago
Hello Ross,

I'm BIOS Engineer from Intel, working on the TXT-related security modules development, including TBOOT project.
I'm leaving you my thougths and objections on this patch:

On 4/21/2025 6:26 PM, Ross Philipson wrote:

Michal Camacho Romero: Replace all tabs with indentations (4 spaces) in the file

> Introduce the main Secure Launch header file used in the early SL stub
> and the early setup code.
> 
> This header file contains the following categories:
>  - Secure Launch implementation specific structures and definitions.
>  - Intel TXT architecture specific DRTM structures, definitions and functions
> used by Secure Launch.
>  - DRTM TPM event logging definitions and helper functions.
> 
> Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
> ---
>  include/linux/slaunch.h | 559 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 559 insertions(+)
>  create mode 100644 include/linux/slaunch.h
> 
> diff --git a/include/linux/slaunch.h b/include/linux/slaunch.h
> new file mode 100644
> index 000000000000..ae67314c2aad
> --- /dev/null
> +++ b/include/linux/slaunch.h
> @@ -0,0 +1,559 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Main Secure Launch header file.
> + *
> + * Copyright (c) 2025 Apertus Solutions, LLC
> + * Copyright (c) 2025, Oracle and/or its affiliates.
> + */
> +
> +#ifndef _LINUX_SLAUNCH_H
> +#define _LINUX_SLAUNCH_H
> +
> +/*
> + * Secure Launch Defined State Flags
> + */
> +#define SL_FLAG_ACTIVE		0x00000001
> +#define SL_FLAG_ARCH_TXT	0x00000002
> +
> +/*
> + * Secure Launch CPU Type
> + */
> +#define SL_CPU_INTEL	1
> +
> +#define __SL32_CS	0x0008
> +#define __SL32_DS	0x0010
> +
> +/*
> + * Intel Safer Mode Extensions (SMX)
> + *
> + * Intel SMX provides a programming interface to establish a Measured Launched
> + * Environment (MLE). The measurement and protection mechanisms supported by the
> + * capabilities of an Intel Trusted Execution Technology (TXT) platform. SMX is
> + * the processor's programming interface in an Intel TXT platform.
> + *
> + * See:
> + *   Intel SDM Volume 2 - 6.1 "Safer Mode Extensions Reference"
> + *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide
> + */
> +
> +/*
> + * SMX GETSEC Leaf Functions
> + */
> +#define SMX_X86_GETSEC_SEXIT	5
> +#define SMX_X86_GETSEC_SMCTRL	7
> +#define SMX_X86_GETSEC_WAKEUP	8
> +

Michal Camacho Romero: Create a new header file, called include/linux/txt.h and move there the following code section (matched in the black quotations):

""" [START]> +/*
> + * Intel Trusted Execution Technology MMIO Registers Banks
> + */
> +#define TXT_PUB_CONFIG_REGS_BASE	0xfed30000
> +#define TXT_PRIV_CONFIG_REGS_BASE	0xfed20000
> +#define TXT_NR_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE - \
> +				  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
> +
> +/*
> + * Intel Trusted Execution Technology (TXT) Registers
> + */
> +#define TXT_CR_STS			0x0000
> +#define TXT_CR_ESTS			0x0008
> +#define TXT_CR_ERRORCODE		0x0030
> +#define TXT_CR_CMD_RESET		0x0038
> +#define TXT_CR_CMD_CLOSE_PRIVATE	0x0048
> +#define TXT_CR_DIDVID			0x0110
> +#define TXT_CR_VER_EMIF			0x0200
> +#define TXT_CR_CMD_UNLOCK_MEM_CONFIG	0x0218
> +#define TXT_CR_SINIT_BASE		0x0270
> +#define TXT_CR_SINIT_SIZE		0x0278
> +#define TXT_CR_MLE_JOIN			0x0290
> +#define TXT_CR_HEAP_BASE		0x0300
> +#define TXT_CR_HEAP_SIZE		0x0308
> +#define TXT_CR_SCRATCHPAD		0x0378
> +#define TXT_CR_CMD_OPEN_LOCALITY1	0x0380
> +#define TXT_CR_CMD_CLOSE_LOCALITY1	0x0388
> +#define TXT_CR_CMD_OPEN_LOCALITY2	0x0390
> +#define TXT_CR_CMD_CLOSE_LOCALITY2	0x0398
> +#define TXT_CR_CMD_SECRETS		0x08e0
> +#define TXT_CR_CMD_NO_SECRETS		0x08e8
> +#define TXT_CR_E2STS			0x08f0
> +
> +/* TXT default register value */
> +#define TXT_REGVALUE_ONE		0x1ULL
> +
> +/* TXTCR_STS status bits */
> +#define TXT_SENTER_DONE_STS		BIT(0)
> +#define TXT_SEXIT_DONE_STS		BIT(1)
> +
> +/*
> + * SINIT/MLE Capabilities Field Bit Definitions
> + */


""" [END]

Michal Camacho Romero: Change TXT_SINIT_MLE_CAP_WAKE_GETSEC macro's name to TXT_SINIT_MLE_CAP_RLP_WAKE_GETSEC and also  TXT_SINIT_MLE_CAP_WAKE_MONITOR macro's name to TXT_SINIT_MLE_CAP_RLP_WAKE_MONITOR then move them to the newly created include/linux/txt.h: 

> +#define TXT_SINIT_MLE_CAP_WAKE_GETSEC	0
> +#define TXT_SINIT_MLE_CAP_WAKE_MONITOR	1
> +

Michal Camacho Romero: Move the following code section (matched in the black quotations) into the new header file include/linux/txt.h:

""" [START]> +/*
> + * OS/MLE Secure Launch Specific Definitions
> + */
> +#define TXT_OS_MLE_STRUCT_VERSION	1
> +#define TXT_OS_MLE_MAX_VARIABLE_MTRRS	32
> +
> +/*
> + * TXT Heap Table Enumeration
> + */
> +#define TXT_BIOS_DATA_TABLE		1
> +#define TXT_OS_MLE_DATA_TABLE		2
> +#define TXT_OS_SINIT_DATA_TABLE		3
> +#define TXT_SINIT_MLE_DATA_TABLE	4
> +#define TXT_SINIT_TABLE_MAX		TXT_SINIT_MLE_DATA_TABLE
> +

""" [END]> +/*
> + * Secure Launch Defined Error Codes used in MLE-initiated TXT resets.
> + *
> + * TXT Specification
> + * Appendix I ACM Error Codes
> + */
> +#define SL_ERROR_GENERIC		0xc0008001
> +#define SL_ERROR_TPM_INIT		0xc0008002
> +#define SL_ERROR_TPM_INVALID_LOG20	0xc0008003
> +#define SL_ERROR_TPM_LOGGING_FAILED	0xc0008004
> +#define SL_ERROR_REGION_STRADDLE_4GB	0xc0008005
> +#define SL_ERROR_TPM_EXTEND		0xc0008006
> +#define SL_ERROR_MTRR_INV_VCNT		0xc0008007
> +#define SL_ERROR_MTRR_INV_DEF_TYPE	0xc0008008
> +#define SL_ERROR_MTRR_INV_BASE		0xc0008009
> +#define SL_ERROR_MTRR_INV_MASK		0xc000800a
> +#define SL_ERROR_MSR_INV_MISC_EN	0xc000800b
> +#define SL_ERROR_INV_AP_INTERRUPT	0xc000800c
> +#define SL_ERROR_INTEGER_OVERFLOW	0xc000800d
> +#define SL_ERROR_HEAP_WALK		0xc000800e
> +#define SL_ERROR_HEAP_MAP		0xc000800f
> +#define SL_ERROR_REGION_ABOVE_4GB	0xc0008010
> +#define SL_ERROR_HEAP_INVALID_DMAR	0xc0008011
> +#define SL_ERROR_HEAP_DMAR_SIZE		0xc0008012
> +#define SL_ERROR_HEAP_DMAR_MAP		0xc0008013
> +#define SL_ERROR_HI_PMR_BASE		0xc0008014
> +#define SL_ERROR_HI_PMR_SIZE		0xc0008015
> +#define SL_ERROR_LO_PMR_BASE		0xc0008016
> +#define SL_ERROR_LO_PMR_MLE		0xc0008017
> +#define SL_ERROR_INITRD_TOO_BIG		0xc0008018
> +#define SL_ERROR_HEAP_ZERO_OFFSET	0xc0008019
> +#define SL_ERROR_WAKE_BLOCK_TOO_SMALL	0xc000801a
> +#define SL_ERROR_MLE_BUFFER_OVERLAP	0xc000801b
> +#define SL_ERROR_BUFFER_BEYOND_PMR	0xc000801c
> +#define SL_ERROR_OS_SINIT_BAD_VERSION	0xc000801d
> +#define SL_ERROR_EVENTLOG_MAP		0xc000801e
> +#define SL_ERROR_TPM_INVALID_ALGS	0xc000801f
> +#define SL_ERROR_TPM_EVENT_COUNT	0xc0008020
> +#define SL_ERROR_TPM_INVALID_EVENT	0xc0008021
> +#define SL_ERROR_INVALID_SLRT		0xc0008022
> +#define SL_ERROR_SLRT_MISSING_ENTRY	0xc0008023
> +#define SL_ERROR_SLRT_MAP		0xc0008024
> +
> +/*
> + * Secure Launch Defined Limits
> + */
> +#define TXT_MAX_CPUS		512
> +#define TXT_BOOT_STACK_SIZE	128
> +
> +/*
> + * Secure Launch event log entry type. The TXT specification defines the
> + * base event value as 0x400 for DRTM values.
> + */
> +#define TXT_EVTYPE_BASE			0x400
> +#define TXT_EVTYPE_SLAUNCH		(TXT_EVTYPE_BASE + 0x102)
> +#define TXT_EVTYPE_SLAUNCH_START	(TXT_EVTYPE_BASE + 0x103)
> +#define TXT_EVTYPE_SLAUNCH_END		(TXT_EVTYPE_BASE + 0x104)
> +
> +/*
> + * MLE scratch area offsets
> + */
> +#define SL_SCRATCH_AP_EBX		0
> +#define SL_SCRATCH_AP_JMP_OFFSET	4
> +#define SL_SCRATCH_AP_STACKS_OFFSET	8
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <linux/io.h>
> +#include <linux/tpm.h>
> +#include <linux/tpm_eventlog.h>
> +
> +/*
> + * Secure Launch AP stack and monitor block
> + */
> +struct sl_ap_stack_and_monitor {
> +	u32 monitor;
> +	u32 cache_pad[15];
> +	u32 stack_pad[15];
> +	u32 apicid;
> +} __packed;
> +
> +/*
> + * Secure Launch AP wakeup information fetched in SMP boot code.
> + */
> +struct sl_ap_wake_info {
> +	u32 ap_wake_block;
> +	u32 ap_wake_block_size;
> +	u32 ap_jmp_offset;
> +	u32 ap_stacks_offset;
> +};
> +

 Michal Camacho Romero: Move the following code section (matched in the black quotations) into the new header file include/linux/txt.h:

""" [START]> +/*
> + * TXT heap extended data elements.
> + */
> +struct txt_heap_ext_data_element {
> +	u32 type;
> +	u32 size;
> +	/* Data */
> +} __packed;
> +
> +#define TXT_HEAP_EXTDATA_TYPE_END			0
> +
> +struct txt_heap_end_element {
> +	u32 type;
> +	u32 size;
> +} __packed;
> +
> +#define TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR		5
> +
> +struct txt_heap_event_log_element {
> +	u64 event_log_phys_addr;
> +} __packed;
> +
> +#define TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1	8
> +
> +struct txt_heap_event_log_pointer2_1_element {
> +	u64 phys_addr;
> +	u32 allocated_event_container_size;
> +	u32 first_record_offset;
> +	u32 next_record_offset;
> +} __packed;
> +
> +/*
> + * Secure Launch defined OS/MLE TXT Heap table
> + */
> +struct txt_os_mle_data {
> +	u32 version;
> +	u32 reserved;
> +	u64 slrt;
> +	u64 txt_info;
> +	u32 ap_wake_block;
> +	u32 ap_wake_block_size;
> +	u8 mle_scratch[64];
> +} __packed;
> +
> +/*
> + * TXT specification defined BIOS data TXT Heap table
> + */
> +struct txt_bios_data {
> +	u32 version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */
> +	u32 bios_sinit_size;
> +	u64 reserved1;
> +	u64 reserved2;
> +	u32 num_logical_procs;


Michal Camacho Romero: Put the comment /* Versions >= 5 with updates in version 6 */ under the sinit_flags struct member. The sinit_flags member exists in the BiosData struct since version 3. 

> +	/* Versions >= 5 with updates in version 6 */


> +	u32 sinit_flags;
> +	u32 mle_flags;
> +	/* Versions >= 4 */
> +	/* Ext Data Elements */
> +} __packed;
> +
> +/*
> + * TXT specification defined OS/SINIT TXT Heap table
> + */
> +struct txt_os_sinit_data {
> +	u32 version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */
> +	u32 flags;
> +	u64 mle_ptab;
> +	u64 mle_size;
> +	u64 mle_hdr_base;
> +	u64 vtd_pmr_lo_base;
> +	u64 vtd_pmr_lo_size;
> +	u64 vtd_pmr_hi_base;
> +	u64 vtd_pmr_hi_size;
> +	u64 lcp_po_base;
> +	u64 lcp_po_size;
> +	u32 capabilities;
> +	/* Version = 5 */
> +	u64 efi_rsdt_ptr;
> +	/* Versions >= 6 */
> +	/* Ext Data Elements */
> +} __packed;
> +
> +/*
> + * TXT specification defined SINIT/MLE TXT Heap table
> + */
> +struct txt_sinit_mle_data {
> +	u32 version;             /* Current values are 6 through 9 */
> +	/* Versions <= 8 */
> +	u8 bios_acm_id[20];
> +	u32 edx_senter_flags;
> +	u64 mseg_valid;
> +	u8 sinit_hash[20];
> +	u8 mle_hash[20];
> +	u8 stm_hash[20];
> +	u8 lcp_policy_hash[20];
> +	u32 lcp_policy_control;
> +	/* Versions >= 7 */
> +	u32 rlp_wakeup_addr;
> +	u32 reserved;
> +	u32 num_of_sinit_mdrs;
> +	u32 sinit_mdrs_table_offset;
> +	u32 sinit_vtd_dmar_table_size;
> +	u32 sinit_vtd_dmar_table_offset;
> +	/* Versions >= 8 */
> +	u32 processor_scrtm_status;
> +	/* Versions >= 9 */
> +	/* Ext Data Elements */
> +} __packed;
> +
> +/*
> + * TXT data reporting structure for memory types
> + */
> +struct txt_sinit_memory_descriptor_record {
> +	u64 address;
> +	u64 length;
> +	u8 type;
> +	u8 reserved[7];
> +} __packed;
> +
> +/*
> + * TXT data structure used by a responsive local processor (RLP) to start
> + * execution in response to a GETSEC[WAKEUP].
> + */
> +struct smx_rlp_mle_join {
> +	u32 rlp_gdt_limit;
> +	u32 rlp_gdt_base;
> +	u32 rlp_seg_sel;     /* cs (ds, es, ss are seg_sel+8) */
> +	u32 rlp_entry_point; /* phys addr */
> +} __packed;
> +
> +/*
> + * TPM event log structures defined in both the TXT specification and
> + * the TCG documentation.
> + */
> +#define TPM_EVTLOG_SIGNATURE "TXT Event Container"
> +
> +struct tpm_event_log_header {
> +	char signature[20];
> +	char reserved[12];
> +	u8 container_ver_major;
> +	u8 container_ver_minor;
> +	u8 pcr_event_ver_major;
> +	u8 pcr_event_ver_minor;
> +	u32 container_size;
> +	u32 pcr_events_offset;
> +	u32 next_event_offset;
> +	/* PCREvents[] */
> +} __packed;
> +
> +/*
> + * Functions to extract data from the Intel TXT Heap Memory. The layout
> + * of the heap is as follows:
> + *  +----------------------------+
> + *  | Size Bios Data table (u64) |
> + *  +----------------------------+
> + *  | Bios Data table            |
> + *  +----------------------------+
> + *  | Size OS MLE table (u64)    |
> + *  +----------------------------+
> + *  | OS MLE table               |
> + *  +--------------------------- +
> + *  | Size OS SINIT table (u64)  |
> + *  +----------------------------+
> + *  | OS SINIT table             |
> + *  +----------------------------+
> + *  | Size SINIT MLE table (u64) |
> + *  +----------------------------+
> + *  | SINIT MLE table            |
> + *  +----------------------------+
> + *
> + *  NOTE: the table size fields include the 8 byte size field itself.
> + */
> +static inline u64 txt_bios_data_size(void *heap)
> +{
> +	return *((u64 *)heap);
> +}
> +
> +static inline void *txt_bios_data_start(void *heap)
> +{
> +	return heap + sizeof(u64);
> +}
> +
> +static inline u64 txt_os_mle_data_size(void *heap)
> +{
> +	return *((u64 *)(heap + txt_bios_data_size(heap)));
> +}
> +
> +static inline void *txt_os_mle_data_start(void *heap)
> +{
> +	return heap + txt_bios_data_size(heap) + sizeof(u64);
> +}
> +
> +static inline u64 txt_os_sinit_data_size(void *heap)
> +{
> +	return *((u64 *)(heap + txt_bios_data_size(heap) +
> +			txt_os_mle_data_size(heap)));
> +}
> +
> +static inline void *txt_os_sinit_data_start(void *heap)
> +{
> +	return heap + txt_bios_data_size(heap) +
> +		txt_os_mle_data_size(heap) + sizeof(u64);
> +}
> +
> +static inline u64 txt_sinit_mle_data_size(void *heap)
> +{
> +	return *((u64 *)(heap + txt_bios_data_size(heap) +
> +			txt_os_mle_data_size(heap) +
> +			txt_os_sinit_data_size(heap)));
> +}
> +
> +static inline void *txt_sinit_mle_data_start(void *heap)
> +{
> +	return heap + txt_bios_data_size(heap) +
> +		txt_os_mle_data_size(heap) +
> +		txt_os_sinit_data_size(heap) + sizeof(u64);
> +}
> +
> +#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
> +
> +/*
> + * TPM event logging functions.
> + */
> +
> +/*
> + * Find the TPM v2 event log element in the TXT heap. This element contains
> + * the information about the size and location of the DRTM event log. Note
> + * this is a TXT specific structure.
> + *
> + * See:
> + *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide - Appendix C.
> + */
> +static inline struct txt_heap_event_log_pointer2_1_element*
> +tpm2_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
> +{
> +	struct txt_heap_ext_data_element *ext_elem;
> +
> +	/* The extended element array as at the end of this table */
> +	ext_elem = (struct txt_heap_ext_data_element *)
> +		((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));
> +
> +	while (ext_elem->type != TXT_HEAP_EXTDATA_TYPE_END) {
> +		if (ext_elem->type == TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1) {
> +			return (struct txt_heap_event_log_pointer2_1_element *)
> +				((u8 *)ext_elem + sizeof(struct txt_heap_ext_data_element));
> +		}
> +		ext_elem = (struct txt_heap_ext_data_element *)
> +			    ((u8 *)ext_elem + ext_elem->size);
> +	}
> +
> +	return NULL;
> +}
> +
> +/*
> + * Log a TPM v1 formatted event to the given DRTM event log.
> + */
> +static inline int tpm_log_event(void *evtlog_base, u32 evtlog_size,
> +				u32 event_size, void *event)
> +{
> +	struct tpm_event_log_header *evtlog =
> +		(struct tpm_event_log_header *)evtlog_base;
> +
> +	if (memcmp(evtlog->signature, TPM_EVTLOG_SIGNATURE,
> +		   sizeof(TPM_EVTLOG_SIGNATURE)))
> +		return -EINVAL;
> +
> +	if (evtlog->container_size > evtlog_size)
> +		return -EINVAL;
> +
> +	if (evtlog->next_event_offset + event_size > evtlog->container_size)
> +		return -E2BIG;
> +
> +	memcpy(evtlog_base + evtlog->next_event_offset, event, event_size);
> +	evtlog->next_event_offset += event_size;
> +
> +	return 0;
> +}
> +
> +/*
> + * Log a TPM v2 formatted event to the given DRTM event log.
> + */
> +static inline int tpm2_log_event(struct txt_heap_event_log_pointer2_1_element *elem,
> +				 void *evtlog_base, u32 evtlog_size,
> +				 u32 event_size, void *event)
> +{
> +	struct tcg_pcr_event *header =
> +		(struct tcg_pcr_event *)evtlog_base;
> +
> +	/* Has to be at least big enough for the signature */
> +	if (header->event_size < sizeof(TCG_SPECID_SIG))
> +		return -EINVAL;
> +
> +	if (memcmp((u8 *)header + sizeof(struct tcg_pcr_event),
> +		   TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
> +		return -EINVAL;
> +
> +	if (elem->allocated_event_container_size > evtlog_size)
> +		return -EINVAL;
> +
> +	if (elem->next_record_offset + event_size >
> +	    elem->allocated_event_container_size)
> +		return -E2BIG;
> +
> +	memcpy(evtlog_base + elem->next_record_offset, event, event_size);
> +	elem->next_record_offset += event_size;
> +
> +	return 0;
> +}
> +
"""[END]

> +/*
> + * External functions available in mainline kernel.
> + */
> +void slaunch_setup_txt(void);
> +void slaunch_fixup_jump_vector(void);
> +u32 slaunch_get_flags(void);
> +struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
> +struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
> +void __noreturn slaunch_txt_reset(void __iomem *txt,
> +					 const char *msg, u64 error);
> +void slaunch_finalize(int do_sexit);
> +
> +static inline bool slaunch_is_txt_launch(void)
> +{
> +	u32 mask = SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
> +
> +	return (slaunch_get_flags() & mask) == mask;
> +}
> +
> +#else
> +
> +static inline void slaunch_setup_txt(void)
> +{
> +}
> +
> +static inline void slaunch_fixup_jump_vector(void)
> +{
> +}
> +
> +static inline u32 slaunch_get_flags(void)
> +{
> +	return 0;
> +}
> +
> +static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
> +{
> +	return dmar;
> +}
> +
> +static inline void slaunch_finalize(int do_sexit)
> +{
> +}
> +
> +static inline bool slaunch_is_txt_launch(void)
> +{
> +	return false;
> +}
> +
> +#endif /* !IS_ENABLED(CONFIG_SECURE_LAUNCH) */
> +
> +#endif /* !__ASSEMBLY */
> +
> +#endif /* _LINUX_SLAUNCH_H */
Regards,
Michal Camacho Romero (michal.camacho.romero@linux.intel.com)
Re: [PATCH v14 04/19] x86: Secure Launch main header file
Posted by ross.philipson@oracle.com 5 months, 4 weeks ago
On 6/23/25 4:44 AM, Camacho Romero, Michal wrote:
> Hello Ross,
> 
> I'm BIOS Engineer from Intel, working on the TXT-related security modules development, including TBOOT project.
> I'm leaving you my thougths and objections on this patch:
> 
> On 4/21/2025 6:26 PM, Ross Philipson wrote:
> 
> Michal Camacho Romero: Replace all tabs with indentations (4 spaces) in the file
> 
>> Introduce the main Secure Launch header file used in the early SL stub
>> and the early setup code.
>>
>> This header file contains the following categories:
>>   - Secure Launch implementation specific structures and definitions.
>>   - Intel TXT architecture specific DRTM structures, definitions and functions
>> used by Secure Launch.
>>   - DRTM TPM event logging definitions and helper functions.
>>
>> Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
>> ---
>>   include/linux/slaunch.h | 559 ++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 559 insertions(+)
>>   create mode 100644 include/linux/slaunch.h
>>
>> diff --git a/include/linux/slaunch.h b/include/linux/slaunch.h
>> new file mode 100644
>> index 000000000000..ae67314c2aad
>> --- /dev/null
>> +++ b/include/linux/slaunch.h
>> @@ -0,0 +1,559 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Main Secure Launch header file.
>> + *
>> + * Copyright (c) 2025 Apertus Solutions, LLC
>> + * Copyright (c) 2025, Oracle and/or its affiliates.
>> + */
>> +
>> +#ifndef _LINUX_SLAUNCH_H
>> +#define _LINUX_SLAUNCH_H
>> +
>> +/*
>> + * Secure Launch Defined State Flags
>> + */
>> +#define SL_FLAG_ACTIVE		0x00000001
>> +#define SL_FLAG_ARCH_TXT	0x00000002
>> +
>> +/*
>> + * Secure Launch CPU Type
>> + */
>> +#define SL_CPU_INTEL	1
>> +
>> +#define __SL32_CS	0x0008
>> +#define __SL32_DS	0x0010
>> +
>> +/*
>> + * Intel Safer Mode Extensions (SMX)
>> + *
>> + * Intel SMX provides a programming interface to establish a Measured Launched
>> + * Environment (MLE). The measurement and protection mechanisms supported by the
>> + * capabilities of an Intel Trusted Execution Technology (TXT) platform. SMX is
>> + * the processor's programming interface in an Intel TXT platform.
>> + *
>> + * See:
>> + *   Intel SDM Volume 2 - 6.1 "Safer Mode Extensions Reference"
>> + *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide
>> + */
>> +
>> +/*
>> + * SMX GETSEC Leaf Functions
>> + */
>> +#define SMX_X86_GETSEC_SEXIT	5
>> +#define SMX_X86_GETSEC_SMCTRL	7
>> +#define SMX_X86_GETSEC_WAKEUP	8
>> +
> 
> Michal Camacho Romero: Create a new header file, called include/linux/txt.h and move there the following code section (matched in the black quotations):

That makes a lot of sense. I think that it has come up before. Since it 
is arch specific should it not go in arch/x86/include?

> 
> """ [START]> +/*
>> + * Intel Trusted Execution Technology MMIO Registers Banks
>> + */
>> +#define TXT_PUB_CONFIG_REGS_BASE	0xfed30000
>> +#define TXT_PRIV_CONFIG_REGS_BASE	0xfed20000
>> +#define TXT_NR_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE - \
>> +				  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
>> +
>> +/*
>> + * Intel Trusted Execution Technology (TXT) Registers
>> + */
>> +#define TXT_CR_STS			0x0000
>> +#define TXT_CR_ESTS			0x0008
>> +#define TXT_CR_ERRORCODE		0x0030
>> +#define TXT_CR_CMD_RESET		0x0038
>> +#define TXT_CR_CMD_CLOSE_PRIVATE	0x0048
>> +#define TXT_CR_DIDVID			0x0110
>> +#define TXT_CR_VER_EMIF			0x0200
>> +#define TXT_CR_CMD_UNLOCK_MEM_CONFIG	0x0218
>> +#define TXT_CR_SINIT_BASE		0x0270
>> +#define TXT_CR_SINIT_SIZE		0x0278
>> +#define TXT_CR_MLE_JOIN			0x0290
>> +#define TXT_CR_HEAP_BASE		0x0300
>> +#define TXT_CR_HEAP_SIZE		0x0308
>> +#define TXT_CR_SCRATCHPAD		0x0378
>> +#define TXT_CR_CMD_OPEN_LOCALITY1	0x0380
>> +#define TXT_CR_CMD_CLOSE_LOCALITY1	0x0388
>> +#define TXT_CR_CMD_OPEN_LOCALITY2	0x0390
>> +#define TXT_CR_CMD_CLOSE_LOCALITY2	0x0398
>> +#define TXT_CR_CMD_SECRETS		0x08e0
>> +#define TXT_CR_CMD_NO_SECRETS		0x08e8
>> +#define TXT_CR_E2STS			0x08f0
>> +
>> +/* TXT default register value */
>> +#define TXT_REGVALUE_ONE		0x1ULL
>> +
>> +/* TXTCR_STS status bits */
>> +#define TXT_SENTER_DONE_STS		BIT(0)
>> +#define TXT_SEXIT_DONE_STS		BIT(1)
>> +
>> +/*
>> + * SINIT/MLE Capabilities Field Bit Definitions
>> + */
> 
> 
> """ [END]
> 
> Michal Camacho Romero: Change TXT_SINIT_MLE_CAP_WAKE_GETSEC macro's name to TXT_SINIT_MLE_CAP_RLP_WAKE_GETSEC and also  TXT_SINIT_MLE_CAP_WAKE_MONITOR macro's name to TXT_SINIT_MLE_CAP_RLP_WAKE_MONITOR then move them to the newly created include/linux/txt.h:
> 
>> +#define TXT_SINIT_MLE_CAP_WAKE_GETSEC	0
>> +#define TXT_SINIT_MLE_CAP_WAKE_MONITOR	1
>> +
> 
> Michal Camacho Romero: Move the following code section (matched in the black quotations) into the new header file include/linux/txt.h:
> 
> """ [START]> +/*
>> + * OS/MLE Secure Launch Specific Definitions
>> + */
>> +#define TXT_OS_MLE_STRUCT_VERSION	1
>> +#define TXT_OS_MLE_MAX_VARIABLE_MTRRS	32
>> +
>> +/*
>> + * TXT Heap Table Enumeration
>> + */
>> +#define TXT_BIOS_DATA_TABLE		1
>> +#define TXT_OS_MLE_DATA_TABLE		2
>> +#define TXT_OS_SINIT_DATA_TABLE		3
>> +#define TXT_SINIT_MLE_DATA_TABLE	4
>> +#define TXT_SINIT_TABLE_MAX		TXT_SINIT_MLE_DATA_TABLE
>> +
> 
> """ [END]> +/*
>> + * Secure Launch Defined Error Codes used in MLE-initiated TXT resets.
>> + *
>> + * TXT Specification
>> + * Appendix I ACM Error Codes
>> + */
>> +#define SL_ERROR_GENERIC		0xc0008001
>> +#define SL_ERROR_TPM_INIT		0xc0008002
>> +#define SL_ERROR_TPM_INVALID_LOG20	0xc0008003
>> +#define SL_ERROR_TPM_LOGGING_FAILED	0xc0008004
>> +#define SL_ERROR_REGION_STRADDLE_4GB	0xc0008005
>> +#define SL_ERROR_TPM_EXTEND		0xc0008006
>> +#define SL_ERROR_MTRR_INV_VCNT		0xc0008007
>> +#define SL_ERROR_MTRR_INV_DEF_TYPE	0xc0008008
>> +#define SL_ERROR_MTRR_INV_BASE		0xc0008009
>> +#define SL_ERROR_MTRR_INV_MASK		0xc000800a
>> +#define SL_ERROR_MSR_INV_MISC_EN	0xc000800b
>> +#define SL_ERROR_INV_AP_INTERRUPT	0xc000800c
>> +#define SL_ERROR_INTEGER_OVERFLOW	0xc000800d
>> +#define SL_ERROR_HEAP_WALK		0xc000800e
>> +#define SL_ERROR_HEAP_MAP		0xc000800f
>> +#define SL_ERROR_REGION_ABOVE_4GB	0xc0008010
>> +#define SL_ERROR_HEAP_INVALID_DMAR	0xc0008011
>> +#define SL_ERROR_HEAP_DMAR_SIZE		0xc0008012
>> +#define SL_ERROR_HEAP_DMAR_MAP		0xc0008013
>> +#define SL_ERROR_HI_PMR_BASE		0xc0008014
>> +#define SL_ERROR_HI_PMR_SIZE		0xc0008015
>> +#define SL_ERROR_LO_PMR_BASE		0xc0008016
>> +#define SL_ERROR_LO_PMR_MLE		0xc0008017
>> +#define SL_ERROR_INITRD_TOO_BIG		0xc0008018
>> +#define SL_ERROR_HEAP_ZERO_OFFSET	0xc0008019
>> +#define SL_ERROR_WAKE_BLOCK_TOO_SMALL	0xc000801a
>> +#define SL_ERROR_MLE_BUFFER_OVERLAP	0xc000801b
>> +#define SL_ERROR_BUFFER_BEYOND_PMR	0xc000801c
>> +#define SL_ERROR_OS_SINIT_BAD_VERSION	0xc000801d
>> +#define SL_ERROR_EVENTLOG_MAP		0xc000801e
>> +#define SL_ERROR_TPM_INVALID_ALGS	0xc000801f
>> +#define SL_ERROR_TPM_EVENT_COUNT	0xc0008020
>> +#define SL_ERROR_TPM_INVALID_EVENT	0xc0008021
>> +#define SL_ERROR_INVALID_SLRT		0xc0008022
>> +#define SL_ERROR_SLRT_MISSING_ENTRY	0xc0008023
>> +#define SL_ERROR_SLRT_MAP		0xc0008024
>> +
>> +/*
>> + * Secure Launch Defined Limits
>> + */
>> +#define TXT_MAX_CPUS		512
>> +#define TXT_BOOT_STACK_SIZE	128
>> +
>> +/*
>> + * Secure Launch event log entry type. The TXT specification defines the
>> + * base event value as 0x400 for DRTM values.
>> + */
>> +#define TXT_EVTYPE_BASE			0x400
>> +#define TXT_EVTYPE_SLAUNCH		(TXT_EVTYPE_BASE + 0x102)
>> +#define TXT_EVTYPE_SLAUNCH_START	(TXT_EVTYPE_BASE + 0x103)
>> +#define TXT_EVTYPE_SLAUNCH_END		(TXT_EVTYPE_BASE + 0x104)
>> +
>> +/*
>> + * MLE scratch area offsets
>> + */
>> +#define SL_SCRATCH_AP_EBX		0
>> +#define SL_SCRATCH_AP_JMP_OFFSET	4
>> +#define SL_SCRATCH_AP_STACKS_OFFSET	8
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +#include <linux/io.h>
>> +#include <linux/tpm.h>
>> +#include <linux/tpm_eventlog.h>
>> +
>> +/*
>> + * Secure Launch AP stack and monitor block
>> + */
>> +struct sl_ap_stack_and_monitor {
>> +	u32 monitor;
>> +	u32 cache_pad[15];
>> +	u32 stack_pad[15];
>> +	u32 apicid;
>> +} __packed;
>> +
>> +/*
>> + * Secure Launch AP wakeup information fetched in SMP boot code.
>> + */
>> +struct sl_ap_wake_info {
>> +	u32 ap_wake_block;
>> +	u32 ap_wake_block_size;
>> +	u32 ap_jmp_offset;
>> +	u32 ap_stacks_offset;
>> +};
>> +
> 
>   Michal Camacho Romero: Move the following code section (matched in the black quotations) into the new header file include/linux/txt.h:
> 
> """ [START]> +/*
>> + * TXT heap extended data elements.
>> + */
>> +struct txt_heap_ext_data_element {
>> +	u32 type;
>> +	u32 size;
>> +	/* Data */
>> +} __packed;
>> +
>> +#define TXT_HEAP_EXTDATA_TYPE_END			0
>> +
>> +struct txt_heap_end_element {
>> +	u32 type;
>> +	u32 size;
>> +} __packed;
>> +
>> +#define TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR		5
>> +
>> +struct txt_heap_event_log_element {
>> +	u64 event_log_phys_addr;
>> +} __packed;
>> +
>> +#define TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1	8
>> +
>> +struct txt_heap_event_log_pointer2_1_element {
>> +	u64 phys_addr;
>> +	u32 allocated_event_container_size;
>> +	u32 first_record_offset;
>> +	u32 next_record_offset;
>> +} __packed;
>> +
>> +/*
>> + * Secure Launch defined OS/MLE TXT Heap table
>> + */
>> +struct txt_os_mle_data {
>> +	u32 version;
>> +	u32 reserved;
>> +	u64 slrt;
>> +	u64 txt_info;
>> +	u32 ap_wake_block;
>> +	u32 ap_wake_block_size;
>> +	u8 mle_scratch[64];
>> +} __packed;
>> +
>> +/*
>> + * TXT specification defined BIOS data TXT Heap table
>> + */
>> +struct txt_bios_data {
>> +	u32 version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */
>> +	u32 bios_sinit_size;
>> +	u64 reserved1;
>> +	u64 reserved2;
>> +	u32 num_logical_procs;
> 
> 
> Michal Camacho Romero: Put the comment /* Versions >= 5 with updates in version 6 */ under the sinit_flags struct member. The sinit_flags member exists in the BiosData struct since version 3.

Ack

> 
>> +	/* Versions >= 5 with updates in version 6 */
> 
> 
>> +	u32 sinit_flags;
>> +	u32 mle_flags;
>> +	/* Versions >= 4 */
>> +	/* Ext Data Elements */
>> +} __packed;
>> +
>> +/*
>> + * TXT specification defined OS/SINIT TXT Heap table
>> + */
>> +struct txt_os_sinit_data {
>> +	u32 version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */
>> +	u32 flags;
>> +	u64 mle_ptab;
>> +	u64 mle_size;
>> +	u64 mle_hdr_base;
>> +	u64 vtd_pmr_lo_base;
>> +	u64 vtd_pmr_lo_size;
>> +	u64 vtd_pmr_hi_base;
>> +	u64 vtd_pmr_hi_size;
>> +	u64 lcp_po_base;
>> +	u64 lcp_po_size;
>> +	u32 capabilities;
>> +	/* Version = 5 */
>> +	u64 efi_rsdt_ptr;
>> +	/* Versions >= 6 */
>> +	/* Ext Data Elements */
>> +} __packed;
>> +
>> +/*
>> + * TXT specification defined SINIT/MLE TXT Heap table
>> + */
>> +struct txt_sinit_mle_data {
>> +	u32 version;             /* Current values are 6 through 9 */
>> +	/* Versions <= 8 */
>> +	u8 bios_acm_id[20];
>> +	u32 edx_senter_flags;
>> +	u64 mseg_valid;
>> +	u8 sinit_hash[20];
>> +	u8 mle_hash[20];
>> +	u8 stm_hash[20];
>> +	u8 lcp_policy_hash[20];
>> +	u32 lcp_policy_control;
>> +	/* Versions >= 7 */
>> +	u32 rlp_wakeup_addr;
>> +	u32 reserved;
>> +	u32 num_of_sinit_mdrs;
>> +	u32 sinit_mdrs_table_offset;
>> +	u32 sinit_vtd_dmar_table_size;
>> +	u32 sinit_vtd_dmar_table_offset;
>> +	/* Versions >= 8 */
>> +	u32 processor_scrtm_status;
>> +	/* Versions >= 9 */
>> +	/* Ext Data Elements */
>> +} __packed;
>> +
>> +/*
>> + * TXT data reporting structure for memory types
>> + */
>> +struct txt_sinit_memory_descriptor_record {
>> +	u64 address;
>> +	u64 length;
>> +	u8 type;
>> +	u8 reserved[7];
>> +} __packed;
>> +
>> +/*
>> + * TXT data structure used by a responsive local processor (RLP) to start
>> + * execution in response to a GETSEC[WAKEUP].
>> + */
>> +struct smx_rlp_mle_join {
>> +	u32 rlp_gdt_limit;
>> +	u32 rlp_gdt_base;
>> +	u32 rlp_seg_sel;     /* cs (ds, es, ss are seg_sel+8) */
>> +	u32 rlp_entry_point; /* phys addr */
>> +} __packed;
>> +
>> +/*
>> + * TPM event log structures defined in both the TXT specification and
>> + * the TCG documentation.
>> + */
>> +#define TPM_EVTLOG_SIGNATURE "TXT Event Container"
>> +
>> +struct tpm_event_log_header {
>> +	char signature[20];
>> +	char reserved[12];
>> +	u8 container_ver_major;
>> +	u8 container_ver_minor;
>> +	u8 pcr_event_ver_major;
>> +	u8 pcr_event_ver_minor;
>> +	u32 container_size;
>> +	u32 pcr_events_offset;
>> +	u32 next_event_offset;
>> +	/* PCREvents[] */
>> +} __packed;
>> +

Should the following accessor functions be moved? They are specific to 
an environment (like protected mode paging off or x64 identity mapped) 
and thus this implementation.

>> +/*
>> + * Functions to extract data from the Intel TXT Heap Memory. The layout
>> + * of the heap is as follows:
>> + *  +----------------------------+
>> + *  | Size Bios Data table (u64) |
>> + *  +----------------------------+
>> + *  | Bios Data table            |
>> + *  +----------------------------+
>> + *  | Size OS MLE table (u64)    |
>> + *  +----------------------------+
>> + *  | OS MLE table               |
>> + *  +--------------------------- +
>> + *  | Size OS SINIT table (u64)  |
>> + *  +----------------------------+
>> + *  | OS SINIT table             |
>> + *  +----------------------------+
>> + *  | Size SINIT MLE table (u64) |
>> + *  +----------------------------+
>> + *  | SINIT MLE table            |
>> + *  +----------------------------+
>> + *
>> + *  NOTE: the table size fields include the 8 byte size field itself.
>> + */
>> +static inline u64 txt_bios_data_size(void *heap)
>> +{
>> +	return *((u64 *)heap);
>> +}
>> +
>> +static inline void *txt_bios_data_start(void *heap)
>> +{
>> +	return heap + sizeof(u64);
>> +}
>> +
>> +static inline u64 txt_os_mle_data_size(void *heap)
>> +{
>> +	return *((u64 *)(heap + txt_bios_data_size(heap)));
>> +}
>> +
>> +static inline void *txt_os_mle_data_start(void *heap)
>> +{
>> +	return heap + txt_bios_data_size(heap) + sizeof(u64);
>> +}
>> +
>> +static inline u64 txt_os_sinit_data_size(void *heap)
>> +{
>> +	return *((u64 *)(heap + txt_bios_data_size(heap) +
>> +			txt_os_mle_data_size(heap)));
>> +}
>> +
>> +static inline void *txt_os_sinit_data_start(void *heap)
>> +{
>> +	return heap + txt_bios_data_size(heap) +
>> +		txt_os_mle_data_size(heap) + sizeof(u64);
>> +}
>> +
>> +static inline u64 txt_sinit_mle_data_size(void *heap)
>> +{
>> +	return *((u64 *)(heap + txt_bios_data_size(heap) +
>> +			txt_os_mle_data_size(heap) +
>> +			txt_os_sinit_data_size(heap)));
>> +}
>> +
>> +static inline void *txt_sinit_mle_data_start(void *heap)
>> +{
>> +	return heap + txt_bios_data_size(heap) +
>> +		txt_os_mle_data_size(heap) +
>> +		txt_os_sinit_data_size(heap) + sizeof(u64);
>> +}
>> +
>> +#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
>> +
>> +/*
>> + * TPM event logging functions.
>> + */
>> +
>> +/*
>> + * Find the TPM v2 event log element in the TXT heap. This element contains
>> + * the information about the size and location of the DRTM event log. Note
>> + * this is a TXT specific structure.
>> + *
>> + * See:
>> + *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide - Appendix C.
>> + */
>> +static inline struct txt_heap_event_log_pointer2_1_element*
>> +tpm2_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
>> +{
>> +	struct txt_heap_ext_data_element *ext_elem;
>> +
>> +	/* The extended element array as at the end of this table */
>> +	ext_elem = (struct txt_heap_ext_data_element *)
>> +		((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));
>> +
>> +	while (ext_elem->type != TXT_HEAP_EXTDATA_TYPE_END) {
>> +		if (ext_elem->type == TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1) {
>> +			return (struct txt_heap_event_log_pointer2_1_element *)
>> +				((u8 *)ext_elem + sizeof(struct txt_heap_ext_data_element));
>> +		}
>> +		ext_elem = (struct txt_heap_ext_data_element *)
>> +			    ((u8 *)ext_elem + ext_elem->size);
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +/*
>> + * Log a TPM v1 formatted event to the given DRTM event log.
>> + */
>> +static inline int tpm_log_event(void *evtlog_base, u32 evtlog_size,
>> +				u32 event_size, void *event)
>> +{
>> +	struct tpm_event_log_header *evtlog =
>> +		(struct tpm_event_log_header *)evtlog_base;
>> +
>> +	if (memcmp(evtlog->signature, TPM_EVTLOG_SIGNATURE,
>> +		   sizeof(TPM_EVTLOG_SIGNATURE)))
>> +		return -EINVAL;
>> +
>> +	if (evtlog->container_size > evtlog_size)
>> +		return -EINVAL;
>> +
>> +	if (evtlog->next_event_offset + event_size > evtlog->container_size)
>> +		return -E2BIG;
>> +
>> +	memcpy(evtlog_base + evtlog->next_event_offset, event, event_size);
>> +	evtlog->next_event_offset += event_size;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Log a TPM v2 formatted event to the given DRTM event log.
>> + */
>> +static inline int tpm2_log_event(struct txt_heap_event_log_pointer2_1_element *elem,
>> +				 void *evtlog_base, u32 evtlog_size,
>> +				 u32 event_size, void *event)
>> +{
>> +	struct tcg_pcr_event *header =
>> +		(struct tcg_pcr_event *)evtlog_base;
>> +
>> +	/* Has to be at least big enough for the signature */
>> +	if (header->event_size < sizeof(TCG_SPECID_SIG))
>> +		return -EINVAL;
>> +
>> +	if (memcmp((u8 *)header + sizeof(struct tcg_pcr_event),
>> +		   TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
>> +		return -EINVAL;
>> +
>> +	if (elem->allocated_event_container_size > evtlog_size)
>> +		return -EINVAL;
>> +
>> +	if (elem->next_record_offset + event_size >
>> +	    elem->allocated_event_container_size)
>> +		return -E2BIG;
>> +
>> +	memcpy(evtlog_base + elem->next_record_offset, event, event_size);
>> +	elem->next_record_offset += event_size;
>> +
>> +	return 0;
>> +}
>> +
> """[END]
> 
>> +/*
>> + * External functions available in mainline kernel.
>> + */
>> +void slaunch_setup_txt(void);
>> +void slaunch_fixup_jump_vector(void);
>> +u32 slaunch_get_flags(void);
>> +struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
>> +struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
>> +void __noreturn slaunch_txt_reset(void __iomem *txt,
>> +					 const char *msg, u64 error);
>> +void slaunch_finalize(int do_sexit);
>> +
>> +static inline bool slaunch_is_txt_launch(void)
>> +{
>> +	u32 mask = SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
>> +
>> +	return (slaunch_get_flags() & mask) == mask;
>> +}
>> +
>> +#else
>> +
>> +static inline void slaunch_setup_txt(void)
>> +{
>> +}
>> +
>> +static inline void slaunch_fixup_jump_vector(void)
>> +{
>> +}
>> +
>> +static inline u32 slaunch_get_flags(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
>> +{
>> +	return dmar;
>> +}
>> +
>> +static inline void slaunch_finalize(int do_sexit)
>> +{
>> +}
>> +
>> +static inline bool slaunch_is_txt_launch(void)
>> +{
>> +	return false;
>> +}
>> +
>> +#endif /* !IS_ENABLED(CONFIG_SECURE_LAUNCH) */
>> +
>> +#endif /* !__ASSEMBLY */
>> +
>> +#endif /* _LINUX_SLAUNCH_H */
> Regards,
> Michal Camacho Romero (michal.camacho.romero@linux.intel.com)

Thank you for your feedback.
Ross
Re: [PATCH v14 04/19] x86: Secure Launch main header file
Posted by Camacho Romero, Michal 5 months, 3 weeks ago

On 6/23/2025 11:29 PM, ross.philipson@oracle.com wrote:
> On 6/23/25 4:44 AM, Camacho Romero, Michal wrote:
>> Hello Ross,
>>
>> I'm BIOS Engineer from Intel, working on the TXT-related security modules development, including TBOOT project.
>> I'm leaving you my thougths and objections on this patch:
>>
>> On 4/21/2025 6:26 PM, Ross Philipson wrote:
>>
>> Michal Camacho Romero: Replace all tabs with indentations (4 spaces) in the file
>>
>>> Introduce the main Secure Launch header file used in the early SL stub
>>> and the early setup code.
>>>
>>> This header file contains the following categories:
>>>   - Secure Launch implementation specific structures and definitions.
>>>   - Intel TXT architecture specific DRTM structures, definitions and functions
>>> used by Secure Launch.
>>>   - DRTM TPM event logging definitions and helper functions.
>>>
>>> Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
>>> ---
>>>   include/linux/slaunch.h | 559 ++++++++++++++++++++++++++++++++++++++++
>>>   1 file changed, 559 insertions(+)
>>>   create mode 100644 include/linux/slaunch.h
>>>
>>> diff --git a/include/linux/slaunch.h b/include/linux/slaunch.h
>>> new file mode 100644
>>> index 000000000000..ae67314c2aad
>>> --- /dev/null
>>> +++ b/include/linux/slaunch.h
>>> @@ -0,0 +1,559 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/*
>>> + * Main Secure Launch header file.
>>> + *
>>> + * Copyright (c) 2025 Apertus Solutions, LLC
>>> + * Copyright (c) 2025, Oracle and/or its affiliates.
>>> + */
>>> +
>>> +#ifndef _LINUX_SLAUNCH_H
>>> +#define _LINUX_SLAUNCH_H
>>> +
>>> +/*
>>> + * Secure Launch Defined State Flags
>>> + */
>>> +#define SL_FLAG_ACTIVE        0x00000001
>>> +#define SL_FLAG_ARCH_TXT    0x00000002
>>> +
>>> +/*
>>> + * Secure Launch CPU Type
>>> + */
>>> +#define SL_CPU_INTEL    1
>>> +
>>> +#define __SL32_CS    0x0008
>>> +#define __SL32_DS    0x0010
>>> +
>>> +/*
>>> + * Intel Safer Mode Extensions (SMX)
>>> + *
>>> + * Intel SMX provides a programming interface to establish a Measured Launched
>>> + * Environment (MLE). The measurement and protection mechanisms supported by the
>>> + * capabilities of an Intel Trusted Execution Technology (TXT) platform. SMX is
>>> + * the processor's programming interface in an Intel TXT platform.
>>> + *
>>> + * See:
>>> + *   Intel SDM Volume 2 - 6.1 "Safer Mode Extensions Reference"
>>> + *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide
>>> + */
>>> +
>>> +/*
>>> + * SMX GETSEC Leaf Functions
>>> + */
>>> +#define SMX_X86_GETSEC_SEXIT    5
>>> +#define SMX_X86_GETSEC_SMCTRL    7
>>> +#define SMX_X86_GETSEC_WAKEUP    8
>>> +
>>
>> Michal Camacho Romero: Create a new header file, called include/linux/txt.h and move there the following code section (matched in the black quotations):
> 
> That makes a lot of sense. I think that it has come up before. Since it is arch specific should it not go in arch/x86/include?

Michal Camacho Romero: Hmm. I've reconsidered this idea and I agree with your suggestion as the TXT technology has been designed to operate under the Intel x86 archictecture. Please then name this new header file: txt.h> 
>>
>> """ [START]> +/*
>>> + * Intel Trusted Execution Technology MMIO Registers Banks
>>> + */
>>> +#define TXT_PUB_CONFIG_REGS_BASE    0xfed30000
>>> +#define TXT_PRIV_CONFIG_REGS_BASE    0xfed20000
>>> +#define TXT_NR_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE - \
>>> +                  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
>>> +
>>> +/*
>>> + * Intel Trusted Execution Technology (TXT) Registers
>>> + */
>>> +#define TXT_CR_STS            0x0000
>>> +#define TXT_CR_ESTS            0x0008
>>> +#define TXT_CR_ERRORCODE        0x0030
>>> +#define TXT_CR_CMD_RESET        0x0038
>>> +#define TXT_CR_CMD_CLOSE_PRIVATE    0x0048
>>> +#define TXT_CR_DIDVID            0x0110
>>> +#define TXT_CR_VER_EMIF            0x0200
>>> +#define TXT_CR_CMD_UNLOCK_MEM_CONFIG    0x0218
>>> +#define TXT_CR_SINIT_BASE        0x0270
>>> +#define TXT_CR_SINIT_SIZE        0x0278
>>> +#define TXT_CR_MLE_JOIN            0x0290
>>> +#define TXT_CR_HEAP_BASE        0x0300
>>> +#define TXT_CR_HEAP_SIZE        0x0308
>>> +#define TXT_CR_SCRATCHPAD        0x0378
>>> +#define TXT_CR_CMD_OPEN_LOCALITY1    0x0380
>>> +#define TXT_CR_CMD_CLOSE_LOCALITY1    0x0388
>>> +#define TXT_CR_CMD_OPEN_LOCALITY2    0x0390
>>> +#define TXT_CR_CMD_CLOSE_LOCALITY2    0x0398
>>> +#define TXT_CR_CMD_SECRETS        0x08e0
>>> +#define TXT_CR_CMD_NO_SECRETS        0x08e8
>>> +#define TXT_CR_E2STS            0x08f0
>>> +
>>> +/* TXT default register value */
>>> +#define TXT_REGVALUE_ONE        0x1ULL
>>> +
>>> +/* TXTCR_STS status bits */
>>> +#define TXT_SENTER_DONE_STS        BIT(0)
>>> +#define TXT_SEXIT_DONE_STS        BIT(1)
>>> +
>>> +/*
>>> + * SINIT/MLE Capabilities Field Bit Definitions
>>> + */
>>
>>
>> """ [END]
>>
>> Michal Camacho Romero: Change TXT_SINIT_MLE_CAP_WAKE_GETSEC macro's name to TXT_SINIT_MLE_CAP_RLP_WAKE_GETSEC and also  TXT_SINIT_MLE_CAP_WAKE_MONITOR macro's name to TXT_SINIT_MLE_CAP_RLP_WAKE_MONITOR then move them to the newly created include/linux/txt.h:
>>
>>> +#define TXT_SINIT_MLE_CAP_WAKE_GETSEC    0
>>> +#define TXT_SINIT_MLE_CAP_WAKE_MONITOR    1
>>> +
>>
>> Michal Camacho Romero: Move the following code section (matched in the black quotations) into the new header file include/linux/txt.h:
>>
>> """ [START]> +/*
>>> + * OS/MLE Secure Launch Specific Definitions
>>> + */
>>> +#define TXT_OS_MLE_STRUCT_VERSION    1
>>> +#define TXT_OS_MLE_MAX_VARIABLE_MTRRS    32
>>> +
>>> +/*
>>> + * TXT Heap Table Enumeration
>>> + */
>>> +#define TXT_BIOS_DATA_TABLE        1
>>> +#define TXT_OS_MLE_DATA_TABLE        2
>>> +#define TXT_OS_SINIT_DATA_TABLE        3
>>> +#define TXT_SINIT_MLE_DATA_TABLE    4
>>> +#define TXT_SINIT_TABLE_MAX        TXT_SINIT_MLE_DATA_TABLE
>>> +
>>
>> """ [END]> +/*
>>> + * Secure Launch Defined Error Codes used in MLE-initiated TXT resets.
>>> + *
>>> + * TXT Specification
>>> + * Appendix I ACM Error Codes
>>> + */
>>> +#define SL_ERROR_GENERIC        0xc0008001
>>> +#define SL_ERROR_TPM_INIT        0xc0008002
>>> +#define SL_ERROR_TPM_INVALID_LOG20    0xc0008003
>>> +#define SL_ERROR_TPM_LOGGING_FAILED    0xc0008004
>>> +#define SL_ERROR_REGION_STRADDLE_4GB    0xc0008005
>>> +#define SL_ERROR_TPM_EXTEND        0xc0008006
>>> +#define SL_ERROR_MTRR_INV_VCNT        0xc0008007
>>> +#define SL_ERROR_MTRR_INV_DEF_TYPE    0xc0008008
>>> +#define SL_ERROR_MTRR_INV_BASE        0xc0008009
>>> +#define SL_ERROR_MTRR_INV_MASK        0xc000800a
>>> +#define SL_ERROR_MSR_INV_MISC_EN    0xc000800b
>>> +#define SL_ERROR_INV_AP_INTERRUPT    0xc000800c
>>> +#define SL_ERROR_INTEGER_OVERFLOW    0xc000800d
>>> +#define SL_ERROR_HEAP_WALK        0xc000800e
>>> +#define SL_ERROR_HEAP_MAP        0xc000800f
>>> +#define SL_ERROR_REGION_ABOVE_4GB    0xc0008010
>>> +#define SL_ERROR_HEAP_INVALID_DMAR    0xc0008011
>>> +#define SL_ERROR_HEAP_DMAR_SIZE        0xc0008012
>>> +#define SL_ERROR_HEAP_DMAR_MAP        0xc0008013
>>> +#define SL_ERROR_HI_PMR_BASE        0xc0008014
>>> +#define SL_ERROR_HI_PMR_SIZE        0xc0008015
>>> +#define SL_ERROR_LO_PMR_BASE        0xc0008016
>>> +#define SL_ERROR_LO_PMR_MLE        0xc0008017
>>> +#define SL_ERROR_INITRD_TOO_BIG        0xc0008018
>>> +#define SL_ERROR_HEAP_ZERO_OFFSET    0xc0008019
>>> +#define SL_ERROR_WAKE_BLOCK_TOO_SMALL    0xc000801a
>>> +#define SL_ERROR_MLE_BUFFER_OVERLAP    0xc000801b
>>> +#define SL_ERROR_BUFFER_BEYOND_PMR    0xc000801c
>>> +#define SL_ERROR_OS_SINIT_BAD_VERSION    0xc000801d
>>> +#define SL_ERROR_EVENTLOG_MAP        0xc000801e
>>> +#define SL_ERROR_TPM_INVALID_ALGS    0xc000801f
>>> +#define SL_ERROR_TPM_EVENT_COUNT    0xc0008020
>>> +#define SL_ERROR_TPM_INVALID_EVENT    0xc0008021
>>> +#define SL_ERROR_INVALID_SLRT        0xc0008022
>>> +#define SL_ERROR_SLRT_MISSING_ENTRY    0xc0008023
>>> +#define SL_ERROR_SLRT_MAP        0xc0008024
>>> +
>>> +/*
>>> + * Secure Launch Defined Limits
>>> + */
>>> +#define TXT_MAX_CPUS        512
>>> +#define TXT_BOOT_STACK_SIZE    128
>>> +
>>> +/*
>>> + * Secure Launch event log entry type. The TXT specification defines the
>>> + * base event value as 0x400 for DRTM values.
>>> + */
>>> +#define TXT_EVTYPE_BASE            0x400
>>> +#define TXT_EVTYPE_SLAUNCH        (TXT_EVTYPE_BASE + 0x102)
>>> +#define TXT_EVTYPE_SLAUNCH_START    (TXT_EVTYPE_BASE + 0x103)
>>> +#define TXT_EVTYPE_SLAUNCH_END        (TXT_EVTYPE_BASE + 0x104)
>>> +
>>> +/*
>>> + * MLE scratch area offsets
>>> + */
>>> +#define SL_SCRATCH_AP_EBX        0
>>> +#define SL_SCRATCH_AP_JMP_OFFSET    4
>>> +#define SL_SCRATCH_AP_STACKS_OFFSET    8
>>> +
>>> +#ifndef __ASSEMBLY__
>>> +
>>> +#include <linux/io.h>
>>> +#include <linux/tpm.h>
>>> +#include <linux/tpm_eventlog.h>
>>> +
>>> +/*
>>> + * Secure Launch AP stack and monitor block
>>> + */
>>> +struct sl_ap_stack_and_monitor {
>>> +    u32 monitor;
>>> +    u32 cache_pad[15];
>>> +    u32 stack_pad[15];
>>> +    u32 apicid;
>>> +} __packed;
>>> +
>>> +/*
>>> + * Secure Launch AP wakeup information fetched in SMP boot code.
>>> + */
>>> +struct sl_ap_wake_info {
>>> +    u32 ap_wake_block;
>>> +    u32 ap_wake_block_size;
>>> +    u32 ap_jmp_offset;
>>> +    u32 ap_stacks_offset;
>>> +};
>>> +
>>
>>   Michal Camacho Romero: Move the following code section (matched in the black quotations) into the new header file include/linux/txt.h:
>>
>> """ [START]> +/*
>>> + * TXT heap extended data elements.
>>> + */
>>> +struct txt_heap_ext_data_element {
>>> +    u32 type;
>>> +    u32 size;
>>> +    /* Data */
>>> +} __packed;
>>> +
>>> +#define TXT_HEAP_EXTDATA_TYPE_END            0
>>> +
>>> +struct txt_heap_end_element {
>>> +    u32 type;
>>> +    u32 size;
>>> +} __packed;
>>> +
>>> +#define TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR        5
>>> +
>>> +struct txt_heap_event_log_element {
>>> +    u64 event_log_phys_addr;
>>> +} __packed;
>>> +
>>> +#define TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1    8
>>> +
>>> +struct txt_heap_event_log_pointer2_1_element {
>>> +    u64 phys_addr;
>>> +    u32 allocated_event_container_size;
>>> +    u32 first_record_offset;
>>> +    u32 next_record_offset;
>>> +} __packed;
>>> +
>>> +/*
>>> + * Secure Launch defined OS/MLE TXT Heap table
>>> + */
>>> +struct txt_os_mle_data {
>>> +    u32 version;
>>> +    u32 reserved;
>>> +    u64 slrt;
>>> +    u64 txt_info;
>>> +    u32 ap_wake_block;
>>> +    u32 ap_wake_block_size;
>>> +    u8 mle_scratch[64];
>>> +} __packed;
>>> +
>>> +/*
>>> + * TXT specification defined BIOS data TXT Heap table
>>> + */
>>> +struct txt_bios_data {
>>> +    u32 version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */
>>> +    u32 bios_sinit_size;
>>> +    u64 reserved1;
>>> +    u64 reserved2;
>>> +    u32 num_logical_procs;
>>
>>
>> Michal Camacho Romero: Put the comment /* Versions >= 5 with updates in version 6 */ under the sinit_flags struct member. The sinit_flags member exists in the BiosData struct since version 3.
> 
> Ack
> 
>>
>>> +    /* Versions >= 5 with updates in version 6 */
>>
>>
>>> +    u32 sinit_flags;
>>> +    u32 mle_flags;
>>> +    /* Versions >= 4 */
>>> +    /* Ext Data Elements */
>>> +} __packed;
>>> +
>>> +/*
>>> + * TXT specification defined OS/SINIT TXT Heap table
>>> + */
>>> +struct txt_os_sinit_data {
>>> +    u32 version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */
>>> +    u32 flags;
>>> +    u64 mle_ptab;
>>> +    u64 mle_size;
>>> +    u64 mle_hdr_base;
>>> +    u64 vtd_pmr_lo_base;
>>> +    u64 vtd_pmr_lo_size;
>>> +    u64 vtd_pmr_hi_base;
>>> +    u64 vtd_pmr_hi_size;
>>> +    u64 lcp_po_base;
>>> +    u64 lcp_po_size;
>>> +    u32 capabilities;
>>> +    /* Version = 5 */
>>> +    u64 efi_rsdt_ptr;
>>> +    /* Versions >= 6 */
>>> +    /* Ext Data Elements */
>>> +} __packed;
>>> +
>>> +/*
>>> + * TXT specification defined SINIT/MLE TXT Heap table
>>> + */
>>> +struct txt_sinit_mle_data {
>>> +    u32 version;             /* Current values are 6 through 9 */
>>> +    /* Versions <= 8 */
>>> +    u8 bios_acm_id[20];
>>> +    u32 edx_senter_flags;
>>> +    u64 mseg_valid;
>>> +    u8 sinit_hash[20];
>>> +    u8 mle_hash[20];
>>> +    u8 stm_hash[20];
>>> +    u8 lcp_policy_hash[20];
>>> +    u32 lcp_policy_control;
>>> +    /* Versions >= 7 */
>>> +    u32 rlp_wakeup_addr;
>>> +    u32 reserved;
>>> +    u32 num_of_sinit_mdrs;
>>> +    u32 sinit_mdrs_table_offset;
>>> +    u32 sinit_vtd_dmar_table_size;
>>> +    u32 sinit_vtd_dmar_table_offset;
>>> +    /* Versions >= 8 */
>>> +    u32 processor_scrtm_status;
>>> +    /* Versions >= 9 */
>>> +    /* Ext Data Elements */
>>> +} __packed;
>>> +
>>> +/*
>>> + * TXT data reporting structure for memory types
>>> + */
>>> +struct txt_sinit_memory_descriptor_record {
>>> +    u64 address;
>>> +    u64 length;
>>> +    u8 type;
>>> +    u8 reserved[7];
>>> +} __packed;
>>> +
>>> +/*
>>> + * TXT data structure used by a responsive local processor (RLP) to start
>>> + * execution in response to a GETSEC[WAKEUP].
>>> + */
>>> +struct smx_rlp_mle_join {
>>> +    u32 rlp_gdt_limit;
>>> +    u32 rlp_gdt_base;
>>> +    u32 rlp_seg_sel;     /* cs (ds, es, ss are seg_sel+8) */
>>> +    u32 rlp_entry_point; /* phys addr */
>>> +} __packed;
>>> +
>>> +/*
>>> + * TPM event log structures defined in both the TXT specification and
>>> + * the TCG documentation.
>>> + */
>>> +#define TPM_EVTLOG_SIGNATURE "TXT Event Container"
>>> +
>>> +struct tpm_event_log_header {
>>> +    char signature[20];
>>> +    char reserved[12];
>>> +    u8 container_ver_major;
>>> +    u8 container_ver_minor;
>>> +    u8 pcr_event_ver_major;
>>> +    u8 pcr_event_ver_minor;
>>> +    u32 container_size;
>>> +    u32 pcr_events_offset;
>>> +    u32 next_event_offset;
>>> +    /* PCREvents[] */
>>> +} __packed;
>>> +
> 
> Should the following accessor functions be moved? They are specific to an environment (like protected mode paging off or x64 identity mapped) and thus this implementation.
Michal Camacho Romero: Yes. As these functions will be used to access the specific regions of the Intel TXT Heap, so they should be located at the same
place as all of the TXT-related registers and structures.> 
>>> +/*
>>> + * Functions to extract data from the Intel TXT Heap Memory. The layout
>>> + * of the heap is as follows:
>>> + *  +----------------------------+
>>> + *  | Size Bios Data table (u64) |
>>> + *  +----------------------------+
>>> + *  | Bios Data table            |
>>> + *  +----------------------------+
>>> + *  | Size OS MLE table (u64)    |
>>> + *  +----------------------------+
>>> + *  | OS MLE table               |
>>> + *  +--------------------------- +
>>> + *  | Size OS SINIT table (u64)  |
>>> + *  +----------------------------+
>>> + *  | OS SINIT table             |
>>> + *  +----------------------------+
>>> + *  | Size SINIT MLE table (u64) |
>>> + *  +----------------------------+
>>> + *  | SINIT MLE table            |
>>> + *  +----------------------------+
>>> + *
>>> + *  NOTE: the table size fields include the 8 byte size field itself.
>>> + */
>>> +static inline u64 txt_bios_data_size(void *heap)
>>> +{
>>> +    return *((u64 *)heap);
>>> +}
>>> +
>>> +static inline void *txt_bios_data_start(void *heap)
>>> +{
>>> +    return heap + sizeof(u64);
>>> +}
>>> +
>>> +static inline u64 txt_os_mle_data_size(void *heap)
>>> +{
>>> +    return *((u64 *)(heap + txt_bios_data_size(heap)));
>>> +}
>>> +
>>> +static inline void *txt_os_mle_data_start(void *heap)
>>> +{
>>> +    return heap + txt_bios_data_size(heap) + sizeof(u64);
>>> +}
>>> +
>>> +static inline u64 txt_os_sinit_data_size(void *heap)
>>> +{
>>> +    return *((u64 *)(heap + txt_bios_data_size(heap) +
>>> +            txt_os_mle_data_size(heap)));
>>> +}
>>> +
>>> +static inline void *txt_os_sinit_data_start(void *heap)
>>> +{
>>> +    return heap + txt_bios_data_size(heap) +
>>> +        txt_os_mle_data_size(heap) + sizeof(u64);
>>> +}
>>> +
>>> +static inline u64 txt_sinit_mle_data_size(void *heap)
>>> +{
>>> +    return *((u64 *)(heap + txt_bios_data_size(heap) +
>>> +            txt_os_mle_data_size(heap) +
>>> +            txt_os_sinit_data_size(heap)));
>>> +}
>>> +
>>> +static inline void *txt_sinit_mle_data_start(void *heap)
>>> +{
>>> +    return heap + txt_bios_data_size(heap) +
>>> +        txt_os_mle_data_size(heap) +
>>> +        txt_os_sinit_data_size(heap) + sizeof(u64);
>>> +}
>>> +
>>> +#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
>>> +
>>> +/*
>>> + * TPM event logging functions.
>>> + */
>>> +
>>> +/*
>>> + * Find the TPM v2 event log element in the TXT heap. This element contains
>>> + * the information about the size and location of the DRTM event log. Note
>>> + * this is a TXT specific structure.
>>> + *
>>> + * See:
>>> + *   Intel Trusted Execution Technology - Measured Launch Environment Developer's Guide - Appendix C.
>>> + */
>>> +static inline struct txt_heap_event_log_pointer2_1_element*
>>> +tpm2_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
>>> +{
>>> +    struct txt_heap_ext_data_element *ext_elem;
>>> +
>>> +    /* The extended element array as at the end of this table */
>>> +    ext_elem = (struct txt_heap_ext_data_element *)
>>> +        ((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));
>>> +
>>> +    while (ext_elem->type != TXT_HEAP_EXTDATA_TYPE_END) {
>>> +        if (ext_elem->type == TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1) {
>>> +            return (struct txt_heap_event_log_pointer2_1_element *)
>>> +                ((u8 *)ext_elem + sizeof(struct txt_heap_ext_data_element));
>>> +        }
>>> +        ext_elem = (struct txt_heap_ext_data_element *)
>>> +                ((u8 *)ext_elem + ext_elem->size);
>>> +    }
>>> +
>>> +    return NULL;
>>> +}
>>> +
>>> +/*
>>> + * Log a TPM v1 formatted event to the given DRTM event log.
>>> + */
>>> +static inline int tpm_log_event(void *evtlog_base, u32 evtlog_size,
>>> +                u32 event_size, void *event)
>>> +{
>>> +    struct tpm_event_log_header *evtlog =
>>> +        (struct tpm_event_log_header *)evtlog_base;
>>> +
>>> +    if (memcmp(evtlog->signature, TPM_EVTLOG_SIGNATURE,
>>> +           sizeof(TPM_EVTLOG_SIGNATURE)))
>>> +        return -EINVAL;
>>> +
>>> +    if (evtlog->container_size > evtlog_size)
>>> +        return -EINVAL;
>>> +
>>> +    if (evtlog->next_event_offset + event_size > evtlog->container_size)
>>> +        return -E2BIG;
>>> +
>>> +    memcpy(evtlog_base + evtlog->next_event_offset, event, event_size);
>>> +    evtlog->next_event_offset += event_size;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +/*
>>> + * Log a TPM v2 formatted event to the given DRTM event log.
>>> + */
>>> +static inline int tpm2_log_event(struct txt_heap_event_log_pointer2_1_element *elem,
>>> +                 void *evtlog_base, u32 evtlog_size,
>>> +                 u32 event_size, void *event)
>>> +{
>>> +    struct tcg_pcr_event *header =
>>> +        (struct tcg_pcr_event *)evtlog_base;
>>> +
>>> +    /* Has to be at least big enough for the signature */
>>> +    if (header->event_size < sizeof(TCG_SPECID_SIG))
>>> +        return -EINVAL;
>>> +
>>> +    if (memcmp((u8 *)header + sizeof(struct tcg_pcr_event),
>>> +           TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
>>> +        return -EINVAL;
>>> +
>>> +    if (elem->allocated_event_container_size > evtlog_size)
>>> +        return -EINVAL;
>>> +
>>> +    if (elem->next_record_offset + event_size >
>>> +        elem->allocated_event_container_size)
>>> +        return -E2BIG;
>>> +
>>> +    memcpy(evtlog_base + elem->next_record_offset, event, event_size);
>>> +    elem->next_record_offset += event_size;
>>> +
>>> +    return 0;
>>> +}
>>> +
>> """[END]
>>
>>> +/*
>>> + * External functions available in mainline kernel.
>>> + */
>>> +void slaunch_setup_txt(void);
>>> +void slaunch_fixup_jump_vector(void);
>>> +u32 slaunch_get_flags(void);
>>> +struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
>>> +struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
>>> +void __noreturn slaunch_txt_reset(void __iomem *txt,
>>> +                     const char *msg, u64 error);
>>> +void slaunch_finalize(int do_sexit);
>>> +
>>> +static inline bool slaunch_is_txt_launch(void)
>>> +{
>>> +    u32 mask = SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
>>> +
>>> +    return (slaunch_get_flags() & mask) == mask;
>>> +}
>>> +
>>> +#else
>>> +
>>> +static inline void slaunch_setup_txt(void)
>>> +{
>>> +}
>>> +
>>> +static inline void slaunch_fixup_jump_vector(void)
>>> +{
>>> +}
>>> +
>>> +static inline u32 slaunch_get_flags(void)
>>> +{
>>> +    return 0;
>>> +}
>>> +
>>> +static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
>>> +{
>>> +    return dmar;
>>> +}
>>> +
>>> +static inline void slaunch_finalize(int do_sexit)
>>> +{
>>> +}
>>> +
>>> +static inline bool slaunch_is_txt_launch(void)
>>> +{
>>> +    return false;
>>> +}
>>> +
>>> +#endif /* !IS_ENABLED(CONFIG_SECURE_LAUNCH) */
>>> +
>>> +#endif /* !__ASSEMBLY */
>>> +
>>> +#endif /* _LINUX_SLAUNCH_H */
>> Regards,
>> Michal Camacho Romero (michal.camacho.romero@linux.intel.com)
> 
> Thank you for your feedback.
> Ross
> 
> 
Regards,
Michal Camacho Romero (michal.camacho.romero@linux.intel.com)
Re: [PATCH v14 04/19] x86: Secure Launch main header file
Posted by Huang, Kai 7 months, 4 weeks ago
On Mon, 2025-04-21 at 09:26 -0700, Ross Philipson wrote:
> Introduce the main Secure Launch header file used in the early SL stub
> and the early setup code.
> 
> This header file contains the following categories:
>  - Secure Launch implementation specific structures and definitions.
>  - Intel TXT architecture specific DRTM structures, definitions and functions
> used by Secure Launch.
>  - DRTM TPM event logging definitions and helper functions.

Looking at the actual code in this patch, seems >90% code in the
<linux/slaunch.h> is Intel specific, e.g., TXT specific macro/structure
definitions.  It doesn't seem to be the right way to organize the code.

E.g., following the current pattern, when we need to add support for another TXT
similar vendor-specific technology, we will need to add yet-another set of
macro/structure definitions for that technology to <linux/slaunch.h> as well.

That would be a giant mess IMHO.

Could we make <linux/slaunch.h> only contain the common things, and move Intel
specific things to some x86 header(s), e.g., <asm/intel-txt.h> or <asm/txt.h>?


[...]

> +/*
> + * External functions available in mainline kernel.
> + */
> +void slaunch_setup_txt(void);
> +void slaunch_fixup_jump_vector(void);
> +u32 slaunch_get_flags(void);
> +struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
> +struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
> +void __noreturn slaunch_txt_reset(void __iomem *txt,
> +					 const char *msg, u64 error);
> +void slaunch_finalize(int do_sexit);
> +
> +static inline bool slaunch_is_txt_launch(void)
> +{
> +	u32 mask = SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
> +
> +	return (slaunch_get_flags() & mask) == mask;
> +}
> +
> +#else
> +
> +static inline void slaunch_setup_txt(void)
> +{
> +}
> +
> +static inline void slaunch_fixup_jump_vector(void)
> +{
> +}
> +
> +static inline u32 slaunch_get_flags(void)
> +{
> +	return 0;
> +}
> +
> +static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
> +{
> +	return dmar;
> +}
> +
> +static inline void slaunch_finalize(int do_sexit)
> +{
> +}
> +
> +static inline bool slaunch_is_txt_launch(void)
> +{
> +	return false;
> +}
> 

.. btw it's not clear which part of the code is common code.  

Looking at the abvoe code, it seems those functions are common functions called
from common code.  E.g., slaunch_finalize() is called from kernel/kexec_core.c,
which means it is a concept in the kernel common code and must be available for
all ARCHs (I haven't read how other functions are called, though).

But the name slaunch_setup_txt(), slaunch_get_dmar_table() and
slaunch_is_txt_launch() are quite Intel specific.  So it seems to me this patch
_tries_ to support Secure Launch at the arch agnostic level but it doesn't do a
good job at the abstraction?
Re: [PATCH v14 04/19] x86: Secure Launch main header file
Posted by ross.philipson@oracle.com 7 months, 4 weeks ago
On 4/24/25 5:29 AM, Huang, Kai wrote:
> On Mon, 2025-04-21 at 09:26 -0700, Ross Philipson wrote:
>> Introduce the main Secure Launch header file used in the early SL stub
>> and the early setup code.
>>
>> This header file contains the following categories:
>>   - Secure Launch implementation specific structures and definitions.
>>   - Intel TXT architecture specific DRTM structures, definitions and functions
>> used by Secure Launch.
>>   - DRTM TPM event logging definitions and helper functions.
> 
> Looking at the actual code in this patch, seems >90% code in the
> <linux/slaunch.h> is Intel specific, e.g., TXT specific macro/structure
> definitions.  It doesn't seem to be the right way to organize the code.
> 
> E.g., following the current pattern, when we need to add support for another TXT
> similar vendor-specific technology, we will need to add yet-another set of
> macro/structure definitions for that technology to <linux/slaunch.h> as well.
> 
> That would be a giant mess IMHO.
> 
> Could we make <linux/slaunch.h> only contain the common things, and move Intel
> specific things to some x86 header(s), e.g., <asm/intel-txt.h> or <asm/txt.h>?

Yes this looks to be a good idea. I think it has been something we have 
thought of before. We will look into it.


> 
> 
> [...]
> 
>> +/*
>> + * External functions available in mainline kernel.
>> + */
>> +void slaunch_setup_txt(void);
>> +void slaunch_fixup_jump_vector(void);
>> +u32 slaunch_get_flags(void);
>> +struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
>> +struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
>> +void __noreturn slaunch_txt_reset(void __iomem *txt,
>> +					 const char *msg, u64 error);
>> +void slaunch_finalize(int do_sexit);
>> +
>> +static inline bool slaunch_is_txt_launch(void)
>> +{
>> +	u32 mask = SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
>> +
>> +	return (slaunch_get_flags() & mask) == mask;
>> +}
>> +
>> +#else
>> +
>> +static inline void slaunch_setup_txt(void)
>> +{
>> +}
>> +
>> +static inline void slaunch_fixup_jump_vector(void)
>> +{
>> +}
>> +
>> +static inline u32 slaunch_get_flags(void)
>> +{
>> +	return 0;
>> +}
>> +
>> +static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
>> +{
>> +	return dmar;
>> +}
>> +
>> +static inline void slaunch_finalize(int do_sexit)
>> +{
>> +}
>> +
>> +static inline bool slaunch_is_txt_launch(void)
>> +{
>> +	return false;
>> +}
>>
> 
> .. btw it's not clear which part of the code is common code.
> 
> Looking at the abvoe code, it seems those functions are common functions called
> from common code.  E.g., slaunch_finalize() is called from kernel/kexec_core.c,
> which means it is a concept in the kernel common code and must be available for
> all ARCHs (I haven't read how other functions are called, though).
> 
> But the name slaunch_setup_txt(), slaunch_get_dmar_table() and
> slaunch_is_txt_launch() are quite Intel specific.  So it seems to me this patch
> _tries_ to support Secure Launch at the arch agnostic level but it doesn't do a
> good job at the abstraction?

If we do what you suggest, I think these ambiguities will go away.

Thank you,
Ross