[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v3 05/18] ppc/spapr: Implement the XiveFabric and Xive
From: |
Cédric Le Goater |
Subject: |
[Qemu-ppc] [PATCH v3 05/18] ppc/spapr: Implement the XiveFabric and XivePresenter interfaces |
Date: |
Wed, 31 Jul 2019 16:12:20 +0200 |
The CAM line matching sequence in the pseries machine does not change
much apart from the use of the new QOM interfaces.
Fixes: af53dbf6227a ("ppc/xive: introduce a simplified XIVE presenter")
Signed-off-by: Cédric Le Goater <address@hidden>
---
include/hw/ppc/spapr_irq.h | 6 ++++++
hw/intc/spapr_xive.c | 41 ++++++++++++++++++++++++++++++++++++++
hw/ppc/spapr.c | 34 +++++++++++++++++++++++++++++++
hw/ppc/spapr_irq.c | 25 +++++++++++++++++++++++
4 files changed, 106 insertions(+)
diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h
index f965a58f8954..8c99b0680f97 100644
--- a/include/hw/ppc/spapr_irq.h
+++ b/include/hw/ppc/spapr_irq.h
@@ -30,6 +30,8 @@ int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t
num, bool align,
void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
void spapr_irq_msi_reset(SpaprMachineState *spapr);
+struct XiveTCTXMatch;
+
typedef struct SpaprIrq {
uint32_t nr_irqs;
uint32_t nr_msis;
@@ -49,6 +51,10 @@ typedef struct SpaprIrq {
void (*set_irq)(void *opaque, int srcno, int val);
const char *(*get_nodename)(SpaprMachineState *spapr);
void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
+ int (*match_nvt)(SpaprMachineState *spapr, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, struct XiveTCTXMatch *match);
} SpaprIrq;
extern SpaprIrq spapr_irq_xics;
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index ba012c7b0fdc..beb5049ad9da 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -419,6 +419,44 @@ static XiveTCTX *spapr_xive_get_tctx(XiveRouter *xrtr,
CPUState *cs)
return spapr_cpu_state(cpu)->tctx;
}
+static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match)
+{
+ CPUState *cs;
+ int count = 0;
+
+ CPU_FOREACH(cs) {
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
+ int ring;
+
+ /*
+ * Check the thread context CAM lines and record matches.
+ */
+ ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
+ cam_ignore, logic_serv);
+ /*
+ * Save the matching thread interrupt context and follow on to
+ * check for duplicates which are invalid.
+ */
+ if (ring != -1) {
+ if (match->tctx) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
+ "context NVT %x/%x\n", nvt_blk, nvt_idx);
+ return -1;
+ }
+
+ match->ring = ring;
+ match->tctx = tctx;
+ count++;
+ }
+ }
+
+ return count;
+}
+
static const VMStateDescription vmstate_spapr_xive_end = {
.name = TYPE_SPAPR_XIVE "/end",
.version_id = 1,
@@ -496,6 +534,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void
*data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
+ XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
dc->desc = "sPAPR XIVE Interrupt Controller";
dc->props = spapr_xive_properties;
@@ -508,6 +547,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void
*data)
xrc->get_nvt = spapr_xive_get_nvt;
xrc->write_nvt = spapr_xive_write_nvt;
xrc->get_tctx = spapr_xive_get_tctx;
+
+ xpc->match_nvt = spapr_xive_match_nvt;
}
static const TypeInfo spapr_xive_info = {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 115bbfb0e788..631db719f41f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4302,6 +4302,37 @@ static void spapr_pic_print_info(InterruptStatsProvider
*obj,
spapr->irq->print_info(spapr, mon);
}
+static int spapr_xive_match_nvt(XiveFabric *xfb, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match)
+{
+ SpaprMachineState *spapr = SPAPR_MACHINE(xfb);
+ int count;
+
+ count = spapr->irq->match_nvt(spapr, format, nvt_blk, nvt_idx, cam_ignore,
+ priority, logic_serv, match);
+ if (count < 0) {
+ return count;
+ }
+
+ /*
+ * When we implement the save and restore of the thread interrupt
+ * contexts in the enter/exit CPU handlers of the machine and the
+ * escalations in QEMU, we should be able to handle non dispatched
+ * vCPUs.
+ *
+ * Until this is done, the sPAPR machine should find at least one
+ * matching context always.
+ */
+ if (count == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is not dispatched\n",
+ nvt_blk, nvt_idx);
+ }
+
+ return count;
+}
+
int spapr_get_vcpu_id(PowerPCCPU *cpu)
{
return cpu->vcpu_id;
@@ -4398,6 +4429,7 @@ static void spapr_machine_class_init(ObjectClass *oc,
void *data)
PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
+ XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
mc->desc = "pSeries Logical Partition (PAPR compliant)";
mc->ignore_boot_device_suffixes = true;
@@ -4456,6 +4488,7 @@ static void spapr_machine_class_init(ObjectClass *oc,
void *data)
*/
mc->numa_mem_align_shift = 28;
mc->numa_mem_supported = true;
+ xfc->match_nvt = spapr_xive_match_nvt;
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
@@ -4488,6 +4521,7 @@ static const TypeInfo spapr_machine_info = {
{ TYPE_PPC_VIRTUAL_HYPERVISOR },
{ TYPE_XICS_FABRIC },
{ TYPE_INTERRUPT_STATS_PROVIDER },
+ { TYPE_XIVE_FABRIC },
{ }
},
};
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index ff3df0bbd8cf..ff824d950f05 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -262,6 +262,7 @@ SpaprIrq spapr_irq_xics = {
.set_irq = spapr_irq_set_irq_xics,
.get_nodename = spapr_irq_get_nodename_xics,
.init_kvm = spapr_irq_init_kvm_xics,
+ .match_nvt = NULL, /* should not be used */
};
/*
@@ -411,6 +412,18 @@ static void spapr_irq_init_kvm_xive(SpaprMachineState
*spapr, Error **errp)
}
}
+static int spapr_irq_match_nvt_xive(SpaprMachineState *spapr, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match)
+{
+ XivePresenter *xptr = XIVE_PRESENTER(spapr->xive);
+ XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+
+ return xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore,
+ priority, logic_serv, match);
+}
+
/*
* XIVE uses the full IRQ number space. Set it to 8K to be compatible
* with XICS.
@@ -436,6 +449,7 @@ SpaprIrq spapr_irq_xive = {
.set_irq = spapr_irq_set_irq_xive,
.get_nodename = spapr_irq_get_nodename_xive,
.init_kvm = spapr_irq_init_kvm_xive,
+ .match_nvt = spapr_irq_match_nvt_xive,
};
/*
@@ -590,6 +604,15 @@ static const char
*spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
return spapr_irq_current(spapr)->get_nodename(spapr);
}
+static int spapr_irq_match_nvt_dual(SpaprMachineState *spapr, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv, XiveTCTXMatch *match)
+{
+ return spapr_irq_current(spapr)->match_nvt(spapr, format, nvt_blk, nvt_idx,
+ cam_ignore, priority, logic_serv, match);
+}
+
/*
* Define values in sync with the XIVE and XICS backend
*/
@@ -613,6 +636,7 @@ SpaprIrq spapr_irq_dual = {
.set_irq = spapr_irq_set_irq_dual,
.get_nodename = spapr_irq_get_nodename_dual,
.init_kvm = NULL, /* should not be used */
+ .match_nvt = spapr_irq_match_nvt_dual,
};
@@ -828,4 +852,5 @@ SpaprIrq spapr_irq_xics_legacy = {
.set_irq = spapr_irq_set_irq_xics,
.get_nodename = spapr_irq_get_nodename_xics,
.init_kvm = spapr_irq_init_kvm_xics,
+ .match_nvt = NULL, /* should not be used */
};
--
2.21.0
- [Qemu-ppc] [PATCH v3 00/18] ppc/pnv: add XIVE support for KVM guests, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 02/18] tests/boot-serial-test: add support for all the PowerNV machines, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 01/18] ppc/pnv: Introduce PowerNV machines with fixed CPU models, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 03/18] ppc/xive: Introduce the XiveFabric and XivePresenter interfaces, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 04/18] ppc/pnv: Implement the XiveFabric and XivePresenter interfaces, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 05/18] ppc/spapr: Implement the XiveFabric and XivePresenter interfaces,
Cédric Le Goater <=
- [Qemu-ppc] [PATCH v3 06/18] ppc/xive: Use the XiveFabric and XivePresenter interfaces, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 07/18] ppc/xive: Extend the TIMA operation with a XivePresenter parameter, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 08/18] ppc/pnv: Clarify how the TIMA is accessed on a multichip system, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 09/18] ppc/xive: Move the TIMA operations to the controller model, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 10/18] ppc/xive: Introduce a xive_tctx_ipb_update() helper, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 11/18] ppc/xive: Synthesize interrupt from the saved IPB in the NVT, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 12/18] ppc/pnv: Remove pnv_xive_vst_size() routine, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 13/18] ppc/pnv: Dump the XIVE NVT table, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 14/18] ppc/pnv: Skip empty slots of the XIVE NVT table, Cédric Le Goater, 2019/07/31
- [Qemu-ppc] [PATCH v3 15/18] ppc/pnv: Introduce a pnv_xive_block_id() helper, Cédric Le Goater, 2019/07/31