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); 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; -- 2.43.0
