On 2026/7/10 上午8:50, Tao Cui wrote:
From: Tao Cui <[email protected]>
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 <[email protected]>
---
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.
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?
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;