Add the VMM Communication Exception (#VC) to the InterruptDescriptorTable
For AMD SEV-ES and SEV-SNP, handling this exception is crucial for
functionality.
@@ -341,7 +341,36 @@ pub struct InterruptDescriptorTable {
pub virtualization: Entry<HandlerFunc>,
/// vector nr. 21-29
- reserved_2: [Entry<HandlerFunc>; 9],
+ reserved_2: [Entry<HandlerFunc>; 8],
+
+ /// The VMM Communication Exception (`#VC`) is always generated by hardware when an `SEV-ES`
+ /// enabled guest is running and an `NAE` event occurs.
+ ///
+ /// `SEV-ES` stands for the _"Encrypted State"_ feature of the _"AMD Secure Encrypted Virtualization"_
+ /// technology. `NAE` stands for an _"Non-Automatic Exit"_, which is an `VMEXIT` event that requires
+ /// hypervisor emulation. See
+ /// [this whitepaper](https://www.amd.com/system/files/TechDocs/Protecting%20VM%20Register%20State%20with%20SEV-ES.pdf)
+ /// for an overview of the `SEV-ES` feature.
+ ///
+ /// The `#VC` exception is a precise, contributory, fault-type exception utilizing exception vector 29.
+ /// This exception cannot be masked. The error code of the `#VC` exception is equal
+ /// to the `#VMEXIT` code of the event that caused the `NAE`.
+ ///
+ /// In response to a `#VC` exception, a typical flow would involve the guest handler inspecting the error
+ /// code to determine the cause of the exception and deciding what register state must be copied to the
+ /// `GHCB` (_"Guest Hypervisor Communication Block"_) for the event to be handled. The handler
+ /// should then execute the `VMGEXIT` instruction to
+ /// create an `AE` and invoke the hypervisor. After a later `VMRUN`, guest execution will resume after the
+ /// `VMGEXIT` instruction where the handler can view the results from the hypervisor and copy state from
+ /// the `GHCB` back to its internal state as needed.
+ ///
+ /// Note that it is inadvisable for the hypervisor to set the `VMCB` (_"Virtual Machine Control Block"_)
+ /// intercept bit for the `#VC` exception as
+ /// this would prevent proper handling of `NAE`s by the guest. Similarly, the hypervisor should avoid
+ /// setting intercept bits for events that would occur in the `#VC` handler (such as `IRET`).
+ ///
+ /// The vector number of the ``#VC`` exception is 29.
+ pub vmm_communication_exception: Entry<HandlerFuncWithErrCode>,
/// The Security Exception (`#SX`) signals security-sensitive events that occur while
/// executing the VMM, in the form of an exception so that the VMM may take appropriate
@@ -407,7 +436,8 @@ impl InterruptDescriptorTable {
machine_check: Entry::missing(),
simd_floating_point: Entry::missing(),
virtualization: Entry::missing(),
- reserved_2: [Entry::missing(); 9],
+ reserved_2: [Entry::missing(); 8],
+ vmm_communication_exception: Entry::missing(),
security_exception: Entry::missing(),
reserved_3: Entry::missing(),
interrupts: [Entry::missing(); 256 - 32],
