From: Tao Cui <cui.tao@linux.dev>
To: Bibo Mao <maobibo@loongson.cn>, qemu-devel@nongnu.org
Cc: cui.tao@linux.dev, "Song Gao" <gaosong@loongson.cn>,
"Jiaxun Yang" <jiaxun.yang@flygoat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@mailo.com>,
"Tao Cui" <cuitao@kylinos.cn>
Subject: Re: [PATCH v2 1/3] target/loongarch/kvm: advertise pv features per vCPU
Date: Fri, 10 Jul 2026 16:09:20 +0800 [thread overview]
Message-ID: <4f914264-be8e-4b5b-a54a-14a911855529@linux.dev> (raw)
In-Reply-To: <70dc23f1-f346-2d47-4a42-e2195ea9e622@loongson.cn>
在 2026/7/10 10:58, Bibo Mao 写道:
>
>
> On 2026/7/10 上午8:50, Tao Cui wrote:
>> From: Tao Cui <cuitao@kylinos.cn>
>>
>> kvm_set_pv_features() programs the KVM_FEATURE cpucfg attribute, which is a
>> per-vCPU setting. It was called from kvm_arch_put_registers() under a
>> function-local static guard, so it ran only once for the whole VM: only the
>> first vCPU got its pv features pushed to KVM, and on SMP guests the others
>> never saw KVM_FEATURE_IPI / KVM_FEATURE_STEAL_TIME.
>>
>> Drop the static guard and push pv features per vCPU under
>> KVM_PUT_FULL_STATE, the same gate kvm_set_stealtime() already uses. Host
>> feature detection stays in kvm_arch_init_vcpu(); the per-vCPU state write
>> belongs in kvm_arch_put_registers().
>>
>> Signed-off-by: Tao Cui <cuitao@kylinos.cn>
>> ---
>> target/loongarch/kvm/kvm.c | 15 ++++++---------
>> 1 file changed, 6 insertions(+), 9 deletions(-)
>>
>> diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
>> index d6539c12ac..c557ee3c3d 100644
>> --- a/target/loongarch/kvm/kvm.c
>> +++ b/target/loongarch/kvm/kvm.c
>> @@ -816,7 +816,6 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp)
>> int kvm_arch_put_registers(CPUState *cs, KvmPutState level, Error **errp)
>> {
>> int ret;
>> - static int once;
>> ret = kvm_loongarch_put_regs_core(cs);
>> if (ret) {
>> @@ -843,19 +842,17 @@ int kvm_arch_put_registers(CPUState *cs, KvmPutState level, Error **errp)
>> return ret;
>> }
>> - if (!once) {
>> + if (level >= KVM_PUT_FULL_STATE) {
>> + /*
>> + * pv_features and steal time are per-vCPU state. Push them on
>> + * full-state sync so every vCPU gets its own settings; the kernel
>> + * clears the steal-time guest_addr on KVM_PUT_RESET_STATE.
>> + */
>> ret = kvm_set_pv_features(cs);
> pv feature is a little different from steal-time. steal-time guest_addr is created from guest OS, pv feature is created from VMM at beginning. steal-time guest_addr can be set for many times, and there is bit KVM_STEAL_PHYS_VALID checking with steal-time guest_addr, however pv feature can be set only once with existing method.
>
Hi Bibo,
Thanks for catching this — I hadn't fully considered the double-call path.
KVM_PUT_FULL_STATE fires both at realize (cpu_synchronize_post_init) and
on incoming migration load (cpu_synchronize_all_post_init), so
kvm_set_pv_features() runs twice on the destination.
> Although I do not understand flow of VM migration, with KVM_PUT_FULL_STATE state changing, there are at least two places where this state is set, one is from cpu_common_realizefn() which calls cpu_synchronize_post_init(), the other is qemu_loadvm_state()/qemu_loadvm_state_main() which calls cpu_synchronize_all_post_init().
>
> It seems that VM will fail to migrate since kvm_set_pv_features is called twice at least here. Do you test VM migration with this patch?
I did test migration (virt-11.2 -> virt-11.2, virt-11.1 -> virt-11.1) and
it passed, but that was on a single host — source and destination computed
the same pv_features. The kernel (kvm_loongarch_cpucfg_set_attr) only
rejects a re-set when the value differs:
if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED) &&
((kvm->arch.pv_features & valid) != val))
return -EINVAL;
So a cross-host migration where the two sides compute different pv_features
would indeed fail on the second set.
I'll add a per-vCPU guard so the push happens exactly once (at the first
FULL_STATE sync); subsequent syncs are skipped and the destination keeps
advertising the features its own host supports. Does that sound like the
right direction?
Thanks,
Tao
>
> Regards
> Bibo Mao
>> if (ret) {
>> return ret;
>> }
>> - once = 1;
>> - }
>> - if (level >= KVM_PUT_FULL_STATE) {
>> - /*
>> - * only KVM_PUT_FULL_STATE is required, kvm kernel will clear
>> - * guest_addr for KVM_PUT_RESET_STATE
>> - */
>> ret = kvm_set_stealtime(cs);
>> if (ret) {
>> return ret;
>>
>
next prev parent reply other threads:[~2026-07-10 8:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 0:50 [PATCH v2 0/3] target/loongarch: advertise pv features per vCPU Tao Cui
2026-07-10 0:50 ` [PATCH v2 1/3] target/loongarch/kvm: " Tao Cui
2026-07-10 2:58 ` Bibo Mao
2026-07-10 8:09 ` Tao Cui [this message]
2026-07-10 8:44 ` Bibo Mao
2026-07-10 12:46 ` Tao Cui
2026-07-13 1:00 ` Bibo Mao
2026-07-10 0:50 ` [PATCH v2 2/3] target/loongarch: migrate pv_features in the vCPU VMState Tao Cui
2026-07-10 3:02 ` Bibo Mao
2026-07-10 3:15 ` Bibo Mao
2026-07-10 8:22 ` Tao Cui
2026-07-10 0:50 ` [PATCH v2 3/3] target/loongarch: add no_pv_feature compat flag Tao Cui
2026-07-10 3:09 ` Bibo Mao
2026-07-10 8:28 ` Tao Cui
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=4f914264-be8e-4b5b-a54a-14a911855529@linux.dev \
--to=cui.tao@linux.dev \
--cc=cuitao@kylinos.cn \
--cc=gaosong@loongson.cn \
--cc=jiaxun.yang@flygoat.com \
--cc=maobibo@loongson.cn \
--cc=pbonzini@redhat.com \
--cc=philmd@mailo.com \
--cc=qemu-devel@nongnu.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 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.