target/loongarch: Add paravirt ipi feature detection

Paravirt ipi feature is OnOffAuto type, feature detection is added
to check whether it is supported by KVM host.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
This commit is contained in:
Bibo Mao 2025-02-17 09:52:40 +08:00
parent 5b0502c564
commit 620d9bd002
2 changed files with 37 additions and 1 deletions

View file

@ -287,6 +287,7 @@ enum loongarch_features {
LOONGARCH_FEATURE_LASX, LOONGARCH_FEATURE_LASX,
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
LOONGARCH_FEATURE_PMU, LOONGARCH_FEATURE_PMU,
LOONGARCH_FEATURE_PV_IPI,
}; };
typedef struct LoongArchBT { typedef struct LoongArchBT {
@ -310,6 +311,7 @@ typedef struct CPUArchState {
lbt_t lbt; lbt_t lbt;
uint32_t cpucfg[21]; uint32_t cpucfg[21];
uint32_t pv_features;
/* LoongArch CSRs */ /* LoongArch CSRs */
uint64_t CSR_CRMD; uint64_t CSR_CRMD;

View file

@ -8,7 +8,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/kvm.h> #include <linux/kvm.h>
#include "asm-loongarch/kvm_para.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/timer.h" #include "qemu/timer.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
@ -882,6 +882,12 @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
return (ret == 0); return (ret == 0);
case LOONGARCH_FEATURE_PV_IPI:
attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
attr.attr = KVM_LOONGARCH_VM_FEAT_PV_IPI;
ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
return (ret == 0);
default: default:
return false; return false;
} }
@ -980,6 +986,29 @@ static int kvm_cpu_check_pmu(CPUState *cs, Error **errp)
return 0; return 0;
} }
static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
CPULoongArchState *env = cpu_env(cs);
bool kvm_supported;
kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PV_IPI);
if (cpu->kvm_pv_ipi == ON_OFF_AUTO_ON) {
if (!kvm_supported) {
error_setg(errp, "'pv_ipi' feature not supported by KVM host");
return -ENOTSUP;
}
} else if (cpu->kvm_pv_ipi != ON_OFF_AUTO_AUTO) {
kvm_supported = false;
}
if (kvm_supported) {
env->pv_features |= BIT(KVM_FEATURE_IPI);
}
return 0;
}
int kvm_arch_init_vcpu(CPUState *cs) int kvm_arch_init_vcpu(CPUState *cs)
{ {
uint64_t val; uint64_t val;
@ -1013,6 +1042,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
error_report_err(local_err); error_report_err(local_err);
} }
ret = kvm_cpu_check_pv_features(cs, &local_err);
if (ret < 0) {
error_report_err(local_err);
}
return ret; return ret;
} }