From dc928109973336fd4d572d460cf3964d56aa087f Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Thu, 24 Mar 2016 13:06:16 -0600 Subject: vfio/pci: Add test for BAR restore If a device is reset without the memory or i/o bits enabled in the command register we may not detect it, potentially leaving the device without valid BAR programming. Add an additional test to check the BARs on each write to the command register. Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci_config.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers/vfio') diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index c9bb2290d39d..b31107803362 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -522,6 +522,23 @@ static int vfio_basic_config_read(struct vfio_pci_device *vdev, int pos, return count; } +/* Test whether BARs match the value we think they should contain */ +static bool vfio_need_bar_restore(struct vfio_pci_device *vdev) +{ + int i = 0, pos = PCI_BASE_ADDRESS_0, ret; + u32 bar; + + for (; pos <= PCI_BASE_ADDRESS_5; i++, pos += 4) { + if (vdev->rbar[i]) { + ret = pci_user_read_config_dword(vdev->pdev, pos, &bar); + if (ret || vdev->rbar[i] != bar) + return true; + } + } + + return false; +} + static int vfio_basic_config_write(struct vfio_pci_device *vdev, int pos, int count, struct perm_bits *perm, int offset, __le32 val) @@ -560,7 +577,8 @@ static int vfio_basic_config_write(struct vfio_pci_device *vdev, int pos, * SR-IOV devices will trigger this, but we catch them later */ if ((new_mem && virt_mem && !phys_mem) || - (new_io && virt_io && !phys_io)) + (new_io && virt_io && !phys_io) || + vfio_need_bar_restore(vdev)) vfio_bar_restore(vdev); } -- cgit v1.2.3