2013-05-07 07:05:05

by Ren Qiaowei

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

This module is expected to be a better tool to access below resources
- TXT config space
- Tboot log mem
- 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 <http://www.intel.com/technology/security/> for more information
about Intel(R) 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.

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

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

Documentation/ABI/testing/sysfs-platform-intel-txt | 402 ++++++++
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/Makefile | 1 +
drivers/platform/x86/intel_txt/Kconfig | 17 +
drivers/platform/x86/intel_txt/Makefile | 5 +
drivers/platform/x86/intel_txt/txt-config.c | 1032 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-config.h | 138 +++
drivers/platform/x86/intel_txt/txt-log.c | 131 +++
drivers/platform/x86/intel_txt/txt-log.h | 27 +
drivers/platform/x86/intel_txt/txt-parameter.c | 253 +++++
drivers/platform/x86/intel_txt/txt-parameter.h | 40 +
drivers/platform/x86/intel_txt/txt-sysfs.c | 60 ++
12 files changed, 2108 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-log.c
create mode 100644 drivers/platform/x86/intel_txt/txt-log.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-07 07:05:18

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH 4/4] 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.

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 | 65 +++++
drivers/platform/x86/intel_txt/Makefile | 2 +-
drivers/platform/x86/intel_txt/txt-parameter.c | 253 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-parameter.h | 40 ++++
drivers/platform/x86/intel_txt/txt-sysfs.c | 5 +
5 files changed, 364 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 ccacac3..c2f9720 100644
--- a/Documentation/ABI/testing/sysfs-platform-intel-txt
+++ b/Documentation/ABI/testing/sysfs-platform-intel-txt
@@ -335,3 +335,68 @@ Contact: "Qiaowei Ren" <[email protected]>
Description: The "block_index" property allows you to set the block
index for output.

+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.
+
+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 external memory
+ types supported during AC mode.
+
+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 2265370..5914c11 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 txt-log.o
+intel_txt-y := txt-sysfs.o txt-config.o txt-log.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..b8be55e
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-parameter.c
@@ -0,0 +1,253 @@
+/*
+ * txt-parameter.c
+ *
+ * specific parameter information for SMX features supported by the processor.
+ *
+ * - 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 = 0, ebx = 0, ecx = 0;
+
+ __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
+ : "=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;
+
+ write_cr4(read_cr4() | CR4_SMXE);
+
+ 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;
+
+ sscanf(buf, "%d", &index);
+
+ 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);
+}
+EXPORT_SYMBOL_GPL(sysfs_create_parameter);
+
+MODULE_LICENSE("GPL");
+
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..cdd681f
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-parameter.h
@@ -0,0 +1,40 @@
+#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_OPCODE ".byte 0x0f,0x37"
+#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 af556b6..7d4f111 100644
--- a/drivers/platform/x86/intel_txt/txt-sysfs.c
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -17,6 +17,7 @@

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

#define DEV_NAME "intel_txt"
static struct platform_device *txt_pdev;
@@ -37,6 +38,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-07 07:05:15

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH 2/4] 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 | 1032 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-config.h | 138 +++
drivers/platform/x86/intel_txt/txt-sysfs.c | 12 +
5 files changed, 1492 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..34311a2
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-config.c
@@ -0,0 +1,1032 @@
+/*
+ * 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);
+}
+EXPORT_SYMBOL_GPL(sysfs_create_config);
+
+MODULE_LICENSE("GPL");
+
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 96efe87..28cc8a2 100644
--- a/drivers/platform/x86/intel_txt/txt-sysfs.c
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -15,16 +15,28 @@
#include <linux/platform_device.h>
#include <linux/sysfs.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;
+
txt_pdev = platform_device_register_simple(DEV_NAME, -1, NULL, 0);
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-07 07:05:12

by Ren Qiaowei

[permalink] [raw]
Subject: [PATCH 3/4] driver: provide sysfs interfaces to access TXT log

These interfaces are located in /sys/devices/platform/intel_txt/log/.

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 | 28 +++++
drivers/platform/x86/intel_txt/Makefile | 2 +-
drivers/platform/x86/intel_txt/txt-log.c | 131 ++++++++++++++++++++
drivers/platform/x86/intel_txt/txt-log.h | 27 ++++
drivers/platform/x86/intel_txt/txt-sysfs.c | 5 +
5 files changed, 192 insertions(+), 1 deletion(-)
create mode 100644 drivers/platform/x86/intel_txt/txt-log.c
create mode 100644 drivers/platform/x86/intel_txt/txt-log.h

diff --git a/Documentation/ABI/testing/sysfs-platform-intel-txt b/Documentation/ABI/testing/sysfs-platform-intel-txt
index fa20a9f..ccacac3 100644
--- a/Documentation/ABI/testing/sysfs-platform-intel-txt
+++ b/Documentation/ABI/testing/sysfs-platform-intel-txt
@@ -307,3 +307,31 @@ 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/log/
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The log/ directory exposes tboot log memory.
+
+What: /sys/devices/platform/intel_txt/log/log_header
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "log_header" property will output log header, including
+ max_size and curr_pos.
+
+What: /sys/devices/platform/intel_txt/log/block
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "block" property will dump pure log in block style,
+ 1 page size.
+
+What: /sys/devices/platform/intel_txt/log/block_index
+Date: May 2013
+KernelVersion: 3.9
+Contact: "Qiaowei Ren" <[email protected]>
+Description: The "block_index" property allows you to set the block
+ index for output.
+
diff --git a/drivers/platform/x86/intel_txt/Makefile b/drivers/platform/x86/intel_txt/Makefile
index 8d5258e..2265370 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-log.o
diff --git a/drivers/platform/x86/intel_txt/txt-log.c b/drivers/platform/x86/intel_txt/txt-log.c
new file mode 100644
index 0000000..3f0f91d
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-log.c
@@ -0,0 +1,131 @@
+/*
+ * txt-log.c
+ *
+ * - log/
+ * log_header -r--r--r-- ; output log header, including max_size and
+ * curr_pos.
+ * block -r--r--r-- ; output pure log in block style, 1 page size.
+ * block_index -rw-rw-r-- ; the block index for output.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+#include <linux/io.h>
+#include <linux/stat.h>
+
+#include "txt-log.h"
+
+static u32 log_block_index;
+
+static int are_uuids_equal(const struct uuid *uuid1,
+ const struct uuid *uuid2)
+{
+ return (memcmp(uuid1, uuid2, sizeof(*uuid1)) == 0) ? 1 : 0;
+}
+
+static struct tboot_log *get_log(void)
+{
+ struct tboot_log *log;
+
+ log = (struct tboot_log *)ioremap_nocache(TBOOT_SERIAL_LOG_ADDR,
+ TBOOT_SERIAL_LOG_SIZE);
+ if (!log)
+ return NULL;
+
+ if (!are_uuids_equal(&(log->uuid),
+ &((struct uuid)TBOOT_LOG_UUID))) {
+ iounmap(log);
+ return NULL;
+ }
+
+ return log;
+}
+
+ssize_t txt_show_log_header(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tboot_log *log;
+ int ret;
+
+ log = get_log();
+ if (!log)
+ return -EFAULT;
+
+ ret = scnprintf(buf, PAGE_SIZE, "max_size: %x\ncurr_pos: %x\n",
+ log->max_size, log->curr_pos);
+
+ iounmap(log);
+ return ret;
+}
+static DEVICE_ATTR(log_header, S_IRUGO, txt_show_log_header, NULL);
+
+ssize_t txt_show_block(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct tboot_log *log;
+ char *block;
+ int ret;
+
+ log = get_log();
+ if (!log)
+ return -EFAULT;
+
+ block = log->buf + log_block_index * PAGE_SIZE;
+ ret = scnprintf(buf, PAGE_SIZE, "%s\n", block);
+
+ iounmap(log);
+ return ret;
+}
+static DEVICE_ATTR(block, S_IRUGO, txt_show_block, NULL);
+
+ssize_t txt_show_block_index(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", log_block_index);
+}
+
+ssize_t txt_store_block_index(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 index;
+ struct tboot_log *log;
+
+ log = get_log();
+ if (!log)
+ return -EFAULT;
+
+ sscanf(buf, "%d", &index);
+ if (index > log->curr_pos / PAGE_SIZE)
+ return -EINVAL;
+ log_block_index = index;
+
+ iounmap(log);
+ return count;
+}
+static DEVICE_ATTR(block_index, S_IRUGO | S_IWUSR | S_IWGRP,
+ txt_show_block_index, txt_store_block_index);
+
+static struct attribute *log_attrs[] = {
+ &dev_attr_log_header.attr,
+ &dev_attr_block.attr,
+ &dev_attr_block_index.attr,
+ NULL,
+};
+
+static struct attribute_group log_attr_grp = {
+ .name = "log",
+ .attrs = log_attrs
+};
+
+int sysfs_create_log(struct kobject *parent)
+{
+ return sysfs_create_group(parent, &log_attr_grp);
+}
+EXPORT_SYMBOL_GPL(sysfs_create_log);
+
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/platform/x86/intel_txt/txt-log.h b/drivers/platform/x86/intel_txt/txt-log.h
new file mode 100644
index 0000000..7eb835e
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-log.h
@@ -0,0 +1,27 @@
+#ifndef __LOG_H__
+#define __LOG_H__
+
+struct uuid {
+ uint32_t data1;
+ uint16_t data2;
+ uint16_t data3;
+ uint16_t data4;
+ uint8_t data5[6];
+} __packed;
+
+struct tboot_log {
+ struct uuid uuid;
+ uint32_t max_size;
+ uint32_t curr_pos;
+ char buf[];
+};
+
+#define TBOOT_LOG_UUID {0xc0192526, 0x6b30, 0x4db4, 0x844c, \
+ {0xa3, 0xe9, 0x53, 0xb8, 0x81, 0x74} }
+#define TBOOT_SERIAL_LOG_ADDR 0x60000
+#define TBOOT_SERIAL_LOG_SIZE 0x08000
+
+extern int sysfs_create_log(struct kobject *parent);
+
+#endif /* __LOG_H__ */
+
diff --git a/drivers/platform/x86/intel_txt/txt-sysfs.c b/drivers/platform/x86/intel_txt/txt-sysfs.c
index 28cc8a2..af556b6 100644
--- a/drivers/platform/x86/intel_txt/txt-sysfs.c
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -16,6 +16,7 @@
#include <linux/sysfs.h>

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

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

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

err:
--
1.7.9.5

2013-05-07 07:05:07

by Ren Qiaowei

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

TXT driver is expected to be a better tool to access below resources:
TXT config space, TXT log and SMX parameter.

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 | 17 +++++++++++++
drivers/platform/x86/intel_txt/Makefile | 5 ++++
drivers/platform/x86/intel_txt/txt-sysfs.c | 38 ++++++++++++++++++++++++++++
5 files changed, 63 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..ddf8b03
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/Kconfig
@@ -0,0 +1,17 @@
+#
+# intel TXT driver configuration
+#
+
+config INTEL_TXT_DRIVER
+ tristate "INTEL TXT sysfs driver"
+ default m
+ depends on INTEL_TXT
+ select SECURITYFS
+ ---help---
+ TXT Driver is expected to be a better tool to access below resources:
+ - TXT config space
+ - Tboot log mem
+ - SMX parameter
+
+ To compile this driver as a module, choose M here; the module will be
+ called 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..96efe87
--- /dev/null
+++ b/drivers/platform/x86/intel_txt/txt-sysfs.c
@@ -0,0 +1,38 @@
+/*
+ * txt-sysfs.c
+ *
+ * This module is expected to be a better tool to access below resources
+ * - TXT config space
+ * - Tboot log mem
+ * - SMX parameter
+ *
+ * Data is currently found below
+ * /sys/devices/platform/intel_txt/...
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+
+#define DEV_NAME "intel_txt"
+static struct platform_device *txt_pdev;
+
+static int __init txt_sysfs_init(void)
+{
+ 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-08 02:30:05

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH 0/4] Intel TXT driver

On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
> This module is expected to be a better tool to access below resources
> - TXT config space
> - Tboot log mem
> - SMX parameter

What's SMX?

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

2013-05-08 02:33:59

by Matthew Garrett

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

On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
> TXT driver is expected to be a better tool to access below resources:
> TXT config space, TXT log and SMX parameter.

Please explain what these things are in the commit log, the config help
and the comment at the top of the driver - it'll make things easier for
people later.

> + To compile this driver as a module, choose M here; the module will be
> + called txt.

That's an awfully generic name. intel_txt would be better.

> + * This module is expected to be a better tool to access below resources

Expected to be or is? :)

> + * Data is currently found below

You're adding it to ABI, so it shouldn't just be current - are you
planning on moving it at any point? Is this functionality that should be
under securityfs instead?

> + txt_pdev = platform_device_register_simple(DEV_NAME, -1, NULL, 0);

This will register even if there's no TXT support on the platform,
right? Is there no mechanism for determining whether a platform has TXT
support before registering a device?

> +module_init(txt_sysfs_init);
> +module_exit(txt_sysfs_exit);

And you've got no module aliases, so this will never be autoloaded. How
does the OS know that the platform implements TXT?

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

2013-05-08 02:44:58

by Matthew Garrett

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

On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:

> + 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.

Is userspace ever going to be running in this situation?

> +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.

AC? MLE?

> +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.

All of which threads? It might be worth adding a general introduction to
TXT in Documentation and referencing it in these entries.

> +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.

It will? When will it be clear? What would userspace ever want this for?

> +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.

Why would userspace ever care about this?

> +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.

Or this?

> +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].

RLPs?

> +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.

Again, it doesn't seem obvious why userspace would ever want this...

> +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.

Or this.

Basically, don't just define what these files do - make it clear why
they'd be used. Right now I have no idea whether these are diagnostic,
likely to be used during runtime or basically completely useless.

> +static ssize_t txt_show_ERRORCODE(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + return show_config(buf, off_ERRORCODE);
> +}

Much as I usually hate it, these all seem pretty boilerplate. It would
arguably be cleaner to replace them all with something like:

#define config_func(x) static size_t txt_show_x(struct device *dev,
struct device_attribute *attr, char *buf) { return show_config(buf
off_x);}\ntxt_store_x(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) { blah blah

config_func(ERRORCODE)
config_func(ESTS_raw)

and so on.

> +int sysfs_create_config(struct kobject *parent)
> +{
> + return sysfs_create_group(parent, &config_attr_grp);
> +}
> +EXPORT_SYMBOL_GPL(sysfs_create_config);

This doesn't seem right. You're linking this into the existing txt
module - you don't need to export symbols.

> +MODULE_LICENSE("GPL");

Or declare a module license.

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

2013-05-08 05:16:53

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH 3/4] driver: provide sysfs interfaces to access TXT log

On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:

> +What: /sys/devices/platform/intel_txt/log/log_header
> +Date: May 2013
> +KernelVersion: 3.9

How different are these logs to the TPM measurements exported via
securityfs?

> +What: /sys/devices/platform/intel_txt/log/block_index
> +Date: May 2013
> +KernelVersion: 3.9
> +Contact: "Qiaowei Ren" <[email protected]>
> +Description: The "block_index" property allows you to set the block
> + index for output.

So I write a value here and then I see different chunks of log? This
doesn't seem like an optimal interface. What do these logs actually
contain? How do I know which block I should be reading?

> +static int are_uuids_equal(const struct uuid *uuid1,
> + const struct uuid *uuid2)
> +{
> + return (memcmp(uuid1, uuid2, sizeof(*uuid1)) == 0) ? 1 : 0;
> +}

Use one of the uuidcmp functions from uuid.h?

> +EXPORT_SYMBOL_GPL(sysfs_create_log);
> +
> +MODULE_LICENSE("GPL");

Same as for the previous patch - you don't need these.

> +struct uuid {
> + uint32_t data1;
> + uint16_t data2;
> + uint16_t data3;
> + uint16_t data4;
> + uint8_t data5[6];
> +} __packed;

There's already UUID structures in uuid.h

> +#define TBOOT_LOG_UUID {0xc0192526, 0x6b30, 0x4db4, 0x844c, \
> + {0xa3, 0xe9, 0x53, 0xb8, 0x81, 0x74} }

uuid.h again.

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

2013-05-08 05:25:09

by Matthew Garrett

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

On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
> These interfaces are located in /sys/devices/platform/intel_txt/parameter/,
> showing specific parameter information for SMX features supported by
> the processor.

Explain what SMX is here.

> +Contact: "Qiaowei Ren" <[email protected]>
> +Description: The parameter/ directory exposes specific parameter
> + information for SMX features supported by the processor.

Also here.

> +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 would userspace use this for?

> +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 external memory
> + types supported during AC mode.

Or this? And what's AC mode?

> +static void __getsec_parameters(uint32_t index, int *param_type,
> + uint32_t *peax, uint32_t *pebx,
> + uint32_t *pecx)
> +{
> + uint32_t eax = 0, ebx = 0, ecx = 0;

These are all going to be overwritten by the getsec operation? Do they
really need to be initialised?

> + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
> + : "=a"(eax), "=b"(ebx), "=c"(ecx)
> + : "a"(IA32_GETSEC_PARAMETERS), "b"(index));
> +
> + *param_type = eax & 0x1f;
> + *peax = eax;
> + *pebx = ebx;
> + *pecx = ecx;

Should there be a check for failure here? Is it possible for this
operation to fail?

> + write_cr4(read_cr4() | CR4_SMXE);

Whoo. This needs at least a giant comment and probably some locking, but
if this is supposed to be set during runtime then it should be done in
core architecture code rather than just in this driver.

> + sscanf(buf, "%d", &index);

What if this fails?

> +EXPORT_SYMBOL_GPL(sysfs_create_parameter);
> +
> +MODULE_LICENSE("GPL");

Not needed.

> +#define IA32_GETSEC_OPCODE ".byte 0x0f,0x37"

Nnf. Does the assembler really not know about this instruction?

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

2013-05-09 08:05:34

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH 3/4] driver: provide sysfs interfaces to access TXT log

On 2013-05-08, Matthew Garrett wrote:
> On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
>
>> +What: /sys/devices/platform/intel_txt/log/log_header
>> +Date: May 2013
>> +KernelVersion: 3.9
>
> How different are these logs to the TPM measurements exported via
> securityfs?

These logs come from tboot (Trusted Boot, an open source, pre-kernel/VMM module that uses Intel® Trusted Execution Technology (Intel® TXT) to perform a measured and verified launch of an OS kernel/VMM.), and should be different from those TPM measurements (from BIOS?) exported via security.

>> +What: /sys/devices/platform/intel_txt/log/block_index
>> +Date: May 2013
>> +KernelVersion: 3.9
>> +Contact: "Qiaowei Ren" <[email protected]>
>> +Description: The "block_index" property allows you to set the block
>> + index for output.
>
> So I write a value here and then I see different chunks of log? This
> doesn't seem like an optimal interface. What do these logs actually
> contain? How do I know which block I should be reading?

Yes. Since total log size is bigger than one page 4K, the log have to be displayed in 4K-block indexed by block_index.
These logs will be very helpful for txt related debugging.

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

2013-05-09 08:19:59

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH 0/4] Intel TXT driver

On 2013-05-08, Matthew Garrett wrote:
> On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
>> This module is expected to be a better tool to access below resources
>> - TXT config space
>> - Tboot log mem
>> - SMX parameter
>
> What's SMX?

Safer Mode Extensions (SMX) provide a programming interface for system software to establish a measured environment within the platform to support trust decisions by end users. SMX functionality is provided in an Intel 64 processor through the GETSEC instruction via leaf functions.

Thanks,
Qiaowei

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

2013-05-09 12:02:25

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH 3/4] driver: provide sysfs interfaces to access TXT log

On Thu, 2013-05-09 at 08:05 +0000, Ren, Qiaowei wrote:
> On 2013-05-08, Matthew Garrett wrote:
> > How different are these logs to the TPM measurements exported via
> > securityfs?
>
> These logs come from tboot (Trusted Boot, an open source, pre-kernel/VMM module that uses Intel® Trusted Execution Technology (Intel® TXT) to perform a measured and verified launch of an OS kernel/VMM.), and should be different from those TPM measurements (from BIOS?) exported via security.

Different in what way? What are they actually logging?

> > So I write a value here and then I see different chunks of log? This
> > doesn't seem like an optimal interface. What do these logs actually
> > contain? How do I know which block I should be reading?
>
> Yes. Since total log size is bigger than one page 4K, the log have to be displayed in 4K-block indexed by block_index.
> These logs will be very helpful for txt related debugging.

If they're only intended for debugging then sysfs probably isn't the
best place for them. debugfs might make more sense.

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

2013-05-09 12:03:29

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH 0/4] Intel TXT driver

On Thu, 2013-05-09 at 08:19 +0000, Ren, Qiaowei wrote:
> On 2013-05-08, Matthew Garrett wrote:
> > On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
> >> This module is expected to be a better tool to access below resources
> >> - TXT config space
> >> - Tboot log mem
> >> - SMX parameter
> >
> > What's SMX?
>
> Safer Mode Extensions (SMX) provide a programming interface for system software to establish a measured environment within the platform to support trust decisions by end users. SMX functionality is provided in an Intel 64 processor through the GETSEC instruction via leaf functions.

Great. Can you include that in the patches and help text?

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

2013-05-10 01:50:16

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH 3/4] driver: provide sysfs interfaces to access TXT log

On 2013-05-09, Matthew Garrett wrote:
> On Thu, 2013-05-09 at 08:05 +0000, Ren, Qiaowei wrote:
> > On 2013-05-08, Matthew Garrett wrote:
> > > How different are these logs to the TPM measurements exported via
> > > securityfs?
> >
> > These logs come from tboot (Trusted Boot, an open source, pre-kernel/VMM
> module that uses Intel® Trusted Execution Technology (Intel® TXT) to perform a
> measured and verified launch of an OS kernel/VMM.), and should be different
> from those TPM measurements (from BIOS?) exported via security.
>
> Different in what way? What are they actually logging?

Tboot log should also contain txt heap memory content, a lot of event log, etc.

> > > So I write a value here and then I see different chunks of log? This
> > > doesn't seem like an optimal interface. What do these logs actually
> > > contain? How do I know which block I should be reading?
> >
> > Yes. Since total log size is bigger than one page 4K, the log have to be
> displayed in 4K-block indexed by block_index.
> > These logs will be very helpful for txt related debugging.
>
> If they're only intended for debugging then sysfs probably isn't the best place
> for them. debugfs might make more sense.

Yes. Debugfs seems to be better choice. Maybe we need to further consider the purpose of outputting tboot log. So I will temporarily remove this feature from this patch.

Thanks,
Qiaowei

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

2013-05-10 02:21:08

by Ren Qiaowei

[permalink] [raw]
Subject: RE: [PATCH 0/4] Intel TXT driver

On 2013-05-09, Matthew Garrett wrote:
> On Thu, 2013-05-09 at 08:19 +0000, Ren, Qiaowei wrote:
> > On 2013-05-08, Matthew Garrett wrote:
> > > On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
> > >> This module is expected to be a better tool to access below resources
> > >> - TXT config space
> > >> - Tboot log mem
> > >> - SMX parameter
> > >
> > > What's SMX?
> >
> > Safer Mode Extensions (SMX) provide a programming interface for system
> software to establish a measured environment within the platform to support
> trust decisions by end users. SMX functionality is provided in an Intel 64
> processor through the GETSEC instruction via leaf functions.
>
> Great. Can you include that in the patches and help text?

Ok.

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

2013-05-10 03:38:12

by Ren Qiaowei

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

On 2013-05-08, Matthew Garrett wrote:
> On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
>
> > + * This module is expected to be a better tool to access below
> > + resources
>
> Expected to be or is? :)

"is" :)

> > + * Data is currently found below
>
> You're adding it to ABI, so it shouldn't just be current - are you planning on
> moving it at any point? Is this functionality that should be under securityfs
> instead?
>
> > + txt_pdev = platform_device_register_simple(DEV_NAME, -1, NULL, 0);
>
> This will register even if there's no TXT support on the platform, right? Is there
> no mechanism for determining whether a platform has TXT support before
> registering a device?
>
> > +module_init(txt_sysfs_init);
> > +module_exit(txt_sysfs_exit);
>
> And you've got no module aliases, so this will never be autoloaded. How does
> the OS know that the platform implements TXT?

Currently this driver only depends on CONFIG_INTEL_TXT, which is the kernel option for enabling Intel TXT support. And there is no explicit interface to check whether txt is supported in this txt enabling part of kernel. But since the tboot code will detect whether the platform actually supports Intel TXT, and so tboot_enabled() in include/linux/tboot.h may be used to determine whether a platform has TXT support.

In fact, we may also check CPU feature ECX[6] (SMX) for this purpose.

Thanks,
Qiaowei

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

2013-05-10 07:05:58

by Ren Qiaowei

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

On 2013-05-08, Matthew Garrett wrote:
> On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
>
> > +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 would userspace use this for?

These sysfs files are just export SMX & TXT related information to userspace. So that other developers (or OSV & ISV) can be able to develop txt related applications or tools based on these information.

> > +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 external memory
> > + types supported during AC mode.
>
> Or this? And what's AC mode?

It means that the property will show supportable memory types for memory mapped outside of the authenticated code execution area.

> > + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n"
> > + : "=a"(eax), "=b"(ebx), "=c"(ecx)
> > + : "a"(IA32_GETSEC_PARAMETERS), "b"(index));
> > +
> > + *param_type = eax & 0x1f;
> > + *peax = eax;
> > + *pebx = ebx;
> > + *pecx = ecx;
>
> Should there be a check for failure here? Is it possible for this operation to fail?

You mean GETSEC instruction? I don't notice related description in manual. Next function get_parameters() will process return eax/ebx/ecx returned by this instruction.

> > + write_cr4(read_cr4() | CR4_SMXE);
>
> Whoo. This needs at least a giant comment and probably some locking, but if
> this is supposed to be set during runtime then it should be done in core
> architecture code rather than just in this driver.

Oh. This code should be removed, because tboot code have set SMXE bit.

Thanks,
Qiaowei

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

2013-05-10 13:08:54

by Matthew Garrett

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

On Fri, 2013-05-10 at 07:05 +0000, Ren, Qiaowei wrote:
> On 2013-05-08, Matthew Garrett wrote:
> > On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
> >
> > > +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 would userspace use this for?
>
> These sysfs files are just export SMX & TXT related information to userspace. So that other developers (or OSV & ISV) can be able to develop txt related applications or tools based on these information.

If they're only using it for debugging purposes then sysfs probably
isn't the right place. Is there any reason tools would need to know this
during normal usage?

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

2013-05-11 00:01:47

by Ren Qiaowei

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

On 2013-05-10, Matthew Garrett wrote:
> On Fri, 2013-05-10 at 07:05 +0000, Ren, Qiaowei wrote:
>> On 2013-05-08, Matthew Garrett wrote:
>>> On Tue, 2013-05-07 at 22:55 +0800, Qiaowei Ren wrote:
>>>
>>>> +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 would userspace use this for?
>>
>> These sysfs files are just export SMX & TXT related information to userspace.
> So that other developers (or OSV & ISV) can be able to develop txt
> related applications or tools based on these information.
>
> If they're only using it for debugging purposes then sysfs probably
> isn't the right place. Is there any reason tools would need to know this during normal usage?

Unlike tboot log, these properties are not used for debugging purposes.
They are used to report attributes, options and limitations of SMX operation. Software may use them to identify operations limits or additional options.

Thanks,
Qiaowei

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