Add bit field 'skip_kexec_clear_master' to struct pci_dev{}. Skip clearing Bus Master Enable bit on PCI device during kexec reboot.
Devices preserved using live update might be performing a DMA transaction during kexec. Skipping clearing this bit allows a device to continue DMA while live update is in progress.
Signed-off-by: Vipin Sharma vipinsh@google.com --- drivers/pci/pci-driver.c | 6 ++++-- include/linux/pci.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 302d61783f6c..6aab358dc27a 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -513,11 +513,13 @@ static void pci_device_shutdown(struct device *dev) /* * If this is a kexec reboot, turn off Bus Master bit on the * device to tell it to not continue to do DMA. Don't touch - * devices in D3cold or unknown states. + * devices in D3cold or unknown states. Don't clear the bit + * if device has explicitly asked to skip it. * If it is not a kexec reboot, firmware will hit the PCI * devices with big hammer and stop their DMA any way. */ - if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot)) + if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot) && + !pci_dev->skip_kexec_clear_master) pci_clear_master(pci_dev); }
diff --git a/include/linux/pci.h b/include/linux/pci.h index d1fdf81fbe1e..8ce2d4528193 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -400,6 +400,8 @@ struct pci_dev { decoding during BAR sizing */ unsigned int wakeup_prepared:1; unsigned int skip_bus_pm:1; /* Internal: Skip bus-level PM */ + unsigned int skip_kexec_clear_master:1; /* Don't clear the Bus Master + Enable bit on kexec reboot */ unsigned int ignore_hotplug:1; /* Ignore hotplug events */ unsigned int hotplug_user_indicators:1; /* SlotCtl indicators controlled exclusively by