On Tue, Jun 16, 2026, Ackerley Tng wrote: > Lisa Wang <[email protected]> writes: > > > This patch series focuses on setting up a TDX VM and adding all code > > necessary to run a basic lifecycle test. > > > > Unlike standard KVM selftests can set up the VM through guest registers, > > TDX module protects TDs' register state from the host. This feature of > > TDX causes problems on VM boot state initialization and the ucall > > implementation. > > > > In standard KVM selftests, the host directly initializes the guest state > > by manipulating Special Registers (SREGs) and General Purpose Registers > > (GPRs) via IOCTLs (KVM_SET_SREGS, etc.) before the first KVM_RUN. > > > > To bypass direct register initialization by the host, we utilize the > > standard x86 reset vector as the default entry point. > > > > The mechanism works as follows: > > 1. The host places register values into a specific memory region and > > inserts boot code at the VM's default starting point. > > 2. When the VM starts, it executes this boot code to "pull" values from > > memory and manually set up its own SREGs and GPRs. > > 3. Once the environment is ready, the boot code jumps to the guest code. > > > > The standard x86 ucall() implementation uses PIO, but it does not > > actually transmit data through the 4-byte PIO data. Instead, it relies > > on the host reading the ucall address directly from the guest's RDI > > register. > > > > TDX selftests cannot utilize the standard x86 ucall implementation, > > because the host is unable to access the guest's RDI register. Based on > > this restriction, we considered these potential solutions for the TDX > > ucall implementation. > > > > 1. TDCALL PIO with RCX-bits Passthrough > > We first considered passing the RDI value through RCX bits to bypass the > > hardware's register protection, which could be the closest approach to > > the non-TDX implementation as per Sean's suggestion[1]. However, this > > approach is blocked by the software-side implementation: KVM_GET_REGS > > currently does not support TDX VMs and returns -EINVAL. To make this > > work, the KVM ioctl would need a test-only hack. > > > > 2. TDCALL PIO with buffer indexing > > To keep a PIO-based approach and unify the get_ucall implementation for > > both TDX and non-TDX VMs, we considered TDCALL PIO with buffer indexing. > > Since the ucall buffer is initialized prior to execution, the VM could > > just pass a buffer index rather than an 8-byte ucall address to fit > > within the 4-byte PIO data limit. The host, already knowing the ucall > > buffer's base address, could then resolve the ucall content via this > > index. We abandoned this solution because it would require changes to > > the common ucall structure and impact other non-x86 architectures. > > > > 3. TDCALL MMIO (Selected solution) > > We ultimately selected TDCALL with an 8-byte MMIO data. This method only > > requires initializing an MMIO GPA and adding TDCALL MMIO implementation > > for TDX under the original x86 ucall path. While this diverges from the > > non-TDX PIO, it provides the cleanest implementation with minimal > > disruption to the overall ucall architecture. > > > > Sean, Lisa evaluated your suggestion [1] (summarized as 1. above) but we > think TDCALL MMIO is better, what do you think?
I think y'all should have responded to that thread with "that doesn't work because host userspace can't access the registers". Reviews are multi-way discussions, not one-way streams of "do this". And the expectation is that either review feedback is addressed in the next version, or the dicussion is closed/resolved *before* posting the next version. Remaining silent and then writing a thesis in the cover letter of a future version of the series is very inefficient for everyone involved. I obviously don't read cover letters all that closely at v13 and I gotta imagine a *lot* of effort went into the above (which I greatly appreciate!). The paper trail also becomes impossible to follow, because anyone reading my response would probably make the same assumption as me: it was a viable idea and that's what we implemented. I'm a-ok with using MMIO, because yeah, there doesn't seem to be a better option.

