From: Sean Christopherson <seanjc@google.com>
To: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Cc: Partha Sarathi Satapathy <partha.satapathy@oracle.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Thomas Gleixner <tglx@kernel.org>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H . Peter Anvin" <hpa@zytor.com>,
Shuah Khan <shuah@kernel.org>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org, wim.ten.have@oracle.com
Subject: Re: [PATCH 1/2] KVM: x86: Select lowest vCPU ID for aliased xAPIC IDs
Date: Fri, 30 Oct 2026 13:12:59 -0700 [thread overview]
Message-ID: <auT6S-I5b5ordXy9@google.com> (raw)
In-Reply-To: <62e09b20-b839-448c-90ad-0c63233b523e@oracle.com>
On Wed, Oct 28, 2026, Alejandro Jimenez wrote:
> On 10/27/26 4:25 PM, Sean Christopherson wrote:
> > On Tue, Oct 27, 2026, Alejandro Jimenez wrote: > On 10/27/26 11: 40 AM,
> >> The issue was triggered with QEMU and a tool that uses libvirt API for
> >> resizing guests and balancing their vCPU allocations across NUMA nodes. I
> >> am not sure if similar work has been published upstream, so I'll defer to
> >> Wim (CC'd) if you want more details.
> >
> > Oooh, actual hotplug of vCPUs. That makes sense.
...
> > I suspect there's no solution that will magically fix everything. E.g. if you're
> > trying to resolve an issue where vCPUs aren't recognizing SIPIs, then the example
> > you provided means vCPU_531 will never wakeup, i.e. which vCPU is "buggy" changes,
> > but the bug itself is still there.
> >
>
> Sorry, I don't follow. vCPU 531 would not receive an INIT/SIPI addressed to
> the aliased 0x13 APIC ID in my example, but it will be reachable using its
> full x2APIC ID of 0x213, for which an entry in the phys_map was installed in:
>
> if (vcpu->kvm->arch.x2apic_format) {
>
> /* See also kvm_apic_match_physical_addr(). */
>
> if (apic_x2apic_mode(apic) || x2apic_id > 0xff)
>
> new->phys_map[x2apic_id] = apic;
Oh, duh, the hotplug hack allows using the x2APIC ID even if the target isn't
in x2APIC mode.
> My interpretation is that behavior is "the KVM hotplug hack", and that
> behavior is not changed in the proposed patch.
>
> My example was meant to show the conflict of your proposed change with the
> "deliver to the lowest ID" rule, which you clarified is not a rule after
> all :) (but perhaps it should be since it has been working so far..?)
Heh, "rule". More like half-assed description of what KVM kinda sorta does.
> > If this is about SIPIs hitting the all CPUs, then I think to have a robust (well,
> > as robust as this mess can get) implementation, we'd have to disable use of the
> > optimized map when processing SIPIs with PHYSICAL delivery, e.g.
>
> But then we would also have to disable the optimized map for INIT as well
> (APIC_DM_INIT), since those would still be routed to the wrong vCPU otherwise?
>
> And if both INIT & SIPI are using the slow path, they will be delivered to
> all matching vCPU IDs, which is likely to cause problems e.g. hot plugging
> one vCPU will potentially initialize and start all of its aliases too?
>
> I need to test this with proper instrumented kernel so I can "bring
> receipts" (and I think Partha is doing it already), but hopefully my
> concern above makes sense.
Don't bother testing my patch, my brain was slow to catch on.
> In short, I think the original proposal of allowing a replacement of a
> phys_map[xapic_id] entry only with a new "low" entry (i.e. one with vcpu_id
> == x2apic_id == xapic_id) fixes the creation order issue while preserving
> the existing behavior for the typical cases.
Agreed, though I think we tie the overide to "xapic_id <= 0xff" instead of letting
the "lower" vCPU win. I.e. to make it a bit more obvious that the goal is to keep
the non-truncated xAPIC ID reachable.
Ha! Yeah, looking at 5bd5db385b3e ("KVM: x86: allow hotplug of VCPU with APIC ID
over 0xff"), it had:
/*
* ... xAPIC ID of VCPUs with APIC ID > 0xff will wrap-around,
* prevent them from masking VCPUs with APIC ID <= 0xff.
*/
if (!apic_x2apic_mode(apic) && !new->phys_map[xapic_id])
new->phys_map[xapic_id] = apic;
so the goal really was to prevent an truncated x2APIC ID from clobbering a "pure"
xAPIC ID.
Actually, even better: what if we only let the vCPU whose ID exactly matches the
aliased xAPIC ID win? Unless I've gone into the weeds yet again, that's what we
(and more importantly, userspace and guest firmware) really want. It shouldn't
matter in practice, but it lets KVM provide a stronger, and hopefully easier to
understand, guarantee in the errata.
E.g.
diff --git a/Documentation/virt/kvm/x86/errata.rst b/Documentation/virt/kvm/x86/errata.rst
index a9cf0e004651..09c6e6a29ae2 100644
--- a/Documentation/virt/kvm/x86/errata.rst
+++ b/Documentation/virt/kvm/x86/errata.rst
@@ -63,10 +63,11 @@ When KVM_X2APIC_API_USE_32BIT_IDS is enabled, KVM activates a hack/quirk that
allows sending events to a single vCPU using its x2APIC ID even if the target
vCPU has legacy xAPIC enabled, e.g. to bring up hotplugged vCPUs via INIT-SIPI
on VMs with > 255 vCPUs. A side effect of the quirk is that, if multiple vCPUs
-have the same physical APIC ID, KVM will deliver events targeting that APIC ID
-only to the vCPU with the lowest vCPU ID. If KVM_X2APIC_API_USE_32BIT_IDS is
-not enabled, KVM follows x86 architecture when processing interrupts (all vCPUs
-matching the target APIC ID receive the interrupt).
+have the same physical legacy xAPIC ID, KVM may deliver events targeting that
+xAPIC ID only to the vCPU whose vCPU ID matches the aliased x2APIC ID. If
+KVM_X2APIC_API_USE_32BIT_IDS is not enabled, KVM follows x86 architecture when
+processing interrupts (all vCPUs matching the target APIC ID receive the
+interrupt).
MTRRs
-----
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index d6e5fbc3c58c..e89c4fef1832 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -297,8 +297,8 @@ static int kvm_recalculate_phys_map(struct kvm_apic_map *new,
* Apply KVM's hotplug hack if userspace has enable 32-bit APIC IDs.
* Allow sending events to vCPUs by their x2APIC ID even if the target
* vCPU is in legacy xAPIC mode, and silently ignore aliased xAPIC IDs
- * (the x2APIC ID is truncated to 8 bits, causing IDs > 0xff to wrap
- * and collide).
+ * but make sure the non-truncated xAPIC ID always "wins" (the x2APIC
+ * ID is truncated to 8 bits, causing IDs > 0xff to wrap and collide).
*
* Honor the architectural (and KVM's non-optimized) behavior if
* userspace has not enabled 32-bit x2APIC IDs. Each APIC is supposed
@@ -312,7 +312,8 @@ static int kvm_recalculate_phys_map(struct kvm_apic_map *new,
if (apic_x2apic_mode(apic) || x2apic_id > 0xff)
new->phys_map[x2apic_id] = apic;
- if (!apic_x2apic_mode(apic) && !new->phys_map[xapic_id])
+ if (!apic_x2apic_mode(apic) &&
+ (!new->phys_map[xapic_id] || vcpu->vcpu_id == xapic_id))
new->phys_map[xapic_id] = apic;
} else {
/*
next prev parent reply other threads:[~2026-10-30 20:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 5:18 Partha Sarathi Satapathy
2026-10-27 5:18 ` [PATCH 2/2] KVM: selftests: Cover aliased xAPIC physical IDs Partha Sarathi Satapathy
2026-10-27 15:40 ` [PATCH 1/2] KVM: x86: Select lowest vCPU ID for aliased xAPIC IDs Sean Christopherson
2026-10-27 19:42 ` Alejandro Jimenez
2026-10-27 20:25 ` Sean Christopherson
2026-10-28 22:34 ` Alejandro Jimenez
2026-10-30 20:12 ` Sean Christopherson [this message]
2026-10-30 20:58 ` Alejandro Jimenez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auT6S-I5b5ordXy9@google.com \
--to=seanjc@google.com \
--cc=alejandro.j.jimenez@oracle.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=partha.satapathy@oracle.com \
--cc=pbonzini@redhat.com \
--cc=shuah@kernel.org \
--cc=tglx@kernel.org \
--cc=wim.ten.have@oracle.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®