mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-12-16 23:48:14 +01:00
shutdown_pirq and startup_pirq are not taking the
irq_mapping_update_lock because they can't due to lock inversion. Both
are called with the irq_desc->lock being taking. The lock order,
however, is first irq_mapping_update_lock and then irq_desc->lock.
This opens multiple races:
- shutdown_pirq can be interrupted by a function that allocates an event
channel:
CPU0 CPU1
shutdown_pirq {
xen_evtchn_close(e)
__startup_pirq {
EVTCHNOP_bind_pirq
-> returns just freed evtchn e
set_evtchn_to_irq(e, irq)
}
xen_irq_info_cleanup() {
set_evtchn_to_irq(e, -1)
}
}
Assume here event channel e refers here to the same event channel
number.
After this race the evtchn_to_irq mapping for e is invalid (-1).
- __startup_pirq races with __unbind_from_irq in a similar way. Because
__startup_pirq doesn't take irq_mapping_update_lock it can grab the
evtchn that __unbind_from_irq is currently freeing and cleaning up. In
this case even though the event channel is allocated, its mapping can
be unset in evtchn_to_irq.
The fix is to first cleanup the mappings and then close the event
channel. In this way, when an event channel gets allocated it's
potential previous evtchn_to_irq mappings are guaranteed to be unset already.
This is also the reverse order of the allocation where first the event
channel is allocated and then the mappings are setup.
On a 5.10 kernel prior to commit
|
||
|---|---|---|
| .. | ||
| events | ||
| xen-pciback | ||
| xenbus | ||
| xenfs | ||
| acpi.c | ||
| arm-device.c | ||
| balloon.c | ||
| biomerge.c | ||
| cpu_hotplug.c | ||
| dbgp.c | ||
| efi.c | ||
| evtchn.c | ||
| features.c | ||
| gntalloc.c | ||
| gntdev-common.h | ||
| gntdev-dmabuf.c | ||
| gntdev-dmabuf.h | ||
| gntdev.c | ||
| grant-dma-iommu.c | ||
| grant-dma-ops.c | ||
| grant-table.c | ||
| Kconfig | ||
| Makefile | ||
| manage.c | ||
| mcelog.c | ||
| mem-reservation.c | ||
| pci.c | ||
| pcpu.c | ||
| platform-pci.c | ||
| privcmd-buf.c | ||
| privcmd.c | ||
| privcmd.h | ||
| pvcalls-back.c | ||
| pvcalls-front.c | ||
| pvcalls-front.h | ||
| swiotlb-xen.c | ||
| sys-hypervisor.c | ||
| time.c | ||
| unpopulated-alloc.c | ||
| xen-acpi-pad.c | ||
| xen-acpi-processor.c | ||
| xen-balloon.c | ||
| xen-front-pgdir-shbuf.c | ||
| xen-scsiback.c | ||
| xlate_mmu.c | ||