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 <gingell@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Matt Gingell 2015-11-16 10:03:06 -08:00 committed by Paolo Bonzini
parent ff99aa64b1
commit 32c18a2dba
6 changed files with 73 additions and 9 deletions

View File

@ -11,6 +11,7 @@
*/ */
#include "hw/boards.h" #include "hw/boards.h"
#include "qapi-visit.h"
#include "qapi/visitor.h" #include "qapi/visitor.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "sysemu/sysemu.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); 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); MachineState *ms = MACHINE(obj);
OnOffSplit mode;
ms->kernel_irqchip_allowed = value; visit_type_OnOffSplit(v, &mode, name, &err);
ms->kernel_irqchip_required = value; 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, 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", object_property_set_description(obj, "accel",
"Accelerator list", "Accelerator list",
NULL); NULL);
object_property_add_bool(obj, "kernel-irqchip", object_property_add(obj, "kernel-irqchip", "OnOffSplit",
NULL, NULL,
machine_set_kernel_irqchip, machine_set_kernel_irqchip,
NULL); NULL, NULL, NULL);
object_property_set_description(obj, "kernel-irqchip", object_property_set_description(obj, "kernel-irqchip",
"Use KVM in-kernel irqchip", "Configure KVM in-kernel irqchip",
NULL); NULL);
object_property_add(obj, "kvm-shadow-mem", "int", object_property_add(obj, "kvm-shadow-mem", "int",
machine_get_kvm_shadow_mem, machine_get_kvm_shadow_mem,
@ -472,6 +500,11 @@ bool machine_kernel_irqchip_required(MachineState *machine)
return machine->kernel_irqchip_required; return machine->kernel_irqchip_required;
} }
bool machine_kernel_irqchip_split(MachineState *machine)
{
return machine->kernel_irqchip_split;
}
int machine_kvm_shadow_mem(MachineState *machine) int machine_kvm_shadow_mem(MachineState *machine)
{ {
return machine->kvm_shadow_mem; return machine->kvm_shadow_mem;

View File

@ -53,6 +53,7 @@
#include "hw/xen/xen_pt.h" #include "hw/xen/xen_pt.h"
#endif #endif
#include "migration/migration.h" #include "migration/migration.h"
#include "kvm_i386.h"
#define MAX_IDE_BUS 2 #define MAX_IDE_BUS 2

View File

@ -35,6 +35,7 @@ extern MachineState *current_machine;
bool machine_usb(MachineState *machine); bool machine_usb(MachineState *machine);
bool machine_kernel_irqchip_allowed(MachineState *machine); bool machine_kernel_irqchip_allowed(MachineState *machine);
bool machine_kernel_irqchip_required(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_kvm_shadow_mem(MachineState *machine);
int machine_phandle_start(MachineState *machine); int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine); bool machine_dump_guest_core(MachineState *machine);
@ -111,6 +112,7 @@ struct MachineState {
char *accel; char *accel;
bool kernel_irqchip_allowed; bool kernel_irqchip_allowed;
bool kernel_irqchip_required; bool kernel_irqchip_required;
bool kernel_irqchip_split;
int kvm_shadow_mem; int kvm_shadow_mem;
char *dtb; char *dtb;
char *dumpdtb; char *dumpdtb;

View File

@ -43,6 +43,7 @@
extern bool kvm_allowed; extern bool kvm_allowed;
extern bool kvm_kernel_irqchip; extern bool kvm_kernel_irqchip;
extern bool kvm_split_irqchip;
extern bool kvm_async_interrupts_allowed; extern bool kvm_async_interrupts_allowed;
extern bool kvm_halt_in_kernel_allowed; extern bool kvm_halt_in_kernel_allowed;
extern bool kvm_eventfds_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) #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: * kvm_async_interrupts_enabled:
* *

View File

@ -115,3 +115,19 @@
## ##
{ 'enum': 'OnOffAuto', { 'enum': 'OnOffAuto',
'data': [ 'auto', 'on', 'off' ] } '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' ] }

View File

@ -33,6 +33,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" property accel=accel1[:accel2[:...]] selects accelerator\n" " property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, tcg (default: tcg)\n" " supported accelerators are kvm, xen, tcg (default: tcg)\n"
" kernel_irqchip=on|off controls accelerated irqchip support\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" " vmport=on|off|auto controls emulation of vmport (default: auto)\n"
" kvm_shadow_mem=size of KVM shadow MMU\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" " 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 than one accelerator specified, the next one is used if the previous one fails
to initialize. to initialize.
@item kernel_irqchip=on|off @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 @item gfx_passthru=on|off
Enables IGD GFX passthrough support for the chosen machine when available. Enables IGD GFX passthrough support for the chosen machine when available.
@item vmport=on|off|auto @item vmport=on|off|auto