qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP


From: Matt Gingell
Subject: [Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP
Date: Fri, 13 Nov 2015 15:25:21 -0800

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 <address@hidden>
---
 hw/core/machine.c    | 48 ++++++++++++++++++++++++++++++++++++++----------
 include/hw/boards.h  |  2 ++
 include/hw/i386/pc.h |  9 +++++++++
 include/sysemu/kvm.h | 11 +++++++++++
 qapi/common.json     | 16 ++++++++++++++++
 qemu-options.hx      |  3 ++-
 6 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index f4db340..3c14e78 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,34 @@ 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)
 {
-    MachineState *ms = MACHINE(obj);
-
-    ms->kernel_irqchip_allowed = value;
-    ms->kernel_irqchip_required = value;
+    OnOffSplit mode;
+    MachineState *ms = MACHINE(obj);
+
+    visit_type_OnOffSplit(v, &mode, name, errp);
+    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:
+        error_report("Option 'kernel-irqchip' must be one of on|off|split");
+        exit(1);
+    }
 }
 
 static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v,
@@ -341,12 +364,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,
@@ -477,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/include/hw/boards.h b/include/hw/boards.h
index 3e9a92c..f647993 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -36,6 +36,7 @@ bool machine_usb(MachineState *machine);
 bool machine_iommu(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);
@@ -107,6 +108,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/hw/i386/pc.h b/include/hw/i386/pc.h
index 4bbc0ff..e74106c 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -125,6 +125,15 @@ void hmp_info_irq(Monitor *mon, const QDict *qdict);
 
 /* ioapic.c */
 
+#define kvm_pit_in_kernel() \
+    (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_pic_in_kernel()  \
+    (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_ioapic_in_kernel() \
+    (kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_apic_in_kernel() \
+    (kvm_irqchip_in_kernel())
+
 void kvm_ioapic_dump_state(Monitor *mon, const QDict *qdict);
 void ioapic_dump_state(Monitor *mon, const QDict *qdict);
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 4ac6176..d34bbe6 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_direct_msi_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 bad56bf..dfc3b10 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -114,3 +114,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 0eea4ee..5affc82e 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
-- 
2.6.0.rc2.230.g3dd15c0





reply via email to

[Prev in Thread] Current Thread [Next in Thread]