2013-05-13 09:34:37

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH v2 0/3] Intel TXT driver

Changeslog from v1:
* remove tboot log code
* add terms description in commit log and comment at the top of the driver
* check whether a platform has TXT support before registering a device

This module is expected to be a better tool to access below resources
- TXT config space
- SMX parameter

Intel TXT (Trusted Execution Technology) will provide higher assurance
of system configuration and initial state as well as data reset
protection. It also helps solve real end user concerns about having
confidence that their hardware is running the VMM or kernel that
it was configured with, especially since they may be responsible for
providing such assurances to VMs and services running on it.

See Documentation/intel_txt.txt for more information about Intel TXT.

Intel TXT configuration registers are a subset of chipset registers.
These chipset registers that interact with SMX are accessed from two
regions of memory, which represent the public and private configuration
spaces, by system software using memory read/write protocols.

Safer Mode Extensions (SMX) provide a processor's programming
interface in an Intel TXT platform for system software to establish
a measured environment within the platform to support trust decisions
by end users.

With this module, it will be easier to access TXT related information.

Qiaowei Ren (3):
driver: add TXT driver in kernel
driver: provide sysfs interfaces to access TXT config space
driver: provide sysfs interfaces to access SMX parameter

Documentation/ABI/testing/sysfs-platform-intel-txt | 382 ++++++++
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/intel_txt/Kconfig | 27 +
drivers/platform/x86/intel_txt/Makefile | 5 +
drivers/platform/x86/intel_txt/txt-config.c | 1029 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-config.h | 138 +++
drivers/platform/x86/intel_txt/txt-parameter.c | 254 +++++
drivers/platform/x86/intel_txt/txt-parameter.h | 39 +
drivers/platform/x86/intel_txt/txt-sysfs.c | 79 ++
10 files changed, 1956 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-platform-intel-txt
create mode 100644 drivers/platform/x86/intel_txt/Kconfig
create mode 100644 drivers/platform/x86/intel_txt/Makefile
create mode 100644 drivers/platform/x86/intel_txt/txt-config.c
create mode 100644 drivers/platform/x86/intel_txt/txt-config.h
create mode 100644 drivers/platform/x86/intel_txt/txt-parameter.c
create mode 100644 drivers/platform/x86/intel_txt/txt-parameter.h
create mode 100644 drivers/platform/x86/intel_txt/txt-sysfs.c

--
1.7.9.5


2013-05-13 09:34:43

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH v2 2/3] driver: provide sysfs interfaces to access TXT config space

These interfaces are located in /sys/devices/platform/intel_txt/config,
and including totally 37 files, providing access to Intel TXT
configuration registers.

Signed-off-by: Qiaowei Ren <[email protected]>
Signed-off-by: Xiaoyan Zhang <[email protected]>
Signed-off-by: Gang Wei <[email protected]>
---
Documentation/ABI/testing/sysfs-platform-intel-txt | 309 ++++++
drivers/platform/x86/intel_txt/Makefile | 2 +-
drivers/platform/x86/intel_txt/txt-config.c | 1029 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-config.h | 138 +++
drivers/platform/x86/intel_txt/txt-sysfs.c | 12 +
5 files changed, 1489 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-platform-intel-txt
create mode 100644 drivers/platform/x86/intel_txt/txt-config.c
create mode 100644 drivers/platform/x86/intel_txt/txt-config.h

diff --git a/Documentation/ABI/testing/sysfs-platform-intel-txt b/Documentation/ABI/testing/sysfs-platform-intel-txt
new file mode 100644
index 0000000..fa20a9f
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-intel-txt
@@ -0,0 +1,309 @@
+What: /sys/devices/platform/intel_txt/config/
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The config/ directory exposes Intel TXT configuration
+ registers. These registers are a subset of chipset registers.
+ They are mapped into two regions of memory, representing the
+ public and private configuration spaces.
+
+ Registers in the private space can only be accessed after a
+ measured environment has been established and before the
+ TXT.CMD.CLOSE-PRIVATE command has been issued. The public space
+ registers are available before, during and after a measured
+ environment launch. All registers are available within both
+ spaces, though with different permissions.
+
+What: /sys/devices/platform/intel_txt/config/STS_raw
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.STS is the general status register. This read-only register
+ is used by AC modules and the MLE to get the status of various
+ Intel TXT features.
+
+What: /sys/devices/platform/intel_txt/config/STS_enter_done
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The chipset sets SENTER.DONE.STS status bit when it sees all
+ of the threads have done an TXT.CYC.SENTER-ACK.
+
+What: /sys/devices/platform/intel_txt/config/STS_sexit_done
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: SEXIT.DONE.STS status bit is set when all of the bits in the
+ TXT.THREADS.JOIN register are clear. Thus, this bit will be
+ set immediately after reset.
+
+What: /sys/devices/platform/intel_txt/config/STS_mem_config_lock
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: MEM-CONFIG-LOCK.STS status bit will be set to 1 when the memory
+ configuration has been locked. Cleared by
+ TXT.CMD.UNLOCK.MEMCONFIG or by a system reset.
+
+What: /sys/devices/platform/intel_txt/config/STS_private_open
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: PRIVATE-OPEN.STS status bit will be set to 1 when
+ TXT.CMD.OPEN-PRIVATE is performed. Cleared by
+ TXT.CMD.CLOSE-PRIVATE or by a system reset.
+
+What: /sys/devices/platform/intel_txt/config/STS_locality_1_open
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.LOCALITY1.OPEN.STS status bit is set when the
+ TXT.CMD.OPEN.LOCALITY1 command is seen by the chipset.
+ It is cleared on reset or when TXT.CMD.CLOSE.LOCALITY1 is seen.
+
+What: /sys/devices/platform/intel_txt/config/STS_locality_2_open
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.LOCALITY2.OPEN.STS status bit is set when either the
+ TXT.CMD.OPEN.LOCALITY2 command or the TXT.CMD.OPEN.PRIVATE
+ is seen by the chipset. It is cleared on reset, when either
+ TXT.CMD.CLOSE.LOCALITY2 or TXT.CMD.CLOSE.PRIVATE is seen,
+ and by the GETSEC[SEXIT] instruction.
+
+What: /sys/devices/platform/intel_txt/config/ESTS_raw
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.ESTS is the error status register which contains status
+ information associated with various error conditions. The
+ contents of this read-only register are preserved across
+ soft resets.
+
+What: /sys/devices/platform/intel_txt/config/ESTS_intel_txt_reset
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT_RESET.STS bit is set to '1' to indicate that an event
+ occurred which may prevent the proper use of TXT (possibly
+ including a TXT reset).
+
+What: /sys/devices/platform/intel_txt/config/ERRORCODE
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.ERRORCODE register holds the Intel TXT shutdown error code.
+ A soft reset does not clear the contents of this register;
+ a hard reset/power cycle will clear the contents. This was
+ formerly labeled the TXT.CRASH register.
+
+What: /sys/devices/platform/intel_txt/config/CMD_RESET
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: A write to TXT.CMD.RESET register causes a system reset.
+ This is performed by the processor as part of an Intel TXT
+ shutdown, after writing to the TXT.ERRORCODE register.
+
+What: /sys/devices/platform/intel_txt/config/CMD_CLOSE_PRIVATE
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: A write to TXT.CMD.CLOSE-PRIVATE register causes the Intel
+ TXT-capable chipset private configuration space to be locked.
+ Locality 2 will also be closed. Once locked, conventional
+ memory read/write operations can no longer be used to access
+ these registers. The private configuration space can only be
+ opened for the MLE by successfully executing GETSEC[SENTER].
+
+What: /sys/devices/platform/intel_txt/config/VER_FSBIF
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.VER.FSBIF register identifies whether the chipset is
+ debug or release fused.
+
+What: /sys/devices/platform/intel_txt/config/DIDVID_raw
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.DIDVID register contains the vendor, device, and revision
+ IDs for the memory controller or chipset.
+
+What: /sys/devices/platform/intel_txt/config/DIDVID_vendor_id
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Vendor ID.
+
+What: /sys/devices/platform/intel_txt/config/DIDVID_device_id
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Device ID.
+
+What: /sys/devices/platform/intel_txt/config/DIDVID_revision_id
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Revision ID.
+
+What: /sys/devices/platform/intel_txt/config/VER_QPIIF
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.VER.QPIIF register identifies whether the memory
+ controller or chipset is debug or release fused.
+
+What: /sys/devices/platform/intel_txt/config/CMD_UNLOCK_MEM_CONFIG
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: When TXT.CMD.UNLOCK-MEM-CONFIG command is invoked, the
+ chipset unlocks all memory configuration registers.
+
+What: /sys/devices/platform/intel_txt/config/SINIT_BASE
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.SINIT.BASE register contains the physical base address
+ of the memory region set aside by the BIOS for loading an
+ SINIT AC module. If BIOS has provided an SINIT AC module,
+ it will be located at this address. System software that
+ provides an SINIT AC module must store it to this location.
+
+What: /sys/devices/platform/intel_txt/config/SINIT_SIZE
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.SINIT.SIZE register contains the size (in bytes) of
+ the memory region set aside by the BIOS for loading an
+ SINIT AC module. This register is initialized by the BIOS.
+
+What: /sys/devices/platform/intel_txt/config/MLE_JOIN
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Holds a physical address pointer to the base of the join
+ data structure used to initialize RLPs in response to
+ GETSEC[WAKEUP].
+
+What: /sys/devices/platform/intel_txt/config/HEAP_BASE
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.HEAP.BASE register contains the physical base address
+ of the Intel TXT Heap memory region. The BIOS initializes
+ this register.
+
+What: /sys/devices/platform/intel_txt/config/HEAP_SIZE
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.HEAP.SIZE register contains the size (in bytes) of the
+ Intel TXT Heap memory region. The BIOS initializes this
+ register.
+
+What: /sys/devices/platform/intel_txt/config/DPR_raw
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: TXT.DPR register defines the DMA Protected Range of memory
+ in which the TXT heap and SINIT region are located.
+
+What: /sys/devices/platform/intel_txt/config/DPR_lock
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Bits 19:0 are locked down in this register when this Lock
+ bit is set.
+
+What: /sys/devices/platform/intel_txt/config/DPR_top
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Top address + 1 of DPR.
+
+What: /sys/devices/platform/intel_txt/config/DPR_size
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: This is the size of memory, in MB, that will be protected from
+ DMA accesses. A value of 0x00 in this field means no additional
+ memory is protected.
+
+What: /sys/devices/platform/intel_txt/config/CMD_OPEN_LOCALITY1
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Writing to this TXT.CMD.OPEN.LOCALITY1 register "opens" the
+ TPM locality 1 address range, enabling decoding by the chipset
+ and thus access to the TPM.
+
+What: /sys/devices/platform/intel_txt/config/CMD_CLOSE_LOCALITY1
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Writing to this TXT.CMD.CLOSE.LOCALITY1 register "closes" the
+ TPM locality 1 address range, disabling decoding by the chipset
+ and thus access to the TPM.
+
+What: /sys/devices/platform/intel_txt/config/CMD_OPEN_LOCALITY2
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Writing to this TXT.CMD.OPEN.LOCALITY2 register "opens" the
+ TPM locality 2 address range, enabling decoding by the chipset
+ and thus access to the TPM.
+
+What: /sys/devices/platform/intel_txt/config/CMD_CLOSE_LOCALITY2
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Writing to this TXT.CMD.CLOSE.LOCALITY2 register "closes" the
+ TPM locality 2 address range, disabling decoding by the chipset
+ and thus access to the TPM.
+
+What: /sys/devices/platform/intel_txt/config/PUBLIC_KEY
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: This read-only TXT.PUBLIC.KEY register contains the hash of
+ the public key used for the verification of AC Modules.
+ The size, hash algorithm, and value are specific to the memory
+ controller or chipset.
+
+What: /sys/devices/platform/intel_txt/config/CMD_SECRETS
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Writing to this TXT.CMD.SECRETS register indicates to the
+ chipset that there are secrets in memory. The chipset tracks
+ this fact with a sticky bit. If the platform reboots with this
+ sticky bit set the BIOS AC module (or BIOS on multiprocessor
+ TXT systems) will scrub memory. The chipset also uses this
+ bit to detect invalid sleep state transitions. If software
+ tries to transition to S3, S4, or S5 while secrets are in
+ memory then the chipset will reset the system.
+
+What: /sys/devices/platform/intel_txt/config/CMD_NO_SECRETS
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: Writing to this TXT.CMD.NO-SECRETS register indicates there
+ are no secrets in memory.
+
+What: /sys/devices/platform/intel_txt/config/E2STS_raw
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: This TXT.E2STS register is used to read the status associated
+ with various errors that might be detected.
+
+What: /sys/devices/platform/intel_txt/config/E2STS_secrets
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: 0 = Chipset acknowledges that no secrets are in memory.
+ 1 = Chipset believes that secrets are in memory and will
+ provide reset protection.
diff --git a/drivers/platform/x86/intel_txt/Makefile b/drivers/platform/x86/intel_txt/Makefile
index a130308..8d5258e 100644
--- a/drivers/platform/x86/intel_txt/Makefile
+++ b/drivers/platform/x86/intel_txt/Makefile
@@ -2,4 +2,4 @@
# Makefile for the intel TXT drivers.
#
obj-$(CONFIG_INTEL_TXT_DRIVER) += intel_txt.o
-intel_txt-y := txt-sysfs.o
+intel_txt-y := txt-sysfs.o txt-config.o
diff --git a/drivers/platform/x86/intel_txt/txt-config.c b/drivers/platform/x86/intel_txt/txt-config.c
new file mode 100644
index 0000000..c16b7e7
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-config.c
@@ -0,0 +1,1029 @@
+/*
+ * txt-config.c
+ *
+ * Totally 37 sysfs files with owner root, each related with a register.
+ *
+ * Intel TXT configuration registers are a subset of chipset registers.
+ * These registers are mapped into two regions of memory, representing
+ * the public and private configuration spaces.
+ *
+ * STS_raw -r--r--r-- ERRORCODE -rw-rw-r--
+ * STS_senter_done -r--r--r-- STS_sexit_done -r--r--r--
+ * STS_mem_config_lock -r--r--r-- STS_private_open -r--r--r--
+ * STS_locality_1_open -r--r--r-- STS_locality_2_open -r--r--r--
+ * ESTS_raw -r--r--r-- ESTS_txt_reset -r--r--r--
+ * E2STS_raw -r--r--r-- E2STS_secrets -rw-rw-r--
+ * VER_FSBIF -r--r--r-- VER_QPIIF -r--r--r--
+ * DIDVID_raw -r--r--r-- DIDVID_vendor_id -r--r--r--
+ * DIDVID_device_id -r--r--r-- DIDVID_revision_id -r--r--r--
+ * SINIT_BASE -rw-rw-r-- SINIT_SIZE -rw-rw-r--
+ * HEAP_BASE -rw-rw-r-- HEAP_SIZE -rw-rw-r--
+ * PUBLIC_KEY -r--r--r-- MLE_JOIN -rw-rw-r--
+ * DPR_raw -rw-rw-r-- DPR_lock -rw-rw-r--
+ * DPR_top -rw-rw-r-- DPR_size -rw-rw-r--
+ * CMD_RESET --w--w---- CMD_CLOSE_PRIVATE --w--w----
+ * CMD_SECRETS --w--w---- CMD_NO_SECRETS --w--w----
+ * CMD_OPEN_LOCALITY1 --w--w---- CMD_OPEN_LOCALITY2 --w--w----
+ * CMD_CLOSE_LOCALITY1 --w--w---- CMD_CLOSE_LOCALITY2 --w--w----
+ * CMD_UNLOCK_MEM_CONFIG --w--w----
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+#include <linux/io.h>
+#include <linux/stat.h>
+
+#include "txt-config.h"
+
+static ssize_t print_hex(char *buf, void *start, size_t len)
+{
+ char *str = buf;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ str += scnprintf(str, PAGE_SIZE, "%02x ", *(uint8_t *)start);
+ start++;
+ if ((i + 1) % 16 == 0)
+ str += scnprintf(str, PAGE_SIZE, "\n");
+ }
+
+ return str - buf;
+}
+
+static ssize_t show_config(char *buf, u32 offset)
+{
+ void __iomem *config;
+ int retval;
+
+ config = ioremap_nocache(TXT_PUB_CONFIG_REGS_BASE,
+ TXT_CONFIG_REGS_SIZE);
+ if (config == NULL)
+ return -ENOMEM;
+
+ switch (offset) {
+ case off_STS_raw:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%08llx\n", sts._raw);
+ break;
+ }
+
+ case off_STS_senter_done:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n", sts.senter_done_sts);
+ break;
+ }
+
+ case off_STS_sexit_done:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n", sts.sexit_done_sts);
+ break;
+ }
+
+ case off_STS_mem_config_lock:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n",
+ sts.mem_config_lock_sts);
+ break;
+ }
+
+ case off_STS_private_open:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n",
+ sts.private_open_sts);
+ break;
+ }
+
+ case off_STS_locality_1_open:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n",
+ sts.locality_1_open_sts);
+ break;
+ }
+
+ case off_STS_locality_2_open:
+ {
+ txt_sts_t sts;
+
+ sts._raw = read_txt_config_reg(config, TXTCR_STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n",
+ sts.locality_2_open_sts);
+ break;
+ }
+
+ case off_ERRORCODE:
+ retval = scnprintf(buf, PAGE_SIZE, "0x%08llx\n",
+ read_txt_config_reg(config, TXTCR_ERRORCODE));
+ break;
+
+ case off_ESTS_raw:
+ {
+ txt_ests_t ests;
+
+ ests._raw = read_txt_config_reg(config, TXTCR_ESTS);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%02llx\n", ests._raw);
+ break;
+ }
+
+ case off_ESTS_txt_reset:
+ {
+ txt_ests_t ests;
+
+ ests._raw = read_txt_config_reg(config, TXTCR_ESTS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n", ests.txt_reset_sts);
+ break;
+ }
+
+ case off_E2STS_raw:
+ {
+ txt_e2sts_t e2sts;
+
+ e2sts._raw = read_txt_config_reg(config, TXTCR_E2STS);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%016llx\n", e2sts._raw);
+ break;
+ }
+
+ case off_E2STS_secrets:
+ {
+ txt_e2sts_t e2sts;
+
+ e2sts._raw = read_txt_config_reg(config, TXTCR_E2STS);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n", e2sts.secrets_sts);
+ break;
+ }
+
+ case off_VER_FSBIF:
+ retval = scnprintf(buf, PAGE_SIZE, "0x%016llx\n",
+ read_txt_config_reg(config, TXTCR_VER_FSBIF));
+ break;
+
+ case off_VER_QPIIF:
+ retval = scnprintf(buf, PAGE_SIZE, "0x%016llx\n",
+ read_txt_config_reg(config, TXTCR_VER_QPIIF));
+ break;
+
+ case off_DIDVID_raw:
+ {
+ txt_didvid_t didvid;
+
+ didvid._raw = read_txt_config_reg(config, TXTCR_DIDVID);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%016llx\n", didvid._raw);
+ break;
+ }
+
+ case off_DIDVID_vendor_id:
+ {
+ txt_didvid_t didvid;
+
+ didvid._raw = read_txt_config_reg(config, TXTCR_DIDVID);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%x\n", didvid.vendor_id);
+ break;
+ }
+
+ case off_DIDVID_device_id:
+ {
+ txt_didvid_t didvid;
+
+ didvid._raw = read_txt_config_reg(config, TXTCR_DIDVID);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%x\n", didvid.device_id);
+ break;
+ }
+
+ case off_DIDVID_revision_id:
+ {
+ txt_didvid_t didvid;
+
+ didvid._raw = read_txt_config_reg(config, TXTCR_DIDVID);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%x\n",
+ didvid.revision_id);
+ break;
+ }
+
+ case off_SINIT_BASE:
+ retval = scnprintf(buf, PAGE_SIZE, "0x%08llx\n",
+ read_txt_config_reg(config, TXTCR_SINIT_BASE));
+ break;
+
+ case off_SINIT_SIZE:
+ retval = scnprintf(buf, PAGE_SIZE, "%lluB (0x%llx)\n",
+ read_txt_config_reg(config, TXTCR_SINIT_SIZE),
+ read_txt_config_reg(config, TXTCR_SINIT_SIZE));
+ break;
+
+ case off_HEAP_BASE:
+ retval = scnprintf(buf, PAGE_SIZE, "0x%08llx\n",
+ read_txt_config_reg(config, TXTCR_HEAP_BASE));
+ break;
+
+ case off_HEAP_SIZE:
+ retval = scnprintf(buf, PAGE_SIZE, "%lluB (0x%llx)\n",
+ read_txt_config_reg(config, TXTCR_HEAP_SIZE),
+ read_txt_config_reg(config, TXTCR_HEAP_SIZE));
+ break;
+
+ case off_PUBLIC_KEY:
+ {
+ uint8_t key[256/8];
+ unsigned int i = 0;
+
+ do {
+ *(uint64_t *)&key[i] = read_txt_config_reg(config,
+ TXTCR_PUBLIC_KEY + i);
+ i += sizeof(uint64_t);
+ } while (i < sizeof(key));
+
+ retval = print_hex(buf, key, sizeof(key));
+ break;
+ }
+
+ case off_MLE_JOIN:
+ retval = scnprintf(buf, PAGE_SIZE, "0x%08llx\n",
+ read_txt_config_reg(config, TXTCR_MLE_JOIN));
+ break;
+
+ case off_DPR_raw:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%016llx\n", dpr._raw);
+ break;
+ }
+
+ case off_DPR_lock:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ retval = scnprintf(buf, PAGE_SIZE, "%d\n", dpr.lock);
+ break;
+ }
+
+ case off_DPR_top:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ retval = scnprintf(buf, PAGE_SIZE, "0x%08x\n", dpr.top << 20);
+ break;
+ }
+
+ case off_DPR_size:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ retval = scnprintf(buf, PAGE_SIZE, "%uMB (%uB)\n",
+ dpr.size, dpr.size*1024*1024);
+ break;
+ }
+
+ default:
+ retval = -EINVAL;
+ }
+
+ iounmap(config);
+ return retval;
+}
+
+static ssize_t store_pub_config(const char *buf, u32 offset)
+{
+ void __iomem *config;
+ long value;
+
+ config = ioremap_nocache(TXT_PUB_CONFIG_REGS_BASE,
+ TXT_CONFIG_REGS_SIZE);
+ if (config == NULL)
+ return -ENOMEM;
+
+ if (kstrtol(buf, 0, &value))
+ return -EINVAL;
+
+ switch (offset) {
+ case off_SINIT_BASE:
+ write_txt_config_reg(config, TXTCR_SINIT_BASE, value);
+ break;
+
+ case off_SINIT_SIZE:
+ write_txt_config_reg(config, TXTCR_SINIT_SIZE, value);
+ break;
+
+ case off_HEAP_BASE:
+ write_txt_config_reg(config, TXTCR_HEAP_BASE, value);
+ break;
+
+ case off_HEAP_SIZE:
+ write_txt_config_reg(config, TXTCR_HEAP_SIZE, value);
+ break;
+
+ case off_MLE_JOIN:
+ write_txt_config_reg(config, TXTCR_MLE_JOIN, value);
+ break;
+
+ case off_DPR_raw:
+ write_txt_config_reg(config, TXTCR_DPR, value);
+ break;
+
+ case off_DPR_lock:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ dpr.lock = value;
+
+ write_txt_config_reg(config, TXTCR_DPR, dpr._raw);
+ break;
+ }
+
+ case off_DPR_top:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ dpr.top = value;
+
+ write_txt_config_reg(config, TXTCR_DPR, dpr._raw);
+ break;
+ }
+
+ case off_DPR_size:
+ {
+ txt_dpr_t dpr;
+
+ dpr._raw = read_txt_config_reg(config, TXTCR_DPR);
+ dpr.size = value;
+
+ write_txt_config_reg(config, TXTCR_DPR, dpr._raw);
+ break;
+ }
+
+ default:
+ return -EINVAL;
+ }
+
+ iounmap(config);
+ return 0;
+}
+
+static ssize_t store_priv_config(const char *buf, u32 offset)
+{
+ void __iomem *config;
+ long value;
+ int retval = 0;
+
+ config = ioremap_nocache(TXT_PRIV_CONFIG_REGS_BASE,
+ TXT_CONFIG_REGS_SIZE);
+ if (config == NULL)
+ return -ENOMEM;
+
+ if (kstrtol(buf, 0, &value))
+ return -EINVAL;
+
+ if (offset != off_ERRORCODE && offset != off_E2STS_secrets) {
+ if (value != 0 && value != 1) {
+ retval = -EINVAL;
+ goto out;
+ }
+ }
+
+ switch (offset) {
+ case off_ERRORCODE:
+ write_txt_config_reg(config, TXTCR_ERRORCODE, value);
+ break;
+
+ case off_E2STS_secrets:
+ write_txt_config_reg(config, TXTCR_E2STS, value);
+ break;
+
+ case off_CMD_RESET:
+ write_txt_config_reg(config, TXTCR_CMD_RESET, value);
+ break;
+
+ case off_CMD_CLOSE_PRIVATE:
+ write_txt_config_reg(config, TXTCR_CMD_CLOSE_PRIVATE, value);
+ break;
+
+ case off_CMD_SECRETS:
+ write_txt_config_reg(config, TXTCR_CMD_SECRETS, value);
+ break;
+
+ case off_CMD_NO_SECRETS:
+ write_txt_config_reg(config, TXTCR_CMD_NO_SECRETS, value);
+ break;
+
+ case off_CMD_OPEN_LOCALITY1:
+ write_txt_config_reg(config, TXTCR_CMD_OPEN_LOCALITY1, value);
+ break;
+
+ case off_CMD_OPEN_LOCALITY2:
+ write_txt_config_reg(config, TXTCR_CMD_OPEN_LOCALITY2, value);
+ break;
+
+ case off_CMD_CLOSE_LOCALITY1:
+ write_txt_config_reg(config, TXTCR_CMD_CLOSE_LOCALITY1,
+ value);
+ break;
+
+ case off_CMD_CLOSE_LOCALITY2:
+ write_txt_config_reg(config, TXTCR_CMD_CLOSE_LOCALITY2,
+ value);
+ break;
+
+ case off_CMD_UNLOCK_MEM_CONFIG:
+ write_txt_config_reg(config, TXTCR_CMD_UNLOCK_MEM_CONFIG,
+ value);
+ break;
+
+ default:
+ retval = -EINVAL;
+ }
+
+out:
+ iounmap(config);
+ return retval;
+}
+
+static ssize_t txt_show_STS_raw(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_raw);
+}
+static DEVICE_ATTR(STS_raw, S_IRUGO, txt_show_STS_raw, NULL);
+
+static ssize_t txt_show_STS_senter_done(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_senter_done);
+}
+static DEVICE_ATTR(STS_senter_done, S_IRUGO, txt_show_STS_senter_done, NULL);
+
+static ssize_t txt_show_STS_sexit_done(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_sexit_done);
+}
+static DEVICE_ATTR(STS_sexit_done, S_IRUGO, txt_show_STS_sexit_done, NULL);
+
+static ssize_t txt_show_STS_mem_config_lock(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_mem_config_lock);
+}
+static DEVICE_ATTR(STS_mem_config_lock, S_IRUGO,
+ txt_show_STS_mem_config_lock, NULL);
+
+static ssize_t txt_show_STS_private_open(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_private_open);
+}
+static DEVICE_ATTR(STS_private_open, S_IRUGO,
+ txt_show_STS_private_open, NULL);
+
+static ssize_t txt_show_STS_locality_1_open(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_locality_1_open);
+}
+static DEVICE_ATTR(STS_locality_1_open, S_IRUGO,
+ txt_show_STS_locality_1_open, NULL);
+
+static ssize_t txt_show_STS_locality_2_open(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_STS_locality_2_open);
+}
+static DEVICE_ATTR(STS_locality_2_open, S_IRUGO,
+ txt_show_STS_locality_2_open, NULL);
+
+static ssize_t txt_show_ERRORCODE(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_config(buf, off_ERRORCODE);
+}
+
+static ssize_t txt_store_ERRORCODE(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_ERRORCODE);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(ERRORCODE, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_ERRORCODE, txt_store_ERRORCODE);
+
+static ssize_t txt_show_ESTS_raw(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_config(buf, off_ESTS_raw);
+}
+static DEVICE_ATTR(ESTS_raw, S_IRUGO, txt_show_ESTS_raw, NULL);
+
+static ssize_t txt_show_ESTS_txt_reset(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_ESTS_txt_reset);
+}
+static DEVICE_ATTR(ESTS_txt_reset, S_IRUGO, txt_show_ESTS_txt_reset, NULL);
+
+static ssize_t txt_show_E2STS_raw(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_config(buf, off_E2STS_raw);
+}
+static DEVICE_ATTR(E2STS_raw, S_IRUGO, txt_show_E2STS_raw, NULL);
+
+static ssize_t txt_show_E2STS_secrets(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_E2STS_secrets);
+}
+
+static ssize_t txt_store_E2STS_secrets(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_E2STS_secrets);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(E2STS_secrets, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_E2STS_secrets, txt_store_E2STS_secrets);
+
+static ssize_t txt_show_VER_FSBIF(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_config(buf, off_VER_FSBIF);
+}
+static DEVICE_ATTR(VER_FSBIF, S_IRUGO, txt_show_VER_FSBIF, NULL);
+
+static ssize_t txt_show_VER_QPIIF(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_VER_QPIIF);
+}
+static DEVICE_ATTR(VER_QPIIF, S_IRUGO, txt_show_VER_QPIIF, NULL);
+
+static ssize_t txt_show_DIDVID_raw(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return show_config(buf, off_DIDVID_raw);
+}
+static DEVICE_ATTR(DIDVID_raw, S_IRUGO, txt_show_DIDVID_raw, NULL);
+
+static ssize_t txt_show_DIDVID_vendor_id(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DIDVID_vendor_id);
+}
+static DEVICE_ATTR(DIDVID_vendor_id, S_IRUGO,
+ txt_show_DIDVID_vendor_id, NULL);
+
+static ssize_t txt_show_DIDVID_device_id(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DIDVID_device_id);
+}
+static DEVICE_ATTR(DIDVID_device_id, S_IRUGO,
+ txt_show_DIDVID_device_id, NULL);
+
+static ssize_t txt_show_DIDVID_revision_id(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DIDVID_revision_id);
+}
+static DEVICE_ATTR(DIDVID_revision_id, S_IRUGO,
+ txt_show_DIDVID_revision_id, NULL);
+
+static ssize_t txt_show_SINIT_BASE(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_SINIT_BASE);
+}
+
+static ssize_t txt_store_SINIT_BASE(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_SINIT_BASE);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(SINIT_BASE, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_SINIT_BASE, txt_store_SINIT_BASE);
+
+static ssize_t txt_show_SINIT_SIZE(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_SINIT_SIZE);
+}
+
+static ssize_t txt_store_SINIT_SIZE(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_SINIT_SIZE);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(SINIT_SIZE, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_SINIT_SIZE, txt_store_SINIT_SIZE);
+
+static ssize_t txt_show_HEAP_BASE(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_HEAP_BASE);
+}
+
+static ssize_t txt_store_HEAP_BASE(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_HEAP_BASE);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(HEAP_BASE, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_HEAP_BASE, txt_store_HEAP_BASE);
+
+static ssize_t txt_show_HEAP_SIZE(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_HEAP_SIZE);
+}
+
+static ssize_t txt_store_HEAP_SIZE(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_HEAP_SIZE);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(HEAP_SIZE, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_HEAP_SIZE, txt_store_HEAP_SIZE);
+
+static ssize_t txt_show_PUBLIC_KEY(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_PUBLIC_KEY);
+}
+static DEVICE_ATTR(PUBLIC_KEY, S_IRUGO, txt_show_PUBLIC_KEY, NULL);
+
+static ssize_t txt_show_MLE_JOIN(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_MLE_JOIN);
+}
+
+static ssize_t txt_store_MLE_JOIN(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_MLE_JOIN);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(MLE_JOIN, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_MLE_JOIN, txt_store_MLE_JOIN);
+
+static ssize_t txt_show_DPR_raw(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DPR_raw);
+}
+
+static ssize_t txt_store_DPR_raw(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_DPR_raw);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(DPR_raw, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_DPR_raw, txt_store_DPR_raw);
+
+static ssize_t txt_show_DPR_lock(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DPR_lock);
+}
+
+static ssize_t txt_store_DPR_lock(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_DPR_lock);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(DPR_lock, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_DPR_lock, txt_store_DPR_lock);
+
+static ssize_t txt_show_DPR_top(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DPR_top);
+}
+
+static ssize_t txt_store_DPR_top(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_DPR_top);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(DPR_top, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_DPR_top, txt_store_DPR_top);
+
+static ssize_t txt_show_DPR_size(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_config(buf, off_DPR_size);
+}
+
+static ssize_t txt_store_DPR_size(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_pub_config(buf, off_DPR_size);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(DPR_size, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_DPR_size, txt_store_DPR_size);
+
+static ssize_t txt_store_CMD_RESET(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_RESET);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_RESET, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_RESET);
+
+static ssize_t txt_store_CMD_CLOSE_PRIVATE(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_CLOSE_PRIVATE);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_CLOSE_PRIVATE, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_CLOSE_PRIVATE);
+
+static ssize_t txt_store_CMD_SECRETS(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_SECRETS);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_SECRETS, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_SECRETS);
+
+static ssize_t txt_store_CMD_NO_SECRETS(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_NO_SECRETS);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_NO_SECRETS, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_NO_SECRETS);
+
+static ssize_t txt_store_CMD_OPEN_LOCALITY1(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_OPEN_LOCALITY1);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_OPEN_LOCALITY1, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_OPEN_LOCALITY1);
+
+static ssize_t txt_store_CMD_OPEN_LOCALITY2(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_OPEN_LOCALITY2);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_OPEN_LOCALITY2, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_OPEN_LOCALITY2);
+
+static ssize_t txt_store_CMD_CLOSE_LOCALITY1(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_CLOSE_LOCALITY1);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_CLOSE_LOCALITY1, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_CLOSE_LOCALITY1);
+
+static ssize_t txt_store_CMD_CLOSE_LOCALITY2(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_CLOSE_LOCALITY2);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_CLOSE_LOCALITY2, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_CLOSE_LOCALITY2);
+
+static ssize_t txt_store_CMD_UNLOCK_MEM_CONFIG(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = store_priv_config(buf, off_CMD_UNLOCK_MEM_CONFIG);
+ if (!ret)
+ return count;
+
+ return ret;
+}
+static DEVICE_ATTR(CMD_UNLOCK_MEM_CONFIG, S_IWUSR | S_IWGRP,
+ NULL, txt_store_CMD_UNLOCK_MEM_CONFIG);
+
+static struct attribute *config_attrs[] = {
+ &dev_attr_STS_raw.attr,
+ &dev_attr_STS_senter_done.attr,
+ &dev_attr_STS_sexit_done.attr,
+ &dev_attr_STS_mem_config_lock.attr,
+ &dev_attr_STS_private_open.attr,
+ &dev_attr_STS_locality_1_open.attr,
+ &dev_attr_STS_locality_2_open.attr,
+ &dev_attr_ERRORCODE.attr,
+ &dev_attr_ESTS_raw.attr,
+ &dev_attr_ESTS_txt_reset.attr,
+ &dev_attr_E2STS_raw.attr,
+ &dev_attr_E2STS_secrets.attr,
+ &dev_attr_VER_FSBIF.attr,
+ &dev_attr_VER_QPIIF.attr,
+ &dev_attr_DIDVID_raw.attr,
+ &dev_attr_DIDVID_vendor_id.attr,
+ &dev_attr_DIDVID_device_id.attr,
+ &dev_attr_DIDVID_revision_id.attr,
+ &dev_attr_SINIT_BASE.attr,
+ &dev_attr_SINIT_SIZE.attr,
+ &dev_attr_HEAP_BASE.attr,
+ &dev_attr_HEAP_SIZE.attr,
+ &dev_attr_PUBLIC_KEY.attr,
+ &dev_attr_MLE_JOIN.attr,
+ &dev_attr_DPR_raw.attr,
+ &dev_attr_DPR_lock.attr,
+ &dev_attr_DPR_top.attr,
+ &dev_attr_DPR_size.attr,
+ &dev_attr_CMD_RESET.attr,
+ &dev_attr_CMD_CLOSE_PRIVATE.attr,
+ &dev_attr_CMD_SECRETS.attr,
+ &dev_attr_CMD_NO_SECRETS.attr,
+ &dev_attr_CMD_OPEN_LOCALITY1.attr,
+ &dev_attr_CMD_OPEN_LOCALITY2.attr,
+ &dev_attr_CMD_CLOSE_LOCALITY1.attr,
+ &dev_attr_CMD_CLOSE_LOCALITY2.attr,
+ &dev_attr_CMD_UNLOCK_MEM_CONFIG.attr,
+ NULL,
+};
+
+static struct attribute_group config_attr_grp = {
+ .name = "config",
+ .attrs = config_attrs
+};
+
+int sysfs_create_config(struct kobject *parent)
+{
+ return sysfs_create_group(parent, &config_attr_grp);
+}
+
diff --git a/drivers/platform/x86/intel_txt/txt-config.h b/drivers/platform/x86/intel_txt/txt-config.h
new file mode 100644
index 0000000..d88cc83
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-config.h
@@ -0,0 +1,138 @@
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define TXT_PUB_CONFIG_REGS_BASE 0xfed30000
+#define TXT_PRIV_CONFIG_REGS_BASE 0xfed20000
+#define TXT_CONFIG_REGS_SIZE 0x10000
+
+#define TXTCR_STS 0x0000
+#define TXTCR_ESTS 0x0008
+#define TXTCR_ERRORCODE 0x0030
+#define TXTCR_CMD_RESET 0x0038
+#define TXTCR_CMD_CLOSE_PRIVATE 0x0048
+#define TXTCR_VER_FSBIF 0x0100
+#define TXTCR_DIDVID 0x0110
+#define TXTCR_VER_QPIIF 0x0200
+#define TXTCR_CMD_UNLOCK_MEM_CONFIG 0x0218
+#define TXTCR_SINIT_BASE 0x0270
+#define TXTCR_SINIT_SIZE 0x0278
+#define TXTCR_MLE_JOIN 0x0290
+#define TXTCR_HEAP_BASE 0x0300
+#define TXTCR_HEAP_SIZE 0x0308
+#define TXTCR_MSEG_BASE 0x0310
+#define TXTCR_MSEG_SIZE 0x0318
+#define TXTCR_DPR 0x0330
+#define TXTCR_CMD_OPEN_LOCALITY1 0x0380
+#define TXTCR_CMD_CLOSE_LOCALITY1 0x0388
+#define TXTCR_CMD_OPEN_LOCALITY2 0x0390
+#define TXTCR_CMD_CLOSE_LOCALITY2 0x0398
+#define TXTCR_PUBLIC_KEY 0x0400
+#define TXTCR_CMD_SECRETS 0x08e0
+#define TXTCR_CMD_NO_SECRETS 0x08e8
+#define TXTCR_E2STS 0x08f0
+
+#define off_STS_raw 1
+#define off_STS_senter_done 2
+#define off_STS_sexit_done 3
+#define off_STS_mem_config_lock 4
+#define off_STS_private_open 5
+#define off_STS_locality_1_open 6
+#define off_STS_locality_2_open 7
+#define off_ERRORCODE 8
+#define off_ESTS_raw 9
+#define off_ESTS_txt_reset 10
+#define off_E2STS_raw 11
+#define off_E2STS_secrets 12
+#define off_VER_FSBIF 13
+#define off_VER_QPIIF 14
+#define off_DIDVID_raw 15
+#define off_DIDVID_vendor_id 16
+#define off_DIDVID_device_id 17
+#define off_DIDVID_revision_id 18
+#define off_SINIT_BASE 19
+#define off_SINIT_SIZE 20
+#define off_HEAP_BASE 21
+#define off_HEAP_SIZE 22
+#define off_PUBLIC_KEY 23
+#define off_MLE_JOIN 24
+#define off_DPR_raw 25
+#define off_DPR_lock 26
+#define off_DPR_top 27
+#define off_DPR_size 28
+#define off_CMD_RESET 29
+#define off_CMD_CLOSE_PRIVATE 30
+#define off_CMD_SECRETS 31
+#define off_CMD_NO_SECRETS 32
+#define off_CMD_OPEN_LOCALITY1 33
+#define off_CMD_OPEN_LOCALITY2 34
+#define off_CMD_CLOSE_LOCALITY1 35
+#define off_CMD_CLOSE_LOCALITY2 36
+#define off_CMD_UNLOCK_MEM_CONFIG 37
+
+typedef union txt_ests {
+ uint64_t _raw;
+ struct {
+ uint64_t txt_reset_sts:1;
+ };
+} txt_ests_t;
+
+typedef union txt_e2sts {
+ uint64_t _raw;
+ struct {
+ uint64_t reserved:1;
+ uint64_t secrets_sts:1;
+ };
+} txt_e2sts_t;
+
+typedef union txt_sts {
+ uint64_t _raw;
+ struct {
+ uint64_t senter_done_sts:1;
+ uint64_t sexit_done_sts:1;
+ uint64_t reserved1:4;
+ uint64_t mem_config_lock_sts:1;
+ uint64_t private_open_sts:1;
+ uint64_t reserved2:7;
+ uint64_t locality_1_open_sts:1;
+ uint64_t locality_2_open_sts:1;
+ };
+} txt_sts_t;
+
+typedef union txt_divid {
+ uint64_t _raw;
+ struct {
+ uint16_t vendor_id;
+ uint16_t device_id;
+ uint16_t revision_id;
+ uint16_t reserved;
+ };
+} txt_didvid_t;
+
+typedef union txt_dpr {
+ uint64_t _raw;
+ struct {
+ uint64_t lock:1;
+ uint64_t reserved1:3;
+ uint64_t size:8;
+ uint64_t reserved2:8;
+ uint64_t top:12;
+ uint64_t reserved3:32;
+ };
+} txt_dpr_t;
+
+static inline uint64_t
+read_txt_config_reg(void *config_regs_base, uint32_t reg)
+{
+ return readq(config_regs_base + reg);
+}
+
+static inline void
+write_txt_config_reg(void *config_regs_base, uint32_t reg, uint64_t val)
+{
+ writeq(val, config_regs_base + reg);
+}
+
+extern int sysfs_create_config(struct kobject *parent);
+
+#endif /* __CONFIG_H__ */
+
diff --git a/drivers/platform/x86/intel_txt/txt-sysfs.c b/drivers/platform/x86/intel_txt/txt-sysfs.c
index 3ea7307..4837935 100644
--- a/drivers/platform/x86/intel_txt/txt-sysfs.c
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -36,11 +36,15 @@
#include <linux/sysfs.h>
#include <linux/tboot.h>

+#include "txt-config.h"
+
#define DEV_NAME "intel_txt"
static struct platform_device *txt_pdev;

static int __init txt_sysfs_init(void)
{
+ int retval;
+
if (!tboot_enabled())
return -ENODEV;

@@ -48,7 +52,15 @@ static int __init txt_sysfs_init(void)
if (IS_ERR(txt_pdev))
return PTR_ERR(txt_pdev);

+ retval = sysfs_create_config(&txt_pdev->dev.kobj);
+ if (retval)
+ goto err;
+
return 0;
+
+err:
+ platform_device_unregister(txt_pdev);
+ return retval;
}

static void __exit txt_sysfs_exit(void)
--
1.7.9.5

2013-05-13 09:35:14

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH v2 3/3] driver: provide sysfs interfaces to access SMX parameter

These interfaces are located in /sys/devices/platform/intel_txt/parameter/,
showing specific parameter information for SMX features supported by
the processor.

Safer Mode Extensions (SMX) provide a processor's programming
interface in an Intel TXT platform for system software to establish
a measured environment within the platform to support trust decisions
by end users.

Signed-off-by: Qiaowei Ren <[email protected]>
Signed-off-by: Xiaoyan Zhang <[email protected]>
Signed-off-by: Gang Wei <[email protected]>
---
Documentation/ABI/testing/sysfs-platform-intel-txt | 73 ++++++
drivers/platform/x86/intel_txt/Makefile | 2 +-
drivers/platform/x86/intel_txt/txt-parameter.c | 254 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-parameter.h | 39 +++
drivers/platform/x86/intel_txt/txt-sysfs.c | 5 +
5 files changed, 372 insertions(+), 1 deletion(-)
create mode 100644 drivers/platform/x86/intel_txt/txt-parameter.c
create mode 100644 drivers/platform/x86/intel_txt/txt-parameter.h

diff --git a/Documentation/ABI/testing/sysfs-platform-intel-txt b/Documentation/ABI/testing/sysfs-platform-intel-txt
index fa20a9f..b445f5d 100644
--- a/Documentation/ABI/testing/sysfs-platform-intel-txt
+++ b/Documentation/ABI/testing/sysfs-platform-intel-txt
@@ -307,3 +307,76 @@ Contact: "Qiaowei Ren" <[email protected]>
Description: 0 = Chipset acknowledges that no secrets are in memory.
1 = Chipset believes that secrets are in memory and will
provide reset protection.
+
+What: /sys/devices/platform/intel_txt/parameter/
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The parameter/ directory exposes specific parameter
+ information for SMX features supported by the processor.
+
+ Safer Mode Extensions (SMX) provide a processor's
+ programming interface in an Intel TXT platform for
+ system software to establish a measured environment
+ within the platform to support trust decisions by
+ end users.
+
+What: /sys/devices/platform/intel_txt/parameter/acm_max_size
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "acm_max_size" property will show max size of
+ authenticated code execution area.
+
+What: /sys/devices/platform/intel_txt/parameter/acm_mem_types
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "acm_max_types" property will show supportable memory
+ types for memory mapped outside of the authenticated code
+ execution area.
+
+What: /sys/devices/platform/intel_txt/parameter/senter_controls
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "senter_controls" property will show selective SENTER
+ functionality control.
+
+What: /sys/devices/platform/intel_txt/parameter/preserve_mce
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "preserve_mce" property produces a '1' if machine
+ check status registers can be preserved through ENTERACCS
+ and SENTER.
+
+What: /sys/devices/platform/intel_txt/parameter/proc_based_scrtm
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "proc_based_scrtm" property produces a '1' if this
+ processor implements a processorrooted S-CRTM capability
+ and '0' if not (S-CRTM is rooted in BIOS).
+
+What: /sys/devices/platform/intel_txt/parameter/n_versions
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "n_versions" property will show AC module version
+ numbers supported.
+
+What: /sys/devices/platform/intel_txt/parameter/acm_version
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "acm_version" property will output supported AC
+ module version, including version comparison mask and
+ version index.
+
+What: /sys/devices/platform/intel_txt/parameter/acm_version_index
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "acm_version_index" property allows you to set the
+ version index for output.
diff --git a/drivers/platform/x86/intel_txt/Makefile b/drivers/platform/x86/intel_txt/Makefile
index 8d5258e..8370582 100644
--- a/drivers/platform/x86/intel_txt/Makefile
+++ b/drivers/platform/x86/intel_txt/Makefile
@@ -2,4 +2,4 @@
# Makefile for the intel TXT drivers.
#
obj-$(CONFIG_INTEL_TXT_DRIVER) += intel_txt.o
-intel_txt-y := txt-sysfs.o txt-config.o
+intel_txt-y := txt-sysfs.o txt-config.o txt-parameter.o
diff --git a/drivers/platform/x86/intel_txt/txt-parameter.c b/drivers/platform/x86/intel_txt/txt-parameter.c
new file mode 100644
index 0000000..a0073bf
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-parameter.c
@@ -0,0 +1,254 @@
+/*
+ * txt-parameter.c
+ *
+ * specific parameter information for SMX features supported by the processor.
+ *
+ * Safer Mode Extensions (SMX) provide a processor's programming
+ * interface in an Intel TXT platform for system software to establish
+ * a measured environment within the platform to support trust decisions
+ * by end users.
+ *
+ * - parameter/
+ * n_versions -r--r--r--;
+ * acm_max_size -r--r--r--;
+ * acm_mem_types -r--r--r--;
+ * senter_controls -r--r--r--;
+ * proc_based_scrtm -r--r--r--;
+ * preserve_mce -r--r--r--;
+ * acm_version_index -rw-rw-r--; desginate which acm_version will be output
+ * acm_version -r--r--r--;
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+
+#include "txt-parameter.h"
+
+static u32 acm_version_index;
+
+static void __getsec_parameters(uint32_t index, int *param_type,
+ uint32_t *peax, uint32_t *pebx,
+ uint32_t *pecx)
+{
+ uint32_t eax, ebx, ecx;
+
+ __asm__ __volatile__ ("getsec"
+ : "=a"(eax), "=b"(ebx), "=c"(ecx)
+ : "a"(IA32_GETSEC_PARAMETERS), "b"(index));
+
+ *param_type = eax & 0x1f;
+ *peax = eax;
+ *pebx = ebx;
+ *pecx = ecx;
+}
+
+static bool get_parameters(struct getsec_parameters *params)
+{
+ uint32_t index, eax, ebx, ecx;
+ int param_type;
+
+ memset(params, 0, sizeof(struct getsec_parameters));
+ params->acm_max_size = DEF_ACM_MAX_SIZE;
+ params->acm_mem_types = DEF_ACM_MEM_TYPES;
+ params->senter_controls = DEF_SENTER_CTRLS;
+ params->proc_based_scrtm = false;
+ params->preserve_mce = false;
+
+ index = 0;
+ do {
+ __getsec_parameters(index++, &param_type, &eax, &ebx, &ecx);
+
+ switch (param_type) {
+ case 1:
+ if (params->n_versions == MAX_SUPPORTED_ACM_VERSIONS)
+ continue;
+ params->acm_versions[params->n_versions].mask = ebx;
+ params->acm_versions[params->n_versions].version = ecx;
+ params->n_versions++;
+ break;
+
+ case 2:
+ params->acm_max_size = eax & 0xffffffe0;
+ break;
+
+ case 3:
+ params->acm_mem_types = eax & 0xffffffe0;
+ break;
+
+ case 4:
+ params->senter_controls = (eax & 0x00007fff) >> 8;
+ break;
+
+ case 5:
+ params->proc_based_scrtm =
+ (eax & 0x00000020) ? true : false;
+ params->preserve_mce =
+ (eax & 0x00000040) ? true : false;
+ break;
+
+ default:
+ param_type = 0;
+ break;
+ }
+ } while (param_type != 0);
+
+ if (params->n_versions == 0) {
+ params->acm_versions[0].mask = DEF_ACM_VER_MASK;
+ params->acm_versions[0].version = DEF_ACM_VER_SUPPORTED;
+ params->n_versions = 1;
+ }
+
+ return true;
+}
+
+static ssize_t show_param(char *buf, u32 index)
+{
+ struct getsec_parameters params;
+
+ if (!get_parameters(&params))
+ return -EPERM;
+
+ switch (index) {
+ case off_n_versions:
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ params.n_versions);
+
+ case off_acm_max_size:
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ params.acm_max_size);
+
+ case off_acm_mem_types:
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ params.acm_mem_types);
+
+ case off_senter_controls:
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ params.senter_controls);
+
+ case off_proc_based_scrtm:
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ params.proc_based_scrtm);
+
+ case off_preserve_mce:
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ params.preserve_mce);
+
+ case off_acm_version:
+ return scnprintf(buf, PAGE_SIZE,
+ "mask: %u\nversion: %u\n",
+ params.acm_versions[acm_version_index].mask,
+ params.acm_versions[acm_version_index].version);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+ssize_t txt_show_param_nversions(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_n_versions);
+}
+static DEVICE_ATTR(n_versions, S_IRUGO, txt_show_param_nversions, NULL);
+
+ssize_t txt_show_param_acmmaxsize(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_acm_max_size);
+}
+static DEVICE_ATTR(acm_max_size, S_IRUGO, txt_show_param_acmmaxsize, NULL);
+
+ssize_t txt_show_param_acmmemtypes(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_acm_mem_types);
+}
+static DEVICE_ATTR(acm_mem_types, S_IRUGO, txt_show_param_acmmemtypes, NULL);
+
+ssize_t txt_show_param_senter(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_senter_controls);
+}
+static DEVICE_ATTR(senter_controls, S_IRUGO, txt_show_param_senter, NULL);
+
+ssize_t txt_show_param_proc(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_proc_based_scrtm);
+}
+static DEVICE_ATTR(proc_based_scrtm, S_IRUGO, txt_show_param_proc, NULL);
+
+ssize_t txt_show_param_preserve(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_preserve_mce);
+}
+static DEVICE_ATTR(preserve_mce, S_IRUGO, txt_show_param_preserve, NULL);
+
+ssize_t txt_show_param_acmvindex(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", acm_version_index);
+}
+
+ssize_t txt_store_param_acmvindex(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 index;
+ struct getsec_parameters params;
+
+ if (sscanf(buf, "%d", &index) != 1)
+ return -EINVAL;
+
+ if (!get_parameters(&params))
+ return -EPERM;
+
+ if (index >= params.n_versions)
+ return -EINVAL;
+
+ acm_version_index = index;
+
+ return count;
+}
+static DEVICE_ATTR(acm_version_index, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_param_acmvindex, txt_store_param_acmvindex);
+
+ssize_t txt_show_param_acmversion(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return show_param(buf, off_acm_version);
+}
+static DEVICE_ATTR(acm_version, S_IRUGO, txt_show_param_acmversion, NULL);
+
+static struct attribute *param_attrs[] = {
+ &dev_attr_n_versions.attr,
+ &dev_attr_acm_max_size.attr,
+ &dev_attr_acm_mem_types.attr,
+ &dev_attr_senter_controls.attr,
+ &dev_attr_proc_based_scrtm.attr,
+ &dev_attr_preserve_mce.attr,
+ &dev_attr_acm_version_index.attr,
+ &dev_attr_acm_version.attr,
+ NULL,
+};
+
+static struct attribute_group param_attr_grp = {
+ .name = "parameter",
+ .attrs = param_attrs
+};
+
+int sysfs_create_parameter(struct kobject *parent)
+{
+ return sysfs_create_group(parent, &param_attr_grp);
+}
+
diff --git a/drivers/platform/x86/intel_txt/txt-parameter.h b/drivers/platform/x86/intel_txt/txt-parameter.h
new file mode 100644
index 0000000..55b232b
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-parameter.h
@@ -0,0 +1,39 @@
+#ifndef __PARAMETER_H__
+#define __PARAMETER_H__
+
+#define CR4_SMXE 0x00004000
+#define MAX_SUPPORTED_ACM_VERSIONS 16
+
+#define DEF_ACM_MAX_SIZE 0x8000
+#define DEF_ACM_VER_MASK 0xffffffff
+#define DEF_ACM_VER_SUPPORTED 0x00
+#define DEF_ACM_MEM_TYPES 0x0100
+#define DEF_SENTER_CTRLS 0x00
+
+#define IA32_GETSEC_PARAMETERS 6
+
+#define off_n_versions 1
+#define off_acm_max_size 2
+#define off_acm_mem_types 3
+#define off_senter_controls 4
+#define off_proc_based_scrtm 5
+#define off_preserve_mce 6
+#define off_acm_version 7
+
+typedef struct getsec_parameters {
+ struct {
+ uint32_t mask;
+ uint32_t version;
+ } acm_versions[MAX_SUPPORTED_ACM_VERSIONS];
+ int n_versions;
+ uint32_t acm_max_size;
+ uint32_t acm_mem_types;
+ uint32_t senter_controls;
+ bool proc_based_scrtm;
+ bool preserve_mce;
+} getsec_parameters_t;
+
+extern int sysfs_create_parameter(struct kobject *parent);
+
+#endif /* __PARAMETER_H__ */
+
diff --git a/drivers/platform/x86/intel_txt/txt-sysfs.c b/drivers/platform/x86/intel_txt/txt-sysfs.c
index 4837935..9884618 100644
--- a/drivers/platform/x86/intel_txt/txt-sysfs.c
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -37,6 +37,7 @@
#include <linux/tboot.h>

#include "txt-config.h"
+#include "txt-parameter.h"

#define DEV_NAME "intel_txt"
static struct platform_device *txt_pdev;
@@ -56,6 +57,10 @@ static int __init txt_sysfs_init(void)
if (retval)
goto err;

+ retval = sysfs_create_parameter(&txt_pdev->dev.kobj);
+ if (retval)
+ goto err;
+
return 0;

err:
--
1.7.9.5

2013-05-13 09:35:43

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH v2 1/3] driver: add TXT driver in kernel

TXT driver can be used to access below resources:
- TXT config space
- SMX parameter

Intel TXT (Trusted Execution Technology) will provide higher
assurance of system configuration and initial state as well as
data reset protection. It also helps solve real end user concerns
about having confidence that their hardware is running the VMM
or kernel that it was configured with, especially since they may
be responsible for providing such assurances to VMs and services
running on it.

See Documentation/intel_txt.txt for more information about
Intel TXT.

Intel TXT configuration registers are a subset of chipset registers.
These chipset registers that interact with SMX are accessed from two
regions of memory, which represent the public and private configuration
spaces, by system software using memory read/write protocols.

Safer Mode Extensions (SMX) provide a processor's programming
interface in an Intel TXT platform for system software to establish
a measured environment within the platform to support trust decisions
by end users.

Signed-off-by: Qiaowei Ren <[email protected]>
Signed-off-by: Xiaoyan Zhang <[email protected]>
Signed-off-by: Gang Wei <[email protected]>
---
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/intel_txt/Kconfig | 27 ++++++++++++
drivers/platform/x86/intel_txt/Makefile | 5 +++
drivers/platform/x86/intel_txt/txt-sysfs.c | 62 ++++++++++++++++++++++++++++
5 files changed, 97 insertions(+)
create mode 100644 drivers/platform/x86/intel_txt/Kconfig
create mode 100644 drivers/platform/x86/intel_txt/Makefile
create mode 100644 drivers/platform/x86/intel_txt/txt-sysfs.c

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3338437..2c50e7d 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -693,6 +693,8 @@ config INTEL_IPS
functionality. If in doubt, say Y here; it will only load on
supported platforms.

+source "drivers/platform/x86/intel_txt/Kconfig"
+
config IBM_RTL
tristate "Device driver to enable PRTL support"
depends on X86 && PCI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ace2b38..669b464 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
obj-$(CONFIG_INTEL_IPS) += intel_ips.o
+obj-$(CONFIG_INTEL_TXT_DRIVER) += intel_txt/
obj-$(CONFIG_GPIO_INTEL_PMIC) += intel_pmic_gpio.o
obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o
obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o
diff --git a/drivers/platform/x86/intel_txt/Kconfig b/drivers/platform/x86/intel_txt/Kconfig
new file mode 100644
index 0000000..dd81b21
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/Kconfig
@@ -0,0 +1,27 @@
+#
+# intel TXT driver configuration
+#
+
+config INTEL_TXT_DRIVER
+ tristate "INTEL TXT sysfs driver"
+ default m
+ depends on INTEL_TXT
+ select SECURITYFS
+ ---help---
+ TXT Driver can be used to access below resources:
+ - TXT config space
+ - SMX parameter
+
+ Intel TXT configuration registers are a subset of chipset
+ registers. These chipset registers that interact with SMX
+ are accessed from two regions of memory, which represent
+ the public and private configuration spaces, by system
+ software using memory read/write protocols.
+
+ Safer Mode Extensions (SMX) provide a processor's programming
+ interface in an Intel TXT platform for system software to
+ establish a measured environment within the platform to support
+ trust decisions by end users.
+
+ To compile this driver as a module, choose M here; the module
+ will be called intel_txt.
diff --git a/drivers/platform/x86/intel_txt/Makefile b/drivers/platform/x86/intel_txt/Makefile
new file mode 100644
index 0000000..a130308
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the intel TXT drivers.
+#
+obj-$(CONFIG_INTEL_TXT_DRIVER) += intel_txt.o
+intel_txt-y := txt-sysfs.o
diff --git a/drivers/platform/x86/intel_txt/txt-sysfs.c b/drivers/platform/x86/intel_txt/txt-sysfs.c
new file mode 100644
index 0000000..3ea7307
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -0,0 +1,62 @@
+/*
+ * txt-sysfs.c
+ *
+ * This module can be used to access below resources
+ * - TXT config space
+ * - SMX parameter
+ *
+ * Intel TXT (Trusted Execution Technology) will provide higher
+ * assurance of system configuration and initial state as well as
+ * data reset protection. It also helps solve real end user concerns
+ * about having confidence that their hardware is running the VMM
+ * or kernel that it was configured with, especially since they may
+ * be responsible for providing such assurances to VMs and services
+ * running on it.
+ *
+ * See Documentation/intel_txt.txt for more information about
+ * Intel TXT.
+ *
+ * Intel TXT configuration registers are a subset of chipset registers.
+ * These chipset registers that interact with SMX are accessed from two
+ * regions of memory, which represent the public and private configuration
+ * spaces, by system software using memory read/write protocols.
+ *
+ * Safer Mode Extensions (SMX) provide a processor's programming
+ * interface in an Intel TXT platform for system software to establish
+ * a measured environment within the platform to support trust decisions
+ * by end users.
+ *
+ * Data can be found below
+ * /sys/devices/platform/intel_txt/...
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+#include <linux/tboot.h>
+
+#define DEV_NAME "intel_txt"
+static struct platform_device *txt_pdev;
+
+static int __init txt_sysfs_init(void)
+{
+ if (!tboot_enabled())
+ return -ENODEV;
+
+ txt_pdev = platform_device_register_simple(DEV_NAME, -1, NULL, 0);
+ if (IS_ERR(txt_pdev))
+ return PTR_ERR(txt_pdev);
+
+ return 0;
+}
+
+static void __exit txt_sysfs_exit(void)
+{
+ platform_device_unregister(txt_pdev);
+}
+
+module_init(txt_sysfs_init);
+module_exit(txt_sysfs_exit);
+
+MODULE_LICENSE("GPL");
--
1.7.9.5

2013-05-13 17:31:45

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] driver: add TXT driver in kernel

On Tue, 2013-05-14 at 01:24 +0800, Qiaowei Ren wrote:
> static int __init txt_sysfs_init(void)
> +{
> + if (!tboot_enabled())
> + return -ENODEV;

If there's a CPU flag that indicates tboot support, you should add a
modalias for it in order to ensure that the module gets automatically
loaded.

--
Matthew Garrett | [email protected]
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-05-13 17:35:18

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] driver: provide sysfs interfaces to access TXT config space

On Tue, 2013-05-14 at 01:24 +0800, Qiaowei Ren wrote:
> These interfaces are located
> in /sys/devices/platform/intel_txt/config,
> and including totally 37 files, providing access to Intel TXT
> configuration registers.

Do you have any example userspace code using these features?

--
Matthew Garrett | [email protected]
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-05-14 01:47:08

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH v2 2/3] driver: provide sysfs interfaces to access TXT config space

On 2013-05-14, Matthew Garrett wrote:
> On Tue, 2013-05-14 at 01:24 +0800, Qiaowei Ren wrote:
> > These interfaces are located
> > in /sys/devices/platform/intel_txt/config,
> > and including totally 37 files, providing access to Intel TXT
> > configuration registers.
>
> Do you have any example userspace code using these features?

You mean test programs using these sysfs files? Currently I just did some simple demos like the following:

cat config/STS_private_open
echo 1 > CMD_CLOSE_PRIVATE
cat config/STS_private_open

cat config/STS_ locality_1_open
echo 1 > CMD_CLOSE_LOCALITY1
cat config/ STS_ locality_1_open
echo 1 > CMD_OPEN_LOCALITY1
cat config/ STS_ locality_1_open

Thanks,
Qiaowei
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-05-14 01:50:04

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH v2 1/3] driver: add TXT driver in kernel

On 2013-05-14, Matthew Garrett wrote:
> On Tue, 2013-05-14 at 01:24 +0800, Qiaowei Ren wrote:
> > static int __init txt_sysfs_init(void)
> > +{
> > + if (!tboot_enabled())
> > + return -ENODEV;
>
> If there's a CPU flag that indicates tboot support, you should add a modalias for
> it in order to ensure that the module gets automatically loaded.

Ok.

Thanks,
Qiaowei
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m???? ????????I?

2013-05-16 16:03:18

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] driver: provide sysfs interfaces to access TXT config space

On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> These interfaces are located in /sys/devices/platform/intel_txt/config,
> and including totally 37 files, providing access to Intel TXT
> configuration registers.

This looks like very wrong interface... equivalent of /dev/mem.

> +What: /sys/devices/platform/intel_txt/config/STS_raw
> +Date: May 2013
> +KernelVersion: 3.9
> +Contact: "Qiaowei Ren" <[email protected]>
> +Description: TXT.STS is the general status register. This read-only register
> + is used by AC modules and the MLE to get the status of various
> + Intel TXT features.

This is not enough to allow people to understand what this does/should
do, nor does it allow (for example) ARM people to implement something
compatible.

Is there specific reason why "better" interface is impossible?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2013-05-17 08:50:17

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH v2 2/3] driver: provide sysfs interfaces to access TXT config space

On 2013-05-17, Pavel Machek wrote:
> On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
>> +What: /sys/devices/platform/intel_txt/config/STS_raw +Date: May 2013
>> +KernelVersion: 3.9 +Contact: "Qiaowei Ren" <[email protected]>
>> +Description: TXT.STS is the general status register. This read-only
>> register + is used by AC modules and the MLE to get the status of
>> various + Intel TXT features.
>
> This is not enough to allow people to understand what this does/should
> do, nor does it allow (for example) ARM people to implement something compatible.

Currently TXT is only a technology for safer computing provided by Intel. I am absolutely not sure whether similar technology will be provided on ARM or other platform in future. But I guess I don't have to consider those future possible implementation on ARM or other platform. :)

Thanks,
Qiaowei

2013-05-17 18:07:40

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] driver: provide sysfs interfaces to access TXT config space

On Fri 2013-05-17 08:50:11, Ren, Qiaowei wrote:
> On 2013-05-17, Pavel Machek wrote:
> > On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> >> +What: /sys/devices/platform/intel_txt/config/STS_raw +Date: May 2013
> >> +KernelVersion: 3.9 +Contact: "Qiaowei Ren" <[email protected]>
> >> +Description: TXT.STS is the general status register. This read-only
> >> register + is used by AC modules and the MLE to get the status of
> >> various + Intel TXT features.
> >
> > This is not enough to allow people to understand what this does/should
> > do, nor does it allow (for example) ARM people to implement something compatible.
>
> Currently TXT is only a technology for safer computing provided by Intel. I am absolutely not sure whether similar technology will be provided on ARM or other platform in future. But I guess I don't have to consider those future possible implementation on ARM or other platform. :)
>

You still have to properly design the interface and properly document
it, so people can understand and test it, and develop compatible
implementations.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2022-02-17 13:05:40

by Dmitrii Okunev

[permalink] [raw]
Subject: [discuss] Improve and merge a driver proposed in 2013: sysfs interfaces to access TXT config space

Hello!

As far as I see the patch wasn't merged. And I see that this is the
only unsolved thread in the discussion:

On Thu, 2013-05-16 at 18:03 +0200, Pavel Machek wrote:
> On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> > These interfaces are located in
> > /sys/devices/platform/intel_txt/config,
> > and including totally 37 files, providing access to Intel TXT
> > configuration registers.
>
> This looks like very wrong interface... equivalent of /dev/mem.

As an active user of these registers I hope it will be merged, so I
would like to improve this patch (or rewrite it from scratch) to make
that happen. Otherwise one have to do hackery around `/dev/mem`, which
also creates problems with proper access control.

To be able to improve the patch, could somebody clarify why exactly
this is a "very wrong interface"?

> > +What:          /sys/devices/platform/intel_txt/config/STS_raw
> > +Date:          May 2013
> > +KernelVersion: 3.9
> > +Contact:       "Qiaowei Ren" <[email protected]>
> > +Description:   TXT.STS is the general status register. This read-
> > only register
> > +               is used by AC modules and the MLE to get the status
> > of various
> > +               Intel TXT features.
>
> This is not enough to allow people to understand what this
> does/should
> do, nor does it allow (for example) ARM people to implement something
> compatible.
>
> Is there specific reason why "better" interface is impossible?

I would love to reuse Intel's public documentation [1] to provide a
proper description (with bit layout of the value).

[1] https://cdrdv2.intel.com/v1/dl/getContent/315168

> [...], nor does it allow (for example) ARM people to
> implement something compatible.

Do I understand correctly that a proper documentation of the registers
solves the problem?

> Is there specific reason why "better" interface is impossible?

What are specific problems with the current interface?

Best regards,
Dmitrii Okunev.

2022-02-17 13:15:45

by Greg KH

[permalink] [raw]
Subject: Re: [discuss] Improve and merge a driver proposed in 2013: sysfs interfaces to access TXT config space

On Thu, Feb 17, 2022 at 11:47:21AM +0000, Dmitrii Okunev wrote:
> Hello!
>
> As far as I see the patch wasn't merged. And I see that this is the
> only unsolved thread in the discussion:
>
> On Thu, 2013-05-16 at 18:03 +0200, Pavel Machek wrote:
> > On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> > > These interfaces are located in
> > > /sys/devices/platform/intel_txt/config,
> > > and including totally 37 files, providing access to Intel TXT
> > > configuration registers.
> >
> > This looks like very wrong interface... equivalent of /dev/mem.
>
> As an active user of these registers I hope it will be merged, so I
> would like to improve this patch (or rewrite it from scratch) to make
> that happen. Otherwise one have to do hackery around `/dev/mem`, which
> also creates problems with proper access control.
>
> To be able to improve the patch, could somebody clarify why exactly
> this is a "very wrong interface"?
>
> > > +What:??????????/sys/devices/platform/intel_txt/config/STS_raw
> > > +Date:??????????May 2013
> > > +KernelVersion:?3.9
> > > +Contact:???????"Qiaowei Ren" <[email protected]>
> > > +Description:???TXT.STS is the general status register. This read-
> > > only register
> > > +???????????????is used by AC modules and the MLE to get the status
> > > of various
> > > +???????????????Intel TXT features.
> >
> > This is not enough to allow people to understand what this
> > does/should
> > do, nor does it allow (for example) ARM people to implement something
> > compatible.
> >
> > Is there specific reason why "better" interface is impossible?
>
> I would love to reuse Intel's public documentation [1] to provide a
> proper description (with bit layout of the value).
>
> [1] https://cdrdv2.intel.com/v1/dl/getContent/315168
>
> > [...], nor does it allow (for example) ARM people to
> > implement something compatible.
>
> Do I understand correctly that a proper documentation of the registers
> solves the problem?
>
> > Is there specific reason why "better" interface is impossible?
>
> What are specific problems with the current interface?

What do you mean by "current" here? You are referring to an email from
2013, 9 years ago.

If you want to propose the change again, correctly update the patch and
submit it that way.

thanks,

greg k-h

2022-02-17 14:06:03

by Pavel Machek

[permalink] [raw]
Subject: Re: [discuss] Improve and merge a driver proposed in 2013: sysfs interfaces to access TXT config space

On Thu 2022-02-17 13:34:40, [email protected] wrote:
> On Thu, Feb 17, 2022 at 11:47:21AM +0000, Dmitrii Okunev wrote:
> > Hello!
> >
> > As far as I see the patch wasn't merged. And I see that this is the
> > only unsolved thread in the discussion:
> >
> > On Thu, 2013-05-16 at 18:03 +0200, Pavel Machek wrote:
> > > On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> > > > These interfaces are located in
> > > > /sys/devices/platform/intel_txt/config,
> > > > and including totally 37 files, providing access to Intel TXT
> > > > configuration registers.
> > >
> > > This looks like very wrong interface... equivalent of /dev/mem.
> >
> > As an active user of these registers I hope it will be merged, so I
> > would like to improve this patch (or rewrite it from scratch) to make
> > that happen. Otherwise one have to do hackery around `/dev/mem`, which
> > also creates problems with proper access control.
> >
> > To be able to improve the patch, could somebody clarify why exactly
> > this is a "very wrong interface"?
> >
> > > > +What:??????????/sys/devices/platform/intel_txt/config/STS_raw
> > > > +Date:??????????May 2013
> > > > +KernelVersion:?3.9
> > > > +Contact:???????"Qiaowei Ren" <[email protected]>
> > > > +Description:???TXT.STS is the general status register. This read-
> > > > only register
> > > > +???????????????is used by AC modules and the MLE to get the status
> > > > of various
> > > > +???????????????Intel TXT features.
> > >
> > > This is not enough to allow people to understand what this
> > > does/should
> > > do, nor does it allow (for example) ARM people to implement something
> > > compatible.
> > >
> > > Is there specific reason why "better" interface is impossible?
> >
> > I would love to reuse Intel's public documentation [1] to provide a
> > proper description (with bit layout of the value).
> >
> > [1] https://cdrdv2.intel.com/v1/dl/getContent/315168
> >
> > > [...], nor does it allow (for example) ARM people to
> > > implement something compatible.
> >
> > Do I understand correctly that a proper documentation of the registers
> > solves the problem?
> >
> > > Is there specific reason why "better" interface is impossible?
> >
> > What are specific problems with the current interface?
>
> What do you mean by "current" here? You are referring to an email from
> 2013, 9 years ago.
>
> If you want to propose the change again, correctly update the patch and
> submit it that way.

I don't believe taking hardware registers and exposing them 1-to-1 in
sysfs is the way to go.

We would like same /sys interface on different hardware, and simply
exposing Intel's registers in /sys will not do the job.

Best regards,
Pavel
--
http://www.livejournal.com/~pavelmachek


Attachments:
(No filename) (2.76 kB)
signature.asc (201.00 B)
Download all attachments

2022-02-18 21:58:28

by Jonathan McDowell

[permalink] [raw]
Subject: Re: [discuss] Improve and merge a driver proposed in 2013: sysfs interfaces to access TXT config space

On Thu, 2022-02-17 at 13:37 +0100, Pavel Machek wrote:
> On Thu 2022-02-17 13:34:40, [email protected] wrote:
> > On Thu, Feb 17, 2022 at 11:47:21AM +0000, Dmitrii Okunev wrote:
> > > Hello!
> > >
> > > As far as I see the patch wasn't merged. And I see that this is
> > > the only unsolved thread in the discussion:
> > >
> > > On Thu, 2013-05-16 at 18:03 +0200, Pavel Machek wrote:
> > > > On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> > > > > These interfaces are located in
> > > > > /sys/devices/platform/intel_txt/config,
> > > > > and including totally 37 files, providing access to Intel TXT
> > > > > configuration registers.
> > > >
> > > > This looks like very wrong interface... equivalent of /dev/mem.
> > >
> > > As an active user of these registers I hope it will be merged, so
> > > I would like to improve this patch (or rewrite it from scratch)
> > > to make that happen. Otherwise one have to do hackery around
> > > `/dev/mem`, which also creates problems with proper access
> > > control.
> > >
> > > To be able to improve the patch, could somebody clarify why
> > > exactly this is a "very wrong interface"?
> > >
> > > > > +What:          /sys/devices/platform/intel_txt/config/STS_ra
> > > > > w
> > > > > +Date:          May 2013
> > > > > +KernelVersion: 3.9
> > > > > +Contact:       "Qiaowei Ren" <[email protected]>
> > > > > +Description:   TXT.STS is the general status register. This
> > > > > read-
> > > > > only register
> > > > > +               is used by AC modules and the MLE to get the
> > > > > status
> > > > > of various
> > > > > +               Intel TXT features.
> > > >
> > > > This is not enough to allow people to understand what this
> > > > does/should do, nor does it allow (for example) ARM people to
> > > > implement something compatible.
> > > >
> > > > Is there specific reason why "better" interface is impossible?
> > >
> > > I would love to reuse Intel's public documentation [1] to provide
> > > a proper description (with bit layout of the value).
> > >
> > > [1] https://cdrdv2.intel.com/v1/dl/getContent/315168
> > >
> > > > [...], nor does it allow (for example) ARM people to
> > > > implement something compatible.
> > >
> > > Do I understand correctly that a proper documentation of the
> > > registers solves the problem?
> > >
> > > > Is there specific reason why "better" interface is impossible?
> > >
> > > What are specific problems with the current interface?
> >
> > What do you mean by "current" here?  You are referring to an email
> > from 2013, 9 years ago.
> >
> > If you want to propose the change again, correctly update the patch
> > and submit it that way.
>
> I don't believe taking hardware registers and exposing them 1-to-1 in
> sysfs is the way to go.
>
> We would like same /sys interface on different hardware, and simply
> exposing Intel's registers in /sys will not do the job.

So, for our particular use case what we want to be able to see is the
status of the TXT device, so when attestation fails it's possible to
diagnose where that might have happened. At a minimum details from the
status register are folded into the first measurement, and the error
register can provide valuable insight as to what the TXT device thinks
failed.

At present these details are retrieved from /dev/mem, but this is less
than ideal and prevents the use of, say, kernel lockdown. As a result
we'd like to export the appropriate details via sysfs. These are likely
to be extremely security block implementation specific, so I'm not
clear that a generic agnostic interface is appropriate to retrieve
these details.

Do you have the same objection to a read only set of information
(rather than the full control offered by the initial submission)?

J.

2022-02-22 09:54:07

by Pavel Machek

[permalink] [raw]
Subject: Re: [discuss] Improve and merge a driver proposed in 2013: sysfs interfaces to access TXT config space

On Fri 2022-02-18 18:05:47, Jonathan McDowell wrote:
> On Thu, 2022-02-17 at 13:37 +0100, Pavel Machek wrote:
> > On Thu 2022-02-17 13:34:40, [email protected]?wrote:
> > > On Thu, Feb 17, 2022 at 11:47:21AM +0000, Dmitrii Okunev wrote:
> > > > Hello!
> > > >
> > > > As far as I see the patch wasn't merged. And I see that this is
> > > > the only unsolved thread in the discussion:
> > > >
> > > > On Thu, 2013-05-16 at 18:03 +0200, Pavel Machek wrote:
> > > > > On Tue 2013-05-14 01:24:43, Qiaowei Ren wrote:
> > > > > > These interfaces are located in
> > > > > > /sys/devices/platform/intel_txt/config,
> > > > > > and including totally 37 files, providing access to Intel TXT
> > > > > > configuration registers.
> > > > >
> > > > > This looks like very wrong interface... equivalent of /dev/mem.
> > > >
> > > > As an active user of these registers I hope it will be merged, so
> > > > I would like to improve this patch (or rewrite it from scratch)
> > > > to make that happen. Otherwise one have to do hackery around
> > > > `/dev/mem`, which also creates problems with proper access
> > > > control.
> > > >
> > > > To be able to improve the patch, could somebody clarify why
> > > > exactly this is a "very wrong interface"?
> > > >
> > > > > > +What:??????????/sys/devices/platform/intel_txt/config/STS_ra
> > > > > > w
> > > > > > +Date:??????????May 2013
> > > > > > +KernelVersion:?3.9
> > > > > > +Contact:???????"Qiaowei Ren" <[email protected]>
> > > > > > +Description:???TXT.STS is the general status register. This
> > > > > > read-
> > > > > > only register
> > > > > > +???????????????is used by AC modules and the MLE to get the
> > > > > > status
> > > > > > of various
> > > > > > +???????????????Intel TXT features.
> > > > >
> > > > > This is not enough to allow people to understand what this
> > > > > does/should do, nor does it allow (for example) ARM people to
> > > > > implement something compatible.
> > > > >
> > > > > Is there specific reason why "better" interface is impossible?
> > > >
> > > > I would love to reuse Intel's public documentation [1] to provide
> > > > a proper description (with bit layout of the value).
> > > >
> > > > [1] https://cdrdv2.intel.com/v1/dl/getContent/315168
> > > >
> > > > > [...], nor does it allow (for example) ARM people to
> > > > > implement something compatible.
> > > >
> > > > Do I understand correctly that a proper documentation of the
> > > > registers solves the problem?
> > > >
> > > > > Is there specific reason why "better" interface is impossible?
> > > >
> > > > What are specific problems with the current interface?
> > >
> > > What do you mean by "current" here?? You are referring to an email
> > > from 2013, 9 years ago.
> > >
> > > If you want to propose the change again, correctly update the patch
> > > and submit it that way.
> >
> > I don't believe taking hardware registers and exposing them 1-to-1 in
> > sysfs is the way to go.
> >
> > We would like same /sys interface on different hardware, and simply
> > exposing Intel's registers in /sys will not do the job.
>
> So, for our particular use case what we want to be able to see is the
> status of the TXT device, so when attestation fails it's possible to
> diagnose where that might have happened. At a minimum?details from the
> status register are folded into the first measurement, and the error
> register can provide valuable insight as to what the TXT device thinks
> failed.
>
> At present these details are retrieved from /dev/mem, but this is less
> than ideal and prevents the use of, say, kernel lockdown. As a result
> we'd like to export the appropriate details via sysfs. These are likely
> to be extremely security block implementation specific, so I'm not
> clear that a generic agnostic interface is appropriate to retrieve
> these details.

> Do you have the same objection to a read only set of information
> (rather than the full control offered by the initial submission)?

Might be a job for debugfs?
Pavel

--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


Attachments:
(No filename) (4.16 kB)
signature.asc (188.00 B)
Digital signature
Download all attachments

2022-03-09 11:15:22

by Jonathan McDowell

[permalink] [raw]
Subject: [RFC PATCH] platform/x86: Add sysfs interface for Intel TXT status

(This is an RFC to see if the approach is generally acceptable; unlike
the previous driver this exposes the information purely as read-only
status information, so userspace can make an informed decision about the
system state without having to poke about in /dev/mem. There are still a
few extra registers I'm trying to dig up information for before a proper
submission.)

This module provides read-only access to the Intel TXT (Trusted
Execution Technology) status registers, allowing userspace to determine
the status of measured boot and whether the dynamic root of trust for
measurement (DRTM) has been fully enabled.

Tools such as txt-stat from tboot
<https://sourceforge.net/projects/tboot/> can make use of this driver to
display state rather than relying on access to /dev/mem.

See Documentation/x86/intel_txt.rst for more information about Intel
TXT.

Signed-off-by: Jonathan McDowell <[email protected]>
---
arch/x86/include/asm/txt.h | 34 +++++
drivers/platform/x86/intel/Kconfig | 14 ++
drivers/platform/x86/intel/Makefile | 2 +
drivers/platform/x86/intel/txt_sysfs.c | 185 +++++++++++++++++++++++++
4 files changed, 235 insertions(+)
create mode 100644 arch/x86/include/asm/txt.h
create mode 100644 drivers/platform/x86/intel/txt_sysfs.c

diff --git a/arch/x86/include/asm/txt.h b/arch/x86/include/asm/txt.h
new file mode 100644
index 000000000000..9c90d894c1af
--- /dev/null
+++ b/arch/x86/include/asm/txt.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * txt.h: Intel TXT (Trusted Execution Technology) related definitions
+ */
+
+#ifndef __TXT_H
+#define __TXT_H
+
+#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)
+
+/*
+ * TXT configuration registers (offsets from TXT_{PUB,PRIV}_CONFIG_REGS_BASE)
+ */
+
+#define TXT_CR_STS 0x0000
+#define TXT_CR_ESTS 0x0008
+#define TXT_CR_ERRORCODE 0x0030
+#define TXT_CR_ACMSTS 0x00A0
+#define TXT_CR_VER_FSBIF 0x0100
+#define TXT_CR_DIDVID 0x0110
+#define TXT_CR_VER_QPIIF 0x0200
+#define TXT_CR_SINIT_BASE 0x0270
+#define TXT_CR_SINIT_SIZE 0x0278
+#define TXT_CR_HEAP_BASE 0x0300
+#define TXT_CR_HEAP_SIZE 0x0308
+#define TXT_CR_DPR 0x0330
+#define TXT_CR_PUBLIC_KEY 0x0400
+#define TXT_CR_E2STS 0x08f0
+
+#endif /* __TXT_H */
diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig
index 8e65086bb6c8..ae8d032b4499 100644
--- a/drivers/platform/x86/intel/Kconfig
+++ b/drivers/platform/x86/intel/Kconfig
@@ -159,6 +159,20 @@ config INTEL_TURBO_MAX_3
This driver is only required when the system is not using Hardware
P-States (HWP). In HWP mode, priority can be read from ACPI tables.

+config INTEL_TXT_SYSFS
+ tristate "Intel TXT sysfs driver"
+ depends on HAVE_INTEL_TXT && SECURITYFS
+ help
+ This driver exports the TXT (Trusted Execution Technology) public
+ configuration space to user space via sysfs.
+
+ These registers provide details about the status of the platform's
+ measured launch and execution environment, allowing userspace to
+ make trust based decisions. See tboot
+ <https://sourceforge.net/projects/tboot/> and TrenchBoot
+ <https://trenchboot.org/> for projects which implement the
+ appropriate boot flow to fully enable these features.
+
config INTEL_UNCORE_FREQ_CONTROL
tristate "Intel Uncore frequency control driver"
depends on X86_64
diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile
index 35f2066578b2..ac73ac61090a 100644
--- a/drivers/platform/x86/intel/Makefile
+++ b/drivers/platform/x86/intel/Makefile
@@ -26,6 +26,8 @@ intel_int0002_vgpio-y := int0002_vgpio.o
obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
intel_oaktrail-y := oaktrail.o
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
+intel_txt_sysfs-y := txt_sysfs.o
+obj-$(CONFIG_INTEL_TXT_SYSFS) += intel_txt_sysfs.o
intel_vsec-y := vsec.o
obj-$(CONFIG_INTEL_VSEC) += intel_vsec.o

diff --git a/drivers/platform/x86/intel/txt_sysfs.c b/drivers/platform/x86/intel/txt_sysfs.c
new file mode 100644
index 000000000000..a8e51abc6854
--- /dev/null
+++ b/drivers/platform/x86/intel/txt_sysfs.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This module can be used to access below resources
+ * - TXT config space
+ * - SMX parameter
+ *
+ * Intel TXT (Trusted Execution Technology) will provide higher
+ * assurance of system configuration and initial state as well as
+ * data reset protection. It also helps solve real end user concerns
+ * about having confidence that their hardware is running the VMM
+ * or kernel that it was configured with, especially since they may
+ * be responsible for providing such assurances to VMs and services
+ * running on it.
+ *
+ * See Documentation/intel_txt.txt for more information about
+ * Intel TXT.
+ *
+ * Intel TXT configuration registers are a subset of chipset registers.
+ * These chipset registers that interact with SMX are accessed from two
+ * regions of memory, which represent the public and private configuration
+ * spaces, by system software using memory read/write protocols.
+ *
+ * Safer Mode Extensions (SMX) provide a processor's programming
+ * interface in an Intel TXT platform for system software to establish
+ * a measured environment within the platform to support trust decisions
+ * by end users.
+ *
+ * Data can be found below
+ * /sys/devices/platform/intel_txt/...
+ */
+
+#include <linux/byteorder/little_endian.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/security.h>
+#include <linux/seq_file.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/txt.h>
+
+#define DEV_NAME "intel_txt"
+static struct platform_device *txt_pdev;
+
+static int txt_enabled_show(struct seq_file *m, void *v);
+static int txt_key_show(struct seq_file *m, void *v);
+static int txt_reg_show(struct seq_file *m, void *v);
+
+/* securityfs related data */
+static struct dentry *txt_dir;
+static void *txt_pub_regs;
+static struct txt_securityfs_file {
+ char *name;
+ u32 ofs;
+ int (*show)(struct seq_file *m, void *v);
+ struct dentry *dentry;
+} txt_securityfs_files[] = {
+ /* Raw registers */
+ { .name = "acmsts", .ofs = TXT_CR_ACMSTS, .show = txt_reg_show },
+ { .name = "didvid", .ofs = TXT_CR_DIDVID, .show = txt_reg_show },
+ { .name = "dpr", .ofs = TXT_CR_DPR, .show = txt_reg_show },
+ { .name = "errorcode", .ofs = TXT_CR_ERRORCODE, .show = txt_reg_show },
+ { .name = "ests", .ofs = TXT_CR_ESTS, .show = txt_reg_show },
+ { .name = "sts", .ofs = TXT_CR_STS, .show = txt_reg_show },
+
+ { .name = "enabled", .show = txt_enabled_show },
+ { .name = "publickey", .show = txt_key_show },
+};
+
+/* Shows if TXT has been enabled */
+static int txt_enabled_show(struct seq_file *m, void *v)
+{
+ /* If the BIOS has enabled TXT then the heap base will be set */
+ seq_printf(m, "%d\n", *(u64 *)(txt_pub_regs + TXT_CR_HEAP_BASE) != 0);
+
+ return 0;
+}
+
+/* Shows the 256 bit hash of the public key */
+static int txt_key_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%016llx%016llx%016llx%016llx\n",
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY)),
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 8)),
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 16)),
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 24)));
+
+ return 0;
+}
+
+/* Show a generic 64 bit register */
+static int txt_reg_show(struct seq_file *m, void *v)
+{
+ struct txt_securityfs_file *ctx = m->private;
+
+ seq_printf(m, "%016llx\n", *(u64 *)(txt_pub_regs + ctx->ofs));
+
+ return 0;
+}
+
+static int txt_pub_reg_open(struct inode *inode, struct file *filp)
+{
+ struct txt_securityfs_file *ctx = file_inode(filp)->i_private;
+
+ return single_open(filp, ctx->show, ctx);
+}
+
+static const struct file_operations txt_pub_reg_fops = {
+ .open = txt_pub_reg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct x86_cpu_id smx_cpu_id[] = {
+ X86_MATCH_FEATURE(X86_FEATURE_SMX, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, smx_cpu_id);
+
+static int __init txt_sysfs_init(void)
+{
+ int i;
+ int err;
+
+ if (!x86_match_cpu(smx_cpu_id))
+ return -ENODEV;
+
+ txt_pdev = platform_device_register_simple(DEV_NAME, -1, NULL, 0);
+ if (IS_ERR(txt_pdev))
+ return PTR_ERR(txt_pdev);
+
+ txt_pub_regs = devm_ioremap(&txt_pdev->dev, TXT_PUB_CONFIG_REGS_BASE,
+ TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+ if (!txt_pub_regs)
+ goto out;
+
+ txt_dir = securityfs_create_dir("txt", NULL);
+ if (IS_ERR(txt_dir)) {
+ err = PTR_ERR(txt_dir);
+ txt_dir = NULL;
+ goto out;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(txt_securityfs_files); i++) {
+ txt_securityfs_files[i].dentry = securityfs_create_file(
+ txt_securityfs_files[i].name, 0444, txt_dir,
+ &txt_securityfs_files[i],
+ &txt_pub_reg_fops);
+ if (IS_ERR(txt_securityfs_files[i].dentry)) {
+ err = PTR_ERR(txt_securityfs_files[i].dentry);
+ txt_securityfs_files[i].dentry = NULL;
+ goto out;
+ }
+ }
+
+ return 0;
+out:
+ for (i = 0; i < ARRAY_SIZE(txt_securityfs_files); i++) {
+ if (txt_securityfs_files[i].dentry != NULL)
+ securityfs_remove(txt_securityfs_files[i].dentry);
+ }
+ if (txt_dir)
+ securityfs_remove(txt_dir);
+ platform_device_unregister(txt_pdev);
+ return err;
+}
+
+static void __exit txt_sysfs_exit(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(txt_securityfs_files); i++) {
+ if (txt_securityfs_files[i].dentry != NULL)
+ securityfs_remove(txt_securityfs_files[i].dentry);
+ }
+ securityfs_remove(txt_dir);
+ platform_device_unregister(txt_pdev);
+}
+
+module_init(txt_sysfs_init);
+module_exit(txt_sysfs_exit);
+
+MODULE_LICENSE("GPL");
--
2.34.1

2022-03-09 11:48:04

by Jonathan McDowell

[permalink] [raw]
Subject: Re: [RFC PATCH] platform/x86: Add sysfs interface for Intel TXT status

On Wed, Mar 09, 2022 at 11:48:23AM +0100, Greg KH wrote:
> On Wed, Mar 09, 2022 at 10:40:03AM +0000, Jonathan McDowell wrote:
> > (This is an RFC to see if the approach is generally acceptable; unlike
> > the previous driver this exposes the information purely as read-only
> > status information, so userspace can make an informed decision about the
> > system state without having to poke about in /dev/mem. There are still a
> > few extra registers I'm trying to dig up information for before a proper
> > submission.)
> >
> > This module provides read-only access to the Intel TXT (Trusted
> > Execution Technology) status registers, allowing userspace to determine
> > the status of measured boot and whether the dynamic root of trust for
> > measurement (DRTM) has been fully enabled.
> >
> > Tools such as txt-stat from tboot
> > <https://sourceforge.net/projects/tboot/ > can make use of this driver to
> > display state rather than relying on access to /dev/mem.
> >
> > See Documentation/x86/intel_txt.rst for more information about Intel
> > TXT.
> >
> > Signed-off-by: Jonathan McDowell <[email protected]>
> > ---
> > arch/x86/include/asm/txt.h | 34 +++++
> > drivers/platform/x86/intel/Kconfig | 14 ++
> > drivers/platform/x86/intel/Makefile | 2 +
> > drivers/platform/x86/intel/txt_sysfs.c | 185 +++++++++++++++++++++++++
>
> No Documentation/ABI/ entry for your new sysfs entry? How can we
> evaluate if this is a good api then?

As a read-only export of configuration registers is a full set of info
in Documentation/ABI/ required? I didn't get a feel for how required
that was from the existing files there.

> Wait, I don't see any sysfs code in here, are you sure you sent a viable
> patch?

The export to sysfs is via securityfs, as that seemed to be the
appropriate route (it fits into a similar area as
/sys/kernel/security/integrity/ima/ or /sys/kernel/security/tpm0/,
providing userspace with some visibility of what the kernel thinks the
state is).

J.

2022-03-09 12:54:40

by Matthew Garrett

[permalink] [raw]
Subject: Re: [RFC PATCH] platform/x86: Add sysfs interface for Intel TXT status

On Wed, Mar 09, 2022 at 10:40:03AM +0000, Jonathan McDowell wrote:

> This module provides read-only access to the Intel TXT (Trusted
> Execution Technology) status registers, allowing userspace to determine
> the status of measured boot and whether the dynamic root of trust for
> measurement (DRTM) has been fully enabled.

So there's the obvious issue that in the event that the system has been
compromised this information is no longer trustworthy - is this expected
to just be informative for diagnostic purposes rather than forming any
part of security policy?

> + These registers provide details about the status of the platform's
> + measured launch and execution environment, allowing userspace to
> + make trust based decisions. See tboot

Mm. This makes it sound like it's expected that userspace make decisions
based on this, which sounds like a bad plan?

> +/* Shows if TXT has been enabled */
> +static int txt_enabled_show(struct seq_file *m, void *v)
> +{
> + /* If the BIOS has enabled TXT then the heap base will be set */

Sorry it's not that I want to say "Wait are you trusting that the BIOS
will do the right thing here" but wait are you trusting that the BIOS
will do the right thing here? Does setting the heap base guarantee that
TXT was enabled (and, conversely, are there any scenarios where TXT was
enabled and the BIOS could have cleared the heap base after a
measurement event?)

> +/* Shows the 256 bit hash of the public key */
> +static int txt_key_show(struct seq_file *m, void *v)
> +{
> + seq_printf(m, "%016llx%016llx%016llx%016llx\n",
> + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY)),
> + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 8)),
> + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 16)),
> + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 24)));

What's the expected consumer of this, and what are they expected to do
with it?

2022-03-09 13:00:36

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [RFC PATCH] platform/x86: Add sysfs interface for Intel TXT status

On Wed, Mar 09, 2022 at 10:40:03AM +0000, Jonathan McDowell wrote:
> (This is an RFC to see if the approach is generally acceptable; unlike
> the previous driver this exposes the information purely as read-only
> status information, so userspace can make an informed decision about the
> system state without having to poke about in /dev/mem. There are still a
> few extra registers I'm trying to dig up information for before a proper
> submission.)
>
> This module provides read-only access to the Intel TXT (Trusted
> Execution Technology) status registers, allowing userspace to determine
> the status of measured boot and whether the dynamic root of trust for
> measurement (DRTM) has been fully enabled.
>
> Tools such as txt-stat from tboot
> <https://sourceforge.net/projects/tboot/> can make use of this driver to
> display state rather than relying on access to /dev/mem.
>
> See Documentation/x86/intel_txt.rst for more information about Intel
> TXT.
>
> Signed-off-by: Jonathan McDowell <[email protected]>
> ---
> arch/x86/include/asm/txt.h | 34 +++++
> drivers/platform/x86/intel/Kconfig | 14 ++
> drivers/platform/x86/intel/Makefile | 2 +
> drivers/platform/x86/intel/txt_sysfs.c | 185 +++++++++++++++++++++++++

No Documentation/ABI/ entry for your new sysfs entry? How can we
evaluate if this is a good api then?

Wait, I don't see any sysfs code in here, are you sure you sent a viable
patch?

confused,

greg k-h

2022-03-09 13:13:46

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [RFC PATCH] platform/x86: Add sysfs interface for Intel TXT status

On Wed, Mar 09, 2022 at 10:58:17AM +0000, Jonathan McDowell wrote:
> On Wed, Mar 09, 2022 at 11:48:23AM +0100, Greg KH wrote:
> > On Wed, Mar 09, 2022 at 10:40:03AM +0000, Jonathan McDowell wrote:
> > > (This is an RFC to see if the approach is generally acceptable; unlike
> > > the previous driver this exposes the information purely as read-only
> > > status information, so userspace can make an informed decision about the
> > > system state without having to poke about in /dev/mem. There are still a
> > > few extra registers I'm trying to dig up information for before a proper
> > > submission.)
> > >
> > > This module provides read-only access to the Intel TXT (Trusted
> > > Execution Technology) status registers, allowing userspace to determine
> > > the status of measured boot and whether the dynamic root of trust for
> > > measurement (DRTM) has been fully enabled.
> > >
> > > Tools such as txt-stat from tboot
> > > <https://sourceforge.net/projects/tboot/ > can make use of this driver to
> > > display state rather than relying on access to /dev/mem.
> > >
> > > See Documentation/x86/intel_txt.rst for more information about Intel
> > > TXT.
> > >
> > > Signed-off-by: Jonathan McDowell <[email protected]>
> > > ---
> > > arch/x86/include/asm/txt.h | 34 +++++
> > > drivers/platform/x86/intel/Kconfig | 14 ++
> > > drivers/platform/x86/intel/Makefile | 2 +
> > > drivers/platform/x86/intel/txt_sysfs.c | 185 +++++++++++++++++++++++++
> >
> > No Documentation/ABI/ entry for your new sysfs entry? How can we
> > evaluate if this is a good api then?
>
> As a read-only export of configuration registers is a full set of info
> in Documentation/ABI/ required? I didn't get a feel for how required
> that was from the existing files there.

For all sysfs entries, yes, it is required. Run the scripts/get_abi.pl
tool as proof :)

> > Wait, I don't see any sysfs code in here, are you sure you sent a viable
> > patch?
>
> The export to sysfs is via securityfs, as that seemed to be the
> appropriate route (it fits into a similar area as
> /sys/kernel/security/integrity/ima/ or /sys/kernel/security/tpm0/,
> providing userspace with some visibility of what the kernel thinks the
> state is).

Then this is securityfs, NOT sysfs. securityfs just happens to be
mounted at that location. You could mount it anywhere else as well.
Please fix up the terminology here, it is very confusing and has nothing
to do with sysfs at all.

thanks,

greg k-h

2022-03-09 21:26:09

by Jonathan McDowell

[permalink] [raw]
Subject: Re: [RFC PATCH] platform/x86: Add sysfs interface for Intel TXT status

On Wed, Mar 09, 2022 at 10:53:43AM +0000, Matthew Garrett wrote:
> On Wed, Mar 09, 2022 at 10:40:03AM +0000, Jonathan McDowell wrote:
>
> > This module provides read-only access to the Intel TXT (Trusted
> > Execution Technology) status registers, allowing userspace to determine
> > the status of measured boot and whether the dynamic root of trust for
> > measurement (DRTM) has been fully enabled.
>
> So there's the obvious issue that in the event that the system has been
> compromised this information is no longer trustworthy - is this expected
> to just be informative for diagnostic purposes rather than forming any
> part of security policy?

This is purely for diagnostic purposes when the system ends up in an
unexpected state, to aid automated remediation. In particular dealing
with unexpected PCR0 values that have failed attestation; the state of
TXT helps with trying to diagnose how we got to the unexpected value.

> > + These registers provide details about the status of the platform's
> > + measured launch and execution environment, allowing userspace to
> > + make trust based decisions. See tboot
>
> Mm. This makes it sound like it's expected that userspace make decisions
> based on this, which sounds like a bad plan?

I should clean up the description to be clearer for v2.

> > +/* Shows if TXT has been enabled */
> > +static int txt_enabled_show(struct seq_file *m, void *v)
> > +{
> > + /* If the BIOS has enabled TXT then the heap base will be set */
>
> Sorry it's not that I want to say "Wait are you trusting that the BIOS
> will do the right thing here" but wait are you trusting that the BIOS
> will do the right thing here? Does setting the heap base guarantee that
> TXT was enabled (and, conversely, are there any scenarios where TXT was
> enabled and the BIOS could have cleared the heap base after a
> measurement event?)

If the BIOS hasn't enabled the heap then it won't have been able to pass
any data to the system for a managed launch environment, so I think it's
fairly safe to assume if it's never been set we're not in a situation
where anything has tried to initialise TXT. If we're in a situation
where we've tried to initialise it and then something has gone wrong and
the BIOS has managed to clear it that's probably a firmware bug and I'd
expect to see some status register oddities too. We're not trusting the
BIOS here, we're just using the fact the heap is actually setup to
indicate that we've tried to do TXT in terms of diagnosis. (And, in
fact, one of the failure modes we've seen is where TXT is supposed to be
configured in the BIOS but it doesn't actually get setup at all and we
correctly see a 0 entry here.)

> > +/* Shows the 256 bit hash of the public key */
> > +static int txt_key_show(struct seq_file *m, void *v)
> > +{
> > + seq_printf(m, "%016llx%016llx%016llx%016llx\n",
> > + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY)),
> > + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 8)),
> > + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 16)),
> > + cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 24)));
>
> What's the expected consumer of this, and what are they expected to do
> with it?

I added it purely because txt-stat is already showing it, and it differs
between platforms. I note 315168-017 says newer platforms use CPU MSRs
0x20::0x23 instead. So it's informational at this point for older
platforms.

J.

2022-04-12 23:24:26

by Jonathan McDowell

[permalink] [raw]
Subject: [RFC PATCH v2] platform/x86: Add securityfs interface for TXT status

This module provides read-only access to the Intel TXT (Trusted
Execution Technology) status registers, allowing userspace to determine
the status of measured boot and whether the dynamic root of trust for
measurement (DRTM) has been fully enabled.

Tools such as txt-stat from tboot
<https://sourceforge.net/projects/tboot/> can make use of this driver to
display state and attempt to remediate issues rather than relying on
access to /dev/mem.

See Documentation/x86/intel_txt.rst for more information about Intel
TXT.

Signed-off-by: Jonathan McDowell <[email protected]>
---
v2:
- Refer to securityfs instead of sysfs
- Clarify this is read-only access for remediation
- Add documentation for the securityfs files presented
---
.../ABI/testing/securityfs-intel-txt | 226 ++++++++++++++++++
arch/x86/include/asm/txt.h | 42 ++++
drivers/platform/x86/intel/Kconfig | 16 ++
drivers/platform/x86/intel/Makefile | 2 +
drivers/platform/x86/intel/txt_securityfs.c | 189 +++++++++++++++
5 files changed, 475 insertions(+)
create mode 100644 Documentation/ABI/testing/securityfs-intel-txt
create mode 100644 arch/x86/include/asm/txt.h
create mode 100644 drivers/platform/x86/intel/txt_securityfs.c

diff --git a/Documentation/ABI/testing/securityfs-intel-txt b/Documentation/ABI/testing/securityfs-intel-txt
new file mode 100644
index 000000000000..2e0df93a168c
--- /dev/null
+++ b/Documentation/ABI/testing/securityfs-intel-txt
@@ -0,0 +1,226 @@
+What: /sys/security/security/intel-txt/*
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Various files relating to Intel's TXT (Trusted Execution
+ Technology). These provide read-only access to the state of
+ measured boot and whether the dynamic root of trust (DRTM) has
+ been fully enabled.
+
+ These details are intended for use in allowing userspace to
+ remediate issues with the TXT feature. They should not be relied
+ upon for confirming the system is in a secure state.
+
+ Many of the files listed below provide the raw hex values from
+ the device registers. Where possible the bit fields are
+ documented, but bits defined as reserved have been observed to
+ be clear on some platforms and set on others. As the primary
+ purpose of this support is to allow full visibility of state for
+ the purpose of remediation it is more useful to have the raw
+ values than a partially decoded state.
+
+What: /sys/security/security/intel-txt/enabled
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Indicates if it looks like the BIOS has successfully enabled the
+ TXT functionality. Checks that a heap has correctly been
+ configured for the device. A non-initialised heap is not a
+ guarantee that an errant BIOS has not tried to enable
+ functionality and then clear status, nor does the presence of a
+ configured heap mean the device is fully initialised.
+
+What: /sys/security/security/intel-txt/didvid
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Contains the vendor, device and revision IDs for the memory
+ controller or chipset.
+
+ b[15:0]
+ Vendor ID: 8086 for Intel
+ b[31:16]
+ Device ID: Specific to the chipset/platform
+ b[47:32]
+ Revision ID: Specific to the chipset/platform
+ b[63:48]
+ Extended ID: Specific to the chipset/platform
+
+What: /sys/security/security/intel-txt/dpr
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Defines the details of the DMA Protected Range in which the TXT
+ heap and SINIT regions are located.
+
+ Platforms utilising SGX implement this as part of uncore and so
+ this register has no underlying hardware functionality on those
+ platforms.
+
+ b[0]
+ Bits 19:0 are locked down in this register when this bit
+ is set.
+ b[3:1]
+ Reserved.
+ b[11:4]
+ The size of memory, in MB, that will be protected from
+ DMA accesses. 0 indicates no memory is protected.
+ b[19:12]
+ Reserved.
+ b[31:20]
+ Top address + 1 of the DMA protected range.
+
+What: /sys/security/security/intel-txt/e2sts
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Extended error status details. Contents are preserved across
+ soft resets.
+
+ b[0]
+ Reserved.
+ b[1]
+ SECRET.STS.
+ 0 = Chipset acknowledged that no secrets are in memory.
+ 1 = Chipset believes that secrets are in memory and will
+ provide reset protection.
+ b[63:2]
+ Reserved.
+
+What: /sys/security/security/intel-txt/errorcode
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Shutdown error code details. Preserved over a soft reset,
+ cleared by a hard reset or power cycle.
+
+ b[3:0]
+ Module details.
+ 0 = BIOS ACM
+ 1 = SINIT
+ b[9:4]
+ Class code
+ b[14:10]
+ Major error code
+ b[15]
+ Software source
+ 0 = Authenticated Code Module (ACM)
+ 1 = Measure Launch Environment (MLE)
+ b[27:16]
+ Minor error code
+ b[29:28]
+ Reserved.
+ b[30]
+ 0 = Error reported by processor
+ 1 = Error reported by software
+ b[31]
+ Valid bit
+ 0 = Register contents invalid, should be ignored
+ 1 = Error details valid
+ b[63:32]
+ Reserved.
+
+What: /sys/security/security/intel-txt/ests
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Details associated with various error conditions. Contents are
+ preserved across soft resets.
+
+ b[0]
+ TXT_RESET.STS. Set to 1 to indicate an error occurred
+ which may prevent the proper use of TXT. While this bit
+ is set the Safer Mode Extension (SMX) instructions
+ GETSEC[ENTERACCS] and GETSEC[SENTER] will fail.
+
+ This bit is only cleared on a power cycle.
+ b[63:1]
+ Reserved.
+
+What: /sys/security/security/intel-txt/spad
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ Details from the startup Authenticated Code Module (ACM)
+ conveying the results of its operation. Generally of interest to
+ the BIOS rather than the OS in normal operation it can provide
+ details of where TXT initialisation failed.
+
+ b[29:0]
+ Reserved.
+ b[30]
+ Indicates TXT startup success; successful preparation
+ for the BIOS, SINIT and MLE components.
+ b[46:31]
+ General startup ACM to BIOS boot status communication.
+ b[47]
+ Indicates memory contents were cleared via a power down.
+ b[52:48]
+ Startup ACM to BIOS communication in MP platforms.
+ b[53]
+ Startup ACM indication of run-time enabled status of
+ TXT. Generally driven by FIT type 0xA record.
+ b[58:54]
+ Startup ACM to BIOS communication in MP platforms.
+ b[59]
+ Indicates the BIOS is trusted.
+ b[60]
+ Indicates that TXT has been disabled by a runtime FIT
+ type 0xA record.
+ b[61]
+ Startup ACM to BIOS communication in MP platforms.
+ b[62]
+ Indicates an ACM authentication error from the CPU.
+ b[63]
+ Indicates S-ACM successfully enforced its logic for all
+ provisioned technologies.
+
+What: /sys/security/security/intel-txt/sts
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ General status details for various TXT features.
+
+ b[0]
+ SENTER.DONE.STS. Set by the chipset when it sees all
+ threads have done a TXT.CYC.SENTER-ACK. When any of the
+ threads does a TXT.CYC.SYSEXIT-ACK then TXT.THREADS.JOIN
+ and TXT.THREAD.EXISTS registers will not be equal and
+ the chipset will clear this bit.
+ b[1]
+ SEXIT.DONE.STS. Set when all bits in the
+ TXT.THREADS.JOIN register are clear. This is thus set
+ after reset (since the bits are all 0) and once all
+ threads have done a TXT.CYC.SYSEXIT-ACK.
+ b[5:2]
+ Reserved.
+ b[6]
+ MEM-CONFIG-LOCK.STS. Set to 1 when the memory
+ configuration is locked. Cleared by
+ TXT.CMD.UNLOCK.MEMCONFIG or a system reset.
+ b[7]
+ PRIVATE-OPEN.STS. Set to 1 when TXT.CMD.OPEN-PRIVATE is
+ performed. Cleared by TXT.CMD.CLOSE-PRIVATE or by a
+ system reset.
+ b[14:8]
+ Reserved.
+ b[15]
+ TXT.LOCALITY1.OPEN.STS. Set when TXT.CMD.OPEN.LOCALITY1
+ is seen by the chipset. Cleared on reset or when
+ TXT.CMD.CLOSE.LOCALITY1 is seen.
+ b[16]
+ TXT.LOCALITY2.OPEN.STS. Set when TXT.CMD.OPEN.LOCALITY2
+ or TXT.CMD.OPEN.PRIVATE is seen by the chipset. Cleared
+ on reset, or when either TXT.CMD.CLOSE.LOCALITY2 or
+ TXT.CMD.CLOSE.PRIVATE is seen, and by the GETSEC[SEXIT]
+ instruction.
+ b[63:17]
+ Reserved.
+
+What: /sys/security/security/intel-txt/publickey
+Date: April 2022
+Contact: Jonathan McDowell <[email protected]>
+Description:
+ 256 bit hash of the public key used for the verification of the
+ Authenticated Code Modules. Details are specific to the memory
+ controller or chipset.
diff --git a/arch/x86/include/asm/txt.h b/arch/x86/include/asm/txt.h
new file mode 100644
index 000000000000..a26df62f990c
--- /dev/null
+++ b/arch/x86/include/asm/txt.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * txt.h: Intel TXT (Trusted Execution Technology) related definitions
+ */
+
+#ifndef __TXT_H
+#define __TXT_H
+
+#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)
+
+/*
+ * TXT configuration registers (offsets from TXT_{PUB,PRIV}_CONFIG_REGS_BASE)
+ *
+ * Registers exist at the same offsets in both spaces, but access control
+ * may differ.
+ *
+ * See Intel's "Measured Launch Environment Developer's Guide" (315168)
+ * for full details.
+ */
+
+#define TXT_CR_STS 0x0000
+#define TXT_CR_ESTS 0x0008
+#define TXT_CR_ERRORCODE 0x0030
+#define TXT_CR_SPAD 0x00A0
+#define TXT_CR_VER_FSBIF 0x0100
+#define TXT_CR_DIDVID 0x0110
+#define TXT_CR_VER_EMIF 0x0200
+#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_DPR 0x0330
+#define TXT_CR_SCRATCHPAD 0x0378
+#define TXT_CR_PUBLIC_KEY 0x0400
+#define TXT_CR_E2STS 0x08f0
+
+#endif /* __TXT_H */
diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig
index 8e65086bb6c8..40b55e7fbfce 100644
--- a/drivers/platform/x86/intel/Kconfig
+++ b/drivers/platform/x86/intel/Kconfig
@@ -159,6 +159,22 @@ config INTEL_TURBO_MAX_3
This driver is only required when the system is not using Hardware
P-States (HWP). In HWP mode, priority can be read from ACPI tables.

+config INTEL_TXT_SECURITYFS
+ tristate "Intel TXT securityfs driver"
+ depends on HAVE_INTEL_TXT && SECURITYFS
+ help
+ This driver exports the TXT (Trusted Execution Technology) public
+ configuration space to user space via securityfs.
+
+ These registers provide details about the status of the platform's
+ measured launch and execution environment, allowing userspace to
+ perform diagnosis and potential remediation when attestation or
+ other trust related operations are failing.
+
+ For kernel implementations which actually provide a trusted
+ environment see tboot <https://sourceforge.net/projects/tboot/>
+ and TrenchBoot <https://trenchboot.org/>.
+
config INTEL_UNCORE_FREQ_CONTROL
tristate "Intel Uncore frequency control driver"
depends on X86_64
diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile
index 35f2066578b2..5d4531d4ada5 100644
--- a/drivers/platform/x86/intel/Makefile
+++ b/drivers/platform/x86/intel/Makefile
@@ -26,6 +26,8 @@ intel_int0002_vgpio-y := int0002_vgpio.o
obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
intel_oaktrail-y := oaktrail.o
obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
+intel_txt_securityfs-y := txt_securityfs.o
+obj-$(CONFIG_INTEL_TXT_SECURITYFS) += intel_txt_securityfs.o
intel_vsec-y := vsec.o
obj-$(CONFIG_INTEL_VSEC) += intel_vsec.o

diff --git a/drivers/platform/x86/intel/txt_securityfs.c b/drivers/platform/x86/intel/txt_securityfs.c
new file mode 100644
index 000000000000..2db9aa95acb9
--- /dev/null
+++ b/drivers/platform/x86/intel/txt_securityfs.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This module can be used to access below resources
+ * - TXT config space
+ * - SMX parameter
+ *
+ * Intel TXT (Trusted Execution Technology) will provide higher
+ * assurance of system configuration and initial state as well as
+ * data reset protection. It also helps solve real end user concerns
+ * about having confidence that their hardware is running the VMM
+ * or kernel that it was configured with, especially since they may
+ * be responsible for providing such assurances to VMs and services
+ * running on it.
+ *
+ * See Documentation/x86/intel_txt.rst for more information about
+ * Intel TXT.
+ *
+ * Intel TXT configuration registers are a subset of chipset registers.
+ * These chipset registers that interact with SMX are accessed from two
+ * regions of memory, which represent the public and private configuration
+ * spaces, by system software using memory read/write protocols.
+ *
+ * Safer Mode Extensions (SMX) provide a processor's programming
+ * interface in an Intel TXT platform for system software to establish
+ * a measured environment within the platform to support trust decisions
+ * by end users.
+ *
+ * Data can be found below
+ * /sys/security/security/intel-txt/
+ *
+ * Details of the registers can be found in
+ * Documentation/ABI/testing/securityfs-intel-txt
+ */
+
+#include <linux/byteorder/little_endian.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/security.h>
+#include <linux/seq_file.h>
+
+#include <asm/cpu_device_id.h>
+#include <asm/txt.h>
+
+#define DEV_NAME "intel_txt"
+static struct platform_device *txt_pdev;
+
+static int txt_enabled_show(struct seq_file *m, void *v);
+static int txt_key_show(struct seq_file *m, void *v);
+static int txt_reg_show(struct seq_file *m, void *v);
+
+/* securityfs related data */
+static struct dentry *txt_dir;
+static void *txt_pub_regs;
+static struct txt_securityfs_file {
+ char *name;
+ u32 ofs;
+ int (*show)(struct seq_file *m, void *v);
+ struct dentry *dentry;
+} txt_securityfs_files[] = {
+ /* Raw registers */
+ { .name = "didvid", .ofs = TXT_CR_DIDVID, .show = txt_reg_show },
+ { .name = "dpr", .ofs = TXT_CR_DPR, .show = txt_reg_show },
+ { .name = "e2sts", .ofs = TXT_CR_E2STS, .show = txt_reg_show },
+ { .name = "errorcode", .ofs = TXT_CR_ERRORCODE, .show = txt_reg_show },
+ { .name = "ests", .ofs = TXT_CR_ESTS, .show = txt_reg_show },
+ { .name = "spad", .ofs = TXT_CR_SPAD, .show = txt_reg_show },
+ { .name = "sts", .ofs = TXT_CR_STS, .show = txt_reg_show },
+
+ { .name = "enabled", .show = txt_enabled_show },
+ { .name = "publickey", .show = txt_key_show },
+};
+
+/* Shows if TXT has been enabled */
+static int txt_enabled_show(struct seq_file *m, void *v)
+{
+ /* If the BIOS has enabled TXT then the heap base will be set */
+ seq_printf(m, "%d\n", *(u64 *)(txt_pub_regs + TXT_CR_HEAP_BASE) != 0);
+
+ return 0;
+}
+
+/* Shows the 256 bit hash of the public key */
+static int txt_key_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%016llx%016llx%016llx%016llx\n",
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY)),
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 8)),
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 16)),
+ cpu_to_be64(*(u64 *)(txt_pub_regs + TXT_CR_PUBLIC_KEY + 24)));
+
+ return 0;
+}
+
+/* Show a generic 64 bit register */
+static int txt_reg_show(struct seq_file *m, void *v)
+{
+ struct txt_securityfs_file *ctx = m->private;
+
+ seq_printf(m, "%016llx\n", *(u64 *)(txt_pub_regs + ctx->ofs));
+
+ return 0;
+}
+
+static int txt_pub_reg_open(struct inode *inode, struct file *filp)
+{
+ struct txt_securityfs_file *ctx = file_inode(filp)->i_private;
+
+ return single_open(filp, ctx->show, ctx);
+}
+
+static const struct file_operations txt_pub_reg_fops = {
+ .open = txt_pub_reg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct x86_cpu_id smx_cpu_id[] = {
+ X86_MATCH_FEATURE(X86_FEATURE_SMX, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(x86cpu, smx_cpu_id);
+
+static int __init txt_securityfs_init(void)
+{
+ int i;
+ int err;
+
+ if (!x86_match_cpu(smx_cpu_id))
+ return -ENODEV;
+
+ txt_pdev = platform_device_register_simple(DEV_NAME, -1, NULL, 0);
+ if (IS_ERR(txt_pdev))
+ return PTR_ERR(txt_pdev);
+
+ txt_pub_regs = devm_ioremap(&txt_pdev->dev, TXT_PUB_CONFIG_REGS_BASE,
+ TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+ if (!txt_pub_regs)
+ goto out;
+
+ txt_dir = securityfs_create_dir("intel-txt", NULL);
+ if (IS_ERR(txt_dir)) {
+ err = PTR_ERR(txt_dir);
+ txt_dir = NULL;
+ goto out;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(txt_securityfs_files); i++) {
+ txt_securityfs_files[i].dentry = securityfs_create_file(
+ txt_securityfs_files[i].name, 0444, txt_dir,
+ &txt_securityfs_files[i],
+ &txt_pub_reg_fops);
+ if (IS_ERR(txt_securityfs_files[i].dentry)) {
+ err = PTR_ERR(txt_securityfs_files[i].dentry);
+ txt_securityfs_files[i].dentry = NULL;
+ goto out;
+ }
+ }
+
+ return 0;
+out:
+ for (i = 0; i < ARRAY_SIZE(txt_securityfs_files); i++) {
+ if (txt_securityfs_files[i].dentry != NULL)
+ securityfs_remove(txt_securityfs_files[i].dentry);
+ }
+ if (txt_dir)
+ securityfs_remove(txt_dir);
+ platform_device_unregister(txt_pdev);
+ return err;
+}
+
+static void __exit txt_securityfs_exit(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(txt_securityfs_files); i++) {
+ if (txt_securityfs_files[i].dentry != NULL)
+ securityfs_remove(txt_securityfs_files[i].dentry);
+ }
+ securityfs_remove(txt_dir);
+ platform_device_unregister(txt_pdev);
+}
+
+module_init(txt_securityfs_init);
+module_exit(txt_securityfs_exit);
+
+MODULE_LICENSE("GPL");
--
2.34.1