aboutsummaryrefslogtreecommitdiff
path: root/target/loongarch/kvm/kvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/loongarch/kvm/kvm.c')
-rw-r--r--target/loongarch/kvm/kvm.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 28735c8..e5ea2db 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -18,7 +18,7 @@
#include "system/kvm_int.h"
#include "hw/pci/pci.h"
#include "exec/memattrs.h"
-#include "exec/address-spaces.h"
+#include "system/address-spaces.h"
#include "hw/boards.h"
#include "hw/irq.h"
#include "hw/loongarch/virt.h"
@@ -1071,7 +1071,11 @@ static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp)
env->pv_features |= BIT(KVM_FEATURE_VIRT_EXTIOI);
}
}
+ return 0;
+}
+int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)
+{
return 0;
}
@@ -1080,9 +1084,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
uint64_t val;
int ret;
Error *local_err = NULL;
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
- ret = 0;
- qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
+ cpu->vmsentry = qemu_add_vm_change_state_handler(
+ kvm_loongarch_vm_stage_change, cs);
if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
brk_insn = val;
@@ -1091,29 +1096,34 @@ int kvm_arch_init_vcpu(CPUState *cs)
ret = kvm_cpu_check_lsx(cs, &local_err);
if (ret < 0) {
error_report_err(local_err);
+ return ret;
}
ret = kvm_cpu_check_lasx(cs, &local_err);
if (ret < 0) {
error_report_err(local_err);
+ return ret;
}
ret = kvm_cpu_check_lbt(cs, &local_err);
if (ret < 0) {
error_report_err(local_err);
+ return ret;
}
ret = kvm_cpu_check_pmu(cs, &local_err);
if (ret < 0) {
error_report_err(local_err);
+ return ret;
}
ret = kvm_cpu_check_pv_features(cs, &local_err);
if (ret < 0) {
error_report_err(local_err);
+ return ret;
}
- return ret;
+ return 0;
}
static bool loongarch_get_lbt(Object *obj, Error **errp)
@@ -1193,6 +1203,9 @@ void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
int kvm_arch_destroy_vcpu(CPUState *cs)
{
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+
+ qemu_del_vm_change_state_handler(cpu->vmsentry);
return 0;
}
@@ -1227,6 +1240,22 @@ void kvm_arch_init_irq_routing(KVMState *s)
{
}
+void kvm_loongarch_init_irq_routing(void)
+{
+ int i;
+
+ kvm_async_interrupts_allowed = true;
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
+ if (kvm_has_gsi_routing()) {
+ for (i = 0; i < KVM_IRQCHIP_NUM_PINS; ++i) {
+ kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
+ }
+
+ kvm_gsi_routing_allowed = true;
+ kvm_irqchip_commit_routes(kvm_state);
+ }
+}
+
int kvm_arch_get_default_type(MachineState *ms)
{
return 0;
@@ -1240,7 +1269,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
int kvm_arch_irqchip_create(KVMState *s)
{
- return 0;
+ if (kvm_kernel_irqchip_split()) {
+ error_report("kernel_irqchip=split is not supported on LoongArch");
+ exit(1);
+ }
+
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
}
void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)