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


Reply via email to