When userspace (e.g., QEMU) sets PV features via KVM_SET_DEVICE_ATTR with CPUCFG_KVM_FEATURE, it completely replaces the kernel-default pv_features. This causes features auto-enabled by the kernel (such as KVM_FEATURE_STEAL_TIME) to be lost if userspace doesn't explicitly include them. Add a pv_auto_features field to struct kvm_arch that saves the kernel-default PV features set during kvm_vm_init_features(). When userspace overrides pv_features, OR the saved auto features back to preserve them. Signed-off-by: Tao Cui --- arch/loongarch/include/asm/kvm_host.h | 2 ++ arch/loongarch/kvm/vcpu.c | 2 +- arch/loongarch/kvm/vm.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h index 776bc487a705..903cb67ca817 100644 --- a/arch/loongarch/include/asm/kvm_host.h +++ b/arch/loongarch/include/asm/kvm_host.h @@ -127,6 +127,8 @@ struct kvm_arch { struct kvm_phyid_map *phyid_map; /* Enabled PV features */ unsigned long pv_features; + /* PV features auto-enabled by kernel */ + unsigned long pv_auto_features; /* Supported KVM features */ unsigned long kvm_features; diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index e28084c49e68..d82782b90457 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1169,7 +1169,7 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu, if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED) && ((kvm->arch.pv_features & valid) != val)) return -EINVAL; - kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED; + kvm->arch.pv_features = (val | kvm->arch.pv_auto_features) | LOONGARCH_PV_FEAT_UPDATED; return 0; default: return -ENXIO; diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c index 1317c718f896..8af874e0b36b 100644 --- a/arch/loongarch/kvm/vm.c +++ b/arch/loongarch/kvm/vm.c @@ -57,6 +57,7 @@ static void kvm_vm_init_features(struct kvm *kvm) kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PV_PREEMPT); kvm->arch.kvm_features |= BIT(KVM_LOONGARCH_VM_FEAT_PV_STEALTIME); } + kvm->arch.pv_auto_features = kvm->arch.pv_features; } int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) -- 2.43.0