Conversation
|
This PR modifies files containing For more on why we check whole files, instead of just diffs, check out the Rustonomicon |
a705f70 to
9cdb83d
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds “Secure AVIC” support for AMD SEV-SNP CVMs across x86 definitions, the IGVM loader configuration/manifests, and the OpenHCL SNP runtime (including AVIC exit handling and APIC backing-page plumbing).
Changes:
- Add/extend x86defs structures and CPUID/MSR bitfields for secure AVIC (including a new SNP AVIC backing-page layout) and rename the VMX APIC page type.
- Extend IGVM manifest/config plumbing to select secure AVIC for SNP, and propagate that into generated VMSA SEV_FEATURES.
- Wire secure AVIC backing pages + register programming into OpenHCL (HCL ioctl layer + virt_mshv_vtl SNP processor logic) and update CPUID filtering accordingly.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| vm/x86/x86defs/src/vmx.rs | Rename VMX APIC page type and assert 4K layout. |
| vm/x86/x86defs/src/snp.rs | Add secure AVIC control/exit info bitfields, AVIC page layout, and tests. |
| vm/x86/x86defs/src/lib.rs | Add SEV secure AVIC MSR const and move ApicRegister to crate root. |
| vm/x86/x86defs/src/cpuid.rs | Extend SEV CPUID feature bits for secure AVIC + related fields. |
| vm/loader/manifests/*.json | Enable secure AVIC in x64 SNP manifests. |
| vm/loader/igvmfilegen_config/src/lib.rs | Add secure_avic selection to SNP isolation config schema. |
| vm/loader/igvmfilegen/src/vp_context_builder/snp.rs | Set SEV_FEATURES bits for secure AVIC in generated VMSAs. |
| vm/loader/igvmfilegen/src/main.rs | Map manifest secure_avic to internal builder enum. |
| vm/loader/igvmfilegen/src/file_loader.rs | Carry secure AVIC setting through loader isolation type and tests. |
| vm/hv1/hvdef/src/lib.rs | Add new HV register IDs and SNP interrupt injection / SEV AVIC register bitfields. |
| openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs | Update to renamed VMX APIC page type and shared ApicRegister. |
| openhcl/virt_mshv_vtl/src/processor/snp/mod.rs | Secure AVIC runtime enablement, AVIC exit handling, and APIC offload plumbing. |
| openhcl/virt_mshv_vtl/src/lib.rs | Plumb host secure AVIC status into SNP CPUID building. |
| openhcl/virt_mshv_vtl/src/cvm_cpuid/* | Add secure_avic knob and tweak APIC MSR enlightenment selection. |
| openhcl/hcl/src/vmsa.rs | Expose secure_avic_control accessor on VMSA wrapper. |
| openhcl/hcl/src/ioctl/*.rs | Map SNP AVIC pages, expose secure AVIC PFN ioctl, and update register hvcall allowlist. |
|
|
||
| open_enum! { | ||
| #[derive(IntoBytes, Immutable, KnownLayout, FromBytes)] | ||
| pub enum HvSnpInterruptInjection : u8 { |
There was a problem hiding this comment.
This uses #![allow(non_upper_case_globals)], but the workspace enables clippy::allow_attributes = "warn" and CI denies warnings. Please add a paired #![expect(clippy::allow_attributes)] on the same item (or otherwise restructure to avoid the allow) so clippy doesn’t fail CI.
| pub enum HvSnpInterruptInjection : u8 { | |
| pub enum HvSnpInterruptInjection : u8 { | |
| #![expect(clippy::allow_attributes)] |
| if vtl < HCL_SECURE_VTL { | ||
| vmsa.sev_features | ||
| .set_alternate_injection(injection_type == InjectionType::Restricted); | ||
| if injection_type == InjectionType::Normal { | ||
| vmsa.sev_features | ||
| .set_secure_avic(secure_avic == SecureAvic::Enabled); | ||
| vmsa.sev_features | ||
| .set_guest_intercept_control(secure_avic == SecureAvic::Enabled); | ||
| } |
There was a problem hiding this comment.
secure_avic is silently ignored for vtl < HCL_SECURE_VTL when injection_type is Restricted (the only case where alternate injection is enabled). Since the config/manifests can request secure_avic = Enabled alongside Restricted, this should be validated (error/assert) or explicitly documented so we don’t ship a config knob that does nothing in this mode.
| "enable_debug": true, | ||
| "injection_type": "restricted" | ||
| "injection_type": "restricted", | ||
| "secure_avic": "enabled" |
There was a problem hiding this comment.
This manifest sets secure_avic: enabled while injection_type is restricted. In vp_context_builder/snp.rs, Secure AVIC is only applied for the Normal injection path for low VTLs, so this setting is currently ineffective. Please make the manifest consistent with the supported combination (or update code to validate/handle this pairing).
| "secure_avic": "enabled" | |
| "secure_avic": "disabled" |
| // If only xAPIC is supported, then the Hyper-V MSRs are | ||
| // more efficient for EOIs. | ||
| // | ||
| // If X2APIC is supported, then we can use the X2APIC MSRs. These | ||
| // are as efficient as the Hyper-V MSRs, and they are | ||
| // compatible with APIC hardware offloads. | ||
| // However, Lazy EOI on SNP is beneficial and requires the | ||
| // Hyper-V MSRs to function. Enable it here always. | ||
| .with_use_apic_msrs(true) | ||
| // | ||
| // When Secure AVIC is enabled, x2APIC MSR accesses are | ||
| // not intercepted. Secure AVIC accelerates EOIs (15.36.21.5 Guest APIC Accesses). | ||
| .with_use_apic_msrs(!self.secure_avic) | ||
| .with_long_spin_wait_count(!0) |
There was a problem hiding this comment.
The comment says “Enable it here always” (re: Hyper-V APIC MSRs / Lazy EOI), but the code now sets use_apic_msrs to !self.secure_avic. Please update the comment to match the new conditional behavior (and clarify the tradeoff for Lazy EOI vs Secure AVIC).
50effe8 to
2c7bb0d
Compare
| #![allow(non_upper_case_globals)] | ||
| HvSnpRestricted = 0x0, | ||
| HvSnpNormal = 0x1, | ||
| HvSnpAlternate = 0x2, | ||
| HvSnpSecureAvic = 0x3, |
There was a problem hiding this comment.
HvSnpInterruptInjection uses #![allow(non_upper_case_globals)]. This is likely to trigger the workspace clippy::allow_attributes = "warn" lint (and CI treats warnings as errors), and it also diverges from the existing open_enum! style in this file (variants are consistently ALL_CAPS). Prefer renaming the variants to ALL_CAPS (e.g., RESTRICTED, NORMAL, …) and dropping the allow attribute, or add an explicit #[expect(clippy::allow_attributes)] on the item if an allow is truly required.
| #![allow(non_upper_case_globals)] | |
| HvSnpRestricted = 0x0, | |
| HvSnpNormal = 0x1, | |
| HvSnpAlternate = 0x2, | |
| HvSnpSecureAvic = 0x3, | |
| RESTRICTED = 0x0, | |
| NORMAL = 0x1, | |
| ALTERNATE = 0x2, | |
| SECURE_AVIC = 0x3, |
| // cause AVIC_NOACCEL exits. These accesses are via WRMSR/RDMSR | ||
| // (2-byte opcodes: 0x0F 0x30 / 0x0F 0x32), and the hardware does | ||
| // not provide next_rip for this exit type. | ||
| // See AMD PPR: 15.36.21.5 "Guest APIC Accesses". | ||
| vmsa.set_rip(vmsa.rip() + 2); |
There was a problem hiding this comment.
For SevExitCode::AVIC_NOACCEL, advance_to_next_instruction unconditionally advances RIP by + 2 assuming the guest executed a bare RDMSR/WRMSR (0x0F 0x32 / 0x0F 0x30). A guest can legally prefix these instructions (legacy prefixes and/or REX), which changes the instruction length; advancing by 2 can desynchronize RIP and potentially hang or mis-execute the guest. Consider decoding the instruction length (or at least skipping valid prefixes before the 0x0F opcode) when next_rip isn’t available, rather than hardcoding + 2.
|
we have a full RI-TP test pass with this change with good test results |
2c7bb0d to
6e0b291
Compare
Add initial support for SNP secure AVIC.
Update kernel to a temporary 6.12 version that supports secure AVIC. A new 6.18 version is in progress.