On 11/26/2024 11:52 AM, Huang, Kai wrote:
On Tue, 2024-11-26 at 09:44 +0800, Binbin Wu wrote:
On 11/26/2024 6:51 AM, Sean Christopherson wrote:
[...]
When an NMI happens in non-root, the NMI is acknowledged by the CPU prior to
performing VM-Exit. In regular VMX, NMIs are blocked after such VM-Exits. With
TDX, that blocking happens for SEAM root, but the SEAMRET back to VMX root will
load interruptibility from the SEAMCALL VMCS, and I don't see any code in the
TDX-Module that propagates that blocking to SEAMCALL VMCS.
I see, thanks for the explanation!
Hmm, actually, this means that TDX has a causality inversion, which may become
visible with FRED's NMI source reporting. E.g. NMI X arrives in SEAM non-root
and triggers a VM-Exit. NMI X+1 becomes pending while SEAM root is active.
TDX-Module SEAMRETs to VMX root, NMIs are unblocked, and so NMI X+1 is delivered
and handled before NMI X.
This example can also cause an issue without FRED.
1. NMI X arrives in SEAM non-root and triggers a VM-Exit.
2. NMI X+1 becomes pending while SEAM root is active.
3. TDX-Module SEAMRETs to VMX root, NMIs are unblocked.
4. NMI X+1 is delivered and handled before NMI X.
(NMI handler could handle all NMI source events, including the source
triggered NMI X)
5. KVM calls exc_nmi() to handle the VM Exit caused by NMI X
In step 5, because the source event caused NMI X has been handled, and NMI X
will not be detected as a second half of back-to-back NMIs, according to
Linux NMI handler, it will be considered as an unknown NMI.
I don't think KVM should call exc_nmi() anymore if NMI is unblocked upon
SEAMRET.
IIUC, KVM has to, because the NMI triggered the VM-Exit can't trigger the
NMI handler to be invoked automatically even if NMI is unblocked upon SEAMRET.
Actually, the issue could happen if NMI X+1 occurs after exiting to SEAM root
mode and before KVM handling the VM-Exit caused by NMI X.
If we can make sure NMI is still blocked upon SEAMRET then everything follows
the current VMX flow IIUC. We should make that happen IMHO.
Agree.