All of lore.kernel.org
 help / color / mirror / Atom feed
From: fuqiang wang <fuqiang.wng@gmail.com>
To: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>
Cc: Zenghui Yu <yuzenghui@huawei.com>,
	linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev,
	dongxu zhang <xu910121@sina.com>,
	wangfuqiang49 <wangfuqiang49@jd.com>,
	"diaojiaqing.1" <diaojiaqing.1@jd.com>
Subject: Re: [PATCH v2 2/2] KVM: arm64: Skip unreset vCPUs in MPIDR lookup table
Date: Thu, 18 Jun 2026 19:38:54 +0800	[thread overview]
Message-ID: <ef4bd4eb-f67a-4a44-a548-08240c2eba30@gmail.com> (raw)
In-Reply-To: <87cxxs86bg.wl-maz@kernel.org>



On 6/15/26 6:08 PM, Marc Zyngier wrote:

Hi Oliver, Marc

Thank you very much for your replies and guidance. I'm sorry for the
late reply.(I took some time to brush up on ARM CPU hotplug.)

> On Mon, 15 Jun 2026 05:20:35 +0100,
> Oliver Upton <oupton@kernel.org> wrote:
>>
>> On Sun, Jun 14, 2026 at 10:26:32AM +0100, Marc Zyngier wrote:
>>>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>>>> index 3732ee9eb0d4..fccfa97370df 100644
>>>> --- a/arch/arm64/kvm/arm.c
>>>> +++ b/arch/arm64/kvm/arm.c
>>>> @@ -887,8 +887,18 @@ static void kvm_init_mpidr_data(struct kvm *kvm)
>>>>   	data->mpidr_mask = mask;
>>>>   
>>>>   	kvm_for_each_vcpu(c, vcpu, kvm) {
>>>> -		u64 aff = kvm_vcpu_get_mpidr_aff(vcpu);
>>>> -		u16 index = kvm_mpidr_index(data, aff);
>>>> +		u64 aff;
>>>> +		u16 index;
>>>> +
>>>> +		/*
>>>> +		 * Skip vCPUs that haven't been reset yet; their MPIDR_EL1 is
>>>> +		 * zero.
>>>> +		 */
>>>> +		if (!kvm_vcpu_mpidr_is_reset(vcpu))
>>>> +			continue;
>>>
>>> But what about the initial loop that computes the significant bits
>>> amongst the vcpus?

Yes, this is indeed missed here, possibly making the following nr_entries
calculation too large.

>>>
>>>> +
>>>> +		aff = kvm_vcpu_get_mpidr_aff(vcpu);
>>>> +		index = kvm_mpidr_index(data, aff);
>>>
>>> In all honesty, I think this is a userspace bug more than anything
>>> else, and checking for random bits in MPDR_EL1 to verify whether the
>>> value is plausible is gross.
>>
>> +1. Checking the MPIDR value is also broken because userspace can write
>> whatever it wants to the register, which could even clear the RES1 bit
>> that's getting tested here.

Yes, the change here is quite ugly — it looks like temporary debug code.
It would be better to change it to !kvm_vcpu_initialized().

>>
>>> Yhis isn't different from setting MPIDR_EL1 to the same value on all
>>> vcpus, which we don't try to mitigate. Late setting of MPIDR_EL1 also
>>> defeats the whole point of having a cache for the affinity to index
>>> conversion, making SGIs pretty slow for late CPUs.
>>>
>>> I really think that by not finalising your vcpus and start running the
>>> guest, you have cornered yourself pretty badly, and we shouldn't try
>>> to paper over it.
>>
>> I generally agree, although I wouldn't be against a change that nuked
>> any of the cached routings in case of userspace doing stupid things like
>> collisions and whatnot.

I once thought about sending patch [1] again, because I found that Oliver
had done something similar[2]... but then I gave up.

For restless userspace programs, KVM cannot foresee their behavior. For
example, when a VCPU is running, there may be cases like:

+ some vcpus not create, later create
+ some vcpus created but not reset, later reset
+ some vcpu not create, later create BUT never run. This may prevent other
   vCPU threads from using the mpidr_data, because they rely on the vCPU that
   destroys the mpidr_data to trigger a rebuild. (Although we can rebuild
   mpidr_data when resetting the vCPU(just for later-created vcpu), it is
   preferable to defer the rebuild until after all destruction actions have
   been completed).

even, as mentioned above, userspace write MPIDR_EL1 to cause collisions. It
seems somewhat not worth the effort.

[1]: https://github.com/cai-fuqiang/armkvm/commit/eeda9309e0a6c700449e90cf27127a7e4e0238ed
[2]: https://lore.kernel.org/all/20240508071952.2035422-1-oliver.upton@linux.dev/#r

> 
> Detecting collisions is difficult, as we have no idea of the overall
> guest topology. All we can do is work out whether the computed mask
> has enough bits to represent the number of online vcpus, but that's
> not necessarily good enough.
> 
> One possibility would be to invalidate the cache on each update to any
> MPIDR_EL1, including reset. People doing silly things by initialising
> vcpus post first start will still suffer, but should we care?

However, could we detect collisions within the init function and, upon
detection, notify userspace without taking any corrective or fallback
action? This would serve as a stronger reminder to userspace of its
non-compliant behavior.

e.g.

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3732ee9eb0d4..7563feab1a11 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -893,6 +893,17 @@ static void kvm_init_mpidr_data(struct kvm *kvm)
                 data->cmpidr_to_idx[index] = c;
         }

+       kvm_for_each_vcpu(c, vcpu, kvm) {
+               u64 aff = kvm_vcpu_get_mpidr_aff(vcpu);
+               u16 index = kvm_mpidr_index(data, aff);
+
+               if (data->cmpidr_to_idx[index] != c) {
+                       pr_warn("Multiple vCPUs share the same MPIDR value, "
+                               "it may cause the guest to hang or run slower\n");
+                       break;
+               }
+       }
+
         rcu_assign_pointer(kvm->arch.mpidr_data, data);
  out:
         mutex_unlock(&kvm->arch.config_lock);


Thanks
fuqiang

> 
> Thanks,
> 
> 	M.
> 


  reply	other threads:[~2026-06-18 11:38 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-11 14:40 [PATCH v2 0/2] KVM: arm64: Fix MPIDR lookup for unreset vCPUs fuqiang wang
2026-06-11 14:40 ` [PATCH v2 1/2] arm64: Add MPIDR_EL1 RES1 definitions fuqiang wang
2026-06-11 14:40 ` [PATCH v2 2/2] KVM: arm64: Skip unreset vCPUs in MPIDR lookup table fuqiang wang
2026-06-14  9:26   ` Marc Zyngier
2026-06-15  4:20     ` Oliver Upton
2026-06-15 10:08       ` Marc Zyngier
2026-06-18 11:38         ` fuqiang wang [this message]
2026-06-18 12:32           ` Marc Zyngier

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=ef4bd4eb-f67a-4a44-a548-08240c2eba30@gmail.com \
    --to=fuqiang.wng@gmail.com \
    --cc=diaojiaqing.1@jd.com \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=wangfuqiang49@jd.com \
    --cc=xu910121@sina.com \
    --cc=yuzenghui@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.