Skip to content

Commit

Permalink
pci/pcie: stop plug/unplug if the slot is locked
Browse files Browse the repository at this point in the history
We better stop right away. For now, errors would be partially ignored
(so the guest might get informed or the device might get unplugged),
although actual plug/unplug will be reported as failed to the user.

While at it, properly move the check to the pre_plug handler for the plug
case, as we can test the slot state before the device will be realized.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
davidhildenbrand authored and mstsirkin committed Jan 15, 2019
1 parent 89bd861 commit b973185
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
25 changes: 17 additions & 8 deletions hw/pci/pcie.c
Expand Up @@ -391,10 +391,10 @@ static void pcie_cap_slot_event(PCIDevice *dev, PCIExpressHotPlugEvent event)
}

static void pcie_cap_slot_plug_common(PCIDevice *hotplug_dev, DeviceState *dev,
uint8_t **exp_cap, Error **errp)
Error **errp)
{
*exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap;
uint16_t sltsta = pci_get_word(*exp_cap + PCI_EXP_SLTSTA);
uint8_t *exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap;
uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);

PCIE_DEV_PRINTF(PCI_DEVICE(dev), "hotplug state: 0x%x\n", sltsta);
if (sltsta & PCI_EXP_SLTSTA_EIS) {
Expand All @@ -405,14 +405,19 @@ static void pcie_cap_slot_plug_common(PCIDevice *hotplug_dev, DeviceState *dev,
}
}

void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, errp);
}

void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
uint8_t *exp_cap;
PCIDevice *hotplug_pdev = PCI_DEVICE(hotplug_dev);
uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap;
PCIDevice *pci_dev = PCI_DEVICE(dev);

pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);

/* Don't send event when device is enabled during qemu machine creation:
* it is present on boot, no hotplug event is necessary. We do send an
* event when the device is disabled later. */
Expand Down Expand Up @@ -458,11 +463,15 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque)
void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
uint8_t *exp_cap;
Error *local_err = NULL;
PCIDevice *pci_dev = PCI_DEVICE(dev);
PCIBus *bus = pci_get_bus(pci_dev);

pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}

/* In case user cancel the operation of multi-function hot-add,
* remove the function that is unexposed to guest individually,
Expand Down
1 change: 1 addition & 0 deletions hw/pci/pcie_port.c
Expand Up @@ -154,6 +154,7 @@ static void pcie_slot_class_init(ObjectClass *oc, void *data)
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);

dc->props = pcie_slot_props;
hc->pre_plug = pcie_cap_slot_pre_plug_cb;
hc->plug = pcie_cap_slot_plug_cb;
hc->unplug = pcie_cap_slot_unplug_cb;
hc->unplug_request = pcie_cap_slot_unplug_request_cb;
Expand Down
2 changes: 2 additions & 0 deletions include/hw/pci/pcie.h
Expand Up @@ -132,6 +132,8 @@ void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn);
void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num);
void pcie_ats_init(PCIDevice *dev, uint16_t offset);

void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Expand Down

0 comments on commit b973185

Please sign in to comment.