On 8/28/2026 10:18 PM, Sean Christopherson wrote:
> On Thu, Aug 27, 2026, Peter Fang wrote:
>> On Fri, Aug 28, 2026 at 10:31:14AM +0800, Xiaoyao Li wrote:
>>>>
>>>> Hmm... This makes me wonder if vm->arch.s_bit below could be replaced
>>>> with the same architectural approach. GPAW is available through
>>>> TDG.VP.INFO or the initial RBX value. This does require a bit more
>>>> plumbing though.
>>>
>>> I'm afraid not. Because below is host code, and vm->arch.s_bit is not used
>>> in guest code.
>>>
>>> Or are suggesting something like dropping the
>>>
>>> if (is_tdx_vm(vm)) {
>>> ucall_mmio_gpa = UCALL_MMIO_GPA | vm->arch.s_bit;
>>> sync_global_to_guest(vm, ucall_mmio_gpa);
>>> }
>>>
>>> entirely and use below hardcoded value instead in guest code?
>>>
>>> UCALL_MMIO_GPA | 1 << (GPAW - 1)
>>
>> Yeah this is what I meant. Just drop sync_global_to_guest() entirely and
>> do things like a normal TDX guest would.
>
> Blech. Every time I come back to this series we're still discussing ucall
> crud,
> and "doing thing like a normal TDX guest". Selftests aren't normal guests.
>
> I know I suggested using the HPET base, but I only did so very begrudgingly
> as I
> couldn't come up with a better alternative to emulated MMIO, and the end
> result
> is quite gross. Not only does the code ignore @mmio_gpa but still obviously
> use
> emulated MMIO, it requires synchronizing data to the guest because KVM
> disallows
> "private" MMIO.
>
> void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
> {
> vm_type = vm->type;
> sync_global_to_guest(vm, vm_type);
>
> if (is_tdx_vm(vm)) {
> ucall_mmio_gpa = UCALL_MMIO_GPA | vm->arch.s_bit;
> sync_global_to_guest(vm, ucall_mmio_gpa);
> }
> }
>
> Retrieving GPA via TDG.VP.INFO isn't any better, it's still an absurd amount
> of
> "work" for something that should be trivial.
>
> Can't we just abuse TDVMCALL_REPORT_FATAL_ERROR? AFAICT, there's no
> restriction
> on the data payload, and there's enough space to all but guarantee we'll
> never get
> a false positive.
>
> Pulling in Xiaoyao's idea about using CPUID...
>
>>> +void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
>>> +{
>>> + vm_type = vm->type;
>>> + sync_global_to_guest(vm, vm_type);
>>
>> It works and it looks simple. But we have the architectural approach to
>> test if a guest is TD guest, by checking the CPUID 0x21.
>>
>> Since checking CPUID 0x21 is not complex, and as a bonus it can help
>> test if TDX module behaves correctly for CPUID leaf 0x21, I think we
>> should switch to use CPUID 0x21 to check if it is TDX VM in guest code?
>
> Absolutely not. It will require at least one an extra VM-Exit for TDX and
> non-TDX
> guests alike, and thanks to Intel's wonderful CPUID behavior of having
> unsupported
> leaves return the last supported leaf, the guest would have to check
> CPUID.0x0 and
> then CPUID.0x21 on modern hardware, i.e. would incur two extra VM-Exits. I
> don't
> care about the performance, but from a debug perspective that's going to be
> awful,
> as what should be a super simple operation will be polluted with unwanted
> data.
As you said, "Selftests aren't normal guests". So the guest code doesn't
need to check CPUID.0x0 to get maximum supported leaf before CPUID.0x21.
And for TDX, the CPUID doesn't cause VM-Exit to KVM, it only exits to TDX
module, which is transparent to KVM.
Anyway, if we go with the TDVMCALL_REPORT_FATAL_ERROR as you proposed, we
don't need the logic to check if it is a TDX VM in the guest.
> Stop trying to reinvent the wheel and just use a virtual function table.
>
> I've verified the attached patches don't break non-TDX selftests, someone just
> needs to test the TDX changes.
I test it and it works.