diff options
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 29 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci_core.c | 39 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci_core.h | 9 |
3 files changed, 41 insertions, 36 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 4e31bd3001ad..2729b777a56d 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -82,9 +82,36 @@ static bool vfio_pci_is_denylisted(struct pci_dev *pdev) return true; } +static int vfio_pci_open_device(struct vfio_device *core_vdev) +{ + struct vfio_pci_core_device *vdev = + container_of(core_vdev, struct vfio_pci_core_device, vdev); + struct pci_dev *pdev = vdev->pdev; + int ret; + + ret = vfio_pci_core_enable(vdev); + if (ret) + return ret; + + if (vfio_pci_is_vga(pdev) && + pdev->vendor == PCI_VENDOR_ID_INTEL && + IS_ENABLED(CONFIG_VFIO_PCI_IGD)) { + ret = vfio_pci_igd_init(vdev); + if (ret && ret != -ENODEV) { + pci_warn(pdev, "Failed to setup Intel IGD regions\n"); + vfio_pci_core_disable(vdev); + return ret; + } + } + + vfio_pci_core_finish_enable(vdev); + + return 0; +} + static const struct vfio_device_ops vfio_pci_ops = { .name = "vfio-pci", - .open_device = vfio_pci_core_open_device, + .open_device = vfio_pci_open_device, .close_device = vfio_pci_core_close_device, .ioctl = vfio_pci_core_ioctl, .read = vfio_pci_core_read, diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index c0d71f72d4f1..3b3bf7445367 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -91,11 +91,6 @@ static unsigned int vfio_pci_set_vga_decode(void *opaque, bool single_vga) return decodes; } -static inline bool vfio_pci_is_vga(struct pci_dev *pdev) -{ - return (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; -} - static void vfio_pci_probe_mmaps(struct vfio_pci_core_device *vdev) { struct resource *res; @@ -166,7 +161,6 @@ no_mmap: struct vfio_pci_group_info; static bool vfio_pci_dev_set_try_reset(struct vfio_device_set *dev_set); -static void vfio_pci_disable(struct vfio_pci_core_device *vdev); static int vfio_pci_dev_set_hot_reset(struct vfio_device_set *dev_set, struct vfio_pci_group_info *groups); @@ -252,7 +246,7 @@ int vfio_pci_set_power_state(struct vfio_pci_core_device *vdev, pci_power_t stat return ret; } -static int vfio_pci_enable(struct vfio_pci_core_device *vdev) +int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) { struct pci_dev *pdev = vdev->pdev; int ret; @@ -321,26 +315,11 @@ static int vfio_pci_enable(struct vfio_pci_core_device *vdev) if (!vfio_vga_disabled() && vfio_pci_is_vga(pdev)) vdev->has_vga = true; - if (vfio_pci_is_vga(pdev) && - pdev->vendor == PCI_VENDOR_ID_INTEL && - IS_ENABLED(CONFIG_VFIO_PCI_IGD)) { - ret = vfio_pci_igd_init(vdev); - if (ret && ret != -ENODEV) { - pci_warn(pdev, "Failed to setup Intel IGD regions\n"); - goto disable_exit; - } - } - - vfio_pci_probe_mmaps(vdev); return 0; - -disable_exit: - vfio_pci_disable(vdev); - return ret; } -static void vfio_pci_disable(struct vfio_pci_core_device *vdev) +void vfio_pci_core_disable(struct vfio_pci_core_device *vdev) { struct pci_dev *pdev = vdev->pdev; struct vfio_pci_dummy_resource *dummy_res, *tmp; @@ -479,7 +458,7 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) vfio_pci_vf_token_user_add(vdev, -1); vfio_spapr_pci_eeh_release(vdev->pdev); - vfio_pci_disable(vdev); + vfio_pci_core_disable(vdev); mutex_lock(&vdev->igate); if (vdev->err_trigger) { @@ -493,19 +472,11 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) mutex_unlock(&vdev->igate); } -int vfio_pci_core_open_device(struct vfio_device *core_vdev) +void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev) { - struct vfio_pci_core_device *vdev = - container_of(core_vdev, struct vfio_pci_core_device, vdev); - int ret = 0; - - ret = vfio_pci_enable(vdev); - if (ret) - return ret; - + vfio_pci_probe_mmaps(vdev); vfio_spapr_pci_eeh_open(vdev->pdev); vfio_pci_vf_token_user_add(vdev, 1); - return 0; } static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_type) diff --git a/drivers/vfio/pci/vfio_pci_core.h b/drivers/vfio/pci/vfio_pci_core.h index 7dbdd4dda5c0..ffaf544f35db 100644 --- a/drivers/vfio/pci/vfio_pci_core.h +++ b/drivers/vfio/pci/vfio_pci_core.h @@ -210,7 +210,6 @@ static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, void vfio_pci_core_cleanup(void); int vfio_pci_core_init(void); void vfio_pci_core_close_device(struct vfio_device *core_vdev); -int vfio_pci_core_open_device(struct vfio_device *core_vdev); void vfio_pci_core_init_device(struct vfio_pci_core_device *vdev, struct pci_dev *pdev, const struct vfio_device_ops *vfio_pci_ops); @@ -228,5 +227,13 @@ ssize_t vfio_pci_core_write(struct vfio_device *core_vdev, const char __user *bu int vfio_pci_core_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma); void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count); int vfio_pci_core_match(struct vfio_device *core_vdev, char *buf); +int vfio_pci_core_enable(struct vfio_pci_core_device *vdev); +void vfio_pci_core_disable(struct vfio_pci_core_device *vdev); +void vfio_pci_core_finish_enable(struct vfio_pci_core_device *vdev); + +static inline bool vfio_pci_is_vga(struct pci_dev *pdev) +{ + return (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; +} #endif /* VFIO_PCI_CORE_H */ |