Paravirt preempt feature is OnOffAuto type, it is disabled by default, also the feature detection is added to check whether it is supported on KVM host.
Signed-off-by: Bibo Mao <[email protected]> --- target/loongarch/cpu.h | 2 ++ target/loongarch/kvm/kvm.c | 39 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index c592f69885..c6dad2417c 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -302,6 +302,7 @@ enum loongarch_features { LOONGARCH_FEATURE_STEALTIME, LOONGARCH_FEATURE_PTW, LOONGARCH_FEATURE_MSGINT, + LOONGARCH_FEATURE_PV_PREEMPT, }; typedef struct LoongArchBT { @@ -464,6 +465,7 @@ struct ArchCPU { OnOffAuto msgint; OnOffAuto kvm_pv_ipi; OnOffAuto kvm_steal_time; + OnOffAuto kvm_pv_preempt; int32_t socket_id; /* socket-id of this CPU */ int32_t core_id; /* core-id of this CPU */ int32_t thread_id; /* thread-id of this CPU */ diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 941142305e..7ca95181a1 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -1039,6 +1039,12 @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); return (ret == 0); + case LOONGARCH_FEATURE_PV_PREEMPT: + attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; + attr.attr = KVM_LOONGARCH_VM_FEAT_PV_PREEMPT, + ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); + return (ret == 0); + default: return false; } @@ -1203,6 +1209,21 @@ static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp) env->pv_features |= BIT(KVM_FEATURE_STEAL_TIME); } + kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PV_PREEMPT); + if (cpu->kvm_pv_preempt == ON_OFF_AUTO_ON) { + if (!kvm_supported) { + error_setg(errp, "'pv preempt' feature not supported by KVM host"); + return -ENOTSUP; + } + } else if (cpu->kvm_pv_preempt != ON_OFF_AUTO_AUTO) { + kvm_supported = false; + } + + /* Feature preempt_hint depends on steal_time */ + if (kvm_supported && (cpu->kvm_pv_preempt == ON_OFF_AUTO_ON)) { + env->pv_features |= BIT(KVM_FEATURE_PREEMPT); + } + if (object_dynamic_cast(OBJECT(ms), TYPE_LOONGARCH_VIRT_MACHINE)) { LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms); @@ -1412,6 +1433,18 @@ static void kvm_steal_time_set(Object *obj, bool value, Error **errp) cpu->kvm_steal_time = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; } +static bool kvm_pv_preempt_get(Object *obj, Error **errp) +{ + return LOONGARCH_CPU(obj)->kvm_pv_preempt != ON_OFF_AUTO_OFF; +} + +static void kvm_pv_preempt_set(Object *obj, bool value, Error **errp) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + + cpu->kvm_pv_preempt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu) { cpu->lbt = ON_OFF_AUTO_AUTO; @@ -1437,6 +1470,12 @@ void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu) kvm_steal_time_set); object_property_set_description(OBJECT(cpu), "kvm-steal-time", "Set off to disable KVM steal time."); + + cpu->kvm_pv_preempt = ON_OFF_AUTO_OFF; + object_property_add_bool(OBJECT(cpu), "kvm-pv-preempt", kvm_pv_preempt_get, + kvm_pv_preempt_set); + object_property_set_description(OBJECT(cpu), "kvm-pv-preempt", + "Set off to disable KVM paravirt preempt."); } int kvm_arch_destroy_vcpu(CPUState *cs) base-commit: c1c18d1e640b64292859ce9f30f3c344edfb0294 -- 2.54.0
