lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250923050317.205482-14-Neeraj.Upadhyay@amd.com>
Date: Tue, 23 Sep 2025 10:33:13 +0530
From: Neeraj Upadhyay <Neeraj.Upadhyay@....com>
To: <kvm@...r.kernel.org>, <seanjc@...gle.com>, <pbonzini@...hat.com>
CC: <linux-kernel@...r.kernel.org>, <Thomas.Lendacky@....com>,
	<nikunj@....com>, <Santosh.Shukla@....com>, <Vasant.Hegde@....com>,
	<Suravee.Suthikulpanit@....com>, <bp@...en8.de>, <David.Kaplan@....com>,
	<huibo.wang@....com>, <naveen.rao@....com>, <tiala@...rosoft.com>
Subject: [RFC PATCH v2 13/17] KVM: SVM: Add IOAPIC EOI support for Secure AVIC guests

While Secure AVIC hardware accelerates End-of-Interrupt (EOI) processing
for edge-triggered interrupts, it requires hypervisor assistance for
level-triggered interrupts originating from the IOAPIC. For these
interrupts, a guest write to the EOI MSR triggers a VM-Exit.

The primary challenge in handling this exit is that the guest's real
In-Service Register (ISR) is not visible to KVM. When KVM receives an EOI,
it has no direct way of knowing which interrupt vector is being
acknowledged.

To solve this, use KVM's software vAPIC state as a shadow tracking
mechanism for active, level-triggered interrupts.

The implementation follows this flow:

1.  On interrupt injection (sev_savic_set_requested_irr), check KVM's
    software vAPIC Trigger Mode Register (TMR) to identify if the
    interrupt is level-triggered.

2.  If it is, set the corresponding vector in KVM's software shadow ISR.
    This marks the interrupt as "in-service" from KVM's perspective.

3.  When the guest later issues an EOI, the APIC_EOI MSR write exit
    handler finds the highest vector set in this shadow ISR.

4.  The handler then clears the vector from the shadow ISR and calls
    kvm_apic_set_eoi_accelerated() to propagate the EOI to the virtual
    IOAPIC, allowing it to de-assert the interrupt line.

This enables correct EOI handling for level-triggered interrupts in
Secure AVIC guests, despite the hardware-enforced opacity of the guest's
APIC state.

Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@....com>
---
 arch/x86/kvm/svm/sev.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 3e9cc50f2705..5be2956fb812 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -4474,7 +4474,9 @@ static void savic_handle_icr_write(struct kvm_vcpu *kvm_vcpu, u64 icr)
 
 static bool savic_handle_msr_exit(struct kvm_vcpu *vcpu)
 {
+	struct kvm_lapic *apic;
 	u32 msr, reg;
+	int vec;
 
 	msr = kvm_rcx_read(vcpu);
 	reg = (msr - APIC_BASE_MSR) << 4;
@@ -4492,6 +4494,12 @@ static bool savic_handle_msr_exit(struct kvm_vcpu *vcpu)
 			return true;
 		}
 		break;
+	case APIC_EOI:
+		apic = vcpu->arch.apic;
+		vec = apic_find_highest_vector(apic->regs + APIC_ISR);
+		apic_clear_vector(vec, apic->regs + APIC_ISR);
+		kvm_apic_set_eoi_accelerated(vcpu, vec);
+		return true;
 	default:
 		break;
 	}
@@ -5379,6 +5387,8 @@ void sev_savic_set_requested_irr(struct vcpu_svm *svm, bool reinjected)
 			vec = vec_start + vec_pos;
 			apic_clear_vector(vec, apic->regs + APIC_IRR);
 			val = val & ~BIT(vec_pos);
+			if (apic_test_vector(vec, apic->regs + APIC_TMR))
+				apic_set_vector(vec, apic->regs + APIC_ISR);
 		} while (val);
 	}
 
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ