staticconststruct attribute_group *tdx_mr_init(void)
{ conststruct attribute_group *g; int rc;
u8 *buf __free(kfree) = kzalloc(TDX_REPORT_LEN, GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM);
tdx_report_buf = buf;
rc = tdx_mr_refresh(&tdx_measurements); if (rc) return ERR_PTR(rc);
/* * @mr_value was initialized with the offset only, while the base * address is being added here.
*/ for (size_t i = 0; i < ARRAY_SIZE(tdx_mrs); ++i)
*(long *)&tdx_mrs[i].mr_value += (long)buf;
g = tsm_mr_create_attribute_group(&tdx_measurements); if (!IS_ERR(g))
tdx_report_buf = no_free_ptr(buf);
/* * Intel's SGX QE implementation generally uses Quote size less * than 8K (2K Quote data + ~5K of certificate blob).
*/ #define GET_QUOTE_BUF_SIZE SZ_8K
/* struct tdx_quote_buf: Format of Quote request buffer. * @version: Quote format version, filled by TD. * @status: Status code of Quote request, filled by VMM. * @in_len: Length of TDREPORT, filled by TD. * @out_len: Length of Quote data, filled by VMM. * @data: Quote data on output or TDREPORT on input. * * More details of Quote request buffer can be found in TDX * Guest-Host Communication Interface (GHCI) for Intel TDX 1.0, * section titled "TDG.VP.VMCALL<GetQuote>"
*/ struct tdx_quote_buf {
u64 version;
u64 status;
u32 in_len;
u32 out_len;
u8 data[];
};
/* Quote data buffer */ staticvoid *quote_data;
/* Lock to streamline quote requests */ static DEFINE_MUTEX(quote_lock);
/* * GetQuote request timeout in seconds. Expect that 30 seconds * is enough time for QE to respond to any Quote requests.
*/ static u32 getquote_timeout = 30;
staticvoid free_quote_buf(void *buf)
{
size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE); unsignedint count = len >> PAGE_SHIFT;
if (set_memory_encrypted((unsignedlong)buf, count)) {
pr_err("Failed to restore encryption mask for Quote buffer, leak it\n"); return;
}
free_pages_exact(buf, len);
}
staticvoid *alloc_quote_buf(void)
{
size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE); unsignedint count = len >> PAGE_SHIFT; void *addr;
addr = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO); if (!addr) return NULL;
if (set_memory_decrypted((unsignedlong)addr, count)) return NULL;
return addr;
}
/* * wait_for_quote_completion() - Wait for Quote request completion * @quote_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>", * the status field in the Quote buffer will be set to GET_QUOTE_IN_FLIGHT * while VMM processes the GetQuote request, and will change it to success * or error code after processing is complete. So wait till the status * changes from GET_QUOTE_IN_FLIGHT or the request being timed out.
*/ staticint wait_for_quote_completion(struct tdx_quote_buf *quote_buf, u32 timeout)
{ int i = 0;
/* * 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) { if (msleep_interruptible(MSEC_PER_SEC)) return -EINTR;
}
/* * If the previous request is timedout or interrupted, and the * Quote buf status is still in GET_QUOTE_IN_FLIGHT (owned by * VMM), don't permit any new request.
*/ if (quote_buf->status == GET_QUOTE_IN_FLIGHT) return -EBUSY;
if (desc->inblob_len != TDX_REPORTDATA_LEN) return -EINVAL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.