Register a callback to handle memory acceptance after memory plugging in TDX guests. When memory is added by virtio-mem or other memory hotplug drivers, the TDX guest must accept the memory pages using TDG.MEM.PAGE.ACCEPT TDCALL before they can be safely accessed.
The callback uses the existing tdx_accept_memory() function to accept all pages in the newly plugged memory range. Without this callback, newly added memory would remain in "unaccepted" state, and any access to these pages would trigger VM exits and potentially cause guest crashes. The callback is registered during TDX setup and remains active for the lifetime of the guest, ensuring all dynamically added memory is properly accepted before being made available to the kernel's memory management subsystem. Signed-off-by: Zhenzhong Duan <[email protected]> --- arch/x86/coco/tdx/tdx.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 186915a17c50..d93ba092d311 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -326,6 +326,25 @@ static void reduce_unnecessary_ve(void) enable_cpu_topology_enumeration(); } +static int tdx_memory_post_plug(u64 addr, u64 size) +{ + u64 end; + + if (!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(size)) + return -EINVAL; + + if (check_add_overflow(addr, size, &end)) + return -EINVAL; + + if (tdx_accept_memory(addr, end)) + return 0; + + pr_err("Failed to accept memory [0x%llx, 0x%llx)\n", + (unsigned long long)addr, (unsigned long long)end); + + return -EINVAL; +} + static void tdx_setup(u64 *cc_mask) { struct tdx_module_args args = {}; @@ -359,6 +378,8 @@ static void tdx_setup(u64 *cc_mask) disable_sept_ve(td_attr); reduce_unnecessary_ve(); + + set_memory_post_plug_callback(tdx_memory_post_plug); } /* -- 2.52.0

