Skip to content

Conversation

romank-msft
Copy link
Contributor

No description provided.

@romank-msft romank-msft force-pushed the savic_vtl_support branch 2 times, most recently from f6e87dc to a981b57 Compare May 2, 2025 18:10
@romank-msft romank-msft force-pushed the savic_vtl_support branch 3 times, most recently from a27315b to 47325a6 Compare May 6, 2025 21:15
kishonvijayabraham and others added 23 commits June 16, 2025 12:48
The Secure AVIC feature provides SEV-SNP guests hardware acceleration
for performance sensitive APIC accesses while securely managing the
guest-owned APIC state through the use of a private APIC backing page.
This helps prevent malicious hypervisor from generating unexpected
interrupts for a vCPU or otherwise violate architectural assumptions
around APIC behavior.

Add a new x2APIC driver that will serve as the base of the Secure AVIC
support. It is initially the same as the x2APIC phys driver, but will be
modified as features of Secure AVIC are implemented.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Co-developed-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
With Secure AVIC, the APIC backing page is owned and managed by guest.
Allocate APIC backing page for all guest CPUs. In addition, add a
setup() APIC callback. This callback is used by Secure AVIC driver to
initialize APIC backing page area for each CPU.

Allocate APIC backing page memory area in chunks of 2M, so that
backing page memory is mapped using full huge pages. Without this,
if there are private to shared page state conversions for any
non-backing-page allocation which is part of the same huge page as the
one containing a backing page, hypervisor splits the huge page into 4K
pages. Splitting of APIC backing page area into individual 4K pages can
result in performance impact, due to TLB pressure.

Secure AVIC requires that vCPU's APIC backing page's NPT entry is always
present while that vCPU is running. If APIC backing page's NPT entry is
not present, a VMEXIT_BUSY is returned on VMRUN and the vCPU cannot
be resumed after that point. To handle this, invoke sev_notify_savic_gpa()
in Secure AVIC driver's setup() callback. This triggers SVM_VMGEXIT_SECURE_
AVIC_GPA exit for the hypervisor to note GPA of the vCPU's APIC
backing page. Hypervisor uses this information to ensure that the APIC
backing page is mapped in NPT before invoking VMRUN.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Co-developed-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
The x2APIC registers are mapped at an offset within the guest APIC
backing page which is same as their x2APIC MMIO offset. Secure AVIC
adds new registers such as ALLOWED_IRRs (which are at 4-byte offset
within the IRR register offset range) and NMI_REQ to the APIC register
space. In addition, the APIC_ID register is writable and configured by
guest.

Add read() and write() APIC callback functions to read and write x2APIC
registers directly from the guest APIC backing page.

The default .read()/.write() callbacks of x2APIC drivers perform
a rdmsr/wrmsr of the x2APIC registers. When Secure AVIC is enabled,
these would result in #VC exception (for non-accelerated register
accesses). The #VC exception handler reads/write the x2APIC register
in the guest APIC backing page. Since this would increase the latency
of accessing x2APIC registers, the read() and write() callbacks of
Secure AVIC driver directly reads/writes to the guest APIC backing page.

Co-developed-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Secure AVIC lets guest manage the APIC backing page (unlike emulated
x2APIC or x2AVIC where the hypervisor manages the APIC backing page).

However the introduced Secure AVIC Linux design still maintains the
APIC backing page in the hypervisor to shadow the APIC backing page
maintained by guest (It should be noted only subset of the registers
are shadowed for specific usecases and registers like APIC_IRR,
APIC_ISR are not shadowed).

Add sev_ghcb_msr_read() to invoke "SVM_EXIT_MSR" VMGEXIT to read
MSRs from hypervisor. Initialize the Secure AVIC's APIC backing
page by copying the initial state of shadow APIC backing page in
the hypervisor to the guest APIC backing page. Specifically copy
APIC_LVR, APIC_LDR, and APIC_LVT MSRs from the shadow APIC backing
page.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Co-developed-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Initialize the APIC ID in the APIC backing page with the
CPUID function 0000_000bh_EDX (Extended Topology Enumeration),
and ensure that APIC ID msr read from hypervisor is consistent
with the value read from CPUID.

Signed-off-by: Neeraj Upadhyay <[email protected]>
Add update_vector callback to set/clear ALLOWED_IRR field in
the APIC backing page. The allowed IRR vector indicates the
interrupt vectors which the guest allows the hypervisor to
send (typically for emulated devices). ALLOWED_IRR is meant
to be used specifically for vectors that the hypervisor is
allowed to inject, such as device interrupts.  Interrupt
vectors used exclusively by the guest itself (like IPI vectors)
should not be allowed to be injected into the guest for security
reasons.

The update_vector callback is invoked from APIC vector domain
whenever a vector is allocated, freed or moved.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Co-developed-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
With Secure AVIC only Self-IPI is accelerated. To handle all the
other IPIs, add new callbacks for sending IPI, which write to the
IRR of the target guest APIC backing page (after decoding the ICR
register) and then issue VMGEXIT for the hypervisor to notify the
target vCPU.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Co-developed-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Secure AVIC requires LAPIC timer to be emulated by hypervisor. KVM
already supports emulating LAPIC timer using hrtimers. In order
to emulate LAPIC timer, APIC_LVTT, APIC_TMICT and APIC_TDCR register
values need to be propagated to the hypervisor for arming the timer.
APIC_TMCCT register value has to be read from the hypervisor, which
is required for calibrating the APIC timer. So, read/write all APIC
timer registers from/to the hypervisor.

In addition, configure APIC_ALLOWED_IRR for the hypervisor to inject
timer interrupt using LOCAL_TIMER_VECTOR.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Co-developed-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Signed-off-by: Tianyu Lan <[email protected]>
VINTR_CTRL in VMSA should be configured for Secure AVIC. Configure
for secondary vCPUs (the configuration for boot CPU is done in
hypervisor).

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Secure AVIC has introduced a new field in the APIC backing page
"NmiReq" that has to be set by the guest to request a NMI IPI.

Add support to set NmiReq appropriately to send NMI IPI.

This also requires Virtual NMI feature to be enabled in VINTRL_CTRL
field in the VMSA. However this would be added by a later commit
after adding support for injecting NMI from the hypervisor.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Secure AVIC requires "AllowedNmi" bit in the Secure AVIC Control MSR
to be set for NMI to be injected from hypervisor.

Set "AllowedNmi" bit in Secure AVIC Control MSR here to allow NMI
interrupts to be injected from hypervisor. While at that, also propagate
APIC_LVT0 and APIC_LVT1 register values to the hypervisor required for
injecting NMI interrupts from hypervisor.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Now that support to send NMI IPI and support to inject NMI from
hypervisor has been added, set V_NMI_ENABLE in VINTR_CTRL field of
VMSA to enable NMI.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
With all the pieces in place now, enable Secure AVIC in Secure
AVIC Control MSR. Any access to x2APIC MSRs are emulated by
hypervisor before Secure AVIC is enabled in the Control MSR.
Post Secure AVIC enablement, all x2APIC MSR accesses (whether
accelerated by AVIC hardware or trapped as #VC exception) operate
on guest APIC backing page.

Signed-off-by: Neeraj Upadhyay <[email protected]>
Now that Secure AVIC support is added in the guest, indicate SEV-SNP
guest supports Secure AVIC.

Without this, the guest terminates booting with Non-Automatic Exit(NAE)
termination request event.

Signed-off-by: Kishon Vijay Abraham I <[email protected]>
Signed-off-by: Neeraj Upadhyay <[email protected]>
Secure AVIC provides backing page to aid the
guest in limiting which interrupt vectors can
be injected into the guest. Hyper-V has specific
hvcall to set backing page and call it in
Secure AVIC driver.

Signed-off-by: Tianyu Lan <[email protected]>
When Secure AVIC is available, AMD x2apic Secure
AVIC driver should be selected and return directly
in the hv_apic_init().

Signed-off-by: Tianyu Lan <[email protected]>
Expose x2apic_savic_update_vector() to allow driver
or arch code to allow Hyper-V inject related vector.

Signed-off-by: Tianyu Lan <[email protected]>
When Secure AVIC is enabled, Vmbus driver should
call x2apic Secure AVIC interface to allow Hyper-V
to inject Vmbus message interrupt.

Signed-off-by: Tianyu Lan <[email protected]>
When Secure AVIC is enabled, call Secure AVIC
function to allow Hyper-V to inject REENLIGHTENMENT,
STIMER0 and CALLBACK vectors.

Signed-off-by: Tianyu Lan <[email protected]>
Hyper-V doesn't support auto-eoi with Secure AVIC.
So Enable HV_DEPRECATING_AEOI_RECOMMENDED flag
to force to write eoi register after handling
interrupt.

Signed-off-by: Tianyu Lan <[email protected]>
…bled.

When Secure AVIC is not enabled, init_backing_page()
should return directly.

Signed-off-by: Tianyu Lan <[email protected]>
Select AMD Secure AVIC driver in the CVM config
file.

Signed-off-by: Tianyu Lan <[email protected]>
@romank-msft romank-msft force-pushed the savic_vtl_support branch 4 times, most recently from 87d6ae1 to 0861f28 Compare June 18, 2025 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants