On Tue, Mar 12, 2024, Kai Huang wrote: > On 28/02/2024 12:20 pm, Paolo Bonzini wrote: > > From: Isaku Yamahata <isaku.yamahata@xxxxxxxxx> > > > > To support TDX, KVM is enhanced to operate with #VE. For TDX, KVM uses the > > suppress #VE bit in EPT entries selectively, in order to be able to trap > > non-present conditions. However, #VE isn't used for VMX and it's a bug > > if it happens. To be defensive and test that VMX case isn't broken > > introduce an option ept_violation_ve_test and when it's set, BUG the vm. > > I am wondering from HW's point of view, is it OK for the kernel to > explicitly send #VE IPI, in which case, IIUC, the guest can legally get the > #VE w/o being a TDX guest? Ooh, fun. Short answer: there's nothing to worry about here. Legally, no. Vectors 0-31 are reserved. However, I do _think_ the guest could technically send IPIs on vectors 16-31, as the local APIC doesn't outright reject such vectors. But such software would be in clear violation of the SDM. 11.5.2 Valid Interrupt Vectors The Intel 64 and IA-32 architectures define 256 vector numbers, ranging from 0 through 255 (see Section 6.2, “Exception and Interrupt Vectors”). Local and I/O APICs support 240 of these vectors (in the range of 16 to 255) as valid interrupts. When an interrupt vector in the range of 0 to 15 is sent or received through the local APIC, the APIC indicates an illegal vector in its Error Status Register (see Section 11.5.3, “Error Handling”). The Intel 64 and IA-32 architectures reserve vectors 16 through 31 for predefined interrupts, exceptions, and Intel-reserved encodings (see Table 6-1). However, the local APIC does not treat vectors in this range as illegal. When an illegal vector value (0 to 15) is written to an LVT entry and the delivery mode is Fixed (bits 8-11 equal 0), the APIC may signal an illegal vector error, without regard to whether the mask bit is set or whether an interrupt is actually seen on the input. where Table 6-1 defines the various exceptions, including #VE, and for vectors 22-31 says "Intel reserved. Do not use." Vectors 32-255 are explicitly described as "User Defined (Non-reserved) Interrupts" that can be generated via "External interrupt or INT n instruction." However, INTn is far more interesting than IPIs, as INTn can definitely generate interrupts for vectors 0-31, and the legality of software generating such interrupts is questionable. E.g. KVM used to "forward" NMI VM-Exits to the kernel by doing INTn with vector 2. Key word "interrupts"! IPIs are hardware interrupts, and INTn generates software interrupts, neither of which are subject to exception bitmap interception: Exceptions (faults, traps, and aborts) cause VM exits based on the exception bitmap (see Section 25.6.3). If an exception occurs, its vector (in the range 0–31) is used to select a bit in the exception bitmap. If the bit is 1, a VM exit occurs; if the bit is 0, the exception is delivered normally through the guest IDT. This use of the exception bitmap applies also to exceptions generated by the instructions INT1, INT3, INTO, BOUND, UD0, UD1, and UD2. with a footnote that further says: INT1 and INT3 refer to the instructions with opcodes F1 and CC, respectively, and not to INT n with value 1 or 3 for n. So while a misbehaving guest could generate a software interrupt on vector 20, it would not be a true #VE, i.e. not an exception, and thus would not generate an EXCEPTION_NMI VM-Exit. I.e. the KVM_BUG_ON() can't be triggered by the guest (assuming hardware isn't broken).