hw/intc/arm_gic: Allow reset of the running priority
When running Linux on a machine with GICv2, the kernel can crash while processing an interrupt and can subsequently start a kdump kernel from the active interrupt handler. In such a case, the crashed kernel might not gracefully signal the end of interrupt to the GICv2 hardware. The kdump kernel will however try to reset the GIC state on startup to get the controller into a sane state, in particular the kernel writes ones to GICD_ICACTIVERn and wipes out GICC_APRn to make sure that no interrupt is active. The patch adds a logic to recalculate the running priority when GICC_APRn/GICC_NSAPRn is written which makes sure that the mentioned reset works with the GICv2 emulation in QEMU too and the kdump kernel starts receiving interrupts. The described scenario can be reproduced on an AArch64 QEMU virt machine with a kdump-enabled Linux system by using the softdog module. The kdump kernel will hang at some point because QEMU still thinks the running priority is that of the timer interrupt and asserts no new interrupts to the system: $ modprobe softdog soft_margin=10 soft_panic=1 $ cat > /dev/watchdog [Press Enter to start the watchdog, wait for its timeout and observe that the kdump kernel hangs on startup.] Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Message-id: 20220113151916.17978-3-ppavlu@suse.cz Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a66a24585f
commit
5e66daec9e
@ -1736,6 +1736,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
|
|||||||
} else {
|
} else {
|
||||||
s->apr[regno][cpu] = value;
|
s->apr[regno][cpu] = value;
|
||||||
}
|
}
|
||||||
|
s->running_priority[cpu] = gic_get_prio_from_apr_bits(s, cpu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0xe0: case 0xe4: case 0xe8: case 0xec:
|
case 0xe0: case 0xe4: case 0xe8: case 0xec:
|
||||||
@ -1752,6 +1753,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
|
|||||||
return MEMTX_OK;
|
return MEMTX_OK;
|
||||||
}
|
}
|
||||||
s->nsapr[regno][cpu] = value;
|
s->nsapr[regno][cpu] = value;
|
||||||
|
s->running_priority[cpu] = gic_get_prio_from_apr_bits(s, cpu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x1000:
|
case 0x1000:
|
||||||
|
Loading…
Reference in New Issue
Block a user