diff options
| author | Nicholas Piggin <npiggin@gmail.com> | 2024-08-06 23:13:11 +1000 |
|---|---|---|
| committer | Nicholas Piggin <npiggin@gmail.com> | 2024-11-04 09:08:09 +1000 |
| commit | 899e488650bb8bd52e1b2b44ceaae17df2e20b7f (patch) | |
| tree | 378e6ac3c45e9904b37f73a78c1c004794a25777 /hw/ppc/pnv_lpc.c | |
| parent | 7b4820a3e1dfba2b81f2354e7c748fc04b275dba (diff) | |
| download | focaccia-qemu-899e488650bb8bd52e1b2b44ceaae17df2e20b7f.tar.gz focaccia-qemu-899e488650bb8bd52e1b2b44ceaae17df2e20b7f.zip | |
ppc/pnv: Fix LPC serirq routing calculation
The serirq routing table is split over two registers, the calculation for the high irqs in the second register did not subtract the irq offset. This was spotted by Coverity as a shift-by-negative. Fix this and change the open-coded shifting and masking to use extract32() function so it's less error-prone. This went unnoticed because irqs >= 14 are not used in a standard QEMU/OPAL boot, changing the first QEMU serial-isa irq to 14 to test does demonstrate serial irqs aren't received, and that this change fixes that. Cc: qemu-stable@nongnu.org Reported-by: Cédric Le Goater <clg@redhat.com> Resolves: Coverity CID 1558829 (partially) Reviewed-by: Cédric Le Goater <clg@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Diffstat (limited to 'hw/ppc/pnv_lpc.c')
| -rw-r--r-- | hw/ppc/pnv_lpc.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index f8aad955b5..80b79dfbbc 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -435,13 +435,19 @@ static void pnv_lpc_eval_serirq_routes(PnvLpcController *lpc) return; } + /* + * Each of the ISA irqs is routed to one of the 4 SERIRQ irqs with 2 + * bits, split across 2 OPB registers. + */ for (irq = 0; irq <= 13; irq++) { - int serirq = (lpc->opb_irq_route1 >> (31 - 5 - (irq * 2))) & 0x3; + int serirq = extract32(lpc->opb_irq_route1, + PPC_BIT32_NR(5 + irq * 2), 2); lpc->irq_to_serirq_route[irq] = serirq; } for (irq = 14; irq < ISA_NUM_IRQS; irq++) { - int serirq = (lpc->opb_irq_route0 >> (31 - 9 - (irq * 2))) & 0x3; + int serirq = extract32(lpc->opb_irq_route0, + PPC_BIT32_NR(9 + (irq - 14) * 2), 2); lpc->irq_to_serirq_route[irq] = serirq; } } |