All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP
@ 2015-11-13 23:25 Matt Gingell
  2015-11-14  0:11 ` Eric Blake
  0 siblings, 1 reply; 4+ messages in thread
From: Matt Gingell @ 2015-11-13 23:25 UTC (permalink / raw)
  To: qemu-devel

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>
---
 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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP
  2015-11-13 23:25 [Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP Matt Gingell
@ 2015-11-14  0:11 ` Eric Blake
  2015-11-16 18:03   ` Matt Gingell
  2015-11-16 18:03   ` [Qemu-devel] [PATCH v2 " Matt Gingell
  0 siblings, 2 replies; 4+ messages in thread
From: Eric Blake @ 2015-11-14  0:11 UTC (permalink / raw)
  To: Matt Gingell, qemu-devel, Markus Armbruster

[-- Attachment #1: Type: text/plain, Size: 4307 bytes --]

On 11/13/2015 04:25 PM, Matt Gingell wrote:

[meta-comment:]  This patch was sent without an In-Reply-To header tying
it back to the 0/2 cover letter, which means mailers render it as its
own thread.  Git 'send-email' can do proper threading with the right
settings (although I'm not sure exactly what to suggest tweaking, if the
defaults aren't already right).

> 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>
> ---

> -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) {

'mode' starts life uninitialized, and the current contract of
visit_type_OnOffSplit (or any visit_type_Enum, for that matter) is that
it is left unchanged except on success (see
qapi/qapi-visit-core.c:input_type_enum() for the implementation).
However, you are blindly calling switch without checking whether an
error was reported, which could lead to spurious code behavior depending
on what was previously on the stack.

Arguably, we could fix the qapi generator for visit_type_Enum() to set
the parameter to the sentinel _MAX value on error, to make buggy code
like this less likely to do the wrong things on uninitialized input.	But
I don't know if that is a bug worth fixing during 2.5 hardfreeze (it's
more likely to expose other bugs, but why not let sleeping dogs lie
rather than risk regressions where things happened to work by chance).

So, your choices are to pre-initialize mode to a sane sentinel value, or
else check for error before switching on mode (and remember that you
can't check errp directly, but would need a local err, since the caller
may have passed in errp==NULL).  Or in code, either:

OnOffSplit mode = ON_OFF_SPLIT_MAX;
visit_type_OnOffSplit(v, &mode, name, errp);
switch (mode) {
case ON_OFF_SPLIT_MAX:
 // flag invalid input; errp already contains potentially nice message

or:

OnOffSplit mode;
Error *err = NULL;
visit_type_OnOffSplit(v, &mode, name, &err);
if (err) {
    // handle err, perhaps with error_propagate()
} else {
    switch (mode) {
    case ON_OFF_SPLIT_ON:
    case ON_OFF_SPLIT_OFF:
    case ON_OFF_SPLIT_SPLIT:
       // handle
       break;
    default:
       abort(); // unreachable
}

> +    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);

Eww. Why are you calling exit() in a function that already returns errp?
 Shouldn't you instead just bubble the error up the stack?


> +++ 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' ] }

Use of qapi for the enum mapping looks sane.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP
  2015-11-14  0:11 ` Eric Blake
@ 2015-11-16 18:03   ` Matt Gingell
  2015-11-16 18:03   ` [Qemu-devel] [PATCH v2 " Matt Gingell
  1 sibling, 0 replies; 4+ messages in thread
From: Matt Gingell @ 2015-11-16 18:03 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, Markus Armbruster

Hi Eric,

Thanks for your comments. I’m submitting a v2 based on your feedback.

Matt

> On Nov 13, 2015, at 4:11 PM, Eric Blake <eblake@redhat.com> wrote:
> 
> On 11/13/2015 04:25 PM, Matt Gingell wrote:
> 
> [meta-comment:]  This patch was sent without an In-Reply-To header tying
> it back to the 0/2 cover letter, which means mailers render it as its
> own thread.  Git 'send-email' can do proper threading with the right
> settings (although I'm not sure exactly what to suggest tweaking, if the
> defaults aren't already right).
> 
>> 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>
>> ---
> 
>> -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) {
> 
> 'mode' starts life uninitialized, and the current contract of
> visit_type_OnOffSplit (or any visit_type_Enum, for that matter) is that
> it is left unchanged except on success (see
> qapi/qapi-visit-core.c:input_type_enum() for the implementation).
> However, you are blindly calling switch without checking whether an
> error was reported, which could lead to spurious code behavior depending
> on what was previously on the stack.
> 
> Arguably, we could fix the qapi generator for visit_type_Enum() to set
> the parameter to the sentinel _MAX value on error, to make buggy code
> like this less likely to do the wrong things on uninitialized input.	But
> I don't know if that is a bug worth fixing during 2.5 hardfreeze (it's
> more likely to expose other bugs, but why not let sleeping dogs lie
> rather than risk regressions where things happened to work by chance).
> 
> So, your choices are to pre-initialize mode to a sane sentinel value, or
> else check for error before switching on mode (and remember that you
> can't check errp directly, but would need a local err, since the caller
> may have passed in errp==NULL).  Or in code, either:
> 
> OnOffSplit mode = ON_OFF_SPLIT_MAX;
> visit_type_OnOffSplit(v, &mode, name, errp);
> switch (mode) {
> case ON_OFF_SPLIT_MAX:
> // flag invalid input; errp already contains potentially nice message
> 
> or:
> 
> OnOffSplit mode;
> Error *err = NULL;
> visit_type_OnOffSplit(v, &mode, name, &err);
> if (err) {
>    // handle err, perhaps with error_propagate()
> } else {
>    switch (mode) {
>    case ON_OFF_SPLIT_ON:
>    case ON_OFF_SPLIT_OFF:
>    case ON_OFF_SPLIT_SPLIT:
>       // handle
>       break;
>    default:
>       abort(); // unreachable
> }
> 
>> +    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);
> 
> Eww. Why are you calling exit() in a function that already returns errp?
> Shouldn't you instead just bubble the error up the stack?
> 
> 
>> +++ 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' ] }
> 
> Use of qapi for the enum mapping looks sane.
> 
> -- 
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/2] add support for KVM_CAP_SPLIT_IRQCHIP
  2015-11-14  0:11 ` Eric Blake
  2015-11-16 18:03   ` Matt Gingell
@ 2015-11-16 18:03   ` Matt Gingell
  1 sibling, 0 replies; 4+ messages in thread
From: Matt Gingell @ 2015-11-16 18:03 UTC (permalink / raw)
  To: qemu-devel

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>
---
 hw/core/machine.c    | 49 +++++++++++++++++++++++++++++++++++++++++--------
 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, 81 insertions(+), 9 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index f4db340..41683c8 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,
@@ -477,6 +505,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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-11-16 18:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-13 23:25 [Qemu-devel] [PATCH 1/2] add support for KVM_CAP_SPLIT_IRQCHIP Matt Gingell
2015-11-14  0:11 ` Eric Blake
2015-11-16 18:03   ` Matt Gingell
2015-11-16 18:03   ` [Qemu-devel] [PATCH v2 " Matt Gingell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.