From 119eaa9d11cb5245fae0a2cbe4f18dda55744dfb Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Nov 2019 07:58:07 +0100 Subject: [PATCH] ppc/pnv: Fix TIMA indirect access MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Message-Id: <20191125065820.927-8-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/pnv_xive.c | 13 +++++++------ hw/ppc/pnv.c | 17 +++++++++++++++++ include/hw/ppc/pnv.h | 2 ++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index ec8349ee4a..b2ab2ccc91 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 d899c83e52..8f688f4efc 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); diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 12b0169a40..a58cfea3f2 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) -- 2.11.4.GIT