irqchip fixes for 5.13, take #2
- Fix GICv3 NMI handling where an IRQ could be mistakenly handled as a NMI, with disatrous effects -----BEGIN PGP SIGNATURE----- iQJDBAABCgAtFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAmDCREAPHG1hekBrZXJu ZWwub3JnAAoJECPQ0LrRPXpDqd4P/3+CcBq9PnVtmPHzP8be/2QRf3nRbM/2Fwzt Ovu68Y4xQzYHfC5nzRHghb4AZJthUFVDiEtuzDTav2G9PlwhKdw0yE2DoPaFpAkq p8sBTdd68bUxL64gpHHLjv7s9oA7mYmwlNVZM6fiXiqvmNUYuCjaic5RqKWcxlE7 ERcAa4me3tvfbKxHSo2rDm4bK8oYUHlCxdPgVPGZFQm2+q3/IWNM3E0B4GBvWIwO BiVFNzVma9/TmxSP2NAlLtIvUUSChumzcipLlpOigfiFc6yuego8cL/QxHILPhK5 DO8UsKMbja1jVc9C/zAbpU/PbaBhveMGwoGkgOqQfbvuqkImgOMrsN6Z+kPxAijg yhdYkw23awcmsDs2HhALxvoGhu+OUBXjPb1/jRsqv60zHq2VY6YV5ohK7WYnm7RA 1K0Bcf+GNpjAp2uWIrnsrfXXdFGPZXOK7XZS3sLE2DAnUHUPL3EvKCVGOfAS6Sd9 IcSbTDSC8MtJfgc/Hp7upmaogZ5tR/0/LyhNu6Bg4nVMGRPJ97FmNEecRswq33Wr W5ZQJRRRCQO+hpi5eRnGMol1646MxwOF9b75vJ3XLd/ZUxOrdYOlyUBFebjHIX3F 0xnzroPD9mQY9cO2nQDa+ulu75B+MCswyvFA+49Bn9JLgE/jFd7uE5mGkWEE70a4 LvcX+Ate =yKDo -----END PGP SIGNATURE----- Merge tag 'irqchip-fixes-5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent Pull irqchip fixes from Marc Zyngier: - Fix GICv3 NMI handling where an IRQ could be mistakenly handled as a NMI, with disatrous effects Link: https://lore.kernel.org/r/20210610171127.2404752-1-maz@kernel.org
This commit is contained in:
commit
a13d0f8d11
1 changed files with 35 additions and 1 deletions
|
@ -642,11 +642,45 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
|
||||||
nmi_exit();
|
nmi_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 do_read_iar(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
u32 iar;
|
||||||
|
|
||||||
|
if (gic_supports_nmi() && unlikely(!interrupts_enabled(regs))) {
|
||||||
|
u64 pmr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We were in a context with IRQs disabled. However, the
|
||||||
|
* entry code has set PMR to a value that allows any
|
||||||
|
* interrupt to be acknowledged, and not just NMIs. This can
|
||||||
|
* lead to surprising effects if the NMI has been retired in
|
||||||
|
* the meantime, and that there is an IRQ pending. The IRQ
|
||||||
|
* would then be taken in NMI context, something that nobody
|
||||||
|
* wants to debug twice.
|
||||||
|
*
|
||||||
|
* Until we sort this, drop PMR again to a level that will
|
||||||
|
* actually only allow NMIs before reading IAR, and then
|
||||||
|
* restore it to what it was.
|
||||||
|
*/
|
||||||
|
pmr = gic_read_pmr();
|
||||||
|
gic_pmr_mask_irqs();
|
||||||
|
isb();
|
||||||
|
|
||||||
|
iar = gic_read_iar();
|
||||||
|
|
||||||
|
gic_write_pmr(pmr);
|
||||||
|
} else {
|
||||||
|
iar = gic_read_iar();
|
||||||
|
}
|
||||||
|
|
||||||
|
return iar;
|
||||||
|
}
|
||||||
|
|
||||||
static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
|
static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
u32 irqnr;
|
u32 irqnr;
|
||||||
|
|
||||||
irqnr = gic_read_iar();
|
irqnr = do_read_iar(regs);
|
||||||
|
|
||||||
/* Check for special IDs first */
|
/* Check for special IDs first */
|
||||||
if ((irqnr >= 1020 && irqnr <= 1023))
|
if ((irqnr >= 1020 && irqnr <= 1023))
|
||||||
|
|
Loading…
Add table
Reference in a new issue