From a1fd7c3e73e929c85a57b3711159d3df5af27f59 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 15 Oct 2021 11:36:09 +0200 Subject: [PATCH 1/2] Add the VMM Communication Exception (#VC) to the InterruptDescriptorTable For AMD SEV-ES and SEV-SNP, handling this exception is crucial for functionality. Signed-off-by: Harald Hoyer Co-authored-by: Philipp Oppermann --- src/structures/idt.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 5b0d9d1ba..7f7d2c525 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -341,7 +341,36 @@ pub struct InterruptDescriptorTable { pub virtualization: Entry, /// vector nr. 21-29 - reserved_2: [Entry; 9], + reserved_2: [Entry; 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, /// 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], From 0e8071100b3f981123b6fe8efe78c2e45b84c2b6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 6 Nov 2021 14:24:33 +0100 Subject: [PATCH 2/2] Adjust vector number range in docs --- src/structures/idt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 7f7d2c525..da93db813 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -340,7 +340,7 @@ pub struct InterruptDescriptorTable { /// vector nr. 20 pub virtualization: Entry, - /// vector nr. 21-29 + /// vector nr. 21-28 reserved_2: [Entry; 8], /// The VMM Communication Exception (`#VC`) is always generated by hardware when an `SEV-ES`