ppc/xive2: Remote VSDs need to match on forwarding address

In a multi chip environment there will be remote/forwarded VSDs.  The check
to find a matching INT controller (XIVE) of the remote block number was
checking the INTs chip number.  Block numbers are not tied to a chip number.
The matching remote INT is the one that matches the forwarded VSD address
with VSD types associated MMIO BAR.

Signed-off-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Michael Kowal <kowal@linux.ibm.com>
Reviewed-by: Caleb Schlossin <calebs@linux.ibm.com>
Tested-by: Gautam Menghani <gautam@linux.ibm.com>
Link: https://lore.kernel.org/qemu-devel/20250512031100.439842-5-npiggin@gmail.com
[ clg: Fixed log format in pnv_xive2_get_remote() ]
Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
Michael Kowal 2025-05-12 13:10:13 +10:00 committed by Cédric Le Goater
parent f16697292a
commit e8cf73b849

View file

@ -101,12 +101,10 @@ static uint32_t pnv_xive2_block_id(PnvXive2 *xive)
}
/*
* Remote access to controllers. HW uses MMIOs. For now, a simple scan
* of the chips is good enough.
*
* TODO: Block scope support
* Remote access to INT controllers. HW uses MMIOs(?). For now, a simple
* scan of all the chips INT controller is good enough.
*/
static PnvXive2 *pnv_xive2_get_remote(uint8_t blk)
static PnvXive2 *pnv_xive2_get_remote(uint32_t vsd_type, hwaddr fwd_addr)
{
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
int i;
@ -115,10 +113,23 @@ static PnvXive2 *pnv_xive2_get_remote(uint8_t blk)
Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
PnvXive2 *xive = &chip10->xive;
if (pnv_xive2_block_id(xive) == blk) {
/*
* Is this the XIVE matching the forwarded VSD address is for this
* VSD type
*/
if ((vsd_type == VST_ESB && fwd_addr == xive->esb_base) ||
(vsd_type == VST_END && fwd_addr == xive->end_base) ||
((vsd_type == VST_NVP ||
vsd_type == VST_NVG) && fwd_addr == xive->nvpg_base) ||
(vsd_type == VST_NVC && fwd_addr == xive->nvc_base)) {
return xive;
}
}
qemu_log_mask(LOG_GUEST_ERROR,
"XIVE: >>>>> %s vsd_type %u fwd_addr 0x%"HWADDR_PRIx
" NOT FOUND\n",
__func__, vsd_type, fwd_addr);
return NULL;
}
@ -251,8 +262,7 @@ static uint64_t pnv_xive2_vst_addr(PnvXive2 *xive, uint32_t type, uint8_t blk,
/* Remote VST access */
if (GETFIELD(VSD_MODE, vsd) == VSD_MODE_FORWARD) {
xive = pnv_xive2_get_remote(blk);
xive = pnv_xive2_get_remote(type, (vsd & VSD_ADDRESS_MASK));
return xive ? pnv_xive2_vst_addr(xive, type, blk, idx) : 0;
}