mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 23:23:03 +00:00
fa765c4b4a
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 |