Re: [PATCH v2 08/25] x86/virt/tdx: Add SEAMCALL wrappers for TDX page cache management

From: Huang, Kai
Date: Thu Oct 31 2024 - 19:34:05 EST




On 1/11/2024 7:57 am, Edgecombe, Rick P wrote:
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index bad83f6a3b0c..bb7cdb867581 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c

...

+static void tdx_clear_page(unsigned long page_pa)
+{
+ const void *zero_page = (const void *) __va(page_to_phys(ZERO_PAGE(0)));
+ void *page = __va(page_pa);
+ unsigned long i;
+
+ /*
+ * The page could have been poisoned. MOVDIR64B also clears
+ * the poison bit so the kernel can safely use the page again.
+ */
+ for (i = 0; i < PAGE_SIZE; i += 64)
+ movdir64b(page + i, zero_page);
+ /*
+ * MOVDIR64B store uses WC buffer. Prevent following memory reads
+ * from seeing potentially poisoned cache.
+ */
+ __mb();
+}

Just FYI there's already one reset_tdx_pages() doing the same thing in x86 tdx.c:

/*
* Convert TDX private pages back to normal by using MOVDIR64B to
* clear these pages. Note this function doesn't flush cache of
* these TDX private pages. The caller should make sure of that.
*/
static void reset_tdx_pages(unsigned long base, unsigned long size)
{
const void *zero_page = (const void *)page_address(ZERO_PAGE(0));
unsigned long phys, end;

end = base + size;
for (phys = base; phys < end; phys += 64)
movdir64b(__va(phys), zero_page);

/*
* MOVDIR64B uses WC protocol. Use memory barrier to
* make sure any later user of these pages sees the
* updated data.
*/
mb();
}