From e0235fd34ab2a715fe4704807c37206c5e98010a Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Wed, 5 Jun 2019 04:58:42 +0000 Subject: [PATCH] Only respond to the PCIe Attention Button if a device is already plugged in. Prior to this commit, if PCIEM_SLOT_STA_ABP and PCIEM_SLOT_STA_PDC are asserted simultaneously, FreeBSD sets a 5 second "hardware going away" timer and then processes the "presence detect" change. In the (physically challenging) case that someone presses the "attention button" and inserts a new PCIe device at exactly the same moment, this results in FreeBSD recognizing that the device is present, attaching it, and then detaching it 5 seconds later. On EC2 "bare metal" hardware this is the precise sequence of events which takes place when a new EBS volume is attached; virtual machines have no difficulty effecting physically implausible simultaneity. This patch changes the handling of PCIEM_SLOT_STA_ABP to only detach a device if the presence of a device was detected *before* the interrupt which reports the Attention Button push. Reported by: Matt Wilson Reviewed by: jhb MFC after: 1 week Sponsored by: https://www.patreon.com/cperciva Differential Revision: https://reviews.freebsd.org/D20499 --- sys/dev/pci/pci_pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index 2f71a122661..f3233584096 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -1170,9 +1170,11 @@ pcib_pcie_intr_hotplug(void *arg) { struct pcib_softc *sc; device_t dev; + uint16_t old_slot_sta; sc = arg; dev = sc->dev; + old_slot_sta = sc->pcie_slot_sta; sc->pcie_slot_sta = pcie_read_config(dev, PCIER_SLOT_STA, 2); /* Clear the events just reported. */ @@ -1188,7 +1190,8 @@ pcib_pcie_intr_hotplug(void *arg) "Attention Button Pressed: Detach Cancelled\n"); sc->flags &= ~PCIB_DETACH_PENDING; callout_stop(&sc->pcie_ab_timer); - } else { + } else if (old_slot_sta & PCIEM_SLOT_STA_PDS) { + /* Only initiate detach sequence if device present. */ device_printf(dev, "Attention Button Pressed: Detaching in 5 seconds\n"); sc->flags |= PCIB_DETACH_PENDING;