From: Dan Williams <dan.j.williams@intel.com>
To: <linux-coco@lists.linux.dev>
Cc: <cedric.xing@intel.com>
Subject: [PATCH v8 1/7] tsm-mr: Add TVM Measurement Register support
Date: Thu, 8 May 2025 19:07:39 -0700 [thread overview]
Message-ID: <20250509020739.882913-1-dan.j.williams@intel.com> (raw)
In-Reply-To: <20250509010104.669669-1-dan.j.williams@intel.com>
From: Cedric Xing <cedric.xing@intel.com>
Introduce new TSM Measurement helper library (tsm-mr) for TVM guest drivers
to expose MRs (Measurement Registers) as sysfs attributes, with Crypto
Agility support.
Add the following new APIs (see include/linux/tsm-mr.h for details):
- tsm_mr_create_attribute_group(): Take on input a `struct
tsm_measurements` instance, which includes one `struct
tsm_measurement_register` per MR with properties like `TSM_MR_F_READABLE`
and `TSM_MR_F_WRITABLE`, to determine the supported operations and create
the sysfs attributes accordingly. On success, return a `struct
attribute_group` instance that will typically be included by the guest
driver into `miscdevice.groups` before calling misc_register().
- tsm_mr_free_attribute_group(): Free the memory allocated to the attrubute
group returned by tsm_mr_create_attribute_group().
tsm_mr_create_attribute_group() creates one attribute for each MR, with
names following this pattern:
MRNAME[:HASH]
- MRNAME - Placeholder for the MR name, as specified by
`tsm_measurement_register.mr_name`.
- :HASH - Optional suffix indicating the hash algorithm associated with
this MR, as specified by `tsm_measurement_register.mr_hash`.
Support Crypto Agility by allowing multiple definitions of the same MR
(i.e., with the same `mr_name`) with distinct HASH algorithms.
NOTE: Crypto Agility, introduced in TPM 2.0, allows new hash algorithms to
be introduced without breaking compatibility with applications using older
algorithms. CC architectures may face the same challenge in the future,
needing new hashes for security while retaining compatibility with older
hashes, hence the need for Crypto Agility.
Signed-off-by: Cedric Xing <cedric.xing@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Dionna Amalie Glaze <dionnaglaze@google.com>
[djbw: fixup bin_attr const conflict]
Link: https://patch.msgid.link/20250509010104.669669-1-dan.j.williams@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
Changes since v7:
* move to bin_attr_new so that this change compiles on both pre and post
'constify bin_attr' baselines
Documentation/driver-api/coco/index.rst | 12 +
.../driver-api/coco/measurement-registers.rst | 12 +
Documentation/driver-api/index.rst | 1 +
MAINTAINERS | 5 +-
drivers/virt/coco/Kconfig | 5 +
drivers/virt/coco/Makefile | 1 +
drivers/virt/coco/tsm-mr.c | 251 ++++++++++++++++++
include/linux/tsm-mr.h | 89 +++++++
include/trace/events/tsm_mr.h | 80 ++++++
9 files changed, 454 insertions(+), 2 deletions(-)
create mode 100644 Documentation/driver-api/coco/index.rst
create mode 100644 Documentation/driver-api/coco/measurement-registers.rst
create mode 100644 drivers/virt/coco/tsm-mr.c
create mode 100644 include/linux/tsm-mr.h
create mode 100644 include/trace/events/tsm_mr.h
diff --git a/Documentation/driver-api/coco/index.rst b/Documentation/driver-api/coco/index.rst
new file mode 100644
index 000000000000..af9f08ca0cfd
--- /dev/null
+++ b/Documentation/driver-api/coco/index.rst
@@ -0,0 +1,12 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+======================
+Confidential Computing
+======================
+
+.. toctree::
+ :maxdepth: 1
+
+ measurement-registers
+
+.. only:: subproject and html
diff --git a/Documentation/driver-api/coco/measurement-registers.rst b/Documentation/driver-api/coco/measurement-registers.rst
new file mode 100644
index 000000000000..cef85945a9a7
--- /dev/null
+++ b/Documentation/driver-api/coco/measurement-registers.rst
@@ -0,0 +1,12 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: <isonum.txt>
+
+=====================
+Measurement Registers
+=====================
+
+.. kernel-doc:: include/linux/tsm-mr.h
+ :internal:
+
+.. kernel-doc:: drivers/virt/coco/tsm-mr.c
+ :export:
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index 16e2c4ec3c01..3e2a270bd828 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -81,6 +81,7 @@ Subsystem-specific APIs
acpi/index
backlight/lp855x-driver.rst
clk
+ coco/index
console
crypto/index
dmaengine/index
diff --git a/MAINTAINERS b/MAINTAINERS
index 69511c3b2b76..5d36823d26b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24648,8 +24648,9 @@ M: Dan Williams <dan.j.williams@intel.com>
L: linux-coco@lists.linux.dev
S: Maintained
F: Documentation/ABI/testing/configfs-tsm
-F: drivers/virt/coco/tsm.c
-F: include/linux/tsm.h
+F: Documentation/driver-api/coco/
+F: drivers/virt/coco/tsm*.c
+F: include/linux/tsm*.h
TRUSTED SERVICES TEE DRIVER
M: Balint Dobszay <balint.dobszay@arm.com>
diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
index ff869d883d95..737106d5dcbc 100644
--- a/drivers/virt/coco/Kconfig
+++ b/drivers/virt/coco/Kconfig
@@ -7,6 +7,11 @@ config TSM_REPORTS
select CONFIGFS_FS
tristate
+config TSM_MEASUREMENTS
+ select CRYPTO_HASH_INFO
+ select CRYPTO
+ bool
+
source "drivers/virt/coco/efi_secret/Kconfig"
source "drivers/virt/coco/pkvm-guest/Kconfig"
diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile
index c3d07cfc087e..eb6ec5c1d2e1 100644
--- a/drivers/virt/coco/Makefile
+++ b/drivers/virt/coco/Makefile
@@ -3,6 +3,7 @@
# Confidential computing related collateral
#
obj-$(CONFIG_TSM_REPORTS) += tsm.o
+obj-$(CONFIG_TSM_MEASUREMENTS) += tsm-mr.o
obj-$(CONFIG_EFI_SECRET) += efi_secret/
obj-$(CONFIG_ARM_PKVM_GUEST) += pkvm-guest/
obj-$(CONFIG_SEV_GUEST) += sev-guest/
diff --git a/drivers/virt/coco/tsm-mr.c b/drivers/virt/coco/tsm-mr.c
new file mode 100644
index 000000000000..1f0c43a516fb
--- /dev/null
+++ b/drivers/virt/coco/tsm-mr.c
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2024-2025 Intel Corporation. All rights reserved. */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/tsm_mr.h>
+
+/*
+ * struct tm_context - contains everything necessary to implement sysfs
+ * attributes for MRs.
+ * @rwsem: protects the MR cache from concurrent access.
+ * @agrp: contains all MR attributes created by tsm_mr_create_attribute_group().
+ * @tm: input to tsm_mr_create_attribute_group() containing MR definitions/ops.
+ * @in_sync: %true if MR cache is up-to-date.
+ * @mrs: array of &struct bin_attribute, one for each MR.
+ *
+ * This internal structure contains everything needed to implement
+ * tm_digest_read() and tm_digest_write().
+ *
+ * Given tm->refresh() is potentially expensive, tm_digest_read() caches MR
+ * values and calls tm->refresh() only when necessary. Only live MRs (i.e., with
+ * %TSM_MR_F_LIVE set) can trigger tm->refresh(), while others are assumed to
+ * retain their values from the last tm->write(). @in_sync tracks if there have
+ * been tm->write() calls since the last tm->refresh(). That is, tm->refresh()
+ * will be called only when a live MR is being read and the cache is stale
+ * (@in_sync is %false).
+ *
+ * tm_digest_write() sets @in_sync to %false and calls tm->write(), whose
+ * semantics is arch and MR specific. Most (if not all) writable MRs support the
+ * extension semantics (i.e., tm->write() extends the input buffer into the MR).
+ */
+struct tm_context {
+ struct rw_semaphore rwsem;
+ struct attribute_group agrp;
+ const struct tsm_measurements *tm;
+ bool in_sync;
+ struct bin_attribute mrs[];
+};
+
+static ssize_t tm_digest_read(struct file *filp, struct kobject *kobj,
+ const struct bin_attribute *attr, char *buffer,
+ loff_t off, size_t count)
+{
+ struct tm_context *ctx;
+ const struct tsm_measurement_register *mr;
+ int rc;
+
+ ctx = attr->private;
+ rc = down_read_interruptible(&ctx->rwsem);
+ if (rc)
+ return rc;
+
+ mr = &ctx->tm->mrs[attr - ctx->mrs];
+
+ /*
+ * @ctx->in_sync indicates if the MR cache is stale. It is a global
+ * instead of a per-MR flag for simplicity, as most (if not all) archs
+ * allow reading all MRs in oneshot.
+ *
+ * ctx->refresh() is necessary only for LIVE MRs, while others retain
+ * their values from their respective last ctx->write().
+ */
+ if ((mr->mr_flags & TSM_MR_F_LIVE) && !ctx->in_sync) {
+ up_read(&ctx->rwsem);
+
+ rc = down_write_killable(&ctx->rwsem);
+ if (rc)
+ return rc;
+
+ if (!ctx->in_sync) {
+ rc = ctx->tm->refresh(ctx->tm);
+ ctx->in_sync = !rc;
+ trace_tsm_mr_refresh(mr, rc);
+ }
+
+ downgrade_write(&ctx->rwsem);
+ }
+
+ memcpy(buffer, mr->mr_value + off, count);
+ trace_tsm_mr_read(mr);
+
+ up_read(&ctx->rwsem);
+ return rc ?: count;
+}
+
+static ssize_t tm_digest_write(struct file *filp, struct kobject *kobj,
+ const struct bin_attribute *attr, char *buffer,
+ loff_t off, size_t count)
+{
+ struct tm_context *ctx;
+ const struct tsm_measurement_register *mr;
+ ssize_t rc;
+
+ /* partial writes are not supported */
+ if (off != 0 || count != attr->size)
+ return -EINVAL;
+
+ ctx = attr->private;
+ mr = &ctx->tm->mrs[attr - ctx->mrs];
+
+ rc = down_write_killable(&ctx->rwsem);
+ if (rc)
+ return rc;
+
+ rc = ctx->tm->write(ctx->tm, mr, buffer);
+
+ /* mark MR cache stale */
+ if (!rc) {
+ ctx->in_sync = false;
+ trace_tsm_mr_write(mr, buffer);
+ }
+
+ up_write(&ctx->rwsem);
+ return rc ?: count;
+}
+
+/**
+ * tsm_mr_create_attribute_group() - creates an attribute group for measurement
+ * registers (MRs)
+ * @tm: pointer to &struct tsm_measurements containing the MR definitions.
+ *
+ * This function creates attributes corresponding to the MR definitions
+ * provided by @tm->mrs.
+ *
+ * The created attributes will reference @tm and its members. The caller must
+ * not free @tm until after tsm_mr_free_attribute_group() is called.
+ *
+ * Context: Process context. May sleep due to memory allocation.
+ *
+ * Return:
+ * * On success, the pointer to a an attribute group is returned; otherwise
+ * * %-EINVAL - Invalid MR definitions.
+ * * %-ENOMEM - Out of memory.
+ */
+const struct attribute_group *
+tsm_mr_create_attribute_group(const struct tsm_measurements *tm)
+{
+ size_t nlen;
+
+ if (!tm || !tm->mrs)
+ return ERR_PTR(-EINVAL);
+
+ /* aggregated length of all MR names */
+ nlen = 0;
+ for (size_t i = 0; i < tm->nr_mrs; ++i) {
+ if ((tm->mrs[i].mr_flags & TSM_MR_F_LIVE) && !tm->refresh)
+ return ERR_PTR(-EINVAL);
+
+ if ((tm->mrs[i].mr_flags & TSM_MR_F_WRITABLE) && !tm->write)
+ return ERR_PTR(-EINVAL);
+
+ if (!tm->mrs[i].mr_name)
+ return ERR_PTR(-EINVAL);
+
+ if (tm->mrs[i].mr_flags & TSM_MR_F_NOHASH)
+ continue;
+
+ if (tm->mrs[i].mr_hash >= HASH_ALGO__LAST)
+ return ERR_PTR(-EINVAL);
+
+ /* MR sysfs attribute names have the form of MRNAME:HASH */
+ nlen += strlen(tm->mrs[i].mr_name) + 1 +
+ strlen(hash_algo_name[tm->mrs[i].mr_hash]) + 1;
+ }
+
+ /*
+ * @attrs and the MR name strings are combined into a single allocation
+ * so that we don't have to free MR names one-by-one in
+ * tsm_mr_free_attribute_group()
+ */
+ const struct bin_attribute * const *attrs __free(kfree) =
+ kzalloc(sizeof(*attrs) * (tm->nr_mrs + 1) + nlen, GFP_KERNEL);
+ struct tm_context *ctx __free(kfree) =
+ kzalloc(struct_size(ctx, mrs, tm->nr_mrs), GFP_KERNEL);
+ char *name, *end;
+
+ if (!ctx || !attrs)
+ return ERR_PTR(-ENOMEM);
+
+ /* @attrs is followed immediately by MR name strings */
+ name = (char *)&attrs[tm->nr_mrs + 1];
+ end = name + nlen;
+
+ for (size_t i = 0; i < tm->nr_mrs; ++i) {
+ /* break const for init */
+ struct bin_attribute **bas = (struct bin_attribute **)attrs;
+
+ bas[i] = &ctx->mrs[i];
+ sysfs_bin_attr_init(bas[i]);
+
+ if (tm->mrs[i].mr_flags & TSM_MR_F_NOHASH)
+ bas[i]->attr.name = tm->mrs[i].mr_name;
+ else if (name < end) {
+ bas[i]->attr.name = name;
+ name += snprintf(name, end - name, "%s:%s",
+ tm->mrs[i].mr_name,
+ hash_algo_name[tm->mrs[i].mr_hash]);
+ ++name;
+ } else
+ return ERR_PTR(-EINVAL);
+
+ /* check for duplicated MR definitions */
+ for (size_t j = 0; j < i; ++j)
+ if (!strcmp(bas[i]->attr.name, bas[j]->attr.name))
+ return ERR_PTR(-EINVAL);
+
+ if (tm->mrs[i].mr_flags & TSM_MR_F_READABLE) {
+ bas[i]->attr.mode |= 0444;
+ bas[i]->read_new = tm_digest_read;
+ }
+
+ if (tm->mrs[i].mr_flags & TSM_MR_F_WRITABLE) {
+ bas[i]->attr.mode |= 0200;
+ bas[i]->write_new = tm_digest_write;
+ }
+
+ bas[i]->size = tm->mrs[i].mr_size;
+ bas[i]->private = ctx;
+ }
+
+ if (name != end)
+ return ERR_PTR(-EINVAL);
+
+ init_rwsem(&ctx->rwsem);
+ ctx->agrp.name = "measurements";
+ ctx->agrp.bin_attrs_new = no_free_ptr(attrs);
+ ctx->tm = tm;
+ return &no_free_ptr(ctx)->agrp;
+}
+EXPORT_SYMBOL_GPL(tsm_mr_create_attribute_group);
+
+/**
+ * tsm_mr_free_attribute_group() - frees the attribute group returned by
+ * tsm_mr_create_attribute_group()
+ * @attr_grp: attribute group returned by tsm_mr_create_attribute_group()
+ *
+ * Context: Process context.
+ */
+void tsm_mr_free_attribute_group(const struct attribute_group *attr_grp)
+{
+ if (!IS_ERR_OR_NULL(attr_grp)) {
+ kfree(attr_grp->bin_attrs);
+ kfree(container_of(attr_grp, struct tm_context, agrp));
+ }
+}
+EXPORT_SYMBOL_GPL(tsm_mr_free_attribute_group);
diff --git a/include/linux/tsm-mr.h b/include/linux/tsm-mr.h
new file mode 100644
index 000000000000..50a521f4ac97
--- /dev/null
+++ b/include/linux/tsm-mr.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __TSM_MR_H
+#define __TSM_MR_H
+
+#include <crypto/hash_info.h>
+
+/**
+ * struct tsm_measurement_register - describes an architectural measurement
+ * register (MR)
+ * @mr_name: name of the MR
+ * @mr_value: buffer containing the current value of the MR
+ * @mr_size: size of the MR - typically the digest size of @mr_hash
+ * @mr_flags: bitwise OR of one or more flags, detailed below
+ * @mr_hash: optional hash identifier defined in include/uapi/linux/hash_info.h.
+ *
+ * A CC guest driver encloses an array of this structure in struct
+ * tsm_measurements to detail the measurement facility supported by the
+ * underlying CC hardware.
+ *
+ * @mr_name and @mr_value must stay valid until this structure is no longer in
+ * use.
+ *
+ * @mr_flags is the bitwise-OR of zero or more of the flags below.
+ *
+ * * %TSM_MR_F_READABLE - the sysfs attribute corresponding to this MR is readable.
+ * * %TSM_MR_F_WRITABLE - the sysfs attribute corresponding to this MR is writable.
+ * The semantics is typically to extend the MR but could vary depending on the
+ * architecture and the MR.
+ * * %TSM_MR_F_LIVE - this MR's value may differ from the last value written, so
+ * must be read back from the underlying CC hardware/firmware.
+ * * %TSM_MR_F_RTMR - bitwise-OR of %TSM_MR_F_LIVE and %TSM_MR_F_WRITABLE.
+ * * %TSM_MR_F_NOHASH - this MR does NOT have an associated hash algorithm.
+ * @mr_hash will be ignored when this flag is set.
+ */
+struct tsm_measurement_register {
+ const char *mr_name;
+ void *mr_value;
+ u32 mr_size;
+ u32 mr_flags;
+ enum hash_algo mr_hash;
+};
+
+#define TSM_MR_F_NOHASH 1
+#define TSM_MR_F_WRITABLE 2
+#define TSM_MR_F_READABLE 4
+#define TSM_MR_F_LIVE 8
+#define TSM_MR_F_RTMR (TSM_MR_F_LIVE | TSM_MR_F_WRITABLE)
+
+#define TSM_MR_(mr, hash) \
+ .mr_name = #mr, .mr_size = hash##_DIGEST_SIZE, \
+ .mr_hash = HASH_ALGO_##hash, .mr_flags = TSM_MR_F_READABLE
+
+/**
+ * struct tsm_measurements - defines the CC architecture specific measurement
+ * facility and methods for updating measurement registers (MRs)
+ * @mrs: Array of MR definitions.
+ * @nr_mrs: Number of elements in @mrs.
+ * @refresh: Callback function to load/sync all MRs from TVM hardware/firmware
+ * into the kernel cache.
+ * @write: Callback function to write to the MR specified by the parameter @mr.
+ * Typically, writing to an MR extends the input buffer to that MR.
+ *
+ * The @refresh callback is invoked when an MR with %TSM_MR_F_LIVE set is being
+ * read and the cache is stale. It must reload all MRs with %TSM_MR_F_LIVE set.
+ * The function parameter @tm is a pointer pointing back to this structure.
+ *
+ * The @write callback is invoked whenever an MR is being written. It takes two
+ * additional parameters besides @tm:
+ *
+ * * @mr - points to the MR (an element of @tm->mrs) being written.
+ * * @data - contains the bytes to write and whose size is @mr->mr_size.
+ *
+ * Both @refresh and @write should return 0 on success and an appropriate error
+ * code on failure.
+ */
+struct tsm_measurements {
+ const struct tsm_measurement_register *mrs;
+ size_t nr_mrs;
+ int (*refresh)(const struct tsm_measurements *tm);
+ int (*write)(const struct tsm_measurements *tm,
+ const struct tsm_measurement_register *mr, const u8 *data);
+};
+
+const struct attribute_group *
+tsm_mr_create_attribute_group(const struct tsm_measurements *tm);
+void tsm_mr_free_attribute_group(const struct attribute_group *attr_grp);
+
+#endif
diff --git a/include/trace/events/tsm_mr.h b/include/trace/events/tsm_mr.h
new file mode 100644
index 000000000000..f40de4ad3e2d
--- /dev/null
+++ b/include/trace/events/tsm_mr.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM tsm_mr
+
+#if !defined(_TRACE_TSM_MR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_TSM_MR_H
+
+#include <linux/tracepoint.h>
+#include <linux/tsm-mr.h>
+
+TRACE_EVENT(tsm_mr_read,
+
+ TP_PROTO(const struct tsm_measurement_register *mr),
+
+ TP_ARGS(mr),
+
+ TP_STRUCT__entry(
+ __string(mr, mr->mr_name)
+ __string(hash, mr->mr_flags & TSM_MR_F_NOHASH ?
+ "data" : hash_algo_name[mr->mr_hash])
+ __dynamic_array(u8, d, mr->mr_size)
+ ),
+
+ TP_fast_assign(
+ __assign_str(mr);
+ __assign_str(hash);
+ memcpy(__get_dynamic_array(d), mr->mr_value, __get_dynamic_array_len(d));
+ ),
+
+ TP_printk("[%s] %s:%s", __get_str(mr), __get_str(hash),
+ __print_hex_str(__get_dynamic_array(d), __get_dynamic_array_len(d)))
+);
+
+TRACE_EVENT(tsm_mr_refresh,
+
+ TP_PROTO(const struct tsm_measurement_register *mr, int rc),
+
+ TP_ARGS(mr, rc),
+
+ TP_STRUCT__entry(
+ __string(mr, mr->mr_name)
+ __field(int, rc)
+ ),
+
+ TP_fast_assign(
+ __assign_str(mr);
+ __entry->rc = rc;
+ ),
+
+ TP_printk("[%s] %s:%d", __get_str(mr),
+ __entry->rc ? "failed" : "succeeded", __entry->rc)
+);
+
+TRACE_EVENT(tsm_mr_write,
+
+ TP_PROTO(const struct tsm_measurement_register *mr, const u8 *data),
+
+ TP_ARGS(mr, data),
+
+ TP_STRUCT__entry(
+ __string(mr, mr->mr_name)
+ __string(hash, mr->mr_flags & TSM_MR_F_NOHASH ?
+ "data" : hash_algo_name[mr->mr_hash])
+ __dynamic_array(u8, d, mr->mr_size)
+ ),
+
+ TP_fast_assign(
+ __assign_str(mr);
+ __assign_str(hash);
+ memcpy(__get_dynamic_array(d), data, __get_dynamic_array_len(d));
+ ),
+
+ TP_printk("[%s] %s:%s", __get_str(mr), __get_str(hash),
+ __print_hex_str(__get_dynamic_array(d), __get_dynamic_array_len(d)))
+);
+
+#endif
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
base-commit: 92a09c47464d040866cf2b4cd052bc60555185fb
--
2.49.0
next prev parent reply other threads:[~2025-05-09 2:07 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-06 22:57 [PATCH v6 0/7] tsm-mr: Unified Measurement Register ABI for TVMs Cedric Xing
2025-05-06 22:57 ` [PATCH v6 1/7] tsm-mr: Add TVM Measurement Register support Cedric Xing
2025-05-09 1:01 ` [PATCH v7 " Dan Williams
2025-05-09 2:07 ` Dan Williams [this message]
2025-05-06 22:57 ` [PATCH v6 2/7] tsm-mr: Add tsm-mr sample code Cedric Xing
2025-05-06 22:57 ` [PATCH v6 3/7] x86/tdx: Add tdx_mcall_extend_rtmr() interface Cedric Xing
2025-05-06 22:57 ` [PATCH v6 4/7] x86/tdx: tdx_mcall_get_report0: Return -EBUSY on TDCALL_OPERAND_BUSY error Cedric Xing
2025-05-06 22:57 ` [PATCH v6 5/7] virt: tdx-guest: Expose TDX MRs as sysfs attributes Cedric Xing
2025-05-08 0:45 ` Dan Williams
2025-05-08 1:06 ` [PATCH v7 " Dan Williams
2025-05-06 22:57 ` [PATCH v6 6/7] virt: tdx-guest: Refactor and streamline TDREPORT generation Cedric Xing
2025-05-06 22:57 ` [PATCH v6 7/7] virt: tdx-guest: Transition to scoped_cond_guard for mutex operations Cedric Xing
2025-05-15 8:39 ` [PATCH v6 0/7] tsm-mr: Unified Measurement Register ABI for TVMs Mikko Ylinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250509020739.882913-1-dan.j.williams@intel.com \
--to=dan.j.williams@intel.com \
--cc=cedric.xing@intel.com \
--cc=linux-coco@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).