* [Qemu-devel] [PATCH 1/8] spapr: introduce an IRQ allocator at the machine level
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-11-08 9:54 ` Greg Kurz
2017-10-29 18:12 ` [Qemu-devel] [PATCH 2/8] spapr: introduce a machine class flag to handle migration compatibility Cédric Le Goater
` (6 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
Currently, the ICSState 'ics' object of the sPAPR machine acts as the
global interrupt source handler and also as the IRQ number allocator
for the machine. Some IRQ numbers are allocated very early in the
machine initialization sequence to populate the device tree, and this
is a problem to introduce the new POWER XIVE interrupt model, as it
needs to share the IRQ numbers with the older model.
To prepare ground for XIVE, here is a proposal adding a set of new
XICSFabric operations to let the machine handle directly the IRQ
number allocation and to decorrelate the allocation from the interrupt
source object :
bool (*irq_test)(XICSFabric *xi, int irq);
int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
void (*irq_free_block)(XICSFabric *xi, int irq, int num);
In these prototypes, the 'irq' parameter refers to a number in the
global IRQ number space. Indexes for arrays storing different state
informations on the interrupts, like the ICSIRQState, are named
'srcno'.
On the sPAPR platform, these IRQ operations are simply backed by a
bitmap 'irq_map' in the machine.
'irq_base' is a base number in sync with the ICSState 'offset'. It
lets us allocate only the subset of the IRQ numbers used on the sPAPR
platform but we could also choose to waste some extra bytes (512) and
allocate the whole number space. 'nr_irqs' is the total number of
IRQs, required to manipulate the bitmap.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/intc/xics.c | 3 ++-
hw/intc/xics_spapr.c | 57 ++++++++++++----------------------------------
hw/ppc/spapr.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-
include/hw/ppc/spapr.h | 4 ++++
include/hw/ppc/xics.h | 4 ++++
5 files changed, 85 insertions(+), 45 deletions(-)
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index cc9816e7f204..2c4899f278e2 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -53,6 +53,7 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon)
void ics_pic_print_info(ICSState *ics, Monitor *mon)
{
uint32_t i;
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
monitor_printf(mon, "ICS %4x..%4x %p\n",
ics->offset, ics->offset + ics->nr_irqs - 1, ics);
@@ -64,7 +65,7 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
for (i = 0; i < ics->nr_irqs; i++) {
ICSIRQState *irq = ics->irqs + i;
- if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
+ if (!xic->irq_test(ics->xics, i + ics->offset)) {
continue;
}
monitor_printf(mon, " %4x %s %02x %02x\n",
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index d98ea8b13068..f2e20bca5b2e 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -245,50 +245,23 @@ void xics_spapr_init(sPAPRMachineState *spapr)
spapr_register_hypercall(H_IPOLL, h_ipoll);
}
-#define ICS_IRQ_FREE(ics, srcno) \
- (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
-
-static int ics_find_free_block(ICSState *ics, int num, int alignnum)
-{
- int first, i;
-
- for (first = 0; first < ics->nr_irqs; first += alignnum) {
- if (num > (ics->nr_irqs - first)) {
- return -1;
- }
- for (i = first; i < first + num; ++i) {
- if (!ICS_IRQ_FREE(ics, i)) {
- break;
- }
- }
- if (i == (first + num)) {
- return first;
- }
- }
-
- return -1;
-}
-
int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
{
int irq;
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
- if (!ics) {
- return -1;
- }
if (irq_hint) {
- if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
+ if (xic->irq_test(ics->xics, irq_hint)) {
error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
return -1;
}
irq = irq_hint;
} else {
- irq = ics_find_free_block(ics, 1, 1);
+ irq = xic->irq_alloc_block(ics->xics, 1, 0);
if (irq < 0) {
error_setg(errp, "can't allocate IRQ: no IRQ left");
return -1;
}
- irq += ics->offset;
}
ics_set_irq_type(ics, irq - ics->offset, lsi);
@@ -305,10 +278,8 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
bool align, Error **errp)
{
int i, first = -1;
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
- if (!ics) {
- return -1;
- }
/*
* MSIMesage::data is used for storing VIRQ so
@@ -320,9 +291,9 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
if (align) {
assert((num == 1) || (num == 2) || (num == 4) ||
(num == 8) || (num == 16) || (num == 32));
- first = ics_find_free_block(ics, num, num);
+ first = xic->irq_alloc_block(ics->xics, num, num);
} else {
- first = ics_find_free_block(ics, num, 1);
+ first = xic->irq_alloc_block(ics->xics, num, 0);
}
if (first < 0) {
error_setg(errp, "can't find a free %d-IRQ block", num);
@@ -331,25 +302,25 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
if (first >= 0) {
for (i = first; i < first + num; ++i) {
- ics_set_irq_type(ics, i, lsi);
+ ics_set_irq_type(ics, i - ics->offset, lsi);
}
}
- first += ics->offset;
trace_xics_alloc_block(first, num, lsi, align);
return first;
}
-static void ics_free(ICSState *ics, int srcno, int num)
+static void ics_free(ICSState *ics, int irq, int num)
{
int i;
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
- for (i = srcno; i < srcno + num; ++i) {
- if (ICS_IRQ_FREE(ics, i)) {
- trace_xics_ics_free_warn(0, i + ics->offset);
+ for (i = irq; i < irq + num; ++i) {
+ if (xic->irq_test(ics->xics, i)) {
+ trace_xics_ics_free_warn(0, i);
}
- memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
+ xic->irq_free_block(ics->xics, i, 1);
}
}
@@ -357,7 +328,7 @@ void spapr_ics_free(ICSState *ics, int irq, int num)
{
if (ics_valid_irq(ics, irq)) {
trace_xics_ics_free(0, irq, num);
- ics_free(ics, irq - ics->offset, num);
+ ics_free(ics, irq, num);
}
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d682f013d422..88da4bad2328 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1681,6 +1681,24 @@ static const VMStateDescription vmstate_spapr_patb_entry = {
},
};
+static bool spapr_irq_map_needed(void *opaque)
+{
+ sPAPRMachineState *spapr = opaque;
+
+ return find_first_bit(spapr->irq_map, spapr->nr_irqs) < spapr->nr_irqs;
+}
+
+static const VMStateDescription vmstate_spapr_irq_map = {
+ .name = "spapr_irq_map",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .needed = spapr_irq_map_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, nr_irqs),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_spapr = {
.name = "spapr",
.version_id = 3,
@@ -1700,6 +1718,7 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_ov5_cas,
&vmstate_spapr_patb_entry,
&vmstate_spapr_pending_events,
+ &vmstate_spapr_irq_map,
NULL
}
};
@@ -2337,8 +2356,13 @@ static void ppc_spapr_init(MachineState *machine)
/* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
+ /* Initialize the IRQ allocator */
+ spapr->nr_irqs = XICS_IRQS_SPAPR;
+ spapr->irq_map = bitmap_new(spapr->nr_irqs);
+ spapr->irq_base = XICS_IRQ_BASE;
+
/* Set up Interrupt Controller before we create the VCPUs */
- xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal);
+ xics_system_init(machine, spapr->nr_irqs, &error_fatal);
/* Set up containers for ibm,client-architecture-support negotiated options
*/
@@ -3536,6 +3560,38 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
return cpu ? ICP(cpu->intc) : NULL;
}
+static bool spapr_irq_test(XICSFabric *xi, int irq)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+ int srcno = irq - spapr->irq_base;
+
+ return test_bit(srcno, spapr->irq_map);
+}
+
+static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+ int start = 0;
+ int srcno;
+
+ srcno = bitmap_find_next_zero_area(spapr->irq_map, spapr->nr_irqs, start,
+ count, align);
+ if (srcno == spapr->nr_irqs) {
+ return -1;
+ }
+
+ bitmap_set(spapr->irq_map, srcno, count);
+ return srcno + spapr->irq_base;
+}
+
+static void spapr_irq_free_block(XICSFabric *xi, int irq, int num)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+ int srcno = irq - spapr->irq_base;
+
+ bitmap_clear(spapr->irq_map, srcno, num);
+}
+
static void spapr_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
@@ -3630,6 +3686,10 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
xic->ics_get = spapr_ics_get;
xic->ics_resend = spapr_ics_resend;
xic->icp_get = spapr_icp_get;
+ xic->irq_test = spapr_irq_test;
+ xic->irq_alloc_block = spapr_irq_alloc_block;
+ xic->irq_free_block = spapr_irq_free_block;
+
ispc->print_info = spapr_pic_print_info;
/* Force NUMA node memory size to be a multiple of
* SPAPR_MEMORY_BLOCK_SIZE (256M) since that's the granularity
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 9d21ca9bde3a..b962bfe09bb5 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -7,6 +7,7 @@
#include "hw/ppc/spapr_drc.h"
#include "hw/mem/pc-dimm.h"
#include "hw/ppc/spapr_ovec.h"
+#include "qemu/bitmap.h"
struct VIOsPAPRBus;
struct sPAPRPHBState;
@@ -78,6 +79,9 @@ struct sPAPRMachineState {
struct VIOsPAPRBus *vio_bus;
QLIST_HEAD(, sPAPRPHBState) phbs;
struct sPAPRNVRAM *nvram;
+ int32_t nr_irqs;
+ unsigned long *irq_map;
+ uint32_t irq_base;
ICSState *ics;
sPAPRRTCState rtc;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 28d248abad61..30e7f2e0a7dd 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -175,6 +175,10 @@ typedef struct XICSFabricClass {
ICSState *(*ics_get)(XICSFabric *xi, int irq);
void (*ics_resend)(XICSFabric *xi);
ICPState *(*icp_get)(XICSFabric *xi, int server);
+ /* IRQ allocator helpers */
+ bool (*irq_test)(XICSFabric *xi, int irq);
+ int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
+ void (*irq_free_block)(XICSFabric *xi, int irq, int num);
} XICSFabricClass;
#define XICS_IRQS_SPAPR 1024
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 1/8] spapr: introduce an IRQ allocator at the machine level
2017-10-29 18:12 ` [Qemu-devel] [PATCH 1/8] spapr: " Cédric Le Goater
@ 2017-11-08 9:54 ` Greg Kurz
2017-11-08 16:56 ` Cédric Le Goater
0 siblings, 1 reply; 13+ messages in thread
From: Greg Kurz @ 2017-11-08 9:54 UTC (permalink / raw)
To: Cédric Le Goater
Cc: qemu-ppc, qemu-devel, David Gibson, Benjamin Herrenschmidt
On Sun, 29 Oct 2017 19:12:10 +0100
Cédric Le Goater <clg@kaod.org> wrote:
> Currently, the ICSState 'ics' object of the sPAPR machine acts as the
> global interrupt source handler and also as the IRQ number allocator
> for the machine. Some IRQ numbers are allocated very early in the
> machine initialization sequence to populate the device tree, and this
> is a problem to introduce the new POWER XIVE interrupt model, as it
> needs to share the IRQ numbers with the older model.
>
> To prepare ground for XIVE, here is a proposal adding a set of new
> XICSFabric operations to let the machine handle directly the IRQ
> number allocation and to decorrelate the allocation from the interrupt
> source object :
>
> bool (*irq_test)(XICSFabric *xi, int irq);
> int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
> void (*irq_free_block)(XICSFabric *xi, int irq, int num);
>
> In these prototypes, the 'irq' parameter refers to a number in the
> global IRQ number space. Indexes for arrays storing different state
> informations on the interrupts, like the ICSIRQState, are named
> 'srcno'.
>
> On the sPAPR platform, these IRQ operations are simply backed by a
> bitmap 'irq_map' in the machine.
>
> 'irq_base' is a base number in sync with the ICSState 'offset'. It
> lets us allocate only the subset of the IRQ numbers used on the sPAPR
> platform but we could also choose to waste some extra bytes (512) and
> allocate the whole number space. 'nr_irqs' is the total number of
> IRQs, required to manipulate the bitmap.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
Hi,
The idea makes sense but this patch brings too many changes IMHO.
> hw/intc/xics.c | 3 ++-
> hw/intc/xics_spapr.c | 57 ++++++++++++----------------------------------
> hw/ppc/spapr.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-
> include/hw/ppc/spapr.h | 4 ++++
> include/hw/ppc/xics.h | 4 ++++
> 5 files changed, 85 insertions(+), 45 deletions(-)
>
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index cc9816e7f204..2c4899f278e2 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -53,6 +53,7 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon)
> void ics_pic_print_info(ICSState *ics, Monitor *mon)
> {
> uint32_t i;
> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>
> monitor_printf(mon, "ICS %4x..%4x %p\n",
> ics->offset, ics->offset + ics->nr_irqs - 1, ics);
> @@ -64,7 +65,7 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
> for (i = 0; i < ics->nr_irqs; i++) {
> ICSIRQState *irq = ics->irqs + i;
>
> - if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
> + if (!xic->irq_test(ics->xics, i + ics->offset)) {
> continue;
> }
> monitor_printf(mon, " %4x %s %02x %02x\n",
> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
> index d98ea8b13068..f2e20bca5b2e 100644
> --- a/hw/intc/xics_spapr.c
> +++ b/hw/intc/xics_spapr.c
> @@ -245,50 +245,23 @@ void xics_spapr_init(sPAPRMachineState *spapr)
> spapr_register_hypercall(H_IPOLL, h_ipoll);
> }
>
> -#define ICS_IRQ_FREE(ics, srcno) \
> - (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
> -
> -static int ics_find_free_block(ICSState *ics, int num, int alignnum)
> -{
> - int first, i;
> -
> - for (first = 0; first < ics->nr_irqs; first += alignnum) {
> - if (num > (ics->nr_irqs - first)) {
> - return -1;
> - }
> - for (i = first; i < first + num; ++i) {
> - if (!ICS_IRQ_FREE(ics, i)) {
> - break;
> - }
> - }
> - if (i == (first + num)) {
> - return first;
> - }
> - }
> -
> - return -1;
> -}
> -
> int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
> {
> int irq;
> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>
> - if (!ics) {
> - return -1;
> - }
If spapr_ics_alloc() is never called with ics == NULL, then you
should assert. Also, this looks like this deserves a separate
patch.
> if (irq_hint) {
> - if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
> + if (xic->irq_test(ics->xics, irq_hint)) {
> error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
> return -1;
> }
> irq = irq_hint;
> } else {
> - irq = ics_find_free_block(ics, 1, 1);
> + irq = xic->irq_alloc_block(ics->xics, 1, 0);
> if (irq < 0) {
> error_setg(errp, "can't allocate IRQ: no IRQ left");
> return -1;
> }
> - irq += ics->offset;
> }
>
> ics_set_irq_type(ics, irq - ics->offset, lsi);
> @@ -305,10 +278,8 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
> bool align, Error **errp)
> {
> int i, first = -1;
> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>
> - if (!ics) {
> - return -1;
> - }
>
Ditto.
> /*
> * MSIMesage::data is used for storing VIRQ so
> @@ -320,9 +291,9 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
> if (align) {
> assert((num == 1) || (num == 2) || (num == 4) ||
> (num == 8) || (num == 16) || (num == 32));
> - first = ics_find_free_block(ics, num, num);
> + first = xic->irq_alloc_block(ics->xics, num, num);
> } else {
> - first = ics_find_free_block(ics, num, 1);
> + first = xic->irq_alloc_block(ics->xics, num, 0);
> }
> if (first < 0) {
> error_setg(errp, "can't find a free %d-IRQ block", num);
> @@ -331,25 +302,25 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
>
> if (first >= 0) {
It looks like this check isn't needed since we return in the first < 0 case.
Maybe you can fix this in a preliminary patch ?
> for (i = first; i < first + num; ++i) {
> - ics_set_irq_type(ics, i, lsi);
> + ics_set_irq_type(ics, i - ics->offset, lsi);
> }
> }
> - first += ics->offset;
>
> trace_xics_alloc_block(first, num, lsi, align);
>
> return first;
> }
>
> -static void ics_free(ICSState *ics, int srcno, int num)
> +static void ics_free(ICSState *ics, int irq, int num)
> {
> int i;
> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>
> - for (i = srcno; i < srcno + num; ++i) {
> - if (ICS_IRQ_FREE(ics, i)) {
> - trace_xics_ics_free_warn(0, i + ics->offset);
> + for (i = irq; i < irq + num; ++i) {
> + if (xic->irq_test(ics->xics, i)) {
> + trace_xics_ics_free_warn(0, i);
> }
> - memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
> + xic->irq_free_block(ics->xics, i, 1);
> }
> }
>
> @@ -357,7 +328,7 @@ void spapr_ics_free(ICSState *ics, int irq, int num)
> {
> if (ics_valid_irq(ics, irq)) {
> trace_xics_ics_free(0, irq, num);
> - ics_free(ics, irq - ics->offset, num);
> + ics_free(ics, irq, num);
> }
> }
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index d682f013d422..88da4bad2328 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1681,6 +1681,24 @@ static const VMStateDescription vmstate_spapr_patb_entry = {
> },
> };
>
> +static bool spapr_irq_map_needed(void *opaque)
> +{
> + sPAPRMachineState *spapr = opaque;
> +
> + return find_first_bit(spapr->irq_map, spapr->nr_irqs) < spapr->nr_irqs;
> +}
This will allow migration from older QEMU. Maybe you can add a machine property
so that the subsection is only generated for newer pseries, and you'll support
migration to older QEMU (see details at the end of === Subsections === in
docs/devel/migration.txt).
> +
> +static const VMStateDescription vmstate_spapr_irq_map = {
> + .name = "spapr_irq_map",
> + .version_id = 0,
> + .minimum_version_id = 0,
> + .needed = spapr_irq_map_needed,
> + .fields = (VMStateField[]) {
> + VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, nr_irqs),
> + VMSTATE_END_OF_LIST()
> + },
> +};
> +
> static const VMStateDescription vmstate_spapr = {
> .name = "spapr",
> .version_id = 3,
> @@ -1700,6 +1718,7 @@ static const VMStateDescription vmstate_spapr = {
> &vmstate_spapr_ov5_cas,
> &vmstate_spapr_patb_entry,
> &vmstate_spapr_pending_events,
> + &vmstate_spapr_irq_map,
> NULL
> }
> };
> @@ -2337,8 +2356,13 @@ static void ppc_spapr_init(MachineState *machine)
> /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
> load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
>
> + /* Initialize the IRQ allocator */
> + spapr->nr_irqs = XICS_IRQS_SPAPR;
> + spapr->irq_map = bitmap_new(spapr->nr_irqs);
> + spapr->irq_base = XICS_IRQ_BASE;
> +
> /* Set up Interrupt Controller before we create the VCPUs */
> - xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal);
> + xics_system_init(machine, spapr->nr_irqs, &error_fatal);
>
> /* Set up containers for ibm,client-architecture-support negotiated options
> */
> @@ -3536,6 +3560,38 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
> return cpu ? ICP(cpu->intc) : NULL;
> }
>
> +static bool spapr_irq_test(XICSFabric *xi, int irq)
> +{
> + sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> + int srcno = irq - spapr->irq_base;
> +
> + return test_bit(srcno, spapr->irq_map);
> +}
> +
> +static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align)
> +{
> + sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> + int start = 0;
> + int srcno;
> +
> + srcno = bitmap_find_next_zero_area(spapr->irq_map, spapr->nr_irqs, start,
> + count, align);
> + if (srcno == spapr->nr_irqs) {
> + return -1;
> + }
> +
> + bitmap_set(spapr->irq_map, srcno, count);
> + return srcno + spapr->irq_base;
> +}
> +
> +static void spapr_irq_free_block(XICSFabric *xi, int irq, int num)
> +{
> + sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
> + int srcno = irq - spapr->irq_base;
> +
> + bitmap_clear(spapr->irq_map, srcno, num);
> +}
> +
> static void spapr_pic_print_info(InterruptStatsProvider *obj,
> Monitor *mon)
> {
> @@ -3630,6 +3686,10 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
> xic->ics_get = spapr_ics_get;
> xic->ics_resend = spapr_ics_resend;
> xic->icp_get = spapr_icp_get;
> + xic->irq_test = spapr_irq_test;
> + xic->irq_alloc_block = spapr_irq_alloc_block;
> + xic->irq_free_block = spapr_irq_free_block;
> +
> ispc->print_info = spapr_pic_print_info;
> /* Force NUMA node memory size to be a multiple of
> * SPAPR_MEMORY_BLOCK_SIZE (256M) since that's the granularity
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 9d21ca9bde3a..b962bfe09bb5 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -7,6 +7,7 @@
> #include "hw/ppc/spapr_drc.h"
> #include "hw/mem/pc-dimm.h"
> #include "hw/ppc/spapr_ovec.h"
> +#include "qemu/bitmap.h"
>
> struct VIOsPAPRBus;
> struct sPAPRPHBState;
> @@ -78,6 +79,9 @@ struct sPAPRMachineState {
> struct VIOsPAPRBus *vio_bus;
> QLIST_HEAD(, sPAPRPHBState) phbs;
> struct sPAPRNVRAM *nvram;
> + int32_t nr_irqs;
> + unsigned long *irq_map;
> + uint32_t irq_base;
> ICSState *ics;
> sPAPRRTCState rtc;
>
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 28d248abad61..30e7f2e0a7dd 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -175,6 +175,10 @@ typedef struct XICSFabricClass {
> ICSState *(*ics_get)(XICSFabric *xi, int irq);
> void (*ics_resend)(XICSFabric *xi);
> ICPState *(*icp_get)(XICSFabric *xi, int server);
> + /* IRQ allocator helpers */
> + bool (*irq_test)(XICSFabric *xi, int irq);
> + int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
> + void (*irq_free_block)(XICSFabric *xi, int irq, int num);
API looks good to me. I suggest you introduce it in a dedicated patch, and
change the allocator implementation in another patch.
> } XICSFabricClass;
>
> #define XICS_IRQS_SPAPR 1024
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 1/8] spapr: introduce an IRQ allocator at the machine level
2017-11-08 9:54 ` Greg Kurz
@ 2017-11-08 16:56 ` Cédric Le Goater
0 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-11-08 16:56 UTC (permalink / raw)
To: Greg Kurz; +Cc: qemu-ppc, qemu-devel, David Gibson, Benjamin Herrenschmidt
On 11/08/2017 09:54 AM, Greg Kurz wrote:
> On Sun, 29 Oct 2017 19:12:10 +0100
> Cédric Le Goater <clg@kaod.org> wrote:
>
>> Currently, the ICSState 'ics' object of the sPAPR machine acts as the
>> global interrupt source handler and also as the IRQ number allocator
>> for the machine. Some IRQ numbers are allocated very early in the
>> machine initialization sequence to populate the device tree, and this
>> is a problem to introduce the new POWER XIVE interrupt model, as it
>> needs to share the IRQ numbers with the older model.
>>
>> To prepare ground for XIVE, here is a proposal adding a set of new
>> XICSFabric operations to let the machine handle directly the IRQ
>> number allocation and to decorrelate the allocation from the interrupt
>> source object :
>>
>> bool (*irq_test)(XICSFabric *xi, int irq);
>> int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
>> void (*irq_free_block)(XICSFabric *xi, int irq, int num);
>>
>> In these prototypes, the 'irq' parameter refers to a number in the
>> global IRQ number space. Indexes for arrays storing different state
>> informations on the interrupts, like the ICSIRQState, are named
>> 'srcno'.
>>
>> On the sPAPR platform, these IRQ operations are simply backed by a
>> bitmap 'irq_map' in the machine.
>>
>> 'irq_base' is a base number in sync with the ICSState 'offset'. It
>> lets us allocate only the subset of the IRQ numbers used on the sPAPR
>> platform but we could also choose to waste some extra bytes (512) and
>> allocate the whole number space. 'nr_irqs' is the total number of
>> IRQs, required to manipulate the bitmap.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>
> Hi,
>
> The idea makes sense but this patch brings too many changes IMHO.
yes. I agree. The next version splits a bit more the changes and
introduces the XICSFabric ops before the bitmap.
>> hw/intc/xics.c | 3 ++-
>> hw/intc/xics_spapr.c | 57 ++++++++++++----------------------------------
>> hw/ppc/spapr.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-
>> include/hw/ppc/spapr.h | 4 ++++
>> include/hw/ppc/xics.h | 4 ++++
>> 5 files changed, 85 insertions(+), 45 deletions(-)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index cc9816e7f204..2c4899f278e2 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -53,6 +53,7 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon)
>> void ics_pic_print_info(ICSState *ics, Monitor *mon)
>> {
>> uint32_t i;
>> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>>
>> monitor_printf(mon, "ICS %4x..%4x %p\n",
>> ics->offset, ics->offset + ics->nr_irqs - 1, ics);
>> @@ -64,7 +65,7 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
>> for (i = 0; i < ics->nr_irqs; i++) {
>> ICSIRQState *irq = ics->irqs + i;
>>
>> - if (!(irq->flags & XICS_FLAGS_IRQ_MASK)) {
>> + if (!xic->irq_test(ics->xics, i + ics->offset)) {
>> continue;
>> }
>> monitor_printf(mon, " %4x %s %02x %02x\n",
>> diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
>> index d98ea8b13068..f2e20bca5b2e 100644
>> --- a/hw/intc/xics_spapr.c
>> +++ b/hw/intc/xics_spapr.c
>> @@ -245,50 +245,23 @@ void xics_spapr_init(sPAPRMachineState *spapr)
>> spapr_register_hypercall(H_IPOLL, h_ipoll);
>> }
>>
>> -#define ICS_IRQ_FREE(ics, srcno) \
>> - (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
>> -
>> -static int ics_find_free_block(ICSState *ics, int num, int alignnum)
>> -{
>> - int first, i;
>> -
>> - for (first = 0; first < ics->nr_irqs; first += alignnum) {
>> - if (num > (ics->nr_irqs - first)) {
>> - return -1;
>> - }
>> - for (i = first; i < first + num; ++i) {
>> - if (!ICS_IRQ_FREE(ics, i)) {
>> - break;
>> - }
>> - }
>> - if (i == (first + num)) {
>> - return first;
>> - }
>> - }
>> -
>> - return -1;
>> -}
>> -
>> int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
>> {
>> int irq;
>> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>>
>> - if (!ics) {
>> - return -1;
>> - }
>
> If spapr_ics_alloc() is never called with ics == NULL, then you
> should assert. Also, this looks like this deserves a separate
> patch.
yes.
>> if (irq_hint) {
>> - if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
>> + if (xic->irq_test(ics->xics, irq_hint)) {
>> error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
>> return -1;
>> }
>> irq = irq_hint;
>> } else {
>> - irq = ics_find_free_block(ics, 1, 1);
>> + irq = xic->irq_alloc_block(ics->xics, 1, 0);
>> if (irq < 0) {
>> error_setg(errp, "can't allocate IRQ: no IRQ left");
>> return -1;
>> }
>> - irq += ics->offset;
>> }
>>
>> ics_set_irq_type(ics, irq - ics->offset, lsi);
>> @@ -305,10 +278,8 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
>> bool align, Error **errp)
>> {
>> int i, first = -1;
>> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>>
>> - if (!ics) {
>> - return -1;
>> - }
>>
>
> Ditto.
>
>> /*
>> * MSIMesage::data is used for storing VIRQ so
>> @@ -320,9 +291,9 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
>> if (align) {
>> assert((num == 1) || (num == 2) || (num == 4) ||
>> (num == 8) || (num == 16) || (num == 32));
>> - first = ics_find_free_block(ics, num, num);
>> + first = xic->irq_alloc_block(ics->xics, num, num);
>> } else {
>> - first = ics_find_free_block(ics, num, 1);
>> + first = xic->irq_alloc_block(ics->xics, num, 0);
>> }
>> if (first < 0) {
>> error_setg(errp, "can't find a free %d-IRQ block", num);
>> @@ -331,25 +302,25 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
>>
>> if (first >= 0) {
>
> It looks like this check isn't needed since we return in the first < 0 case.
> Maybe you can fix this in a preliminary patch ?
done.
>> for (i = first; i < first + num; ++i) {
>> - ics_set_irq_type(ics, i, lsi);
>> + ics_set_irq_type(ics, i - ics->offset, lsi);
>> }
>> }
>> - first += ics->offset;
>>
>> trace_xics_alloc_block(first, num, lsi, align);
>>
>> return first;
>> }
>>
>> -static void ics_free(ICSState *ics, int srcno, int num)
>> +static void ics_free(ICSState *ics, int irq, int num)
>> {
>> int i;
>> + XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
>>
>> - for (i = srcno; i < srcno + num; ++i) {
>> - if (ICS_IRQ_FREE(ics, i)) {
>> - trace_xics_ics_free_warn(0, i + ics->offset);
>> + for (i = irq; i < irq + num; ++i) {
>> + if (xic->irq_test(ics->xics, i)) {
>> + trace_xics_ics_free_warn(0, i);
>> }
>> - memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
>> + xic->irq_free_block(ics->xics, i, 1);
>> }
>> }
>>
>> @@ -357,7 +328,7 @@ void spapr_ics_free(ICSState *ics, int irq, int num)
>> {
>> if (ics_valid_irq(ics, irq)) {
>> trace_xics_ics_free(0, irq, num);
>> - ics_free(ics, irq - ics->offset, num);
>> + ics_free(ics, irq, num);
>> }
>> }
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index d682f013d422..88da4bad2328 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -1681,6 +1681,24 @@ static const VMStateDescription vmstate_spapr_patb_entry = {
>> },
>> };
>>
>> +static bool spapr_irq_map_needed(void *opaque)
>> +{
>> + sPAPRMachineState *spapr = opaque;
>> +
>> + return find_first_bit(spapr->irq_map, spapr->nr_irqs) < spapr->nr_irqs;
>> +}
>
> This will allow migration from older QEMU. Maybe you can add a machine property
> so that the subsection is only generated for newer pseries, and you'll support
> migration to older QEMU (see details at the end of === Subsections === in
> docs/devel/migration.txt).
I have found a better way to save state. We will discuss it in the next round.
>> +
>> +static const VMStateDescription vmstate_spapr_irq_map = {
>> + .name = "spapr_irq_map",
>> + .version_id = 0,
>> + .minimum_version_id = 0,
>> + .needed = spapr_irq_map_needed,
>> + .fields = (VMStateField[]) {
>> + VMSTATE_BITMAP(irq_map, sPAPRMachineState, 0, nr_irqs),
>> + VMSTATE_END_OF_LIST()
>> + },
>> +};
>> +
>> static const VMStateDescription vmstate_spapr = {
>> .name = "spapr",
>> .version_id = 3,
>> @@ -1700,6 +1718,7 @@ static const VMStateDescription vmstate_spapr = {
>> &vmstate_spapr_ov5_cas,
>> &vmstate_spapr_patb_entry,
>> &vmstate_spapr_pending_events,
>> + &vmstate_spapr_irq_map,
>> NULL
>> }
>> };
>> @@ -2337,8 +2356,13 @@ static void ppc_spapr_init(MachineState *machine)
>> /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
>> load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
>>
>> + /* Initialize the IRQ allocator */
>> + spapr->nr_irqs = XICS_IRQS_SPAPR;
>> + spapr->irq_map = bitmap_new(spapr->nr_irqs);
>> + spapr->irq_base = XICS_IRQ_BASE;
>> +
>> /* Set up Interrupt Controller before we create the VCPUs */
>> - xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal);
>> + xics_system_init(machine, spapr->nr_irqs, &error_fatal);
>>
>> /* Set up containers for ibm,client-architecture-support negotiated options
>> */
>> @@ -3536,6 +3560,38 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
>> return cpu ? ICP(cpu->intc) : NULL;
>> }
>>
>> +static bool spapr_irq_test(XICSFabric *xi, int irq)
>> +{
>> + sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
>> + int srcno = irq - spapr->irq_base;
>> +
>> + return test_bit(srcno, spapr->irq_map);
>> +}
>> +
>> +static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align)
>> +{
>> + sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
>> + int start = 0;
>> + int srcno;
>> +
>> + srcno = bitmap_find_next_zero_area(spapr->irq_map, spapr->nr_irqs, start,
>> + count, align);
>> + if (srcno == spapr->nr_irqs) {
>> + return -1;
>> + }
>> +
>> + bitmap_set(spapr->irq_map, srcno, count);
>> + return srcno + spapr->irq_base;
>> +}
>> +
>> +static void spapr_irq_free_block(XICSFabric *xi, int irq, int num)
>> +{
>> + sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
>> + int srcno = irq - spapr->irq_base;
>> +
>> + bitmap_clear(spapr->irq_map, srcno, num);
>> +}
>> +
>> static void spapr_pic_print_info(InterruptStatsProvider *obj,
>> Monitor *mon)
>> {
>> @@ -3630,6 +3686,10 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>> xic->ics_get = spapr_ics_get;
>> xic->ics_resend = spapr_ics_resend;
>> xic->icp_get = spapr_icp_get;
>> + xic->irq_test = spapr_irq_test;
>> + xic->irq_alloc_block = spapr_irq_alloc_block;
>> + xic->irq_free_block = spapr_irq_free_block;
>> +
>> ispc->print_info = spapr_pic_print_info;
>> /* Force NUMA node memory size to be a multiple of
>> * SPAPR_MEMORY_BLOCK_SIZE (256M) since that's the granularity
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index 9d21ca9bde3a..b962bfe09bb5 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -7,6 +7,7 @@
>> #include "hw/ppc/spapr_drc.h"
>> #include "hw/mem/pc-dimm.h"
>> #include "hw/ppc/spapr_ovec.h"
>> +#include "qemu/bitmap.h"
>>
>> struct VIOsPAPRBus;
>> struct sPAPRPHBState;
>> @@ -78,6 +79,9 @@ struct sPAPRMachineState {
>> struct VIOsPAPRBus *vio_bus;
>> QLIST_HEAD(, sPAPRPHBState) phbs;
>> struct sPAPRNVRAM *nvram;
>> + int32_t nr_irqs;
>> + unsigned long *irq_map;
>> + uint32_t irq_base;
>> ICSState *ics;
>> sPAPRRTCState rtc;
>>
>> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
>> index 28d248abad61..30e7f2e0a7dd 100644
>> --- a/include/hw/ppc/xics.h
>> +++ b/include/hw/ppc/xics.h
>> @@ -175,6 +175,10 @@ typedef struct XICSFabricClass {
>> ICSState *(*ics_get)(XICSFabric *xi, int irq);
>> void (*ics_resend)(XICSFabric *xi);
>> ICPState *(*icp_get)(XICSFabric *xi, int server);
>> + /* IRQ allocator helpers */
>> + bool (*irq_test)(XICSFabric *xi, int irq);
>> + int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
>> + void (*irq_free_block)(XICSFabric *xi, int irq, int num);
>
> API looks good to me. I suggest you introduce it in a dedicated patch, and
> change the allocator implementation in another patch.
yep.
Thanks
C.
>> } XICSFabricClass;
>>
>> #define XICS_IRQS_SPAPR 1024
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/8] spapr: introduce a machine class flag to handle migration compatibility
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 1/8] spapr: " Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-11-08 13:21 ` Greg Kurz
2017-10-29 18:12 ` [Qemu-devel] [PATCH 3/8] pnv: introduce an irq_test() operation Cédric Le Goater
` (5 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
Older pseries machines, before 2.11, do not have a bitmap acting as a
IRQ number allocator but use the ICSIRQState array for this purpose.
This difference between machine versions needs to be taken into
account when loading the state.
To keep in sync the bitmap with the ICSIRQState array flags, we
introduce a machine class flag 'pre_2_11_has_no_bitmap' identifying an
older version.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/ppc/spapr.c | 19 +++++++++++++++++++
include/hw/ppc/spapr.h | 1 +
2 files changed, 20 insertions(+)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 88da4bad2328..b33eebe44906 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1532,6 +1532,7 @@ static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
static int spapr_post_load(void *opaque, int version_id)
{
sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
int err = 0;
if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
@@ -1562,6 +1563,20 @@ static int spapr_post_load(void *opaque, int version_id)
}
}
+ /*
+ * synchronize the IRQ number bitmap with the ICSIRQState array
+ * coming from an pre-2.11 pseries machine
+ */
+ if (smc->pre_2_11_has_no_bitmap) {
+ int srcno;
+
+ for (srcno = 0; srcno < spapr->ics->nr_irqs; srcno++) {
+ if (spapr->ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK &&
+ !test_bit(srcno, spapr->irq_map)) {
+ bitmap_set(spapr->irq_map, srcno, 1);
+ }
+ }
+ }
return err;
}
@@ -3772,8 +3787,12 @@ static void spapr_machine_2_10_instance_options(MachineState *machine)
static void spapr_machine_2_10_class_options(MachineClass *mc)
{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
spapr_machine_2_11_class_options(mc);
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_10);
+
+ smc->pre_2_11_has_no_bitmap = true;
}
DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index b962bfe09bb5..1525d1518c47 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -62,6 +62,7 @@ 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 pre_2_11_has_no_bitmap;
void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/8] spapr: introduce a machine class flag to handle migration compatibility
2017-10-29 18:12 ` [Qemu-devel] [PATCH 2/8] spapr: introduce a machine class flag to handle migration compatibility Cédric Le Goater
@ 2017-11-08 13:21 ` Greg Kurz
2017-11-08 16:53 ` Cédric Le Goater
0 siblings, 1 reply; 13+ messages in thread
From: Greg Kurz @ 2017-11-08 13:21 UTC (permalink / raw)
To: Cédric Le Goater
Cc: qemu-ppc, qemu-devel, David Gibson, Benjamin Herrenschmidt
On Sun, 29 Oct 2017 19:12:11 +0100
Cédric Le Goater <clg@kaod.org> wrote:
> Older pseries machines, before 2.11, do not have a bitmap acting as a
We're in hard freeze for 2.11: this should now target 2.12 (David has just
created the ppc-for-2.12 branch).
> IRQ number allocator but use the ICSIRQState array for this purpose.
> This difference between machine versions needs to be taken into
> account when loading the state.
>
> To keep in sync the bitmap with the ICSIRQState array flags, we
> introduce a machine class flag 'pre_2_11_has_no_bitmap' identifying an
> older version.
>
Since you're introducing the bitmap in this series, I think you should
rather do the other way around: add a 'has_irq_bitmap' flag to the machine
class defaulting to 'true' in spapr_machine_class_init() and setting it to
'false' for older machine types.
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> hw/ppc/spapr.c | 19 +++++++++++++++++++
> include/hw/ppc/spapr.h | 1 +
> 2 files changed, 20 insertions(+)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 88da4bad2328..b33eebe44906 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1532,6 +1532,7 @@ static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
> static int spapr_post_load(void *opaque, int version_id)
> {
> sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
> + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> int err = 0;
>
> if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
> @@ -1562,6 +1563,20 @@ static int spapr_post_load(void *opaque, int version_id)
> }
> }
>
> + /*
> + * synchronize the IRQ number bitmap with the ICSIRQState array
> + * coming from an pre-2.11 pseries machine
> + */
> + if (smc->pre_2_11_has_no_bitmap) {
> + int srcno;
> +
> + for (srcno = 0; srcno < spapr->ics->nr_irqs; srcno++) {
> + if (spapr->ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK &&
> + !test_bit(srcno, spapr->irq_map)) {
> + bitmap_set(spapr->irq_map, srcno, 1);
> + }
> + }
> + }
> return err;
> }
>
> @@ -3772,8 +3787,12 @@ static void spapr_machine_2_10_instance_options(MachineState *machine)
>
> static void spapr_machine_2_10_class_options(MachineClass *mc)
> {
> + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
> +
> spapr_machine_2_11_class_options(mc);
> SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_10);
> +
> + smc->pre_2_11_has_no_bitmap = true;
> }
>
> DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index b962bfe09bb5..1525d1518c47 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -62,6 +62,7 @@ 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 pre_2_11_has_no_bitmap;
> void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
> uint64_t *buid, hwaddr *pio,
> hwaddr *mmio32, hwaddr *mmio64,
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 2/8] spapr: introduce a machine class flag to handle migration compatibility
2017-11-08 13:21 ` Greg Kurz
@ 2017-11-08 16:53 ` Cédric Le Goater
0 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-11-08 16:53 UTC (permalink / raw)
To: Greg Kurz; +Cc: qemu-ppc, qemu-devel, David Gibson, Benjamin Herrenschmidt
On 11/08/2017 01:21 PM, Greg Kurz wrote:
> On Sun, 29 Oct 2017 19:12:11 +0100
> Cédric Le Goater <clg@kaod.org> wrote:
>
>> Older pseries machines, before 2.11, do not have a bitmap acting as a
>
> We're in hard freeze for 2.11: this should now target 2.12 (David has just
> created the ppc-for-2.12 branch).
ok. I have switched my 'xive' branch to track Dave's ppc-for-2.12.
>> IRQ number allocator but use the ICSIRQState array for this purpose.
>> This difference between machine versions needs to be taken into
>> account when loading the state.
>>
>> To keep in sync the bitmap with the ICSIRQState array flags, we
>> introduce a machine class flag 'pre_2_11_has_no_bitmap' identifying an
>> older version.
>>
>
> Since you're introducing the bitmap in this series, I think you should
> rather do the other way around: add a 'has_irq_bitmap' flag to the machine
> class defaulting to 'true' in spapr_machine_class_init() and setting it to
> 'false' for older machine types.
yes. Will do.
Thanks,
C.
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>> hw/ppc/spapr.c | 19 +++++++++++++++++++
>> include/hw/ppc/spapr.h | 1 +
>> 2 files changed, 20 insertions(+)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 88da4bad2328..b33eebe44906 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -1532,6 +1532,7 @@ static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
>> static int spapr_post_load(void *opaque, int version_id)
>> {
>> sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
>> + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
>> int err = 0;
>>
>> if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
>> @@ -1562,6 +1563,20 @@ static int spapr_post_load(void *opaque, int version_id)
>> }
>> }
>>
>> + /*
>> + * synchronize the IRQ number bitmap with the ICSIRQState array
>> + * coming from an pre-2.11 pseries machine
>> + */
>> + if (smc->pre_2_11_has_no_bitmap) {
>> + int srcno;
>> +
>> + for (srcno = 0; srcno < spapr->ics->nr_irqs; srcno++) {
>> + if (spapr->ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK &&
>> + !test_bit(srcno, spapr->irq_map)) {
>> + bitmap_set(spapr->irq_map, srcno, 1);
>> + }
>> + }
>> + }
>> return err;
>> }
>>
>> @@ -3772,8 +3787,12 @@ static void spapr_machine_2_10_instance_options(MachineState *machine)
>>
>> static void spapr_machine_2_10_class_options(MachineClass *mc)
>> {
>> + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
>> +
>> spapr_machine_2_11_class_options(mc);
>> SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_10);
>> +
>> + smc->pre_2_11_has_no_bitmap = true;
>> }
>>
>> DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
>> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
>> index b962bfe09bb5..1525d1518c47 100644
>> --- a/include/hw/ppc/spapr.h
>> +++ b/include/hw/ppc/spapr.h
>> @@ -62,6 +62,7 @@ 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 pre_2_11_has_no_bitmap;
>> void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
>> uint64_t *buid, hwaddr *pio,
>> hwaddr *mmio32, hwaddr *mmio64,
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 3/8] pnv: introduce an irq_test() operation
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 1/8] spapr: " Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 2/8] spapr: introduce a machine class flag to handle migration compatibility Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 4/8] spapr: split the IRQ number space for LSI interrupts Cédric Le Goater
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
On PowerNV, there is no need for a bitmap for the moment. The only
interrupts handled are the ones from the PSI controller.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/ppc/pnv.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index c35c439d816b..8288940ef9d7 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1018,6 +1018,23 @@ static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
return cpu ? ICP(cpu->intc) : NULL;
}
+static bool pnv_irq_test(XICSFabric *xi, int irq)
+{
+ PnvMachineState *pnv = POWERNV_MACHINE(xi);
+ int i;
+
+ /* We don't have a IRQ allocator for the PowerNV machine yet, so
+ * just check that the IRQ number is valid for the PSI source
+ */
+ for (i = 0; i < pnv->num_chips; i++) {
+ ICSState *ics = &pnv->chips[i]->psi.ics;
+ if (ics_valid_irq(ics, irq)) {
+ return true;
+ }
+ }
+ return false;
+}
+
static void pnv_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
@@ -1102,6 +1119,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
xic->icp_get = pnv_icp_get;
xic->ics_get = pnv_ics_get;
xic->ics_resend = pnv_ics_resend;
+ xic->irq_test = pnv_irq_test;
ispc->print_info = pnv_pic_print_info;
powernv_machine_class_props_init(oc);
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 4/8] spapr: split the IRQ number space for LSI interrupts
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
` (2 preceding siblings ...)
2017-10-29 18:12 ` [Qemu-devel] [PATCH 3/8] pnv: introduce an irq_test() operation Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 5/8] spapr: introduce an is_lsi() operation Cédric Le Goater
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
The nature of an interrupt, MSI or LSI, is stored under the flag
attribute of the ICSIRQState array. To reduce the use of this array
and consequently of the ICSState object (needed to introduce for the
new XIVE model), we choose to split the IRQ number space of the
machine in two: first the LSIs and then the MSIs.
This also has the benefit to keep the LSI IRQ numbers in a well known
range which will be useful for PHB hotplug.
For compatibility with older machines, we use the machine class flag
'pre_2_11_has_no_bitmap'.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/intc/xics_spapr.c | 6 +++---
hw/ppc/spapr.c | 25 ++++++++++++++++++++++---
include/hw/ppc/xics.h | 2 +-
3 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index f2e20bca5b2e..e1f158302a6a 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -257,7 +257,7 @@ int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
}
irq = irq_hint;
} else {
- irq = xic->irq_alloc_block(ics->xics, 1, 0);
+ irq = xic->irq_alloc_block(ics->xics, 1, 0, lsi);
if (irq < 0) {
error_setg(errp, "can't allocate IRQ: no IRQ left");
return -1;
@@ -291,9 +291,9 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
if (align) {
assert((num == 1) || (num == 2) || (num == 4) ||
(num == 8) || (num == 16) || (num == 32));
- first = xic->irq_alloc_block(ics->xics, num, num);
+ first = xic->irq_alloc_block(ics->xics, num, num, lsi);
} else {
- first = xic->irq_alloc_block(ics->xics, num, 0);
+ first = xic->irq_alloc_block(ics->xics, num, 0, lsi);
}
if (first < 0) {
error_setg(errp, "can't find a free %d-IRQ block", num);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b33eebe44906..5e42e3329ef4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1696,6 +1696,13 @@ static const VMStateDescription vmstate_spapr_patb_entry = {
},
};
+/*
+ * Let's provision 4 LSIs per PHBs
+ */
+#define SPAPR_MAX_PHBS ((SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / \
+ SPAPR_PCI_MEM64_WIN_SIZE - 1)
+#define SPAPR_MAX_LSI (SPAPR_MAX_PHBS * 4)
+
static bool spapr_irq_map_needed(void *opaque)
{
sPAPRMachineState *spapr = opaque;
@@ -3523,8 +3530,6 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
* 1TiB 64-bit MMIO windows for each PHB.
*/
const uint64_t base_buid = 0x800000020000000ULL;
-#define SPAPR_MAX_PHBS ((SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / \
- SPAPR_PCI_MEM64_WIN_SIZE - 1)
int i;
/* Sanity check natural alignments */
@@ -3583,18 +3588,32 @@ static bool spapr_irq_test(XICSFabric *xi, int irq)
return test_bit(srcno, spapr->irq_map);
}
-static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align)
+/*
+ * Split the IRQ number space of the machine in two: first the LSIs
+ * and then the MSIs. This allows us to keep the LSI IRQ numbers in a
+ * well known range which is useful for PHB hotplug.
+ */
+static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align, bool lsi)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
int start = 0;
int srcno;
+ if (!lsi && !smc->pre_2_11_has_no_bitmap) {
+ start = SPAPR_MAX_LSI;
+ }
+
srcno = bitmap_find_next_zero_area(spapr->irq_map, spapr->nr_irqs, start,
count, align);
if (srcno == spapr->nr_irqs) {
return -1;
}
+ if (lsi && !smc->pre_2_11_has_no_bitmap && srcno >= SPAPR_MAX_LSI) {
+ return -1;
+ }
+
bitmap_set(spapr->irq_map, srcno, count);
return srcno + spapr->irq_base;
}
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 30e7f2e0a7dd..c8e6637d16e4 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -177,7 +177,7 @@ typedef struct XICSFabricClass {
ICPState *(*icp_get)(XICSFabric *xi, int server);
/* IRQ allocator helpers */
bool (*irq_test)(XICSFabric *xi, int irq);
- int (*irq_alloc_block)(XICSFabric *xi, int count, int align);
+ int (*irq_alloc_block)(XICSFabric *xi, int count, int align, bool lsi);
void (*irq_free_block)(XICSFabric *xi, int irq, int num);
} XICSFabricClass;
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 5/8] spapr: introduce an is_lsi() operation
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
` (3 preceding siblings ...)
2017-10-29 18:12 ` [Qemu-devel] [PATCH 4/8] spapr: split the IRQ number space for LSI interrupts Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 6/8] sparp: merge ics_set_irq_type() in irq_alloc_block() operation Cédric Le Goater
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
Now that we can distinguish an LSI interrupt from an MSI using the IRQ
number, let's introduce a new XICSFabric operation for this purpose
and remove the use of XICS_FLAGS_IRQ_LSI flag.
The 'irq' parameter continues to refer to the global IRQ number space.
For compatibility with older machines, we use the machine class flag
'pre_2_11_has_no_bitmap'.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/intc/xics.c | 26 +++++++++++++++++---------
hw/intc/xics_kvm.c | 4 ++--
hw/ppc/pnv.c | 16 ++++++++++++++++
hw/ppc/spapr.c | 14 ++++++++++++++
include/hw/ppc/xics.h | 2 ++
5 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 2c4899f278e2..42880e736697 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -33,6 +33,7 @@
#include "trace.h"
#include "qemu/timer.h"
#include "hw/ppc/xics.h"
+#include "hw/ppc/spapr.h"
#include "qemu/error-report.h"
#include "qapi/visitor.h"
#include "monitor/monitor.h"
@@ -70,8 +71,7 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon)
}
monitor_printf(mon, " %4x %s %02x %02x\n",
ics->offset + i,
- (irq->flags & XICS_FLAGS_IRQ_LSI) ?
- "LSI" : "MSI",
+ ics_is_lsi(ics, i) ? "LSI" : "MSI",
irq->priority, irq->status);
}
}
@@ -377,6 +377,14 @@ static const TypeInfo icp_info = {
/*
* ICS: Source layer
*/
+bool ics_is_lsi(ICSState *ics, int srcno)
+{
+ XICSFabric *xi = ics->xics;
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
+
+ return xic->irq_is_lsi(xi, srcno + ics->offset);
+}
+
static void ics_simple_resend_msi(ICSState *ics, int srcno)
{
ICSIRQState *irq = ics->irqs + srcno;
@@ -435,7 +443,7 @@ static void ics_simple_set_irq(void *opaque, int srcno, int val)
{
ICSState *ics = (ICSState *)opaque;
- if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
+ if (ics_is_lsi(ics, srcno)) {
ics_simple_set_irq_lsi(ics, srcno, val);
} else {
ics_simple_set_irq_msi(ics, srcno, val);
@@ -472,7 +480,7 @@ void ics_simple_write_xive(ICSState *ics, int srcno, int server,
trace_xics_ics_simple_write_xive(ics->offset + srcno, srcno, server,
priority);
- if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
+ if (ics_is_lsi(ics, srcno)) {
ics_simple_write_xive_lsi(ics, srcno);
} else {
ics_simple_write_xive_msi(ics, srcno);
@@ -484,10 +492,10 @@ static void ics_simple_reject(ICSState *ics, uint32_t nr)
ICSIRQState *irq = ics->irqs + nr - ics->offset;
trace_xics_ics_simple_reject(nr, nr - ics->offset);
- if (irq->flags & XICS_FLAGS_IRQ_MSI) {
- irq->status |= XICS_STATUS_REJECTED;
- } else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
+ if (ics_is_lsi(ics, nr - ics->offset)) {
irq->status &= ~XICS_STATUS_SENT;
+ } else {
+ irq->status |= XICS_STATUS_REJECTED;
}
}
@@ -497,7 +505,7 @@ static void ics_simple_resend(ICSState *ics)
for (i = 0; i < ics->nr_irqs; i++) {
/* FIXME: filter by server#? */
- if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
+ if (ics_is_lsi(ics, i)) {
ics_simple_resend_lsi(ics, i);
} else {
ics_simple_resend_msi(ics, i);
@@ -512,7 +520,7 @@ static void ics_simple_eoi(ICSState *ics, uint32_t nr)
trace_xics_ics_simple_eoi(nr);
- if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
+ if (ics_is_lsi(ics, srcno)) {
irq->status &= ~XICS_STATUS_SENT;
}
}
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 3091ad3ac2c8..2f10637c9f7c 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -258,7 +258,7 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
state |= KVM_XICS_MASKED;
}
- if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
+ if (ics_is_lsi(ics, i)) {
state |= KVM_XICS_LEVEL_SENSITIVE;
if (irq->status & XICS_STATUS_ASSERTED) {
state |= KVM_XICS_PENDING;
@@ -293,7 +293,7 @@ static void ics_kvm_set_irq(void *opaque, int srcno, int val)
int rc;
args.irq = srcno + ics->offset;
- if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MSI) {
+ if (!ics_is_lsi(ics, srcno)) {
if (!val) {
return;
}
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8288940ef9d7..958223376b4c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1035,6 +1035,21 @@ static bool pnv_irq_test(XICSFabric *xi, int irq)
return false;
}
+static bool pnv_irq_is_lsi(XICSFabric *xi, int irq)
+{
+ PnvMachineState *pnv = POWERNV_MACHINE(xi);
+ int i;
+
+ /* PowerNV machine only has PSI interrupts which are all LSIs */
+ for (i = 0; i < pnv->num_chips; i++) {
+ ICSState *ics = &pnv->chips[i]->psi.ics;
+ if (ics_valid_irq(ics, irq)) {
+ return true;
+ }
+ }
+ return false;
+}
+
static void pnv_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
@@ -1120,6 +1135,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
xic->ics_get = pnv_ics_get;
xic->ics_resend = pnv_ics_resend;
xic->irq_test = pnv_irq_test;
+ xic->irq_is_lsi = pnv_irq_is_lsi;
ispc->print_info = pnv_pic_print_info;
powernv_machine_class_props_init(oc);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5e42e3329ef4..d97f287118f0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3626,6 +3626,19 @@ static void spapr_irq_free_block(XICSFabric *xi, int irq, int num)
bitmap_clear(spapr->irq_map, srcno, num);
}
+static bool spapr_irq_is_lsi(XICSFabric *xi, int irq)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ int srcno = irq - spapr->irq_base;
+
+ if (smc->pre_2_11_has_no_bitmap) {
+ return spapr->ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI;
+ } else {
+ return (srcno >= 0) && (srcno < SPAPR_MAX_LSI);
+ }
+}
+
static void spapr_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
@@ -3723,6 +3736,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
xic->irq_test = spapr_irq_test;
xic->irq_alloc_block = spapr_irq_alloc_block;
xic->irq_free_block = spapr_irq_free_block;
+ xic->irq_is_lsi = spapr_irq_is_lsi;
ispc->print_info = spapr_pic_print_info;
/* Force NUMA node memory size to be a multiple of
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index c8e6637d16e4..292b929e88eb 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -179,6 +179,7 @@ typedef struct XICSFabricClass {
bool (*irq_test)(XICSFabric *xi, int irq);
int (*irq_alloc_block)(XICSFabric *xi, int count, int align, bool lsi);
void (*irq_free_block)(XICSFabric *xi, int irq, int num);
+ bool (*irq_is_lsi)(XICSFabric *xi, int irq);
} XICSFabricClass;
#define XICS_IRQS_SPAPR 1024
@@ -205,6 +206,7 @@ void ics_simple_write_xive(ICSState *ics, int nr, int server,
void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
void icp_pic_print_info(ICPState *icp, Monitor *mon);
void ics_pic_print_info(ICSState *ics, Monitor *mon);
+bool ics_is_lsi(ICSState *ics, int srno);
void ics_resend(ICSState *ics);
void icp_resend(ICPState *ss);
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 6/8] sparp: merge ics_set_irq_type() in irq_alloc_block() operation
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
` (4 preceding siblings ...)
2017-10-29 18:12 ` [Qemu-devel] [PATCH 5/8] spapr: introduce an is_lsi() operation Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 7/8] spapr: move spapr_ics_free() under irq_free_block() operation Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 8/8] spapr: use sPAPRMachineState in spapr_ics_* prototypes Cédric Le Goater
7 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
Setting the XICS_FLAGS_IRQ_LSI (or XICS_FLAGS_IRQ_MSI) for pre-2.11
pseries machines can now be done directly under the irq_alloc_block()
operation. let's remove ics_set_irq_type() which becomes useless.
The PowerNV machine is a bit special because it does not manage its
own IRQ number allocator yet. But, as it only handles the PSI
interrupts which are LSIs, this is not a problem.
For compatibility with older machines, we use the machine class flag
'pre_2_11_has_no_bitmap'.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/intc/xics.c | 8 --------
hw/intc/xics_spapr.c | 9 +--------
hw/ppc/pnv_psi.c | 4 ----
hw/ppc/spapr.c | 9 ++++++++-
4 files changed, 9 insertions(+), 21 deletions(-)
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 42880e736697..237eed3c11f8 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -710,14 +710,6 @@ ICPState *xics_icp_get(XICSFabric *xi, int server)
return xic->icp_get(xi, server);
}
-void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
-{
- assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
-
- ics->irqs[srcno].flags |=
- lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
-}
-
static void xics_register_types(void)
{
type_register_static(&ics_simple_info);
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index e1f158302a6a..23d81ff83182 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -264,7 +264,6 @@ int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
}
}
- ics_set_irq_type(ics, irq - ics->offset, lsi);
trace_xics_alloc(irq);
return irq;
@@ -277,7 +276,7 @@ int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
bool align, Error **errp)
{
- int i, first = -1;
+ int first = -1;
XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
@@ -300,12 +299,6 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
return -1;
}
- if (first >= 0) {
- for (i = first; i < first + num; ++i) {
- ics_set_irq_type(ics, i - ics->offset, lsi);
- }
- }
-
trace_xics_alloc_block(first, num, lsi, align);
return first;
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 9876c266223d..ee7fca311cbf 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -487,10 +487,6 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
return;
}
- for (i = 0; i < ics->nr_irqs; i++) {
- ics_set_irq_type(ics, i, true);
- }
-
/* XSCOM region for PSI registers */
pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_xscom_ops,
psi, "xscom-psi", PNV_XSCOM_PSIHB_SIZE);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d97f287118f0..557d89d9ecb5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3598,7 +3598,7 @@ static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align, bool lsi)
sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
int start = 0;
- int srcno;
+ int srcno, i;
if (!lsi && !smc->pre_2_11_has_no_bitmap) {
start = SPAPR_MAX_LSI;
@@ -3614,6 +3614,13 @@ static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align, bool lsi)
return -1;
}
+ if (lsi && smc->pre_2_11_has_no_bitmap) {
+ for (i = srcno; i < srcno + count; ++i) {
+ assert(!(spapr->ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));
+ spapr->ics->irqs[srcno].flags = XICS_FLAGS_IRQ_LSI;
+ }
+ }
+
bitmap_set(spapr->irq_map, srcno, count);
return srcno + spapr->irq_base;
}
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 7/8] spapr: move spapr_ics_free() under irq_free_block() operation
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
` (5 preceding siblings ...)
2017-10-29 18:12 ` [Qemu-devel] [PATCH 6/8] sparp: merge ics_set_irq_type() in irq_alloc_block() operation Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
2017-10-29 18:12 ` [Qemu-devel] [PATCH 8/8] spapr: use sPAPRMachineState in spapr_ics_* prototypes Cédric Le Goater
7 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
So we can now use bitmap_clear() which is slightly more efficent but
more important, it removes the usage of ics_valid_irq() which has a
reference to the 'ics' object of the machine.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/intc/trace-events | 2 --
hw/intc/xics_spapr.c | 19 ++-----------------
hw/ppc/spapr.c | 11 ++++++++++-
hw/ppc/trace-events | 2 ++
4 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index b86f242b0fcf..e34ecf7a16e5 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -65,8 +65,6 @@ xics_ics_simple_reject(int nr, int srcno) "reject irq 0x%x [src %d]"
xics_ics_simple_eoi(int nr) "ics_eoi: irq 0x%x"
xics_alloc(int irq) "irq %d"
xics_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %d irqs, lsi=%d, alignnum %d"
-xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
-xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free"
# hw/intc/s390_flic_kvm.c
flic_create_device(int err) "flic: create device failed %d"
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 23d81ff83182..4ba23fe5125b 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -304,25 +304,10 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
return first;
}
-static void ics_free(ICSState *ics, int irq, int num)
-{
- int i;
- XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
-
- for (i = irq; i < irq + num; ++i) {
- if (xic->irq_test(ics->xics, i)) {
- trace_xics_ics_free_warn(0, i);
- }
- xic->irq_free_block(ics->xics, i, 1);
- }
-}
-
void spapr_ics_free(ICSState *ics, int irq, int num)
{
- if (ics_valid_irq(ics, irq)) {
- trace_xics_ics_free(0, irq, num);
- ics_free(ics, irq, num);
- }
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
+ xic->irq_free_block(ics->xics, irq, num);
}
void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 557d89d9ecb5..f8224ea3e894 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3629,8 +3629,17 @@ static void spapr_irq_free_block(XICSFabric *xi, int irq, int num)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
int srcno = irq - spapr->irq_base;
+ int i;
- bitmap_clear(spapr->irq_map, srcno, num);
+ if (srcno >= 0 && srcno < spapr->nr_irqs) {
+ trace_spapr_irq_free(0, irq, num);
+ for (i = srcno; i < srcno + num; ++i) {
+ if (!test_bit(i, spapr->irq_map)) {
+ trace_spapr_irq_free_warn(0, i);
+ }
+ }
+ bitmap_clear(spapr->irq_map, srcno, num);
+ }
}
static bool spapr_irq_is_lsi(XICSFabric *xi, int irq)
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index 4a6a6490fa78..dc9ab4c4deb3 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -12,6 +12,8 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) "
# hw/ppc/spapr.c
spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
+spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
+spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free"
# hw/ppc/spapr_hcall.c
spapr_cas_pvr_try(uint32_t pvr) "0x%x"
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 8/8] spapr: use sPAPRMachineState in spapr_ics_* prototypes
2017-10-29 18:12 [Qemu-devel] [PATCH 0/8] introduce an IRQ allocator at the machine level Cédric Le Goater
` (6 preceding siblings ...)
2017-10-29 18:12 ` [Qemu-devel] [PATCH 7/8] spapr: move spapr_ics_free() under irq_free_block() operation Cédric Le Goater
@ 2017-10-29 18:12 ` Cédric Le Goater
7 siblings, 0 replies; 13+ messages in thread
From: Cédric Le Goater @ 2017-10-29 18:12 UTC (permalink / raw)
To: qemu-ppc, qemu-devel, David Gibson, Greg Kurz,
Benjamin Herrenschmidt
Cc: Cédric Le Goater
The routines manipulating the IRQ numbers for the sPAPR machine do not
have any relation with the ICSState anymore. So use a sPAPRMachineState
parameter in their prototype and prefix them with spapr_irq_.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
hw/intc/xics_spapr.c | 23 ++++++++++++-----------
hw/ppc/spapr.c | 5 +++--
hw/ppc/spapr_events.c | 4 ++--
hw/ppc/spapr_pci.c | 8 ++++----
hw/ppc/spapr_vio.c | 2 +-
include/hw/ppc/xics.h | 13 +++++++------
6 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 4ba23fe5125b..3f8c937c4fa1 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -245,19 +245,20 @@ void xics_spapr_init(sPAPRMachineState *spapr)
spapr_register_hypercall(H_IPOLL, h_ipoll);
}
-int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
+int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi,
+ Error **errp)
{
int irq;
- XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(spapr);
if (irq_hint) {
- if (xic->irq_test(ics->xics, irq_hint)) {
+ if (xic->irq_test(XICS_FABRIC(spapr), irq_hint)) {
error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
return -1;
}
irq = irq_hint;
} else {
- irq = xic->irq_alloc_block(ics->xics, 1, 0, lsi);
+ irq = xic->irq_alloc_block(XICS_FABRIC(spapr), 1, 0, lsi);
if (irq < 0) {
error_setg(errp, "can't allocate IRQ: no IRQ left");
return -1;
@@ -273,11 +274,11 @@ int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp)
* Allocate block of consecutive IRQs, and return the number of the first IRQ in
* the block. If align==true, aligns the first IRQ number to num.
*/
-int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
+int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi,
bool align, Error **errp)
{
int first = -1;
- XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(spapr);
/*
@@ -290,9 +291,9 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
if (align) {
assert((num == 1) || (num == 2) || (num == 4) ||
(num == 8) || (num == 16) || (num == 32));
- first = xic->irq_alloc_block(ics->xics, num, num, lsi);
+ first = xic->irq_alloc_block(XICS_FABRIC(spapr), num, num, lsi);
} else {
- first = xic->irq_alloc_block(ics->xics, num, 0, lsi);
+ first = xic->irq_alloc_block(XICS_FABRIC(spapr), num, 0, lsi);
}
if (first < 0) {
error_setg(errp, "can't find a free %d-IRQ block", num);
@@ -304,10 +305,10 @@ int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi,
return first;
}
-void spapr_ics_free(ICSState *ics, int irq, int num)
+void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num)
{
- XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(ics->xics);
- xic->irq_free_block(ics->xics, irq, num);
+ XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(spapr);
+ xic->irq_free_block(XICS_FABRIC(spapr), irq, num);
}
void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f8224ea3e894..a5b087eb5c56 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3593,7 +3593,8 @@ static bool spapr_irq_test(XICSFabric *xi, int irq)
* and then the MSIs. This allows us to keep the LSI IRQ numbers in a
* well known range which is useful for PHB hotplug.
*/
-static int spapr_irq_alloc_block(XICSFabric *xi, int count, int align, bool lsi)
+static int spapr_irq_alloc_block_xi(XICSFabric *xi, int count, int align,
+ bool lsi)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(xi);
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
@@ -3750,7 +3751,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
xic->ics_resend = spapr_ics_resend;
xic->icp_get = spapr_icp_get;
xic->irq_test = spapr_irq_test;
- xic->irq_alloc_block = spapr_irq_alloc_block;
+ xic->irq_alloc_block = spapr_irq_alloc_block_xi;
xic->irq_free_block = spapr_irq_free_block;
xic->irq_is_lsi = spapr_irq_is_lsi;
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index e377fc7ddea2..cead596f3e7a 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -718,7 +718,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
spapr->event_sources = spapr_event_sources_new();
spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW,
- spapr_ics_alloc(spapr->ics, 0, false,
+ spapr_irq_alloc(spapr, 0, false,
&error_fatal));
/* NOTE: if machine supports modern/dedicated hotplug event source,
@@ -731,7 +731,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
*/
if (spapr->use_hotplug_event_source) {
spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG,
- spapr_ics_alloc(spapr->ics, 0, false,
+ spapr_irq_alloc(spapr, 0, false,
&error_fatal));
}
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 5a3122a9f9f9..e0ef77a480e5 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -314,7 +314,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
- spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
+ spapr_irq_free(spapr, msi->first_irq, msi->num);
if (msi_present(pdev)) {
spapr_msi_setmsg(pdev, 0, false, 0, 0);
}
@@ -352,7 +352,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
/* Allocate MSIs */
- irq = spapr_ics_alloc_block(spapr->ics, req_num, false,
+ irq = spapr_irq_alloc_block(spapr, req_num, false,
ret_intr_type == RTAS_TYPE_MSI, &err);
if (err) {
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
@@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
/* Release previous MSIs */
if (msi) {
- spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
+ spapr_irq_free(spapr, msi->first_irq, msi->num);
g_hash_table_remove(phb->msi, &config_addr);
}
@@ -1675,7 +1675,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
uint32_t irq;
Error *local_err = NULL;
- irq = spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_err);
+ irq = spapr_irq_alloc_block(spapr, 1, true, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "can't allocate LSIs: ");
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index ea3bc8bd9e21..bb7ed2c537b0 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -454,7 +454,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
dev->qdev.id = id;
}
- dev->irq = spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err);
+ dev->irq = spapr_irq_alloc(spapr, dev->irq, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 292b929e88eb..943f6f235be1 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -184,10 +184,13 @@ typedef struct XICSFabricClass {
#define XICS_IRQS_SPAPR 1024
-int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
-int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
- Error **errp);
-void spapr_ics_free(ICSState *ics, int irq, int num);
+typedef struct sPAPRMachineState sPAPRMachineState;
+
+int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi,
+ Error **errp);
+int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi,
+ bool align, Error **errp);
+void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle);
qemu_irq xics_get_qirq(XICSFabric *xi, int irq);
@@ -211,8 +214,6 @@ bool ics_is_lsi(ICSState *ics, int srno);
void ics_resend(ICSState *ics);
void icp_resend(ICPState *ss);
-typedef struct sPAPRMachineState sPAPRMachineState;
-
int xics_kvm_init(sPAPRMachineState *spapr, Error **errp);
void xics_spapr_init(sPAPRMachineState *spapr);
--
2.13.6
^ permalink raw reply related [flat|nested] 13+ messages in thread