On Mon, Nov 25, 2019 at 07:58:07AM +0100, Cédric Le Goater wrote: > When the TIMA of a CPU needs to be accessed from the indirect page, > the thread id of the target CPU is first stored in the PC_TCTXT_INDIR0 > register. This thread id is relative to the chip and not to the system. > > Introduce a helper routine to look for a CPU of a given PIR and fix > pnv_xive_get_indirect_tctx() to scan only the threads of the local > chip and not the whole machine. > > Signed-off-by: Cédric Le Goater <c...@kaod.org>
Applied to ppc-for-5.0. > --- > include/hw/ppc/pnv.h | 2 ++ > hw/intc/pnv_xive.c | 13 +++++++------ > hw/ppc/pnv.c | 17 +++++++++++++++++ > 3 files changed, 26 insertions(+), 6 deletions(-) > > diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h > index 12b0169a4010..a58cfea3f2fd 100644 > --- a/include/hw/ppc/pnv.h > +++ b/include/hw/ppc/pnv.h > @@ -162,6 +162,8 @@ typedef struct PnvChipClass { > #define PNV_CHIP_INDEX(chip) \ > (((chip)->chip_id >> 2) * 2 + ((chip)->chip_id & 0x3)) > > +PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir); > + > #define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv") > #define PNV_MACHINE(obj) \ > OBJECT_CHECK(PnvMachineState, (obj), TYPE_PNV_MACHINE) > diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c > index ec8349ee4a1f..b2ab2ccc91e7 100644 > --- a/hw/intc/pnv_xive.c > +++ b/hw/intc/pnv_xive.c > @@ -1400,12 +1400,13 @@ static const MemoryRegionOps pnv_xive_ic_lsi_ops = { > */ > > /* > - * When the TIMA is accessed from the indirect page, the thread id > - * (PIR) has to be configured in the IC registers before. This is used > - * for resets and for debug purpose also. > + * When the TIMA is accessed from the indirect page, the thread id of > + * the target CPU is configured in the PC_TCTXT_INDIR0 register before > + * use. This is used for resets and for debug purpose also. > */ > static XiveTCTX *pnv_xive_get_indirect_tctx(PnvXive *xive) > { > + PnvChip *chip = xive->chip; > uint64_t tctxt_indir = xive->regs[PC_TCTXT_INDIR0 >> 3]; > PowerPCCPU *cpu = NULL; > int pir; > @@ -1415,15 +1416,15 @@ static XiveTCTX *pnv_xive_get_indirect_tctx(PnvXive > *xive) > return NULL; > } > > - pir = GETFIELD(PC_TCTXT_INDIR_THRDID, tctxt_indir) & 0xff; > - cpu = ppc_get_vcpu_by_pir(pir); > + pir = (chip->chip_id << 8) | GETFIELD(PC_TCTXT_INDIR_THRDID, > tctxt_indir); > + cpu = pnv_chip_find_cpu(chip, pir); > if (!cpu) { > xive_error(xive, "IC: invalid PIR %x for indirect access", pir); > return NULL; > } > > /* Check that HW thread is XIVE enabled */ > - if (!(xive->regs[PC_THREAD_EN_REG0 >> 3] & PPC_BIT(pir & 0x3f))) { > + if (!pnv_xive_is_cpu_enabled(xive, cpu)) { > xive_error(xive, "IC: CPU %x is not enabled", pir); > } > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c > index d899c83e5255..8f688f4efc5a 100644 > --- a/hw/ppc/pnv.c > +++ b/hw/ppc/pnv.c > @@ -1371,6 +1371,23 @@ static void pnv_chip_class_init(ObjectClass *klass, > void *data) > dc->desc = "PowerNV Chip"; > } > > +PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir) > +{ > + int i, j; > + > + for (i = 0; i < chip->nr_cores; i++) { > + PnvCore *pc = chip->cores[i]; > + CPUCore *cc = CPU_CORE(pc); > + > + for (j = 0; j < cc->nr_threads; j++) { > + if (ppc_cpu_pir(pc->threads[j]) == pir) { > + return pc->threads[j]; > + } > + } > + } > + return NULL; > +} > + > static ICSState *pnv_ics_get(XICSFabric *xi, int irq) > { > PnvMachineState *pnv = PNV_MACHINE(xi); -- 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