* [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic
@ 2026-09-28 10:08 Peter Fang
2026-09-28 10:08 ` [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer Peter Fang
` (5 more replies)
0 siblings, 6 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
Hi,
This is v5 of the series to make the TDX guest driver's Quote buffer
size dynamic. There is more refactoring in this version, which added 2
more patches. I also reordered the patches so that cleanups/refactoring
come first, and the last patch focuses on the dynamic size feature
itself. This means they're no longer grouped by subsystem first, in
favor of the logical order of the changes.
One thing worth mentioning is that I used EXPORT_SYMBOL_FOR_MODULES() to
export the symbol to the driver, even though I argued in the past [1]
that this is a new pattern for guest-side TDX code. This is because a
separate patch on the list [2] is adding this pattern to
arch/x86/coco/tdx/tdx.c, so hopefully everything will eventually come
together nicely.
Newer TDX modules have an ABI that tells the guest how big a Quote can
get. The Quote buffer no longer has to be a fixed size. So effectively:
s/FIXED_BUF_SIZE/queried_buf_size/
... in the TDX guest driver.
Terminology
===========
A "TD Quote" is an attestation structure signed with a platform key. It
contains information about a TDX guest and the platform it's running on.
The "Quote buffer" in the TDX guest driver is a memory buffer shared
between the TDX guest and the host VMM to retrieve TD Quotes. It has a
header defined in the GHCI spec [3].
Device Identifier Composition Engine ("DICE") provides a framework for
layering attestation evidence. This replaces the SGX model of contacting
an Intel server to obtain a certificate.
Problem
=======
The fixed-size Quote buffer approach is not sustainable. As
cryptographic algorithms evolve, TD Quote sizes also grow. A previous
commit [4] increased the guest driver's fixed-size Quote buffer to 128KB
to accommodate DICE Quotes, but it may still be insufficient when those
Quotes use post-quantum cryptography (PQC). PQC certificate chains are
roughly 10x-15x larger than conventional ones, which can increase Quote
sizes significantly.
What's in this series
=====================
To avoid changing the driver whenever the Quote buffer becomes too
small, newer TDX modules report their largest possible Quote size via a
metadata field [5]. The guest driver uses this value, plus room for the
header, for its Quote buffer when available. Older TDX modules continue
to use the 128KB buffer.
Patches 1-4 refactor the existing fixed buffer handling. Patch 5 adds a
helper to query the new metadata field, and patch 6 then makes the
buffer size dynamic.
Patch 1/6: Take the Quote buffer as a generic pointer.
Patch 2/6: Give the Quote buffer an explicit type.
Patch 3/6: Calculate the Quote buffer size with struct_size_t().
Patch 4/6: Read the Quote buffer size from a helper.
Patch 5/6: Add a helper to read the QUOTE_MAX_SIZE metadata field.
Patch 6/6: The final s/FIXED_BUF_SIZE/queried_buf_size/, when available.
Base
====
This is based on v7.3-rc5.
AI use
======
I used AI to help edit this cover letter and the changelogs, and to
collect and apply the review feedback on lore under my supervision. The
series also underwent AI code review, but its comments were limited to
style suggestions and existing issues. Sashiko's __GFP_NOWARN suggestion
was adopted in v2, but it was dropped in v3.
v4: https://lore.kernel.org/all/20260915092632.2822169-1-peter.fang@intel.com/
Changes in v5:
- Give the Quote buffer an explicit type. [Dave]
- Replace the quote_data_len global with a helper. [Dave, Xiaoyao]
- Simplify tdx_get_max_quote_size(). [Dave]
- Use EXPORT_SYMBOL_FOR_MODULES() instead of EXPORT_SYMBOL_GPL().
[Xiaoyao, Dave]
- Rename GET_QUOTE_DEFAULT_BUF_SIZE to TDX_DEFAULT_QUOTE_SIZE. [Dave]
- Rename TDX_QUOTE_BUF_LEN() to TDX_QUOTE_TOTAL_SIZE(). [Dave]
- Drop the comment about the buddy allocator. [Dave]
- Reorder the patches so that cleanups/refactoring come before the
feature.
- Add Kiryl's Reviewed-by to patch 3.
- Drop the Reviewed-by tags from patches 4-6 as they were reworked.
- Change the author of patch 6 to me, and credit Sathya in the log.
v3: https://lore.kernel.org/all/20260729122939.1340412-1-peter.fang@intel.com/
Changes in v4:
- Update the TDCS_QUOTE_MAX_SIZE encoding to 0x9010000200000007.
- Provide documentation for the metadata field. [Rick, Kiryl]
- Document the reported size's properties. [Xiaoyao, Tony]
- Page align quote_data_len unconditionally. [Xiaoyao]
- Collect Reviewed-by tags. [Sathya, Tony, Xiaoyao, Binbin]
v2: https://lore.kernel.org/all/20260717214349.4075994-1-peter.fang@intel.com/
Changes in v3:
- Split the v2 "Allocate Quote buffer dynamically" patch to do the
refactoring first, then make the buffer size dynamic. [Dave]
- Improve patterns for readability. [Dave]
- Drop __GFP_NOWARN so an allocation failure warns. [Dave, Rick, Kiryl]
- Add Binbin's Reviewed-by to patch 1.
- Drop the Reviewed-by tags (Kiryl, Binbin) as the patch was reworked.
v1: https://lore.kernel.org/all/20260612110853.3188196-1-peter.fang@intel.com/
Changes in v2:
- Collect Reviewed-by tags. [Kiryl, Xiaoyao, Binbin, Sathya]
- Keep the explicit (u32) cast in tdx_get_max_quote_size(). [Binbin]
- Calculate the Quote buffer size with struct_size_t(). [Kiryl, Binbin]
- Add __GFP_NOWARN to the allocation since its size comes from the
host. [sashiko]
- Rename quote_data_size to quote_data_len. [Sathya]
- Drop the Assisted-by tags, as AI was not used to write the code.
[1] https://lore.kernel.org/all/20260623044411.GB923079@pedri/
[2] https://lore.kernel.org/all/20260925131808.2415177-1-nik.borisov@suse.com/
[3] Guest Hypervisor Communication Interface (GHCI) Specification,
Version 1.5, Section "TDG.VP.VMCALL<GetQuote>"
[4] 43185067c6fd ("configfs-tsm-report: tdx_guest: Increase Quote buffer
size to 128KB")
[5] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
field "TD_QUOTE_MAX_SIZE"
Peter Fang (6):
x86/tdx: Take the Quote buffer as a generic pointer
virt: tdx-guest: Give the Quote buffer an explicit type
virt: tdx-guest: Calculate the Quote buffer size safely
virt: tdx-guest: Add a helper for the Quote buffer size
x86/tdx: Add a helper to query maximum Quote size
virt: tdx-guest: Make the Quote buffer size dynamic
arch/x86/coco/tdx/tdx.c | 19 +++++-
arch/x86/include/asm/shared/tdx.h | 1 +
arch/x86/include/asm/tdx.h | 4 +-
drivers/virt/coco/tdx-guest/tdx-guest.c | 79 +++++++++++++++++--------
4 files changed, 75 insertions(+), 28 deletions(-)
base-commit: 72d3fcf802c45d00b300f25b848a93c3a2bd7c7e
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
@ 2026-09-28 10:08 ` Peter Fang
2026-09-28 19:04 ` Edgecombe, Rick P
2026-09-28 20:10 ` Kuppuswamy Sathyanarayanan
2026-09-28 10:08 ` [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type Peter Fang
` (4 subsequent siblings)
5 siblings, 2 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
tdx_hcall_get_quote() takes a "u8 *" buffer unnecessarily. It is never
used as such, since only the buffer's memory address matters. Let the
guest driver give the buffer a type internally and just accept it as a
"void *" instead.
AI was used under supervision to collect/apply feedback, review code and
workshop logs.
Signed-off-by: Peter Fang <peter.fang@intel.com>
---
v5:
- New patch. Prepare for a typed Quote buffer. [Dave]
---
arch/x86/coco/tdx/tdx.c | 2 +-
arch/x86/include/asm/tdx.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index f904a636d449..bcaf4180a8db 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -191,7 +191,7 @@ EXPORT_SYMBOL_GPL(tdx_mcall_extend_rtmr);
*
* Return 0 on success or error code on failure.
*/
-u64 tdx_hcall_get_quote(u8 *buf, size_t size)
+u64 tdx_hcall_get_quote(void *buf, size_t size)
{
/* Since buf is a shared memory, set the shared (decrypted) bits */
return _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(buf)), size, 0, 0);
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 89e97d5761d8..a3c37d61e676 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -81,7 +81,7 @@ int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
int tdx_mcall_extend_rtmr(u8 index, u8 *data);
-u64 tdx_hcall_get_quote(u8 *buf, size_t size);
+u64 tdx_hcall_get_quote(void *buf, size_t size);
void __init tdx_dump_attributes(u64 td_attr);
void __init tdx_dump_td_ctls(u64 td_ctls);
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
2026-09-28 10:08 ` [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer Peter Fang
@ 2026-09-28 10:08 ` Peter Fang
2026-09-28 19:14 ` Edgecombe, Rick P
2026-09-28 20:16 ` Kuppuswamy Sathyanarayanan
2026-09-28 10:08 ` [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely Peter Fang
` (3 subsequent siblings)
5 siblings, 2 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
The Quote buffer is always a "struct tdx_quote_buf", but its global
pointer is a "void *". A function would have to convert it back to make
sense of it.
Declare the global with its actual type, and give it a better name.
This creates variable shadowing in wait_for_quote_completion(), so
rename its parameter for clarity.
AI was used under supervision to collect/apply feedback, review code and
workshop logs.
Signed-off-by: Peter Fang <peter.fang@intel.com>
---
v5:
- New patch. [Dave]
---
drivers/virt/coco/tdx-guest/tdx-guest.c | 35 ++++++++++++-------------
1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
index d0303e31e816..896eb0a09c4a 100644
--- a/drivers/virt/coco/tdx-guest/tdx-guest.c
+++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
@@ -192,7 +192,7 @@ struct tdx_quote_buf {
};
/* Quote data buffer */
-static void *quote_data;
+static struct tdx_quote_buf *quote_buf;
/* Lock to streamline quote requests */
static DEFINE_MUTEX(quote_lock);
@@ -209,7 +209,7 @@ static long tdx_get_report0(struct tdx_report_req __user *req)
USER_SOCKPTR(req->tdreport));
}
-static void free_quote_buf(void *buf)
+static void free_quote_buf(struct tdx_quote_buf *buf)
{
size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
unsigned int count = len >> PAGE_SHIFT;
@@ -222,25 +222,25 @@ static void free_quote_buf(void *buf)
free_pages_exact(buf, len);
}
-static void *alloc_quote_buf(void)
+static struct tdx_quote_buf *alloc_quote_buf(void)
{
size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
unsigned int count = len >> PAGE_SHIFT;
- void *addr;
+ struct tdx_quote_buf *buf;
- addr = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO);
- if (!addr)
+ buf = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO);
+ if (!buf)
return NULL;
- if (set_memory_decrypted((unsigned long)addr, count))
+ if (set_memory_decrypted((unsigned long)buf, count))
return NULL;
- return addr;
+ return buf;
}
/*
* wait_for_quote_completion() - Wait for Quote request completion
- * @quote_buf: Address of Quote buffer.
+ * @buf: Address of Quote buffer.
* @timeout: Timeout in seconds to wait for the Quote generation.
*
* As per TDX GHCI v1.0 specification, sec titled "TDG.VP.VMCALL<GetQuote>",
@@ -249,7 +249,7 @@ static void *alloc_quote_buf(void)
* or error code after processing is complete. So wait till the status
* changes from GET_QUOTE_IN_FLIGHT or the request being timed out.
*/
-static int wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeout)
+static int wait_for_quote_completion(struct tdx_quote_buf *buf, u32 timeout)
{
int i = 0;
@@ -257,7 +257,7 @@ static int wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeou
* Quote requests usually take a few seconds to complete, so waking up
* once per second to recheck the status is fine for this use case.
*/
- while (quote_buf->status == GET_QUOTE_IN_FLIGHT && i++ < timeout) {
+ while (buf->status == GET_QUOTE_IN_FLIGHT && i++ < timeout) {
if (msleep_interruptible(MSEC_PER_SEC))
return -EINTR;
}
@@ -268,7 +268,6 @@ static int wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeou
static int tdx_report_new_locked(struct tsm_report *report, void *data)
{
u8 *buf;
- struct tdx_quote_buf *quote_buf = quote_data;
struct tsm_report_desc *desc = &report->desc;
u32 out_len;
int ret;
@@ -285,7 +284,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
if (desc->inblob_len != TDX_REPORTDATA_LEN)
return -EINVAL;
- memset(quote_data, 0, GET_QUOTE_BUF_SIZE);
+ memset(quote_buf, 0, GET_QUOTE_BUF_SIZE);
/* Update Quote buffer header */
quote_buf->version = GET_QUOTE_CMD_VER;
@@ -296,7 +295,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
if (ret)
return ret;
- err = tdx_hcall_get_quote(quote_data, GET_QUOTE_BUF_SIZE);
+ err = tdx_hcall_get_quote(quote_buf, GET_QUOTE_BUF_SIZE);
if (err) {
pr_err("GetQuote hypercall failed, status:%llx\n", err);
return -EIO;
@@ -417,8 +416,8 @@ static int __init tdx_guest_init(void)
if (ret)
goto deinit_mr;
- quote_data = alloc_quote_buf();
- if (!quote_data) {
+ quote_buf = alloc_quote_buf();
+ if (!quote_buf) {
pr_err("Failed to allocate Quote buffer\n");
ret = -ENOMEM;
goto free_misc;
@@ -431,7 +430,7 @@ static int __init tdx_guest_init(void)
return 0;
free_quote:
- free_quote_buf(quote_data);
+ free_quote_buf(quote_buf);
free_misc:
misc_deregister(&tdx_misc_dev);
deinit_mr:
@@ -444,7 +443,7 @@ module_init(tdx_guest_init);
static void __exit tdx_guest_exit(void)
{
tsm_report_unregister(&tdx_tsm_ops);
- free_quote_buf(quote_data);
+ free_quote_buf(quote_buf);
misc_deregister(&tdx_misc_dev);
tdx_mr_deinit(tdx_attr_groups[0]);
}
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
2026-09-28 10:08 ` [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer Peter Fang
2026-09-28 10:08 ` [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type Peter Fang
@ 2026-09-28 10:08 ` Peter Fang
2026-09-28 15:50 ` Dave Hansen
2026-09-28 10:08 ` [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size Peter Fang
` (2 subsequent siblings)
5 siblings, 1 reply; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
struct tdx_quote_buf has a trailing flexible array member.
struct_size_t() calculates the size of this kind of struct safely. It
handles overflow, which helps since the Quote size comes from the host.
Use it to rewrite the bounds check logic, since
"header_size + data_size > buf_size"
... is more readable than "data_size > buf_size - header_size".
This also prepares for a later change that needs the same
"header_size + data_size" calculation for the Quote buffer size.
AI was used to review code.
Signed-off-by: Peter Fang <peter.fang@intel.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
---
v5:
- Rename TDX_QUOTE_BUF_LEN() to TDX_QUOTE_TOTAL_SIZE(). [Dave]
- Add Kiryl's Reviewed-by.
v4:
- No code changes.
- Add Reviewed-by tags. [Sathya, Tony, Xiaoyao, Binbin]
v3:
- Split out the use of struct_size_t() for buffer length from the v2
"Allocate Quote buffer dynamically" patch to refactor first. [Dave]
- Drop the Reviewed-by tags from v2 (Kiryl, Binbin) as the patch was
reworked.
---
drivers/virt/coco/tdx-guest/tdx-guest.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
index 896eb0a09c4a..b30439584886 100644
--- a/drivers/virt/coco/tdx-guest/tdx-guest.c
+++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
@@ -170,7 +170,7 @@ static void tdx_mr_deinit(const struct attribute_group *mr_grp)
#define GET_QUOTE_SUCCESS 0
#define GET_QUOTE_IN_FLIGHT 0xffffffffffffffff
-#define TDX_QUOTE_MAX_LEN (GET_QUOTE_BUF_SIZE - sizeof(struct tdx_quote_buf))
+#define TDX_QUOTE_TOTAL_SIZE(n) struct_size_t(struct tdx_quote_buf, data, n)
/* struct tdx_quote_buf: Format of Quote request buffer.
* @version: Quote format version, filled by TD.
@@ -314,7 +314,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
out_len = READ_ONCE(quote_buf->out_len);
- if (out_len > TDX_QUOTE_MAX_LEN)
+ if (TDX_QUOTE_TOTAL_SIZE(out_len) > GET_QUOTE_BUF_SIZE)
return -EFBIG;
buf = kvmemdup(quote_buf->data, out_len, GFP_KERNEL);
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
` (2 preceding siblings ...)
2026-09-28 10:08 ` [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely Peter Fang
@ 2026-09-28 10:08 ` Peter Fang
2026-09-28 16:13 ` Dave Hansen
2026-09-28 18:23 ` Edgecombe, Rick P
2026-09-28 10:08 ` [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size Peter Fang
2026-09-28 10:08 ` [PATCH v5 6/6] virt: tdx-guest: Make the Quote buffer size dynamic Peter Fang
5 siblings, 2 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
The Quote buffer size is a constant sprinkled across several places.
Read it from a helper instead. And rename the constant to avoid using a
verb.
Cache the answer in the helper, so a later change can make the size
dynamic without new plumbing.
AI was used under supervision to collect/apply feedback, review code and
workshop logs.
Signed-off-by: Peter Fang <peter.fang@intel.com>
---
v5:
- Reworked v4 3/4 to use a helper instead of a global. [Dave, Xiaoyao]
- Use TDX_DEFAULT_QUOTE_SIZE instead of GET_QUOTE_DEFAULT_BUF_SIZE.
[Dave]
- Use "size" instead of "len" for buffer size variables. [Dave]
- Drop the RB tags, as the code changed substantially.
---
drivers/virt/coco/tdx-guest/tdx-guest.c | 37 ++++++++++++++++++-------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
index b30439584886..b79b4325da3a 100644
--- a/drivers/virt/coco/tdx-guest/tdx-guest.c
+++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
@@ -162,7 +162,7 @@ static void tdx_mr_deinit(const struct attribute_group *mr_grp)
* DICE-based attestation uses layered evidence that requires
* larger Quote size (~100K).
*/
-#define GET_QUOTE_BUF_SIZE SZ_128K
+#define TDX_DEFAULT_QUOTE_SIZE SZ_128K
#define GET_QUOTE_CMD_VER 1
@@ -209,26 +209,42 @@ static long tdx_get_report0(struct tdx_report_req __user *req)
USER_SOCKPTR(req->tdreport));
}
+static size_t get_quote_buf_size(void)
+{
+ static size_t quote_buf_size;
+
+ if (quote_buf_size)
+ return quote_buf_size;
+
+ quote_buf_size = PAGE_ALIGN(TDX_DEFAULT_QUOTE_SIZE);
+
+ return quote_buf_size;
+}
+
static void free_quote_buf(struct tdx_quote_buf *buf)
{
- size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
- unsigned int count = len >> PAGE_SHIFT;
+ size_t buf_size = get_quote_buf_size();
+ unsigned int count;
+
+ count = buf_size >> PAGE_SHIFT;
if (set_memory_encrypted((unsigned long)buf, count)) {
pr_err("Failed to restore encryption mask for Quote buffer, leak it\n");
return;
}
- free_pages_exact(buf, len);
+ free_pages_exact(buf, buf_size);
}
static struct tdx_quote_buf *alloc_quote_buf(void)
{
- size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
- unsigned int count = len >> PAGE_SHIFT;
+ size_t buf_size = get_quote_buf_size();
struct tdx_quote_buf *buf;
+ unsigned int count;
- buf = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO);
+ count = buf_size >> PAGE_SHIFT;
+
+ buf = alloc_pages_exact(buf_size, GFP_KERNEL | __GFP_ZERO);
if (!buf)
return NULL;
@@ -269,6 +285,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
{
u8 *buf;
struct tsm_report_desc *desc = &report->desc;
+ size_t quote_buf_size = get_quote_buf_size();
u32 out_len;
int ret;
u64 err;
@@ -284,7 +301,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
if (desc->inblob_len != TDX_REPORTDATA_LEN)
return -EINVAL;
- memset(quote_buf, 0, GET_QUOTE_BUF_SIZE);
+ memset(quote_buf, 0, quote_buf_size);
/* Update Quote buffer header */
quote_buf->version = GET_QUOTE_CMD_VER;
@@ -295,7 +312,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
if (ret)
return ret;
- err = tdx_hcall_get_quote(quote_buf, GET_QUOTE_BUF_SIZE);
+ err = tdx_hcall_get_quote(quote_buf, quote_buf_size);
if (err) {
pr_err("GetQuote hypercall failed, status:%llx\n", err);
return -EIO;
@@ -314,7 +331,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
out_len = READ_ONCE(quote_buf->out_len);
- if (TDX_QUOTE_TOTAL_SIZE(out_len) > GET_QUOTE_BUF_SIZE)
+ if (TDX_QUOTE_TOTAL_SIZE(out_len) > quote_buf_size)
return -EFBIG;
buf = kvmemdup(quote_buf->data, out_len, GFP_KERNEL);
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
` (3 preceding siblings ...)
2026-09-28 10:08 ` [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size Peter Fang
@ 2026-09-28 10:08 ` Peter Fang
2026-09-28 18:35 ` Edgecombe, Rick P
` (2 more replies)
2026-09-28 10:08 ` [PATCH v5 6/6] virt: tdx-guest: Make the Quote buffer size dynamic Peter Fang
5 siblings, 3 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
TDX attestation report ("Quote") sizes can grow with newer crypto
algorithms, so guests can no longer rely on a fixed-size buffer for the
Quote.
The TDX module added a new ABI that reports the largest possible Quote
size via a metadata field [1]. Add a helper to query the size instead of
exposing tdg_vm_rd() directly, as it can read arbitrary metadata fields.
The reported size covers every Quote type the platform can produce,
including SGX-based Quotes.
Thanks to Xu Yilun for suggesting this in an off-list discussion.
AI was used under supervision to collect/apply feedback, review code and
workshop logs.
[1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
field "TD_QUOTE_MAX_SIZE"
Signed-off-by: Peter Fang <peter.fang@intel.com>
---
v5:
- Drop unused EXPORT_SYMBOL_GPL(). [Dave]
- Use an error code to report failure. [Dave]
- Drop the u32 cast. [Dave]
- Replace the kernel-doc comment with a one-liner. [Dave]
- Drop the RB tags, as the code changed substantially.
v4:
- Update the TDCS_QUOTE_MAX_SIZE encoding to 0x9010000200000007. [1]
- Provide documentation for the metadata field. [Rick, Kiryl]
- Document that the reported size covers every Quote type. [Xiaoyao]
- Document that a module update does not change the reported size.
[Tony]
- Add Tony's Reviewed-by.
v3:
- No code changes. Add Binbin's Reviewed-by.
v2:
- Keep the explicit (u32) cast to document the metadata field width.
[Binbin]
- Note that Xu Yilun's suggestion was made in an off-list discussion.
[Sathya]
- Drop the Assisted-by tags, as the code was not written by AI.
---
arch/x86/coco/tdx/tdx.c | 16 ++++++++++++++++
arch/x86/include/asm/shared/tdx.h | 1 +
arch/x86/include/asm/tdx.h | 2 ++
3 files changed, 19 insertions(+)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index bcaf4180a8db..323e1efc78ea 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -198,6 +198,22 @@ u64 tdx_hcall_get_quote(void *buf, size_t size)
}
EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
+/*
+ * Ask the TDX module what the largest possible Quote might be.
+ */
+int tdx_get_max_quote_size(u64 *max_quote_size)
+{
+ u64 err;
+
+ err = tdg_vm_rd(TDCS_QUOTE_MAX_SIZE, max_quote_size);
+
+ /* Old modules do not support this. Tell the caller. */
+ if (err)
+ return -EINVAL;
+
+ return 0;
+}
+
static void __noreturn tdx_panic(const char *msg)
{
struct tdx_module_args args = {
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index f20e91d7ac35..6f106d4b1a58 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -50,6 +50,7 @@
/* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */
#define TDCS_CONFIG_FLAGS 0x1110000300000016
#define TDCS_TD_CTLS 0x1110000300000017
+#define TDCS_QUOTE_MAX_SIZE 0x9010000200000007
#define TDCS_NOTIFY_ENABLES 0x9100000000000010
#define TDCS_TOPOLOGY_ENUM_CONFIGURED 0x9100000000000019
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index a3c37d61e676..6a465827d8f9 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -83,6 +83,8 @@ int tdx_mcall_extend_rtmr(u8 index, u8 *data);
u64 tdx_hcall_get_quote(void *buf, size_t size);
+int tdx_get_max_quote_size(u64 *max_quote_size);
+
void __init tdx_dump_attributes(u64 td_attr);
void __init tdx_dump_td_ctls(u64 td_ctls);
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH v5 6/6] virt: tdx-guest: Make the Quote buffer size dynamic
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
` (4 preceding siblings ...)
2026-09-28 10:08 ` [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size Peter Fang
@ 2026-09-28 10:08 ` Peter Fang
2026-09-28 20:37 ` Kuppuswamy Sathyanarayanan
5 siblings, 1 reply; 27+ messages in thread
From: Peter Fang @ 2026-09-28 10:08 UTC (permalink / raw)
To: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe, Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy,
Peter Fang
Support a new TDX module ABI that reports the Quote size limit in a
metadata field. The fixed 128KB buffer in the driver may be too small
for Quotes that use new algorithms like post-quantum cryptography (PQC),
which can produce much larger certificates. With this ABI, the guest
sizes the buffer to the platform's needs and no longer has to rely on
some empirical number.
The shared buffer comes from the buddy allocator, as the host expects it
to be physically contiguous. The allocator's page order limit should be
sufficient for current attestation needs. Platforms that don't report
the limit fall back to the default 128KB buffer.
AI was used under supervision to collect/apply feedback, review code and
workshop logs.
Based on a patch originally by Kuppuswamy Sathyanarayanan.
Signed-off-by: Peter Fang <peter.fang@intel.com>
---
v5:
- Do the export here, and use EXPORT_SYMBOL_FOR_MODULES() instead.
[Xiaoyao, Dave]
- Drop the comment about the buddy allocator. [Dave]
- Drop the RB tags, as the code changed substantially.
v4:
- Move the PAGE_ALIGN() out of get_quote_buf_size(). [Xiaoyao]
- Improve the get_quote_buf_size() pattern again.
- Document that the reported size covers every Quote type. [Xiaoyao]
- Document that a module update does not change the reported size.
[Tony]
- Add Tony's Reviewed-by.
v3:
- Split out from the v2 "Allocate Quote buffer dynamically" patch. Add
the dynamic buffer feature on top of the refactoring. [Dave]
- Improve the get_quote_buf_size() pattern for better readability.
[Dave]
- Drop __GFP_NOWARN so an allocation failure warns. [Dave, Rick, Kiryl]
- Drop the Reviewed-by tags from v2 (Kiryl, Binbin) as the patch was
reworked.
---
arch/x86/coco/tdx/tdx.c | 1 +
drivers/virt/coco/tdx-guest/tdx-guest.c | 13 ++++++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 323e1efc78ea..847430fc639f 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -213,6 +213,7 @@ int tdx_get_max_quote_size(u64 *max_quote_size)
return 0;
}
+EXPORT_SYMBOL_FOR_MODULES(tdx_get_max_quote_size, "tdx-guest");
static void __noreturn tdx_panic(const char *msg)
{
diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
index b79b4325da3a..ad2cb4740898 100644
--- a/drivers/virt/coco/tdx-guest/tdx-guest.c
+++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
@@ -212,11 +212,22 @@ static long tdx_get_report0(struct tdx_report_req __user *req)
static size_t get_quote_buf_size(void)
{
static size_t quote_buf_size;
+ u64 max_quote_size;
if (quote_buf_size)
return quote_buf_size;
- quote_buf_size = PAGE_ALIGN(TDX_DEFAULT_QUOTE_SIZE);
+ /* Start with the default buffer size */
+ quote_buf_size = TDX_DEFAULT_QUOTE_SIZE;
+
+ /*
+ * Override the default when the TDX module reports a size. Add room
+ * for the header metadata.
+ */
+ if (!tdx_get_max_quote_size(&max_quote_size))
+ quote_buf_size = TDX_QUOTE_TOTAL_SIZE(max_quote_size);
+
+ quote_buf_size = PAGE_ALIGN(quote_buf_size);
return quote_buf_size;
}
--
2.53.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely
2026-09-28 10:08 ` [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely Peter Fang
@ 2026-09-28 15:50 ` Dave Hansen
2026-09-28 20:53 ` Peter Fang
0 siblings, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2026-09-28 15:50 UTC (permalink / raw)
To: Peter Fang, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy
On 9/28/26 03:08, Peter Fang wrote:
> -#define TDX_QUOTE_MAX_LEN (GET_QUOTE_BUF_SIZE - sizeof(struct tdx_quote_buf))
> +#define TDX_QUOTE_TOTAL_SIZE(n) struct_size_t(struct tdx_quote_buf, data, n)
>
> /* struct tdx_quote_buf: Format of Quote request buffer.
> * @version: Quote format version, filled by TD.
> @@ -314,7 +314,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
>
> out_len = READ_ONCE(quote_buf->out_len);
>
> - if (out_len > TDX_QUOTE_MAX_LEN)
> + if (TDX_QUOTE_TOTAL_SIZE(out_len) > GET_QUOTE_BUF_SIZE)
> return -EFBIG;
Gah, this is awful. There are two different literal "data" things:
1. The function argument: void *data
2. The flexible array member: tdx_quote_buf->data[]
Worse, I think the function argument isn't even used, despite being
passed through at least one level of static, file-local TDX calls.
It becomes a *total* liability since there are so many "data" names
being tossed around.
I just committed this:
> https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?h=x86/tdx&id=d48b2d347105436365280a3697a265aa4d37e96c
Any reason not to keep it?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size
2026-09-28 10:08 ` [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size Peter Fang
@ 2026-09-28 16:13 ` Dave Hansen
2026-09-28 19:13 ` Edgecombe, Rick P
2026-09-28 18:23 ` Edgecombe, Rick P
1 sibling, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2026-09-28 16:13 UTC (permalink / raw)
To: Peter Fang, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Kuppuswamy Sathyanarayanan
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy
On 9/28/26 03:08, Peter Fang wrote:
> +static size_t get_quote_buf_size(void)
> +{
> + static size_t quote_buf_size;
> +
> + if (quote_buf_size)
> + return quote_buf_size;
> +
> + quote_buf_size = PAGE_ALIGN(TDX_DEFAULT_QUOTE_SIZE);
> +
> + return quote_buf_size;
> +}
<sarcasm>
This is gloriously unencumbered by unwieldy comments!
</sarcasm>
Please explain the goal of this function. Why is it doing what it is
doing? This should also explain why it is page-aligning and caching things.
Which also reminds me, it really isn't calculating the size of the quote
"buf". It's calculating the size of the allocation required to transport
it around, no?
Because, there are three sizes here:
1. The actual data of the quote
2. The size of #1 with the metadata added in
3. The size of #2 with page padding
Which one of those three is "buf_size", eh?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size
2026-09-28 10:08 ` [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size Peter Fang
2026-09-28 16:13 ` Dave Hansen
@ 2026-09-28 18:23 ` Edgecombe, Rick P
1 sibling, 0 replies; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 18:23 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy, kas, Fang, Peter, dave.hansen
Cc: seanjc, bp, x86, binbin.wu, hpa, mingo, linux-kernel, Li,
Xiaoyao, tglx, kvm, linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> +static size_t get_quote_buf_size(void)
> +{
> + static size_t quote_buf_size;
> +
> + if (quote_buf_size)
> + return quote_buf_size;
> +
> + quote_buf_size = PAGE_ALIGN(TDX_DEFAULT_QUOTE_SIZE);
> +
> + return quote_buf_size;
> +}
> +
This makes no sense, at the point of this patch. It lazily sets a global to a
constant value. Function scoped static is also weird.
I think you are doing it this way so that later you can plug in the dynamic
read. But later it still doesn't make sense why to lazily fetch it. Why not just
read it in the tdx_guest_init() to a global? If the read fails, set to
TDX_DEFAULT_QUOTE_SIZE. Then you are done. All callers of tdx_guest_init() just
refer to the global. Why not?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 10:08 ` [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size Peter Fang
@ 2026-09-28 18:35 ` Edgecombe, Rick P
2026-09-28 21:00 ` Peter Fang
2026-09-28 18:50 ` Edgecombe, Rick P
2026-09-28 20:32 ` Kuppuswamy Sathyanarayanan
2 siblings, 1 reply; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 18:35 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy, kas, Fang, Peter, dave.hansen
Cc: seanjc, bp, x86, binbin.wu, hpa, mingo, linux-kernel, Li,
Xiaoyao, tglx, kvm, linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> TDX attestation report ("Quote") sizes can grow with newer crypto
> algorithms, so guests can no longer rely on a fixed-size buffer for the
> Quote.
>
> The TDX module added a new ABI that reports the largest possible Quote
> size via a metadata field [1]. Add a helper to query the size instead of
> exposing tdg_vm_rd() directly, as it can read arbitrary metadata fields.
>
> The reported size covers every Quote type the platform can produce,
> including SGX-based Quotes.
>
> Thanks to Xu Yilun for suggesting this in an off-list discussion.
Suggesting what?
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> [1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
> field "TD_QUOTE_MAX_SIZE"
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
> v5:
> - Drop unused EXPORT_SYMBOL_GPL(). [Dave]
> - Use an error code to report failure. [Dave]
> - Drop the u32 cast. [Dave]
> - Replace the kernel-doc comment with a one-liner. [Dave]
> - Drop the RB tags, as the code changed substantially.
> v4:
> - Update the TDCS_QUOTE_MAX_SIZE encoding to 0x9010000200000007. [1]
> - Provide documentation for the metadata field. [Rick, Kiryl]
> - Document that the reported size covers every Quote type. [Xiaoyao]
> - Document that a module update does not change the reported size.
> [Tony]
> - Add Tony's Reviewed-by.
> v3:
> - No code changes. Add Binbin's Reviewed-by.
> v2:
> - Keep the explicit (u32) cast to document the metadata field width.
> [Binbin]
> - Note that Xu Yilun's suggestion was made in an off-list discussion.
> [Sathya]
> - Drop the Assisted-by tags, as the code was not written by AI.
> ---
> arch/x86/coco/tdx/tdx.c | 16 ++++++++++++++++
> arch/x86/include/asm/shared/tdx.h | 1 +
> arch/x86/include/asm/tdx.h | 2 ++
> 3 files changed, 19 insertions(+)
>
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index bcaf4180a8db..323e1efc78ea 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -198,6 +198,22 @@ u64 tdx_hcall_get_quote(void *buf, size_t size)
> }
> EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
>
> +/*
> + * Ask the TDX module what the largest possible Quote might be.
How about adding the "largest on the host platform" detail to this comment.
> + */
> +int tdx_get_max_quote_size(u64 *max_quote_size)
> +{
> + u64 err;
> +
> + err = tdg_vm_rd(TDCS_QUOTE_MAX_SIZE, max_quote_size);
> +
> + /* Old modules do not support this. Tell the caller. */
> + if (err)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> static void __noreturn tdx_panic(const char *msg)
> {
> struct tdx_module_args args = {
> diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
> index f20e91d7ac35..6f106d4b1a58 100644
> --- a/arch/x86/include/asm/shared/tdx.h
> +++ b/arch/x86/include/asm/shared/tdx.h
> @@ -50,6 +50,7 @@
> /* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */
> #define TDCS_CONFIG_FLAGS 0x1110000300000016
> #define TDCS_TD_CTLS 0x1110000300000017
> +#define TDCS_QUOTE_MAX_SIZE 0x9010000200000007
> #define TDCS_NOTIFY_ENABLES 0x9100000000000010
> #define TDCS_TOPOLOGY_ENUM_CONFIGURED 0x9100000000000019
>
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> index a3c37d61e676..6a465827d8f9 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -83,6 +83,8 @@ int tdx_mcall_extend_rtmr(u8 index, u8 *data);
>
> u64 tdx_hcall_get_quote(void *buf, size_t size);
>
> +int tdx_get_max_quote_size(u64 *max_quote_size);
> +
> void __init tdx_dump_attributes(u64 td_attr);
> void __init tdx_dump_td_ctls(u64 td_ctls);
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 10:08 ` [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size Peter Fang
2026-09-28 18:35 ` Edgecombe, Rick P
@ 2026-09-28 18:50 ` Edgecombe, Rick P
2026-09-28 21:13 ` Peter Fang
2026-09-28 20:32 ` Kuppuswamy Sathyanarayanan
2 siblings, 1 reply; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 18:50 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy, kas, Fang, Peter, dave.hansen
Cc: seanjc, bp, x86, binbin.wu, hpa, mingo, linux-kernel, Li,
Xiaoyao, tglx, kvm, linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> [1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
> field "TD_QUOTE_MAX_SIZE"
The latest seems to be June 2026:
https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html
So where is this? Does it say anything about being page aligned already?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer
2026-09-28 10:08 ` [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer Peter Fang
@ 2026-09-28 19:04 ` Edgecombe, Rick P
2026-09-28 20:37 ` Peter Fang
2026-09-28 20:10 ` Kuppuswamy Sathyanarayanan
1 sibling, 1 reply; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 19:04 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy, kas, Fang, Peter, dave.hansen
Cc: seanjc, bp, x86, binbin.wu, hpa, mingo, linux-kernel, Li,
Xiaoyao, tglx, kvm, linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> tdx_hcall_get_quote() takes a "u8 *" buffer unnecessarily. It is never
> used as such, since only the buffer's memory address matters. Let the
> guest driver give the buffer a type internally and just accept it as a
> "void *" instead.
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
> v5:
> - New patch. Prepare for a typed Quote buffer. [Dave]
I guess this traces back to a comment by Binbin. Which had a specific reason.
Changing the global from a void * means a cast would be needed to pass it to
tdx_hcall_get_quote(). I had to go hunting back multiple versions to learn this
because the log didn't mention it. Otherwise it looks like misc cleanup. Can you
explain the connection to future changes in the log?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size
2026-09-28 16:13 ` Dave Hansen
@ 2026-09-28 19:13 ` Edgecombe, Rick P
0 siblings, 0 replies; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 19:13 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy, Hansen, Dave, kas, Fang, Peter, dave.hansen
Cc: seanjc, bp, x86, binbin.wu, hpa, mingo, linux-kernel, Li,
Xiaoyao, tglx, kvm, linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, 2026-09-28 at 09:13 -0700, Dave Hansen wrote:
> Please explain the goal of this function. Why is it doing what it is
> doing? This should also explain why it is page-aligning and caching things.
I'm not sure it actually needs to be. It shortens the math in the places where
it needs to calculate the pages. And then in tdx_report_new_locked() it skips
zeroing the whole buffer (not sure why to zero the buffer actually. Seems it
could just zero the struct members, or maybe skip it).
But actually, this series has a little bit of a change there? Because after this
helper is used, the whole page aligned buffer is zeroed regardless of the quote
size being aligned. Today the compile time constant buffer size happens to be
page aligned already though, so actually there is no change.
But still, a more limited change would have get_quote_buf_size() return the un-
aligned size, like how the define is treated. Then leave the align logic alone
in the callers. Another patch (not in this series) could change that and maybe
make the memset() length in tdx_report_new_locked() make more sense. How about
it?
I guess it just seems like this patch preps for the dynamic changes, while only
halfway addressing the align mysteries.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type
2026-09-28 10:08 ` [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type Peter Fang
@ 2026-09-28 19:14 ` Edgecombe, Rick P
2026-09-28 20:16 ` Kuppuswamy Sathyanarayanan
1 sibling, 0 replies; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 19:14 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy, kas, Fang, Peter, dave.hansen
Cc: seanjc, bp, x86, binbin.wu, hpa, mingo, linux-kernel, Li,
Xiaoyao, tglx, kvm, linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> The Quote buffer is always a "struct tdx_quote_buf", but its global
> pointer is a "void *". A function would have to convert it back to make
> sense of it.
>
> Declare the global with its actual type, and give it a better name.
>
> This creates variable shadowing in wait_for_quote_completion(), so
> rename its parameter for clarity.
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer
2026-09-28 10:08 ` [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer Peter Fang
2026-09-28 19:04 ` Edgecombe, Rick P
@ 2026-09-28 20:10 ` Kuppuswamy Sathyanarayanan
1 sibling, 0 replies; 27+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-28 20:10 UTC (permalink / raw)
To: Peter Fang, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy
Hi,
On 9/28/2026 3:08 AM, Peter Fang wrote:
> tdx_hcall_get_quote() takes a "u8 *" buffer unnecessarily. It is never
> used as such, since only the buffer's memory address matters. Let the
> guest driver give the buffer a type internally and just accept it as a
> "void *" instead.
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
Looks good to me.
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> v5:
> - New patch. Prepare for a typed Quote buffer. [Dave]
> ---
> arch/x86/coco/tdx/tdx.c | 2 +-
> arch/x86/include/asm/tdx.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index f904a636d449..bcaf4180a8db 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -191,7 +191,7 @@ EXPORT_SYMBOL_GPL(tdx_mcall_extend_rtmr);
> *
> * Return 0 on success or error code on failure.
> */
> -u64 tdx_hcall_get_quote(u8 *buf, size_t size)
> +u64 tdx_hcall_get_quote(void *buf, size_t size)
> {
> /* Since buf is a shared memory, set the shared (decrypted) bits */
> return _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(buf)), size, 0, 0);
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> index 89e97d5761d8..a3c37d61e676 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -81,7 +81,7 @@ int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
>
> int tdx_mcall_extend_rtmr(u8 index, u8 *data);
>
> -u64 tdx_hcall_get_quote(u8 *buf, size_t size);
> +u64 tdx_hcall_get_quote(void *buf, size_t size);
>
> void __init tdx_dump_attributes(u64 td_attr);
> void __init tdx_dump_td_ctls(u64 td_ctls);
--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type
2026-09-28 10:08 ` [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type Peter Fang
2026-09-28 19:14 ` Edgecombe, Rick P
@ 2026-09-28 20:16 ` Kuppuswamy Sathyanarayanan
1 sibling, 0 replies; 27+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-28 20:16 UTC (permalink / raw)
To: Peter Fang, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy
Hi,
On 9/28/2026 3:08 AM, Peter Fang wrote:
> The Quote buffer is always a "struct tdx_quote_buf", but its global
> pointer is a "void *". A function would have to convert it back to make
> sense of it.
>
> Declare the global with its actual type, and give it a better name.
>
> This creates variable shadowing in wait_for_quote_completion(), so
> rename its parameter for clarity.
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> v5:
> - New patch. [Dave]
> ---
> drivers/virt/coco/tdx-guest/tdx-guest.c | 35 ++++++++++++-------------
> 1 file changed, 17 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
> index d0303e31e816..896eb0a09c4a 100644
> --- a/drivers/virt/coco/tdx-guest/tdx-guest.c
> +++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
> @@ -192,7 +192,7 @@ struct tdx_quote_buf {
> };
>
> /* Quote data buffer */
> -static void *quote_data;
> +static struct tdx_quote_buf *quote_buf;
>
> /* Lock to streamline quote requests */
> static DEFINE_MUTEX(quote_lock);
> @@ -209,7 +209,7 @@ static long tdx_get_report0(struct tdx_report_req __user *req)
> USER_SOCKPTR(req->tdreport));
> }
>
> -static void free_quote_buf(void *buf)
> +static void free_quote_buf(struct tdx_quote_buf *buf)
> {
> size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
> unsigned int count = len >> PAGE_SHIFT;
> @@ -222,25 +222,25 @@ static void free_quote_buf(void *buf)
> free_pages_exact(buf, len);
> }
>
> -static void *alloc_quote_buf(void)
> +static struct tdx_quote_buf *alloc_quote_buf(void)
> {
> size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
> unsigned int count = len >> PAGE_SHIFT;
> - void *addr;
> + struct tdx_quote_buf *buf;
>
> - addr = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO);
> - if (!addr)
> + buf = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO);
> + if (!buf)
> return NULL;
>
> - if (set_memory_decrypted((unsigned long)addr, count))
> + if (set_memory_decrypted((unsigned long)buf, count))
> return NULL;
>
> - return addr;
> + return buf;
> }
>
> /*
> * wait_for_quote_completion() - Wait for Quote request completion
> - * @quote_buf: Address of Quote buffer.
> + * @buf: Address of Quote buffer.
> * @timeout: Timeout in seconds to wait for the Quote generation.
> *
> * As per TDX GHCI v1.0 specification, sec titled "TDG.VP.VMCALL<GetQuote>",
> @@ -249,7 +249,7 @@ static void *alloc_quote_buf(void)
> * or error code after processing is complete. So wait till the status
> * changes from GET_QUOTE_IN_FLIGHT or the request being timed out.
> */
> -static int wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeout)
> +static int wait_for_quote_completion(struct tdx_quote_buf *buf, u32 timeout)
> {
> int i = 0;
>
> @@ -257,7 +257,7 @@ static int wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeou
> * Quote requests usually take a few seconds to complete, so waking up
> * once per second to recheck the status is fine for this use case.
> */
> - while (quote_buf->status == GET_QUOTE_IN_FLIGHT && i++ < timeout) {
> + while (buf->status == GET_QUOTE_IN_FLIGHT && i++ < timeout) {
> if (msleep_interruptible(MSEC_PER_SEC))
> return -EINTR;
> }
> @@ -268,7 +268,6 @@ static int wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeou
> static int tdx_report_new_locked(struct tsm_report *report, void *data)
> {
> u8 *buf;
> - struct tdx_quote_buf *quote_buf = quote_data;
> struct tsm_report_desc *desc = &report->desc;
> u32 out_len;
> int ret;
> @@ -285,7 +284,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
> if (desc->inblob_len != TDX_REPORTDATA_LEN)
> return -EINVAL;
>
> - memset(quote_data, 0, GET_QUOTE_BUF_SIZE);
> + memset(quote_buf, 0, GET_QUOTE_BUF_SIZE);
>
> /* Update Quote buffer header */
> quote_buf->version = GET_QUOTE_CMD_VER;
> @@ -296,7 +295,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
> if (ret)
> return ret;
>
> - err = tdx_hcall_get_quote(quote_data, GET_QUOTE_BUF_SIZE);
> + err = tdx_hcall_get_quote(quote_buf, GET_QUOTE_BUF_SIZE);
> if (err) {
> pr_err("GetQuote hypercall failed, status:%llx\n", err);
> return -EIO;
> @@ -417,8 +416,8 @@ static int __init tdx_guest_init(void)
> if (ret)
> goto deinit_mr;
>
> - quote_data = alloc_quote_buf();
> - if (!quote_data) {
> + quote_buf = alloc_quote_buf();
> + if (!quote_buf) {
> pr_err("Failed to allocate Quote buffer\n");
> ret = -ENOMEM;
> goto free_misc;
> @@ -431,7 +430,7 @@ static int __init tdx_guest_init(void)
> return 0;
>
> free_quote:
> - free_quote_buf(quote_data);
> + free_quote_buf(quote_buf);
> free_misc:
> misc_deregister(&tdx_misc_dev);
> deinit_mr:
> @@ -444,7 +443,7 @@ module_init(tdx_guest_init);
> static void __exit tdx_guest_exit(void)
> {
> tsm_report_unregister(&tdx_tsm_ops);
> - free_quote_buf(quote_data);
> + free_quote_buf(quote_buf);
> misc_deregister(&tdx_misc_dev);
> tdx_mr_deinit(tdx_attr_groups[0]);
> }
--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 10:08 ` [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size Peter Fang
2026-09-28 18:35 ` Edgecombe, Rick P
2026-09-28 18:50 ` Edgecombe, Rick P
@ 2026-09-28 20:32 ` Kuppuswamy Sathyanarayanan
2 siblings, 0 replies; 27+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-28 20:32 UTC (permalink / raw)
To: Peter Fang, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy
Hi,
On 9/28/2026 3:08 AM, Peter Fang wrote:
> TDX attestation report ("Quote") sizes can grow with newer crypto
> algorithms, so guests can no longer rely on a fixed-size buffer for the
> Quote.
>
> The TDX module added a new ABI that reports the largest possible Quote
> size via a metadata field [1]. Add a helper to query the size instead of
> exposing tdg_vm_rd() directly, as it can read arbitrary metadata fields.
>
> The reported size covers every Quote type the platform can produce,
> including SGX-based Quotes.
>
> Thanks to Xu Yilun for suggesting this in an off-list discussion.
If the patch is suggested by Xu Uilun you can use Suggested-by:
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> [1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
> field "TD_QUOTE_MAX_SIZE"
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
> v5:
> - Drop unused EXPORT_SYMBOL_GPL(). [Dave]
> - Use an error code to report failure. [Dave]
> - Drop the u32 cast. [Dave]
> - Replace the kernel-doc comment with a one-liner. [Dave]
> - Drop the RB tags, as the code changed substantially.
> v4:
> - Update the TDCS_QUOTE_MAX_SIZE encoding to 0x9010000200000007. [1]
> - Provide documentation for the metadata field. [Rick, Kiryl]
> - Document that the reported size covers every Quote type. [Xiaoyao]
> - Document that a module update does not change the reported size.
> [Tony]
> - Add Tony's Reviewed-by.
> v3:
> - No code changes. Add Binbin's Reviewed-by.
> v2:
> - Keep the explicit (u32) cast to document the metadata field width.
> [Binbin]
> - Note that Xu Yilun's suggestion was made in an off-list discussion.
> [Sathya]
> - Drop the Assisted-by tags, as the code was not written by AI.
> ---
> arch/x86/coco/tdx/tdx.c | 16 ++++++++++++++++
> arch/x86/include/asm/shared/tdx.h | 1 +
> arch/x86/include/asm/tdx.h | 2 ++
> 3 files changed, 19 insertions(+)
>
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index bcaf4180a8db..323e1efc78ea 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -198,6 +198,22 @@ u64 tdx_hcall_get_quote(void *buf, size_t size)
> }
> EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
>
> +/*
> + * Ask the TDX module what the largest possible Quote might be.
> + */
> +int tdx_get_max_quote_size(u64 *max_quote_size)
> +{
> + u64 err;
> +
> + err = tdg_vm_rd(TDCS_QUOTE_MAX_SIZE, max_quote_size);
> +
> + /* Old modules do not support this. Tell the caller. */
> + if (err)
> + return -EINVAL;
I think -ENODEV or -EOPNOTSUPP is more appropriate return value
for unsupported case.
Also tdg_vm_rd() updates max_quote_size on error case as well.
You can reset it or use local variable to skip passing incorrect
value on error case.
> +
> + return 0;
> +}
> +
> static void __noreturn tdx_panic(const char *msg)
> {
> struct tdx_module_args args = {
> diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
> index f20e91d7ac35..6f106d4b1a58 100644
> --- a/arch/x86/include/asm/shared/tdx.h
> +++ b/arch/x86/include/asm/shared/tdx.h
> @@ -50,6 +50,7 @@
> /* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */
> #define TDCS_CONFIG_FLAGS 0x1110000300000016
> #define TDCS_TD_CTLS 0x1110000300000017
> +#define TDCS_QUOTE_MAX_SIZE 0x9010000200000007
> #define TDCS_NOTIFY_ENABLES 0x9100000000000010
> #define TDCS_TOPOLOGY_ENUM_CONFIGURED 0x9100000000000019
>
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> index a3c37d61e676..6a465827d8f9 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -83,6 +83,8 @@ int tdx_mcall_extend_rtmr(u8 index, u8 *data);
>
> u64 tdx_hcall_get_quote(void *buf, size_t size);
>
> +int tdx_get_max_quote_size(u64 *max_quote_size);
> +
> void __init tdx_dump_attributes(u64 td_attr);
> void __init tdx_dump_td_ctls(u64 td_ctls);
>
--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 6/6] virt: tdx-guest: Make the Quote buffer size dynamic
2026-09-28 10:08 ` [PATCH v5 6/6] virt: tdx-guest: Make the Quote buffer size dynamic Peter Fang
@ 2026-09-28 20:37 ` Kuppuswamy Sathyanarayanan
0 siblings, 0 replies; 27+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2026-09-28 20:37 UTC (permalink / raw)
To: Peter Fang, Dave Hansen, Kiryl Shutsemau, Rick Edgecombe
Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
H. Peter Anvin, linux-kernel, linux-coco, kvm, Xiaoyao Li,
Binbin Wu, Tony Lindgren, Sean Christopherson, Artem Bityutskiy
Hi,
On 9/28/2026 3:08 AM, Peter Fang wrote:
> Support a new TDX module ABI that reports the Quote size limit in a
> metadata field. The fixed 128KB buffer in the driver may be too small
> for Quotes that use new algorithms like post-quantum cryptography (PQC),
> which can produce much larger certificates. With this ABI, the guest
> sizes the buffer to the platform's needs and no longer has to rely on
> some empirical number.
>
> The shared buffer comes from the buddy allocator, as the host expects it
> to be physically contiguous. The allocator's page order limit should be
> sufficient for current attestation needs. Platforms that don't report
> the limit fall back to the default 128KB buffer.
>
> AI was used under supervision to collect/apply feedback, review code and
> workshop logs.
>
> Based on a patch originally by Kuppuswamy Sathyanarayanan.
>
> Signed-off-by: Peter Fang <peter.fang@intel.com>
> ---
> v5:
> - Do the export here, and use EXPORT_SYMBOL_FOR_MODULES() instead.
> [Xiaoyao, Dave]
> - Drop the comment about the buddy allocator. [Dave]
> - Drop the RB tags, as the code changed substantially.
> v4:
> - Move the PAGE_ALIGN() out of get_quote_buf_size(). [Xiaoyao]
> - Improve the get_quote_buf_size() pattern again.
> - Document that the reported size covers every Quote type. [Xiaoyao]
> - Document that a module update does not change the reported size.
> [Tony]
> - Add Tony's Reviewed-by.
> v3:
> - Split out from the v2 "Allocate Quote buffer dynamically" patch. Add
> the dynamic buffer feature on top of the refactoring. [Dave]
> - Improve the get_quote_buf_size() pattern for better readability.
> [Dave]
> - Drop __GFP_NOWARN so an allocation failure warns. [Dave, Rick, Kiryl]
> - Drop the Reviewed-by tags from v2 (Kiryl, Binbin) as the patch was
> reworked.
> ---
> arch/x86/coco/tdx/tdx.c | 1 +
> drivers/virt/coco/tdx-guest/tdx-guest.c | 13 ++++++++++++-
> 2 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index 323e1efc78ea..847430fc639f 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -213,6 +213,7 @@ int tdx_get_max_quote_size(u64 *max_quote_size)
>
> return 0;
> }
> +EXPORT_SYMBOL_FOR_MODULES(tdx_get_max_quote_size, "tdx-guest");
I think you can cleanup other exports consumed by tdx-guest driver
to use the same format (in a prep patch).
tdx_hcall_get_quote(), tdx_mcall_get_report0() and tdx_mcall_extend_rtmr(0.
>
> static void __noreturn tdx_panic(const char *msg)
> {
> diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c
> index b79b4325da3a..ad2cb4740898 100644
> --- a/drivers/virt/coco/tdx-guest/tdx-guest.c
> +++ b/drivers/virt/coco/tdx-guest/tdx-guest.c
> @@ -212,11 +212,22 @@ static long tdx_get_report0(struct tdx_report_req __user *req)
> static size_t get_quote_buf_size(void)
> {
> static size_t quote_buf_size;
> + u64 max_quote_size;
>
> if (quote_buf_size)
> return quote_buf_size;
>
> - quote_buf_size = PAGE_ALIGN(TDX_DEFAULT_QUOTE_SIZE);
> + /* Start with the default buffer size */
> + quote_buf_size = TDX_DEFAULT_QUOTE_SIZE;
> +
> + /*
> + * Override the default when the TDX module reports a size. Add room
> + * for the header metadata.
> + */
> + if (!tdx_get_max_quote_size(&max_quote_size))
> + quote_buf_size = TDX_QUOTE_TOTAL_SIZE(max_quote_size);
> +
> + quote_buf_size = PAGE_ALIGN(quote_buf_size);
>
> return quote_buf_size;
> }
--
Sathyanarayanan Kuppuswamy
Linux Kernel Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer
2026-09-28 19:04 ` Edgecombe, Rick P
@ 2026-09-28 20:37 ` Peter Fang
0 siblings, 0 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 20:37 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: sathyanarayanan.kuppuswamy, kas, dave.hansen, seanjc, bp, x86,
binbin.wu, hpa, mingo, linux-kernel, Li, Xiaoyao, tglx, kvm,
linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, Sep 28, 2026 at 12:04:30PM -0700, Edgecombe, Rick P wrote:
> On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> > tdx_hcall_get_quote() takes a "u8 *" buffer unnecessarily. It is never
> > used as such, since only the buffer's memory address matters. Let the
> > guest driver give the buffer a type internally and just accept it as a
> > "void *" instead.
> >
> > AI was used under supervision to collect/apply feedback, review code and
> > workshop logs.
> >
> > Signed-off-by: Peter Fang <peter.fang@intel.com>
> > ---
> > v5:
> > - New patch. Prepare for a typed Quote buffer. [Dave]
>
> I guess this traces back to a comment by Binbin. Which had a specific reason.
> Changing the global from a void * means a cast would be needed to pass it to
> tdx_hcall_get_quote(). I had to go hunting back multiple versions to learn this
> because the log didn't mention it. Otherwise it looks like misc cleanup. Can you
> explain the connection to future changes in the log?
Thanks for pointing this out. Yeah some of the review history got lost
in the shuffle. I'll document better in the next version.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely
2026-09-28 15:50 ` Dave Hansen
@ 2026-09-28 20:53 ` Peter Fang
0 siblings, 0 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 20:53 UTC (permalink / raw)
To: Dave Hansen
Cc: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
Kuppuswamy Sathyanarayanan, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, x86, H. Peter Anvin, linux-kernel, linux-coco,
kvm, Xiaoyao Li, Binbin Wu, Tony Lindgren, Sean Christopherson,
Artem Bityutskiy
On Mon, Sep 28, 2026 at 08:50:10AM -0700, Dave Hansen wrote:
> On 9/28/26 03:08, Peter Fang wrote:
> > -#define TDX_QUOTE_MAX_LEN (GET_QUOTE_BUF_SIZE - sizeof(struct tdx_quote_buf))
> > +#define TDX_QUOTE_TOTAL_SIZE(n) struct_size_t(struct tdx_quote_buf, data, n)
> >
> > /* struct tdx_quote_buf: Format of Quote request buffer.
> > * @version: Quote format version, filled by TD.
> > @@ -314,7 +314,7 @@ static int tdx_report_new_locked(struct tsm_report *report, void *data)
> >
> > out_len = READ_ONCE(quote_buf->out_len);
> >
> > - if (out_len > TDX_QUOTE_MAX_LEN)
> > + if (TDX_QUOTE_TOTAL_SIZE(out_len) > GET_QUOTE_BUF_SIZE)
> > return -EFBIG;
>
> Gah, this is awful. There are two different literal "data" things:
>
> 1. The function argument: void *data
> 2. The flexible array member: tdx_quote_buf->data[]
>
> Worse, I think the function argument isn't even used, despite being
> passed through at least one level of static, file-local TDX calls.
>
> It becomes a *total* liability since there are so many "data" names
> being tossed around.
>
> I just committed this:
>
> > https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?h=x86/tdx&id=d48b2d347105436365280a3697a265aa4d37e96c
>
> Any reason not to keep it?
Thanks Dave! Your change makes perfect sense to me. I totally agree.
There are so many uses of "data" in this driver.
Dave actually suggested offline removing TDX_QUOTE_TOTAL_SIZE()
altogether because it really doesn't add much value, forces the reader
to look for the macro def, and doesn't even reduce LOC. So the next
version won't have this macro anymore. That also reduces one line of
code which is a small win.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 18:35 ` Edgecombe, Rick P
@ 2026-09-28 21:00 ` Peter Fang
0 siblings, 0 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 21:00 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: sathyanarayanan.kuppuswamy, kas, dave.hansen, seanjc, bp, x86,
binbin.wu, hpa, mingo, linux-kernel, Li, Xiaoyao, tglx, kvm,
linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, Sep 28, 2026 at 11:35:11AM -0700, Edgecombe, Rick P wrote:
> On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> > TDX attestation report ("Quote") sizes can grow with newer crypto
> > algorithms, so guests can no longer rely on a fixed-size buffer for the
> > Quote.
> >
> > The TDX module added a new ABI that reports the largest possible Quote
> > size via a metadata field [1]. Add a helper to query the size instead of
> > exposing tdg_vm_rd() directly, as it can read arbitrary metadata fields.
> >
> > The reported size covers every Quote type the platform can produce,
> > including SGX-based Quotes.
> >
> > Thanks to Xu Yilun for suggesting this in an off-list discussion.
>
> Suggesting what?
Suggesting using another helper instead of exposing tdg_vm_rd()
directly. I'll clarify it in the next version.
>
> > diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> > index bcaf4180a8db..323e1efc78ea 100644
> > --- a/arch/x86/coco/tdx/tdx.c
> > +++ b/arch/x86/coco/tdx/tdx.c
> > @@ -198,6 +198,22 @@ u64 tdx_hcall_get_quote(void *buf, size_t size)
> > }
> > EXPORT_SYMBOL_GPL(tdx_hcall_get_quote);
> >
> > +/*
> > + * Ask the TDX module what the largest possible Quote might be.
>
> How about adding the "largest on the host platform" detail to this comment.
I'll do that. Thanks.
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 18:50 ` Edgecombe, Rick P
@ 2026-09-28 21:13 ` Peter Fang
2026-09-28 21:25 ` Edgecombe, Rick P
0 siblings, 1 reply; 27+ messages in thread
From: Peter Fang @ 2026-09-28 21:13 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: sathyanarayanan.kuppuswamy, kas, dave.hansen, seanjc, bp, x86,
binbin.wu, hpa, mingo, linux-kernel, Li, Xiaoyao, tglx, kvm,
linux-coco, Bityutskiy, Artem, tony.lindgren
On Mon, Sep 28, 2026 at 11:50:32AM -0700, Edgecombe, Rick P wrote:
> On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> > [1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
> > field "TD_QUOTE_MAX_SIZE"
>
> The latest seems to be June 2026:
> https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html
I think that's "Intel TDX Module ABI Specification". "Intel TDX Module
ABI Definitions" was updated in August. Yeah these names can be
confusing sometimes.
>
> So where is this? Does it say anything about being page aligned already?
In the pdf the wording is "Maximum size of the buffer that must be
allocated to contain the TDX Quote received from TDX Module". It doesn't
say anything about page alignment. I can confirm with the TDX module
folks.
But even if the reported size is always page aligned, the driver would
still need to slap the GHCI header in front of it, and that would make
the total buffer size again not page aligned. So would it be useful in
the end?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 21:13 ` Peter Fang
@ 2026-09-28 21:25 ` Edgecombe, Rick P
2026-09-28 21:25 ` Edgecombe, Rick P
2026-09-28 23:01 ` Peter Fang
0 siblings, 2 replies; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 21:25 UTC (permalink / raw)
To: Fang, Peter
Cc: kvm, Li, Xiaoyao, linux-coco, dave.hansen, kas, seanjc,
binbin.wu, tony.lindgren, mingo, linux-kernel, hpa, tglx, bp,
Bityutskiy, Artem, sathyanarayanan.kuppuswamy, x86
On Mon, 2026-09-28 at 14:13 -0700, Peter Fang wrote:
> On Mon, Sep 28, 2026 at 11:50:32AM -0700, Edgecombe, Rick P wrote:
> > On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> > > [1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
> > > field "TD_QUOTE_MAX_SIZE"
> >
> > The latest seems to be June 2026:
> > https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html
>
> I think that's "Intel TDX Module ABI Specification". "Intel TDX Module
> ABI Definitions" was updated in August. Yeah these names can be
> confusing sometimes.
I see: Intel TDX Module ABI Definitions - ABI definitions in PDF, CSV and JSON
format - June 2026
Ah! There are two listed: one from June and one from August. The August ones are
still labeled for community review. "These documents are not final and are
subject to change based on feedback."
This means that we are upstreaming head of the spec being finalized. And TDX
module will not be able to change anything we depend on. We need to make sure
they know what we are locked onto.
>
> >
> > So where is this? Does it say anything about being page aligned already?
>
> In the pdf the wording is "Maximum size of the buffer that must be
> allocated to contain the TDX Quote received from TDX Module". It doesn't
> say anything about page alignment. I can confirm with the TDX module
> folks.
>
> But even if the reported size is always page aligned, the driver would
> still need to slap the GHCI header in front of it, and that would make
> the total buffer size again not page aligned. So would it be useful in
> the end?
Ah right.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 21:25 ` Edgecombe, Rick P
@ 2026-09-28 21:25 ` Edgecombe, Rick P
2026-09-28 22:47 ` Peter Fang
2026-09-28 23:01 ` Peter Fang
1 sibling, 1 reply; 27+ messages in thread
From: Edgecombe, Rick P @ 2026-09-28 21:25 UTC (permalink / raw)
To: Fang, Peter
Cc: kvm, Li, Xiaoyao, linux-coco, dave.hansen, kas, seanjc,
binbin.wu, tony.lindgren, mingo, linux-kernel, hpa, tglx, bp,
Bityutskiy, Artem, sathyanarayanan.kuppuswamy, x86
On Mon, 2026-09-28 at 14:25 -0700, Rick Edgecombe wrote:
> > But even if the reported size is always page aligned, the driver would
> > still need to slap the GHCI header in front of it, and that would make
> > the total buffer size again not page aligned. So would it be useful in
> > the end?
>
> Ah right.
But that means the memset length is a real functional change?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 21:25 ` Edgecombe, Rick P
@ 2026-09-28 22:47 ` Peter Fang
0 siblings, 0 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 22:47 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: kvm, Li, Xiaoyao, linux-coco, dave.hansen, kas, seanjc,
binbin.wu, tony.lindgren, mingo, linux-kernel, hpa, tglx, bp,
Bityutskiy, Artem, sathyanarayanan.kuppuswamy, x86
On Mon, Sep 28, 2026 at 02:25:48PM -0700, Edgecombe, Rick P wrote:
> On Mon, 2026-09-28 at 14:25 -0700, Rick Edgecombe wrote:
> > > But even if the reported size is always page aligned, the driver would
> > > still need to slap the GHCI header in front of it, and that would make
> > > the total buffer size again not page aligned. So would it be useful in
> > > the end?
> >
> > Ah right.
>
> But that means the memset length is a real functional change?
In a way yes. Previously when the driver was just using the 128KB
constant, there was not a need to explicitly expose this header math. So
the 128KB implicity considered "header + actual quote". Now that's it's
an ABI, pushing this header math into the TDX module would mean less
flexibility in the future to use something other than the GHCI for
quoting.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size
2026-09-28 21:25 ` Edgecombe, Rick P
2026-09-28 21:25 ` Edgecombe, Rick P
@ 2026-09-28 23:01 ` Peter Fang
1 sibling, 0 replies; 27+ messages in thread
From: Peter Fang @ 2026-09-28 23:01 UTC (permalink / raw)
To: Edgecombe, Rick P
Cc: kvm, Li, Xiaoyao, linux-coco, dave.hansen, kas, seanjc,
binbin.wu, tony.lindgren, mingo, linux-kernel, hpa, tglx, bp,
Bityutskiy, Artem, sathyanarayanan.kuppuswamy, x86
On Mon, Sep 28, 2026 at 02:25:16PM -0700, Edgecombe, Rick P wrote:
> On Mon, 2026-09-28 at 14:13 -0700, Peter Fang wrote:
> > On Mon, Sep 28, 2026 at 11:50:32AM -0700, Edgecombe, Rick P wrote:
> > > On Mon, 2026-09-28 at 03:08 -0700, Peter Fang wrote:
> > > > [1] Intel TDX Module ABI Definitions, August 2026, TD-scope metadata
> > > > field "TD_QUOTE_MAX_SIZE"
> > >
> > > The latest seems to be June 2026:
> > > https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html
> >
> > I think that's "Intel TDX Module ABI Specification". "Intel TDX Module
> > ABI Definitions" was updated in August. Yeah these names can be
> > confusing sometimes.
>
> I see: Intel TDX Module ABI Definitions - ABI definitions in PDF, CSV and JSON
> format - June 2026
>
> Ah! There are two listed: one from June and one from August. The August ones are
> still labeled for community review. "These documents are not final and are
> subject to change based on feedback."
>
> This means that we are upstreaming head of the spec being finalized. And TDX
> module will not be able to change anything we depend on. We need to make sure
> they know what we are locked onto.
Yep, once locked in any additional incompatible change will be flagged
as a bug.
>
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2026-09-28 23:01 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-28 10:08 [PATCH v5 0/6] tdx-guest: Make Quote buffer size dynamic Peter Fang
2026-09-28 10:08 ` [PATCH v5 1/6] x86/tdx: Take the Quote buffer as a generic pointer Peter Fang
2026-09-28 19:04 ` Edgecombe, Rick P
2026-09-28 20:37 ` Peter Fang
2026-09-28 20:10 ` Kuppuswamy Sathyanarayanan
2026-09-28 10:08 ` [PATCH v5 2/6] virt: tdx-guest: Give the Quote buffer an explicit type Peter Fang
2026-09-28 19:14 ` Edgecombe, Rick P
2026-09-28 20:16 ` Kuppuswamy Sathyanarayanan
2026-09-28 10:08 ` [PATCH v5 3/6] virt: tdx-guest: Calculate the Quote buffer size safely Peter Fang
2026-09-28 15:50 ` Dave Hansen
2026-09-28 20:53 ` Peter Fang
2026-09-28 10:08 ` [PATCH v5 4/6] virt: tdx-guest: Add a helper for the Quote buffer size Peter Fang
2026-09-28 16:13 ` Dave Hansen
2026-09-28 19:13 ` Edgecombe, Rick P
2026-09-28 18:23 ` Edgecombe, Rick P
2026-09-28 10:08 ` [PATCH v5 5/6] x86/tdx: Add a helper to query maximum Quote size Peter Fang
2026-09-28 18:35 ` Edgecombe, Rick P
2026-09-28 21:00 ` Peter Fang
2026-09-28 18:50 ` Edgecombe, Rick P
2026-09-28 21:13 ` Peter Fang
2026-09-28 21:25 ` Edgecombe, Rick P
2026-09-28 21:25 ` Edgecombe, Rick P
2026-09-28 22:47 ` Peter Fang
2026-09-28 23:01 ` Peter Fang
2026-09-28 20:32 ` Kuppuswamy Sathyanarayanan
2026-09-28 10:08 ` [PATCH v5 6/6] virt: tdx-guest: Make the Quote buffer size dynamic Peter Fang
2026-09-28 20:37 ` Kuppuswamy Sathyanarayanan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®