From 32c18a2dbaf79c241eddabd19a3b410bab5bf0cc Mon Sep 17 00:00:00 2001 From: Matt Gingell Date: Mon, 16 Nov 2015 10:03:06 -0800 Subject: [PATCH] kvm: add support for -machine kernel_irqchip=split This patch adds the initial plumbing for split IRQ chip mode via KVM_CAP_SPLIT_IRQCHIP. In addition to option processing, a number of kvm_*_in_kernel macros are defined to help clarify which component is where. Signed-off-by: Matt Gingell Signed-off-by: Paolo Bonzini --- hw/core/machine.c | 49 ++++++++++++++++++++++++++++++++++++-------- hw/i386/pc_piix.c | 1 + include/hw/boards.h | 2 ++ include/sysemu/kvm.h | 11 ++++++++++ qapi/common.json | 16 +++++++++++++++ qemu-options.hx | 3 ++- 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; @@ -70,6 +71,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: * 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