kexec.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v15 00/28] x86: Secure Launch support for Intel TXT
@ 2025-12-15 23:32 Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 01/28] tpm: Initial step to reorganize TPM public headers Ross Philipson
                   ` (28 more replies)
  0 siblings, 29 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Secure Launch is a vendor-neutral approach to implementing TGC Dynamic
Root of Trust (DRTM) support in the kernel. This is complementary to
better known Static Root of Trust (SRTM) schemes such as UEFI SecureBoot.

This series provides the common infrastructure along with Intel TXT
support, without needing the tboot exokernel. Support for AMD SKINIT is
pending the common infrastructure getting nailed down, and ARM are
looking to build on it too.

Originally, tboot were approached to see if they'd take support for
other vendors, but they elected not to. Hence this approach instead.

Work is being coordinated by the Trenchboot project, https://trenchboot.org/,
organising Secure Launch support for upstream open source projects including
Grub, iPXE and Xen. The goal of the Trenchboot project is to make DTRM easy
to use.  e.g. for Grub, it's simply adding "slaunch" as a command in the boot
stanza.  See https://trenchboot.org/user-docs/QUICKSTART/#linux-quick-start-guide
for more details

Patch set based on commit:
torvalds/master/fd57572253bc356330dbe5b233c2e1d8426c66fd

Depends on v3 of the following TPM patch set (note this patch
set is being actively worked on separately):
[PATCH v3 00/10]  tpm: Decouple Trenchboot dependencies
Message ID: 20250929194832.2913286-1-jarkko@kernel.org

Finally we would like to thank everyone for their input and
assistance. It has all been very helpful in improving the quality of
our solution and in reviewing/strengthening our security posture.

Thanks
Ross Philipson and Daniel P. Smith

Changes in v15:

 - Rewriting and reformatting of the cover letter, commit message and
   code comments per requests from maintainers.
 - Introduction of a early TPM driver in the x86 setup kernel to allow
   TPM extend command very early in the boot.
 - Remove previous TPM extending architecture that attempted to update
   the TPM PCRs later in the boot process.
 - Split slaunch.h into 2 files, with a new txt.h. The former contains
   platform agnostic definitions for the SL feature. The new txt.h file
   contains Intel TXT definitions from the public specs.
 - Split TPM headers up following the specifications where the
   technologies are defined.
 - Include set of split up TPM header files to allow TPM driver reuse
   in other environments (e.g. early kernel, x86).
 - Fix code formatting and type-os.


Alec Brown (1):
  tpm: Remove main TPM header from TPM event log header

Daniel P. Smith (6):
  tpm/tpm_tis: Close all localities
  tpm/tpm_tis: Address positive localities in tpm_tis_request_locality()
  Documentation/x86: Secure Launch kernel documentation
  x86: Add early SHA-1 support for Secure Launch early measurements
  x86: Add early SHA-256 support for Secure Launch early measurements
  x86: Secure Launch late initcall platform module

Ross Philipson (21):
  tpm: Initial step to reorganize TPM public headers
  tpm: Move TPM1 specific definitions and functions to new headers
  tpm: Move TPM2 specific definitions and functions to new headers
  tpm: Move TPM common base definitions to new public common header
  tpm: Move platform specific definitions to the new PTP header
  tpm: Add TPM buffer support header for standalone reuse
  tpm/tpm_tis: Allow locality to be set to a different value
  tpm/sysfs: Show locality used by kernel
  x86: Secure Launch Kconfig
  x86: Secure Launch Resource Table header file
  x86: Secure Launch main header file
  x86/txt: Intel Trusted eXecution Technology (TXT) definitions
  x86/tpm: Early TPM PCR extending driver
  x86/msr: Add variable MTRR base/mask and x2apic ID registers
  x86/boot: Place TXT MLE header in the kernel_info section
  x86: Secure Launch kernel early boot stub
  x86: Secure Launch kernel late boot stub
  x86: Secure Launch SMP bringup support
  kexec: Secure Launch kexec SEXIT support
  x86/reboot: Secure Launch SEXIT support on reboot paths
  x86/efi: EFI stub DRTM launch support for Secure Launch

 Documentation/arch/x86/boot.rst               |  21 +
 Documentation/security/index.rst              |   1 +
 .../security/launch-integrity/index.rst       |  11 +
 .../security/launch-integrity/principles.rst  | 308 +++++++
 .../secure_launch_details.rst                 | 587 +++++++++++++
 .../secure_launch_overview.rst                | 240 ++++++
 arch/x86/Kconfig                              |  14 +
 arch/x86/boot/compressed/Makefile             |   8 +
 arch/x86/boot/compressed/early_tpm_extend.c   | 601 ++++++++++++++
 arch/x86/boot/compressed/head_64.S            |  29 +
 arch/x86/boot/compressed/kernel_info.S        |  50 +-
 arch/x86/boot/compressed/sha1.c               |   7 +
 arch/x86/boot/compressed/sha256.c             |   6 +
 arch/x86/boot/compressed/sl_main.c            | 638 +++++++++++++++
 arch/x86/boot/compressed/sl_stub.S            | 770 ++++++++++++++++++
 arch/x86/boot/compressed/tpm.h                |  42 +
 arch/x86/boot/compressed/vmlinux.lds.S        |   7 +
 arch/x86/include/asm/msr-index.h              |   5 +
 arch/x86/include/asm/realmode.h               |   3 +
 arch/x86/include/asm/txt.h                    | 330 ++++++++
 arch/x86/include/uapi/asm/bootparam.h         |   1 +
 arch/x86/kernel/Makefile                      |   2 +
 arch/x86/kernel/asm-offsets.c                 |  20 +
 arch/x86/kernel/reboot.c                      |  14 +
 arch/x86/kernel/setup.c                       |   3 +
 arch/x86/kernel/slaunch.c                     | 615 ++++++++++++++
 arch/x86/kernel/slmodule.c                    | 348 ++++++++
 arch/x86/kernel/smpboot.c                     |  47 +-
 arch/x86/realmode/init.c                      |   8 +
 arch/x86/realmode/rm/header.S                 |   3 +
 arch/x86/realmode/rm/trampoline_64.S          |  32 +
 drivers/char/tpm/tpm-buf.c                    |  10 +-
 drivers/char/tpm/tpm-chip.c                   |  34 +-
 drivers/char/tpm/tpm-sysfs.c                  |  10 +
 drivers/char/tpm/tpm.h                        | 180 +---
 drivers/char/tpm/tpm1-cmd.c                   |  18 +-
 drivers/char/tpm/tpm1_structs.h               |  97 +++
 drivers/char/tpm/tpm2-cmd.c                   |  32 +-
 drivers/char/tpm/tpm2-space.c                 |  13 -
 drivers/char/tpm/tpm2_structs.h               |  58 ++
 drivers/char/tpm/tpm_tis_core.c               |  21 +-
 drivers/char/tpm/tpm_tis_core.h               |  64 +-
 drivers/firmware/efi/libstub/efistub.h        |   8 +
 drivers/firmware/efi/libstub/x86-stub.c       | 100 +++
 drivers/iommu/intel/dmar.c                    |   4 +
 include/keys/trusted_tpm.h                    |   1 -
 include/linux/slaunch.h                       | 251 ++++++
 include/linux/slr_table.h                     | 308 +++++++
 include/linux/tpm.h                           | 240 +-----
 include/linux/tpm1.h                          |  87 ++
 include/linux/tpm2.h                          | 247 ++++++
 include/linux/tpm_buf.h                       |  57 ++
 include/linux/tpm_command.h                   |  30 -
 include/linux/tpm_common.h                    |  99 +++
 include/linux/tpm_eventlog.h                  |   4 +-
 include/linux/tpm_ptp.h                       | 139 ++++
 kernel/kexec_core.c                           |   8 +
 security/keys/trusted-keys/trusted_tpm1.c     |   1 -
 security/keys/trusted-keys/trusted_tpm2.c     |   1 -
 59 files changed, 6319 insertions(+), 574 deletions(-)
 create mode 100644 Documentation/security/launch-integrity/index.rst
 create mode 100644 Documentation/security/launch-integrity/principles.rst
 create mode 100644 Documentation/security/launch-integrity/secure_launch_details.rst
 create mode 100644 Documentation/security/launch-integrity/secure_launch_overview.rst
 create mode 100644 arch/x86/boot/compressed/early_tpm_extend.c
 create mode 100644 arch/x86/boot/compressed/sha1.c
 create mode 100644 arch/x86/boot/compressed/sha256.c
 create mode 100644 arch/x86/boot/compressed/sl_main.c
 create mode 100644 arch/x86/boot/compressed/sl_stub.S
 create mode 100644 arch/x86/boot/compressed/tpm.h
 create mode 100644 arch/x86/include/asm/txt.h
 create mode 100644 arch/x86/kernel/slaunch.c
 create mode 100644 arch/x86/kernel/slmodule.c
 create mode 100644 drivers/char/tpm/tpm1_structs.h
 create mode 100644 drivers/char/tpm/tpm2_structs.h
 create mode 100644 include/linux/slaunch.h
 create mode 100644 include/linux/slr_table.h
 create mode 100644 include/linux/tpm1.h
 create mode 100644 include/linux/tpm2.h
 create mode 100644 include/linux/tpm_buf.h
 delete mode 100644 include/linux/tpm_command.h
 create mode 100644 include/linux/tpm_common.h
 create mode 100644 include/linux/tpm_ptp.h

-- 
2.43.7



^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH v15 01/28] tpm: Initial step to reorganize TPM public headers
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 02/28] tpm: Move TPM1 specific definitions and functions to new headers Ross Philipson
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Replace the existing public header tpm_command.h with the first two
new public headers tpm1.h and tpm_common.h. In addition, related
definitions in tpm1_cmd.c were moved to the new tpm1.h.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 drivers/char/tpm/tpm-buf.c                |  3 +-
 drivers/char/tpm/tpm1-cmd.c               | 13 +-----
 include/keys/trusted_tpm.h                |  1 -
 include/linux/tpm.h                       |  3 ++
 include/linux/tpm1.h                      | 55 +++++++++++++++++++++++
 include/linux/tpm_command.h               | 30 -------------
 include/linux/tpm_common.h                | 22 +++++++++
 security/keys/trusted-keys/trusted_tpm1.c |  1 -
 security/keys/trusted-keys/trusted_tpm2.c |  1 -
 9 files changed, 82 insertions(+), 47 deletions(-)
 create mode 100644 include/linux/tpm1.h
 delete mode 100644 include/linux/tpm_command.h
 create mode 100644 include/linux/tpm_common.h

diff --git a/drivers/char/tpm/tpm-buf.c b/drivers/char/tpm/tpm-buf.c
index 1cb649938c01..dae23e6de269 100644
--- a/drivers/char/tpm/tpm-buf.c
+++ b/drivers/char/tpm/tpm-buf.c
@@ -3,7 +3,6 @@
  * Handling of TPM command and other buffers.
  */
 
-#include <linux/tpm_command.h>
 #include <linux/module.h>
 #include <linux/tpm.h>
 
@@ -296,7 +295,7 @@ void tpm1_buf_append_extend(struct tpm_buf *buf, u32 pcr_idx, const u8 *hash)
 	if (buf->flags & TPM_BUF_INVALID)
 		return;
 
-	if (!tpm1_buf_is_command(buf, TPM_ORD_EXTEND)) {
+	if (!tpm1_buf_is_command(buf, TPM_ORD_PCR_EXTEND)) {
 		WARN(1, "tpm_buf: invalid TPM_Extend command\n");
 		buf->flags |= TPM_BUF_INVALID;
 		return;
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index bc156d7d59f2..f29827b454d2 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -18,12 +18,9 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
-#include <linux/tpm_command.h>
 #include <linux/tpm_eventlog.h>
 #include "tpm.h"
 
-#define TPM_MAX_ORDINAL 243
-
 /*
  * Array with one entry per ordinal defining the maximum amount
  * of time the chip could take to return the result.  The ordinal
@@ -308,9 +305,6 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
 		return duration;
 }
 
-#define TPM_ORD_STARTUP 153
-#define TPM_ST_CLEAR 1
-
 /**
  * tpm1_startup() - turn on the TPM
  * @chip: TPM chip to use
@@ -478,7 +472,6 @@ int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
 	return rc;
 }
 
-#define TPM_ORD_GET_CAP 101
 ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
 		    const char *desc, size_t min_cap_length)
 {
@@ -574,7 +567,6 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 	return rc;
 }
 
-#define TPM_ORD_PCRREAD 21
 int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
 {
 	int rc;
@@ -584,7 +576,7 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
 		return -ENOMEM;
 
 	tpm_buf_init(buf, TPM_BUFSIZE);
-	tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCRREAD);
+	tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_READ);
 	tpm_buf_append_u32(buf, pcr_idx);
 
 	rc = tpm_transmit_cmd(chip, buf, TPM_DIGEST_SIZE,
@@ -599,7 +591,6 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
 	return rc;
 }
 
-#define TPM_ORD_CONTINUE_SELFTEST 83
 /**
  * tpm1_continue_selftest() - run TPM's selftest
  * @chip: TPM chip to use
@@ -716,8 +707,6 @@ int tpm1_auto_startup(struct tpm_chip *chip)
 	return rc;
 }
 
-#define TPM_ORD_SAVESTATE 152
-
 /**
  * tpm1_pm_suspend() - pm suspend handler
  * @chip: TPM chip to use.
diff --git a/include/keys/trusted_tpm.h b/include/keys/trusted_tpm.h
index 0fadc6a4f166..3a0fa3bc8454 100644
--- a/include/keys/trusted_tpm.h
+++ b/include/keys/trusted_tpm.h
@@ -3,7 +3,6 @@
 #define __TRUSTED_TPM_H
 
 #include <keys/trusted-type.h>
-#include <linux/tpm_command.h>
 
 extern struct trusted_key_ops trusted_key_tpm_ops;
 
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 8da49e8769d5..ef81e0b59657 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -25,6 +25,9 @@
 #include <crypto/hash_info.h>
 #include <crypto/aes.h>
 
+#include "tpm_common.h"
+#include "tpm1.h"
+
 #define TPM_DIGEST_SIZE		20	/* Max TPM v1.2 PCR size */
 #define TPM_HEADER_SIZE		10
 #define TPM_BUFSIZE		4096
diff --git a/include/linux/tpm1.h b/include/linux/tpm1.h
new file mode 100644
index 000000000000..54c6c211eb9e
--- /dev/null
+++ b/include/linux/tpm1.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ * Debora Velarde <dvelarde@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+#ifndef __LINUX_TPM1_H__
+#define __LINUX_TPM1_H__
+
+/*
+ * TPM 1.2 Main Specification
+ * https://trustedcomputinggroup.org/resource/tpm-main-specification/
+ */
+
+/* Command TAGS */
+enum tpm_command_tags {
+	TPM_TAG_RQU_COMMAND		= 193,
+	TPM_TAG_RQU_AUTH1_COMMAND	= 194,
+	TPM_TAG_RQU_AUTH2_COMMAND	= 195,
+	TPM_TAG_RSP_COMMAND		= 196,
+	TPM_TAG_RSP_AUTH1_COMMAND	= 197,
+	TPM_TAG_RSP_AUTH2_COMMAND	= 198,
+};
+
+/* Command Ordinals */
+enum tpm_command_ordinals {
+	TPM_ORD_CONTINUE_SELFTEST	= 83,
+	TPM_ORD_GET_CAP			= 101,
+	TPM_ORD_GET_RANDOM		= 70,
+	TPM_ORD_PCR_EXTEND		= 20,
+	TPM_ORD_PCR_READ		= 21,
+	TPM_ORD_OSAP			= 11,
+	TPM_ORD_OIAP			= 10,
+	TPM_ORD_SAVESTATE		= 152,
+	TPM_ORD_SEAL			= 23,
+	TPM_ORD_STARTUP			= 153,
+	TPM_ORD_UNSEAL			= 24,
+};
+
+/* Other constants */
+#define SRKHANDLE                       0x40000000
+#define TPM_NONCE_SIZE                  20
+#define TPM_ST_CLEAR			1
+
+#endif
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
deleted file mode 100644
index 02038972a05f..000000000000
--- a/include/linux/tpm_command.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __LINUX_TPM_COMMAND_H__
-#define __LINUX_TPM_COMMAND_H__
-
-/*
- * TPM Command constants from specifications at
- * http://www.trustedcomputinggroup.org
- */
-
-/* Command TAGS */
-#define TPM_TAG_RQU_COMMAND             193
-#define TPM_TAG_RQU_AUTH1_COMMAND       194
-#define TPM_TAG_RQU_AUTH2_COMMAND       195
-#define TPM_TAG_RSP_COMMAND             196
-#define TPM_TAG_RSP_AUTH1_COMMAND       197
-#define TPM_TAG_RSP_AUTH2_COMMAND       198
-
-/* Command Ordinals */
-#define TPM_ORD_OIAP                    10
-#define TPM_ORD_OSAP                    11
-#define TPM_ORD_EXTEND			20
-#define TPM_ORD_SEAL                    23
-#define TPM_ORD_UNSEAL                  24
-#define TPM_ORD_GET_RANDOM              70
-
-/* Other constants */
-#define SRKHANDLE                       0x40000000
-#define TPM_NONCE_SIZE                  20
-
-#endif
diff --git a/include/linux/tpm_common.h b/include/linux/tpm_common.h
new file mode 100644
index 000000000000..b8be669913dd
--- /dev/null
+++ b/include/linux/tpm_common.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ * Debora Velarde <dvelarde@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+#ifndef __LINUX_TPM_COMMON_H__
+#define __LINUX_TPM_COMMON_H__
+
+#define TPM_MAX_ORDINAL 243
+
+#endif
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 6e6a9fb48e63..3717a06a5212 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -17,7 +17,6 @@
 #include <keys/trusted-type.h>
 #include <linux/key-type.h>
 #include <linux/tpm.h>
-#include <linux/tpm_command.h>
 
 #include <keys/trusted_tpm.h>
 
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 0a99bd051a25..e6000c71eeb6 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/err.h>
 #include <linux/tpm.h>
-#include <linux/tpm_command.h>
 
 #include <keys/trusted-type.h>
 #include <keys/trusted_tpm.h>
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 02/28] tpm: Move TPM1 specific definitions and functions to new headers
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 01/28] tpm: Initial step to reorganize TPM public headers Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 03/28] tpm: Move TPM2 " Ross Philipson
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

This gathers all the TPM1 definitions and structures into two separate
header files (public tpm1.h and private tpm1_structs.h). The definitions
moved to these files correspond to the TCG specification for TPM 1 family:

TPM 1.2 Main Specification
 -  https://trustedcomputinggroup.org/resource/tpm-main-specification/

Note that the structures were pulled into tpm1_structs.h to allow their
external reuse.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 drivers/char/tpm/tpm.h          | 98 +--------------------------------
 drivers/char/tpm/tpm1-cmd.c     |  5 --
 drivers/char/tpm/tpm1_structs.h | 97 ++++++++++++++++++++++++++++++++
 include/linux/tpm1.h            | 34 +++++++++++-
 4 files changed, 132 insertions(+), 102 deletions(-)
 create mode 100644 drivers/char/tpm/tpm1_structs.h

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index ca391b2a211c..1f9f8540eede 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -50,105 +50,9 @@ enum tpm_addr {
 	TPM_ADDR = 0x4E,
 };
 
-#define TPM_WARN_RETRY          0x800
-#define TPM_WARN_DOING_SELFTEST 0x802
-#define TPM_ERR_DEACTIVATED     0x6
-#define TPM_ERR_DISABLED        0x7
-#define TPM_ERR_FAILEDSELFTEST  0x1C
-#define TPM_ERR_INVALID_POSTINIT 38
-
-#define TPM_TAG_RQU_COMMAND 193
-
 /* TPM2 specific constants. */
 #define TPM2_SPACE_BUFFER_SIZE		16384 /* 16 kB */
 
-struct	stclear_flags_t {
-	__be16	tag;
-	u8	deactivated;
-	u8	disableForceClear;
-	u8	physicalPresence;
-	u8	physicalPresenceLock;
-	u8	bGlobalLock;
-} __packed;
-
-struct tpm1_version {
-	u8 major;
-	u8 minor;
-	u8 rev_major;
-	u8 rev_minor;
-} __packed;
-
-struct tpm1_version2 {
-	__be16 tag;
-	struct tpm1_version version;
-} __packed;
-
-struct	timeout_t {
-	__be32	a;
-	__be32	b;
-	__be32	c;
-	__be32	d;
-} __packed;
-
-struct duration_t {
-	__be32	tpm_short;
-	__be32	tpm_medium;
-	__be32	tpm_long;
-} __packed;
-
-struct permanent_flags_t {
-	__be16	tag;
-	u8	disable;
-	u8	ownership;
-	u8	deactivated;
-	u8	readPubek;
-	u8	disableOwnerClear;
-	u8	allowMaintenance;
-	u8	physicalPresenceLifetimeLock;
-	u8	physicalPresenceHWEnable;
-	u8	physicalPresenceCMDEnable;
-	u8	CEKPUsed;
-	u8	TPMpost;
-	u8	TPMpostLock;
-	u8	FIPS;
-	u8	operator;
-	u8	enableRevokeEK;
-	u8	nvLocked;
-	u8	readSRKPub;
-	u8	tpmEstablished;
-	u8	maintenanceDone;
-	u8	disableFullDALogicInfo;
-} __packed;
-
-typedef union {
-	struct	permanent_flags_t perm_flags;
-	struct	stclear_flags_t	stclear_flags;
-	__u8	owned;
-	__be32	num_pcrs;
-	struct tpm1_version version1;
-	struct tpm1_version2 version2;
-	__be32	manufacturer_id;
-	struct timeout_t  timeout;
-	struct duration_t duration;
-} cap_t;
-
-enum tpm_capabilities {
-	TPM_CAP_FLAG = 4,
-	TPM_CAP_PROP = 5,
-	TPM_CAP_VERSION_1_1 = 0x06,
-	TPM_CAP_VERSION_1_2 = 0x1A,
-};
-
-enum tpm_sub_capabilities {
-	TPM_CAP_PROP_PCR = 0x101,
-	TPM_CAP_PROP_MANUFACTURER = 0x103,
-	TPM_CAP_FLAG_PERM = 0x108,
-	TPM_CAP_FLAG_VOL = 0x109,
-	TPM_CAP_PROP_OWNER = 0x111,
-	TPM_CAP_PROP_TIS_TIMEOUT = 0x115,
-	TPM_CAP_PROP_TIS_DURATION = 0x120,
-};
-
 enum tpm2_pt_props {
 	TPM2_PT_NONE = 0x00000000,
 	TPM2_PT_GROUP = 0x00000100,
@@ -229,6 +133,8 @@ enum tpm2_pt_props {
  * compiler warnings about stack frame size. */
 #define TPM_MAX_RNG_DATA	128
 
+#include "tpm1_structs.h"
+
 extern const struct class tpm_class;
 extern const struct class tpmrm_class;
 extern dev_t tpm_devt;
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index f29827b454d2..02f20a0aa37d 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -505,11 +505,6 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
 }
 EXPORT_SYMBOL_GPL(tpm1_getcap);
 
-struct tpm1_get_random_out {
-	__be32 rng_data_len;
-	u8 rng_data[TPM_MAX_RNG_DATA];
-} __packed;
-
 /**
  * tpm1_get_random() - get random bytes from the TPM's RNG
  * @chip:	a &struct tpm_chip instance
diff --git a/drivers/char/tpm/tpm1_structs.h b/drivers/char/tpm/tpm1_structs.h
new file mode 100644
index 000000000000..ad21376af5ab
--- /dev/null
+++ b/drivers/char/tpm/tpm1_structs.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004 IBM Corporation
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+
+#ifndef __TPM1_STRUCTS_H__
+#define __TPM1_STRUCTS_H__
+
+struct	stclear_flags_t {
+	__be16	tag;
+	u8	deactivated;
+	u8	disableForceClear;
+	u8	physicalPresence;
+	u8	physicalPresenceLock;
+	u8	bGlobalLock;
+} __packed;
+
+struct tpm1_version {
+	u8 major;
+	u8 minor;
+	u8 rev_major;
+	u8 rev_minor;
+} __packed;
+
+struct tpm1_version2 {
+	__be16 tag;
+	struct tpm1_version version;
+} __packed;
+
+struct	timeout_t {
+	__be32	a;
+	__be32	b;
+	__be32	c;
+	__be32	d;
+} __packed;
+
+struct duration_t {
+	__be32	tpm_short;
+	__be32	tpm_medium;
+	__be32	tpm_long;
+} __packed;
+
+struct permanent_flags_t {
+	__be16	tag;
+	u8	disable;
+	u8	ownership;
+	u8	deactivated;
+	u8	readPubek;
+	u8	disableOwnerClear;
+	u8	allowMaintenance;
+	u8	physicalPresenceLifetimeLock;
+	u8	physicalPresenceHWEnable;
+	u8	physicalPresenceCMDEnable;
+	u8	CEKPUsed;
+	u8	TPMpost;
+	u8	TPMpostLock;
+	u8	FIPS;
+	u8	operator;
+	u8	enableRevokeEK;
+	u8	nvLocked;
+	u8	readSRKPub;
+	u8	tpmEstablished;
+	u8	maintenanceDone;
+	u8	disableFullDALogicInfo;
+} __packed;
+
+/* Gather all capabilities related information info one type */
+typedef union {
+	struct	permanent_flags_t perm_flags;
+	struct	stclear_flags_t	stclear_flags;
+	__u8	owned;
+	__be32	num_pcrs;
+	struct tpm1_version version1;
+	struct tpm1_version2 version2;
+	__be32	manufacturer_id;
+	struct timeout_t  timeout;
+	struct duration_t duration;
+} cap_t;
+
+struct tpm1_get_random_out {
+	__be32 rng_data_len;
+	u8 rng_data[TPM_MAX_RNG_DATA];
+} __packed;
+
+#endif
diff --git a/include/linux/tpm1.h b/include/linux/tpm1.h
index 54c6c211eb9e..5fad94ac8d15 100644
--- a/include/linux/tpm1.h
+++ b/include/linux/tpm1.h
@@ -47,7 +47,39 @@ enum tpm_command_ordinals {
 	TPM_ORD_UNSEAL			= 24,
 };
 
-/* Other constants */
+enum tpm_capabilities {
+	TPM_CAP_FLAG		= 4,
+	TPM_CAP_PROP		= 5,
+	TPM_CAP_VERSION_1_1	= 0x06,
+	TPM_CAP_VERSION_1_2	= 0x1A,
+};
+
+enum tpm_sub_capabilities {
+	TPM_CAP_PROP_PCR		= 0x101,
+	TPM_CAP_PROP_MANUFACTURER	= 0x103,
+	TPM_CAP_FLAG_PERM		= 0x108,
+	TPM_CAP_FLAG_VOL		= 0x109,
+	TPM_CAP_PROP_OWNER		= 0x111,
+	TPM_CAP_PROP_TIS_TIMEOUT	= 0x115,
+	TPM_CAP_PROP_TIS_DURATION	= 0x120,
+};
+
+/* Return Codes */
+enum tpm_return_codes {
+	TPM_BASE_MASK			= 0,
+	TPM_NON_FATAL_MASK		= 0x00000800,
+	TPM_SUCCESS			= TPM_BASE_MASK + 0,
+	TPM_ERR_DEACTIVATED		= TPM_BASE_MASK + 6,
+	TPM_ERR_DISABLED		= TPM_BASE_MASK + 7,
+	TPM_ERR_FAIL			= TPM_BASE_MASK + 9,
+	TPM_ERR_FAILEDSELFTEST		= TPM_BASE_MASK + 28,
+	TPM_ERR_INVALID_POSTINIT	= TPM_BASE_MASK + 38,
+	TPM_ERR_INVALID_FAMILY		= TPM_BASE_MASK + 55,
+	TPM_WARN_RETRY			= TPM_BASE_MASK + TPM_NON_FATAL_MASK + 0,
+	TPM_WARN_DOING_SELFTEST		= TPM_BASE_MASK + TPM_NON_FATAL_MASK + 2,
+};
+
+/* Misc. constants */
 #define SRKHANDLE                       0x40000000
 #define TPM_NONCE_SIZE                  20
 #define TPM_ST_CLEAR			1
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 03/28] tpm: Move TPM2 specific definitions and functions to new headers
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 01/28] tpm: Initial step to reorganize TPM public headers Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 02/28] tpm: Move TPM1 specific definitions and functions to new headers Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 04/28] tpm: Move TPM common base definitions to new public common header Ross Philipson
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

This gathers all the TPM2 definitions and structures into two separate
header files (public tpm2.h and private tpm2_structs.h). The definitions
moved to these files correspond to the TCG specification for TPM 1 family:

TPM 2.0 Library
 - https://trustedcomputinggroup.org/resource/tpm-library-specification/

Note that the structures were pulled into tpm2_structs.h to allow their
external reuse.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 drivers/char/tpm/tpm.h          |  78 +---------
 drivers/char/tpm/tpm2-cmd.c     |  32 +---
 drivers/char/tpm/tpm2-space.c   |  13 --
 drivers/char/tpm/tpm2_structs.h |  58 ++++++++
 include/linux/tpm.h             | 141 +-----------------
 include/linux/tpm2.h            | 252 ++++++++++++++++++++++++++++++++
 6 files changed, 313 insertions(+), 261 deletions(-)
 create mode 100644 drivers/char/tpm/tpm2_structs.h
 create mode 100644 include/linux/tpm2.h

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1f9f8540eede..faac3c7065bf 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -50,83 +50,6 @@ enum tpm_addr {
 	TPM_ADDR = 0x4E,
 };
 
-/* TPM2 specific constants. */
-#define TPM2_SPACE_BUFFER_SIZE		16384 /* 16 kB */
-
-enum tpm2_pt_props {
-	TPM2_PT_NONE = 0x00000000,
-	TPM2_PT_GROUP = 0x00000100,
-	TPM2_PT_FIXED = TPM2_PT_GROUP * 1,
-	TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0,
-	TPM2_PT_LEVEL = TPM2_PT_FIXED + 1,
-	TPM2_PT_REVISION = TPM2_PT_FIXED + 2,
-	TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3,
-	TPM2_PT_YEAR = TPM2_PT_FIXED + 4,
-	TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5,
-	TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6,
-	TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7,
-	TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8,
-	TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9,
-	TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10,
-	TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11,
-	TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12,
-	TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13,
-	TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14,
-	TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15,
-	TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16,
-	TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17,
-	TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18,
-	TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19,
-	TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20,
-	TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22,
-	TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23,
-	TPM2_PT_MEMORY = TPM2_PT_FIXED + 24,
-	TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25,
-	TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26,
-	TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27,
-	TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28,
-	TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29,
-	TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30,
-	TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31,
-	TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32,
-	TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33,
-	TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34,
-	TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35,
-	TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36,
-	TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37,
-	TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38,
-	TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39,
-	TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40,
-	TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41,
-	TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42,
-	TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43,
-	TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44,
-	TPM2_PT_MODES = TPM2_PT_FIXED + 45,
-	TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46,
-	TPM2_PT_VAR = TPM2_PT_GROUP * 2,
-	TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
-	TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
-	TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2,
-	TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3,
-	TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4,
-	TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5,
-	TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6,
-	TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7,
-	TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8,
-	TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9,
-	TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10,
-	TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11,
-	TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12,
-	TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13,
-	TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
-	TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
-	TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
-	TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
-	TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18,
-	TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19,
-	TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
-};
-
 /* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
  * bytes, but 128 is still a relatively large number of random bytes and
  * anything much bigger causes users of struct tpm_cmd_t to start getting
@@ -134,6 +57,7 @@ enum tpm2_pt_props {
 #define TPM_MAX_RNG_DATA	128
 
 #include "tpm1_structs.h"
+#include "tpm2_structs.h"
 
 extern const struct class tpm_class;
 extern const struct class tpmrm_class;
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index a0fcd3cd00b7..7308b08a915f 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -11,8 +11,8 @@
  * used by the kernel internally.
  */
 
-#include "tpm.h"
 #include <crypto/hash_info.h>
+#include "tpm.h"
 
 static bool disable_pcr_integrity;
 module_param(disable_pcr_integrity, bool, 0444);
@@ -79,17 +79,6 @@ unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
 	return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
 }
 
-struct tpm2_pcr_read_out {
-	__be32	update_cnt;
-	__be32	pcr_selects_cnt;
-	__be16	hash_alg;
-	u8	pcr_select_size;
-	u8	pcr_select[TPM2_PCR_SELECT_MIN];
-	__be32	digests_cnt;
-	__be16	digest_size;
-	u8	digest[];
-} __packed;
-
 /**
  * tpm2_pcr_read() - read a PCR value
  * @chip:	TPM chip to use.
@@ -205,11 +194,6 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
 	return rc;
 }
 
-struct tpm2_get_random_out {
-	__be16 size;
-	u8 buffer[TPM_MAX_RNG_DATA];
-} __packed;
-
 /**
  * tpm2_get_random() - get random bytes from the TPM RNG
  *
@@ -322,14 +306,6 @@ void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
 }
 EXPORT_SYMBOL_GPL(tpm2_flush_context);
 
-struct tpm2_get_cap_out {
-	u8 more_data;
-	__be32 subcap_id;
-	__be32 property_cnt;
-	__be32 property_id;
-	__be32 value;
-} __packed;
-
 /**
  * tpm2_get_tpm_pt() - get value of a TPM_CAP_TPM_PROPERTIES type property
  * @chip:		a &tpm_chip instance
@@ -498,12 +474,6 @@ static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index)
 	return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size);
 }
 
-struct tpm2_pcr_selection {
-	__be16  hash_alg;
-	u8  size_of_select;
-	u8  pcr_select[3];
-} __packed;
-
 ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
 {
 	struct tpm2_pcr_selection pcr_selection;
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index e80fd767998f..8595107ab5b2 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -15,19 +15,6 @@
 #include <linux/unaligned.h>
 #include "tpm.h"
 
-enum tpm2_handle_types {
-	TPM2_HT_HMAC_SESSION	= 0x02000000,
-	TPM2_HT_POLICY_SESSION	= 0x03000000,
-	TPM2_HT_TRANSIENT	= 0x80000000,
-};
-
-struct tpm2_context {
-	__be64 sequence;
-	__be32 saved_handle;
-	__be32 hierarchy;
-	__be16 blob_size;
-} __packed;
-
 static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
 {
 	int i;
diff --git a/drivers/char/tpm/tpm2_structs.h b/drivers/char/tpm/tpm2_structs.h
new file mode 100644
index 000000000000..85c15f2369f2
--- /dev/null
+++ b/drivers/char/tpm/tpm2_structs.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004 IBM Corporation
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+
+#ifndef __TPM2_STRUCTS_H__
+#define __TPM2_STRUCTS_H__
+
+struct tpm2_pcr_read_out {
+	__be32	update_cnt;
+	__be32	pcr_selects_cnt;
+	__be16	hash_alg;
+	u8	pcr_select_size;
+	u8	pcr_select[TPM2_PCR_SELECT_MIN];
+	__be32	digests_cnt;
+	__be16	digest_size;
+	u8	digest[];
+} __packed;
+
+struct tpm2_get_random_out {
+	__be16 size;
+	u8 buffer[TPM_MAX_RNG_DATA];
+} __packed;
+
+struct tpm2_get_cap_out {
+	u8 more_data;
+	__be32 subcap_id;
+	__be32 property_cnt;
+	__be32 property_id;
+	__be32 value;
+} __packed;
+
+struct tpm2_pcr_selection {
+	__be16  hash_alg;
+	u8  size_of_select;
+	u8  pcr_select[3];
+} __packed;
+
+struct tpm2_context {
+	__be64 sequence;
+	__be32 saved_handle;
+	__be32 hierarchy;
+	__be16 blob_size;
+} __packed;
+
+#endif
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index ef81e0b59657..e77e3e2c1d9e 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -27,6 +27,7 @@
 
 #include "tpm_common.h"
 #include "tpm1.h"
+#include "tpm2.h"
 
 #define TPM_DIGEST_SIZE		20	/* Max TPM v1.2 PCR size */
 #define TPM_HEADER_SIZE		10
@@ -43,12 +44,6 @@ struct trusted_key_options;
 /* opaque structure, holds auth session parameters like the session key */
 struct tpm2_auth;
 
-enum tpm2_session_types {
-	TPM2_SE_HMAC	= 0x00,
-	TPM2_SE_POLICY	= 0x01,
-	TPM2_SE_TRIAL	= 0x02,
-};
-
 /* if you add a new hash to this, increment TPM_MAX_HASHES below */
 enum tpm_algorithms {
 	TPM_ALG_ERROR		= 0x0000,
@@ -70,11 +65,6 @@ enum tpm_algorithms {
  */
 #define TPM_MAX_HASHES	5
 
-enum tpm2_curves {
-	TPM2_ECC_NONE		= 0x0000,
-	TPM2_ECC_NIST_P256	= 0x0003,
-};
-
 struct tpm_digest {
 	u16 alg_id;
 	u8 digest[TPM2_MAX_DIGEST_SIZE];
@@ -225,117 +215,11 @@ struct tpm_chip {
 #endif
 };
 
-enum tpm2_timeouts {
-	TPM2_TIMEOUT_A          =    750,
-	TPM2_TIMEOUT_B          =   4000,
-	TPM2_TIMEOUT_C          =    200,
-	TPM2_TIMEOUT_D          =     30,
-};
-
-enum tpm2_durations {
-	TPM2_DURATION_SHORT     =     20,
-	TPM2_DURATION_LONG      =   2000,
-	TPM2_DURATION_DEFAULT   = 120000,
-};
-
-enum tpm2_structures {
-	TPM2_ST_NO_SESSIONS	= 0x8001,
-	TPM2_ST_SESSIONS	= 0x8002,
-	TPM2_ST_CREATION	= 0x8021,
-};
-
-/* Indicates from what layer of the software stack the error comes from */
-#define TSS2_RC_LAYER_SHIFT	 16
-#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT)
-
-enum tpm2_return_codes {
-	TPM2_RC_SUCCESS		= 0x0000,
-	TPM2_RC_HASH		= 0x0083, /* RC_FMT1 */
-	TPM2_RC_HANDLE		= 0x008B,
-	TPM2_RC_INTEGRITY	= 0x009F,
-	TPM2_RC_INITIALIZE	= 0x0100, /* RC_VER1 */
-	TPM2_RC_FAILURE		= 0x0101,
-	TPM2_RC_DISABLED	= 0x0120,
-	TPM2_RC_UPGRADE		= 0x012D,
-	TPM2_RC_COMMAND_CODE    = 0x0143,
-	TPM2_RC_TESTING		= 0x090A, /* RC_WARN */
-	TPM2_RC_REFERENCE_H0	= 0x0910,
-	TPM2_RC_RETRY		= 0x0922,
-	TPM2_RC_SESSION_MEMORY	= 0x0903,
-};
-
-enum tpm2_command_codes {
-	TPM2_CC_FIRST		        = 0x011F,
-	TPM2_CC_HIERARCHY_CONTROL       = 0x0121,
-	TPM2_CC_HIERARCHY_CHANGE_AUTH   = 0x0129,
-	TPM2_CC_CREATE_PRIMARY          = 0x0131,
-	TPM2_CC_SEQUENCE_COMPLETE       = 0x013E,
-	TPM2_CC_SELF_TEST	        = 0x0143,
-	TPM2_CC_STARTUP		        = 0x0144,
-	TPM2_CC_SHUTDOWN	        = 0x0145,
-	TPM2_CC_NV_READ                 = 0x014E,
-	TPM2_CC_CREATE		        = 0x0153,
-	TPM2_CC_LOAD		        = 0x0157,
-	TPM2_CC_SEQUENCE_UPDATE         = 0x015C,
-	TPM2_CC_UNSEAL		        = 0x015E,
-	TPM2_CC_CONTEXT_LOAD	        = 0x0161,
-	TPM2_CC_CONTEXT_SAVE	        = 0x0162,
-	TPM2_CC_FLUSH_CONTEXT	        = 0x0165,
-	TPM2_CC_READ_PUBLIC		= 0x0173,
-	TPM2_CC_START_AUTH_SESS		= 0x0176,
-	TPM2_CC_VERIFY_SIGNATURE        = 0x0177,
-	TPM2_CC_GET_CAPABILITY	        = 0x017A,
-	TPM2_CC_GET_RANDOM	        = 0x017B,
-	TPM2_CC_PCR_READ	        = 0x017E,
-	TPM2_CC_PCR_EXTEND	        = 0x0182,
-	TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
-	TPM2_CC_HASH_SEQUENCE_START     = 0x0186,
-	TPM2_CC_CREATE_LOADED           = 0x0191,
-	TPM2_CC_LAST		        = 0x0193, /* Spec 1.36 */
-};
-
-enum tpm2_permanent_handles {
-	TPM2_RH_NULL		= 0x40000007,
-	TPM2_RS_PW		= 0x40000009,
-};
-
-/* Most Significant Octet for key types  */
-enum tpm2_mso_type {
-	TPM2_MSO_NVRAM		= 0x01,
-	TPM2_MSO_SESSION	= 0x02,
-	TPM2_MSO_POLICY		= 0x03,
-	TPM2_MSO_PERMANENT	= 0x40,
-	TPM2_MSO_VOLATILE	= 0x80,
-	TPM2_MSO_PERSISTENT	= 0x81,
-};
-
 static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle)
 {
 	return handle >> 24;
 }
 
-enum tpm2_capabilities {
-	TPM2_CAP_HANDLES	= 1,
-	TPM2_CAP_COMMANDS	= 2,
-	TPM2_CAP_PCRS		= 5,
-	TPM2_CAP_TPM_PROPERTIES = 6,
-};
-
-enum tpm2_properties {
-	TPM_PT_TOTAL_COMMANDS	= 0x0129,
-};
-
-enum tpm2_startup_types {
-	TPM2_SU_CLEAR	= 0x0000,
-	TPM2_SU_STATE	= 0x0001,
-};
-
-enum tpm2_cc_attrs {
-	TPM2_CC_ATTR_CHANDLES	= 25,
-	TPM2_CC_ATTR_RHANDLE	= 28,
-	TPM2_CC_ATTR_VENDOR	= 29,
-};
-
 #define TPM_VID_INTEL    0x8086
 #define TPM_VID_WINBOND  0x1050
 #define TPM_VID_STM      0x104A
@@ -387,29 +271,6 @@ struct tpm_buf {
 	u8 data[];
 };
 
-enum tpm2_object_attributes {
-	TPM2_OA_FIXED_TPM		= BIT(1),
-	TPM2_OA_ST_CLEAR		= BIT(2),
-	TPM2_OA_FIXED_PARENT		= BIT(4),
-	TPM2_OA_SENSITIVE_DATA_ORIGIN	= BIT(5),
-	TPM2_OA_USER_WITH_AUTH		= BIT(6),
-	TPM2_OA_ADMIN_WITH_POLICY	= BIT(7),
-	TPM2_OA_NO_DA			= BIT(10),
-	TPM2_OA_ENCRYPTED_DUPLICATION	= BIT(11),
-	TPM2_OA_RESTRICTED		= BIT(16),
-	TPM2_OA_DECRYPT			= BIT(17),
-	TPM2_OA_SIGN			= BIT(18),
-};
-
-enum tpm2_session_attributes {
-	TPM2_SA_CONTINUE_SESSION	= BIT(0),
-	TPM2_SA_AUDIT_EXCLUSIVE		= BIT(1),
-	TPM2_SA_AUDIT_RESET		= BIT(3),
-	TPM2_SA_DECRYPT			= BIT(5),
-	TPM2_SA_ENCRYPT			= BIT(6),
-	TPM2_SA_AUDIT			= BIT(7),
-};
-
 struct tpm2_hash {
 	unsigned int crypto_id;
 	unsigned int tpm_id;
diff --git a/include/linux/tpm2.h b/include/linux/tpm2.h
new file mode 100644
index 000000000000..f87489aea780
--- /dev/null
+++ b/include/linux/tpm2.h
@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ * Debora Velarde <dvelarde@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+#ifndef __LINUX_TPM2_H__
+#define __LINUX_TPM2_H__
+
+/*
+ * TPM 2.0 Library
+ * https://trustedcomputinggroup.org/resource/tpm-library-specification/
+ */
+
+/* TPM2 specific constants. */
+#define TPM2_SPACE_BUFFER_SIZE	16384 /* 16 kB */
+
+enum tpm2_session_types {
+	TPM2_SE_HMAC	= 0x00,
+	TPM2_SE_POLICY	= 0x01,
+	TPM2_SE_TRIAL	= 0x02,
+};
+
+enum tpm2_structures {
+	TPM2_ST_NO_SESSIONS	= 0x8001,
+	TPM2_ST_SESSIONS	= 0x8002,
+	TPM2_ST_CREATION	= 0x8021,
+};
+
+enum tpm2_timeouts {
+	TPM2_TIMEOUT_A          =    750,
+	TPM2_TIMEOUT_B          =   4000,
+	TPM2_TIMEOUT_C          =    200,
+	TPM2_TIMEOUT_D          =     30,
+	TPM2_DURATION_SHORT     =     20,
+	TPM2_DURATION_MEDIUM    =    750,
+	TPM2_DURATION_LONG      =   2000,
+	TPM2_DURATION_LONG_LONG = 300000,
+	TPM2_DURATION_DEFAULT   = 120000,
+};
+
+/* Indicates from what layer of the software stack the error comes from */
+#define TSS2_RC_LAYER_SHIFT	 16
+#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT)
+
+enum tpm2_return_codes {
+	TPM2_RC_SUCCESS		= 0x0000,
+	TPM2_RC_HASH		= 0x0083, /* RC_FMT1 */
+	TPM2_RC_HANDLE		= 0x008B,
+	TPM2_RC_INTEGRITY	= 0x009F,
+	TPM2_RC_INITIALIZE	= 0x0100, /* RC_VER1 */
+	TPM2_RC_FAILURE		= 0x0101,
+	TPM2_RC_DISABLED	= 0x0120,
+	TPM2_RC_UPGRADE		= 0x012D,
+	TPM2_RC_COMMAND_CODE   	= 0x0143,
+	TPM2_RC_TESTING		= 0x090A, /* RC_WARN */
+	TPM2_RC_REFERENCE_H0	= 0x0910,
+	TPM2_RC_RETRY		= 0x0922,
+	TPM2_RC_SESSION_MEMORY	= 0x0903,
+};
+
+enum tpm2_command_codes {
+	TPM2_CC_FIRST			= 0x011F,
+	TPM2_CC_HIERARCHY_CONTROL	= 0x0121,
+	TPM2_CC_HIERARCHY_CHANGE_AUTH	= 0x0129,
+	TPM2_CC_CREATE_PRIMARY		= 0x0131,
+	TPM2_CC_SEQUENCE_COMPLETE	= 0x013E,
+	TPM2_CC_SELF_TEST		= 0x0143,
+	TPM2_CC_STARTUP			= 0x0144,
+	TPM2_CC_SHUTDOWN		= 0x0145,
+	TPM2_CC_NV_READ			= 0x014E,
+	TPM2_CC_CREATE			= 0x0153,
+	TPM2_CC_LOAD			= 0x0157,
+	TPM2_CC_SEQUENCE_UPDATE		= 0x015C,
+	TPM2_CC_UNSEAL			= 0x015E,
+	TPM2_CC_CONTEXT_LOAD		= 0x0161,
+	TPM2_CC_CONTEXT_SAVE		= 0x0162,
+	TPM2_CC_FLUSH_CONTEXT		= 0x0165,
+	TPM2_CC_READ_PUBLIC		= 0x0173,
+	TPM2_CC_START_AUTH_SESS		= 0x0176,
+	TPM2_CC_VERIFY_SIGNATURE	= 0x0177,
+	TPM2_CC_GET_CAPABILITY		= 0x017A,
+	TPM2_CC_GET_RANDOM		= 0x017B,
+	TPM2_CC_PCR_READ		= 0x017E,
+	TPM2_CC_PCR_EXTEND		= 0x0182,
+	TPM2_CC_EVENT_SEQUENCE_COMPLETE	= 0x0185,
+	TPM2_CC_HASH_SEQUENCE_START	= 0x0186,
+	TPM2_CC_CREATE_LOADED		= 0x0191,
+	TPM2_CC_LAST			= 0x0193, /* Spec 1.36 */
+};
+
+enum tpm2_capabilities {
+	TPM2_CAP_HANDLES	= 1,
+	TPM2_CAP_COMMANDS	= 2,
+	TPM2_CAP_PCRS		= 5,
+	TPM2_CAP_TPM_PROPERTIES = 6,
+};
+
+enum tpm2_properties {
+	TPM_PT_TOTAL_COMMANDS	= 0x0129,
+};
+
+enum tpm2_startup_types {
+	TPM2_SU_CLEAR	= 0x0000,
+	TPM2_SU_STATE	= 0x0001,
+};
+
+enum tpm2_cc_attrs {
+	TPM2_CC_ATTR_CHANDLES	= 25,
+	TPM2_CC_ATTR_RHANDLE	= 28,
+	TPM2_CC_ATTR_VENDOR	= 29,
+};
+
+enum tpm2_permanent_handles {
+	TPM2_RH_NULL		= 0x40000007,
+	TPM2_RS_PW		= 0x40000009,
+};
+
+/* Most Significant Octet for key types  */
+enum tpm2_mso_type {
+	TPM2_MSO_NVRAM		= 0x01,
+	TPM2_MSO_SESSION	= 0x02,
+	TPM2_MSO_POLICY		= 0x03,
+	TPM2_MSO_PERMANENT	= 0x40,
+	TPM2_MSO_VOLATILE	= 0x80,
+	TPM2_MSO_PERSISTENT	= 0x81,
+};
+
+enum tpm2_ecc_curve {
+	TPM2_ECC_NONE		= 0x0000,
+	TPM2_ECC_NIST_P256	= 0x0003,
+};
+
+enum tpm2_object_attributes {
+	TPM2_OA_FIXED_TPM		= BIT(1),
+	TPM2_OA_ST_CLEAR		= BIT(2),
+	TPM2_OA_FIXED_PARENT		= BIT(4),
+	TPM2_OA_SENSITIVE_DATA_ORIGIN	= BIT(5),
+	TPM2_OA_USER_WITH_AUTH		= BIT(6),
+	TPM2_OA_ADMIN_WITH_POLICY	= BIT(7),
+	TPM2_OA_NO_DA			= BIT(10),
+	TPM2_OA_ENCRYPTED_DUPLICATION	= BIT(11),
+	TPM2_OA_RESTRICTED		= BIT(16),
+	TPM2_OA_DECRYPT			= BIT(17),
+	TPM2_OA_SIGN			= BIT(18),
+};
+
+enum tpm2_session_attributes {
+	TPM2_SA_CONTINUE_SESSION	= BIT(0),
+	TPM2_SA_AUDIT_EXCLUSIVE		= BIT(1),
+	TPM2_SA_AUDIT_RESET		= BIT(3),
+	TPM2_SA_DECRYPT			= BIT(5),
+	TPM2_SA_ENCRYPT			= BIT(6),
+	TPM2_SA_AUDIT			= BIT(7),
+};
+
+enum tpm2_pcr_select {
+	TPM2_PLATFORM_PCR	= 24,
+	TPM2_PCR_SELECT_MIN	= ((TPM2_PLATFORM_PCR + 7) / 8),
+};
+
+enum tpm2_handle_types {
+	TPM2_HT_HMAC_SESSION	= 0x02000000,
+	TPM2_HT_POLICY_SESSION	= 0x03000000,
+	TPM2_HT_TRANSIENT	= 0x80000000,
+};
+
+enum tpm2_pt_props {
+	TPM2_PT_NONE			= 0x00000000,
+	TPM2_PT_GROUP			= 0x00000100,
+	TPM2_PT_FIXED			= TPM2_PT_GROUP * 1,
+	TPM2_PT_FAMILY_INDICATOR	= TPM2_PT_FIXED + 0,
+	TPM2_PT_LEVEL		= TPM2_PT_FIXED + 1,
+	TPM2_PT_REVISION	= TPM2_PT_FIXED + 2,
+	TPM2_PT_DAY_OF_YEAR	= TPM2_PT_FIXED + 3,
+	TPM2_PT_YEAR		= TPM2_PT_FIXED + 4,
+	TPM2_PT_MANUFACTURER	= TPM2_PT_FIXED + 5,
+	TPM2_PT_VENDOR_STRING_1	= TPM2_PT_FIXED + 6,
+	TPM2_PT_VENDOR_STRING_2	= TPM2_PT_FIXED + 7,
+	TPM2_PT_VENDOR_STRING_3	= TPM2_PT_FIXED + 8,
+	TPM2_PT_VENDOR_STRING_4	= TPM2_PT_FIXED + 9,
+	TPM2_PT_VENDOR_TPM_TYPE	= TPM2_PT_FIXED + 10,
+	TPM2_PT_FIRMWARE_VERSION_1	= TPM2_PT_FIXED + 11,
+	TPM2_PT_FIRMWARE_VERSION_2	= TPM2_PT_FIXED + 12,
+	TPM2_PT_INPUT_BUFFER		= TPM2_PT_FIXED + 13,
+	TPM2_PT_HR_TRANSIENT_MIN	= TPM2_PT_FIXED + 14,
+	TPM2_PT_HR_PERSISTENT_MIN	= TPM2_PT_FIXED + 15,
+	TPM2_PT_HR_LOADED_MIN		= TPM2_PT_FIXED + 16,
+	TPM2_PT_ACTIVE_SESSIONS_MAX	= TPM2_PT_FIXED + 17,
+	TPM2_PT_PCR_COUNT	= TPM2_PT_FIXED + 18,
+	TPM2_PT_PCR_SELECT_MIN	= TPM2_PT_FIXED + 19,
+	TPM2_PT_CONTEXT_GAP_MAX	= TPM2_PT_FIXED + 20,
+	TPM2_PT_NV_COUNTERS_MAX	= TPM2_PT_FIXED + 22,
+	TPM2_PT_NV_INDEX_MAX	= TPM2_PT_FIXED + 23,
+	TPM2_PT_MEMORY		= TPM2_PT_FIXED + 24,
+	TPM2_PT_CLOCK_UPDATE	= TPM2_PT_FIXED + 25,
+	TPM2_PT_CONTEXT_HASH	= TPM2_PT_FIXED + 26,
+	TPM2_PT_CONTEXT_SYM	= TPM2_PT_FIXED + 27,
+	TPM2_PT_CONTEXT_SYM_SIZE	= TPM2_PT_FIXED + 28,
+	TPM2_PT_ORDERLY_COUNT		= TPM2_PT_FIXED + 29,
+	TPM2_PT_MAX_COMMAND_SIZE	= TPM2_PT_FIXED + 30,
+	TPM2_PT_MAX_RESPONSE_SIZE	= TPM2_PT_FIXED + 31,
+	TPM2_PT_MAX_DIGEST		= TPM2_PT_FIXED + 32,
+	TPM2_PT_MAX_OBJECT_CONTEXT	= TPM2_PT_FIXED + 33,
+	TPM2_PT_MAX_SESSION_CONTEXT	= TPM2_PT_FIXED + 34,
+	TPM2_PT_PS_FAMILY_INDICATOR	= TPM2_PT_FIXED + 35,
+	TPM2_PT_PS_LEVEL	= TPM2_PT_FIXED + 36,
+	TPM2_PT_PS_REVISION	= TPM2_PT_FIXED + 37,
+	TPM2_PT_PS_DAY_OF_YEAR	= TPM2_PT_FIXED + 38,
+	TPM2_PT_PS_YEAR		= TPM2_PT_FIXED + 39,
+	TPM2_PT_SPLIT_MAX	= TPM2_PT_FIXED + 40,
+	TPM2_PT_TOTAL_COMMANDS	= TPM2_PT_FIXED + 41,
+	TPM2_PT_LIBRARY_COMMANDS	= TPM2_PT_FIXED + 42,
+	TPM2_PT_VENDOR_COMMANDS		= TPM2_PT_FIXED + 43,
+	TPM2_PT_NV_BUFFER_MAX		= TPM2_PT_FIXED + 44,
+	TPM2_PT_MODES			= TPM2_PT_FIXED + 45,
+	TPM2_PT_MAX_CAP_BUFFER		= TPM2_PT_FIXED + 46,
+	TPM2_PT_VAR		= TPM2_PT_GROUP * 2,
+	TPM2_PT_PERMANENT	= TPM2_PT_VAR + 0,
+	TPM2_PT_STARTUP_CLEAR	= TPM2_PT_VAR + 1,
+	TPM2_PT_HR_NV_INDEX	= TPM2_PT_VAR + 2,
+	TPM2_PT_HR_LOADED	= TPM2_PT_VAR + 3,
+	TPM2_PT_HR_LOADED_AVAIL	= TPM2_PT_VAR + 4,
+	TPM2_PT_HR_ACTIVE	= TPM2_PT_VAR + 5,
+	TPM2_PT_HR_ACTIVE_AVAIL	= TPM2_PT_VAR + 6,
+	TPM2_PT_HR_TRANSIENT_AVAIL	= TPM2_PT_VAR + 7,
+	TPM2_PT_HR_PERSISTENT		= TPM2_PT_VAR + 8,
+	TPM2_PT_HR_PERSISTENT_AVAIL	= TPM2_PT_VAR + 9,
+	TPM2_PT_NV_COUNTERS		= TPM2_PT_VAR + 10,
+	TPM2_PT_NV_COUNTERS_AVAIL	= TPM2_PT_VAR + 11,
+	TPM2_PT_ALGORITHM_SET		= TPM2_PT_VAR + 12,
+	TPM2_PT_LOADED_CURVES		= TPM2_PT_VAR + 13,
+	TPM2_PT_LOCKOUT_COUNTER		= TPM2_PT_VAR + 14,
+	TPM2_PT_MAX_AUTH_FAIL		= TPM2_PT_VAR + 15,
+	TPM2_PT_LOCKOUT_INTERVAL	= TPM2_PT_VAR + 16,
+	TPM2_PT_LOCKOUT_RECOVERY	= TPM2_PT_VAR + 17,
+	TPM2_PT_NV_WRITE_RECOVERY	= TPM2_PT_VAR + 18,
+	TPM2_PT_AUDIT_COUNTER_0	= TPM2_PT_VAR + 19,
+	TPM2_PT_AUDIT_COUNTER_1	= TPM2_PT_VAR + 20,
+};
+
+#endif
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 04/28] tpm: Move TPM common base definitions to new public common header
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (2 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 03/28] tpm: Move TPM2 " Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 05/28] tpm: Move platform specific definitions to the new PTP header Ross Philipson
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

These are top level definitions shared by both TPM 1 and 2
family chips. This includes core definitions like TPM localities,
timeouts, and common crypto algorithm IDs.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 drivers/char/tpm/tpm.h     |  6 ----
 include/linux/tpm.h        | 44 -------------------------
 include/linux/tpm2.h       |  5 ---
 include/linux/tpm_common.h | 67 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 67 insertions(+), 55 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index faac3c7065bf..7d608b166bbf 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -50,12 +50,6 @@ enum tpm_addr {
 	TPM_ADDR = 0x4E,
 };
 
-/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
- * bytes, but 128 is still a relatively large number of random bytes and
- * anything much bigger causes users of struct tpm_cmd_t to start getting
- * compiler warnings about stack frame size. */
-#define TPM_MAX_RNG_DATA	128
-
 #include "tpm1_structs.h"
 #include "tpm2_structs.h"
 
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index e77e3e2c1d9e..8a778bcc2dd5 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -29,47 +29,12 @@
 #include "tpm1.h"
 #include "tpm2.h"
 
-#define TPM_DIGEST_SIZE		20	/* Max TPM v1.2 PCR size */
-#define TPM_HEADER_SIZE		10
-#define TPM_BUFSIZE		4096
-
-#define TPM2_PLATFORM_PCR	24
-#define TPM2_PCR_SELECT_MIN	3
-#define TPM2_MAX_DIGEST_SIZE	SHA512_DIGEST_SIZE
-#define TPM2_MAX_BANKS		4
-
 struct tpm_chip;
 struct trusted_key_payload;
 struct trusted_key_options;
 /* opaque structure, holds auth session parameters like the session key */
 struct tpm2_auth;
 
-/* if you add a new hash to this, increment TPM_MAX_HASHES below */
-enum tpm_algorithms {
-	TPM_ALG_ERROR		= 0x0000,
-	TPM_ALG_SHA1		= 0x0004,
-	TPM_ALG_AES		= 0x0006,
-	TPM_ALG_KEYEDHASH	= 0x0008,
-	TPM_ALG_SHA256		= 0x000B,
-	TPM_ALG_SHA384		= 0x000C,
-	TPM_ALG_SHA512		= 0x000D,
-	TPM_ALG_NULL		= 0x0010,
-	TPM_ALG_SM3_256		= 0x0012,
-	TPM_ALG_ECC		= 0x0023,
-	TPM_ALG_CFB		= 0x0043,
-};
-
-/*
- * maximum number of hashing algorithms a TPM can have.  This is
- * basically a count of every hash in tpm_algorithms above
- */
-#define TPM_MAX_HASHES	5
-
-struct tpm_digest {
-	u16 alg_id;
-	u8 digest[TPM2_MAX_DIGEST_SIZE];
-} __packed;
-
 struct tpm_bank_info {
 	u16 alg_id;
 	u16 digest_size;
@@ -243,15 +208,6 @@ enum tpm_chip_flags {
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
 
-struct tpm_header {
-	__be16 tag;
-	__be32 length;
-	union {
-		__be32 ordinal;
-		__be32 return_code;
-	};
-} __packed;
-
 enum tpm_buf_flags {
 	/* TPM2B format: */
 	TPM_BUF_TPM2B		= BIT(0),
diff --git a/include/linux/tpm2.h b/include/linux/tpm2.h
index f87489aea780..c2ece73a54c5 100644
--- a/include/linux/tpm2.h
+++ b/include/linux/tpm2.h
@@ -164,11 +164,6 @@ enum tpm2_session_attributes {
 	TPM2_SA_AUDIT			= BIT(7),
 };
 
-enum tpm2_pcr_select {
-	TPM2_PLATFORM_PCR	= 24,
-	TPM2_PCR_SELECT_MIN	= ((TPM2_PLATFORM_PCR + 7) / 8),
-};
-
 enum tpm2_handle_types {
 	TPM2_HT_HMAC_SESSION	= 0x02000000,
 	TPM2_HT_POLICY_SESSION	= 0x03000000,
diff --git a/include/linux/tpm_common.h b/include/linux/tpm_common.h
index b8be669913dd..b5c6b2c1e517 100644
--- a/include/linux/tpm_common.h
+++ b/include/linux/tpm_common.h
@@ -19,4 +19,71 @@
 
 #define TPM_MAX_ORDINAL 243
 
+#define TPM_DIGEST_SIZE		20	/* Max TPM v1.2 PCR size */
+#define TPM_HEADER_SIZE		10
+#define TPM_BUFSIZE		4096
+
+#define TPM2_PLATFORM_PCR	24
+#define TPM2_PCR_SELECT_MIN	3
+#define TPM2_MAX_DIGEST_SIZE	SHA512_DIGEST_SIZE
+#define TPM2_MAX_BANKS		4
+
+/* if you add a new hash to this, increment TPM_MAX_HASHES below */
+enum tpm_algorithms {
+	TPM_ALG_ERROR		= 0x0000,
+	TPM_ALG_SHA1		= 0x0004,
+	TPM_ALG_AES		= 0x0006,
+	TPM_ALG_KEYEDHASH	= 0x0008,
+	TPM_ALG_SHA256		= 0x000B,
+	TPM_ALG_SHA384		= 0x000C,
+	TPM_ALG_SHA512		= 0x000D,
+	TPM_ALG_NULL		= 0x0010,
+	TPM_ALG_SM3_256		= 0x0012,
+	TPM_ALG_ECC		= 0x0023,
+	TPM_ALG_CFB		= 0x0043,
+};
+
+/*
+ * The locality (0 - 4) for a TPM, as defined in section 3.2 of the
+ * Client Platform Profile Specification.
+ */
+enum tpm_localities {
+	TPM_LOCALITY_0		= 0, /* Static RTM */
+	TPM_LOCALITY_1		= 1, /* Dynamic OS */
+	TPM_LOCALITY_2		= 2, /* DRTM Environment */
+	TPM_LOCALITY_3		= 3, /* Aux Components */
+	TPM_LOCALITY_4		= 4, /* CPU DRTM Establishment */
+	TPM_MAX_LOCALITY	= TPM_LOCALITY_4
+};
+
+/*
+ * 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
+ * bytes, but 128 is still a relatively large number of random bytes and
+ * anything much bigger causes users of struct tpm_cmd_t to start getting
+ * compiler warnings about stack frame size.
+ */
+#define TPM_MAX_RNG_DATA	128
+
+/*
+ * maximum number of hashing algorithms a TPM can have.  This is
+ * basically a count of every hash in tpm_algorithms above
+ */
+#define TPM_MAX_HASHES	5
+
+struct tpm_digest {
+	u16 alg_id;
+	u8 digest[TPM2_MAX_DIGEST_SIZE];
+} __packed;
+
+#define TPM_HEADER_SIZE		10
+
+struct tpm_header {
+	__be16 tag;
+	__be32 length;
+	union {
+		__be32 ordinal;
+		__be32 return_code;
+	};
+} __packed;
+
 #endif
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 05/28] tpm: Move platform specific definitions to the new PTP header
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (3 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 04/28] tpm: Move TPM common base definitions to new public common header Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 06/28] tpm: Add TPM buffer support header for standalone reuse Ross Philipson
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

These are definitions for the TPM interface and interactions with
the platform as defined in the TCG specification:

TCG PC Client Platform TPM Profile (PTP) Specification
 - https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 drivers/char/tpm/tpm_tis_core.h |  64 +--------------
 include/linux/tpm_ptp.h         | 139 ++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+), 63 deletions(-)
 create mode 100644 include/linux/tpm_ptp.h

diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
index 6c3aa480396b..be68883ed399 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -19,71 +19,9 @@
 #ifndef __TPM_TIS_CORE_H__
 #define __TPM_TIS_CORE_H__
 
+#include <linux/tpm_ptp.h>
 #include "tpm.h"
 
-enum tis_access {
-	TPM_ACCESS_VALID = 0x80,
-	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
-	TPM_ACCESS_REQUEST_PENDING = 0x04,
-	TPM_ACCESS_REQUEST_USE = 0x02,
-};
-
-enum tis_status {
-	TPM_STS_VALID = 0x80,
-	TPM_STS_COMMAND_READY = 0x40,
-	TPM_STS_GO = 0x20,
-	TPM_STS_DATA_AVAIL = 0x10,
-	TPM_STS_DATA_EXPECT = 0x08,
-	TPM_STS_RESPONSE_RETRY = 0x02,
-	TPM_STS_READ_ZERO = 0x23, /* bits that must be zero on read */
-};
-
-enum tis_int_flags {
-	TPM_GLOBAL_INT_ENABLE = 0x80000000,
-	TPM_INTF_BURST_COUNT_STATIC = 0x100,
-	TPM_INTF_CMD_READY_INT = 0x080,
-	TPM_INTF_INT_EDGE_FALLING = 0x040,
-	TPM_INTF_INT_EDGE_RISING = 0x020,
-	TPM_INTF_INT_LEVEL_LOW = 0x010,
-	TPM_INTF_INT_LEVEL_HIGH = 0x008,
-	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
-	TPM_INTF_STS_VALID_INT = 0x002,
-	TPM_INTF_DATA_AVAIL_INT = 0x001,
-};
-
-enum tis_defaults {
-	TIS_MEM_LEN = 0x5000,
-	TIS_SHORT_TIMEOUT = 750,	/* ms */
-	TIS_LONG_TIMEOUT = 4000,	/* 4 secs */
-	TIS_TIMEOUT_MIN_ATML = 14700,	/* usecs */
-	TIS_TIMEOUT_MAX_ATML = 15000,	/* usecs */
-};
-
-/* Some timeout values are needed before it is known whether the chip is
- * TPM 1.0 or TPM 2.0.
- */
-#define TIS_TIMEOUT_A_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A)
-#define TIS_TIMEOUT_B_MAX	max_t(int, TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B)
-#define TIS_TIMEOUT_C_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C)
-#define TIS_TIMEOUT_D_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D)
-
-#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
-#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
-#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
-#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
-#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
-#define	TPM_STS(l)			(0x0018 | ((l) << 12))
-#define	TPM_STS3(l)			(0x001b | ((l) << 12))
-#define	TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
-
-#define	TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
-#define	TPM_RID(l)			(0x0F04 | ((l) << 12))
-
-#define LPC_CNTRL_OFFSET		0x84
-#define LPC_CLKRUN_EN			(1 << 2)
-#define INTEL_LEGACY_BLK_BASE_ADDR	0xFED08000
-#define ILB_REMAP_SIZE			0x100
-
 enum tpm_tis_flags {
 	TPM_TIS_ITPM_WORKAROUND		= 0,
 	TPM_TIS_INVALID_STATUS		= 1,
diff --git a/include/linux/tpm_ptp.h b/include/linux/tpm_ptp.h
new file mode 100644
index 000000000000..9b75a54089a5
--- /dev/null
+++ b/include/linux/tpm_ptp.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ * Debora Velarde <dvelarde@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+#ifndef __LINUX_TPM_PTP_H__
+#define __LINUX_TPM_PTP_H__
+
+/*
+ * TCG PC Client Platform TPM Profile (PTP) Specification
+ * https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
+ */
+
+enum tis_access {
+	TPM_ACCESS_VALID		= 0x80,
+	TPM_ACCESS_ACTIVE_LOCALITY	= 0x20,	/* (R) */
+	TPM_ACCESS_RELINQUISH_LOCALITY	= 0x20, /* (W) */
+	TPM_ACCESS_REQUEST_PENDING	= 0x04,	/* (W) */
+	TPM_ACCESS_REQUEST_USE		= 0x02,	/* (W) */
+};
+
+enum tis_status {
+	TPM_STS_VALID		= 0x80, /* (R) */
+	TPM_STS_COMMAND_READY	= 0x40, /* (R) */
+	TPM_STS_DATA_AVAIL	= 0x10, /* (R) */
+	TPM_STS_DATA_EXPECT	= 0x08, /* (R) */
+	TPM_STS_GO		= 0x20, /* (W) */
+	TPM_STS_RESPONSE_RETRY	= 0x02, /* (R) */
+	TPM_STS_READ_ZERO	= 0x23, /* bits that must be zero on read */
+};
+
+enum tis_int_flags {
+	TPM_GLOBAL_INT_ENABLE		= 0x80000000,
+	TPM_INTF_BURST_COUNT_STATIC	= 0x100,
+	TPM_INTF_CMD_READY_INT		= 0x080,
+	TPM_INTF_INT_EDGE_FALLING	= 0x040,
+	TPM_INTF_INT_EDGE_RISING	= 0x020,
+	TPM_INTF_INT_LEVEL_LOW		= 0x010,
+	TPM_INTF_INT_LEVEL_HIGH		= 0x008,
+	TPM_INTF_LOCALITY_CHANGE_INT	= 0x004,
+	TPM_INTF_STS_VALID_INT		= 0x002,
+	TPM_INTF_DATA_AVAIL_INT		= 0x001,
+};
+
+enum tis_defaults {
+	TIS_MEM_LEN		= 0x5000,
+	TIS_SHORT_TIMEOUT	= 750,   /* ms */
+	TIS_LONG_TIMEOUT	= 4000,  /* 4 secs */
+	TIS_TIMEOUT_MIN_ATML	= 14700, /* usecs */
+	TIS_TIMEOUT_MAX_ATML	= 15000, /* usecs */
+};
+
+/*
+ * Some timeout values are needed before it is known whether the chip is
+ * TPM 1.0 or TPM 2.0.
+ */
+#define TIS_TIMEOUT_A_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A)
+#define TIS_TIMEOUT_B_MAX	max_t(int, TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B)
+#define TIS_TIMEOUT_C_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C)
+#define TIS_TIMEOUT_D_MAX	max_t(int, TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D)
+
+#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
+#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
+#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
+#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
+#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
+#define	TPM_STS(l)			(0x0018 | ((l) << 12))
+#define	TPM_STS3(l)			(0x001b | ((l) << 12))
+#define	TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
+#define	TPM_INTF_ID(l)			(0x0030 | ((l) << 12))
+
+#define	TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
+#define	TPM_RID(l)			(0x0F04 | ((l) << 12))
+
+#define LPC_CNTRL_OFFSET		0x84
+#define LPC_CLKRUN_EN			(1 << 2)
+#define INTEL_LEGACY_BLK_BASE_ADDR	0xFED08000
+#define ILB_REMAP_SIZE			0x100
+
+/* TPM HW Interface and Capabilities */
+#define TPM_TIS_INTF_ACTIVE	0x00
+#define TPM_CRB_INTF_ACTIVE	0x01
+
+struct tpm_interface_id {
+	union {
+		u32 val;
+		struct {
+			u32 interface_type:4;
+			u32 interface_version:4;
+			u32 cap_locality:1;
+			u32 reserved1:4;
+			u32 cap_tis:1;
+			u32 cap_crb:1;
+			u32 cap_if_res:2;
+			u32 interface_selector:2;
+			u32 intf_sel_lock:1;
+			u32 reserved2:4;
+			u32 reserved3:8;
+		};
+	};
+} __packed;
+
+#define TPM_TIS_INTF_12		0x00
+#define TPM_TIS_INTF_13		0x02
+#define TPM2_TIS_INTF_13	0x03
+
+struct tpm_intf_capability {
+	union {
+		u32 val;
+		struct {
+			u32 data_avail_int_support:1;
+			u32 sts_valid_int_support:1;
+			u32 locality_change_int_support:1;
+			u32 interrupt_level_high:1;
+			u32 interrupt_level_low:1;
+			u32 interrupt_edge_rising:1;
+			u32 interrupt_edge_falling:1;
+			u32 command_ready_int_support:1;
+			u32 burst_count_static:1;
+			u32 data_transfer_size_support:2;
+			u32 reserved1:17;
+			u32 interface_version:3;
+			u32 reserved2:1;
+		};
+	};
+} __packed;
+
+#endif
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 06/28] tpm: Add TPM buffer support header for standalone reuse
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (4 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 05/28] tpm: Move platform specific definitions to the new PTP header Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 07/28] tpm: Remove main TPM header from TPM event log header Ross Philipson
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Extact all the functions and definitions for the TPM buffer handling
and separate them into their own header. TPM buf functionality was
decoupled throughout the TPM code base in an earlier commit.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 drivers/char/tpm/tpm-buf.c |  7 ++++-
 include/linux/tpm.h        | 44 +----------------------------
 include/linux/tpm_buf.h    | 57 ++++++++++++++++++++++++++++++++++++++
 include/linux/tpm_common.h | 10 +++++++
 4 files changed, 74 insertions(+), 44 deletions(-)
 create mode 100644 include/linux/tpm_buf.h

diff --git a/drivers/char/tpm/tpm-buf.c b/drivers/char/tpm/tpm-buf.c
index dae23e6de269..f0b6a7453edd 100644
--- a/drivers/char/tpm/tpm-buf.c
+++ b/drivers/char/tpm/tpm-buf.c
@@ -3,8 +3,13 @@
  * Handling of TPM command and other buffers.
  */
 
+#include <linux/types.h>
 #include <linux/module.h>
-#include <linux/tpm.h>
+#include <crypto/sha2.h>
+#include <linux/tpm_common.h>
+#include <linux/tpm1.h>
+#include <linux/tpm2.h>
+#include <linux/tpm_buf.h>
 
 static void __tpm_buf_size_invariant(struct tpm_buf *buf, u16 buf_size)
 {
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 8a778bcc2dd5..4c02076a8c39 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -28,6 +28,7 @@
 #include "tpm_common.h"
 #include "tpm1.h"
 #include "tpm2.h"
+#include "tpm_buf.h"
 
 struct tpm_chip;
 struct trusted_key_payload;
@@ -35,12 +36,6 @@ struct trusted_key_options;
 /* opaque structure, holds auth session parameters like the session key */
 struct tpm2_auth;
 
-struct tpm_bank_info {
-	u16 alg_id;
-	u16 digest_size;
-	u16 crypto_id;
-};
-
 enum TPM_OPS_FLAGS {
 	TPM_OPS_AUTO_STARTUP = BIT(0),
 };
@@ -208,48 +203,11 @@ enum tpm_chip_flags {
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
 
-enum tpm_buf_flags {
-	/* TPM2B format: */
-	TPM_BUF_TPM2B		= BIT(0),
-	/* The buffer is in invalid and unusable state: */
-	TPM_BUF_INVALID		= BIT(1),
-};
-
-/*
- * A buffer for constructing and parsing TPM commands, responses and sized
- * (TPM2B) buffers.
- */
-struct tpm_buf {
-	u8 flags;
-	u8 handles;
-	u16 length;
-	u16 capacity;
-	u8 data[];
-};
-
 struct tpm2_hash {
 	unsigned int crypto_id;
 	unsigned int tpm_id;
 };
 
-void tpm_buf_init(struct tpm_buf *buf, u16 buf_size);
-void tpm_buf_init_sized(struct tpm_buf *buf, u16 buf_size);
-void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal);
-void tpm_buf_reset_sized(struct tpm_buf *buf);
-u32 tpm_buf_length(struct tpm_buf *buf);
-void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length);
-void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value);
-void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value);
-void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value);
-u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset);
-u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset);
-u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset);
-void tpm_buf_append_handle(struct tpm_buf *buf, u32 handle);
-void tpm1_buf_append_extend(struct tpm_buf *buf, u32 pcr_idx, const u8 *hash);
-void tpm2_buf_append_pcr_extend(struct tpm_buf *buf, struct tpm_digest *digests,
-				struct tpm_bank_info *banks,
-				unsigned int nr_banks);
-
 /*
  * Check if TPM device is in the firmware upgrade mode.
  */
diff --git a/include/linux/tpm_buf.h b/include/linux/tpm_buf.h
new file mode 100644
index 000000000000..648fec72e490
--- /dev/null
+++ b/include/linux/tpm_buf.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2004,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Dave Safford <safford@watson.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ * Debora Velarde <dvelarde@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ */
+#ifndef __LINUX_TPM_BUF_H__
+#define __LINUX_TPM_BUF_H__
+
+enum tpm_buf_flags {
+	/* TPM2B format: */
+	TPM_BUF_TPM2B		= BIT(0),
+	/* The buffer is in invalid and unusable state: */
+	TPM_BUF_INVALID		= BIT(1),
+};
+
+/*
+ * A buffer for constructing and parsing TPM commands, responses and sized
+ * (TPM2B) buffers.
+ */
+struct tpm_buf {
+	u8 flags;
+	u8 handles;
+	u16 length;
+	u16 capacity;
+	u8 data[];
+};
+
+void tpm_buf_init(struct tpm_buf *buf, u16 buf_size);
+void tpm_buf_init_sized(struct tpm_buf *buf, u16 buf_size);
+void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal);
+void tpm_buf_reset_sized(struct tpm_buf *buf);
+u32 tpm_buf_length(struct tpm_buf *buf);
+void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length);
+void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value);
+void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value);
+void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value);
+u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset);
+u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset);
+u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset);
+void tpm_buf_append_handle(struct tpm_buf *buf, u32 handle);
+void tpm1_buf_append_extend(struct tpm_buf *buf, u32 pcr_idx, const u8 *hash);
+void tpm2_buf_append_pcr_extend(struct tpm_buf *buf, struct tpm_digest *digests,
+				struct tpm_bank_info *banks,
+				unsigned int nr_banks);
+
+#endif
diff --git a/include/linux/tpm_common.h b/include/linux/tpm_common.h
index b5c6b2c1e517..0577f8182f67 100644
--- a/include/linux/tpm_common.h
+++ b/include/linux/tpm_common.h
@@ -56,6 +56,16 @@ enum tpm_localities {
 	TPM_MAX_LOCALITY	= TPM_LOCALITY_4
 };
 
+/*
+ * Structure to represent active PCR algorithm banks usable by the
+ * TPM.
+ */
+struct tpm_bank_info {
+	u16 alg_id;
+	u16 digest_size;
+	u16 crypto_id;
+};
+
 /*
  * 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
  * bytes, but 128 is still a relatively large number of random bytes and
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 07/28] tpm: Remove main TPM header from TPM event log header
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (5 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 06/28] tpm: Add TPM buffer support header for standalone reuse Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 08/28] tpm/tpm_tis: Close all localities Ross Philipson
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

From: Alec Brown <alec.r.brown@oracle.com>

To allow TPM event log functionality to be used withouth including
the main TPM driver definitions, the main TPM driver header was
removed and replaced by only the required TPM headers.

Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 include/linux/tpm_eventlog.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h
index 891368e82558..cdf54b7a45c2 100644
--- a/include/linux/tpm_eventlog.h
+++ b/include/linux/tpm_eventlog.h
@@ -3,7 +3,9 @@
 #ifndef __LINUX_TPM_EVENTLOG_H__
 #define __LINUX_TPM_EVENTLOG_H__
 
-#include <linux/tpm.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
+#include <linux/tpm_common.h>
 
 #define TCG_EVENT_NAME_LEN_MAX	255
 #define MAX_TEXT_EVENT		1000	/* Max event string length */
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 08/28] tpm/tpm_tis: Close all localities
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (6 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 07/28] tpm: Remove main TPM header from TPM event log header Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 09/28] tpm/tpm_tis: Address positive localities in tpm_tis_request_locality() Ross Philipson
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

From: "Daniel P. Smith" <dpsmith@apertussolutions.com>

There are environments, for example, those that comply with the TCG DRTM
specification that requires the TPM to be left in locality 2. Prepare
kernel for such environments by closing all the localities.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
 drivers/char/tpm/tpm_tis_core.c | 11 ++++++++++-
 include/linux/tpm.h             |  6 ++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 8954a8660ffc..12a2340dd5e0 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -1112,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 	u32 intmask;
 	u32 clkrun_val;
 	u8 rid;
-	int rc, probe;
+	int rc, probe, i;
 	struct tpm_chip *chip;
 
 	chip = tpmm_chip_alloc(dev, &tpm_tis);
@@ -1177,6 +1177,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		goto out_err;
 	}
 
+	/*
+	 * In order to comply with the TCG D-RTM specification, relinquish all
+	 * the localities.
+	 */
+	for (i = 0; i <= TPM_MAX_LOCALITY; i++) {
+		if (check_locality(chip, i))
+			tpm_tis_relinquish_locality(chip, i);
+	}
+
 	/* Take control of the TPM's interrupt hardware and shut it off */
 	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
 	if (rc < 0)
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 4c02076a8c39..87978cc584ee 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -107,6 +107,12 @@ struct tpm_chip_seqops {
  */
 #define TPM2_MAX_CONTEXT_SIZE 4096
 
+/*
+ * The maximum locality (0 - 4) for a TPM, as defined in section 3.2 of the
+ * Client Platform Profile Specification.
+ */
+#define TPM_MAX_LOCALITY		4
+
 struct tpm_chip {
 	struct device dev;
 	struct device devs;
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 09/28] tpm/tpm_tis: Address positive localities in tpm_tis_request_locality()
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (7 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 08/28] tpm/tpm_tis: Close all localities Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 10/28] tpm/tpm_tis: Allow locality to be set to a different value Ross Philipson
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

From: "Daniel P. Smith" <dpsmith@apertussolutions.com>

Validate that the input locality is within the correct range, as specified
by TCG standards, and increase the locality count also for the positive
localities.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
 drivers/char/tpm/tpm_tis_core.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 12a2340dd5e0..14a7e60bfbb8 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -233,10 +233,16 @@ static int tpm_tis_request_locality(struct tpm_chip *chip, int l)
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	int ret = 0;
 
+	if (l < 0 || l > TPM_MAX_LOCALITY) {
+		dev_warn(&chip->dev, "%s: failed to request unknown locality: %d\n",
+			 __func__, l);
+		return -EINVAL;
+	}
+
 	mutex_lock(&priv->locality_count_mutex);
 	if (priv->locality_count == 0)
 		ret = __tpm_tis_request_locality(chip, l);
-	if (!ret)
+	if (ret >= 0)
 		priv->locality_count++;
 	mutex_unlock(&priv->locality_count_mutex);
 	return ret;
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 10/28] tpm/tpm_tis: Allow locality to be set to a different value
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (8 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 09/28] tpm/tpm_tis: Address positive localities in tpm_tis_request_locality() Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:32 ` [PATCH v15 11/28] tpm/sysfs: Show locality used by kernel Ross Philipson
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

DRTM needs to be able to set the locality used by kernel. Provide
a one-shot function tpm_chip_set_locality() for the purpose.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
 drivers/char/tpm/tpm-chip.c     | 34 ++++++++++++++++++++++++++++++++-
 drivers/char/tpm/tpm_tis_core.c |  2 ++
 include/linux/tpm.h             |  4 ++++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 6cb25862688f..3171684ca782 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -44,7 +44,7 @@ static int tpm_request_locality(struct tpm_chip *chip)
 	if (!chip->ops->request_locality)
 		return 0;
 
-	rc = chip->ops->request_locality(chip, 0);
+	rc = chip->ops->request_locality(chip, chip->kernel_locality);
 	if (rc < 0)
 		return rc;
 
@@ -380,6 +380,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
 	}
 
 	chip->locality = -1;
+	chip->kernel_locality = 0;
 	return chip;
 
 out:
@@ -700,3 +701,34 @@ void tpm_chip_unregister(struct tpm_chip *chip)
 	tpm_del_char_device(chip);
 }
 EXPORT_SYMBOL_GPL(tpm_chip_unregister);
+
+/**
+ * tpm_chip_set_locality() - Set the TPM locality kernel uses
+ * @chip:	&tpm_chip instance
+ * @locality:   new locality
+ *
+ * This a one-shot function. Returns zero or POSIX error on failure.
+ */
+int tpm_chip_set_locality(struct tpm_chip *chip, u8 locality)
+{
+	int ret;
+
+	if (locality >= TPM_MAX_LOCALITY)
+		return -EINVAL;
+
+	ret = tpm_try_get_ops(chip);
+	if (ret)
+		return ret;
+
+	if (!(chip->flags & TPM_CHIP_FLAG_SET_LOCALITY_ENABLED)) {
+		tpm_put_ops(chip);
+		return -EPERM;
+	}
+
+	chip->kernel_locality = locality;
+	chip->flags &= ~TPM_CHIP_FLAG_SET_LOCALITY_ENABLED;
+	tpm_put_ops(chip);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tpm_chip_set_locality);
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 14a7e60bfbb8..07e3b6e137f7 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -1125,6 +1125,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 	if (IS_ERR(chip))
 		return PTR_ERR(chip);
 
+	chip->flags |= TPM_CHIP_FLAG_SET_LOCALITY_ENABLED;
+
 #ifdef CONFIG_ACPI
 	chip->acpi_dev_handle = acpi_dev_handle;
 #endif
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 87978cc584ee..11264d04a9ef 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -167,6 +167,8 @@ struct tpm_chip {
 
 	/* active locality */
 	int locality;
+	/* the locality used by kernel */
+	u8 kernel_locality;
 
 #ifdef CONFIG_TCG_TPM2_HMAC
 	/* details for communication security via sessions */
@@ -205,6 +207,7 @@ enum tpm_chip_flags {
 	TPM_CHIP_FLAG_HWRNG_DISABLED		= BIT(9),
 	TPM_CHIP_FLAG_DISABLE			= BIT(10),
 	TPM_CHIP_FLAG_SYNC			= BIT(11),
+	TPM_CHIP_FLAG_SET_LOCALITY_ENABLED	= BIT(12),
 };
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
@@ -252,6 +255,7 @@ static inline ssize_t tpm_ret_to_err(ssize_t ret)
 extern int tpm_is_tpm2(struct tpm_chip *chip);
 extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
 extern void tpm_put_ops(struct tpm_chip *chip);
+int tpm_chip_set_locality(struct tpm_chip *chip, u8 locality);
 extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
 				size_t min_rsp_body_length, const char *desc);
 extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 11/28] tpm/sysfs: Show locality used by kernel
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (9 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 10/28] tpm/tpm_tis: Allow locality to be set to a different value Ross Philipson
@ 2025-12-15 23:32 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 13/28] x86: Secure Launch Kconfig Ross Philipson
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:32 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Expose the current locality used by the kernel TPM driver via
the sysfs interface.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
 drivers/char/tpm/tpm-sysfs.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 530037a3f4ba..375d487565c4 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -309,6 +309,14 @@ static ssize_t tpm_version_major_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(tpm_version_major);
 
+static ssize_t locality_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct tpm_chip *chip = to_tpm_chip(dev);
+
+	return sprintf(buf, "%u\n", chip->kernel_locality);
+}
+static DEVICE_ATTR_RO(locality);
+
 #ifdef CONFIG_TCG_TPM2_HMAC
 static ssize_t null_name_show(struct device *dev, struct device_attribute *attr,
 			      char *buf)
@@ -336,6 +344,7 @@ static struct attribute *tpm1_dev_attrs[] = {
 	&dev_attr_durations.attr,
 	&dev_attr_timeouts.attr,
 	&dev_attr_tpm_version_major.attr,
+	&dev_attr_locality.attr,
 	NULL,
 };
 
@@ -344,6 +353,7 @@ static struct attribute *tpm2_dev_attrs[] = {
 #ifdef CONFIG_TCG_TPM2_HMAC
 	&dev_attr_null_name.attr,
 #endif
+	&dev_attr_locality.attr,
 	NULL
 };
 
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 13/28] x86: Secure Launch Kconfig
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (10 preceding siblings ...)
  2025-12-15 23:32 ` [PATCH v15 11/28] tpm/sysfs: Show locality used by kernel Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-16  3:20   ` Randy Dunlap
  2025-12-15 23:33 ` [PATCH v15 14/28] x86: Secure Launch Resource Table header file Ross Philipson
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Add a Kconfig option for compiling in/out the Secure Launch feature.
Secure Launch is controlled by a singel boolean on/off.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/Kconfig | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index fa3b616af03a..9404d207c420 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1975,6 +1975,20 @@ config EFI_RUNTIME_MAP
 
 	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
 
+config SECURE_LAUNCH
+	bool "Secure Launch DRTM support"
+	depends on X86_64 && X86_X2APIC && TCG_TIS && TCG_CRB
+	select CRYPTO_LIB_SHA1
+	select CRYPTO_LIB_SHA256
+	help
+	  The Secure Launch feature allows a kernel to be launched directly
+	  through a vendor neutral DTRM (Dynamic Root of Trust for Measurement)
+	  solution, with Intel TXT being one example.  The DRTM establishes an
+	  environment where the CPU measures the kernel image, employing the TPM,
+	  before starting it. Secure Launch then continues the measurement chain
+	  over kernel configuration information and other launch artifacts (e.g.
+	  any initramfs image).
+
 source "kernel/Kconfig.hz"
 
 config ARCH_SUPPORTS_KEXEC
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 14/28] x86: Secure Launch Resource Table header file
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (11 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 13/28] x86: Secure Launch Kconfig Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 15/28] x86: Secure Launch main " Ross Philipson
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

The Secure Launch Specification is an architectural agnostic, software neutral
API/ABI maintained by the TrenchBoot project. Its function is to allow any
compliant boot loader to communicate the pre-launch configuration to any
compliant post-launch kernel. The Secure Launch Resource Table, defined
in the specification, presents the programmatic interface for this API/ABI.

The specification can be found here:
https://github.com/TrenchBoot/documentation/blob/master/specifications/secure-launch-specification.rst

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 include/linux/slr_table.h | 308 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 308 insertions(+)
 create mode 100644 include/linux/slr_table.h

diff --git a/include/linux/slr_table.h b/include/linux/slr_table.h
new file mode 100644
index 000000000000..c28bc96d8814
--- /dev/null
+++ b/include/linux/slr_table.h
@@ -0,0 +1,308 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TrenchBoot Secure Launch Resource Table
+ *
+ * The Secure Launch Resource Table (SLRT) is a TrenchBoot project defined
+ * specification to provide a cross-platform interface/ABI between
+ * the Secure Launch components. While most of the table is platform
+ * agnostic, platform or architecture specific entries can be added.
+ *
+ * See TrenchBoot Secure Launch kernel documentation for details.
+ *
+ * Copyright (c) 2025 Apertus Solutions, LLC
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#ifndef _LINUX_SLR_TABLE_H
+#define _LINUX_SLR_TABLE_H
+
+/* SLR table GUID for registering as an EFI Configuration Table (put this in efi.h if it becomes a standard) */
+#define SLR_TABLE_GUID				EFI_GUID(0x877a9b2a, 0x0385, 0x45d1, 0xa0, 0x34, 0x9d, 0xac, 0x9c, 0x9e, 0x56, 0x5f)
+
+/* SLR table header values */
+#define SLR_TABLE_MAGIC		0x4452544d
+#define SLR_TABLE_REVISION	1
+
+/* Current revisions for the policy and UEFI config */
+#define SLR_POLICY_REVISION		1
+#define SLR_UEFI_CONFIG_REVISION	1
+
+/* SLR defined architectures */
+#define SLR_INTEL_TXT		1
+#define SLR_AMD_SKINIT		2
+
+/* SLR defined bootloaders */
+#define SLR_BOOTLOADER_INVALID	0
+#define SLR_BOOTLOADER_GRUB	1
+
+/* Log formats */
+#define SLR_DRTM_TPM12_LOG	1
+#define SLR_DRTM_TPM20_LOG	2
+
+/* DRTM Policy Entry Flags */
+#define SLR_POLICY_FLAG_MEASURED	0x1
+#define SLR_POLICY_IMPLICIT_SIZE	0x2
+
+/* Array Lengths */
+#define TPM_EVENT_INFO_LENGTH		32
+#define TXT_VARIABLE_MTRRS_LENGTH	32
+
+/* Tags */
+#define SLR_ENTRY_INVALID	0x0000
+#define SLR_ENTRY_DL_INFO	0x0001
+#define SLR_ENTRY_LOG_INFO	0x0002
+#define SLR_ENTRY_ENTRY_POLICY	0x0003
+#define SLR_ENTRY_INTEL_INFO	0x0004
+#define SLR_ENTRY_AMD_INFO	0x0005
+#define SLR_ENTRY_ARM_INFO	0x0006
+#define SLR_ENTRY_UEFI_INFO	0x0007
+#define SLR_ENTRY_UEFI_CONFIG	0x0008
+#define SLR_ENTRY_END		0xffff
+
+/* Entity Types */
+#define SLR_ET_UNSPECIFIED	0x0000
+#define SLR_ET_SLRT		0x0001
+#define SLR_ET_BOOT_PARAMS	0x0002
+#define SLR_ET_SETUP_DATA	0x0003
+#define SLR_ET_CMDLINE		0x0004
+#define SLR_ET_UEFI_MEMMAP	0x0005
+#define SLR_ET_RAMDISK		0x0006
+#define SLR_ET_TXT_OS2MLE	0x0010
+#define SLR_ET_UNUSED		0xffff
+
+#ifndef __ASSEMBLER__
+
+/*
+ * Primary Secure Launch Resource Table header
+ */
+struct slr_table {
+	u32 magic;
+	u16 revision;
+	u16 architecture;
+	u32 size;
+	u32 max_size;
+	/* table entries */
+} __packed;
+
+/*
+ * Common SLRT entry header
+ */
+struct slr_entry_hdr {
+	u32 tag;
+	u32 size;
+} __packed;
+
+/*
+ * Boot loader context
+ */
+struct slr_bl_context {
+	u16 bootloader;
+	u16 reserved[3];
+	u64 context;
+} __packed;
+
+/*
+ * Dynamic Launch Callback Function type
+ */
+typedef void (*dl_handler_func)(struct slr_bl_context *bl_context);
+
+/*
+ * DRTM Dynamic Launch Configuration
+ */
+struct slr_entry_dl_info {
+	struct slr_entry_hdr hdr;
+	u64 dce_size;
+	u64 dce_base;
+	u64 dlme_size;
+	u64 dlme_base;
+	u64 dlme_entry;
+	struct slr_bl_context bl_context;
+	u64 dl_handler;
+} __packed;
+
+/*
+ * TPM Log Information
+ */
+struct slr_entry_log_info {
+	struct slr_entry_hdr hdr;
+	u16 format;
+	u16 reserved;
+	u32 size;
+	u64 addr;
+} __packed;
+
+/*
+ * DRTM Measurement Entry
+ */
+struct slr_policy_entry {
+	u16 pcr;
+	u16 entity_type;
+	u16 flags;
+	u16 reserved;
+	u64 size;
+	u64 entity;
+	char evt_info[TPM_EVENT_INFO_LENGTH];
+} __packed;
+
+/*
+ * DRTM Measurement Policy
+ */
+struct slr_entry_policy {
+	struct slr_entry_hdr hdr;
+	u16 reserved[2];
+	u16 revision;
+	u16 nr_entries;
+	struct slr_policy_entry policy_entries[];
+} __packed;
+
+/*
+ * Secure Launch defined MTRR saving structures
+ */
+struct slr_txt_mtrr_pair {
+	u64 mtrr_physbase;
+	u64 mtrr_physmask;
+} __packed;
+
+struct slr_txt_mtrr_state {
+	u64 default_mem_type;
+	u64 mtrr_vcnt;
+	struct slr_txt_mtrr_pair mtrr_pair[TXT_VARIABLE_MTRRS_LENGTH];
+} __packed;
+
+/*
+ * Intel TXT Info table
+ */
+struct slr_entry_intel_info {
+	struct slr_entry_hdr hdr;
+	u64 boot_params_addr;
+	u64 txt_heap;
+	u64 saved_misc_enable_msr;
+	struct slr_txt_mtrr_state saved_bsp_mtrrs;
+} __packed;
+
+/*
+ * UEFI config measurement entry
+ */
+struct slr_uefi_cfg_entry {
+	u16 pcr;
+	u16 reserved;
+	u32 size;
+	u64 cfg; /* address or value */
+	char evt_info[TPM_EVENT_INFO_LENGTH];
+} __packed;
+
+/*
+ * UEFI config measurements
+ */
+struct slr_entry_uefi_config {
+	struct slr_entry_hdr hdr;
+	u16 reserved[2];
+	u16 revision;
+	u16 nr_entries;
+	struct slr_uefi_cfg_entry uefi_cfg_entries[];
+} __packed;
+
+/*
+ * The SLRT is laid out as a Tag-Length-Value (TLV) data structure
+ * allowing a flexible number of entries in the table. An instance
+ * of the slr_table structure is present as a header at the beginning.
+ *
+ * The following functions help to manipulate the SLRT structure
+ * and contents.
+ */
+
+/*
+ * Return the address of the end of the SLRT past the final entry.
+ */
+static inline void *slr_end_of_entries(struct slr_table *table)
+{
+	return (void *)table + table->size;
+}
+
+/*
+ * Return the next entry in the SLRT given the current entry passed
+ * to the function. NULL is returned if there are no entries to return.
+ */
+static inline void *
+slr_next_entry(struct slr_table *table,
+	       struct slr_entry_hdr *curr)
+{
+	struct slr_entry_hdr *next = (struct slr_entry_hdr *)((u8 *)curr + curr->size);
+
+	if ((void *)next >= slr_end_of_entries(table))
+		return NULL;
+	if (next->tag == SLR_ENTRY_END)
+		return NULL;
+
+	return next;
+}
+
+/*
+ * Return the next entry with the given tag in the SLRT starting at the
+ * current entry. If entry is NULL, the search begins at the beginning of
+ * table.
+ */
+static inline void *
+slr_next_entry_by_tag(struct slr_table *table,
+		      struct slr_entry_hdr *entry,
+		      u16 tag)
+{
+	if (!entry) /* Start from the beginning */
+		entry = (struct slr_entry_hdr *)(((u8 *)table) + sizeof(*table));
+
+	for ( ; ; ) {
+		if (entry->tag == tag)
+			return entry;
+
+		entry = slr_next_entry(table, entry);
+		if (!entry)
+			return NULL;
+	}
+
+	return NULL;
+}
+
+/*
+ * Add an entry to the SLRT. Entries are placed at the end.
+ */
+static inline int
+slr_add_entry(struct slr_table *table,
+	      struct slr_entry_hdr *entry)
+{
+	struct slr_entry_hdr *end;
+
+	if ((table->size + entry->size) > table->max_size)
+		return -1;
+
+	memcpy((u8 *)table + table->size - sizeof(*end), entry, entry->size);
+	table->size += entry->size;
+
+	end = (struct slr_entry_hdr *)((u8 *)table + table->size - sizeof(*end));
+	end->tag = SLR_ENTRY_END;
+	end->size = sizeof(*end);
+
+	return 0;
+}
+
+/*
+ * Initialize the SLRT for use. This prepares the meta-data in the SLRT
+ * header section of the table and table end entry.
+ */
+static inline void
+slr_init_table(struct slr_table *slrt, u16 architecture, u32 max_size)
+{
+	struct slr_entry_hdr *end;
+
+	slrt->magic = SLR_TABLE_MAGIC;
+	slrt->revision = SLR_TABLE_REVISION;
+	slrt->architecture = architecture;
+	slrt->size = sizeof(*slrt) + sizeof(*end);
+	slrt->max_size = max_size;
+	end = (struct slr_entry_hdr *)((u8 *)slrt + sizeof(*slrt));
+	end->tag = SLR_ENTRY_END;
+	end->size = sizeof(*end);
+}
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* _LINUX_SLR_TABLE_H */
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 15/28] x86: Secure Launch main header file
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (12 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 14/28] x86: Secure Launch Resource Table header file Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions Ross Philipson
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Introduce the main Secure Launch header file. This header file
contains the platform neutral feature definitions. This includes:
 - Secure Launch error codes
 - DRTM TPM event logging definitions and helper functions
 - Other feature specific structures and definitions

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 include/linux/slaunch.h | 251 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 251 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..330492fcdd8c
--- /dev/null
+++ b/include/linux/slaunch.h
@@ -0,0 +1,251 @@
+/* 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
+
+#include <asm/txt.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
+
+/*
+ * Secure Launch Defined Error Codes used in MLE-initiated TXT resets.
+ *
+ * Intel Trusted Execution Technology (TXT) Software Development Guide
+ * 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 SL_MAX_CPUS		512
+#define SL_BOOT_STACK_SIZE	128
+
+/*
+ * Secure Launch event log entry type. The TXT specification defines the
+ * base event value as 0x400 for DRTM values.
+ *
+ * Intel Trusted Execution Technology (TXT) Software Development Guide
+ * Appendix F - TPM Event Log
+ */
+#define SL_EVTYPE_BASE			0x400
+#define SL_EVTYPE_SECURE_LAUNCH		(SL_EVTYPE_BASE + 0x102)
+
+/*
+ * MLE scratch area offsets within TXT OS-MLE SL defined portion of the heap.
+ */
+#define SL_SCRATCH_AP_EBX		0
+#define SL_SCRATCH_AP_JMP_OFFSET	4
+#define SL_SCRATCH_AP_STACKS_OFFSET	8
+
+#ifndef __ASSEMBLER__
+
+#include <linux/io.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;
+};
+
+/*
+ * Secure Launch defined OS/MLE TXT Heap table
+ *
+ * This table is defined at the top level by the TXT specification
+ * but the format of this structure is implementation specific.
+ *
+ * Intel Trusted Execution Technology (TXT) Software Development Guide
+ * Appendix C - Intel TXT Heap Memory
+ */
+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;
+
+#ifdef CONFIG_SECURE_LAUNCH
+
+/*
+ * TPM event logging functions.
+ */
+
+/*
+ * 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(void);
+void slaunch_fixup_ap_wake_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_reset(void *ctx, 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(void)
+{
+}
+
+static inline void slaunch_fixup_ap_wake_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 /* !CONFIG_SECURE_LAUNCH */
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* _LINUX_SLAUNCH_H */
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (13 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 15/28] x86: Secure Launch main " Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-16 22:14   ` Dave Hansen
  2025-12-15 23:33 ` [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements Ross Philipson
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Intel TXT architectural specific definitions. See the specification
for detailed information:

https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/include/asm/txt.h | 330 +++++++++++++++++++++++++++++++++++++
 1 file changed, 330 insertions(+)
 create mode 100644 arch/x86/include/asm/txt.h

diff --git a/arch/x86/include/asm/txt.h b/arch/x86/include/asm/txt.h
new file mode 100644
index 000000000000..3886fd7b248a
--- /dev/null
+++ b/arch/x86/include/asm/txt.h
@@ -0,0 +1,330 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Intel Trusted eXecution Technology (TXT) Definitions
+ *
+ * Copyright (c) 2025 Apertus Solutions, LLC
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#ifndef _ASM_X86_TXT_H
+#define _ASM_X86_TXT_H
+
+/*
+ * Intel Safer Mode Extensions (SMX)
+ *
+ * Intel SMX provides a programming interface to establish a Measured Launched
+ * Environment (MLE). The measurement and protection mechanisms are 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_RLP_WAKE_GETSEC	0
+#define TXT_SINIT_MLE_CAP_RLP_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
+
+#ifndef __ASSEMBLER__
+
+/*
+ * 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;
+
+/*
+ * 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;
+	u32 sinit_flags;
+	u32 mle_flags;
+	/* Versions >= 5 with updates in version 6 */
+	/* 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);
+}
+
+/*
+ * 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*
+txt_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
+{
+	struct txt_heap_ext_data_element *ext_elem;
+
+	/* The extended element array is 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;
+}
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* _ASM_X86_TXT_H */
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (14 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-16  0:21   ` Eric Biggers
  2025-12-15 23:33 ` [PATCH v15 18/28] x86: Add early SHA-256 " Ross Philipson
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

From: "Daniel P. Smith" <dpsmith@apertussolutions.com>

Secure Launch is written to be compliant with the Intel TXT Measured Launch
Developer's Guide. The MLE Guide dictates that the system can be configured to
use both the SHA-1 and SHA-2 hashing algorithms.

Regardless of the preference towards SHA-2, if the firmware elected to start
with the SHA-1 and SHA-2 banks active and the dynamic launch was configured to
include SHA-1, Secure Launch is obligated to record measurements for all
algorithms requested in the launch configuration.

The user environment or the integrity management does not desire to use SHA-1,
it is free to just ignore the SHA-1 bank in any integrity operation with the
TPM. If there is a larger concern about the SHA-1 bank being active, it is free
to deliberately cap the SHA-1 PCRs, recording the event in the D-RTM log.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/boot/compressed/Makefile | 4 ++++
 arch/x86/boot/compressed/sha1.c   | 7 +++++++
 2 files changed, 11 insertions(+)
 create mode 100644 arch/x86/boot/compressed/sha1.c

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 74657589264d..69592146ced7 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -112,6 +112,10 @@ ifdef CONFIG_EFI_SBAT
 $(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)
 endif
 
+slaunch-objs += $(obj)/sha1.o
+
+vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(slaunch-objs)
+
 $(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
 	$(call if_changed,ld)
 
diff --git a/arch/x86/boot/compressed/sha1.c b/arch/x86/boot/compressed/sha1.c
new file mode 100644
index 000000000000..dd1b4cf5caf5
--- /dev/null
+++ b/arch/x86/boot/compressed/sha1.c
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Apertus Solutions, LLC.
+ */
+
+#undef CONFIG_CRYPTO_LIB_SHA1_ARCH
+#include "../../../../lib/crypto/sha1.c"
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 18/28] x86: Add early SHA-256 support for Secure Launch early measurements
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (15 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver Ross Philipson
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

From: "Daniel P. Smith" <dpsmith@apertussolutions.com>

The SHA-256 algorithm is necessary to measure configuration information into
the TPM as early as possible before using the values. This implementation
uses the established approach of #including the SHA-256 libraries directly in
the code since the compressed kernel is not uncompressed at this point.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/boot/compressed/Makefile | 1 +
 arch/x86/boot/compressed/sha256.c | 6 ++++++
 2 files changed, 7 insertions(+)
 create mode 100644 arch/x86/boot/compressed/sha256.c

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 69592146ced7..0ea8a11ec271 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -113,6 +113,7 @@ $(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE)
 endif
 
 slaunch-objs += $(obj)/sha1.o
+slaunch-objs += $(obj)/sha256.o
 
 vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(slaunch-objs)
 
diff --git a/arch/x86/boot/compressed/sha256.c b/arch/x86/boot/compressed/sha256.c
new file mode 100644
index 000000000000..7795926e7e1d
--- /dev/null
+++ b/arch/x86/boot/compressed/sha256.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Apertus Solutions, LLC
+ */
+
+#include "../../../../lib/crypto/sha256.c"
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (16 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 18/28] x86: Add early SHA-256 " Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-16 21:53   ` Dave Hansen
  2025-12-15 23:33 ` [PATCH v15 20/28] x86/msr: Add variable MTRR base/mask and x2apic ID registers Ross Philipson
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Introduce an early driver that can interact minimally with the
TPM. This allows the Secure Launch startup code to extend measurement
values into the TPM's DRTM PCR banks early in the launch process.

This driver implementation is very minimal, only supporting basic
initialization and extend commands. An extend command can be sent to both
a TPM 2.0 or 1.2 chip but only the TIS/FIFO interface is currently
supported. The CRB interface is currently not supported. The TCG specs
for these interface can be found here:

https://trustedcomputinggroup.org/resource/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis/
https://trustedcomputinggroup.org/resource/tpm-2-0-mobile-command-response-buffer-interface-specification/

The driver could be extended for further operations if needed. This
TPM dirver implementation relies as much as possible on existing mainline
kernel TPM code.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/boot/compressed/Makefile           |   1 +
 arch/x86/boot/compressed/early_tpm_extend.c | 601 ++++++++++++++++++++
 arch/x86/boot/compressed/tpm.h              |  42 ++
 3 files changed, 644 insertions(+)
 create mode 100644 arch/x86/boot/compressed/early_tpm_extend.c
 create mode 100644 arch/x86/boot/compressed/tpm.h

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 0ea8a11ec271..b108e0edf367 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -114,6 +114,7 @@ endif
 
 slaunch-objs += $(obj)/sha1.o
 slaunch-objs += $(obj)/sha256.o
+slaunch-objs += $(obj)/early_tpm_extend.o
 
 vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(slaunch-objs)
 
diff --git a/arch/x86/boot/compressed/early_tpm_extend.c b/arch/x86/boot/compressed/early_tpm_extend.c
new file mode 100644
index 000000000000..7cfdb7969878
--- /dev/null
+++ b/arch/x86/boot/compressed/early_tpm_extend.c
@@ -0,0 +1,601 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense.  All rights reserved.
+ *
+ * based off of the original tools/vtpm_manager code base which is:
+ * Copyright (c) 2005, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <crypto/sha2.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+
+#include <linux/tpm_common.h>
+#include <linux/tpm1.h>
+#include <linux/tpm2.h>
+#include <linux/tpm_ptp.h>
+#include <linux/tpm_buf.h>
+
+#include "../../../../drivers/char/tpm/tpm1_structs.h"
+#include "../../../../drivers/char/tpm/tpm2_structs.h"
+
+#include "tpm.h"
+
+static u8 tpm_buf_page[PAGE_SIZE];
+
+/*
+ * Single threaded environment only running on BSP. Use a single shared
+ * page for all TPM extend operations.
+ */
+static inline struct tpm_buf *tpm_buf_alloc_page(void)
+{
+	memset(tpm_buf_page, 0, PAGE_SIZE);
+	return (struct tpm_buf *)tpm_buf_page;
+}
+
+static inline void tpm_buf_free_page(void)
+{
+	memset(tpm_buf_page, 0, PAGE_SIZE);
+}
+
+/* Pull in TPM buffer management support */
+#undef WARN
+#define WARN(c, f...)
+#undef WARN_ON
+#define WARN_ON(c) (0)
+
+#include "../../../../drivers/char/tpm/tpm-buf.c"
+
+static u32 tpm_get_alg_size(u16 alg_id)
+{
+	switch (alg_id) {
+	case TPM_ALG_SHA1:
+		return TPM_DIGEST_SIZE;
+	case TPM_ALG_SHA256:
+	case TPM_ALG_SM3_256:
+		return SHA256_DIGEST_SIZE;
+	case TPM_ALG_SHA384:
+		return SHA384_DIGEST_SIZE;
+	case TPM_ALG_SHA512:
+	default:
+		return SHA512_DIGEST_SIZE;
+	};
+}
+
+static inline u8 tpm_read8(struct tpm_chip *chip, u32 field)
+{
+	void *mmio_addr = (void *)(uintptr_t)(chip->baseaddr | field);
+	return readb(mmio_addr);
+}
+
+static inline void tpm_write8(struct tpm_chip *chip, u32 field, u8 val)
+{
+	void *mmio_addr = (void *)(uintptr_t)(chip->baseaddr | field);
+	writeb(val, mmio_addr);
+}
+
+static inline u32 tpm_read32(struct tpm_chip *chip, u32 field)
+{
+	void *mmio_addr = (void *)(uintptr_t)(chip->baseaddr | field);
+	return readl(mmio_addr);
+}
+
+static inline void tpm_write32(struct tpm_chip *chip, u32 field, u32 val)
+{
+	void *mmio_addr = (void *)(uintptr_t)(chip->baseaddr | field);
+	writel(val, mmio_addr);
+}
+
+static unsigned long ticks_per_ms = (5UL * 1000 * 1000 /* cpu_khz */ / 1000);
+
+static inline ktime_t tpm_now_ms(void)
+{
+	return rdtsc()/ticks_per_ms;
+}
+
+/*
+ * We're far too early to calibrate time.  Assume a 5GHz processor (the upper
+ * end of the Fam19h range), which causes us to be wrong in the safe direction
+ * on slower systems.
+ */
+static inline void tpm_mdelay(unsigned int msecs)
+{
+	unsigned long ticks = msecs * ticks_per_ms;
+	unsigned long s, e;
+
+	s = rdtsc();
+	do {
+		cpu_relax();
+		e = rdtsc();
+	} while ((e - s) < ticks);
+}
+
+static inline u8 __tis_status(struct tpm_chip *chip)
+{
+	return tpm_read8(chip, TPM_STS(chip->locality));
+}
+
+static inline void __tis_cancel(struct tpm_chip *chip)
+{
+	/* This causes the current command to be aborted */
+	tpm_write8(chip, TPM_STS(chip->locality), TPM_STS_COMMAND_READY);
+}
+
+static int __tis_get_burstcount(struct tpm_chip *chip)
+{
+	ktime_t stop;
+	int burstcnt;
+
+	stop = tpm_now_ms() + chip->timeout_d;
+	do {
+		burstcnt = tpm_read8(chip, (TPM_STS(chip->locality) + 1));
+		burstcnt += tpm_read8(chip, TPM_STS(chip->locality) + 2) << 8;
+
+		if (burstcnt)
+			return burstcnt;
+
+		tpm_mdelay(TPM_TIMEOUT);
+	} while (tpm_now_ms() < stop);
+
+	return -EBUSY;
+}
+
+static int __tis_wait_for_stat(struct tpm_chip *chip, u8 mask, ktime_t timeout)
+{
+	ktime_t stop;
+	u8 status;
+
+	if ((__tis_status(chip) & mask) == mask)
+		return 0;
+
+	stop = tpm_now_ms() + timeout;
+	do {
+		tpm_mdelay(TPM_TIMEOUT);
+
+		status = __tis_status(chip);
+		if ((status & mask) == mask)
+			return 0;
+	} while (tpm_now_ms() < stop);
+
+	return -ETIME;
+}
+
+static int __tis_recv_data(struct tpm_chip *chip, u8 *buf, int count)
+{
+	int size = 0;
+	int burstcnt;
+
+	while (size < count && __tis_wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, chip->timeout_c) == 0) {
+		burstcnt = __tis_get_burstcount(chip);
+
+		for ( ; burstcnt > 0 && size < count; --burstcnt)
+			buf[size++] = tpm_read8(chip, TPM_DATA_FIFO(chip->locality));
+	}
+
+	return size;
+}
+
+/**
+ * tpm_tis_check_locality - Check if the given locality is the active one
+ * @chip:	The TPM chip instance
+ * @loc:	The locality to check
+ *
+ * Return: true - locality active, false - not active
+ */
+bool tpm_tis_check_locality(struct tpm_chip *chip, int loc)
+{
+	if ((tpm_read8(chip, TPM_ACCESS(loc)) & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+		chip->locality = loc;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * tpm_tis_release_locality - Release the active locality
+ * @chip:	The TPM chip instance
+ */
+void tpm_tis_release_locality(struct tpm_chip *chip)
+{
+	if ((tpm_read8(chip, TPM_ACCESS(chip->locality)) & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
+		tpm_write8(chip, TPM_ACCESS(chip->locality), TPM_ACCESS_RELINQUISH_LOCALITY);
+
+	chip->locality = 0;
+}
+
+/**
+ * tpm_tis_request_locality - Request to make the given locality the active one
+ * @chip:	The TPM chip instance
+ * @loc:	The locality to make active/set as current
+ *
+ * Return:
+ *  >= 0 - Success, new active locality returned or locality already active
+ *  < 0  - Error occurred
+ */
+int tpm_tis_request_locality(struct tpm_chip *chip, int loc)
+{
+	ktime_t stop;
+
+	if (tpm_tis_check_locality(chip, loc))
+		return loc;
+
+	/* Set the new locality */
+	tpm_write8(chip, TPM_ACCESS(loc), TPM_ACCESS_REQUEST_USE);
+
+	stop = tpm_now_ms() + chip->timeout_b;
+	do {
+		if (tpm_tis_check_locality(chip, loc))
+			return loc;
+
+		tpm_mdelay(TPM_TIMEOUT);
+	} while (tpm_now_ms() < stop);
+
+	return -1;
+}
+
+/**
+ * tpm_tis_disable_interrupts - Disable interrupts for the TPM, use polling mode only
+ * @chip:	The TPM chip instance
+ */
+void tpm_tis_disable_interrupts(struct tpm_chip *chip)
+{
+	u32 intmask;
+
+	intmask = tpm_read32(chip, TPM_INT_ENABLE(chip->locality));
+	/* Disable everything to make sure it is in a consistent state */
+	intmask &= ~(TPM_GLOBAL_INT_ENABLE | TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT | TPM_INTF_DATA_AVAIL_INT);
+	tpm_write32(chip, TPM_INT_ENABLE(chip->locality), intmask);
+}
+
+/**
+ * tpm_tis_recv - Receive response data from TPM via TIS FIFO
+ * @chip:	The TPM chip instance
+ * @buf:	The response buffer
+ * @count:	Length of the response buffer
+ *
+ * Return:
+ *  = 0 - Success, no response data
+ *  > 0 - Success, value is the response data length
+ *  < 0 - Error occurred
+ */
+static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, int count)
+{
+	int expected, status, size = 0, rc = -EIO;
+
+	if (count < TPM_HEADER_SIZE)
+		goto out;
+
+	/* Read first 10 bytes, including tag, paramsize, and result */
+	size = __tis_recv_data(chip, buf, TPM_HEADER_SIZE);
+	if (size < TPM_HEADER_SIZE)
+		goto out;
+
+	expected = be32_to_cpu(*((u32 *)(buf + 2)));
+	if (expected > count)
+		goto out;
+
+	size += __tis_recv_data(chip, &buf[TPM_HEADER_SIZE], expected - TPM_HEADER_SIZE);
+	if (size < expected) {
+		rc = -ETIME;
+		goto out;
+	}
+
+	__tis_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c);
+
+	status = __tis_status(chip);
+	if (status & TPM_STS_DATA_AVAIL) {
+		rc = -EIO;
+		goto out;
+	}
+
+	return size;
+out:
+	__tis_cancel(chip);
+	tpm_tis_release_locality(chip);
+	return rc;
+}
+
+/**
+ * tpm_tis_send - Send command to TPM via TIS FIFO
+ * @chip:	The TPM chip instance
+ * @buf:	The command buffer
+ * @len:	Length of the command buffer to send
+ *
+ * Return:
+ *  = len - Success, all data sent
+ *  < 0	  - Error occurred
+ */
+static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, int len)
+{
+	int status, burstcnt = 0;
+	int count = 0;
+	int rc = 0;
+
+	status = __tis_status(chip);
+	if ((status & TPM_STS_COMMAND_READY) == 0) {
+		__tis_cancel(chip);
+		if (__tis_wait_for_stat(chip, TPM_STS_COMMAND_READY, chip->timeout_b) < 0) {
+			rc = -ETIME;
+			goto out_err;
+		}
+	}
+
+	while (count < len - 1) {
+		burstcnt = __tis_get_burstcount(chip);
+		for ( ; burstcnt > 0 && count < len - 1; --burstcnt)
+			tpm_write8(chip, TPM_DATA_FIFO(chip->locality), buf[count++]);
+
+		__tis_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c);
+		status = __tis_status(chip);
+		if ((status & TPM_STS_DATA_EXPECT) == 0) {
+			rc = -EIO;
+			goto out_err;
+		}
+	}
+
+	/* Write last byte */
+	tpm_write8(chip, TPM_DATA_FIFO(chip->locality), buf[count]);
+	__tis_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c);
+	status = __tis_status(chip);
+	if ((status & TPM_STS_DATA_EXPECT) != 0) {
+		rc = -EIO;
+		goto out_err;
+	}
+
+	/* Go and do it */
+	tpm_write8(chip, TPM_STS(chip->locality), TPM_STS_GO);
+
+	return len;
+
+out_err:
+	__tis_cancel(chip);
+	tpm_tis_release_locality(chip);
+	return rc;
+}
+
+/**
+ * tpm_tis_transmit - Transmit a TPM FIFO command
+ * @chip:	The TPM chip instance
+ * @buf:	The request and response buffer object
+ * @bufsize:	Entire size available in buffer
+ *
+ * Return:
+ *  = 0 - Success, no returned data
+ *  > 0 - Success, value is the return data length
+ *  < 0 - Error occurred
+ */
+static int tpm_tis_transmit(struct tpm_chip *chip, u8 *buf, u32 bufsize)
+{
+	ktime_t stop;
+	u32 count;
+	u8 status;
+	int rc;
+
+	count = be32_to_cpu(*((u32 *) (buf + 2)));
+	if (count == 0)
+		return -ENODATA;
+
+	if (count > bufsize)
+		return -E2BIG;
+
+	rc = tpm_tis_send(chip, buf, count);
+	if (rc < 0)
+		goto out;
+
+	stop = tpm_now_ms() + TIS_DURATION;
+	do {
+		status = __tis_status(chip);
+		if ((status & (TPM_STS_DATA_AVAIL | TPM_STS_VALID)) == (TPM_STS_DATA_AVAIL | TPM_STS_VALID))
+			goto out_recv;
+
+		if (status == TPM_STS_COMMAND_READY) {
+			rc = -ECANCELED;
+			goto out;
+		}
+
+		tpm_mdelay(TPM_TIMEOUT);
+		rmb();
+	} while (tpm_now_ms() < stop);
+
+	/* Cancel the command */
+	__tis_cancel(chip);
+	rc = -ETIME;
+	goto out;
+
+out_recv:
+	rc = tpm_tis_recv(chip, buf, bufsize);
+	if (rc >= 0) {
+		if (rc > 0 && rc < TPM_HEADER_SIZE)
+			return -EFAULT;
+		return rc;
+	}
+	/* Else return was an error, nothing to receive */
+
+out:
+	return rc;
+}
+
+/**
+ * tpm_find_interface_and_family - interface FIFO/CRB, family 2.0 or 1.2
+ * @chip:	The TPM chip instance
+ *
+ * Return: TPM family ID enum
+ */
+static enum tpm_family tpm_find_interface_and_family(struct tpm_chip *chip)
+{
+	struct tpm_intf_capability intf_cap;
+	struct tpm_interface_id intf_id;
+
+	/* Sort out whether it is 1.x */
+	intf_cap.val = tpm_read32(chip, TPM_INTF_CAPS(0));
+	if ((intf_cap.interface_version == TPM_TIS_INTF_12) ||
+	    (intf_cap.interface_version == TPM_TIS_INTF_13))
+		return TPM_FAMILY_12; /* Always TIS */
+
+	/* Assume that it is 2.0 but check if the interface is CRB */
+	intf_id.val = tpm_read32(chip, TPM_INTF_ID(0));
+	if (intf_id.interface_type == TPM_CRB_INTF_ACTIVE)
+		return TPM_FAMILY_INVALID;
+
+	/* Else TPM 2.0 with TIS interface */
+	return TPM_FAMILY_20;
+}
+
+/**
+ * tpm1_pcr_extend - send a TPM1 extend command to the device
+ * @chip:	a TPM chip to use
+ * @pcr_idx:	the PCR index to extend for the current locality
+ * @hash:	the SHA1 hash digest to extend
+ *
+ * Return:
+ * * 0		- OK
+ * * -errno	- A system error
+ * * TPM_RC	- A TPM error
+ */
+int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash)
+{
+	int rc = 0;
+	struct tpm_buf *buf = tpm_buf_alloc_page();
+
+	if (!buf)
+		return -ENOMEM;
+
+	tpm_buf_init(buf, TPM_BUFSIZE);
+	tpm_buf_reset(buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND);
+
+	tpm_buf_append_u32(buf, pcr_idx);
+	tpm_buf_append(buf, hash, TPM_DIGEST_SIZE);
+
+	rc = tpm_tis_transmit(chip, buf->data, PAGE_SIZE);
+
+	/* Ignoring output */
+	if (rc > 0)
+		rc = 0;
+
+	tpm_buf_free_page();
+
+	return rc;
+}
+
+/**
+ * tpm2_pcr_extend() - send a TPM2 extend command to the device
+ *
+ * @chip:		TPM chip to use.
+ * @pcr_idx:		index of the PCR.
+ * @digests:		list of PCR banks and corresponding digest values to extend.
+ * @digest_count:	count of digests to extend
+ *
+ * Return:
+ * * 0		- OK
+ * * -errno	- A system error
+ * * TPM_RC	- A TPM error
+ */
+int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
+		    struct tpm_digest *digests, u32 digest_count)
+{
+	struct tpm_buf *buf = tpm_buf_alloc_page();
+	int rc = 0, i;
+
+	if (!buf)
+		return -ENOMEM;
+
+	tpm_buf_init(buf, TPM_BUFSIZE);
+	tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+
+	tpm_buf_append_handle(buf, pcr_idx);
+
+	/* Setup a NULL auth session for the command */
+	tpm_buf_append_u32(buf, 9);
+	/* auth handle */
+	tpm_buf_append_u32(buf, TPM2_RS_PW);
+	/* nonce */
+	tpm_buf_append_u16(buf, 0);
+	/* attributes */
+	tpm_buf_append_u8(buf, 0);
+	/* passphrase */
+	tpm_buf_append_u16(buf, 0);
+
+	tpm_buf_append_u32(buf, digest_count);
+
+	for (i = 0; i < digest_count; i++) {
+		tpm_buf_append_u16(buf, digests[i].alg_id);
+		tpm_buf_append(buf, (const unsigned char *)&digests[i].digest,
+			       tpm_get_alg_size(digests[i].alg_id));
+	}
+
+	rc = tpm_tis_transmit(chip, buf->data, PAGE_SIZE);
+
+	/* Ignoring output */
+	if (rc > 0)
+		rc = 0;
+
+	tpm_buf_free_page();
+
+	return rc;
+}
+
+int early_tpm_init(struct tpm_chip *chip, u64 baseaddr)
+{
+	u32 didvid;
+
+	memset(chip, 0, sizeof(*chip));
+	chip->baseaddr = baseaddr;
+
+	chip->family = tpm_find_interface_and_family(chip);
+	if (chip->family == TPM_FAMILY_INVALID)
+		return TPM_ERR_INVALID_FAMILY;
+
+	/* Set default timeouts */
+	chip->timeout_a = TIS_SHORT_TIMEOUT;
+	chip->timeout_b = TIS_LONG_TIMEOUT;
+	chip->timeout_c = TIS_SHORT_TIMEOUT;
+	chip->timeout_d = TIS_SHORT_TIMEOUT;
+
+	/* Get the vendor and device ids */
+	didvid = tpm_read32(chip, TPM_DID_VID(0));
+	chip->did = didvid >> 16;
+	chip->vid = didvid & 0xFFFF;
+
+	return TPM_SUCCESS;
+}
+
+int early_tpm_fini(struct tpm_chip *chip)
+{
+	tpm_tis_release_locality(chip);
+	memset(chip, 0, sizeof(*chip));
+
+	return TPM_SUCCESS;
+}
diff --git a/arch/x86/boot/compressed/tpm.h b/arch/x86/boot/compressed/tpm.h
new file mode 100644
index 000000000000..6986593e0100
--- /dev/null
+++ b/arch/x86/boot/compressed/tpm.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef BOOT_COMPRESSED_TPM_H
+#define BOOT_COMPRESSED_TPM_H
+
+enum early_tis_defaults {
+	TIS_MEM_X86_LPC_BASE	= 0xFED40000,
+	TIS_MEM_X86_LEN		= 0x5000,
+	TPM_TIMEOUT		= 5, /* ms */
+	TIS_DURATION		= 120000, /* 120 secs in ms */
+};
+
+enum tpm_family {
+	TPM_FAMILY_INVALID	= 0,
+	TPM_FAMILY_12		= 1,
+	TPM_FAMILY_20		= 2
+};
+
+struct tpm_chip {
+	enum tpm_family family;
+	u64 baseaddr;
+	int locality;
+	int did;
+	int vid;
+
+	/* in ms */
+	ktime_t timeout_a;
+	ktime_t timeout_b;
+	ktime_t timeout_c;
+	ktime_t timeout_d;
+};
+
+bool tpm_tis_check_locality(struct tpm_chip *chip, int loc);
+void tpm_tis_release_locality(struct tpm_chip *chip);
+int tpm_tis_request_locality(struct tpm_chip *chip, int loc);
+void tpm_tis_disable_interrupts(struct tpm_chip *chip);
+int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash);
+int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
+		    struct tpm_digest *digests, u32 digest_count);
+int early_tpm_init(struct tpm_chip *chip, u64 baseaddr);
+int early_tpm_fini(struct tpm_chip *chip);
+
+#endif /* BOOT_COMPRESSED_TPM_H */
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 20/28] x86/msr: Add variable MTRR base/mask and x2apic ID registers
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (17 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 21/28] x86/boot: Place TXT MLE header in the kernel_info section Ross Philipson
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Add the MSR values required by Secure Launch to locate particular CPU cores
during application processor (AP) startup, and restore the MTRR state after
an Intel TXT launch.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/include/asm/msr-index.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 9e1720d73244..ae620e609101 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -379,6 +379,9 @@
 #define MSR_IA32_RTIT_OUTPUT_BASE	0x00000560
 #define MSR_IA32_RTIT_OUTPUT_MASK	0x00000561
 
+#define MSR_MTRRphysBase0		0x00000200
+#define MSR_MTRRphysMask0		0x00000201
+
 #define MSR_MTRRfix64K_00000		0x00000250
 #define MSR_MTRRfix16K_80000		0x00000258
 #define MSR_MTRRfix16K_A0000		0x00000259
@@ -928,6 +931,8 @@
 #define MSR_IA32_APICBASE_ENABLE	(1<<11)
 #define MSR_IA32_APICBASE_BASE		(0xfffff<<12)
 
+#define MSR_IA32_X2APIC_APICID		0x00000802
+
 #define MSR_IA32_UCODE_WRITE		0x00000079
 #define MSR_IA32_UCODE_REV		0x0000008b
 
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 21/28] x86/boot: Place TXT MLE header in the kernel_info section
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (18 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 20/28] x86/msr: Add variable MTRR base/mask and x2apic ID registers Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 23/28] x86: Secure Launch kernel late boot stub Ross Philipson
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

The Measured Launch Environment (MLE) header must be locatable by the
boot loader and Intel TXT must be setup to do a launch with this header's
location. While the offset to the kernel_info structure does not need
to be at a fixed offset, the offsets in the header must be relative
offsets from the start of the setup kernel. Note that from the viewpoint
of the prelaunch phase and TXT, the setup kernel image as loaded into
memory is the MLE image.

The changes to the linker file achieve this by making available the
offset values which are updated in the MLE header structure. The following
are the needed offsets from the beginning of the setup kernel image:

- kernel_info_offset: Offset of the main kernel_info structure.
- mle_header_offset: Offset of the MLE header structure.
- sl_stub_entry_offset: Offset of the Secure Launch initial entry point.
- _edata_offset: Offset of the _edata label used as the end of the MLE image.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Suggested-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/boot/compressed/kernel_info.S | 50 +++++++++++++++++++++++---
 arch/x86/boot/compressed/vmlinux.lds.S |  7 ++++
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/arch/x86/boot/compressed/kernel_info.S b/arch/x86/boot/compressed/kernel_info.S
index f818ee8fba38..e3c9816eacbf 100644
--- a/arch/x86/boot/compressed/kernel_info.S
+++ b/arch/x86/boot/compressed/kernel_info.S
@@ -1,12 +1,20 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
+#include <linux/linkage.h>
 #include <asm/bootparam.h>
 
-	.section ".rodata.kernel_info", "a"
+/*
+ * The kernel_info structure is not placed at a fixed offset in the
+ * kernel image. So this macro and the support in the linker file
+ * allow the relative offsets for the MLE header within the kernel
+ * image to be configured at build time.
+ */
+#define roffset(X) ((X) - kernel_info)
 
-	.global kernel_info
+	.section ".rodata.kernel_info", "a"
 
-kernel_info:
+	.balign	16
+SYM_DATA_START(kernel_info)
 	/* Header, Linux top (structure). */
 	.ascii	"LToP"
 	/* Size. */
@@ -17,6 +25,40 @@ kernel_info:
 	/* Maximal allowed type for setup_data and setup_indirect structs. */
 	.long	SETUP_TYPE_MAX
 
+	/* Offset to the MLE header structure */
+#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
+	.long	roffset(mle_header_offset)
+#else
+	.long	0
+#endif
+
 kernel_info_var_len_data:
 	/* Empty for time being... */
-kernel_info_end:
+SYM_DATA_END_LABEL(kernel_info, SYM_L_LOCAL, kernel_info_end)
+
+#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
+	/*
+	 * The MLE Header per the TXT Specification, section 2.1
+	 * MLE capabilities, see table 4. Capabilities set:
+	 * bit 0: Support for GETSEC[WAKEUP] for RLP wakeup
+	 * bit 1: Support for RLP wakeup using MONITOR address
+	 * bit 2: The ECX register will contain the pointer to the MLE page table
+	 * bit 5: TPM 1.2 family: Details/authorities PCR usage support
+	 * bit 9: Supported format of TPM 2.0 event log - TCG compliant
+	 */
+SYM_DATA_START(mle_header)
+	.long	0x9082ac5a			/* UUID0 */
+	.long	0x74a7476f			/* UUID1 */
+	.long	0xa2555c0f			/* UUID2 */
+	.long	0x42b651cb			/* UUID3 */
+	.long	0x00000034			/* MLE header size */
+	.long	0x00020002			/* MLE version 2.2 */
+	.long	roffset(sl_stub_entry_offset)	/* Linear entry point of MLE (virt. address) */
+	.long	0x00000000			/* First valid page of MLE */
+	.long	0x00000000			/* Offset within binary of first byte of MLE */
+	.long	roffset(_edata_offset)		/* Offset within binary of last byte + 1 of MLE */
+	.long	0x00000227			/* Bit vector of MLE-supported capabilities */
+	.long	0x00000000			/* Starting linear address of command line (unused) */
+	.long	0x00000000			/* Ending linear address of command line (unused) */
+SYM_DATA_END(mle_header)
+#endif
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S
index 587ce3e7c504..d061ae6046b2 100644
--- a/arch/x86/boot/compressed/vmlinux.lds.S
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -126,3 +126,10 @@ SECTIONS
 	}
 	ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
 }
+
+#ifdef CONFIG_SECURE_LAUNCH
+PROVIDE(kernel_info_offset      = ABSOLUTE(kernel_info - startup_32));
+PROVIDE(mle_header_offset       = kernel_info_offset + ABSOLUTE(mle_header - startup_32));
+PROVIDE(sl_stub_entry_offset    = kernel_info_offset + ABSOLUTE(sl_stub_entry - startup_32));
+PROVIDE(_edata_offset           = kernel_info_offset + ABSOLUTE(_edata - startup_32));
+#endif
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 23/28] x86: Secure Launch kernel late boot stub
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (19 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 21/28] x86/boot: Place TXT MLE header in the kernel_info section Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 24/28] x86: Secure Launch SMP bringup support Ross Philipson
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

The routine slaunch_setup() is called out of the x86 specific setup_arch()
routine during early kernel boot. After determining what platform is
present, various operations specific to that platform occur. This
includes finalizing setting for the platform late launch and verifying
that memory protections are in place.

Intel VT-d/IOMMU hardware provides special registers called Protected
Memory Regions (PMRs) that allow all memory to be protected from
DMA during a TXT DRTM launch. This coverage is validated during the
late setup process to ensure DMA protection is in place prior to
the IOMMUs being initialized and configured by the mainline kernel.
See the Intel Trusted Execution Technology - Measured Launch Environment
Developer's Guide for more details:

https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf

In addition this routine reserves key memory regions used by Secure Launch
(e.g. the TXT heap, AP startup block etc) as well as fetching values needed
later from the TXT heap and SLRT.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/kernel/Makefile   |   1 +
 arch/x86/kernel/setup.c    |   3 +
 arch/x86/kernel/slaunch.c  | 509 +++++++++++++++++++++++++++++++++++++
 drivers/iommu/intel/dmar.c |   4 +
 4 files changed, 517 insertions(+)
 create mode 100644 arch/x86/kernel/slaunch.c

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index bc184dd38d99..36ea2c12deed 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_X86_32)		+= tls.o
 obj-$(CONFIG_IA32_EMULATION)	+= tls.o
 obj-y				+= step.o
 obj-$(CONFIG_INTEL_TXT)		+= tboot.o
+obj-$(CONFIG_SECURE_LAUNCH)	+= slaunch.o
 obj-$(CONFIG_ISA_DMA_API)	+= i8237.o
 obj-y				+= stacktrace.o
 obj-y				+= cpu/
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 1b2edd07a3e1..7c027cd1bd38 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -24,6 +24,7 @@
 #include <linux/static_call.h>
 #include <linux/swiotlb.h>
 #include <linux/tboot.h>
+#include <linux/slaunch.h>
 #include <linux/usb/xhci-dbgp.h>
 #include <linux/vmalloc.h>
 
@@ -1025,6 +1026,8 @@ void __init setup_arch(char **cmdline_p)
 	early_gart_iommu_check();
 #endif
 
+	slaunch_setup();
+
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
diff --git a/arch/x86/kernel/slaunch.c b/arch/x86/kernel/slaunch.c
new file mode 100644
index 000000000000..6958734fe5e9
--- /dev/null
+++ b/arch/x86/kernel/slaunch.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Secure Launch late validation/setup and finalization support.
+ *
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/security.h>
+#include <linux/memblock.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+#include <asm/e820/api.h>
+#include <asm/setup.h>
+#include <asm/realmode.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
+
+static u32 sl_flags __ro_after_init;
+static struct sl_ap_wake_info ap_wake_info __ro_after_init;
+static u64 evtlog_addr __ro_after_init;
+static u32 evtlog_size __ro_after_init;
+static u64 vtd_pmr_lo_size __ro_after_init;
+
+/* This should be plenty of room */
+static u8 txt_dmar[PAGE_SIZE] __aligned(16);
+
+/*
+ * Get the Secure Launch flags that indicate what kind of launch is being done.
+ * E.g. a TXT launch is in progress or no Secure Launch is happening.
+ */
+u32 slaunch_get_flags(void)
+{
+	return sl_flags;
+}
+
+/*
+ * Return the AP wakeup information used in the SMP boot code to start up
+ * the APs that are parked using MONITOR/MWAIT.
+ */
+struct sl_ap_wake_info *slaunch_get_ap_wake_info(void)
+{
+	return &ap_wake_info;
+}
+
+/*
+ * On Intel platforms, TXT passes a safe copy of the DMAR ACPI table to the
+ * DRTM. The DRTM is supposed to use this instead of the one found in the
+ * ACPI tables.
+ */
+struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
+{
+	/* The DMAR is only stashed and provided via TXT on Intel systems */
+	if (memcmp(txt_dmar, "DMAR", 4))
+		return dmar;
+
+	return (struct acpi_table_header *)(txt_dmar);
+}
+
+/*
+ * If running within a TXT established DRTM, this is the proper way to reset
+ * the system if a failure occurs or a security issue is found.
+ */
+static void __noreturn slaunch_txt_reset(void __iomem *txt, const char *msg, u64 error)
+{
+	u64 one = 1, val;
+
+	pr_err("%s", msg);
+
+	/*
+	 * This performs a TXT reset with a sticky error code. The reads of
+	 * TXT_CR_E2STS act as barriers.
+	 */
+	memcpy_toio(txt + TXT_CR_ERRORCODE, &error, sizeof(error));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_NO_SECRETS, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_UNLOCK_MEM_CONFIG, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_RESET, &one, sizeof(one));
+
+	for ( ; ; )
+		asm volatile ("hlt");
+
+	unreachable();
+}
+
+/*
+ * Handle fatal errors during DRTM initialization.
+ */
+void __noreturn slaunch_reset(void *ctx, const char *msg, u64 error)
+{
+	if (slaunch_is_txt_launch())
+		slaunch_txt_reset(ctx, msg, error);
+
+	/* Generic handler for x86 */
+	pr_err("Secure Launch: %s - error: 0x%llx", msg, error);
+	asm volatile ("ud2");
+
+	unreachable();
+}
+
+/*
+ * The TXT heap is too big to map all at once with early_ioremap
+ * so it is done a table at a time.
+ */
+static void __init *txt_early_get_heap_table(void __iomem *txt, u32 type,
+					     u32 bytes)
+{
+	u64 base, size, offset = 0;
+	void *heap;
+	int i;
+
+	if (type > TXT_SINIT_TABLE_MAX)
+		slaunch_reset(txt, "Error invalid table type for early heap walk\n", SL_ERROR_HEAP_WALK);
+
+	memcpy_fromio(&base, txt + TXT_CR_HEAP_BASE, sizeof(base));
+	memcpy_fromio(&size, txt + TXT_CR_HEAP_SIZE, sizeof(size));
+
+	/* Iterate over heap tables looking for table of "type" */
+	for (i = 0; i < type; i++) {
+		base += offset;
+		heap = early_memremap(base, sizeof(u64));
+		if (!heap)
+			slaunch_reset(txt, "Error early_memremap of heap for heap walk\n", SL_ERROR_HEAP_MAP);
+
+		offset = *((u64 *)heap);
+
+		/*
+		 * After the first iteration, any offset of zero is invalid and
+		 * implies the TXT heap is corrupted.
+		 */
+		if (!offset)
+			slaunch_reset(txt, "Error invalid 0 offset in heap walk\n", SL_ERROR_HEAP_ZERO_OFFSET);
+
+		early_memunmap(heap, sizeof(u64));
+	}
+
+	/* Skip the size field at the head of each table */
+	base += sizeof(u64);
+	heap = early_memremap(base, bytes);
+	if (!heap)
+		slaunch_reset(txt, "Error early_memremap of heap section\n", SL_ERROR_HEAP_MAP);
+
+	return heap;
+}
+
+static void __init txt_early_put_heap_table(void *addr, unsigned long size)
+{
+	early_memunmap(addr, size);
+}
+
+/*
+ * TXT uses a special set of VTd registers to protect all of memory from DMA
+ * until the IOMMU can be programmed to protect memory. There is the low
+ * memory PMR that can protect all memory up to 4G. The high memory PRM can
+ * be setup to protect all memory beyond 4Gb. Validate that these values cover
+ * what is expected.
+ */
+static void __init slaunch_verify_pmrs(void __iomem *txt)
+{
+	struct txt_os_sinit_data *os_sinit_data;
+	u32 field_offset, err = 0;
+	const char *errmsg = "";
+	unsigned long last_pfn;
+
+	field_offset = offsetof(struct txt_os_sinit_data, lcp_po_base);
+	os_sinit_data = txt_early_get_heap_table(txt, TXT_OS_SINIT_DATA_TABLE,
+						 field_offset);
+
+	/* Save a copy */
+	vtd_pmr_lo_size = os_sinit_data->vtd_pmr_lo_size;
+
+	last_pfn = e820__end_of_ram_pfn();
+
+	/*
+	 * First make sure the hi PMR covers all memory above 4G. In the
+	 * unlikely case where there is < 4G on the system, the hi PMR will
+	 * not be set.
+	 */
+	if (os_sinit_data->vtd_pmr_hi_base != 0x0ULL) {
+		if (os_sinit_data->vtd_pmr_hi_base != 0x100000000ULL) {
+			err = SL_ERROR_HI_PMR_BASE;
+			errmsg =  "Error hi PMR base\n";
+			goto out;
+		}
+
+		if (PFN_PHYS(last_pfn) > os_sinit_data->vtd_pmr_hi_base +
+		    os_sinit_data->vtd_pmr_hi_size) {
+			err = SL_ERROR_HI_PMR_SIZE;
+			errmsg = "Error hi PMR size\n";
+			goto out;
+		}
+	}
+
+	/*
+	 * Lo PMR base should always be 0. This was already checked in
+	 * early stub.
+	 */
+
+	/*
+	 * Check that if the kernel was loaded below 4G, that it is protected
+	 * by the lo PMR. Note this is the decompressed kernel. The ACM would
+	 * have ensured the compressed kernel (the MLE image) was protected.
+	 */
+	if (__pa_symbol(_end) < 0x100000000ULL && __pa_symbol(_end) > os_sinit_data->vtd_pmr_lo_size) {
+		err = SL_ERROR_LO_PMR_MLE;
+		errmsg = "Error lo PMR does not cover MLE kernel\n";
+	}
+
+	/*
+	 * Other regions of interest like boot param, AP wake block, cmdline
+	 * already checked for PMR coverage in the early stub code.
+	 */
+
+out:
+	txt_early_put_heap_table(os_sinit_data, field_offset);
+
+	if (err)
+		slaunch_reset(txt, errmsg, err);
+}
+
+static void __init slaunch_txt_reserve_range(u64 base, u64 size)
+{
+	int type;
+
+	type = e820__get_entry_type(base, base + size - 1);
+	if (type == E820_TYPE_RAM) {
+		pr_info("memblock reserve base: %llx size: %llx\n", base, size);
+		memblock_reserve(base, size);
+	}
+}
+
+/*
+ * For Intel, certain regions of memory must be marked as reserved by putting
+ * them on the memblock reserved list if they are not already e820 reserved.
+ * This includes:
+ *  - The TXT HEAP
+ *  - The ACM area
+ *  - The TXT private register bank
+ *  - The MDR list sent to the MLE by the ACM (see TXT specification)
+ *  (Normally the above are properly reserved by firmware but if it was not
+ *  done, reserve them now)
+ *  - The AP wake block
+ *  - TPM log external to the TXT heap
+ *
+ * Also if the low PMR doesn't cover all memory < 4G, any RAM regions above
+ * the low PMR must be reserved too.
+ */
+static void __init slaunch_txt_reserve(void __iomem *txt)
+{
+	struct txt_sinit_memory_descriptor_record *mdr;
+	struct txt_sinit_mle_data *sinit_mle_data;
+	u64 base, size, heap_base, heap_size;
+	u32 mdrnum, mdroffset, mdrslen;
+	u32 field_offset, i;
+	void *mdrs;
+
+	base = TXT_PRIV_CONFIG_REGS_BASE;
+	size = TXT_PUB_CONFIG_REGS_BASE - TXT_PRIV_CONFIG_REGS_BASE;
+	slaunch_txt_reserve_range(base, size);
+
+	memcpy_fromio(&heap_base, txt + TXT_CR_HEAP_BASE, sizeof(heap_base));
+	memcpy_fromio(&heap_size, txt + TXT_CR_HEAP_SIZE, sizeof(heap_size));
+	slaunch_txt_reserve_range(heap_base, heap_size);
+
+	memcpy_fromio(&base, txt + TXT_CR_SINIT_BASE, sizeof(base));
+	memcpy_fromio(&size, txt + TXT_CR_SINIT_SIZE, sizeof(size));
+	slaunch_txt_reserve_range(base, size);
+
+	field_offset = offsetof(struct txt_sinit_mle_data,
+				sinit_vtd_dmar_table_size);
+	sinit_mle_data = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+						  field_offset);
+
+	mdrnum = sinit_mle_data->num_of_sinit_mdrs;
+	mdroffset = sinit_mle_data->sinit_mdrs_table_offset;
+
+	txt_early_put_heap_table(sinit_mle_data, field_offset);
+
+	if (!mdrnum)
+		goto nomdr;
+
+	mdrslen = mdrnum * sizeof(*mdr);
+
+	mdrs = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+					mdroffset + mdrslen - 8);
+
+	mdr = mdrs + mdroffset - 8;
+
+	for (i = 0; i < mdrnum; i++, mdr++) {
+		/* Spec says some entries can have length 0, ignore them */
+		if (mdr->type > 0 && mdr->length > 0)
+			slaunch_txt_reserve_range(mdr->address, mdr->length);
+	}
+
+	txt_early_put_heap_table(mdrs, mdroffset + mdrslen - 8);
+
+nomdr:
+	slaunch_txt_reserve_range(ap_wake_info.ap_wake_block,
+				  ap_wake_info.ap_wake_block_size);
+
+	/*
+	 * Earlier checks ensured that the event log was properly situated
+	 * either inside the TXT heap or outside. This is a check to see if the
+	 * event log needs to be reserved. If it is in the TXT heap, it is
+	 * already reserved.
+	 */
+	if (evtlog_addr < heap_base || evtlog_addr > (heap_base + heap_size))
+		slaunch_txt_reserve_range(evtlog_addr, evtlog_size);
+
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		base = e820_table->entries[i].addr;
+		size = e820_table->entries[i].size;
+		if (base >= vtd_pmr_lo_size && base < 0x100000000ULL)
+			slaunch_txt_reserve_range(base, size);
+		else if (base < vtd_pmr_lo_size && base + size > vtd_pmr_lo_size)
+			slaunch_txt_reserve_range(vtd_pmr_lo_size,
+						  base + size - vtd_pmr_lo_size);
+	}
+}
+
+/*
+ * TXT stashes a safe copy of the DMAR ACPI table to prevent tampering.
+ * It is stored in the TXT heap. Fetch it from there and make it available
+ * to the IOMMU driver.
+ */
+static void __init slaunch_copy_dmar_table(void __iomem *txt)
+{
+	struct txt_sinit_mle_data *sinit_mle_data;
+	u32 field_offset, dmar_size, dmar_offset;
+	void *dmar;
+
+	field_offset = offsetof(struct txt_sinit_mle_data,
+				processor_scrtm_status);
+	sinit_mle_data = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+						  field_offset);
+
+	dmar_size = sinit_mle_data->sinit_vtd_dmar_table_size;
+	dmar_offset = sinit_mle_data->sinit_vtd_dmar_table_offset;
+
+	txt_early_put_heap_table(sinit_mle_data, field_offset);
+
+	if (!dmar_size || !dmar_offset)
+		slaunch_reset(txt, "Error invalid DMAR table values\n", SL_ERROR_HEAP_INVALID_DMAR);
+
+	if (unlikely(dmar_size > PAGE_SIZE))
+		slaunch_reset(txt, "Error DMAR too big to store\n", SL_ERROR_HEAP_DMAR_SIZE);
+
+	dmar = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+					dmar_offset + dmar_size - 8);
+	if (!dmar)
+		slaunch_reset(txt, "Error early_ioremap of DMAR\n", SL_ERROR_HEAP_DMAR_MAP);
+
+	memcpy(txt_dmar, dmar + dmar_offset - 8, dmar_size);
+
+	txt_early_put_heap_table(dmar, dmar_offset + dmar_size - 8);
+}
+
+/*
+ * The location of the safe AP wake code block is stored in the TXT heap.
+ * Fetch needed values here in the early init code for later use in SMP
+ * startup.
+ *
+ * Also get the TPM event log values are in the SLRT and have to be fetched.
+ * They will be put on the memblock reserve list later.
+ */
+static void __init slaunch_fetch_values(void __iomem *txt)
+{
+	struct txt_os_mle_data *os_mle_data;
+	struct slr_entry_log_info *log_info;
+	u8 *jmp_offset, *stacks_offset;
+	struct slr_table *slrt;
+	u32 size;
+
+	os_mle_data = txt_early_get_heap_table(txt, TXT_OS_MLE_DATA_TABLE,
+					       sizeof(*os_mle_data));
+
+	ap_wake_info.ap_wake_block = os_mle_data->ap_wake_block;
+	ap_wake_info.ap_wake_block_size = os_mle_data->ap_wake_block_size;
+
+	jmp_offset = os_mle_data->mle_scratch + SL_SCRATCH_AP_JMP_OFFSET;
+	ap_wake_info.ap_jmp_offset = *((u32 *)jmp_offset);
+
+	stacks_offset = os_mle_data->mle_scratch + SL_SCRATCH_AP_STACKS_OFFSET;
+	ap_wake_info.ap_stacks_offset = *((u32 *)stacks_offset);
+
+	slrt = (struct slr_table *)early_memremap(os_mle_data->slrt, sizeof(*slrt));
+	if (!slrt)
+		slaunch_reset(txt, "Error early_memremap of SLRT failed\n", SL_ERROR_SLRT_MAP);
+
+	size = slrt->size;
+	early_memunmap(slrt, sizeof(*slrt));
+
+	slrt = (struct slr_table *)early_memremap(os_mle_data->slrt, size);
+	if (!slrt)
+		slaunch_reset(txt, "Error early_memremap of SLRT failed\n", SL_ERROR_SLRT_MAP);
+
+	log_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_LOG_INFO);
+
+	if (!log_info)
+		slaunch_reset(txt, "SLRT missing logging info entry\n", SL_ERROR_SLRT_MISSING_ENTRY);
+
+	evtlog_addr = log_info->addr;
+	evtlog_size = log_info->size;
+
+	early_memunmap(slrt, size);
+
+	txt_early_put_heap_table(os_mle_data, sizeof(*os_mle_data));
+}
+
+/*
+ * Intel TXT specific late stub setup and validation called from within
+ * x86 specific setup_arch().
+ */
+static void __init slaunch_setup_txt(void)
+{
+	u64 one = TXT_REGVALUE_ONE, val;
+	void __iomem *txt;
+
+	/*
+	 * See if SENTER was done by reading the status register in the
+	 * public space. If the public register space cannot be read, TXT may
+	 * be disabled.
+	 */
+	txt = early_ioremap(TXT_PUB_CONFIG_REGS_BASE,
+			    TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+	if (!txt)
+		panic("Error early_ioremap in TXT setup failed\n");
+
+	memcpy_fromio(&val, txt + TXT_CR_STS, sizeof(val));
+	early_iounmap(txt, TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+
+	/* SENTER should have been done */
+	if (!(val & TXT_SENTER_DONE_STS))
+		panic("Error TXT.STS SENTER_DONE not set\n");
+
+	/* SEXIT should have been cleared */
+	if (val & TXT_SEXIT_DONE_STS)
+		panic("Error TXT.STS SEXIT_DONE set\n");
+
+	/* Now we want to use the private register space */
+	txt = early_ioremap(TXT_PRIV_CONFIG_REGS_BASE,
+			    TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+	if (!txt) {
+		/* This is really bad, no where to go from here */
+		panic("Error early_ioremap of TXT priv registers\n");
+	}
+
+	/*
+	 * Try to read the Intel VID from the TXT private registers to see if
+	 * TXT measured launch happened properly and the private space is
+	 * available.
+	 */
+	memcpy_fromio(&val, txt + TXT_CR_DIDVID, sizeof(val));
+	if ((val & 0xffff) != 0x8086) {
+		/*
+		 * Can't do a proper TXT reset since it appears something is
+		 * wrong even though SENTER happened and it should be in SMX
+		 * mode.
+		 */
+		panic("Invalid TXT vendor ID, not in SMX mode\n");
+	}
+
+	/* Set flags so subsequent code knows the status of the launch */
+	sl_flags |= (SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT);
+
+	/*
+	 * Reading the proper DIDVID from the private register space means we
+	 * are in SMX mode and private registers are open for read/write.
+	 */
+
+	/* On Intel, have to handle TPM localities via TXT */
+	memcpy_toio(txt + TXT_CR_CMD_SECRETS, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_OPEN_LOCALITY1, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+
+	slaunch_fetch_values(txt);
+
+	slaunch_verify_pmrs(txt);
+
+	slaunch_txt_reserve(txt);
+
+	slaunch_copy_dmar_table(txt);
+
+	early_iounmap(txt, TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+
+	pr_info("Intel TXT setup complete\n");
+}
+
+void __init slaunch_setup(void)
+{
+	/*
+	 * If booted through secure launch entry point, the loadflags
+	 * option will be set.
+	 */
+	if (!(boot_params.hdr.loadflags & SLAUNCH_FLAG))
+		return;
+
+	if (boot_cpu_has(X86_FEATURE_SMX))
+		slaunch_setup_txt();
+}
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index ec975c73cfe6..51b9b4c72924 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -28,6 +28,7 @@
 #include <linux/iommu.h>
 #include <linux/numa.h>
 #include <linux/limits.h>
+#include <linux/slaunch.h>
 #include <asm/irq_remapping.h>
 
 #include "iommu.h"
@@ -661,6 +662,9 @@ parse_dmar_table(void)
 	 */
 	dmar_tbl = tboot_get_dmar_table(dmar_tbl);
 
+	/* If Secure Launch is active, it has similar logic */
+	dmar_tbl = slaunch_get_dmar_table(dmar_tbl);
+
 	dmar = (struct acpi_table_dmar *)dmar_tbl;
 	if (!dmar)
 		return -ENODEV;
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 24/28] x86: Secure Launch SMP bringup support
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (20 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 23/28] x86: Secure Launch kernel late boot stub Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 25/28] kexec: Secure Launch kexec SEXIT support Ross Philipson
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

On Intel, the APs are left in a well documented state after TXT performs
the late launch. Specifically they cannot have #INIT asserted on them so
a standard startup via INIT/SIPI/SIPI cannot be performed. Instead the
early SL stub code uses MONITOR and MWAIT to park the APs. The realmode/init.c
code updates the jump address for the waiting APs with the location of the
Secure Launch entry point in the rmpiggy image.

The rmpiggy image is a payload contained in the kernel used to start the
APs (in 16b or 32b modes). It is loaded at runtime so its location and entry point
must be updated in the long jump for the waiting APs by the running
kernel.

As the APs are woken up by writing the monitor, the APs jump to the Secure
Launch entry point in the rmpiggy which mimics what the real mode code would
do then jumps to the standard rmpiggy protected mode entry point.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/include/asm/realmode.h      |  3 ++
 arch/x86/kernel/slaunch.c            | 26 +++++++++++++++
 arch/x86/kernel/smpboot.c            | 47 ++++++++++++++++++++++++++--
 arch/x86/realmode/init.c             |  8 +++++
 arch/x86/realmode/rm/header.S        |  3 ++
 arch/x86/realmode/rm/trampoline_64.S | 32 +++++++++++++++++++
 6 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
index e406a1e92c63..e3336c49d26b 100644
--- a/arch/x86/include/asm/realmode.h
+++ b/arch/x86/include/asm/realmode.h
@@ -38,6 +38,9 @@ struct real_mode_header {
 #ifdef CONFIG_X86_64
 	u32	machine_real_restart_seg;
 #endif
+#ifdef CONFIG_SECURE_LAUNCH
+	u32	sl_trampoline_start32;
+#endif
 };
 
 /* This must match data at realmode/rm/trampoline_{32,64}.S */
diff --git a/arch/x86/kernel/slaunch.c b/arch/x86/kernel/slaunch.c
index 6958734fe5e9..0699cbf41753 100644
--- a/arch/x86/kernel/slaunch.c
+++ b/arch/x86/kernel/slaunch.c
@@ -507,3 +507,29 @@ void __init slaunch_setup(void)
 	if (boot_cpu_has(X86_FEATURE_SMX))
 		slaunch_setup_txt();
 }
+
+/*
+ * After a launch, the APs are woken up, enter the DRTM and are left to
+ * wait for a wakeup call on a MONITOR address. The block where they are
+ * idle has a long jump to the AP startup code in the mainline kernel.
+ * This address has to be calculated at runtime and "fixed up" to point
+ * to the SL startup location in the rmpiggy SMP startup image. This image
+ * is loaded into separate  memory at kernel start time.
+ */
+void __init slaunch_fixup_ap_wake_vector(void)
+{
+	struct sl_ap_wake_info *ap_wake_info;
+	u32 *ap_jmp_ptr;
+
+	if (!slaunch_is_txt_launch())
+		return;
+
+	ap_wake_info = slaunch_get_ap_wake_info();
+
+	ap_jmp_ptr = (u32 *)__va(ap_wake_info->ap_wake_block +
+				 ap_wake_info->ap_jmp_offset);
+
+	*ap_jmp_ptr = real_mode_header->sl_trampoline_start32;
+
+	pr_info("TXT AP startup vector address updated\n");
+}
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index eb289abece23..c351280b1cbc 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -61,6 +61,7 @@
 #include <linux/cpuhotplug.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
+#include <linux/slaunch.h>
 
 #include <asm/acpi.h>
 #include <asm/cacheinfo.h>
@@ -833,6 +834,45 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
+#if (IS_ENABLED(CONFIG_SECURE_LAUNCH))
+
+/*
+ * TXT AP startup is quite different than normal. The APs cannot have #INIT
+ * asserted on them or receive SIPIs. The early Secure Launch code has parked
+ * the APs using MONITOR/MWAIT in the safe AP wake block area (details in
+ * sl_stub.S). The SMP boot will wake the APs by writing the MONITOR associated
+ * with the AP and have them jump to the protected mode code in the rmpiggy where
+ * the rest of the SMP boot of the AP will proceed normally.
+ *
+ * Intel Trusted Execution Technology (TXT) Software Development Guide
+ * Section 2.3 -  MLE Initialization
+ */
+static void slaunch_wakeup_cpu_from_txt(int cpu, int apicid)
+{
+	struct sl_ap_stack_and_monitor *stack_monitor;
+	struct sl_ap_wake_info *ap_wake_info;
+
+	ap_wake_info = slaunch_get_ap_wake_info();
+
+	stack_monitor = (struct sl_ap_stack_and_monitor *)__va(ap_wake_info->ap_wake_block +
+							       ap_wake_info->ap_stacks_offset);
+
+	for (unsigned int i = SL_MAX_CPUS - 1; i >= 0; i--) {
+		if (stack_monitor[i].apicid == apicid) {
+			stack_monitor[i].monitor = 1;
+			break;
+		}
+	}
+}
+
+#else
+
+static inline void slaunch_wakeup_cpu_from_txt(int cpu, int apicid)
+{
+}
+
+#endif  /* IS_ENABLED(CONFIG_SECURE_LAUNCH) */
+
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -842,7 +882,7 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
 static int do_boot_cpu(u32 apicid, unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long start_ip = real_mode_header->trampoline_start;
-	int ret;
+	int ret = 0;
 
 #ifdef CONFIG_X86_64
 	/* If 64-bit wakeup method exists, use the 64-bit mode trampoline IP */
@@ -887,12 +927,15 @@ static int do_boot_cpu(u32 apicid, unsigned int cpu, struct task_struct *idle)
 
 	/*
 	 * Wake up a CPU in difference cases:
+	 * - Intel TXT DRTM launch uses its own method to wake the APs
 	 * - Use a method from the APIC driver if one defined, with wakeup
 	 *   straight to 64-bit mode preferred over wakeup to RM.
 	 * Otherwise,
 	 * - Use an INIT boot APIC message
 	 */
-	if (apic->wakeup_secondary_cpu_64)
+	if (slaunch_is_txt_launch())
+		slaunch_wakeup_cpu_from_txt(cpu, apicid);
+	else if (apic->wakeup_secondary_cpu_64)
 		ret = apic->wakeup_secondary_cpu_64(apicid, start_ip, cpu);
 	else if (apic->wakeup_secondary_cpu)
 		ret = apic->wakeup_secondary_cpu(apicid, start_ip, cpu);
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 88be32026768..ded4dafc6a0a 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -4,6 +4,7 @@
 #include <linux/memblock.h>
 #include <linux/cc_platform.h>
 #include <linux/pgtable.h>
+#include <linux/slaunch.h>
 
 #include <asm/set_memory.h>
 #include <asm/realmode.h>
@@ -213,6 +214,13 @@ void __init init_real_mode(void)
 
 	setup_real_mode();
 	set_real_mode_permissions();
+
+	/*
+	 * If Secure Launch is active, it will use the rmpiggy to do the TXT AP
+	 * startup. Secure Launch has its own entry stub in the rmpiggy and this prepares
+	 * it for SMP boot.
+	 */
+	slaunch_fixup_ap_wake_vector();
 }
 
 static int __init do_init_real_mode(void)
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S
index 2eb62be6d256..3b5cbcbbfc90 100644
--- a/arch/x86/realmode/rm/header.S
+++ b/arch/x86/realmode/rm/header.S
@@ -37,6 +37,9 @@ SYM_DATA_START(real_mode_header)
 #ifdef CONFIG_X86_64
 	.long	__KERNEL32_CS
 #endif
+#ifdef CONFIG_SECURE_LAUNCH
+	.long	pa_sl_trampoline_start32
+#endif
 SYM_DATA_END(real_mode_header)
 
 	/* End signature, used to verify integrity */
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
index 14d9c7daf90f..b0ce6205d7ea 100644
--- a/arch/x86/realmode/rm/trampoline_64.S
+++ b/arch/x86/realmode/rm/trampoline_64.S
@@ -122,6 +122,38 @@ SYM_CODE_END(sev_es_trampoline_start)
 
 	.section ".text32","ax"
 	.code32
+#ifdef CONFIG_SECURE_LAUNCH
+	.balign 4
+SYM_CODE_START(sl_trampoline_start32)
+	/*
+	 * The early secure launch stub AP wakeup code has taken care of all
+	 * the vagaries of launching out of TXT. This bit just mimics what the
+	 * 16b entry code does and jumps off to the real startup_32.
+	 */
+	cli
+	wbinvd
+
+	/*
+	 * The %ebx provided is not terribly useful since it is the physical
+	 * address of tb_trampoline_start and not the base of the image.
+	 * Use pa_real_mode_base, which is fixed up, to get a run time
+	 * base register to use for offsets to location that do not have
+	 * pa_ symbols.
+	 */
+	movl    $pa_real_mode_base, %ebx
+
+	LOCK_AND_LOAD_REALMODE_ESP lock_pa=1
+
+	lgdt    tr_gdt(%ebx)
+	lidt    tr_idt(%ebx)
+
+	movw	$__KERNEL_DS, %dx	# Data segment descriptor
+
+	/* Jump to where the 16b code would have jumped */
+	ljmpl	$__KERNEL32_CS, $pa_startup_32
+SYM_CODE_END(sl_trampoline_start32)
+#endif
+
 	.balign 4
 SYM_CODE_START(startup_32)
 	movl	%edx, %ss
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 25/28] kexec: Secure Launch kexec SEXIT support
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (21 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 24/28] x86: Secure Launch SMP bringup support Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 26/28] x86/reboot: Secure Launch SEXIT support on reboot paths Ross Philipson
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

Prior to running the next kernel via kexec, the Secure Launch code
closes down private SMX resources and does an SEXIT. This allows the
next kernel to start normally, effectively exiting the DRTM
environment.

The function slaunch_finalize() takes a boolean argument that controls
whether a GETSEC[SEXIT] can be issued. When true, the finalize code can
completely shutdown and exit the DRTM. This allows another kernel to
start normally and in turn can re-establish another DRTM session.

In cases where the machine has not been fully shutdown (e.g. machione_shutdown()
was not called), the SEXIT step cannot be done (SEXIT will fail if other
processors are busy). In these cases SEXIT is not attempted.  This normally
occurs on power off or reboot operations where it doesn't really matter.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/kernel/slaunch.c | 80 +++++++++++++++++++++++++++++++++++++++
 kernel/kexec_core.c       |  8 ++++
 2 files changed, 88 insertions(+)

diff --git a/arch/x86/kernel/slaunch.c b/arch/x86/kernel/slaunch.c
index 0699cbf41753..c61445c079ff 100644
--- a/arch/x86/kernel/slaunch.c
+++ b/arch/x86/kernel/slaunch.c
@@ -533,3 +533,83 @@ void __init slaunch_fixup_ap_wake_vector(void)
 
 	pr_info("TXT AP startup vector address updated\n");
 }
+
+static inline void smx_getsec_sexit(void)
+{
+	asm volatile ("getsec\n" : : "a" (SMX_X86_GETSEC_SEXIT));
+}
+
+/*
+ * Used during kexec and on reboot paths to finalize the TXT state
+ * and do an SEXIT SMX operation, exiting the DRTM and disabling SMX mode.
+ */
+void slaunch_finalize(int do_sexit)
+{
+	u64 one = TXT_REGVALUE_ONE, val;
+	void __iomem *config;
+
+	if (!slaunch_is_txt_launch())
+		return;
+
+	config = ioremap(TXT_PRIV_CONFIG_REGS_BASE, TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+	if (!config) {
+		pr_emerg("TXT: SEXIT failed to ioremap TXT private registers\n");
+		return;
+	}
+
+	/* Clear secrets bit for SEXIT */
+	memcpy_toio(config + TXT_CR_CMD_NO_SECRETS, &one, sizeof(one));
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	/* Unlock memory configurations */
+	memcpy_toio(config + TXT_CR_CMD_UNLOCK_MEM_CONFIG, &one, sizeof(one));
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	/* Close the TXT private register space */
+	memcpy_toio(config + TXT_CR_CMD_CLOSE_PRIVATE, &one, sizeof(one));
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	/*
+	 * Calls to iounmap are skipped due to the system state this late in the
+	 * kexec process. Local IRQs are disabled and iounmap causes a TLB flush
+	 * which in turn causes a warning. Leaving these mappings is not an issue
+	 * since the next kernel is going to completely re-setup memory management.
+	 */
+
+	/* Map public registers and do a final read fence */
+	config = ioremap(TXT_PUB_CONFIG_REGS_BASE, TXT_NR_CONFIG_PAGES *
+			 PAGE_SIZE);
+	if (!config) {
+		pr_emerg("TXT: SEXIT failed to ioremap TXT public registers\n");
+		return;
+	}
+
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	pr_emerg("TXT clear secrets bit and unlock memory complete.\n");
+
+	/*
+	 * Mostly finalized but the system is still in SMX mode. At this point if the
+	 * system has been quiesced, the APs are halted and the current process is
+	 * running on the BSP, a final GETSEC(SEXIT) can be done exiting DRTM/SMX mode.
+	 * This cannot be done on certain boot paths where the system has not been quiesced
+	 * (e.g. where machine_shutdown() has not been called).
+	 */
+	if (!do_sexit)
+		return;
+
+	if (smp_processor_id() != 0)
+		panic("TXT: SEXIT must be called on CPU 0\n");
+
+	/*
+	 * In case SMX mode was disabled, enable it for SEXIT. Clearing the bit
+	 * anytime during DRTM operation will not have an affect until the next
+	 * GETSEC() op is performed.
+	 */
+	cr4_set_bits(X86_CR4_SMXE);
+
+	/* Do the SEXIT SMX operation */
+	smx_getsec_sexit();
+
+	pr_info("TXT SEXIT complete.\n");
+}
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index fa00b239c5d9..7d092747a0da 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -41,6 +41,7 @@
 #include <linux/objtool.h>
 #include <linux/kmsg_dump.h>
 #include <linux/dma-map-ops.h>
+#include <linux/slaunch.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -1196,6 +1197,13 @@ int kernel_kexec(void)
 		cpu_hotplug_enable();
 		pr_notice("Starting new kernel\n");
 		machine_shutdown();
+
+		/*
+		 * If a Secure Launch is in progress and the current kernel is
+		 * running as a DRTM with TXT, finalize the Secure Launch state
+		 * and do the GETSEC(SEXIT) returning from SMX mode to do the KEXEC.
+		 */
+		slaunch_finalize(1);
 	}
 
 	kmsg_dump(KMSG_DUMP_SHUTDOWN);
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 26/28] x86/reboot: Secure Launch SEXIT support on reboot paths
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (22 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 25/28] kexec: Secure Launch kexec SEXIT support Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 27/28] x86: Secure Launch late initcall platform module Ross Philipson
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

If the MLE kernel is being powered off, rebooted or halted,
then SEXIT must be called. Note that the GETSEC[SEXIT] leaf
can only be called after a machine_shutdown() has been done on
these paths. The machine_shutdown() is not called on a few paths
like when poweroff action does not have a poweroff callback (into
ACPI code) or when an emergency reset is done. In these cases,
just the TXT registers are finalized but SEXIT is skipped.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
---
 arch/x86/kernel/reboot.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 964f6b0a3d68..b1e6c1972f0b 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -13,6 +13,7 @@
 #include <linux/objtool.h>
 #include <linux/pgtable.h>
 #include <linux/kexec.h>
+#include <linux/slaunch.h>
 #include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/apic.h>
@@ -778,6 +779,12 @@ static void native_machine_restart(char *__unused)
 
 	if (!reboot_force)
 		machine_shutdown();
+	/*
+	 * The comments for slaunch_finalize() provides the explanation for the
+	 * conditions required to do the SEXIT op reflected in the conditional
+	 * parameter do_sexit.
+	 */
+	slaunch_finalize(!reboot_force);
 	__machine_emergency_restart(0);
 }
 
@@ -788,6 +795,8 @@ static void native_machine_halt(void)
 
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 
+	slaunch_finalize(1);
+
 	stop_this_cpu(NULL);
 }
 
@@ -796,8 +805,12 @@ static void native_machine_power_off(void)
 	if (kernel_can_power_off()) {
 		if (!reboot_force)
 			machine_shutdown();
+		slaunch_finalize(!reboot_force);
 		do_kernel_power_off();
+	} else {
+		slaunch_finalize(0);
 	}
+
 	/* A fallback in case there is no PM info available */
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 }
@@ -825,6 +838,7 @@ void machine_shutdown(void)
 
 void machine_emergency_restart(void)
 {
+	slaunch_finalize(0);
 	__machine_emergency_restart(1);
 }
 
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 27/28] x86: Secure Launch late initcall platform module
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (23 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 26/28] x86/reboot: Secure Launch SEXIT support on reboot paths Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-15 23:33 ` [PATCH v15 28/28] x86/efi: EFI stub DRTM launch support for Secure Launch Ross Philipson
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

From: "Daniel P. Smith" <dpsmith@apertussolutions.com>

The Secure Launch platform module is a late init module. During the
init call, the TPM event log is read and measurements taken in the
early boot stub code are located. These measurements are extended
into the TPM PCRs using the mainline TPM kernel driver.

The platform module also registers the securityfs nodes to allow
fetching and writing events events to the DRTM TPM event log. In
addition, on Intel, access to TXT register fields is made available
for reading.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: garnetgrimm <grimmg@ainfosec.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/kernel/Makefile   |   1 +
 arch/x86/kernel/slmodule.c | 348 +++++++++++++++++++++++++++++++++++++
 2 files changed, 349 insertions(+)
 create mode 100644 arch/x86/kernel/slmodule.c

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 36ea2c12deed..c2025c8eac25 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_IA32_EMULATION)	+= tls.o
 obj-y				+= step.o
 obj-$(CONFIG_INTEL_TXT)		+= tboot.o
 obj-$(CONFIG_SECURE_LAUNCH)	+= slaunch.o
+obj-$(CONFIG_SECURE_LAUNCH)	+= slmodule.o
 obj-$(CONFIG_ISA_DMA_API)	+= i8237.o
 obj-y				+= stacktrace.o
 obj-y				+= cpu/
diff --git a/arch/x86/kernel/slmodule.c b/arch/x86/kernel/slmodule.c
new file mode 100644
index 000000000000..407288c6c2d5
--- /dev/null
+++ b/arch/x86/kernel/slmodule.c
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Secure Launch late validation/setup, securityfs exposure and finalization.
+ *
+ * Copyright (c) 2025 Apertus Solutions, LLC
+ * Copyright (c) 2025 Assured Information Security, Inc.
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/security.h>
+#include <linux/memblock.h>
+#include <linux/tpm.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+#include <crypto/sha2.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
+
+/*
+ * The macro DECLARE_TXT_PUB_READ_U is used to read values from the TXT
+ * public registers as unsigned values.
+ */
+#define DECLARE_TXT_PUB_READ_U(size, fmt, msg_size)			\
+static ssize_t txt_pub_read_u##size(unsigned int offset,		\
+		loff_t *read_offset,					\
+		size_t read_len,					\
+		char __user *buf)					\
+{									\
+	char msg_buffer[msg_size];					\
+	u##size reg_value = 0;						\
+	void __iomem *txt;						\
+									\
+	txt = ioremap(TXT_PUB_CONFIG_REGS_BASE,				\
+			TXT_NR_CONFIG_PAGES * PAGE_SIZE);		\
+	if (!txt)							\
+		return -EFAULT;						\
+	memcpy_fromio(&reg_value, txt + offset, sizeof(u##size));	\
+	iounmap(txt);							\
+	snprintf(msg_buffer, msg_size, fmt, reg_value);			\
+	return simple_read_from_buffer(buf, read_len, read_offset,	\
+			&msg_buffer, msg_size);				\
+}
+
+DECLARE_TXT_PUB_READ_U(8, "%#04x\n", 6);
+DECLARE_TXT_PUB_READ_U(32, "%#010x\n", 12);
+DECLARE_TXT_PUB_READ_U(64, "%#018llx\n", 20);
+
+#define DECLARE_TXT_FOPS(reg_name, reg_offset, reg_size)		\
+static ssize_t txt_##reg_name##_read(struct file *flip,			\
+		char __user *buf, size_t read_len, loff_t *read_offset)	\
+{									\
+	return txt_pub_read_u##reg_size(reg_offset, read_offset,	\
+			read_len, buf);					\
+}									\
+static const struct file_operations reg_name##_ops = {			\
+	.read = txt_##reg_name##_read,					\
+}
+
+DECLARE_TXT_FOPS(sts, TXT_CR_STS, 64);
+DECLARE_TXT_FOPS(ests, TXT_CR_ESTS, 8);
+DECLARE_TXT_FOPS(errorcode, TXT_CR_ERRORCODE, 32);
+DECLARE_TXT_FOPS(didvid, TXT_CR_DIDVID, 64);
+DECLARE_TXT_FOPS(e2sts, TXT_CR_E2STS, 64);
+DECLARE_TXT_FOPS(ver_emif, TXT_CR_VER_EMIF, 32);
+DECLARE_TXT_FOPS(scratchpad, TXT_CR_SCRATCHPAD, 64);
+
+/*
+ * Securityfs exposure
+ */
+struct memfile {
+	char *name;
+	void *addr;
+	size_t size;
+};
+
+static struct memfile sl_evtlog = { "eventlog", NULL, 0 };
+static void *txt_heap;
+static struct txt_heap_event_log_pointer2_1_element *evtlog21;
+static DEFINE_MUTEX(sl_evt_log_mutex);
+static struct tcg_efi_specid_event_head *efi_head;
+
+static ssize_t sl_evtlog_read(struct file *file, char __user *buf,
+			      size_t count, loff_t *pos)
+{
+	ssize_t size;
+
+	if (!sl_evtlog.addr)
+		return 0;
+
+	mutex_lock(&sl_evt_log_mutex);
+	size = simple_read_from_buffer(buf, count, pos, sl_evtlog.addr,
+				       sl_evtlog.size);
+	mutex_unlock(&sl_evt_log_mutex);
+
+	return size;
+}
+
+static ssize_t sl_evtlog_write(struct file *file, const char __user *buf,
+			       size_t datalen, loff_t *ppos)
+{
+	ssize_t result;
+	char *data;
+
+	if (!sl_evtlog.addr)
+		return 0;
+
+	/* No partial writes. */
+	result = -EINVAL;
+	if (*ppos != 0)
+		goto out;
+
+	data = memdup_user(buf, datalen);
+	if (IS_ERR(data)) {
+		result = PTR_ERR(data);
+		goto out;
+	}
+
+	mutex_lock(&sl_evt_log_mutex);
+	if (evtlog21)
+		result = tpm2_log_event(evtlog21, sl_evtlog.addr,
+					sl_evtlog.size, datalen, data);
+	else
+		result = tpm_log_event(sl_evtlog.addr, sl_evtlog.size,
+				       datalen, data);
+	mutex_unlock(&sl_evt_log_mutex);
+
+	kfree(data);
+out:
+	return result;
+}
+
+static const struct file_operations sl_evtlog_ops = {
+	.read = sl_evtlog_read,
+	.write = sl_evtlog_write,
+	.llseek = default_llseek,
+};
+
+struct sfs_file {
+	const char *name;
+	const struct file_operations *fops;
+};
+
+#define SL_TXT_ENTRY_COUNT	7
+static const struct sfs_file sl_txt_files[] = {
+	{ "sts", &sts_ops },
+	{ "ests", &ests_ops },
+	{ "errorcode", &errorcode_ops },
+	{ "didvid", &didvid_ops },
+	{ "ver_emif", &ver_emif_ops },
+	{ "scratchpad", &scratchpad_ops },
+	{ "e2sts", &e2sts_ops }
+};
+
+/* sysfs file handles */
+static struct dentry *slaunch_dir;
+static struct dentry *event_file;
+static struct dentry *txt_dir;
+static struct dentry *txt_entries[SL_TXT_ENTRY_COUNT];
+
+static long slaunch_expose_securityfs(void)
+{
+	long ret = 0;
+	int i;
+
+	slaunch_dir = securityfs_create_dir("slaunch", NULL);
+	if (IS_ERR(slaunch_dir))
+		return PTR_ERR(slaunch_dir);
+
+	if (slaunch_get_flags() & SL_FLAG_ARCH_TXT) {
+		txt_dir = securityfs_create_dir("txt", slaunch_dir);
+		if (IS_ERR(txt_dir)) {
+			ret = PTR_ERR(txt_dir);
+			goto remove_slaunch;
+		}
+
+		for (i = 0; i < ARRAY_SIZE(sl_txt_files); i++) {
+			txt_entries[i] =
+				securityfs_create_file(sl_txt_files[i].name, 0440, txt_dir,
+						       NULL, sl_txt_files[i].fops);
+			if (IS_ERR(txt_entries[i])) {
+				ret = PTR_ERR(txt_entries[i]);
+				goto remove_files;
+			}
+		}
+	}
+
+	if (sl_evtlog.addr) {
+		event_file = securityfs_create_file(sl_evtlog.name, 0440,
+						    slaunch_dir, NULL,
+						    &sl_evtlog_ops);
+		if (IS_ERR(event_file)) {
+			ret = PTR_ERR(event_file);
+			goto remove_files;
+		}
+	}
+
+	return 0;
+
+remove_files:
+	if (slaunch_get_flags() & SL_FLAG_ARCH_TXT) {
+		while (--i >= 0)
+			securityfs_remove(txt_entries[i]);
+		securityfs_remove(txt_dir);
+	}
+
+remove_slaunch:
+	securityfs_remove(slaunch_dir);
+
+	return ret;
+}
+
+static void slaunch_teardown_securityfs(void)
+{
+	int i;
+
+	securityfs_remove(event_file);
+	if (sl_evtlog.addr) {
+		memunmap(sl_evtlog.addr);
+		sl_evtlog.addr = NULL;
+	}
+	sl_evtlog.size = 0;
+
+	if (slaunch_get_flags() & SL_FLAG_ARCH_TXT) {
+		for (i = 0; i < ARRAY_SIZE(sl_txt_files); i++)
+			securityfs_remove(txt_entries[i]);
+
+		securityfs_remove(txt_dir);
+
+		if (txt_heap) {
+			memunmap(txt_heap);
+			txt_heap = NULL;
+		}
+	}
+
+	securityfs_remove(slaunch_dir);
+}
+
+static void slaunch_intel_evtlog(void __iomem *txt)
+{
+	struct slr_entry_log_info *log_info;
+	struct txt_os_mle_data *params;
+	struct slr_table *slrt;
+	void *os_sinit_data;
+	u64 base, size;
+
+	memcpy_fromio(&base, txt + TXT_CR_HEAP_BASE, sizeof(base));
+	memcpy_fromio(&size, txt + TXT_CR_HEAP_SIZE, sizeof(size));
+
+	/* now map TXT heap */
+	txt_heap = memremap(base, size, MEMREMAP_WB);
+	if (!txt_heap)
+		slaunch_reset(txt, "Error failed to memremap TXT heap\n", SL_ERROR_HEAP_MAP);
+
+	params = (struct txt_os_mle_data *)txt_os_mle_data_start(txt_heap);
+
+	/* Get the SLRT and remap it */
+	slrt = memremap(params->slrt, sizeof(*slrt), MEMREMAP_WB);
+	if (!slrt)
+		slaunch_reset(txt, "Error failed to memremap SLR Table\n", SL_ERROR_SLRT_MAP);
+	size = slrt->size;
+	memunmap(slrt);
+
+	slrt = memremap(params->slrt, size, MEMREMAP_WB);
+	if (!slrt)
+		slaunch_reset(txt, "Error failed to memremap SLR Table\n", SL_ERROR_SLRT_MAP);
+
+	log_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_LOG_INFO);
+	if (!log_info)
+		slaunch_reset(txt, "Error failed to memremap SLR Table\n", SL_ERROR_SLRT_MISSING_ENTRY);
+
+	sl_evtlog.size = log_info->size;
+	sl_evtlog.addr = memremap(log_info->addr, log_info->size, MEMREMAP_WB);
+	if (!sl_evtlog.addr)
+		slaunch_reset(txt, "Error failed to memremap TPM event log\n", SL_ERROR_EVENTLOG_MAP);
+
+	memunmap(slrt);
+
+	/* Determine if this is TPM 1.2 or 2.0 event log */
+	if (memcmp(sl_evtlog.addr + sizeof(struct tcg_pcr_event), TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
+		return; /* looks like it is not 2.0 */
+
+	/* For TPM 2.0 logs, the extended heap element must be located */
+	os_sinit_data = txt_os_sinit_data_start(txt_heap);
+
+	evtlog21 = txt_find_log2_1_element(os_sinit_data);
+
+	/*
+	 * If this fails, things are in really bad shape. Any attempt to write
+	 * events to the log will fail.
+	 */
+	if (!evtlog21)
+		slaunch_reset(txt, "Error failed to find TPM20 event log element\n", SL_ERROR_TPM_INVALID_LOG20);
+
+	/* Save pointer to the EFI SpecID log header */
+	efi_head = (struct tcg_efi_specid_event_head *)(sl_evtlog.addr + sizeof(struct tcg_pcr_event));
+}
+
+static void slaunch_tpm_open_locality2(void __iomem *txt)
+{
+	struct tpm_chip *tpm;
+	int rc;
+
+	tpm = tpm_default_chip();
+	if (!tpm)
+		slaunch_reset(txt, "Could not get default TPM chip\n", SL_ERROR_TPM_INIT);
+
+	rc = tpm_chip_set_locality(tpm, 2);
+	if (rc)
+		slaunch_reset(txt, "Could not set TPM chip locality 2\n", SL_ERROR_TPM_INIT);
+}
+
+static int __init slaunch_module_init(void)
+{
+	void __iomem *txt;
+
+	/* Check to see if Secure Launch happened */
+	if ((slaunch_get_flags() & (SL_FLAG_ACTIVE|SL_FLAG_ARCH_TXT)) !=
+	    (SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT))
+		return 0;
+
+	txt = ioremap(TXT_PRIV_CONFIG_REGS_BASE, TXT_NR_CONFIG_PAGES *
+		      PAGE_SIZE);
+	if (!txt)
+		panic("Error ioremap of TXT priv registers\n");
+
+	/* Only Intel TXT is supported at this point */
+	slaunch_intel_evtlog(txt);
+	slaunch_tpm_open_locality2(txt);
+	iounmap(txt);
+
+	return slaunch_expose_securityfs();
+}
+
+static void __exit slaunch_module_exit(void)
+{
+	slaunch_teardown_securityfs();
+}
+
+late_initcall(slaunch_module_init);
+__exitcall(slaunch_module_exit);
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH v15 28/28] x86/efi: EFI stub DRTM launch support for Secure Launch
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (24 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 27/28] x86: Secure Launch late initcall platform module Ross Philipson
@ 2025-12-15 23:33 ` Ross Philipson
  2025-12-16  3:46 ` [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Jarkko Sakkinen
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 41+ messages in thread
From: Ross Philipson @ 2025-12-15 23:33 UTC (permalink / raw)
  To: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu
  Cc: ross.philipson, dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb,
	mjg59, James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita,
	herbert, davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

This support allows the DRTM launch to be initiated after an EFI stub
launch of the Linux kernel is done. This is accomplished by providing
a handler to jump to when a Secure Launch is in progress. This has to be
called after the EFI stub does Exit Boot Services.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/efistub.h  |   8 ++
 drivers/firmware/efi/libstub/x86-stub.c | 100 ++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index f5ba032863a9..6e4cbf02500b 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -135,6 +135,14 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
 	*hi = upper_32_bits(data);
 }
 
+static inline
+void efi_set_u64_form(u32 lo, u32 hi, u64 *data)
+{
+	u64 upper = hi;
+
+	*data = lo | upper << 32;
+}
+
 /*
  * Allocation types for calls to boottime->allocate_pages.
  */
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index 761121a77f9e..e664dfddc173 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -9,6 +9,8 @@
 #include <linux/efi.h>
 #include <linux/pci.h>
 #include <linux/stddef.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
 
 #include <asm/efi.h>
 #include <asm/e820/types.h>
@@ -795,6 +797,101 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry,
 						  kernel_inittext_size);
 }
 
+#if (IS_ENABLED(CONFIG_SECURE_LAUNCH))
+
+static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
+						 struct boot_params *boot_params)
+{
+	struct slr_entry_intel_info *txt_info;
+	struct slr_entry_policy *policy;
+	bool updated = false;
+	int i;
+
+	txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
+	if (!txt_info)
+		return false;
+
+	txt_info->boot_params_addr = (u64)boot_params;
+
+	policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
+	if (!policy)
+		return false;
+
+	for (i = 0; i < policy->nr_entries; i++) {
+		if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
+			policy->policy_entries[i].entity = (u64)boot_params;
+			updated = true;
+			break;
+		}
+	}
+
+	/*
+	 * If this is a PE entry into EFI stub the mocked up boot params will
+	 * be missing some of the setup header data needed for the second stage
+	 * of the Secure Launch boot.
+	 */
+	if (image) {
+		struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
+					    offsetof(struct boot_params, hdr));
+		u64 cmdline_ptr;
+
+		boot_params->hdr.setup_sects = hdr->setup_sects;
+		boot_params->hdr.syssize = hdr->syssize;
+		boot_params->hdr.version = hdr->version;
+		boot_params->hdr.loadflags = hdr->loadflags;
+		boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
+		boot_params->hdr.min_alignment = hdr->min_alignment;
+		boot_params->hdr.xloadflags = hdr->xloadflags;
+		boot_params->hdr.init_size = hdr->init_size;
+		boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
+		efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
+				 &cmdline_ptr);
+		boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
+	}
+
+	return updated;
+}
+
+static void efi_secure_launch(struct boot_params *boot_params)
+{
+	struct slr_entry_dl_info *dlinfo;
+	efi_guid_t guid = SLR_TABLE_GUID;
+	dl_handler_func handler_callback;
+	struct slr_table *slrt;
+
+	/*
+	 * The presence of this table indicated a Secure Launch
+	 * is being requested.
+	 */
+	slrt = (struct slr_table *)get_efi_config_table(guid);
+	if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
+		return;
+
+	/*
+	 * Since the EFI stub library creates its own boot_params on entry, the
+	 * SLRT and TXT heap have to be updated with this version.
+	 */
+	if (!efi_secure_launch_update_boot_params(slrt, boot_params))
+		return;
+
+	/* Jump through DL stub to initiate Secure Launch */
+	dlinfo = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
+
+	handler_callback = (dl_handler_func)dlinfo->dl_handler;
+
+	handler_callback(&dlinfo->bl_context);
+
+	unreachable();
+}
+
+#else
+
+static void efi_secure_launch(struct boot_params *boot_params)
+{
+}
+
+#endif /* IS_ENABLED(CONFIG_SECURE_LAUNCH) */
+
 static void __noreturn enter_kernel(unsigned long kernel_addr,
 				    struct boot_params *boot_params)
 {
@@ -929,6 +1026,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
 		goto fail;
 	}
 
+	/* If a Secure Launch is in progress, this never returns */
+	efi_secure_launch(boot_params);
+
 	/*
 	 * Call the SEV init code while still running with the firmware's
 	 * GDT/IDT, so #VC exceptions will be handled by EFI.
-- 
2.43.7



^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements
  2025-12-15 23:33 ` [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements Ross Philipson
@ 2025-12-16  0:21   ` Eric Biggers
  2025-12-17 18:10     ` ross.philipson
  0 siblings, 1 reply; 41+ messages in thread
From: Eric Biggers @ 2025-12-16  0:21 UTC (permalink / raw)
  To: Ross Philipson
  Cc: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu, dpsmith, tglx, mingo, bp, hpa,
	dave.hansen, ardb, mjg59, James.Bottomley, peterhuewe, jarkko,
	jgg, luto, nivedita, herbert, davem, corbet, ebiederm, dwmw2,
	baolu.lu, kanth.ghatraju, andrew.cooper3, trenchboot-devel

On Mon, Dec 15, 2025 at 03:33:05PM -0800, Ross Philipson wrote:
> diff --git a/arch/x86/boot/compressed/sha1.c b/arch/x86/boot/compressed/sha1.c
> new file mode 100644
> index 000000000000..dd1b4cf5caf5
> --- /dev/null
> +++ b/arch/x86/boot/compressed/sha1.c
> @@ -0,0 +1,7 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2025 Apertus Solutions, LLC.
> + */
> +
> +#undef CONFIG_CRYPTO_LIB_SHA1_ARCH
> +#include "../../../../lib/crypto/sha1.c"

CONFIG_* options shouldn't be undefined like this.  It seems that you're
trying to build the SHA-1 code into a pre-boot environment.  This
problem was already solved in the SHA-256 code, by making
lib/crypto/sha256.c aware of __DISABLE_EXPORTS.  The SHA-1 code should
use the same solution.

- Eric


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 13/28] x86: Secure Launch Kconfig
  2025-12-15 23:33 ` [PATCH v15 13/28] x86: Secure Launch Kconfig Ross Philipson
@ 2025-12-16  3:20   ` Randy Dunlap
  2025-12-17 18:11     ` ross.philipson
  0 siblings, 1 reply; 41+ messages in thread
From: Randy Dunlap @ 2025-12-16  3:20 UTC (permalink / raw)
  To: Ross Philipson, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel



On 12/15/25 3:33 PM, Ross Philipson wrote:
> Add a Kconfig option for compiling in/out the Secure Launch feature.
> Secure Launch is controlled by a singel boolean on/off.
> 
> Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
> ---
>  arch/x86/Kconfig | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index fa3b616af03a..9404d207c420 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -1975,6 +1975,20 @@ config EFI_RUNTIME_MAP
>  
>  	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
>  
> +config SECURE_LAUNCH
> +	bool "Secure Launch DRTM support"
> +	depends on X86_64 && X86_X2APIC && TCG_TIS && TCG_CRB
> +	select CRYPTO_LIB_SHA1
> +	select CRYPTO_LIB_SHA256
> +	help
> +	  The Secure Launch feature allows a kernel to be launched directly
> +	  through a vendor neutral DTRM (Dynamic Root of Trust for Measurement)

	                           DRTM

> +	  solution, with Intel TXT being one example.  The DRTM establishes an
> +	  environment where the CPU measures the kernel image, employing the TPM,
> +	  before starting it. Secure Launch then continues the measurement chain
> +	  over kernel configuration information and other launch artifacts (e.g.
> +	  any initramfs image).
> +
>  source "kernel/Kconfig.hz"
>  
>  config ARCH_SUPPORTS_KEXEC

-- 
~Randy



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 00/28] x86: Secure Launch support for Intel TXT
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (25 preceding siblings ...)
  2025-12-15 23:33 ` [PATCH v15 28/28] x86/efi: EFI stub DRTM launch support for Secure Launch Ross Philipson
@ 2025-12-16  3:46 ` Jarkko Sakkinen
  2025-12-17 18:15   ` ross.philipson
  2025-12-16 22:14 ` Dave Hansen
       [not found] ` <20251215233316.1076248-23-ross.philipson@oracle.com>
  28 siblings, 1 reply; 41+ messages in thread
From: Jarkko Sakkinen @ 2025-12-16  3:46 UTC (permalink / raw)
  To: Ross Philipson
  Cc: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu, dpsmith, tglx, mingo, bp, hpa,
	dave.hansen, ardb, mjg59, James.Bottomley, peterhuewe, jgg, luto,
	nivedita, herbert, davem, corbet, ebiederm, dwmw2, baolu.lu,
	kanth.ghatraju, andrew.cooper3, trenchboot-devel

On Mon, Dec 15, 2025 at 03:32:48PM -0800, Ross Philipson wrote:
> Secure Launch is a vendor-neutral approach to implementing TGC Dynamic
> Root of Trust (DRTM) support in the kernel. This is complementary to
> better known Static Root of Trust (SRTM) schemes such as UEFI SecureBoot.
> 
> This series provides the common infrastructure along with Intel TXT
> support, without needing the tboot exokernel. Support for AMD SKINIT is
> pending the common infrastructure getting nailed down, and ARM are
> looking to build on it too.
> 
> Originally, tboot were approached to see if they'd take support for
> other vendors, but they elected not to. Hence this approach instead.
> 
> Work is being coordinated by the Trenchboot project, https://trenchboot.org/,
> organising Secure Launch support for upstream open source projects including
> Grub, iPXE and Xen. The goal of the Trenchboot project is to make DTRM easy
> to use.  e.g. for Grub, it's simply adding "slaunch" as a command in the boot
> stanza.  See https://trenchboot.org/user-docs/QUICKSTART/#linux-quick-start-guide
> for more details
> 
> Patch set based on commit:
> torvalds/master/fd57572253bc356330dbe5b233c2e1d8426c66fd
> 
> Depends on v3 of the following TPM patch set (note this patch
> set is being actively worked on separately):
> [PATCH v3 00/10]  tpm: Decouple Trenchboot dependencies
> Message ID: 20250929194832.2913286-1-jarkko@kernel.org
> 
> Finally we would like to thank everyone for their input and
> assistance. It has all been very helpful in improving the quality of
> our solution and in reviewing/strengthening our security posture.
> 
> Thanks
> Ross Philipson and Daniel P. Smith
> 
> Changes in v15:
> 
>  - Rewriting and reformatting of the cover letter, commit message and
>    code comments per requests from maintainers.
>  - Introduction of a early TPM driver in the x86 setup kernel to allow
>    TPM extend command very early in the boot.
>  - Remove previous TPM extending architecture that attempted to update
>    the TPM PCRs later in the boot process.
>  - Split slaunch.h into 2 files, with a new txt.h. The former contains
>    platform agnostic definitions for the SL feature. The new txt.h file
>    contains Intel TXT definitions from the public specs.
>  - Split TPM headers up following the specifications where the
>    technologies are defined.
>  - Include set of split up TPM header files to allow TPM driver reuse
>    in other environments (e.g. early kernel, x86).
>  - Fix code formatting and type-os.
> 
> 
> Alec Brown (1):
>   tpm: Remove main TPM header from TPM event log header
> 
> Daniel P. Smith (6):
>   tpm/tpm_tis: Close all localities
>   tpm/tpm_tis: Address positive localities in tpm_tis_request_locality()
>   Documentation/x86: Secure Launch kernel documentation
>   x86: Add early SHA-1 support for Secure Launch early measurements
>   x86: Add early SHA-256 support for Secure Launch early measurements
>   x86: Secure Launch late initcall platform module
> 
> Ross Philipson (21):
>   tpm: Initial step to reorganize TPM public headers
>   tpm: Move TPM1 specific definitions and functions to new headers
>   tpm: Move TPM2 specific definitions and functions to new headers
>   tpm: Move TPM common base definitions to new public common header
>   tpm: Move platform specific definitions to the new PTP header
>   tpm: Add TPM buffer support header for standalone reuse
>   tpm/tpm_tis: Allow locality to be set to a different value
>   tpm/sysfs: Show locality used by kernel
>   x86: Secure Launch Kconfig
>   x86: Secure Launch Resource Table header file
>   x86: Secure Launch main header file
>   x86/txt: Intel Trusted eXecution Technology (TXT) definitions
>   x86/tpm: Early TPM PCR extending driver
>   x86/msr: Add variable MTRR base/mask and x2apic ID registers
>   x86/boot: Place TXT MLE header in the kernel_info section
>   x86: Secure Launch kernel early boot stub
>   x86: Secure Launch kernel late boot stub
>   x86: Secure Launch SMP bringup support
>   kexec: Secure Launch kexec SEXIT support
>   x86/reboot: Secure Launch SEXIT support on reboot paths
>   x86/efi: EFI stub DRTM launch support for Secure Launch
> 
>  Documentation/arch/x86/boot.rst               |  21 +
>  Documentation/security/index.rst              |   1 +
>  .../security/launch-integrity/index.rst       |  11 +
>  .../security/launch-integrity/principles.rst  | 308 +++++++
>  .../secure_launch_details.rst                 | 587 +++++++++++++
>  .../secure_launch_overview.rst                | 240 ++++++
>  arch/x86/Kconfig                              |  14 +
>  arch/x86/boot/compressed/Makefile             |   8 +
>  arch/x86/boot/compressed/early_tpm_extend.c   | 601 ++++++++++++++
>  arch/x86/boot/compressed/head_64.S            |  29 +
>  arch/x86/boot/compressed/kernel_info.S        |  50 +-
>  arch/x86/boot/compressed/sha1.c               |   7 +
>  arch/x86/boot/compressed/sha256.c             |   6 +
>  arch/x86/boot/compressed/sl_main.c            | 638 +++++++++++++++
>  arch/x86/boot/compressed/sl_stub.S            | 770 ++++++++++++++++++
>  arch/x86/boot/compressed/tpm.h                |  42 +
>  arch/x86/boot/compressed/vmlinux.lds.S        |   7 +
>  arch/x86/include/asm/msr-index.h              |   5 +
>  arch/x86/include/asm/realmode.h               |   3 +
>  arch/x86/include/asm/txt.h                    | 330 ++++++++
>  arch/x86/include/uapi/asm/bootparam.h         |   1 +
>  arch/x86/kernel/Makefile                      |   2 +
>  arch/x86/kernel/asm-offsets.c                 |  20 +
>  arch/x86/kernel/reboot.c                      |  14 +
>  arch/x86/kernel/setup.c                       |   3 +
>  arch/x86/kernel/slaunch.c                     | 615 ++++++++++++++
>  arch/x86/kernel/slmodule.c                    | 348 ++++++++
>  arch/x86/kernel/smpboot.c                     |  47 +-
>  arch/x86/realmode/init.c                      |   8 +
>  arch/x86/realmode/rm/header.S                 |   3 +
>  arch/x86/realmode/rm/trampoline_64.S          |  32 +
>  drivers/char/tpm/tpm-buf.c                    |  10 +-
>  drivers/char/tpm/tpm-chip.c                   |  34 +-
>  drivers/char/tpm/tpm-sysfs.c                  |  10 +
>  drivers/char/tpm/tpm.h                        | 180 +---
>  drivers/char/tpm/tpm1-cmd.c                   |  18 +-
>  drivers/char/tpm/tpm1_structs.h               |  97 +++
>  drivers/char/tpm/tpm2-cmd.c                   |  32 +-
>  drivers/char/tpm/tpm2-space.c                 |  13 -
>  drivers/char/tpm/tpm2_structs.h               |  58 ++
>  drivers/char/tpm/tpm_tis_core.c               |  21 +-
>  drivers/char/tpm/tpm_tis_core.h               |  64 +-
>  drivers/firmware/efi/libstub/efistub.h        |   8 +
>  drivers/firmware/efi/libstub/x86-stub.c       | 100 +++
>  drivers/iommu/intel/dmar.c                    |   4 +
>  include/keys/trusted_tpm.h                    |   1 -
>  include/linux/slaunch.h                       | 251 ++++++
>  include/linux/slr_table.h                     | 308 +++++++
>  include/linux/tpm.h                           | 240 +-----
>  include/linux/tpm1.h                          |  87 ++
>  include/linux/tpm2.h                          | 247 ++++++
>  include/linux/tpm_buf.h                       |  57 ++
>  include/linux/tpm_command.h                   |  30 -
>  include/linux/tpm_common.h                    |  99 +++
>  include/linux/tpm_eventlog.h                  |   4 +-
>  include/linux/tpm_ptp.h                       | 139 ++++
>  kernel/kexec_core.c                           |   8 +
>  security/keys/trusted-keys/trusted_tpm1.c     |   1 -
>  security/keys/trusted-keys/trusted_tpm2.c     |   1 -
>  59 files changed, 6319 insertions(+), 574 deletions(-)
>  create mode 100644 Documentation/security/launch-integrity/index.rst
>  create mode 100644 Documentation/security/launch-integrity/principles.rst
>  create mode 100644 Documentation/security/launch-integrity/secure_launch_details.rst
>  create mode 100644 Documentation/security/launch-integrity/secure_launch_overview.rst
>  create mode 100644 arch/x86/boot/compressed/early_tpm_extend.c
>  create mode 100644 arch/x86/boot/compressed/sha1.c
>  create mode 100644 arch/x86/boot/compressed/sha256.c
>  create mode 100644 arch/x86/boot/compressed/sl_main.c
>  create mode 100644 arch/x86/boot/compressed/sl_stub.S
>  create mode 100644 arch/x86/boot/compressed/tpm.h
>  create mode 100644 arch/x86/include/asm/txt.h
>  create mode 100644 arch/x86/kernel/slaunch.c
>  create mode 100644 arch/x86/kernel/slmodule.c
>  create mode 100644 drivers/char/tpm/tpm1_structs.h
>  create mode 100644 drivers/char/tpm/tpm2_structs.h
>  create mode 100644 include/linux/slaunch.h
>  create mode 100644 include/linux/slr_table.h
>  create mode 100644 include/linux/tpm1.h
>  create mode 100644 include/linux/tpm2.h
>  create mode 100644 include/linux/tpm_buf.h
>  delete mode 100644 include/linux/tpm_command.h
>  create mode 100644 include/linux/tpm_common.h
>  create mode 100644 include/linux/tpm_ptp.h
> 
> -- 
> 2.43.7
> 

Most likely I'll review this after the holidays (for heads up).

BR, Jarkko


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver
  2025-12-15 23:33 ` [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver Ross Philipson
@ 2025-12-16 21:53   ` Dave Hansen
  2025-12-17 18:40     ` ross.philipson
  0 siblings, 1 reply; 41+ messages in thread
From: Dave Hansen @ 2025-12-16 21:53 UTC (permalink / raw)
  To: Ross Philipson, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

I'm mostly spot-checking this to see what kind of shape it's in and how
much work and diligence has been applied in the last 8 months since v14.

On 12/15/25 15:33, Ross Philipson wrote:
...
> The driver could be extended for further operations if needed. This
> TPM dirver implementation relies as much as possible on existing mainline

<sigh>

v15 and no spell checking. :(

> --- /dev/null
> +++ b/arch/x86/boot/compressed/early_tpm_extend.c
> @@ -0,0 +1,601 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2010-2012 United States Government, as represented by
> + * the Secretary of Defense.  All rights reserved.

IANAL, but this looks fishy.

It's theoretically fine to go grab random code off the Internet and
submit it to the kernel, given the correct license. But I do want to
know what its story is and where it came from.

I also seem to remember that there are special rules around the US
federal government's inability to hold copyrights. This seems worth at
least a mention ... somewhere.

This is helpful, for instance:

> + * based off of the original tools/vtpm_manager code base which is:
> + * Copyright (c) 2005, Intel Corp.
> + * All rights reserved.

so thanks for that one.

> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + *   * Redistributions of source code must retain the above copyright
> + *     notice, this list of conditions and the following disclaimer.
> + *   * Redistributions in binary form must reproduce the above
> + *     copyright notice, this list of conditions and the following
> + *     disclaimer in the documentation and/or other materials provided
> + *     with the distribution.
> + *   * Neither the name of Intel Corporation nor the names of its
> + *     contributors may be used to endorse or promote products derived
> + *     from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> + * OF THE POSSIBILITY OF SUCH DAMAGE.
> + */

Also, IANAL, but this looks BSD-ish.

I would have kinda expected the SPDX header to say BSD-blah-blah and not
GPL-2.0-only.

I'd really appreciate if you could go have a huddle with your corporate
Open Source folks and make sure this is all proper. To me, it looks
fishy at _best_.

...
> +/*
> + * We're far too early to calibrate time.  Assume a 5GHz processor (the upper
> + * end of the Fam19h range), which causes us to be wrong in the safe direction
> + * on slower systems.
> + */

https://docs.kernel.org/process/maintainer-tip.html#changelog

Imperative voice please.

...
> +static int __tis_recv_data(struct tpm_chip *chip, u8 *buf, int count)
> +{
> +	int size = 0;
> +	int burstcnt;
> +
> +	while (size < count && __tis_wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, chip->timeout_c) == 0) {
> +		burstcnt = __tis_get_burstcount(chip);
> +
> +		for ( ; burstcnt > 0 && size < count; --burstcnt)
> +			buf[size++] = tpm_read8(chip, TPM_DATA_FIFO(chip->locality));
> +	}
> +
> +	return size;
> +}
> +
> +/**
> + * tpm_tis_check_locality - Check if the given locality is the active one
> + * @chip:	The TPM chip instance
> + * @loc:	The locality to check
> + *
> + * Return: true - locality active, false - not active
> + */
> +bool tpm_tis_check_locality(struct tpm_chip *chip, int loc)
> +{
> +	if ((tpm_read8(chip, TPM_ACCESS(loc)) & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
> +		chip->locality = loc;
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +/**
> + * tpm_tis_release_locality - Release the active locality
> + * @chip:	The TPM chip instance
> + */
> +void tpm_tis_release_locality(struct tpm_chip *chip)
> +{
> +	if ((tpm_read8(chip, TPM_ACCESS(chip->locality)) & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
> +		tpm_write8(chip, TPM_ACCESS(chip->locality), TPM_ACCESS_RELINQUISH_LOCALITY);
> +
> +	chip->locality = 0;
> +}

I guess some folks aren't enforcing the 80-column limits. But this is
not even close. It's almost 80x2.

Has there even been an attempt to make this conform to kernel coding
style? What other checkpatch.pl warnings are being ignored?


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 00/28] x86: Secure Launch support for Intel TXT
  2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
                   ` (26 preceding siblings ...)
  2025-12-16  3:46 ` [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Jarkko Sakkinen
@ 2025-12-16 22:14 ` Dave Hansen
       [not found] ` <20251215233316.1076248-23-ross.philipson@oracle.com>
  28 siblings, 0 replies; 41+ messages in thread
From: Dave Hansen @ 2025-12-16 22:14 UTC (permalink / raw)
  To: Ross Philipson, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

On 12/15/25 15:32, Ross Philipson wrote:
> Patch set based on commit:
> torvalds/master/fd57572253bc356330dbe5b233c2e1d8426c66fd

That's an interesting place to pick. What was the reasoning behind it?


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions
  2025-12-15 23:33 ` [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions Ross Philipson
@ 2025-12-16 22:14   ` Dave Hansen
  2025-12-17 18:44     ` ross.philipson
  0 siblings, 1 reply; 41+ messages in thread
From: Dave Hansen @ 2025-12-16 22:14 UTC (permalink / raw)
  To: Ross Philipson, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

On 12/15/25 15:33, Ross Philipson wrote:
> +static inline struct txt_heap_event_log_pointer2_1_element*
> +txt_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
> +{
> +	struct txt_heap_ext_data_element *ext_elem;
> +
> +	/* The extended element array is at the end of this table */
> +	ext_elem = (struct txt_heap_ext_data_element *)
> +		((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));

I'd really honestly see a helper for this kind of thing:

#define ptr_after(foo)	((void *)foo + sizeof(foo))

resulting in:

	ext_elem = ptr_after(os_sinit_data);

would be a billion times easier to read than what's there. I honestly
don't even see why this bothers with the u8 and cast to 'struct
txt_heap_ext_data_element *' versus just using void* and being done with it.

There's no type safety here in the first place so why bother?

> +	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);
> +	}


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 22/28] x86: Secure Launch kernel early boot stub
       [not found] ` <20251215233316.1076248-23-ross.philipson@oracle.com>
@ 2025-12-16 22:32   ` Dave Hansen
  2025-12-17 18:47     ` ross.philipson
  0 siblings, 1 reply; 41+ messages in thread
From: Dave Hansen @ 2025-12-16 22:32 UTC (permalink / raw)
  To: Ross Philipson, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

On 12/15/25 15:33, Ross Philipson wrote:
> +static u64 sl_txt_read(u32 reg)
> +{
> +	return readq((void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
> +}
> +
> +static void sl_txt_write(u32 reg, u64 val)
> +{
> +	writeq(val, (void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
> +}

Man, that's a lot of casting. If TXT_PRIV_CONFIG_REGS_BASE were just a
pointer to being with, it could be:

	writeq(val, TXT_PRIV_CONFIG_REGS_BASE + reg);

Right?

This _looks_ like it was just written and then had casts added to it
until it compiled.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements
  2025-12-16  0:21   ` Eric Biggers
@ 2025-12-17 18:10     ` ross.philipson
  0 siblings, 0 replies; 41+ messages in thread
From: ross.philipson @ 2025-12-17 18:10 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu, dpsmith, tglx, mingo, bp, hpa,
	dave.hansen, ardb, mjg59, James.Bottomley, peterhuewe, jarkko,
	jgg, luto, nivedita, herbert, davem, corbet, ebiederm, dwmw2,
	baolu.lu, kanth.ghatraju, andrew.cooper3, trenchboot-devel

On 12/15/25 4:21 PM, Eric Biggers wrote:
> On Mon, Dec 15, 2025 at 03:33:05PM -0800, Ross Philipson wrote:
>> diff --git a/arch/x86/boot/compressed/sha1.c b/arch/x86/boot/compressed/sha1.c
>> new file mode 100644
>> index 000000000000..dd1b4cf5caf5
>> --- /dev/null
>> +++ b/arch/x86/boot/compressed/sha1.c
>> @@ -0,0 +1,7 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2025 Apertus Solutions, LLC.
>> + */
>> +
>> +#undef CONFIG_CRYPTO_LIB_SHA1_ARCH
>> +#include "../../../../lib/crypto/sha1.c"
> 
> CONFIG_* options shouldn't be undefined like this.  It seems that you're
> trying to build the SHA-1 code into a pre-boot environment.  This
> problem was already solved in the SHA-256 code, by making
> lib/crypto/sha256.c aware of __DISABLE_EXPORTS.  The SHA-1 code should
> use the same solution.
> 
> - Eric

That makes perfects sense, we will address that.

Thank you,
Ross


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 13/28] x86: Secure Launch Kconfig
  2025-12-16  3:20   ` Randy Dunlap
@ 2025-12-17 18:11     ` ross.philipson
  0 siblings, 0 replies; 41+ messages in thread
From: ross.philipson @ 2025-12-17 18:11 UTC (permalink / raw)
  To: Randy Dunlap, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel, ross.philipson

On 12/15/25 7:20 PM, Randy Dunlap wrote:
> 
> 
> On 12/15/25 3:33 PM, Ross Philipson wrote:
>> Add a Kconfig option for compiling in/out the Secure Launch feature.
>> Secure Launch is controlled by a singel boolean on/off.
>>
>> Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
>> ---
>>   arch/x86/Kconfig | 14 ++++++++++++++
>>   1 file changed, 14 insertions(+)
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index fa3b616af03a..9404d207c420 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -1975,6 +1975,20 @@ config EFI_RUNTIME_MAP
>>   
>>   	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
>>   
>> +config SECURE_LAUNCH
>> +	bool "Secure Launch DRTM support"
>> +	depends on X86_64 && X86_X2APIC && TCG_TIS && TCG_CRB
>> +	select CRYPTO_LIB_SHA1
>> +	select CRYPTO_LIB_SHA256
>> +	help
>> +	  The Secure Launch feature allows a kernel to be launched directly
>> +	  through a vendor neutral DTRM (Dynamic Root of Trust for Measurement)
> 
> 	                           DRTM

Thank you, will fix.
Ross

> 
>> +	  solution, with Intel TXT being one example.  The DRTM establishes an
>> +	  environment where the CPU measures the kernel image, employing the TPM,
>> +	  before starting it. Secure Launch then continues the measurement chain
>> +	  over kernel configuration information and other launch artifacts (e.g.
>> +	  any initramfs image).
>> +
>>   source "kernel/Kconfig.hz"
>>   
>>   config ARCH_SUPPORTS_KEXEC
> 



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 00/28] x86: Secure Launch support for Intel TXT
  2025-12-16  3:46 ` [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Jarkko Sakkinen
@ 2025-12-17 18:15   ` ross.philipson
  0 siblings, 0 replies; 41+ messages in thread
From: ross.philipson @ 2025-12-17 18:15 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-kernel, x86, linux-integrity, linux-doc, linux-crypto,
	kexec, linux-efi, iommu, dpsmith, tglx, mingo, bp, hpa,
	dave.hansen, ardb, mjg59, James.Bottomley, peterhuewe, jgg, luto,
	nivedita, herbert, davem, corbet, ebiederm, dwmw2, baolu.lu,
	kanth.ghatraju, andrew.cooper3, trenchboot-devel

On 12/15/25 7:46 PM, Jarkko Sakkinen wrote:
> On Mon, Dec 15, 2025 at 03:32:48PM -0800, Ross Philipson wrote:
>> Secure Launch is a vendor-neutral approach to implementing TGC Dynamic
>> Root of Trust (DRTM) support in the kernel. This is complementary to
>> better known Static Root of Trust (SRTM) schemes such as UEFI SecureBoot.
>>
>> This series provides the common infrastructure along with Intel TXT
>> support, without needing the tboot exokernel. Support for AMD SKINIT is
>> pending the common infrastructure getting nailed down, and ARM are
>> looking to build on it too.
>>
>> Originally, tboot were approached to see if they'd take support for
>> other vendors, but they elected not to. Hence this approach instead.
>>
>> Work is being coordinated by the Trenchboot project, https://trenchboot.org/,
>> organising Secure Launch support for upstream open source projects including
>> Grub, iPXE and Xen. The goal of the Trenchboot project is to make DTRM easy
>> to use.  e.g. for Grub, it's simply adding "slaunch" as a command in the boot
>> stanza.  See https://trenchboot.org/user-docs/QUICKSTART/#linux-quick-start-guide
>> for more details
>>
>> Patch set based on commit:
>> torvalds/master/fd57572253bc356330dbe5b233c2e1d8426c66fd
>>
>> Depends on v3 of the following TPM patch set (note this patch
>> set is being actively worked on separately):
>> [PATCH v3 00/10]  tpm: Decouple Trenchboot dependencies
>> Message ID: 20250929194832.2913286-1-jarkko@kernel.org
>>
>> Finally we would like to thank everyone for their input and
>> assistance. It has all been very helpful in improving the quality of
>> our solution and in reviewing/strengthening our security posture.
>>
>> Thanks
>> Ross Philipson and Daniel P. Smith
>>
>> Changes in v15:
>>
>>   - Rewriting and reformatting of the cover letter, commit message and
>>     code comments per requests from maintainers.
>>   - Introduction of a early TPM driver in the x86 setup kernel to allow
>>     TPM extend command very early in the boot.
>>   - Remove previous TPM extending architecture that attempted to update
>>     the TPM PCRs later in the boot process.
>>   - Split slaunch.h into 2 files, with a new txt.h. The former contains
>>     platform agnostic definitions for the SL feature. The new txt.h file
>>     contains Intel TXT definitions from the public specs.
>>   - Split TPM headers up following the specifications where the
>>     technologies are defined.
>>   - Include set of split up TPM header files to allow TPM driver reuse
>>     in other environments (e.g. early kernel, x86).
>>   - Fix code formatting and type-os.
>>
>>
>> Alec Brown (1):
>>    tpm: Remove main TPM header from TPM event log header
>>
>> Daniel P. Smith (6):
>>    tpm/tpm_tis: Close all localities
>>    tpm/tpm_tis: Address positive localities in tpm_tis_request_locality()
>>    Documentation/x86: Secure Launch kernel documentation
>>    x86: Add early SHA-1 support for Secure Launch early measurements
>>    x86: Add early SHA-256 support for Secure Launch early measurements
>>    x86: Secure Launch late initcall platform module
>>
>> Ross Philipson (21):
>>    tpm: Initial step to reorganize TPM public headers
>>    tpm: Move TPM1 specific definitions and functions to new headers
>>    tpm: Move TPM2 specific definitions and functions to new headers
>>    tpm: Move TPM common base definitions to new public common header
>>    tpm: Move platform specific definitions to the new PTP header
>>    tpm: Add TPM buffer support header for standalone reuse
>>    tpm/tpm_tis: Allow locality to be set to a different value
>>    tpm/sysfs: Show locality used by kernel
>>    x86: Secure Launch Kconfig
>>    x86: Secure Launch Resource Table header file
>>    x86: Secure Launch main header file
>>    x86/txt: Intel Trusted eXecution Technology (TXT) definitions
>>    x86/tpm: Early TPM PCR extending driver
>>    x86/msr: Add variable MTRR base/mask and x2apic ID registers
>>    x86/boot: Place TXT MLE header in the kernel_info section
>>    x86: Secure Launch kernel early boot stub
>>    x86: Secure Launch kernel late boot stub
>>    x86: Secure Launch SMP bringup support
>>    kexec: Secure Launch kexec SEXIT support
>>    x86/reboot: Secure Launch SEXIT support on reboot paths
>>    x86/efi: EFI stub DRTM launch support for Secure Launch
>>
>>   Documentation/arch/x86/boot.rst               |  21 +
>>   Documentation/security/index.rst              |   1 +
>>   .../security/launch-integrity/index.rst       |  11 +
>>   .../security/launch-integrity/principles.rst  | 308 +++++++
>>   .../secure_launch_details.rst                 | 587 +++++++++++++
>>   .../secure_launch_overview.rst                | 240 ++++++
>>   arch/x86/Kconfig                              |  14 +
>>   arch/x86/boot/compressed/Makefile             |   8 +
>>   arch/x86/boot/compressed/early_tpm_extend.c   | 601 ++++++++++++++
>>   arch/x86/boot/compressed/head_64.S            |  29 +
>>   arch/x86/boot/compressed/kernel_info.S        |  50 +-
>>   arch/x86/boot/compressed/sha1.c               |   7 +
>>   arch/x86/boot/compressed/sha256.c             |   6 +
>>   arch/x86/boot/compressed/sl_main.c            | 638 +++++++++++++++
>>   arch/x86/boot/compressed/sl_stub.S            | 770 ++++++++++++++++++
>>   arch/x86/boot/compressed/tpm.h                |  42 +
>>   arch/x86/boot/compressed/vmlinux.lds.S        |   7 +
>>   arch/x86/include/asm/msr-index.h              |   5 +
>>   arch/x86/include/asm/realmode.h               |   3 +
>>   arch/x86/include/asm/txt.h                    | 330 ++++++++
>>   arch/x86/include/uapi/asm/bootparam.h         |   1 +
>>   arch/x86/kernel/Makefile                      |   2 +
>>   arch/x86/kernel/asm-offsets.c                 |  20 +
>>   arch/x86/kernel/reboot.c                      |  14 +
>>   arch/x86/kernel/setup.c                       |   3 +
>>   arch/x86/kernel/slaunch.c                     | 615 ++++++++++++++
>>   arch/x86/kernel/slmodule.c                    | 348 ++++++++
>>   arch/x86/kernel/smpboot.c                     |  47 +-
>>   arch/x86/realmode/init.c                      |   8 +
>>   arch/x86/realmode/rm/header.S                 |   3 +
>>   arch/x86/realmode/rm/trampoline_64.S          |  32 +
>>   drivers/char/tpm/tpm-buf.c                    |  10 +-
>>   drivers/char/tpm/tpm-chip.c                   |  34 +-
>>   drivers/char/tpm/tpm-sysfs.c                  |  10 +
>>   drivers/char/tpm/tpm.h                        | 180 +---
>>   drivers/char/tpm/tpm1-cmd.c                   |  18 +-
>>   drivers/char/tpm/tpm1_structs.h               |  97 +++
>>   drivers/char/tpm/tpm2-cmd.c                   |  32 +-
>>   drivers/char/tpm/tpm2-space.c                 |  13 -
>>   drivers/char/tpm/tpm2_structs.h               |  58 ++
>>   drivers/char/tpm/tpm_tis_core.c               |  21 +-
>>   drivers/char/tpm/tpm_tis_core.h               |  64 +-
>>   drivers/firmware/efi/libstub/efistub.h        |   8 +
>>   drivers/firmware/efi/libstub/x86-stub.c       | 100 +++
>>   drivers/iommu/intel/dmar.c                    |   4 +
>>   include/keys/trusted_tpm.h                    |   1 -
>>   include/linux/slaunch.h                       | 251 ++++++
>>   include/linux/slr_table.h                     | 308 +++++++
>>   include/linux/tpm.h                           | 240 +-----
>>   include/linux/tpm1.h                          |  87 ++
>>   include/linux/tpm2.h                          | 247 ++++++
>>   include/linux/tpm_buf.h                       |  57 ++
>>   include/linux/tpm_command.h                   |  30 -
>>   include/linux/tpm_common.h                    |  99 +++
>>   include/linux/tpm_eventlog.h                  |   4 +-
>>   include/linux/tpm_ptp.h                       | 139 ++++
>>   kernel/kexec_core.c                           |   8 +
>>   security/keys/trusted-keys/trusted_tpm1.c     |   1 -
>>   security/keys/trusted-keys/trusted_tpm2.c     |   1 -
>>   59 files changed, 6319 insertions(+), 574 deletions(-)
>>   create mode 100644 Documentation/security/launch-integrity/index.rst
>>   create mode 100644 Documentation/security/launch-integrity/principles.rst
>>   create mode 100644 Documentation/security/launch-integrity/secure_launch_details.rst
>>   create mode 100644 Documentation/security/launch-integrity/secure_launch_overview.rst
>>   create mode 100644 arch/x86/boot/compressed/early_tpm_extend.c
>>   create mode 100644 arch/x86/boot/compressed/sha1.c
>>   create mode 100644 arch/x86/boot/compressed/sha256.c
>>   create mode 100644 arch/x86/boot/compressed/sl_main.c
>>   create mode 100644 arch/x86/boot/compressed/sl_stub.S
>>   create mode 100644 arch/x86/boot/compressed/tpm.h
>>   create mode 100644 arch/x86/include/asm/txt.h
>>   create mode 100644 arch/x86/kernel/slaunch.c
>>   create mode 100644 arch/x86/kernel/slmodule.c
>>   create mode 100644 drivers/char/tpm/tpm1_structs.h
>>   create mode 100644 drivers/char/tpm/tpm2_structs.h
>>   create mode 100644 include/linux/slaunch.h
>>   create mode 100644 include/linux/slr_table.h
>>   create mode 100644 include/linux/tpm1.h
>>   create mode 100644 include/linux/tpm2.h
>>   create mode 100644 include/linux/tpm_buf.h
>>   delete mode 100644 include/linux/tpm_command.h
>>   create mode 100644 include/linux/tpm_common.h
>>   create mode 100644 include/linux/tpm_ptp.h
>>
>> -- 
>> 2.43.7
>>
> 
> Most likely I'll review this after the holidays (for heads up).
> 
> BR, Jarkko

Thank you Jarkko.


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver
  2025-12-16 21:53   ` Dave Hansen
@ 2025-12-17 18:40     ` ross.philipson
  2025-12-17 19:06       ` Dave Hansen
  0 siblings, 1 reply; 41+ messages in thread
From: ross.philipson @ 2025-12-17 18:40 UTC (permalink / raw)
  To: Dave Hansen, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel, ross.philipson

On 12/16/25 1:53 PM, Dave Hansen wrote:
> I'm mostly spot-checking this to see what kind of shape it's in and how
> much work and diligence has been applied in the last 8 months since v14.
> 
> On 12/15/25 15:33, Ross Philipson wrote:
> ...
>> The driver could be extended for further operations if needed. This
>> TPM dirver implementation relies as much as possible on existing mainline
> 
> <sigh>
> 
> v15 and no spell checking. :(

Will fix.

> 
>> --- /dev/null
>> +++ b/arch/x86/boot/compressed/early_tpm_extend.c
>> @@ -0,0 +1,601 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2010-2012 United States Government, as represented by
>> + * the Secretary of Defense.  All rights reserved.
> 
> IANAL, but this looks fishy.
> 
> It's theoretically fine to go grab random code off the Internet and
> submit it to the kernel, given the correct license. But I do want to
> know what its story is and where it came from.
> 
> I also seem to remember that there are special rules around the US
> federal government's inability to hold copyrights. This seems worth at
> least a mention ... somewhere.
> 
> This is helpful, for instance:
> 
>> + * based off of the original tools/vtpm_manager code base which is:
>> + * Copyright (c) 2005, Intel Corp.
>> + * All rights reserved.
> 
> so thanks for that one.
> 
>> + * Redistribution and use in source and binary forms, with or without
>> + * modification, are permitted provided that the following conditions
>> + * are met:
>> + *
>> + *   * Redistributions of source code must retain the above copyright
>> + *     notice, this list of conditions and the following disclaimer.
>> + *   * Redistributions in binary form must reproduce the above
>> + *     copyright notice, this list of conditions and the following
>> + *     disclaimer in the documentation and/or other materials provided
>> + *     with the distribution.
>> + *   * Neither the name of Intel Corporation nor the names of its
>> + *     contributors may be used to endorse or promote products derived
>> + *     from this software without specific prior written permission.
>> + *
>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
>> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
>> + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
>> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
>> + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
>> + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
>> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
>> + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
>> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
>> + * OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
> 
> Also, IANAL, but this looks BSD-ish.
> 
> I would have kinda expected the SPDX header to say BSD-blah-blah and not
> GPL-2.0-only.
> 
> I'd really appreciate if you could go have a huddle with your corporate
> Open Source folks and make sure this is all proper. To me, it looks
> fishy at _best_.

Yes, we will do exactly that for all the licensing and sort it out.

> 
> ...
>> +/*
>> + * We're far too early to calibrate time.  Assume a 5GHz processor (the upper
>> + * end of the Fam19h range), which causes us to be wrong in the safe direction
>> + * on slower systems.
>> + */
> 
> https://urldefense.com/v3/__https://docs.kernel.org/process/maintainer-tip.html*changelog__;Iw!!ACWV5N9M2RV99hQ!ODp_iKdXfPuA60ae9ZCFdElNvGZjrd7ffPYtSVs3cwOTY2kzGN_tgsRLYawnxEGiHE0jMDN2kgOxBBtMtmu-7ohw$
> 
> Imperative voice please.

+1

> 
> ...
>> +static int __tis_recv_data(struct tpm_chip *chip, u8 *buf, int count)
>> +{
>> +	int size = 0;
>> +	int burstcnt;
>> +
>> +	while (size < count && __tis_wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, chip->timeout_c) == 0) {
>> +		burstcnt = __tis_get_burstcount(chip);
>> +
>> +		for ( ; burstcnt > 0 && size < count; --burstcnt)
>> +			buf[size++] = tpm_read8(chip, TPM_DATA_FIFO(chip->locality));
>> +	}
>> +
>> +	return size;
>> +}
>> +
>> +/**
>> + * tpm_tis_check_locality - Check if the given locality is the active one
>> + * @chip:	The TPM chip instance
>> + * @loc:	The locality to check
>> + *
>> + * Return: true - locality active, false - not active
>> + */
>> +bool tpm_tis_check_locality(struct tpm_chip *chip, int loc)
>> +{
>> +	if ((tpm_read8(chip, TPM_ACCESS(loc)) & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
>> +		chip->locality = loc;
>> +		return true;
>> +	}
>> +
>> +	return false;
>> +}
>> +
>> +/**
>> + * tpm_tis_release_locality - Release the active locality
>> + * @chip:	The TPM chip instance
>> + */
>> +void tpm_tis_release_locality(struct tpm_chip *chip)
>> +{
>> +	if ((tpm_read8(chip, TPM_ACCESS(chip->locality)) & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
>> +		tpm_write8(chip, TPM_ACCESS(chip->locality), TPM_ACCESS_RELINQUISH_LOCALITY);
>> +
>> +	chip->locality = 0;
>> +}
> 
> I guess some folks aren't enforcing the 80-column limits. But this is
> not even close. It's almost 80x2.
> 
> Has there even been an attempt to make this conform to kernel coding
> style? What other checkpatch.pl warnings are being ignored?
> 

We do run checkpatch.pl and fix the issues it points out. I feel it is 
not clear how to approach the 80 character limit rule though. I have 
been told in other reviews that the 80 char rule is not really followed 
and certain things would read better w/o it. Reading the guide again, it 
does not really spell out details other than try to keep it 80 and 
under. Maybe there should be a hard limit (< 80x2) if you exceed it?

But ultimately I will format the code in whatever manner is requested.

Thank you,
Ross



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions
  2025-12-16 22:14   ` Dave Hansen
@ 2025-12-17 18:44     ` ross.philipson
  0 siblings, 0 replies; 41+ messages in thread
From: ross.philipson @ 2025-12-17 18:44 UTC (permalink / raw)
  To: Dave Hansen, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

On 12/16/25 2:14 PM, Dave Hansen wrote:
> On 12/15/25 15:33, Ross Philipson wrote:
>> +static inline struct txt_heap_event_log_pointer2_1_element*
>> +txt_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
>> +{
>> +	struct txt_heap_ext_data_element *ext_elem;
>> +
>> +	/* The extended element array is at the end of this table */
>> +	ext_elem = (struct txt_heap_ext_data_element *)
>> +		((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));
> 
> I'd really honestly see a helper for this kind of thing:
> 
> #define ptr_after(foo)	((void *)foo + sizeof(foo))
> 
> resulting in:
> 
> 	ext_elem = ptr_after(os_sinit_data);
 >

We can do that.
  > would be a billion times easier to read than what's there. I honestly
> don't even see why this bothers with the u8 and cast to 'struct
> txt_heap_ext_data_element *' versus just using void* and being done with it.
> 
> There's no type safety here in the first place so why bother?

Earlier, this was done to a number of other functions for the same 
reason. We will change it here too.

Ross

> 
>> +	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);
>> +	}



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 22/28] x86: Secure Launch kernel early boot stub
  2025-12-16 22:32   ` [PATCH v15 22/28] x86: Secure Launch kernel early boot stub Dave Hansen
@ 2025-12-17 18:47     ` ross.philipson
  0 siblings, 0 replies; 41+ messages in thread
From: ross.philipson @ 2025-12-17 18:47 UTC (permalink / raw)
  To: Dave Hansen, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel, ross.philipson

On 12/16/25 2:32 PM, Dave Hansen wrote:
> On 12/15/25 15:33, Ross Philipson wrote:
>> +static u64 sl_txt_read(u32 reg)
>> +{
>> +	return readq((void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
>> +}
>> +
>> +static void sl_txt_write(u32 reg, u64 val)
>> +{
>> +	writeq(val, (void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
>> +}
> 
> Man, that's a lot of casting. If TXT_PRIV_CONFIG_REGS_BASE were just a
> pointer to being with, it could be:
> 
> 	writeq(val, TXT_PRIV_CONFIG_REGS_BASE + reg);
> 
> Right?

Indeed, we can simplify this per your suggestion.

> 
> This _looks_ like it was just written and then had casts added to it
> until it compiled.

Thank you for you feedback so far.

Ross


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver
  2025-12-17 18:40     ` ross.philipson
@ 2025-12-17 19:06       ` Dave Hansen
  0 siblings, 0 replies; 41+ messages in thread
From: Dave Hansen @ 2025-12-17 19:06 UTC (permalink / raw)
  To: ross.philipson, linux-kernel, x86, linux-integrity, linux-doc,
	linux-crypto, kexec, linux-efi, iommu
  Cc: dpsmith, tglx, mingo, bp, hpa, dave.hansen, ardb, mjg59,
	James.Bottomley, peterhuewe, jarkko, jgg, luto, nivedita, herbert,
	davem, corbet, ebiederm, dwmw2, baolu.lu, kanth.ghatraju,
	andrew.cooper3, trenchboot-devel

On 12/17/25 10:40, ross.philipson@oracle.com wrote:
> But ultimately I will format the code in whatever manner is requested.

Honestly, it looks like folks just copied the code from wherever it came
and completely ignored _any_ sane column limits.

It's not about $FOO columns or $BAR columns. It's about having code
that's readable and maintainable. The key issue here is that there's
been no apparent effort to try to make the code readable and maintainable.

Am I wrong?

Next steps: First, try to make the code readable and maintainable. If
you can do that under 80 columns, great. Aim for 80. If doing 85 or 100
makes the code more readable or maintainable, that's OK too.

But I'm a little discouraged that we're at v15 and talking about
"readable and maintainable". That's RFC fodder, not v15.


^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2025-12-17 19:06 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-15 23:32 [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Ross Philipson
2025-12-15 23:32 ` [PATCH v15 01/28] tpm: Initial step to reorganize TPM public headers Ross Philipson
2025-12-15 23:32 ` [PATCH v15 02/28] tpm: Move TPM1 specific definitions and functions to new headers Ross Philipson
2025-12-15 23:32 ` [PATCH v15 03/28] tpm: Move TPM2 " Ross Philipson
2025-12-15 23:32 ` [PATCH v15 04/28] tpm: Move TPM common base definitions to new public common header Ross Philipson
2025-12-15 23:32 ` [PATCH v15 05/28] tpm: Move platform specific definitions to the new PTP header Ross Philipson
2025-12-15 23:32 ` [PATCH v15 06/28] tpm: Add TPM buffer support header for standalone reuse Ross Philipson
2025-12-15 23:32 ` [PATCH v15 07/28] tpm: Remove main TPM header from TPM event log header Ross Philipson
2025-12-15 23:32 ` [PATCH v15 08/28] tpm/tpm_tis: Close all localities Ross Philipson
2025-12-15 23:32 ` [PATCH v15 09/28] tpm/tpm_tis: Address positive localities in tpm_tis_request_locality() Ross Philipson
2025-12-15 23:32 ` [PATCH v15 10/28] tpm/tpm_tis: Allow locality to be set to a different value Ross Philipson
2025-12-15 23:32 ` [PATCH v15 11/28] tpm/sysfs: Show locality used by kernel Ross Philipson
2025-12-15 23:33 ` [PATCH v15 13/28] x86: Secure Launch Kconfig Ross Philipson
2025-12-16  3:20   ` Randy Dunlap
2025-12-17 18:11     ` ross.philipson
2025-12-15 23:33 ` [PATCH v15 14/28] x86: Secure Launch Resource Table header file Ross Philipson
2025-12-15 23:33 ` [PATCH v15 15/28] x86: Secure Launch main " Ross Philipson
2025-12-15 23:33 ` [PATCH v15 16/28] x86/txt: Intel Trusted eXecution Technology (TXT) definitions Ross Philipson
2025-12-16 22:14   ` Dave Hansen
2025-12-17 18:44     ` ross.philipson
2025-12-15 23:33 ` [PATCH v15 17/28] x86: Add early SHA-1 support for Secure Launch early measurements Ross Philipson
2025-12-16  0:21   ` Eric Biggers
2025-12-17 18:10     ` ross.philipson
2025-12-15 23:33 ` [PATCH v15 18/28] x86: Add early SHA-256 " Ross Philipson
2025-12-15 23:33 ` [PATCH v15 19/28] x86/tpm: Early TPM PCR extending driver Ross Philipson
2025-12-16 21:53   ` Dave Hansen
2025-12-17 18:40     ` ross.philipson
2025-12-17 19:06       ` Dave Hansen
2025-12-15 23:33 ` [PATCH v15 20/28] x86/msr: Add variable MTRR base/mask and x2apic ID registers Ross Philipson
2025-12-15 23:33 ` [PATCH v15 21/28] x86/boot: Place TXT MLE header in the kernel_info section Ross Philipson
2025-12-15 23:33 ` [PATCH v15 23/28] x86: Secure Launch kernel late boot stub Ross Philipson
2025-12-15 23:33 ` [PATCH v15 24/28] x86: Secure Launch SMP bringup support Ross Philipson
2025-12-15 23:33 ` [PATCH v15 25/28] kexec: Secure Launch kexec SEXIT support Ross Philipson
2025-12-15 23:33 ` [PATCH v15 26/28] x86/reboot: Secure Launch SEXIT support on reboot paths Ross Philipson
2025-12-15 23:33 ` [PATCH v15 27/28] x86: Secure Launch late initcall platform module Ross Philipson
2025-12-15 23:33 ` [PATCH v15 28/28] x86/efi: EFI stub DRTM launch support for Secure Launch Ross Philipson
2025-12-16  3:46 ` [PATCH v15 00/28] x86: Secure Launch support for Intel TXT Jarkko Sakkinen
2025-12-17 18:15   ` ross.philipson
2025-12-16 22:14 ` Dave Hansen
     [not found] ` <20251215233316.1076248-23-ross.philipson@oracle.com>
2025-12-16 22:32   ` [PATCH v15 22/28] x86: Secure Launch kernel early boot stub Dave Hansen
2025-12-17 18:47     ` ross.philipson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).