Message ID | 20220606203325.110625-18-mjrosato@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: s390: enable zPCI for interpretive execution | expand |
On 6/6/22 22:33, Matthew Rosato wrote: > During vfio-pci open_device, pass the KVM associated with the vfio group > (if one exists). This is needed in order to pass a special indicator > (GISA) to firmware to allow zPCI interpretation facilities to be used > for only the specific KVM associated with the vfio-pci device. During > vfio-pci close_device, unregister the notifier. > > Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com> Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
On Mon, 6 Jun 2022 16:33:21 -0400 Matthew Rosato <mjrosato@linux.ibm.com> wrote: > During vfio-pci open_device, pass the KVM associated with the vfio group > (if one exists). This is needed in order to pass a special indicator > (GISA) to firmware to allow zPCI interpretation facilities to be used > for only the specific KVM associated with the vfio-pci device. During > vfio-pci close_device, unregister the notifier. > > Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com> > --- > drivers/vfio/pci/vfio_pci_core.c | 10 +++++++++- > drivers/vfio/pci/vfio_pci_zdev.c | 24 ++++++++++++++++++++++++ > include/linux/vfio_pci_core.h | 10 ++++++++++ > 3 files changed, 43 insertions(+), 1 deletion(-) Acked-by: Alex Williamson <alex.williamson@redhat.com> > diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c > index a0d69ddaf90d..b1e5cfbadf38 100644 > --- a/drivers/vfio/pci/vfio_pci_core.c > +++ b/drivers/vfio/pci/vfio_pci_core.c > @@ -316,10 +316,14 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) > pci_write_config_word(pdev, PCI_COMMAND, cmd); > } > > - ret = vfio_config_init(vdev); > + ret = vfio_pci_zdev_open_device(vdev); > if (ret) > goto out_free_state; > > + ret = vfio_config_init(vdev); > + if (ret) > + goto out_free_zdev; > + > msix_pos = pdev->msix_cap; > if (msix_pos) { > u16 flags; > @@ -340,6 +344,8 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) > > return 0; > > +out_free_zdev: > + vfio_pci_zdev_close_device(vdev); > out_free_state: > kfree(vdev->pci_saved_state); > vdev->pci_saved_state = NULL; > @@ -418,6 +424,8 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev) > > vdev->needs_reset = true; > > + vfio_pci_zdev_close_device(vdev); > + > /* > * If we have saved state, restore it. If we can reset the device, > * even better. Resetting with current state seems better than > diff --git a/drivers/vfio/pci/vfio_pci_zdev.c b/drivers/vfio/pci/vfio_pci_zdev.c > index ea4c0d2b0663..686f2e75e392 100644 > --- a/drivers/vfio/pci/vfio_pci_zdev.c > +++ b/drivers/vfio/pci/vfio_pci_zdev.c > @@ -11,6 +11,7 @@ > #include <linux/uaccess.h> > #include <linux/vfio.h> > #include <linux/vfio_zdev.h> > +#include <linux/kvm_host.h> > #include <asm/pci_clp.h> > #include <asm/pci_io.h> > > @@ -136,3 +137,26 @@ int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, > > return ret; > } > + > +int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev) > +{ > + struct zpci_dev *zdev = to_zpci(vdev->pdev); > + > + if (!zdev) > + return -ENODEV; > + > + if (!vdev->vdev.kvm) > + return 0; > + > + return kvm_s390_pci_register_kvm(zdev, vdev->vdev.kvm); > +} > + > +void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev) > +{ > + struct zpci_dev *zdev = to_zpci(vdev->pdev); > + > + if (!zdev || !vdev->vdev.kvm) > + return; > + > + kvm_s390_pci_unregister_kvm(zdev); > +} > diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h > index 63af2897939c..d5d9e17f0156 100644 > --- a/include/linux/vfio_pci_core.h > +++ b/include/linux/vfio_pci_core.h > @@ -209,12 +209,22 @@ static inline int vfio_pci_igd_init(struct vfio_pci_core_device *vdev) > #ifdef CONFIG_VFIO_PCI_ZDEV_KVM > extern int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, > struct vfio_info_cap *caps); > +int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev); > +void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev); > #else > static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, > struct vfio_info_cap *caps) > { > return -ENODEV; > } > + > +static inline int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev) > +{ > + return 0; > +} > + > +static inline void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev) > +{} > #endif > > /* Will be exported for vfio pci drivers usage */
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index a0d69ddaf90d..b1e5cfbadf38 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -316,10 +316,14 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) pci_write_config_word(pdev, PCI_COMMAND, cmd); } - ret = vfio_config_init(vdev); + ret = vfio_pci_zdev_open_device(vdev); if (ret) goto out_free_state; + ret = vfio_config_init(vdev); + if (ret) + goto out_free_zdev; + msix_pos = pdev->msix_cap; if (msix_pos) { u16 flags; @@ -340,6 +344,8 @@ int vfio_pci_core_enable(struct vfio_pci_core_device *vdev) return 0; +out_free_zdev: + vfio_pci_zdev_close_device(vdev); out_free_state: kfree(vdev->pci_saved_state); vdev->pci_saved_state = NULL; @@ -418,6 +424,8 @@ void vfio_pci_core_disable(struct vfio_pci_core_device *vdev) vdev->needs_reset = true; + vfio_pci_zdev_close_device(vdev); + /* * If we have saved state, restore it. If we can reset the device, * even better. Resetting with current state seems better than diff --git a/drivers/vfio/pci/vfio_pci_zdev.c b/drivers/vfio/pci/vfio_pci_zdev.c index ea4c0d2b0663..686f2e75e392 100644 --- a/drivers/vfio/pci/vfio_pci_zdev.c +++ b/drivers/vfio/pci/vfio_pci_zdev.c @@ -11,6 +11,7 @@ #include <linux/uaccess.h> #include <linux/vfio.h> #include <linux/vfio_zdev.h> +#include <linux/kvm_host.h> #include <asm/pci_clp.h> #include <asm/pci_io.h> @@ -136,3 +137,26 @@ int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, return ret; } + +int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev) +{ + struct zpci_dev *zdev = to_zpci(vdev->pdev); + + if (!zdev) + return -ENODEV; + + if (!vdev->vdev.kvm) + return 0; + + return kvm_s390_pci_register_kvm(zdev, vdev->vdev.kvm); +} + +void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev) +{ + struct zpci_dev *zdev = to_zpci(vdev->pdev); + + if (!zdev || !vdev->vdev.kvm) + return; + + kvm_s390_pci_unregister_kvm(zdev); +} diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index 63af2897939c..d5d9e17f0156 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -209,12 +209,22 @@ static inline int vfio_pci_igd_init(struct vfio_pci_core_device *vdev) #ifdef CONFIG_VFIO_PCI_ZDEV_KVM extern int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, struct vfio_info_cap *caps); +int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev); +void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev); #else static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev, struct vfio_info_cap *caps) { return -ENODEV; } + +static inline int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev) +{ + return 0; +} + +static inline void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev) +{} #endif /* Will be exported for vfio pci drivers usage */
During vfio-pci open_device, pass the KVM associated with the vfio group (if one exists). This is needed in order to pass a special indicator (GISA) to firmware to allow zPCI interpretation facilities to be used for only the specific KVM associated with the vfio-pci device. During vfio-pci close_device, unregister the notifier. Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com> --- drivers/vfio/pci/vfio_pci_core.c | 10 +++++++++- drivers/vfio/pci/vfio_pci_zdev.c | 24 ++++++++++++++++++++++++ include/linux/vfio_pci_core.h | 10 ++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-)