Re: [Qemu-devel] [PATCH v5 1/3] spapr: introduce a fixed IRQ number space

2018-07-30 Thread David Gibson
On Mon, Jul 30, 2018 at 11:05:58AM +0200, Cédric Le Goater wrote:
> On 07/27/2018 05:56 AM, David Gibson wrote:
> > On Thu, Jul 26, 2018 at 03:37:21PM +0200, Cédric Le Goater wrote:
> >> This proposal introduces a new IRQ number space layout using static
> >> numbers for all devices, depending on a device index, and a bitmap
> >> allocator for the MSI IRQ numbers which are negotiated by the guest at
> >> runtime.
> >>
> >> As the VIO device model does not have a device index but a "reg"
> >> property, we introduce a formula to compute an IRQ number from a "reg"
> >> value. It should minimize most of the collisions.
> >>
> >> The previous layout is kept in pre-3.1 machines raising the
> >> 'legacy_irq_allocation' machine class flag.
> >>
> >> Signed-off-by: Cédric Le Goater 
> > 
> > One nit left..
> > 
> > [snip]
> >> +static inline uint32_t spapr_vio_reg_to_irq(uint32_t reg)
> >> +{
> >> +uint32_t irq;
> >> +
> >> +if (reg >= SPAPR_VIO_REG_BASE) {
> >> +/*
> >> + * VIO device register values when allocated by QEMU. For
> >> + * these, we simply mask the high bits to fit the overall
> >> + * range: [0x00 - 0xff].
> >> + *
> >> + * The nvram VIO device (reg=0x7100) is a static device of
> >> + * the pseries machine and so is always allocated by QEMU. Its
> >> + * IRQ number is 0x0.
> >> + */
> >> +irq = reg & 0xff;
> >> +
> >> +} else if (reg >= 0x3000) {
> >> +/*
> >> + * VIO tty devices register values, when allocated by livirt,
> >> + * are mapped in range [0xf0 - 0xff], gives us a maximum of 16
> >> + * vtys.
> >> + */
> >> +irq = 0xf0 | ((reg >> 12) & 0xf);
> >> +
> >> +} else {
> >> +/*
> >> + * Other VIO devices register values, when allocated by
> >> + * livirt, are mapped in range [0x00 - 0xef].
> >> + */
> >> +irq = (reg >> 12) & 0xef;
> > 
> > This mask doesn't do what you intend - it will map 0x10 to 0, for
> > example.  You could use % 0xf0, but actually you might as well just
> > use & 0xff.  Yes, it could collide with the vty devices, but either
> > way you can still have collisions if you try hard enough.  And, either
> > way, they'll get detected later.
> > 
> 
> 
> David,
> 
> Shall I resend a v6 with this fix or should I wait for the patch adding 
> 3.1. I could also send a 3.1 pseries machine also if you prefer.

We'll need a pseries-3.1 at some point, so if you can send that, it
would be great.  Then I can stage the lot in ppc-for-3.1.  It might
need some tweaking before final merge, but that shouldn't be too hard.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v5 1/3] spapr: introduce a fixed IRQ number space

2018-07-30 Thread Cédric Le Goater
On 07/27/2018 05:56 AM, David Gibson wrote:
> On Thu, Jul 26, 2018 at 03:37:21PM +0200, Cédric Le Goater wrote:
>> This proposal introduces a new IRQ number space layout using static
>> numbers for all devices, depending on a device index, and a bitmap
>> allocator for the MSI IRQ numbers which are negotiated by the guest at
>> runtime.
>>
>> As the VIO device model does not have a device index but a "reg"
>> property, we introduce a formula to compute an IRQ number from a "reg"
>> value. It should minimize most of the collisions.
>>
>> The previous layout is kept in pre-3.1 machines raising the
>> 'legacy_irq_allocation' machine class flag.
>>
>> Signed-off-by: Cédric Le Goater 
> 
> One nit left..
> 
> [snip]
>> +static inline uint32_t spapr_vio_reg_to_irq(uint32_t reg)
>> +{
>> +uint32_t irq;
>> +
>> +if (reg >= SPAPR_VIO_REG_BASE) {
>> +/*
>> + * VIO device register values when allocated by QEMU. For
>> + * these, we simply mask the high bits to fit the overall
>> + * range: [0x00 - 0xff].
>> + *
>> + * The nvram VIO device (reg=0x7100) is a static device of
>> + * the pseries machine and so is always allocated by QEMU. Its
>> + * IRQ number is 0x0.
>> + */
>> +irq = reg & 0xff;
>> +
>> +} else if (reg >= 0x3000) {
>> +/*
>> + * VIO tty devices register values, when allocated by livirt,
>> + * are mapped in range [0xf0 - 0xff], gives us a maximum of 16
>> + * vtys.
>> + */
>> +irq = 0xf0 | ((reg >> 12) & 0xf);
>> +
>> +} else {
>> +/*
>> + * Other VIO devices register values, when allocated by
>> + * livirt, are mapped in range [0x00 - 0xef].
>> + */
>> +irq = (reg >> 12) & 0xef;
> 
> This mask doesn't do what you intend - it will map 0x10 to 0, for
> example.  You could use % 0xf0, but actually you might as well just
> use & 0xff.  Yes, it could collide with the vty devices, but either
> way you can still have collisions if you try hard enough.  And, either
> way, they'll get detected later.
> 


David,

Shall I resend a v6 with this fix or should I wait for the patch adding 
3.1. I could also send a 3.1 pseries machine also if you prefer.

Thanks,

C.



Re: [Qemu-devel] [PATCH v5 1/3] spapr: introduce a fixed IRQ number space

2018-07-26 Thread Cédric Le Goater
>> +/*
>> + * Other VIO devices register values, when allocated by
>> + * livirt, are mapped in range [0x00 - 0xef].
>> + */
>> +irq = (reg >> 12) & 0xef;
> 
> This mask doesn't do what you intend - it will map 0x10 to 0, for

oops. yes indeed.

> example.  You could use % 0xf0, but actually you might as well just
> use & 0xff.  Yes, it could collide with the vty devices, but either
> way you can still have collisions if you try hard enough.  
> And, either way, they'll get detected later.

I will do that.

C.




Re: [Qemu-devel] [PATCH v5 1/3] spapr: introduce a fixed IRQ number space

2018-07-26 Thread David Gibson
On Thu, Jul 26, 2018 at 03:37:21PM +0200, Cédric Le Goater wrote:
> This proposal introduces a new IRQ number space layout using static
> numbers for all devices, depending on a device index, and a bitmap
> allocator for the MSI IRQ numbers which are negotiated by the guest at
> runtime.
> 
> As the VIO device model does not have a device index but a "reg"
> property, we introduce a formula to compute an IRQ number from a "reg"
> value. It should minimize most of the collisions.
> 
> The previous layout is kept in pre-3.1 machines raising the
> 'legacy_irq_allocation' machine class flag.
> 
> Signed-off-by: Cédric Le Goater 

One nit left..

[snip]
> +static inline uint32_t spapr_vio_reg_to_irq(uint32_t reg)
> +{
> +uint32_t irq;
> +
> +if (reg >= SPAPR_VIO_REG_BASE) {
> +/*
> + * VIO device register values when allocated by QEMU. For
> + * these, we simply mask the high bits to fit the overall
> + * range: [0x00 - 0xff].
> + *
> + * The nvram VIO device (reg=0x7100) is a static device of
> + * the pseries machine and so is always allocated by QEMU. Its
> + * IRQ number is 0x0.
> + */
> +irq = reg & 0xff;
> +
> +} else if (reg >= 0x3000) {
> +/*
> + * VIO tty devices register values, when allocated by livirt,
> + * are mapped in range [0xf0 - 0xff], gives us a maximum of 16
> + * vtys.
> + */
> +irq = 0xf0 | ((reg >> 12) & 0xf);
> +
> +} else {
> +/*
> + * Other VIO devices register values, when allocated by
> + * livirt, are mapped in range [0x00 - 0xef].
> + */
> +irq = (reg >> 12) & 0xef;

This mask doesn't do what you intend - it will map 0x10 to 0, for
example.  You could use % 0xf0, but actually you might as well just
use & 0xff.  Yes, it could collide with the vty devices, but either
way you can still have collisions if you try hard enough.  And, either
way, they'll get detected later.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v5 1/3] spapr: introduce a fixed IRQ number space

2018-07-26 Thread Cédric Le Goater
This proposal introduces a new IRQ number space layout using static
numbers for all devices, depending on a device index, and a bitmap
allocator for the MSI IRQ numbers which are negotiated by the guest at
runtime.

As the VIO device model does not have a device index but a "reg"
property, we introduce a formula to compute an IRQ number from a "reg"
value. It should minimize most of the collisions.

The previous layout is kept in pre-3.1 machines raising the
'legacy_irq_allocation' machine class flag.

Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/spapr.h |  5 +++
 include/hw/ppc/spapr_irq.h | 32 +++
 hw/ppc/spapr.c | 32 ++-
 hw/ppc/spapr_events.c  | 12 ---
 hw/ppc/spapr_irq.c | 56 
 hw/ppc/spapr_pci.c | 29 +
 hw/ppc/spapr_vio.c | 65 ++
 hw/ppc/Makefile.objs   |  2 +-
 8 files changed, 214 insertions(+), 19 deletions(-)
 create mode 100644 include/hw/ppc/spapr_irq.h
 create mode 100644 hw/ppc/spapr_irq.c

diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 7e5de1a6fd42..73067f5ee8aa 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -8,6 +8,7 @@
 #include "hw/ppc/spapr_drc.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/ppc/spapr_ovec.h"
+#include "hw/ppc/spapr_irq.h"
 
 struct VIOsPAPRBus;
 struct sPAPRPHBState;
@@ -101,6 +102,8 @@ struct sPAPRMachineClass {
 bool dr_lmb_enabled;   /* enable dynamic-reconfig/hotplug of LMBs */
 bool use_ohci_by_default;  /* use USB-OHCI instead of XHCI */
 bool pre_2_10_has_unused_icps;
+bool legacy_irq_allocation;
+
 void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
   uint64_t *buid, hwaddr *pio, 
   hwaddr *mmio32, hwaddr *mmio64,
@@ -167,6 +170,8 @@ struct sPAPRMachineState {
 char *kvm_type;
 
 const char *icp_type;
+int32_t irq_map_nr;
+unsigned long *irq_map;
 
 bool cmd_line_caps[SPAPR_CAP_NUM];
 sPAPRCapabilities def, eff, mig;
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
new file mode 100644
index ..6f7f50548809
--- /dev/null
+++ b/include/hw/ppc/spapr_irq.h
@@ -0,0 +1,32 @@
+/*
+ * QEMU PowerPC sPAPR IRQ backend definitions
+ *
+ * Copyright (c) 2018, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef HW_SPAPR_IRQ_H
+#define HW_SPAPR_IRQ_H
+
+/*
+ * IRQ range offsets per device type
+ */
+#define SPAPR_IRQ_EPOW   0x1000  /* XICS_IRQ_BASE offset */
+#define SPAPR_IRQ_HOTPLUG0x1001
+#define SPAPR_IRQ_VIO0x1100  /* 256 VIO devices */
+#define SPAPR_IRQ_PCI_LSI0x1200  /* 32+ PHBs devices */
+
+#define SPAPR_IRQ_MSI0x1300  /* Offset of the dynamic range covered
+  * by the bitmap allocator */
+
+typedef struct sPAPRMachineState sPAPRMachineState;
+
+void spapr_irq_msi_init(sPAPRMachineState *spapr, uint32_t nr_msis);
+int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
+Error **errp);
+void spapr_irq_msi_free(sPAPRMachineState *spapr, int irq, uint32_t num);
+void spapr_irq_msi_reset(sPAPRMachineState *spapr);
+
+#endif
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 421b2dd09b51..1794952d4e2a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -189,6 +189,11 @@ static void xics_system_init(MachineState *machine, int 
nr_irqs, Error **errp)
 sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
 Error *local_err = NULL;
 
+/* Initialize the MSI IRQ allocator. */
+if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
+spapr_irq_msi_init(spapr, XICS_IRQ_BASE + nr_irqs - SPAPR_IRQ_MSI);
+}
+
 if (kvm_enabled()) {
 if (machine_kernel_irqchip_allowed(machine) &&
 !xics_kvm_init(spapr, &local_err)) {
@@ -1636,6 +1641,10 @@ static void spapr_machine_reset(void)
 ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
 }
 
+if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) {
+spapr_irq_msi_reset(spapr);
+}
+
 qemu_devices_reset();
 
 /* DRC reset may cause a device to be unplugged. This will cause troubles
@@ -1910,6 +1919,24 @@ static const VMStateDescription vmstate_spapr_patb_entry 
= {
 },
 };
 
+static bool spapr_irq_map_needed(void *opaque)
+{
+sPAPRMachineState *spapr = opaque;
+
+return spapr->irq_map && !bitmap_empty(spapr->irq_map, spapr->irq_map_nr);
+}
+
+static const VMStateDescription vmstate_spapr_irq_map = {
+.name = "spapr_irq_map",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = spapr_irq_map_needed,
+.fields = (VMStateField[]) {
+VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, irq_map_nr),
+VMSTATE_END_OF_LIST()
+},
+};
+
 static co