7faa8075d8
As Michael Tsirkin demonstrated, current PCI hotplug is vulnerable to a few races. The first is a race with other hotplug operations because we clear the up & down registers at each event. If a new event comes before the last is processed, up/down is cleared and the event is lost. To fix this for the down register, we create a life cycle for the event request that starts with the hot unplug request in piix4_device_hotplug() and ends when the device is ejected. This allows us to mask and clear individual bits, preserving them against races. For the up register, we have no clear end point for when the event is finished. We could modify the BIOS to acknowledge the bit and clear it, but this creates BIOS compatibiliy issues without offering a complete solution. Instead we note that gratuitous ACPI device checks are not harmful, which allows us to issue a device check for every slot. We know which slots are present and we know which slots are hotpluggable, so we can easily reduce this to a more manageable set for the guest. The other race Michael noted was that an unplug request followed by reset may also lose the eject notification, which may also result in the eject request being lost which a subsequent add or remove. Once we're in reset, the device is unused and we can flush the queue of device removals ourselves. Previously if a device_del was issued to a guest without ACPI PCI hotplug support, it was necessary to shutdown the guest to recover the device. With this, a guest reboot is sufficient. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> |
||
---|---|---|
.. | ||
9pfs | ||
ide | ||
kvm | ||
usb | ||
9p.h | ||
a9mpcore.c | ||
a15mpcore.c | ||
ac97.c | ||
acpi_piix4.c | ||
acpi.c | ||
acpi.h | ||
adb.c | ||
adb.h | ||
adlib.c | ||
ads7846.c | ||
alpha_dp264.c | ||
alpha_pci.c | ||
alpha_sys.h | ||
alpha_typhoon.c | ||
an5206.c | ||
apb_pci.c | ||
apb_pci.h | ||
apic_common.c | ||
apic_internal.h | ||
apic.c | ||
apic.h | ||
apm.c | ||
apm.h | ||
applesmc.c | ||
arm11mpcore.c | ||
arm_boot.c | ||
arm_gic.c | ||
arm_l2x0.c | ||
arm_mptimer.c | ||
arm_pic.c | ||
arm_sysctl.c | ||
arm_timer.c | ||
arm-misc.h | ||
armv7m_nvic.c | ||
armv7m.c | ||
audiodev.h | ||
axis_dev88.c | ||
baum.c | ||
baum.h | ||
bitbang_i2c.c | ||
bitbang_i2c.h | ||
blizzard_template.h | ||
blizzard.c | ||
boards.h | ||
bonito.c | ||
bt-hci-csr.c | ||
bt-hci.c | ||
bt-hid.c | ||
bt-l2cap.c | ||
bt-sdp.c | ||
bt.c | ||
bt.h | ||
cadence_gem.c | ||
cadence_ttc.c | ||
cadence_uart.c | ||
cbus.c | ||
ccid-card-emulated.c | ||
ccid-card-passthru.c | ||
ccid.h | ||
cdrom.c | ||
cirrus_vga_rop2.h | ||
cirrus_vga_rop.h | ||
cirrus_vga_template.h | ||
cirrus_vga.c | ||
collie.c | ||
cris_pic_cpu.c | ||
cris-boot.c | ||
cris-boot.h | ||
cs4231.c | ||
cs4231a.c | ||
cuda.c | ||
debugcon.c | ||
dec_pci.c | ||
dec_pci.h | ||
device-hotplug.c | ||
devices.h | ||
dma.c | ||
dp8393x.c | ||
ds1225y.c | ||
ds1338.c | ||
dummy_m68k.c | ||
e1000_hw.h | ||
e1000.c | ||
ecc.c | ||
eccmemctl.c | ||
eepro100.c | ||
eeprom93xx.c | ||
eeprom93xx.h | ||
elf_ops.h | ||
empty_slot.c | ||
empty_slot.h | ||
es1370.c | ||
escc.c | ||
escc.h | ||
esp.c | ||
esp.h | ||
etraxfs_dma.c | ||
etraxfs_dma.h | ||
etraxfs_eth.c | ||
etraxfs_pic.c | ||
etraxfs_ser.c | ||
etraxfs_timer.c | ||
etraxfs.h | ||
exynos4_boards.c | ||
exynos4210_combiner.c | ||
exynos4210_fimd.c | ||
exynos4210_gic.c | ||
exynos4210_mct.c | ||
exynos4210_pmu.c | ||
exynos4210_pwm.c | ||
exynos4210_uart.c | ||
exynos4210.c | ||
exynos4210.h | ||
fdc.c | ||
fdc.h | ||
firmware_abi.h | ||
flash.h | ||
fmopl.c | ||
fmopl.h | ||
framebuffer.c | ||
framebuffer.h | ||
fw_cfg.c | ||
fw_cfg.h | ||
g364fb.c | ||
grackle_pci.c | ||
grlib_apbuart.c | ||
grlib_gptimer.c | ||
grlib_irqmp.c | ||
grlib.h | ||
gt64xxx.c | ||
gumstix.c | ||
gus.c | ||
gusemu_hal.c | ||
gusemu_mixer.c | ||
gusemu.h | ||
gustate.h | ||
hda-audio.c | ||
heathrow_pic.c | ||
hid.c | ||
hid.h | ||
highbank.c | ||
hpet_emul.h | ||
hpet.c | ||
hw.h | ||
i2c.c | ||
i2c.h | ||
i8254_common.c | ||
i8254_internal.h | ||
i8254.c | ||
i8254.h | ||
i8259_common.c | ||
i8259_internal.h | ||
i8259.c | ||
i82374.c | ||
i82378.c | ||
ide.h | ||
integratorcp.c | ||
intel-hda-defs.h | ||
intel-hda.c | ||
intel-hda.h | ||
ioapic_common.c | ||
ioapic_internal.h | ||
ioapic.c | ||
ioapic.h | ||
ioh3420.c | ||
ioh3420.h | ||
irq.c | ||
irq.h | ||
isa_mmio.c | ||
isa-bus.c | ||
isa.h | ||
ivshmem.c | ||
jazz_led.c | ||
kvmvapic.c | ||
lan9118.c | ||
lance.c | ||
leon3.c | ||
lm32_boards.c | ||
lm32_hwsetup.h | ||
lm32_juart.c | ||
lm32_juart.h | ||
lm32_pic.c | ||
lm32_pic.h | ||
lm32_sys.c | ||
lm32_timer.c | ||
lm32_uart.c | ||
lm32.h | ||
lm832x.c | ||
lm4549.c | ||
lm4549.h | ||
loader.c | ||
loader.h | ||
lsi53c895a.c | ||
m48t59.c | ||
mac_dbdma.c | ||
mac_dbdma.h | ||
mac_nvram.c | ||
macio.c | ||
mainstone.c | ||
marvell_88w8618_audio.c | ||
max111x.c | ||
max7310.c | ||
mc146818rtc_regs.h | ||
mc146818rtc.c | ||
mc146818rtc.h | ||
mcf5206.c | ||
mcf5208.c | ||
mcf_fec.c | ||
mcf_intc.c | ||
mcf_uart.c | ||
mcf.h | ||
microblaze_boot.c | ||
microblaze_boot.h | ||
microblaze_pic_cpu.c | ||
microblaze_pic_cpu.h | ||
milkymist-ac97.c | ||
milkymist-hpdmc.c | ||
milkymist-hw.h | ||
milkymist-memcard.c | ||
milkymist-minimac2.c | ||
milkymist-pfpu.c | ||
milkymist-softusb.c | ||
milkymist-sysctl.c | ||
milkymist-tmu2.c | ||
milkymist-uart.c | ||
milkymist-vgafb_template.h | ||
milkymist-vgafb.c | ||
milkymist.c | ||
mips_addr.c | ||
mips_cpudevs.h | ||
mips_fulong2e.c | ||
mips_int.c | ||
mips_jazz.c | ||
mips_malta.c | ||
mips_mipssim.c | ||
mips_r4k.c | ||
mips_timer.c | ||
mips-bios.h | ||
mips.h | ||
mipsnet.c | ||
mpc8544_guts.c | ||
msi.c | ||
msi.h | ||
msix.c | ||
msix.h | ||
msmouse.c | ||
msmouse.h | ||
mst_fpga.c | ||
multiboot.c | ||
multiboot.h | ||
musicpal.c | ||
nand.c | ||
ne2000-isa.c | ||
ne2000.c | ||
ne2000.h | ||
nseries.c | ||
nvram.h | ||
omap1.c | ||
omap2.c | ||
omap_clk.c | ||
omap_dma.c | ||
omap_dss.c | ||
omap_gpio.c | ||
omap_gpmc.c | ||
omap_gptimer.c | ||
omap_i2c.c | ||
omap_intc.c | ||
omap_l4.c | ||
omap_lcd_template.h | ||
omap_lcdc.c | ||
omap_mmc.c | ||
omap_sdrc.c | ||
omap_spi.c | ||
omap_sx1.c | ||
omap_synctimer.c | ||
omap_tap.c | ||
omap_uart.c | ||
omap.h | ||
onenand.c | ||
opencores_eth.c | ||
openpic.c | ||
openpic.h | ||
palm.c | ||
parallel.c | ||
pc_piix.c | ||
pc_sysfw.c | ||
pc.c | ||
pc.h | ||
pci_bridge_dev.c | ||
pci_bridge.c | ||
pci_bridge.h | ||
pci_host.c | ||
pci_host.h | ||
pci_ids.h | ||
pci_internals.h | ||
pci_regs.h | ||
pci-hotplug.c | ||
pci-stub.c | ||
pci.c | ||
pci.h | ||
pcie_aer.c | ||
pcie_aer.h | ||
pcie_host.c | ||
pcie_host.h | ||
pcie_port.c | ||
pcie_port.h | ||
pcie_regs.h | ||
pcie.c | ||
pcie.h | ||
pckbd.c | ||
pcmcia.h | ||
pcnet-pci.c | ||
pcnet.c | ||
pcnet.h | ||
pcspk.c | ||
pcspk.h | ||
petalogix_ml605_mmu.c | ||
petalogix_s3adsp1800_mmu.c | ||
pflash_cfi01.c | ||
pflash_cfi02.c | ||
piix4.c | ||
piix_pci.c | ||
pixel_ops.h | ||
pl011.c | ||
pl022.c | ||
pl031.c | ||
pl041.c | ||
pl041.h | ||
pl041.hx | ||
pl050.c | ||
pl061.c | ||
pl080.c | ||
pl110_template.h | ||
pl110.c | ||
pl181.c | ||
pl190.c | ||
pm_smbus.c | ||
pm_smbus.h | ||
ppc4xx_devs.c | ||
ppc4xx_pci.c | ||
ppc4xx.h | ||
ppc405_boards.c | ||
ppc405_uc.c | ||
ppc405.h | ||
ppc440_bamboo.c | ||
ppc_booke.c | ||
ppc_mac.h | ||
ppc_newworld.c | ||
ppc_oldworld.c | ||
ppc_prep.c | ||
ppc-viosrp.h | ||
ppc.c | ||
ppc.h | ||
ppce500_mpc8544ds.c | ||
ppce500_pci.c | ||
ppce500_spin.c | ||
prep_pci.c | ||
primecell.h | ||
ps2.c | ||
ps2.h | ||
ptimer.c | ||
ptimer.h | ||
pxa2xx_dma.c | ||
pxa2xx_gpio.c | ||
pxa2xx_keypad.c | ||
pxa2xx_lcd.c | ||
pxa2xx_mmci.c | ||
pxa2xx_pcmcia.c | ||
pxa2xx_pic.c | ||
pxa2xx_template.h | ||
pxa2xx_timer.c | ||
pxa2xx.c | ||
pxa.h | ||
qdev-addr.c | ||
qdev-addr.h | ||
qdev-monitor.c | ||
qdev-properties.c | ||
qdev.c | ||
qdev.h | ||
qxl-logger.c | ||
qxl-render.c | ||
qxl.c | ||
qxl.h | ||
r2d.c | ||
rc4030.c | ||
realview_gic.c | ||
realview.c | ||
rtl8139.c | ||
s390-virtio-bus.c | ||
s390-virtio-bus.h | ||
s390-virtio.c | ||
sb16.c | ||
sbi.c | ||
scsi-bus.c | ||
scsi-defs.h | ||
scsi-disk.c | ||
scsi-generic.c | ||
scsi.h | ||
sd.c | ||
sd.h | ||
serial.c | ||
sga.c | ||
sh7750_regnames.c | ||
sh7750_regnames.h | ||
sh7750_regs.h | ||
sh7750.c | ||
sh_intc.c | ||
sh_intc.h | ||
sh_pci.c | ||
sh_serial.c | ||
sh_timer.c | ||
sh.h | ||
sharpsl.h | ||
shix.c | ||
shpc.c | ||
shpc.h | ||
slavio_intctl.c | ||
slavio_misc.c | ||
slavio_timer.c | ||
slotid_cap.c | ||
slotid_cap.h | ||
sm501_template.h | ||
sm501.c | ||
smbios.c | ||
smbios.h | ||
smbus_eeprom.c | ||
smbus.c | ||
smbus.h | ||
smc91c111.c | ||
soc_dma.c | ||
soc_dma.h | ||
spapr_hcall.c | ||
spapr_llan.c | ||
spapr_pci.c | ||
spapr_pci.h | ||
spapr_rtas.c | ||
spapr_vio.c | ||
spapr_vio.h | ||
spapr_vscsi.c | ||
spapr_vty.c | ||
spapr.c | ||
spapr.h | ||
sparc32_dma.c | ||
sparc32_dma.h | ||
spitz.c | ||
srp.h | ||
ssd0303.c | ||
ssd0323.c | ||
ssi-sd.c | ||
ssi.c | ||
ssi.h | ||
stellaris_enet.c | ||
stellaris_input.c | ||
stellaris.c | ||
strongarm.c | ||
strongarm.h | ||
sun4c_intctl.c | ||
sun4m_iommu.c | ||
sun4m.c | ||
sun4m.h | ||
sun4u.c | ||
sysbus.c | ||
sysbus.h | ||
tc6393xb_template.h | ||
tc6393xb.c | ||
tc58128.c | ||
tcx.c | ||
tmp105.c | ||
tosa.c | ||
tsc210x.c | ||
tsc2005.c | ||
tusb6010.c | ||
twl92230.c | ||
unin_pci.c | ||
usb.h | ||
versatile_pci.c | ||
versatilepb.c | ||
vexpress.c | ||
vga_int.h | ||
vga_template.h | ||
vga-isa-mm.c | ||
vga-isa.c | ||
vga-pci.c | ||
vga.c | ||
vga.h | ||
vhost_net.c | ||
vhost_net.h | ||
vhost.c | ||
vhost.h | ||
virtex_ml507.c | ||
virtio-balloon.c | ||
virtio-balloon.h | ||
virtio-blk.c | ||
virtio-blk.h | ||
virtio-console.c | ||
virtio-net.c | ||
virtio-net.h | ||
virtio-pci.c | ||
virtio-pci.h | ||
virtio-scsi.c | ||
virtio-scsi.h | ||
virtio-serial-bus.c | ||
virtio-serial.h | ||
virtio.c | ||
virtio.h | ||
vmmouse.c | ||
vmport.c | ||
vmware_vga.c | ||
vmware_vga.h | ||
vt82c686.c | ||
vt82c686.h | ||
watchdog.c | ||
watchdog.h | ||
wdt_i6300esb.c | ||
wdt_ib700.c | ||
wm8750.c | ||
xen_backend.c | ||
xen_backend.h | ||
xen_blkif.h | ||
xen_common.h | ||
xen_console.c | ||
xen_devconfig.c | ||
xen_disk.c | ||
xen_domainbuild.c | ||
xen_domainbuild.h | ||
xen_machine_pv.c | ||
xen_nic.c | ||
xen_platform.c | ||
xen.h | ||
xenfb.c | ||
xgmac.c | ||
xics.c | ||
xics.h | ||
xilinx_axidma.c | ||
xilinx_axidma.h | ||
xilinx_axienet.c | ||
xilinx_ethlite.c | ||
xilinx_intc.c | ||
xilinx_timer.c | ||
xilinx_uartlite.c | ||
xilinx_zynq.c | ||
xilinx.h | ||
xio3130_downstream.c | ||
xio3130_downstream.h | ||
xio3130_upstream.c | ||
xio3130_upstream.h | ||
xtensa_bootparam.h | ||
xtensa_lx60.c | ||
xtensa_pic.c | ||
xtensa_sim.c | ||
z2.c | ||
zaurus.c | ||
zynq_slcr.c |