aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/core/machine.c49
-rw-r--r--hw/i386/pc_piix.c1
-rw-r--r--include/hw/boards.h2
-rw-r--r--include/sysemu/kvm.h11
-rw-r--r--qapi/common.json16
-rw-r--r--qemu-options.hx3
6 files changed, 73 insertions, 9 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c
index acca00db22..82be54e751 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -11,6 +11,7 @@
*/
#include "hw/boards.h"
+#include "qapi-visit.h"
#include "qapi/visitor.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
@@ -31,12 +32,39 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
ms->accel = g_strdup(value);
}
-static void machine_set_kernel_irqchip(Object *obj, bool value, Error **errp)
+static void machine_set_kernel_irqchip(Object *obj, Visitor *v,
+ void *opaque, const char *name,
+ Error **errp)
{
+ Error *err = NULL;
MachineState *ms = MACHINE(obj);
+ OnOffSplit mode;
- ms->kernel_irqchip_allowed = value;
- ms->kernel_irqchip_required = value;
+ visit_type_OnOffSplit(v, &mode, name, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ } else {
+ switch (mode) {
+ case ON_OFF_SPLIT_ON:
+ ms->kernel_irqchip_allowed = true;
+ ms->kernel_irqchip_required = true;
+ ms->kernel_irqchip_split = false;
+ break;
+ case ON_OFF_SPLIT_OFF:
+ ms->kernel_irqchip_allowed = false;
+ ms->kernel_irqchip_required = false;
+ ms->kernel_irqchip_split = false;
+ break;
+ case ON_OFF_SPLIT_SPLIT:
+ ms->kernel_irqchip_allowed = true;
+ ms->kernel_irqchip_required = true;
+ ms->kernel_irqchip_split = true;
+ break;
+ default:
+ abort();
+ }
+ }
}
static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v,
@@ -341,12 +369,12 @@ static void machine_initfn(Object *obj)
object_property_set_description(obj, "accel",
"Accelerator list",
NULL);
- object_property_add_bool(obj, "kernel-irqchip",
- NULL,
- machine_set_kernel_irqchip,
- NULL);
+ object_property_add(obj, "kernel-irqchip", "OnOffSplit",
+ NULL,
+ machine_set_kernel_irqchip,
+ NULL, NULL, NULL);
object_property_set_description(obj, "kernel-irqchip",
- "Use KVM in-kernel irqchip",
+ "Configure KVM in-kernel irqchip",
NULL);
object_property_add(obj, "kvm-shadow-mem", "int",
machine_get_kvm_shadow_mem,
@@ -472,6 +500,11 @@ bool machine_kernel_irqchip_required(MachineState *machine)
return machine->kernel_irqchip_required;
}
+bool machine_kernel_irqchip_split(MachineState *machine)
+{
+ return machine->kernel_irqchip_split;
+}
+
int machine_kvm_shadow_mem(MachineState *machine)
{
return machine->kvm_shadow_mem;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index abb377aab9..6a498a20d3 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -53,6 +53,7 @@
#include "hw/xen/xen_pt.h"
#endif
#include "migration/migration.h"
+#include "kvm_i386.h"
#define MAX_IDE_BUS 2
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 5da4fb00ee..f19df9769c 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -35,6 +35,7 @@ extern MachineState *current_machine;
bool machine_usb(MachineState *machine);
bool machine_kernel_irqchip_allowed(MachineState *machine);
bool machine_kernel_irqchip_required(MachineState *machine);
+bool machine_kernel_irqchip_split(MachineState *machine);
int machine_kvm_shadow_mem(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
@@ -111,6 +112,7 @@ struct MachineState {
char *accel;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
+ bool kernel_irqchip_split;
int kvm_shadow_mem;
char *dtb;
char *dumpdtb;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 9a569f1f46..c8f43dc82d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -43,6 +43,7 @@
extern bool kvm_allowed;
extern bool kvm_kernel_irqchip;
+extern bool kvm_split_irqchip;
extern bool kvm_async_interrupts_allowed;
extern bool kvm_halt_in_kernel_allowed;
extern bool kvm_eventfds_allowed;
@@ -71,6 +72,16 @@ extern bool kvm_ioeventfd_any_length_allowed;
#define kvm_irqchip_in_kernel() (kvm_kernel_irqchip)
/**
+ * kvm_irqchip_is_split:
+ *
+ * Returns: true if the user asked us to split the irqchip
+ * implementation between user and kernel space. The details are
+ * architecture and machine specific. On PC, it means that the PIC,
+ * IOAPIC, and PIT are in user space while the LAPIC is in the kernel.
+ */
+#define kvm_irqchip_is_split() (kvm_split_irqchip)
+
+/**
* kvm_async_interrupts_enabled:
*
* Returns: true if we can deliver interrupts to KVM
diff --git a/qapi/common.json b/qapi/common.json
index 6fb40e7a15..9353a7b377 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -115,3 +115,19 @@
##
{ 'enum': 'OnOffAuto',
'data': [ 'auto', 'on', 'off' ] }
+
+##
+# @OnOffSplit
+#
+# An enumeration of three values: on, off, and split
+#
+# @on: Enabled
+#
+# @off: Disabled
+#
+# @split: Mixed
+#
+# Since: 2.6
+##
+{ 'enum': 'OnOffSplit',
+ 'data': [ 'on', 'off', 'split' ] }
diff --git a/qemu-options.hx b/qemu-options.hx
index 0eea4ee9e9..5affc82e4c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -33,6 +33,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, tcg (default: tcg)\n"
" kernel_irqchip=on|off controls accelerated irqchip support\n"
+ " kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n"
" vmport=on|off|auto controls emulation of vmport (default: auto)\n"
" kvm_shadow_mem=size of KVM shadow MMU\n"
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
@@ -55,7 +56,7 @@ kvm, xen, or tcg can be available. By default, tcg is used. If there is more
than one accelerator specified, the next one is used if the previous one fails
to initialize.
@item kernel_irqchip=on|off
-Enables in-kernel irqchip support for the chosen accelerator when available.
+Controls in-kernel irqchip support for the chosen accelerator when available.
@item gfx_passthru=on|off
Enables IGD GFX passthrough support for the chosen machine when available.
@item vmport=on|off|auto