aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2025-02-17 09:37:11 +0800
committerBibo Mao <maobibo@loongson.cn>2025-02-25 16:05:31 +0800
commit2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d (patch)
tree527bd3c9cf5ea06f0d3bb9aaa890cac9e43d41f3
parent620d9bd0022e011147c1133ef542c45a0da962e4 (diff)
downloadqemu-2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d.zip
qemu-2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d.tar.gz
qemu-2698cc7c99b50cf4bb127c56e5c90f7f3cba6f0d.tar.bz2
target/loongarch: Enable paravirt ipi feature
The similiar with cpucfg register, paravirt ipi feature is set in function kvm_arch_put_registers(). Instead the paravirt feature can be enabled only once, it cannot be changed dynamically. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Bibo Mao <maobibo@loongson.cn>
-rw-r--r--target/loongarch/kvm/kvm.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 3117441..ed0706e 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -83,6 +83,33 @@ static int kvm_set_stealtime(CPUState *cs)
return 0;
}
+static int kvm_set_pv_features(CPUState *cs)
+{
+ CPULoongArchState *env = cpu_env(cs);
+ int err;
+ uint64_t val;
+ struct kvm_device_attr attr = {
+ .group = KVM_LOONGARCH_VCPU_CPUCFG,
+ .attr = CPUCFG_KVM_FEATURE,
+ .addr = (uint64_t)&val,
+ };
+
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
+ if (err) {
+ return 0;
+ }
+
+ val = env->pv_features;
+ err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
+ if (err) {
+ error_report("Fail to set pv feature "TARGET_FMT_lx " with error %s",
+ val, strerror(errno));
+ return err;
+ }
+
+ return 0;
+}
+
static int kvm_loongarch_get_regs_core(CPUState *cs)
{
int ret = 0;
@@ -738,6 +765,7 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp)
int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
{
int ret;
+ static int once;
ret = kvm_loongarch_put_regs_core(cs);
if (ret) {
@@ -764,6 +792,14 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
return ret;
}
+ if (!once) {
+ 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