* [PATCH 0/3] KVM: SVM: Fix x2AVIC MSR interception mess
@ 2026-04-09 22:24 Sean Christopherson
2026-04-09 22:24 ` [PATCH 1/3] KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports Sean Christopherson
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-04-09 22:24 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Naveen N Rao
Fix a variety of bugs in SVM's handling of x2APIC MSR passthrough for x2AVIC,
where KVM disables interception for MSR accesses that aren't accelerated by
hardware (pointless and suboptimal), and also does NOT disable interception
for practically any of the "range of vectors" MSRs, i.e. IRR, ISR, and TMR.
Lightly tested. Functionally, I'm pretty confident it's correct, but I
haven't done due diligence to verify accesses are being accelerated/intercepted
as expected.
Found by inspection when reviewing a TDX patch to fix a bug where KVM botched
the "range of vectors"[*] (I was curious how other KVM code handled the ranges;
wasn't expecting this...).
I tagged all of this for stable, mainly because handling the
AVIC_UNACCELERATED_ACCESS faults (unlike traps) #VMEXITs requires blind
emulation of the code stream. Which is "fine", but obviously unnecessary.
I.e. I could be convinced these fixes shouldn't be sent to LTS trees.
[*] https://lore.kernel.org/all/20260318190111.1041924-1-dmaluka@chromium.org
Sean Christopherson (3):
KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually
supports
KVM: SVM: Always intercept RDMSR for TMCCT (current APIC timer count)
KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are
accelerated
arch/x86/kvm/svm/avic.c | 50 +++++++++++++----------------------------
1 file changed, 15 insertions(+), 35 deletions(-)
base-commit: b89df297a47e641581ee67793592e5c6ae0428f4
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports
2026-04-09 22:24 [PATCH 0/3] KVM: SVM: Fix x2AVIC MSR interception mess Sean Christopherson
@ 2026-04-09 22:24 ` Sean Christopherson
2026-04-09 22:24 ` [PATCH 2/3] KVM: SVM: Always intercept RDMSR for TMCCT (current APIC timer count) Sean Christopherson
2026-04-09 22:24 ` [PATCH 3/3] KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are accelerated Sean Christopherson
2 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-04-09 22:24 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Naveen N Rao
Fix multiple (classes of) bugs with one stone by using KVM's mask of
readable local APIC registers to determine which x2APIC MSRs to pass
through (or not) when toggling x2AVIC on/off. The existing hand-coded
list of MSRs is wrong on multiple fronts:
- ARBPRI, DFR, and ICR2 aren't supported by x2APIC; disabling
interception is nonsensical and suboptimal (the access generates a
#VMEXIT that requires decoding the instruction).
- RRR is completely unsupported.
- AVIC currently fails to pass through the "range of vectors" registers,
IRR, ISR, and TMR, as e.g. X2APIC_MSR(APIC_IRR) only affects IRR0, and
thus only disables intercept for vectors 31:0 (which are the *least*
interesting registers).
Fixes: 4d1d7942e36a ("KVM: SVM: Introduce logic to (de)activate x2AVIC mode")
Cc: stable@vger.kernel.org
Cc: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/svm/avic.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index adf211860949..df974ee290d0 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -122,6 +122,9 @@ static u32 x2avic_max_physical_id;
static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm,
bool intercept)
{
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ u64 x2apic_readable_mask;
+
static const u32 x2avic_passthrough_msrs[] = {
X2APIC_MSR(APIC_ID),
X2APIC_MSR(APIC_LVR),
@@ -162,9 +165,15 @@ static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm,
if (!x2avic_enabled)
return;
+ x2apic_readable_mask = kvm_lapic_readable_reg_mask(vcpu->arch.apic);
+
+ for (i = 0; i < BITS_PER_TYPE(typeof(x2apic_readable_mask)); i++)
+ svm_set_intercept_for_msr(vcpu, APIC_BASE_MSR + i,
+ MSR_TYPE_R, intercept);
+
for (i = 0; i < ARRAY_SIZE(x2avic_passthrough_msrs); i++)
- svm_set_intercept_for_msr(&svm->vcpu, x2avic_passthrough_msrs[i],
- MSR_TYPE_RW, intercept);
+ svm_set_intercept_for_msr(vcpu, x2avic_passthrough_msrs[i],
+ MSR_TYPE_W, intercept);
svm->x2avic_msrs_intercepted = intercept;
}
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] KVM: SVM: Always intercept RDMSR for TMCCT (current APIC timer count)
2026-04-09 22:24 [PATCH 0/3] KVM: SVM: Fix x2AVIC MSR interception mess Sean Christopherson
2026-04-09 22:24 ` [PATCH 1/3] KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports Sean Christopherson
@ 2026-04-09 22:24 ` Sean Christopherson
2026-04-09 22:24 ` [PATCH 3/3] KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are accelerated Sean Christopherson
2 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-04-09 22:24 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Naveen N Rao
Explicitly intercept RDMSR for TMMCT, a.k.a. the current APIC timer count,
when x2AVIC is enabled, as TMMCT reads aren't accelerated by hardware.
Disabling interception is suboptimal as the RDMSR generates an
AVIC_UNACCELERATED_ACCESS fault #VMEXIT, which forces KVM to decode the
instruction to figure out what the guest was trying to access.
Note, the only reason this isn't a fatal bug is that the AVIC architecture
had the foresight to guard against buggy hypervisors. E.g. if hardware
simply read from the virtual APIC page, the guest would get garbage.
Fixes: 4d1d7942e36a ("KVM: SVM: Introduce logic to (de)activate x2AVIC mode")
Cc: stable@vger.kernel.org
Cc: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/svm/avic.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index df974ee290d0..c9e9872ad880 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -171,6 +171,9 @@ static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm,
svm_set_intercept_for_msr(vcpu, APIC_BASE_MSR + i,
MSR_TYPE_R, intercept);
+ if (!intercept)
+ svm_enable_intercept_for_msr(vcpu, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_R);
+
for (i = 0; i < ARRAY_SIZE(x2avic_passthrough_msrs); i++)
svm_set_intercept_for_msr(vcpu, x2avic_passthrough_msrs[i],
MSR_TYPE_W, intercept);
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are accelerated
2026-04-09 22:24 [PATCH 0/3] KVM: SVM: Fix x2AVIC MSR interception mess Sean Christopherson
2026-04-09 22:24 ` [PATCH 1/3] KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports Sean Christopherson
2026-04-09 22:24 ` [PATCH 2/3] KVM: SVM: Always intercept RDMSR for TMCCT (current APIC timer count) Sean Christopherson
@ 2026-04-09 22:24 ` Sean Christopherson
2 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-04-09 22:24 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel, Naveen N Rao
When x2AVIC is enabled, disable WRMSR interception only for MSRs that are
actually accelerated by hardware. Disabling interception for MSRs that
aren't accelerated is functionally "fine", but very suboptimal as many
accesses generate AVIC_UNACCELERATED_ACCESS fault #VMEXITs, which requires
KVM to decode the instruction to figure out what the guest was trying to
access.
Note, the set of MSRs that are passed through for write is identical to
VMX's set when IPI virtualization is enabled. This is not a coincidence,
as x2AVIC is functionally equivalent to APICv+IPIv.
Fixes: 4d1d7942e36a ("KVM: SVM: Introduce logic to (de)activate x2AVIC mode")
Cc: stable@vger.kernel.org
Cc: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/svm/avic.c | 40 ++++------------------------------------
1 file changed, 4 insertions(+), 36 deletions(-)
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index c9e9872ad880..2b07cc347b90 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -124,39 +124,6 @@ static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm,
{
struct kvm_vcpu *vcpu = &svm->vcpu;
u64 x2apic_readable_mask;
-
- static const u32 x2avic_passthrough_msrs[] = {
- X2APIC_MSR(APIC_ID),
- X2APIC_MSR(APIC_LVR),
- X2APIC_MSR(APIC_TASKPRI),
- X2APIC_MSR(APIC_ARBPRI),
- X2APIC_MSR(APIC_PROCPRI),
- X2APIC_MSR(APIC_EOI),
- X2APIC_MSR(APIC_RRR),
- X2APIC_MSR(APIC_LDR),
- X2APIC_MSR(APIC_DFR),
- X2APIC_MSR(APIC_SPIV),
- X2APIC_MSR(APIC_ISR),
- X2APIC_MSR(APIC_TMR),
- X2APIC_MSR(APIC_IRR),
- X2APIC_MSR(APIC_ESR),
- X2APIC_MSR(APIC_ICR),
- X2APIC_MSR(APIC_ICR2),
-
- /*
- * Note! Always intercept LVTT, as TSC-deadline timer mode
- * isn't virtualized by hardware, and the CPU will generate a
- * #GP instead of a #VMEXIT.
- */
- X2APIC_MSR(APIC_LVTTHMR),
- X2APIC_MSR(APIC_LVTPC),
- X2APIC_MSR(APIC_LVT0),
- X2APIC_MSR(APIC_LVT1),
- X2APIC_MSR(APIC_LVTERR),
- X2APIC_MSR(APIC_TMICT),
- X2APIC_MSR(APIC_TMCCT),
- X2APIC_MSR(APIC_TDCR),
- };
int i;
if (intercept == svm->x2avic_msrs_intercepted)
@@ -174,9 +141,10 @@ static void avic_set_x2apic_msr_interception(struct vcpu_svm *svm,
if (!intercept)
svm_enable_intercept_for_msr(vcpu, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_R);
- for (i = 0; i < ARRAY_SIZE(x2avic_passthrough_msrs); i++)
- svm_set_intercept_for_msr(vcpu, x2avic_passthrough_msrs[i],
- MSR_TYPE_W, intercept);
+ svm_set_intercept_for_msr(vcpu, X2APIC_MSR(APIC_TASKPRI), MSR_TYPE_W, intercept);
+ svm_set_intercept_for_msr(vcpu, X2APIC_MSR(APIC_EOI), MSR_TYPE_W, intercept);
+ svm_set_intercept_for_msr(vcpu, X2APIC_MSR(APIC_SELF_IPI), MSR_TYPE_W, intercept);
+ svm_set_intercept_for_msr(vcpu, X2APIC_MSR(APIC_ICR), MSR_TYPE_W, intercept);
svm->x2avic_msrs_intercepted = intercept;
}
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-04-09 22:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-09 22:24 [PATCH 0/3] KVM: SVM: Fix x2AVIC MSR interception mess Sean Christopherson
2026-04-09 22:24 ` [PATCH 1/3] KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports Sean Christopherson
2026-04-09 22:24 ` [PATCH 2/3] KVM: SVM: Always intercept RDMSR for TMCCT (current APIC timer count) Sean Christopherson
2026-04-09 22:24 ` [PATCH 3/3] KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are accelerated Sean Christopherson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox