aboutsummaryrefslogtreecommitdiff
path: root/accel
diff options
context:
space:
mode:
Diffstat (limited to 'accel')
-rw-r--r--accel/kvm/kvm-all.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 34e8f26d6a..b2f1a5bcb5 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -42,6 +42,8 @@
#include "sysemu/sev.h"
#include "sysemu/balloon.h"
#include "qapi/visitor.h"
+#include "qapi/qapi-types-common.h"
+#include "qapi/qapi-visit-common.h"
#include "hw/boards.h"
@@ -94,6 +96,9 @@ struct KVMState
int many_ioeventfds;
int intx_set_mask;
int kvm_shadow_mem;
+ bool kernel_irqchip_allowed;
+ bool kernel_irqchip_required;
+ bool kernel_irqchip_split;
bool sync_mmu;
bool manual_dirty_log_protect;
/* The man page (and posix) say ioctl numbers are signed int, but
@@ -1794,7 +1799,7 @@ static void kvm_irqchip_create(KVMState *s)
* in-kernel irqchip for us */
ret = kvm_arch_irqchip_create(s);
if (ret == 0) {
- if (kvm_kernel_irqchip_split()) {
+ if (s->kernel_irqchip_split) {
perror("Split IRQ chip mode not supported.");
exit(1);
} else {
@@ -2065,7 +2070,7 @@ static int kvm_init(MachineState *ms)
goto err;
}
- if (machine_kernel_irqchip_allowed(ms)) {
+ if (s->kernel_irqchip_allowed) {
kvm_irqchip_create(s);
}
@@ -2983,19 +2988,57 @@ static void kvm_set_kvm_shadow_mem(Object *obj, Visitor *v,
s->kvm_shadow_mem = value;
}
+static void kvm_set_kernel_irqchip(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ Error *err = NULL;
+ KVMState *s = KVM_STATE(obj);
+ OnOffSplit mode;
+
+ visit_type_OnOffSplit(v, name, &mode, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ } else {
+ switch (mode) {
+ case ON_OFF_SPLIT_ON:
+ s->kernel_irqchip_allowed = true;
+ s->kernel_irqchip_required = true;
+ s->kernel_irqchip_split = false;
+ break;
+ case ON_OFF_SPLIT_OFF:
+ s->kernel_irqchip_allowed = false;
+ s->kernel_irqchip_required = false;
+ s->kernel_irqchip_split = false;
+ break;
+ case ON_OFF_SPLIT_SPLIT:
+ s->kernel_irqchip_allowed = true;
+ s->kernel_irqchip_required = true;
+ s->kernel_irqchip_split = true;
+ break;
+ default:
+ /* The value was checked in visit_type_OnOffSplit() above. If
+ * we get here, then something is wrong in QEMU.
+ */
+ abort();
+ }
+ }
+}
+
bool kvm_kernel_irqchip_allowed(void)
{
- return machine_kernel_irqchip_allowed(current_machine);
+ return kvm_state->kernel_irqchip_allowed;
}
bool kvm_kernel_irqchip_required(void)
{
- return machine_kernel_irqchip_required(current_machine);
+ return kvm_state->kernel_irqchip_required;
}
bool kvm_kernel_irqchip_split(void)
{
- return machine_kernel_irqchip_split(current_machine);
+ return kvm_state->kernel_irqchip_split;
}
static void kvm_accel_instance_init(Object *obj)
@@ -3013,6 +3056,12 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data)
ac->has_memory = kvm_accel_has_memory;
ac->allowed = &kvm_allowed;
+ object_class_property_add(oc, "kernel-irqchip", "on|off|split",
+ NULL, kvm_set_kernel_irqchip,
+ NULL, NULL, &error_abort);
+ object_class_property_set_description(oc, "kernel-irqchip",
+ "Configure KVM in-kernel irqchip", &error_abort);
+
object_class_property_add(oc, "kvm-shadow-mem", "int",
kvm_get_kvm_shadow_mem, kvm_set_kvm_shadow_mem,
NULL, NULL, &error_abort);