* [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE
2021-04-23 23:02 [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Jason Gunthorpe
@ 2021-04-23 23:02 ` Jason Gunthorpe
2021-04-24 0:08 ` Randy Dunlap
2021-04-23 23:03 ` [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev() Jason Gunthorpe
` (3 subsequent siblings)
4 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-23 23:02 UTC (permalink / raw)
To: David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Vasily Gorbik, Heiko Carstens,
intel-gfx, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Halil Pasic, Pierre Morel, Rodrigo Vivi
Cc: Raj, Ashok, Dan Williams, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta
For some reason the vfio_mdev shim mdev_driver has its own module and
kconfig. As the next patch requires access to it from mdev.ko merge the
two modules together and remove VFIO_MDEV_DEVICE.
A later patch deletes this driver entirely.
This also fixes a misuse of kconfig in the samples which prevented the
samples from being built in.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
Documentation/s390/vfio-ap.rst | 1 -
arch/s390/Kconfig | 2 +-
drivers/gpu/drm/i915/Kconfig | 2 +-
drivers/vfio/mdev/Kconfig | 7 -------
drivers/vfio/mdev/Makefile | 3 +--
drivers/vfio/mdev/mdev_core.c | 16 ++++++++++++++--
drivers/vfio/mdev/mdev_private.h | 2 ++
drivers/vfio/mdev/vfio_mdev.c | 24 +-----------------------
samples/Kconfig | 6 +++---
9 files changed, 23 insertions(+), 40 deletions(-)
diff --git a/Documentation/s390/vfio-ap.rst b/Documentation/s390/vfio-ap.rst
index e15436599086b7..f57ae621f33e89 100644
--- a/Documentation/s390/vfio-ap.rst
+++ b/Documentation/s390/vfio-ap.rst
@@ -514,7 +514,6 @@ These are the steps:
* S390_AP_IOMMU
* VFIO
* VFIO_MDEV
- * VFIO_MDEV_DEVICE
* KVM
If using make menuconfig select the following to build the vfio_ap module::
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index c1ff874e6c2e63..dc7928e37fa409 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -773,7 +773,7 @@ config VFIO_CCW
config VFIO_AP
def_tristate n
prompt "VFIO support for AP devices"
- depends on S390_AP_IOMMU && VFIO_MDEV_DEVICE && KVM
+ depends on S390_AP_IOMMU && VFIO_MDEV && KVM
depends on ZCRYPT
help
This driver grants access to Adjunct Processor (AP) devices
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 483e9ff8ca1d23..388bc41aa1a75b 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -125,7 +125,7 @@ config DRM_I915_GVT_KVMGT
tristate "Enable KVM/VFIO support for Intel GVT-g"
depends on DRM_I915_GVT
depends on KVM
- depends on VFIO_MDEV && VFIO_MDEV_DEVICE
+ depends on VFIO_MDEV
default n
help
Choose this option if you want to enable KVMGT support for
diff --git a/drivers/vfio/mdev/Kconfig b/drivers/vfio/mdev/Kconfig
index 5da27f2100f9bd..763c877a1318bc 100644
--- a/drivers/vfio/mdev/Kconfig
+++ b/drivers/vfio/mdev/Kconfig
@@ -9,10 +9,3 @@ config VFIO_MDEV
See Documentation/driver-api/vfio-mediated-device.rst for more details.
If you don't know what do here, say N.
-
-config VFIO_MDEV_DEVICE
- tristate "VFIO driver for Mediated devices"
- depends on VFIO && VFIO_MDEV
- default n
- help
- VFIO based driver for Mediated devices.
diff --git a/drivers/vfio/mdev/Makefile b/drivers/vfio/mdev/Makefile
index 101516fdf3753e..ff9ecd80212503 100644
--- a/drivers/vfio/mdev/Makefile
+++ b/drivers/vfio/mdev/Makefile
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o
+mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o vfio_mdev.o
obj-$(CONFIG_VFIO_MDEV) += mdev.o
-obj-$(CONFIG_VFIO_MDEV_DEVICE) += vfio_mdev.o
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 2a85d6fcb7ddd0..ff8c1a84516698 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -360,11 +360,24 @@ int mdev_device_remove(struct mdev_device *mdev)
static int __init mdev_init(void)
{
- return mdev_bus_register();
+ int rc;
+
+ rc = mdev_bus_register();
+ if (rc)
+ return rc;
+ rc = mdev_register_driver(&vfio_mdev_driver);
+ if (rc)
+ goto err_bus;
+ return 0;
+err_bus:
+ mdev_bus_unregister();
+ return rc;
}
static void __exit mdev_exit(void)
{
+ mdev_unregister_driver(&vfio_mdev_driver);
+
if (mdev_bus_compat_class)
class_compat_unregister(mdev_bus_compat_class);
@@ -378,4 +391,3 @@ MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_SOFTDEP("post: vfio_mdev");
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index a656cfe0346c33..5461b67582289f 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -37,6 +37,8 @@ struct mdev_type {
#define to_mdev_type(_kobj) \
container_of(_kobj, struct mdev_type, kobj)
+extern struct mdev_driver vfio_mdev_driver;
+
int parent_create_sysfs_files(struct mdev_parent *parent);
void parent_remove_sysfs_files(struct mdev_parent *parent);
diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
index 922729071c5a8e..d5b4eede47c1a5 100644
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ b/drivers/vfio/mdev/vfio_mdev.c
@@ -17,10 +17,6 @@
#include "mdev_private.h"
-#define DRIVER_VERSION "0.1"
-#define DRIVER_AUTHOR "NVIDIA Corporation"
-#define DRIVER_DESC "VFIO based driver for Mediated device"
-
static int vfio_mdev_open(struct vfio_device *core_vdev)
{
struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
@@ -151,7 +147,7 @@ static void vfio_mdev_remove(struct mdev_device *mdev)
kfree(vdev);
}
-static struct mdev_driver vfio_mdev_driver = {
+struct mdev_driver vfio_mdev_driver = {
.driver = {
.name = "vfio_mdev",
.owner = THIS_MODULE,
@@ -160,21 +156,3 @@ static struct mdev_driver vfio_mdev_driver = {
.probe = vfio_mdev_probe,
.remove = vfio_mdev_remove,
};
-
-static int __init vfio_mdev_init(void)
-{
- return mdev_register_driver(&vfio_mdev_driver);
-}
-
-static void __exit vfio_mdev_exit(void)
-{
- mdev_unregister_driver(&vfio_mdev_driver);
-}
-
-module_init(vfio_mdev_init)
-module_exit(vfio_mdev_exit)
-
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/samples/Kconfig b/samples/Kconfig
index e76cdfc50e257d..2a4876e2ce0d03 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -147,14 +147,14 @@ config SAMPLE_UHID
config SAMPLE_VFIO_MDEV_MTTY
tristate "Build VFIO mtty example mediated device sample code -- loadable modules only"
- depends on VFIO_MDEV_DEVICE && m
+ depends on VFIO_MDEV
help
Build a virtual tty sample driver for use as a VFIO
mediated device
config SAMPLE_VFIO_MDEV_MDPY
tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
- depends on VFIO_MDEV_DEVICE && m
+ depends on VFIO_MDEV
help
Build a virtual display sample driver for use as a VFIO
mediated device. It is a simple framebuffer and supports
@@ -171,7 +171,7 @@ config SAMPLE_VFIO_MDEV_MDPY_FB
config SAMPLE_VFIO_MDEV_MBOCHS
tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
- depends on VFIO_MDEV_DEVICE && m
+ depends on VFIO_MDEV
select DMA_SHARED_BUFFER
help
Build a virtual display sample driver for use as a VFIO
--
2.31.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE
2021-04-23 23:02 ` [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE Jason Gunthorpe
@ 2021-04-24 0:08 ` Randy Dunlap
2021-04-26 18:26 ` Jason Gunthorpe
0 siblings, 1 reply; 27+ messages in thread
From: Randy Dunlap @ 2021-04-24 0:08 UTC (permalink / raw)
To: Jason Gunthorpe, David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Vasily Gorbik, Heiko Carstens,
intel-gfx, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Halil Pasic, Pierre Morel, Rodrigo Vivi
Cc: Raj, Ashok, Dan Williams, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta
On 4/23/21 4:02 PM, Jason Gunthorpe wrote:
> @@ -171,7 +171,7 @@ config SAMPLE_VFIO_MDEV_MDPY_FB
>
> config SAMPLE_VFIO_MDEV_MBOCHS
> tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
You can drop the ending of the prompt string.
> - depends on VFIO_MDEV_DEVICE && m
> + depends on VFIO_MDEV
> select DMA_SHARED_BUFFER
> help
> Build a virtual display sample driver for use as a VFIO
--
~Randy
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE
2021-04-24 0:08 ` Randy Dunlap
@ 2021-04-26 18:26 ` Jason Gunthorpe
2021-04-26 19:11 ` Randy Dunlap
0 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-26 18:26 UTC (permalink / raw)
To: Randy Dunlap
Cc: David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Vasily Gorbik, Heiko Carstens,
intel-gfx, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Halil Pasic, Pierre Morel, Rodrigo Vivi,
Raj, Ashok, Dan Williams, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta
On Fri, Apr 23, 2021 at 05:08:10PM -0700, Randy Dunlap wrote:
> On 4/23/21 4:02 PM, Jason Gunthorpe wrote:
> > @@ -171,7 +171,7 @@ config SAMPLE_VFIO_MDEV_MDPY_FB
> >
> > config SAMPLE_VFIO_MDEV_MBOCHS
> > tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
>
> You can drop the ending of the prompt string.
Hum, I see this whole sample kconfig file is filled with this '&& m'
pattern, I wonder if there is a reason?
I think I will put the '&& m' back, I thought it was some kconfig
misunderstanding as it is very strange to see a naked '&& M'.
Thanks
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE
2021-04-26 18:26 ` Jason Gunthorpe
@ 2021-04-26 19:11 ` Randy Dunlap
0 siblings, 0 replies; 27+ messages in thread
From: Randy Dunlap @ 2021-04-26 19:11 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Vasily Gorbik, Heiko Carstens,
intel-gfx, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Halil Pasic, Pierre Morel, Rodrigo Vivi,
Raj, Ashok, Dan Williams, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta
On 4/26/21 11:26 AM, Jason Gunthorpe wrote:
> On Fri, Apr 23, 2021 at 05:08:10PM -0700, Randy Dunlap wrote:
>> On 4/23/21 4:02 PM, Jason Gunthorpe wrote:
>>> @@ -171,7 +171,7 @@ config SAMPLE_VFIO_MDEV_MDPY_FB
>>>
>>> config SAMPLE_VFIO_MDEV_MBOCHS
>>> tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
>>
>> You can drop the ending of the prompt string.
>
> Hum, I see this whole sample kconfig file is filled with this '&& m'
> pattern, I wonder if there is a reason?
>
> I think I will put the '&& m' back, I thought it was some kconfig
> misunderstanding as it is very strange to see a naked '&& M'.
It just limits those kconfig items to being =m or not set,
i.e., even though they are tristate, setting to =y is not
allowed. I guess the thinking is that samples don't need to
reside in system memory for very long. However, if you want
this one to be capable of =y, like your patch, you can still
remove the end of the prompt string.
--
~Randy
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-04-23 23:02 [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Jason Gunthorpe
2021-04-23 23:02 ` [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE Jason Gunthorpe
@ 2021-04-23 23:03 ` Jason Gunthorpe
2021-04-26 14:07 ` Christoph Hellwig
2021-04-26 17:48 ` Cornelia Huck
2021-04-23 23:03 ` [PATCH 07/12] vfio/ccw: " Jason Gunthorpe
` (2 subsequent siblings)
4 siblings, 2 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-23 23:03 UTC (permalink / raw)
To: Tony Krowiak, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel
Cc: Raj, Ashok, Dan Williams, Daniel Vetter, Christoph Hellwig,
Leon Romanovsky, Max Gurtovoy, Tarun Gupta
This is straightforward conversion, the ap_matrix_mdev is actually serving
as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
simple container_of().
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/s390/crypto/vfio_ap_ops.c | 137 ++++++++++++++++----------
drivers/s390/crypto/vfio_ap_private.h | 2 +
2 files changed, 89 insertions(+), 50 deletions(-)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 0ce00c9311d378..79872c857dd522 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -24,8 +24,9 @@
#define VFIO_AP_MDEV_TYPE_HWVIRT "passthrough"
#define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device"
-static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev);
+static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev);
static struct vfio_ap_queue *vfio_ap_find_queue(int apqn);
+static const struct vfio_device_ops vfio_ap_matrix_dev_ops;
static int match_apqn(struct device *dev, const void *data)
{
@@ -322,48 +323,63 @@ static void vfio_ap_matrix_init(struct ap_config_info *info,
matrix->adm_max = info->apxa ? info->Nd : 15;
}
-static int vfio_ap_mdev_create(struct mdev_device *mdev)
+static int vfio_ap_mdev_probe(struct mdev_device *mdev)
{
struct ap_matrix_mdev *matrix_mdev;
+ int ret;
if ((atomic_dec_if_positive(&matrix_dev->available_instances) < 0))
return -EPERM;
matrix_mdev = kzalloc(sizeof(*matrix_mdev), GFP_KERNEL);
if (!matrix_mdev) {
- atomic_inc(&matrix_dev->available_instances);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_atomic;
}
+ vfio_init_group_dev(&matrix_mdev->vdev, &mdev->dev,
+ &vfio_ap_matrix_dev_ops);
matrix_mdev->mdev = mdev;
vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->matrix);
- mdev_set_drvdata(mdev, matrix_mdev);
matrix_mdev->pqap_hook.hook = handle_pqap;
matrix_mdev->pqap_hook.owner = THIS_MODULE;
mutex_lock(&matrix_dev->lock);
list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
mutex_unlock(&matrix_dev->lock);
+ ret = vfio_register_group_dev(&matrix_mdev->vdev);
+ if (ret)
+ goto err_list;
+ dev_set_drvdata(&mdev->dev, matrix_mdev);
return 0;
+
+err_list:
+ mutex_lock(&matrix_dev->lock);
+ list_del(&matrix_mdev->node);
+ mutex_unlock(&matrix_dev->lock);
+ kfree(matrix_mdev);
+err_atomic:
+ atomic_inc(&matrix_dev->available_instances);
+ return ret;
}
-static int vfio_ap_mdev_remove(struct mdev_device *mdev)
+static void vfio_ap_mdev_remove(struct mdev_device *mdev)
{
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
- if (matrix_mdev->kvm)
- return -EBUSY;
+ /* FIXME: Remove isn't allowed to fail */
+ if (WARN_ON(matrix_mdev->kvm))
+ return;
+
+ vfio_unregister_group_dev(&matrix_mdev->vdev);
mutex_lock(&matrix_dev->lock);
- vfio_ap_mdev_reset_queues(mdev);
+ vfio_ap_mdev_reset_queues(matrix_mdev);
list_del(&matrix_mdev->node);
mutex_unlock(&matrix_dev->lock);
kfree(matrix_mdev);
- mdev_set_drvdata(mdev, NULL);
atomic_inc(&matrix_dev->available_instances);
-
- return 0;
}
static ssize_t name_show(struct mdev_type *mtype,
@@ -605,8 +621,7 @@ static ssize_t assign_adapter_store(struct device *dev,
{
int ret;
unsigned long apid;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
/* If the guest is running, disallow assignment of adapter */
if (matrix_mdev->kvm)
@@ -671,8 +686,7 @@ static ssize_t unassign_adapter_store(struct device *dev,
{
int ret;
unsigned long apid;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
/* If the guest is running, disallow un-assignment of adapter */
if (matrix_mdev->kvm)
@@ -751,8 +765,7 @@ static ssize_t assign_domain_store(struct device *dev,
{
int ret;
unsigned long apqi;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
unsigned long max_apqi = matrix_mdev->matrix.aqm_max;
/* If the guest is running, disallow assignment of domain */
@@ -813,8 +826,7 @@ static ssize_t unassign_domain_store(struct device *dev,
{
int ret;
unsigned long apqi;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
/* If the guest is running, disallow un-assignment of domain */
if (matrix_mdev->kvm)
@@ -857,8 +869,7 @@ static ssize_t assign_control_domain_store(struct device *dev,
{
int ret;
unsigned long id;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
/* If the guest is running, disallow assignment of control domain */
if (matrix_mdev->kvm)
@@ -906,8 +917,7 @@ static ssize_t unassign_control_domain_store(struct device *dev,
{
int ret;
unsigned long domid;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
unsigned long max_domid = matrix_mdev->matrix.adm_max;
/* If the guest is running, disallow un-assignment of control domain */
@@ -936,8 +946,7 @@ static ssize_t control_domains_show(struct device *dev,
int nchars = 0;
int n;
char *bufpos = buf;
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
unsigned long max_domid = matrix_mdev->matrix.adm_max;
mutex_lock(&matrix_dev->lock);
@@ -955,8 +964,7 @@ static DEVICE_ATTR_RO(control_domains);
static ssize_t matrix_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct mdev_device *mdev = mdev_from_dev(dev);
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
char *bufpos = buf;
unsigned long apid;
unsigned long apqi;
@@ -1085,7 +1093,7 @@ static void vfio_ap_mdev_unset_kvm(struct ap_matrix_mdev *matrix_mdev)
{
kvm_arch_crypto_clear_masks(matrix_mdev->kvm);
matrix_mdev->kvm->arch.crypto.pqap_hook = NULL;
- vfio_ap_mdev_reset_queues(matrix_mdev->mdev);
+ vfio_ap_mdev_reset_queues(matrix_mdev);
kvm_put_kvm(matrix_mdev->kvm);
matrix_mdev->kvm = NULL;
}
@@ -1195,13 +1203,12 @@ int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q,
return ret;
}
-static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev)
+static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev)
{
int ret;
int rc = 0;
unsigned long apid, apqi;
struct vfio_ap_queue *q;
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
for_each_set_bit_inv(apid, matrix_mdev->matrix.apm,
matrix_mdev->matrix.apm_max + 1) {
@@ -1222,9 +1229,10 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev)
return rc;
}
-static int vfio_ap_mdev_open(struct mdev_device *mdev)
+static int vfio_ap_mdev_open(struct vfio_device *vdev)
{
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev =
+ container_of(vdev, struct ap_matrix_mdev, vdev);
unsigned long events;
int ret;
@@ -1235,7 +1243,7 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev)
matrix_mdev->group_notifier.notifier_call = vfio_ap_mdev_group_notifier;
events = VFIO_GROUP_NOTIFY_SET_KVM;
- ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
+ ret = vfio_register_notifier(vdev->dev, VFIO_GROUP_NOTIFY,
&events, &matrix_mdev->group_notifier);
if (ret) {
module_put(THIS_MODULE);
@@ -1244,29 +1252,30 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev)
matrix_mdev->iommu_notifier.notifier_call = vfio_ap_mdev_iommu_notifier;
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
- ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+ ret = vfio_register_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
&events, &matrix_mdev->iommu_notifier);
if (!ret)
return ret;
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
+ vfio_unregister_notifier(vdev->dev, VFIO_GROUP_NOTIFY,
&matrix_mdev->group_notifier);
module_put(THIS_MODULE);
return ret;
}
-static void vfio_ap_mdev_release(struct mdev_device *mdev)
+static void vfio_ap_mdev_release(struct vfio_device *vdev)
{
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
+ struct ap_matrix_mdev *matrix_mdev =
+ container_of(vdev, struct ap_matrix_mdev, vdev);
mutex_lock(&matrix_dev->lock);
if (matrix_mdev->kvm)
vfio_ap_mdev_unset_kvm(matrix_mdev);
mutex_unlock(&matrix_dev->lock);
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+ vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
&matrix_mdev->iommu_notifier);
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
+ vfio_unregister_notifier(vdev->dev, VFIO_GROUP_NOTIFY,
&matrix_mdev->group_notifier);
module_put(THIS_MODULE);
}
@@ -1291,9 +1300,11 @@ static int vfio_ap_mdev_get_device_info(unsigned long arg)
return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0;
}
-static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
+static ssize_t vfio_ap_mdev_ioctl(struct vfio_device *vdev,
unsigned int cmd, unsigned long arg)
{
+ struct ap_matrix_mdev *matrix_mdev =
+ container_of(vdev, struct ap_matrix_mdev, vdev);
int ret;
mutex_lock(&matrix_dev->lock);
@@ -1302,7 +1313,7 @@ static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
ret = vfio_ap_mdev_get_device_info(arg);
break;
case VFIO_DEVICE_RESET:
- ret = vfio_ap_mdev_reset_queues(mdev);
+ ret = vfio_ap_mdev_reset_queues(matrix_mdev);
break;
default:
ret = -EOPNOTSUPP;
@@ -1313,25 +1324,51 @@ static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
return ret;
}
+static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
+ .open = vfio_ap_mdev_open,
+ .release = vfio_ap_mdev_release,
+ .ioctl = vfio_ap_mdev_ioctl,
+};
+
+static struct mdev_driver vfio_ap_matrix_driver = {
+ .driver = {
+ .name = "vfio_ap_mdev",
+ .owner = THIS_MODULE,
+ .mod_name = KBUILD_MODNAME,
+ .dev_groups = vfio_ap_mdev_attr_groups,
+ },
+ .probe = vfio_ap_mdev_probe,
+ .remove = vfio_ap_mdev_remove,
+};
+
static const struct mdev_parent_ops vfio_ap_matrix_ops = {
.owner = THIS_MODULE,
+ .device_driver = &vfio_ap_matrix_driver,
.supported_type_groups = vfio_ap_mdev_type_groups,
- .mdev_attr_groups = vfio_ap_mdev_attr_groups,
- .create = vfio_ap_mdev_create,
- .remove = vfio_ap_mdev_remove,
- .open = vfio_ap_mdev_open,
- .release = vfio_ap_mdev_release,
- .ioctl = vfio_ap_mdev_ioctl,
};
int vfio_ap_mdev_register(void)
{
+ int ret;
+
atomic_set(&matrix_dev->available_instances, MAX_ZDEV_ENTRIES_EXT);
- return mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_ops);
+ ret = mdev_register_driver(&vfio_ap_matrix_driver);
+ if (ret)
+ return ret;
+
+ ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_ops);
+ if (ret)
+ goto err_driver;
+ return 0;
+
+err_driver:
+ mdev_unregister_driver(&vfio_ap_matrix_driver);
+ return ret;
}
void vfio_ap_mdev_unregister(void)
{
mdev_unregister_device(&matrix_dev->device);
+ mdev_unregister_driver(&vfio_ap_matrix_driver);
}
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index 28e9d998976820..b95ba674f60b1b 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/kvm_host.h>
+#include <linux/vfio.h>
#include "ap_bus.h"
@@ -79,6 +80,7 @@ struct ap_matrix {
* @kvm: the struct holding guest's state
*/
struct ap_matrix_mdev {
+ struct vfio_device vdev;
struct list_head node;
struct ap_matrix matrix;
struct notifier_block group_notifier;
--
2.31.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-04-23 23:03 ` [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev() Jason Gunthorpe
@ 2021-04-26 14:07 ` Christoph Hellwig
2021-04-26 17:48 ` Cornelia Huck
1 sibling, 0 replies; 27+ messages in thread
From: Christoph Hellwig @ 2021-04-26 14:07 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Tony Krowiak, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Fri, Apr 23, 2021 at 08:03:03PM -0300, Jason Gunthorpe wrote:
> This is straightforward conversion, the ap_matrix_mdev is actually serving
> as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
> simple container_of().
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-04-23 23:03 ` [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev() Jason Gunthorpe
2021-04-26 14:07 ` Christoph Hellwig
@ 2021-04-26 17:48 ` Cornelia Huck
2021-04-26 18:10 ` Jason Gunthorpe
` (2 more replies)
1 sibling, 3 replies; 27+ messages in thread
From: Cornelia Huck @ 2021-04-26 17:48 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Tony Krowiak, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Fri, 23 Apr 2021 20:03:03 -0300
Jason Gunthorpe <jgg@nvidia.com> wrote:
> This is straightforward conversion, the ap_matrix_mdev is actually serving
> as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
> simple container_of().
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
> drivers/s390/crypto/vfio_ap_ops.c | 137 ++++++++++++++++----------
> drivers/s390/crypto/vfio_ap_private.h | 2 +
> 2 files changed, 89 insertions(+), 50 deletions(-)
>
(...)
> -static int vfio_ap_mdev_remove(struct mdev_device *mdev)
> +static void vfio_ap_mdev_remove(struct mdev_device *mdev)
> {
> - struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
> + struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
>
> - if (matrix_mdev->kvm)
> - return -EBUSY;
> + /* FIXME: Remove isn't allowed to fail */
> + if (WARN_ON(matrix_mdev->kvm))
> + return;
This is a pre-existing problem, but the rework now makes it more
obvious.
Previously, the mdev code would only print a warning and then continue
with device removal, even if a ->remove() callback returned an error.
Now, it's quite clear that we'll end up in a weird half-dead state.
IIRC, the check for matrix_mdev->kvm is intended to protect against
ripping out the device under a running guest (I think it needs to
manipulate some crypto control blocks?)
So my question for the vfio-ap maintainers is: Can we actually end up
in this case? If yes, is there any way to gracefully shut down the
device?
> +
> + vfio_unregister_group_dev(&matrix_mdev->vdev);
>
> mutex_lock(&matrix_dev->lock);
> - vfio_ap_mdev_reset_queues(mdev);
> + vfio_ap_mdev_reset_queues(matrix_mdev);
> list_del(&matrix_mdev->node);
> mutex_unlock(&matrix_dev->lock);
>
> kfree(matrix_mdev);
> - mdev_set_drvdata(mdev, NULL);
> atomic_inc(&matrix_dev->available_instances);
> -
> - return 0;
> }
(...)
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-04-26 17:48 ` Cornelia Huck
@ 2021-04-26 18:10 ` Jason Gunthorpe
2021-04-26 23:41 ` Halil Pasic
2021-05-03 20:14 ` Tony Krowiak
2 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-26 18:10 UTC (permalink / raw)
To: Cornelia Huck
Cc: Tony Krowiak, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Mon, Apr 26, 2021 at 07:48:59PM +0200, Cornelia Huck wrote:
> On Fri, 23 Apr 2021 20:03:03 -0300
> Jason Gunthorpe <jgg@nvidia.com> wrote:
>
> > This is straightforward conversion, the ap_matrix_mdev is actually serving
> > as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
> > simple container_of().
> >
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > drivers/s390/crypto/vfio_ap_ops.c | 137 ++++++++++++++++----------
> > drivers/s390/crypto/vfio_ap_private.h | 2 +
> > 2 files changed, 89 insertions(+), 50 deletions(-)
> >
>
> (...)
>
> > -static int vfio_ap_mdev_remove(struct mdev_device *mdev)
> > +static void vfio_ap_mdev_remove(struct mdev_device *mdev)
> > {
> > - struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
> > + struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
> >
> > - if (matrix_mdev->kvm)
> > - return -EBUSY;
> > + /* FIXME: Remove isn't allowed to fail */
> > + if (WARN_ON(matrix_mdev->kvm))
> > + return;
>
> This is a pre-existing problem, but the rework now makes it more
> obvious.
>
> Previously, the mdev code would only print a warning and then continue
> with device removal, even if a ->remove() callback returned an
> error.
This does mostly the same, the warning was just moved from
mdev_device_remove_common() to here and changed to a WARN_ON() because
it means we are permanently leaking kernel memory. I think in this
case the vfio_device is not deleted - though I could re-order this to
make that happen.
> Now, it's quite clear that we'll end up in a weird half-dead state.
I don't think it changes, after we print the WARN_ON we return to the
driver core which does the same put_device()/etc as
mdev_device_remove_common() was doing.
> IIRC, the check for matrix_mdev->kvm is intended to protect against
> ripping out the device under a running guest (I think it needs to
> manipulate some crypto control blocks?)
In that case it is missing locking too.
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-04-26 17:48 ` Cornelia Huck
2021-04-26 18:10 ` Jason Gunthorpe
@ 2021-04-26 23:41 ` Halil Pasic
2021-05-03 20:14 ` Tony Krowiak
2 siblings, 0 replies; 27+ messages in thread
From: Halil Pasic @ 2021-04-26 23:41 UTC (permalink / raw)
To: Cornelia Huck
Cc: Jason Gunthorpe, Tony Krowiak, Christian Borntraeger,
Harald Freudenberger, Vasily Gorbik, Heiko Carstens, linux-s390,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Mon, 26 Apr 2021 19:48:59 +0200
Cornelia Huck <cohuck@redhat.com> wrote:
> So my question for the vfio-ap maintainers is: Can we actually end up
> in this case? If yes, is there any way to gracefully shut down the
> device?
@Tony: Can you take this one?
Regards,
Halil
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-04-26 17:48 ` Cornelia Huck
2021-04-26 18:10 ` Jason Gunthorpe
2021-04-26 23:41 ` Halil Pasic
@ 2021-05-03 20:14 ` Tony Krowiak
2021-05-03 20:33 ` Jason Gunthorpe
` (2 more replies)
2 siblings, 3 replies; 27+ messages in thread
From: Tony Krowiak @ 2021-05-03 20:14 UTC (permalink / raw)
To: Cornelia Huck, Jason Gunthorpe
Cc: Christian Borntraeger, Harald Freudenberger, Vasily Gorbik,
Heiko Carstens, linux-s390, Halil Pasic, Pierre Morel, Raj, Ashok,
Dan Williams, Daniel Vetter, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta, Jason J . Herne
On 4/26/21 1:48 PM, Cornelia Huck wrote:
> On Fri, 23 Apr 2021 20:03:03 -0300
> Jason Gunthorpe <jgg@nvidia.com> wrote:
>
>> This is straightforward conversion, the ap_matrix_mdev is actually serving
>> as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
>> simple container_of().
>>
>> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
>> ---
>> drivers/s390/crypto/vfio_ap_ops.c | 137 ++++++++++++++++----------
>> drivers/s390/crypto/vfio_ap_private.h | 2 +
>> 2 files changed, 89 insertions(+), 50 deletions(-)
>>
> (...)
>
>> -static int vfio_ap_mdev_remove(struct mdev_device *mdev)
>> +static void vfio_ap_mdev_remove(struct mdev_device *mdev)
>> {
>> - struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
>> + struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
>>
>> - if (matrix_mdev->kvm)
>> - return -EBUSY;
>> + /* FIXME: Remove isn't allowed to fail */
>> + if (WARN_ON(matrix_mdev->kvm))
>> + return;
> This is a pre-existing problem, but the rework now makes it more
> obvious.
I agree, I was not aware that returning a non-zero return code
from this callback did not return the -EBUSY to userspace
when the mdev is removed.
>
> Previously, the mdev code would only print a warning and then continue
> with device removal, even if a ->remove() callback returned an error.
> Now, it's quite clear that we'll end up in a weird half-dead state.
With the latest kernel from our tree, the remove hangs until the
guest is shutdown and the mdev fd is closed. During the hang, the
dmesg log has the following:
"No mdev vendor driver request callback support, blocked until released
by user"
So, it looks like nothing is done with the mdev until the fd for the
mdev is closed when the guest is shut down, at which time the
mdev is removed.
>
> IIRC, the check for matrix_mdev->kvm is intended to protect against
> ripping out the device under a running guest (I think it needs to
> manipulate some crypto control blocks?)
This is correct.
>
> So my question for the vfio-ap maintainers is: Can we actually end up
> in this case? If yes, is there any way to gracefully shut down the
> device?
This case will occur whenever a user removes the mdev
by echoing a '1' into the mdev's sysfs 'remove' attribute
file. I'm not sure it can be considered graceful to take away
all of the crypto devices from a guest while it is running,
but there is a way to process the remove callback without
leaving things in a "weird, half-dead state".
Up to this point, the onus for ensuring the proper procedure
is followed when managing pass-through crypto devices
for a KVM guest is left to the system administrator. In
other words, we don't prevent an admin from shooting
him/herself in the foot when doing things such as removing
an mdev while a KVM guest is using it. With this in mind,
I will handle this case in the follow-on patches implementing
dynamic AP configuration support for KVM guests.
>
>> +
>> + vfio_unregister_group_dev(&matrix_mdev->vdev);
>>
>> mutex_lock(&matrix_dev->lock);
>> - vfio_ap_mdev_reset_queues(mdev);
>> + vfio_ap_mdev_reset_queues(matrix_mdev);
>> list_del(&matrix_mdev->node);
>> mutex_unlock(&matrix_dev->lock);
>>
>> kfree(matrix_mdev);
>> - mdev_set_drvdata(mdev, NULL);
>> atomic_inc(&matrix_dev->available_instances);
>> -
>> - return 0;
>> }
> (...)
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-03 20:14 ` Tony Krowiak
@ 2021-05-03 20:33 ` Jason Gunthorpe
2021-05-04 13:58 ` Tony Krowiak
2021-05-04 15:30 ` Cornelia Huck
2021-05-05 16:28 ` Tony Krowiak
2 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2021-05-03 20:33 UTC (permalink / raw)
To: Tony Krowiak
Cc: Cornelia Huck, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On Mon, May 03, 2021 at 04:14:43PM -0400, Tony Krowiak wrote:
> This case will occur whenever a user removes the mdev
> by echoing a '1' into the mdev's sysfs 'remove' attribute
> file. I'm not sure it can be considered graceful to take away
> all of the crypto devices from a guest while it is running,
> but there is a way to process the remove callback without
> leaving things in a "weird, half-dead state".
It is acceptable to just sleep here until whatever user controlled
condition is resolved.
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-03 20:33 ` Jason Gunthorpe
@ 2021-05-04 13:58 ` Tony Krowiak
2021-05-04 16:04 ` Jason Gunthorpe
0 siblings, 1 reply; 27+ messages in thread
From: Tony Krowiak @ 2021-05-04 13:58 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Cornelia Huck, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On 5/3/21 4:33 PM, Jason Gunthorpe wrote:
> On Mon, May 03, 2021 at 04:14:43PM -0400, Tony Krowiak wrote:
>
>> This case will occur whenever a user removes the mdev
>> by echoing a '1' into the mdev's sysfs 'remove' attribute
>> file. I'm not sure it can be considered graceful to take away
>> all of the crypto devices from a guest while it is running,
>> but there is a way to process the remove callback without
>> leaving things in a "weird, half-dead state".
> It is acceptable to just sleep here until whatever user controlled
> condition is resolved.
>
> Jason
I suppose we could do that, but the user that tried to remove
the mdev via its sysfs 'remove' attribute will be left sitting
there wondering why the operation didn't complete. That
could result in leaving the user hanging in perpetuity.
IMHO, the callback should continue to return an int and
the caller should display the error if a non-zero rc is
returned.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-04 13:58 ` Tony Krowiak
@ 2021-05-04 16:04 ` Jason Gunthorpe
2021-05-05 13:07 ` Tony Krowiak
0 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2021-05-04 16:04 UTC (permalink / raw)
To: Tony Krowiak
Cc: Cornelia Huck, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On Tue, May 04, 2021 at 09:58:45AM -0400, Tony Krowiak wrote:
>
>
> On 5/3/21 4:33 PM, Jason Gunthorpe wrote:
> > On Mon, May 03, 2021 at 04:14:43PM -0400, Tony Krowiak wrote:
> >
> > > This case will occur whenever a user removes the mdev
> > > by echoing a '1' into the mdev's sysfs 'remove' attribute
> > > file. I'm not sure it can be considered graceful to take away
> > > all of the crypto devices from a guest while it is running,
> > > but there is a way to process the remove callback without
> > > leaving things in a "weird, half-dead state".
> > It is acceptable to just sleep here until whatever user controlled
> > condition is resolved.
> >
> > Jason
>
> I suppose we could do that, but the user that tried to remove
> the mdev via its sysfs 'remove' attribute will be left sitting
> there wondering why the operation didn't complete. That
> could result in leaving the user hanging in perpetuity.
Yes.
If the driver can't implement a disconnection then that is
unavoidable. What it does today by leaking memory under user control
is not acceptable.
> IMHO, the callback should continue to return an int and
> the caller should display the error if a non-zero rc is
> returned.
Nope, there is a reason removal is not allowed to fail.. sysfs remove
isn't the only reason the mdev driver could be destroyed, the
underlying physical device could be unplugged or other things.
Drivers need to implement a proper remove.
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-04 16:04 ` Jason Gunthorpe
@ 2021-05-05 13:07 ` Tony Krowiak
0 siblings, 0 replies; 27+ messages in thread
From: Tony Krowiak @ 2021-05-05 13:07 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Cornelia Huck, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On 5/4/21 12:04 PM, Jason Gunthorpe wrote:
> On Tue, May 04, 2021 at 09:58:45AM -0400, Tony Krowiak wrote:
>>
>> On 5/3/21 4:33 PM, Jason Gunthorpe wrote:
>>> On Mon, May 03, 2021 at 04:14:43PM -0400, Tony Krowiak wrote:
>>>
>>>> This case will occur whenever a user removes the mdev
>>>> by echoing a '1' into the mdev's sysfs 'remove' attribute
>>>> file. I'm not sure it can be considered graceful to take away
>>>> all of the crypto devices from a guest while it is running,
>>>> but there is a way to process the remove callback without
>>>> leaving things in a "weird, half-dead state".
>>> It is acceptable to just sleep here until whatever user controlled
>>> condition is resolved.
>>>
>>> Jason
>> I suppose we could do that, but the user that tried to remove
>> the mdev via its sysfs 'remove' attribute will be left sitting
>> there wondering why the operation didn't complete. That
>> could result in leaving the user hanging in perpetuity.
> Yes.
>
> If the driver can't implement a disconnection then that is
> unavoidable. What it does today by leaking memory under user control
> is not acceptable.
Based upon my observations of the behavior during a removal
of the mdev, memory is not leaked. If the fd for the mdev is
open when an attempt is made to remove it, the operation
will hang until the mdev fd is closed which happens when
either the guest is shut down or the mdev device is detached from
the guest. When the fd is closed, the mdev release callback is
invoked which nullifies the KVM pointer, so when the remove callback
is subsequently invoked, the mdev resources will be cleaned up.
Of course, I imagine there are other possibilities
for how an mdev can be removed, but in the normal course of
events, memory will not be leaked.
>
>> IMHO, the callback should continue to return an int and
>> the caller should display the error if a non-zero rc is
>> returned.
> Nope, there is a reason removal is not allowed to fail.. sysfs remove
> isn't the only reason the mdev driver could be destroyed, the
> underlying physical device could be unplugged or other things.
That may be true with other devices, but the matrix device is
not a real, physical device. Its sole purpose in life is to provide
an anchor for the mdev devices used to provide AP resources
to a guest; however, I get your point.
>
> Drivers need to implement a proper remove.
>
> Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-03 20:14 ` Tony Krowiak
2021-05-03 20:33 ` Jason Gunthorpe
@ 2021-05-04 15:30 ` Cornelia Huck
2021-05-05 12:30 ` Tony Krowiak
2021-05-05 16:28 ` Tony Krowiak
2 siblings, 1 reply; 27+ messages in thread
From: Cornelia Huck @ 2021-05-04 15:30 UTC (permalink / raw)
To: Tony Krowiak
Cc: Jason Gunthorpe, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On Mon, 3 May 2021 16:14:43 -0400
Tony Krowiak <akrowiak@linux.ibm.com> wrote:
> On 4/26/21 1:48 PM, Cornelia Huck wrote:
> > On Fri, 23 Apr 2021 20:03:03 -0300
> > Jason Gunthorpe <jgg@nvidia.com> wrote:
> >
> >> This is straightforward conversion, the ap_matrix_mdev is actually serving
> >> as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
> >> simple container_of().
> >>
> >> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> >> ---
> >> drivers/s390/crypto/vfio_ap_ops.c | 137 ++++++++++++++++----------
> >> drivers/s390/crypto/vfio_ap_private.h | 2 +
> >> 2 files changed, 89 insertions(+), 50 deletions(-)
> >>
> > (...)
> >
> >> -static int vfio_ap_mdev_remove(struct mdev_device *mdev)
> >> +static void vfio_ap_mdev_remove(struct mdev_device *mdev)
> >> {
> >> - struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
> >> + struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
> >>
> >> - if (matrix_mdev->kvm)
> >> - return -EBUSY;
> >> + /* FIXME: Remove isn't allowed to fail */
> >> + if (WARN_ON(matrix_mdev->kvm))
> >> + return;
> > This is a pre-existing problem, but the rework now makes it more
> > obvious.
>
> I agree, I was not aware that returning a non-zero return code
> from this callback did not return the -EBUSY to userspace
> when the mdev is removed.
>
> >
> > Previously, the mdev code would only print a warning and then continue
> > with device removal, even if a ->remove() callback returned an error.
> > Now, it's quite clear that we'll end up in a weird half-dead state.
>
> With the latest kernel from our tree, the remove hangs until the
> guest is shutdown and the mdev fd is closed. During the hang, the
> dmesg log has the following:
>
> "No mdev vendor driver request callback support, blocked until released
> by user"
>
> So, it looks like nothing is done with the mdev until the fd for the
> mdev is closed when the guest is shut down, at which time the
> mdev is removed.
You probably want to wire up the request callback and notify userspace.
What happens today if the device in QEMU is removed via device_del?
Does that already clean up things properly?
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-04 15:30 ` Cornelia Huck
@ 2021-05-05 12:30 ` Tony Krowiak
2021-05-05 17:47 ` Jason Gunthorpe
0 siblings, 1 reply; 27+ messages in thread
From: Tony Krowiak @ 2021-05-05 12:30 UTC (permalink / raw)
To: Cornelia Huck
Cc: Jason Gunthorpe, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On 5/4/21 11:30 AM, Cornelia Huck wrote:
> On Mon, 3 May 2021 16:14:43 -0400
> Tony Krowiak <akrowiak@linux.ibm.com> wrote:
>
>> On 4/26/21 1:48 PM, Cornelia Huck wrote:
>>> On Fri, 23 Apr 2021 20:03:03 -0300
>>> Jason Gunthorpe <jgg@nvidia.com> wrote:
>>>
>>>> This is straightforward conversion, the ap_matrix_mdev is actually serving
>>>> as the vfio_device and we can replace all the mdev_get_drvdata()'s with a
>>>> simple container_of().
>>>>
>>>> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
>>>> ---
>>>> drivers/s390/crypto/vfio_ap_ops.c | 137 ++++++++++++++++----------
>>>> drivers/s390/crypto/vfio_ap_private.h | 2 +
>>>> 2 files changed, 89 insertions(+), 50 deletions(-)
>>>>
>>> (...)
>>>
>>>> -static int vfio_ap_mdev_remove(struct mdev_device *mdev)
>>>> +static void vfio_ap_mdev_remove(struct mdev_device *mdev)
>>>> {
>>>> - struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
>>>> + struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(&mdev->dev);
>>>>
>>>> - if (matrix_mdev->kvm)
>>>> - return -EBUSY;
>>>> + /* FIXME: Remove isn't allowed to fail */
>>>> + if (WARN_ON(matrix_mdev->kvm))
>>>> + return;
>>> This is a pre-existing problem, but the rework now makes it more
>>> obvious.
>> I agree, I was not aware that returning a non-zero return code
>> from this callback did not return the -EBUSY to userspace
>> when the mdev is removed.
>>
>>> Previously, the mdev code would only print a warning and then continue
>>> with device removal, even if a ->remove() callback returned an error.
>>> Now, it's quite clear that we'll end up in a weird half-dead state.
>> With the latest kernel from our tree, the remove hangs until the
>> guest is shutdown and the mdev fd is closed. During the hang, the
>> dmesg log has the following:
>>
>> "No mdev vendor driver request callback support, blocked until released
>> by user"
>>
>> So, it looks like nothing is done with the mdev until the fd for the
>> mdev is closed when the guest is shut down, at which time the
>> mdev is removed.
> You probably want to wire up the request callback and notify userspace.
Not sure what you mean by this, but I also don't think it matters.
After coding up the fix for this and testing it, I've learned that
if a user attempts to remove an mdev via the sysfs 'remove'
attribute while the mdev fd is still open (i.e., in use by the guest),
the mdev remove callback is not invoked until the fd is closed
(i.e., the guest is shut down). During that time, the mdev is
physically removed from sysfs so no further actions can be taken
on it; but, since the remove callback has yet to be called, the
guest will have access to the AP resources provided by the
mdev during that time. I also tested detaching the mdev device from the
guest
(i.e., virsh detach-device) while the mdev was in the process of
being removed and this resulted in allowing the remove to
progress due to the mdev fd getting closed when it is detached.
>
> What happens today if the device in QEMU is removed via device_del?
> Does that already clean up things properly?
Hot plug/unplug is already supported, so yes, things get cleaned up
properly when the mdev fd is closed. This is handled by the mdev
release callback.
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-05 12:30 ` Tony Krowiak
@ 2021-05-05 17:47 ` Jason Gunthorpe
0 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2021-05-05 17:47 UTC (permalink / raw)
To: Tony Krowiak
Cc: Cornelia Huck, Christian Borntraeger, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, linux-s390, Halil Pasic,
Pierre Morel, Raj, Ashok, Dan Williams, Daniel Vetter,
Christoph Hellwig, Leon Romanovsky, Max Gurtovoy, Tarun Gupta,
Jason J . Herne
On Wed, May 05, 2021 at 08:30:54AM -0400, Tony Krowiak wrote:
> On 5/4/21 11:30 AM, Cornelia Huck wrote:
> > > So, it looks like nothing is done with the mdev until the fd for the
> > > mdev is closed when the guest is shut down, at which time the
> > > mdev is removed.
> > You probably want to wire up the request callback and notify userspace.
>
> Not sure what you mean by this, but I also don't think it matters.
request is triggered by the vfio core to expedite closing of the FD in
userspace.
> After coding up the fix for this and testing it, I've learned that
> if a user attempts to remove an mdev via the sysfs 'remove'
> attribute while the mdev fd is still open (i.e., in use by the
> guest), the mdev remove callback is not invoked until the fd is
> closed
Right the vfio_del_group_dev() called along this path and it blocks
until all FD related accesses are prevented. After it returns no ops
callback can be invoked.
> (i.e., the guest is shut down). During that time, the mdev is
> physically removed from sysfs so no further actions can be taken
> on it;
sysfs files are removed before we get to the remove callback - this is
part of why remove cannot fail, the damage is already done.
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev()
2021-05-03 20:14 ` Tony Krowiak
2021-05-03 20:33 ` Jason Gunthorpe
2021-05-04 15:30 ` Cornelia Huck
@ 2021-05-05 16:28 ` Tony Krowiak
2 siblings, 0 replies; 27+ messages in thread
From: Tony Krowiak @ 2021-05-05 16:28 UTC (permalink / raw)
To: Cornelia Huck, Jason Gunthorpe
Cc: Christian Borntraeger, Harald Freudenberger, Vasily Gorbik,
Heiko Carstens, linux-s390, Halil Pasic, Pierre Morel, Raj, Ashok,
Dan Williams, Daniel Vetter, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta, Jason J . Herne
On 5/3/21 4:14 PM, Tony Krowiak wrote:
...
>
> Up to this point, the onus for ensuring the proper procedure
> is followed when managing pass-through crypto devices
> for a KVM guest is left to the system administrator. In
> other words, we don't prevent an admin from shooting
> him/herself in the foot when doing things such as removing
> an mdev while a KVM guest is using it. With this in mind,
> I will handle this case in the follow-on patches implementing
> dynamic AP configuration support for KVM guests.
Change of plans: Based upon my exchanges with Jason, I have
decided to create a patch specifically to do the cleanup in
the mdev remove callback regardless of whether a KVM guest
is using the mdev or not.
>
>>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 07/12] vfio/ccw: Convert to use vfio_register_group_dev()
2021-04-23 23:02 [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Jason Gunthorpe
2021-04-23 23:02 ` [PATCH 01/12] vfio/mdev: Remove CONFIG_VFIO_MDEV_DEVICE Jason Gunthorpe
2021-04-23 23:03 ` [PATCH 06/12] vfio/ap_ops: Convert to use vfio_register_group_dev() Jason Gunthorpe
@ 2021-04-23 23:03 ` Jason Gunthorpe
2021-04-23 23:03 ` [PATCH 10/12] vfio/mdev: Remove mdev_parent_ops Jason Gunthorpe
2021-04-26 16:43 ` [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Christian Borntraeger
4 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-23 23:03 UTC (permalink / raw)
To: Christian Borntraeger, Cornelia Huck, Eric Farman, Vasily Gorbik,
Heiko Carstens, kvm, linux-s390, Peter Oberparleiter, Halil Pasic,
Vineeth Vijayan
Cc: Raj, Ashok, Dan Williams, Daniel Vetter, Christoph Hellwig,
Leon Romanovsky, Max Gurtovoy, Tarun Gupta
This is more complicated because vfio_ccw is sharing the vfio_device
between both the mdev_device and its vfio_device and the css_driver.
The mdev is a singleton, and the reason for this sharing appears to be to
allow the extra css_driver function callbacks to be delivered to the
vfio_device.
This keeps things as they were, with the css_driver allocating the
singleton, not the mdev_driver, this is pretty confusing. I'm also
uncertain how the lifetime model for the mdev works in the css_driver
callbacks.
At this point embed the vfio_device in the vfio_ccw_private and
instantiate it as a vfio_device when the mdev probes. The drvdata of both
the css_device and the mdev_device point at the private, and container_of
is used to get it back from the vfio_device.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/s390/cio/vfio_ccw_drv.c | 21 +++--
drivers/s390/cio/vfio_ccw_ops.c | 135 +++++++++++++++-------------
drivers/s390/cio/vfio_ccw_private.h | 5 ++
3 files changed, 94 insertions(+), 67 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 8c625b530035f5..55c4876dfd139d 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -442,7 +442,7 @@ static int __init vfio_ccw_sch_init(void)
vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");
if (!vfio_ccw_work_q) {
ret = -ENOMEM;
- goto out_err;
+ goto out_regions;
}
vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region",
@@ -451,7 +451,7 @@ static int __init vfio_ccw_sch_init(void)
sizeof(struct ccw_io_region), NULL);
if (!vfio_ccw_io_region) {
ret = -ENOMEM;
- goto out_err;
+ goto out_regions;
}
vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region",
@@ -460,7 +460,7 @@ static int __init vfio_ccw_sch_init(void)
sizeof(struct ccw_cmd_region), NULL);
if (!vfio_ccw_cmd_region) {
ret = -ENOMEM;
- goto out_err;
+ goto out_regions;
}
vfio_ccw_schib_region = kmem_cache_create_usercopy("vfio_ccw_schib_region",
@@ -470,7 +470,7 @@ static int __init vfio_ccw_sch_init(void)
if (!vfio_ccw_schib_region) {
ret = -ENOMEM;
- goto out_err;
+ goto out_regions;
}
vfio_ccw_crw_region = kmem_cache_create_usercopy("vfio_ccw_crw_region",
@@ -480,19 +480,25 @@ static int __init vfio_ccw_sch_init(void)
if (!vfio_ccw_crw_region) {
ret = -ENOMEM;
- goto out_err;
+ goto out_regions;
}
+ ret = mdev_register_driver(&vfio_ccw_mdev_driver);
+ if (ret)
+ goto out_regions;
+
isc_register(VFIO_CCW_ISC);
ret = css_driver_register(&vfio_ccw_sch_driver);
if (ret) {
isc_unregister(VFIO_CCW_ISC);
- goto out_err;
+ goto out_driver;
}
return ret;
-out_err:
+out_driver:
+ mdev_unregister_driver(&vfio_ccw_mdev_driver);
+out_regions:
vfio_ccw_destroy_regions();
destroy_workqueue(vfio_ccw_work_q);
vfio_ccw_debug_exit();
@@ -501,6 +507,7 @@ static int __init vfio_ccw_sch_init(void)
static void __exit vfio_ccw_sch_exit(void)
{
+ mdev_unregister_driver(&vfio_ccw_mdev_driver);
css_driver_unregister(&vfio_ccw_sch_driver);
isc_unregister(VFIO_CCW_ISC);
vfio_ccw_destroy_regions();
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 491a64c61fff1a..0fcf46031d3821 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -17,13 +17,13 @@
#include "vfio_ccw_private.h"
-static int vfio_ccw_mdev_reset(struct mdev_device *mdev)
+static const struct vfio_device_ops vfio_ccw_dev_ops;
+
+static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private)
{
- struct vfio_ccw_private *private;
struct subchannel *sch;
int ret;
- private = dev_get_drvdata(mdev_parent_dev(mdev));
sch = private->sch;
/*
* TODO:
@@ -61,7 +61,7 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
if (!cp_iova_pinned(&private->cp, unmap->iova))
return NOTIFY_OK;
- if (vfio_ccw_mdev_reset(private->mdev))
+ if (vfio_ccw_mdev_reset(private))
return NOTIFY_BAD;
cp_free(&private->cp);
@@ -113,10 +113,11 @@ static struct attribute_group *mdev_type_groups[] = {
NULL,
};
-static int vfio_ccw_mdev_create(struct mdev_device *mdev)
+static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
{
struct vfio_ccw_private *private =
dev_get_drvdata(mdev_parent_dev(mdev));
+ int ret;
if (private->state == VFIO_CCW_STATE_NOT_OPER)
return -ENODEV;
@@ -124,6 +125,10 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev)
if (atomic_dec_if_positive(&private->avail) < 0)
return -EPERM;
+ memset(&private->vdev, 0, sizeof(private->vdev));
+ vfio_init_group_dev(&private->vdev, &mdev->dev,
+ &vfio_ccw_dev_ops);
+
private->mdev = mdev;
private->state = VFIO_CCW_STATE_IDLE;
@@ -132,19 +137,28 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev)
private->sch->schid.ssid,
private->sch->schid.sch_no);
+ ret = vfio_register_group_dev(&private->vdev);
+ if (ret)
+ goto err_atomic;
+ dev_set_drvdata(&mdev->dev, private);
return 0;
+
+err_atomic:
+ atomic_inc(&private->avail);
+ return ret;
}
-static int vfio_ccw_mdev_remove(struct mdev_device *mdev)
+static void vfio_ccw_mdev_remove(struct mdev_device *mdev)
{
- struct vfio_ccw_private *private =
- dev_get_drvdata(mdev_parent_dev(mdev));
+ struct vfio_ccw_private *private = dev_get_drvdata(&mdev->dev);
VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n",
mdev_uuid(mdev), private->sch->schid.cssid,
private->sch->schid.ssid,
private->sch->schid.sch_no);
+ vfio_unregister_group_dev(&private->vdev);
+
if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
(private->state != VFIO_CCW_STATE_STANDBY)) {
if (!vfio_ccw_sch_quiesce(private->sch))
@@ -155,20 +169,18 @@ static int vfio_ccw_mdev_remove(struct mdev_device *mdev)
cp_free(&private->cp);
private->mdev = NULL;
atomic_inc(&private->avail);
-
- return 0;
}
-static int vfio_ccw_mdev_open(struct mdev_device *mdev)
+static int vfio_ccw_mdev_open(struct vfio_device *vdev)
{
struct vfio_ccw_private *private =
- dev_get_drvdata(mdev_parent_dev(mdev));
+ container_of(vdev, struct vfio_ccw_private, vdev);
unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
int ret;
private->nb.notifier_call = vfio_ccw_mdev_notifier;
- ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+ ret = vfio_register_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
&events, &private->nb);
if (ret)
return ret;
@@ -189,27 +201,26 @@ static int vfio_ccw_mdev_open(struct mdev_device *mdev)
out_unregister:
vfio_ccw_unregister_dev_regions(private);
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+ vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY,
&private->nb);
return ret;
}
-static void vfio_ccw_mdev_release(struct mdev_device *mdev)
+static void vfio_ccw_mdev_release(struct vfio_device *vdev)
{
struct vfio_ccw_private *private =
- dev_get_drvdata(mdev_parent_dev(mdev));
+ container_of(vdev, struct vfio_ccw_private, vdev);
if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
(private->state != VFIO_CCW_STATE_STANDBY)) {
- if (!vfio_ccw_mdev_reset(mdev))
+ if (!vfio_ccw_mdev_reset(private))
private->state = VFIO_CCW_STATE_STANDBY;
/* The state will be NOT_OPER on error. */
}
cp_free(&private->cp);
vfio_ccw_unregister_dev_regions(private);
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
- &private->nb);
+ vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY, &private->nb);
}
static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
@@ -233,15 +244,14 @@ static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
return ret;
}
-static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev,
+static ssize_t vfio_ccw_mdev_read(struct vfio_device *vdev,
char __user *buf,
size_t count,
loff_t *ppos)
{
+ struct vfio_ccw_private *private =
+ container_of(vdev, struct vfio_ccw_private, vdev);
unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
- struct vfio_ccw_private *private;
-
- private = dev_get_drvdata(mdev_parent_dev(mdev));
if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
return -EINVAL;
@@ -288,15 +298,14 @@ static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private,
return ret;
}
-static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
+static ssize_t vfio_ccw_mdev_write(struct vfio_device *vdev,
const char __user *buf,
size_t count,
loff_t *ppos)
{
+ struct vfio_ccw_private *private =
+ container_of(vdev, struct vfio_ccw_private, vdev);
unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
- struct vfio_ccw_private *private;
-
- private = dev_get_drvdata(mdev_parent_dev(mdev));
if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
return -EINVAL;
@@ -313,12 +322,9 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
return -EINVAL;
}
-static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info,
- struct mdev_device *mdev)
+static int vfio_ccw_mdev_get_device_info(struct vfio_ccw_private *private,
+ struct vfio_device_info *info)
{
- struct vfio_ccw_private *private;
-
- private = dev_get_drvdata(mdev_parent_dev(mdev));
info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions;
info->num_irqs = VFIO_CCW_NUM_IRQS;
@@ -326,14 +332,12 @@ static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info,
return 0;
}
-static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
- struct mdev_device *mdev,
+static int vfio_ccw_mdev_get_region_info(struct vfio_ccw_private *private,
+ struct vfio_region_info *info,
unsigned long arg)
{
- struct vfio_ccw_private *private;
int i;
- private = dev_get_drvdata(mdev_parent_dev(mdev));
switch (info->index) {
case VFIO_CCW_CONFIG_REGION_INDEX:
info->offset = 0;
@@ -408,19 +412,16 @@ static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
return 0;
}
-static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
+static int vfio_ccw_mdev_set_irqs(struct vfio_ccw_private *private,
uint32_t flags,
uint32_t index,
void __user *data)
{
- struct vfio_ccw_private *private;
struct eventfd_ctx **ctx;
if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
return -EINVAL;
- private = dev_get_drvdata(mdev_parent_dev(mdev));
-
switch (index) {
case VFIO_CCW_IO_IRQ_INDEX:
ctx = &private->io_trigger;
@@ -522,10 +523,12 @@ void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private)
private->region = NULL;
}
-static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
+static ssize_t vfio_ccw_mdev_ioctl(struct vfio_device *vdev,
unsigned int cmd,
unsigned long arg)
{
+ struct vfio_ccw_private *private =
+ container_of(vdev, struct vfio_ccw_private, vdev);
int ret = 0;
unsigned long minsz;
@@ -542,7 +545,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
if (info.argsz < minsz)
return -EINVAL;
- ret = vfio_ccw_mdev_get_device_info(&info, mdev);
+ ret = vfio_ccw_mdev_get_device_info(private, &info);
if (ret)
return ret;
@@ -560,7 +563,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
if (info.argsz < minsz)
return -EINVAL;
- ret = vfio_ccw_mdev_get_region_info(&info, mdev, arg);
+ ret = vfio_ccw_mdev_get_region_info(private, &info, arg);
if (ret)
return ret;
@@ -605,47 +608,59 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
return ret;
data = (void __user *)(arg + minsz);
- return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, hdr.index, data);
+ return vfio_ccw_mdev_set_irqs(private, hdr.flags, hdr.index,
+ data);
}
case VFIO_DEVICE_RESET:
- return vfio_ccw_mdev_reset(mdev);
+ return vfio_ccw_mdev_reset(private);
default:
return -ENOTTY;
}
}
/* Request removal of the device*/
-static void vfio_ccw_mdev_request(struct mdev_device *mdev, unsigned int count)
+static void vfio_ccw_mdev_request(struct vfio_device *vdev, unsigned int count)
{
- struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev));
-
- if (!private)
- return;
+ struct vfio_ccw_private *private =
+ container_of(vdev, struct vfio_ccw_private, vdev);
+ struct device *dev = private->vdev.dev;
if (private->req_trigger) {
if (!(count % 10))
- dev_notice_ratelimited(mdev_dev(private->mdev),
+ dev_notice_ratelimited(dev,
"Relaying device request to user (#%u)\n",
count);
eventfd_signal(private->req_trigger, 1);
} else if (count == 0) {
- dev_notice(mdev_dev(private->mdev),
+ dev_notice(dev,
"No device request channel registered, blocked until released by user\n");
}
}
+static const struct vfio_device_ops vfio_ccw_dev_ops = {
+ .open = vfio_ccw_mdev_open,
+ .release = vfio_ccw_mdev_release,
+ .read = vfio_ccw_mdev_read,
+ .write = vfio_ccw_mdev_write,
+ .ioctl = vfio_ccw_mdev_ioctl,
+ .request = vfio_ccw_mdev_request,
+};
+
+struct mdev_driver vfio_ccw_mdev_driver = {
+ .driver = {
+ .name = "vfio_ccw_mdev",
+ .owner = THIS_MODULE,
+ .mod_name = KBUILD_MODNAME,
+ },
+ .probe = vfio_ccw_mdev_probe,
+ .remove = vfio_ccw_mdev_remove,
+};
+
static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
.owner = THIS_MODULE,
+ .device_driver = &vfio_ccw_mdev_driver,
.supported_type_groups = mdev_type_groups,
- .create = vfio_ccw_mdev_create,
- .remove = vfio_ccw_mdev_remove,
- .open = vfio_ccw_mdev_open,
- .release = vfio_ccw_mdev_release,
- .read = vfio_ccw_mdev_read,
- .write = vfio_ccw_mdev_write,
- .ioctl = vfio_ccw_mdev_ioctl,
- .request = vfio_ccw_mdev_request,
};
int vfio_ccw_mdev_reg(struct subchannel *sch)
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index b2c762eb42b9bb..7272eb78861244 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -17,6 +17,7 @@
#include <linux/eventfd.h>
#include <linux/workqueue.h>
#include <linux/vfio_ccw.h>
+#include <linux/vfio.h>
#include <asm/crw.h>
#include <asm/debug.h>
@@ -67,6 +68,7 @@ struct vfio_ccw_crw {
/**
* struct vfio_ccw_private
+ * @vdev: Embedded VFIO device
* @sch: pointer to the subchannel
* @state: internal state of the device
* @completion: synchronization helper of the I/O completion
@@ -90,6 +92,7 @@ struct vfio_ccw_crw {
* @crw_work: work for deferral process of CRW handling
*/
struct vfio_ccw_private {
+ struct vfio_device vdev;
struct subchannel *sch;
int state;
struct completion *completion;
@@ -121,6 +124,8 @@ extern void vfio_ccw_mdev_unreg(struct subchannel *sch);
extern int vfio_ccw_sch_quiesce(struct subchannel *sch);
+extern struct mdev_driver vfio_ccw_mdev_driver;
+
/*
* States of the device statemachine.
*/
--
2.31.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* [PATCH 10/12] vfio/mdev: Remove mdev_parent_ops
2021-04-23 23:02 [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Jason Gunthorpe
` (2 preceding siblings ...)
2021-04-23 23:03 ` [PATCH 07/12] vfio/ccw: " Jason Gunthorpe
@ 2021-04-23 23:03 ` Jason Gunthorpe
2021-04-26 14:19 ` Christoph Hellwig
2021-04-26 16:43 ` [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Christian Borntraeger
4 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-23 23:03 UTC (permalink / raw)
To: David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Eric Farman, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, intel-gfx, intel-gvt-dev,
Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede, linux-doc,
linux-s390, Peter Oberparleiter, Halil Pasic, Pierre Morel,
Rodrigo Vivi, Vineeth Vijayan, Zhenyu Wang, Zhi Wang
Cc: Raj, Ashok, Dan Williams, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta
The last useful member in this struct is the supported_type_groups, move
it to the mdev_driver and delete mdev_parent_ops.
Replace it with mdev_driver as an argument to mdev_register_device()
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
.../driver-api/vfio-mediated-device.rst | 36 +++++++------------
drivers/gpu/drm/i915/gvt/kvmgt.c | 8 ++---
drivers/s390/cio/vfio_ccw_ops.c | 7 +---
drivers/s390/crypto/vfio_ap_ops.c | 9 ++---
drivers/vfio/mdev/mdev_core.c | 13 +++----
drivers/vfio/mdev/mdev_driver.c | 2 +-
drivers/vfio/mdev/mdev_private.h | 2 +-
drivers/vfio/mdev/mdev_sysfs.c | 6 ++--
include/linux/mdev.h | 24 +++----------
samples/vfio-mdev/mbochs.c | 9 ++---
samples/vfio-mdev/mdpy.c | 9 ++---
samples/vfio-mdev/mtty.c | 9 ++---
12 files changed, 38 insertions(+), 96 deletions(-)
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 5f866b17c93e69..b7cf357243d269 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -93,7 +93,7 @@ interfaces:
Registration Interface for a Mediated Bus Driver
------------------------------------------------
-The registration interface for a mediated bus driver provides the following
+The registration interface for a mediated device driver provides the following
structure to represent a mediated device's driver::
/*
@@ -105,6 +105,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
+ struct attribute_group **supported_type_groups;
struct device_driver driver;
};
@@ -119,35 +120,24 @@ to register and unregister itself with the core driver:
extern void mdev_unregister_driver(struct mdev_driver *drv);
-The mediated bus driver is responsible for adding mediated devices to the VFIO
-group when devices are bound to the driver and removing mediated devices from
-the VFIO when devices are unbound from the driver.
+The mediated bus driver's probe function should create a vfio_device on top of
+the mdev_device and connect it to an appropriate implementation of vfio_device_ops.
-
-Physical Device Driver Interface
---------------------------------
-
-The physical device driver interface provides the mdev_parent_ops[3] structure
-to define the APIs to manage work in the mediated core driver that is related
-to the physical device.
-
-The structures in the mdev_parent_ops structure are as follows:
-
-* dev_attr_groups: attributes of the parent device
-* mdev_attr_groups: attributes of the mediated device
-* supported_config: attributes to define supported configurations
-
-A driver should use the mdev_parent_ops structure in the function call to
-register itself with the mdev core driver::
+When a driver wants to add the GUID creation sysfs to an existing device it has
+probe'd to then it should call:
extern int mdev_register_device(struct device *dev,
- const struct mdev_parent_ops *ops);
+ struct mdev_driver *mdev_driver);
+
+This will provide the 'mdev_supported_types/XX/create' files which can then be used
+to trigger the creation of a mdev_device. The created mdev_device will be attached
+to the specified driver.
-However, the mdev_parent_ops structure is not required in the function call
-that a driver should use to unregister itself with the mdev core driver::
+When the driver needs to remove itself it calls:
extern void mdev_unregister_device(struct device *dev);
+Which will unbind and destroy all the created mdevs and remove the sysfs files.
Mediated Device Management Interface Through sysfs
==================================================
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 85ef300087e091..02089efd15bb92 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1669,10 +1669,6 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
.remove = intel_vgpu_remove,
};
-static struct mdev_parent_ops intel_vgpu_ops = {
- .device_driver = &intel_vgpu_mdev_driver,
-};
-
static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
{
struct attribute_group **kvm_vgpu_type_groups;
@@ -1680,9 +1676,9 @@ static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
intel_gvt_ops = ops;
if (!intel_gvt_ops->get_gvt_attrs(&kvm_vgpu_type_groups))
return -EFAULT;
- intel_vgpu_ops.supported_type_groups = kvm_vgpu_type_groups;
+ intel_vgpu_mdev_driver.supported_type_groups = kvm_vgpu_type_groups;
- return mdev_register_device(dev, &intel_vgpu_ops);
+ return mdev_register_device(dev, &intel_vgpu_mdev_driver);
}
static void kvmgt_host_exit(struct device *dev)
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 0fcf46031d3821..161697529dcc41 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -655,17 +655,12 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
-};
-
-static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
- .owner = THIS_MODULE,
- .device_driver = &vfio_ccw_mdev_driver,
.supported_type_groups = mdev_type_groups,
};
int vfio_ccw_mdev_reg(struct subchannel *sch)
{
- return mdev_register_device(&sch->dev, &vfio_ccw_mdev_ops);
+ return mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
}
void vfio_ccw_mdev_unreg(struct subchannel *sch)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 79872c857dd522..92789257c87639 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1339,12 +1339,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
},
.probe = vfio_ap_mdev_probe,
.remove = vfio_ap_mdev_remove,
-};
-
-static const struct mdev_parent_ops vfio_ap_matrix_ops = {
- .owner = THIS_MODULE,
- .device_driver = &vfio_ap_matrix_driver,
- .supported_type_groups = vfio_ap_mdev_type_groups,
+ .supported_type_groups = vfio_ap_mdev_type_groups,
};
int vfio_ap_mdev_register(void)
@@ -1357,7 +1352,7 @@ int vfio_ap_mdev_register(void)
if (ret)
return ret;
- ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_ops);
+ ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_driver);
if (ret)
goto err_driver;
return 0;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index f95d01b57fb168..7e918241de10cc 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -109,12 +109,12 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
/*
* mdev_register_device : Register a device
* @dev: device structure representing parent device.
- * @ops: Parent device operation structure to be registered.
+ * @mdev_driver: Device driver to bind to the newly created mdev
*
* Add device to list of registered parent devices.
* Returns a negative value on error, otherwise 0.
*/
-int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
+int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver)
{
int ret;
struct mdev_parent *parent;
@@ -122,9 +122,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
char *envp[] = { env_string, NULL };
/* check for mandatory ops */
- if (!ops || !ops->supported_type_groups)
- return -EINVAL;
- if (!ops->device_driver)
+ if (!mdev_driver->supported_type_groups)
return -EINVAL;
dev = get_device(dev);
@@ -151,7 +149,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
init_rwsem(&parent->unreg_sem);
parent->dev = dev;
- parent->ops = ops;
+ parent->mdev_driver = mdev_driver;
if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
@@ -257,7 +255,7 @@ static int mdev_bind_driver(struct mdev_device *mdev)
while (1) {
device_lock(&mdev->dev);
if (mdev->dev.driver ==
- &mdev->type->parent->ops->device_driver->driver) {
+ &mdev->type->parent->mdev_driver->driver) {
ret = 0;
goto out_unlock;
}
@@ -304,7 +302,6 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
mdev->dev.parent = parent->dev;
mdev->dev.bus = &mdev_bus_type;
mdev->dev.release = mdev_device_release;
- mdev->dev.groups = parent->ops->mdev_attr_groups;
mdev->type = type;
/* Pairs with the put in mdev_device_release() */
kobject_get(&type->kobj);
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 0012a9ee7cb0a4..12091e32afa396 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -75,7 +75,7 @@ static int mdev_match(struct device *dev, struct device_driver *drv)
{
struct mdev_device *mdev = to_mdev_device(dev);
- return drv == &mdev->type->parent->ops->device_driver->driver;
+ return drv == &mdev->type->parent->mdev_driver->driver;
}
struct bus_type mdev_bus_type = {
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index a656cfe0346c33..839567d059a07d 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -15,7 +15,7 @@ void mdev_bus_unregister(void);
struct mdev_parent {
struct device *dev;
- const struct mdev_parent_ops *ops;
+ const struct mdev_driver *mdev_driver;
struct kref ref;
struct list_head next;
struct kset *mdev_types_kset;
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 66eef08833a4ef..5a3873d1a275ae 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -97,7 +97,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
{
struct mdev_type *type;
struct attribute_group *group =
- parent->ops->supported_type_groups[type_group_id];
+ parent->mdev_driver->supported_type_groups[type_group_id];
int ret;
if (!group->name) {
@@ -154,7 +154,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
static void remove_mdev_supported_type(struct mdev_type *type)
{
struct attribute_group *group =
- type->parent->ops->supported_type_groups[type->type_group_id];
+ type->parent->mdev_driver->supported_type_groups[type->type_group_id];
sysfs_remove_files(&type->kobj,
(const struct attribute **)group->attrs);
@@ -168,7 +168,7 @@ static int add_mdev_supported_type_groups(struct mdev_parent *parent)
{
int i;
- for (i = 0; parent->ops->supported_type_groups[i]; i++) {
+ for (i = 0; parent->mdev_driver->supported_type_groups[i]; i++) {
struct mdev_type *type;
type = add_mdev_supported_type(parent, i);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index fd9fe1dcf0e230..af807c77c1e0f5 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -51,25 +51,6 @@ unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
struct device *mtype_get_parent_dev(struct mdev_type *mtype);
-/**
- * struct mdev_parent_ops - Structure to be registered for each parent device to
- * register the device to mdev module.
- *
- * @owner: The module owner.
- * @device_driver: Which device driver to probe() on newly created devices
- * @mdev_attr_groups: Attributes of the mediated device.
- * @supported_type_groups: Attributes to define supported types. It is mandatory
- * to provide supported types.
- * Parent device that support mediated device should be registered with mdev
- * module with mdev_parent_ops structure.
- **/
-struct mdev_parent_ops {
- struct module *owner;
- struct mdev_driver *device_driver;
- const struct attribute_group **mdev_attr_groups;
- struct attribute_group **supported_type_groups;
-};
-
/* interface for exporting mdev supported type attributes */
struct mdev_type_attribute {
struct attribute attr;
@@ -94,12 +75,15 @@ struct mdev_type_attribute mdev_type_attr_##_name = \
* struct mdev_driver - Mediated device driver
* @probe: called when new device created
* @remove: called when device removed
+ * @supported_type_groups: Attributes to define supported types. It is mandatory
+ * to provide supported types.
* @driver: device driver structure
*
**/
struct mdev_driver {
int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev);
+ struct attribute_group **supported_type_groups;
struct device_driver driver;
};
@@ -118,7 +102,7 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
extern struct bus_type mdev_bus_type;
-int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops);
+int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver);
void mdev_unregister_device(struct device *dev);
int mdev_register_driver(struct mdev_driver *drv);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index e18821a8a6beb8..c76ceec584b41b 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -1418,12 +1418,7 @@ static struct mdev_driver mbochs_driver = {
},
.probe = mbochs_probe,
.remove = mbochs_remove,
-};
-
-static const struct mdev_parent_ops mdev_fops = {
- .owner = THIS_MODULE,
- .device_driver = &mbochs_driver,
- .supported_type_groups = mdev_type_groups,
+ .supported_type_groups = mdev_type_groups,
};
static const struct file_operations vd_fops = {
@@ -1466,7 +1461,7 @@ static int __init mbochs_dev_init(void)
if (ret)
goto err_class;
- ret = mdev_register_device(&mbochs_dev, &mdev_fops);
+ ret = mdev_register_device(&mbochs_dev, &mbochs_driver);
if (ret)
goto err_device;
diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index 82638de333330d..c22b2c808d132d 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -735,12 +735,7 @@ static struct mdev_driver mdpy_driver = {
},
.probe = mdpy_probe,
.remove = mdpy_remove,
-};
-
-static const struct mdev_parent_ops mdev_fops = {
- .owner = THIS_MODULE,
- .device_driver = &mdpy_driver,
- .supported_type_groups = mdev_type_groups,
+ .supported_type_groups = mdev_type_groups,
};
static const struct file_operations vd_fops = {
@@ -783,7 +778,7 @@ static int __init mdpy_dev_init(void)
if (ret)
goto err_class;
- ret = mdev_register_device(&mdpy_dev, &mdev_fops);
+ ret = mdev_register_device(&mdpy_dev, &mdpy_driver);
if (ret)
goto err_device;
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 31eec76bc553ce..87f5ba12a230e3 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -1308,12 +1308,7 @@ static struct mdev_driver mtty_driver = {
},
.probe = mtty_probe,
.remove = mtty_remove,
-};
-
-static const struct mdev_parent_ops mdev_fops = {
- .owner = THIS_MODULE,
- .device_driver = &mtty_driver,
- .supported_type_groups = mdev_type_groups,
+ .supported_type_groups = mdev_type_groups,
};
static void mtty_device_release(struct device *dev)
@@ -1364,7 +1359,7 @@ static int __init mtty_dev_init(void)
if (ret)
goto err_class;
- ret = mdev_register_device(&mtty_dev.dev, &mdev_fops);
+ ret = mdev_register_device(&mtty_dev.dev, &mtty_driver);
if (ret)
goto err_device;
--
2.31.1
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [PATCH 10/12] vfio/mdev: Remove mdev_parent_ops
2021-04-23 23:03 ` [PATCH 10/12] vfio/mdev: Remove mdev_parent_ops Jason Gunthorpe
@ 2021-04-26 14:19 ` Christoph Hellwig
2021-04-26 18:33 ` Jason Gunthorpe
0 siblings, 1 reply; 27+ messages in thread
From: Christoph Hellwig @ 2021-04-26 14:19 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Eric Farman, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, intel-gfx, intel-gvt-dev,
Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede, linux-doc,
linux-s390, Peter Oberparleiter, Halil Pasic, Pierre Morel,
Rodrigo Vivi, Vineeth Vijayan, Zhenyu Wang, Zhi Wang, Raj, Ashok,
Dan Williams, Christoph Hellwig, Leon Romanovsky, Max Gurtovoy,
Tarun Gupta
> +The mediated bus driver's probe function should create a vfio_device on top of
> +the mdev_device and connect it to an appropriate implementation of vfio_device_ops.
Overly long line.
> +This will provide the 'mdev_supported_types/XX/create' files which can then be used
> +to trigger the creation of a mdev_device. The created mdev_device will be attached
Two more.
Otherwise looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 10/12] vfio/mdev: Remove mdev_parent_ops
2021-04-26 14:19 ` Christoph Hellwig
@ 2021-04-26 18:33 ` Jason Gunthorpe
0 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-26 18:33 UTC (permalink / raw)
To: Christoph Hellwig
Cc: David Airlie, Tony Krowiak, Alex Williamson,
Christian Borntraeger, Cornelia Huck, Jonathan Corbet,
Daniel Vetter, dri-devel, Eric Farman, Harald Freudenberger,
Vasily Gorbik, Heiko Carstens, intel-gfx, intel-gvt-dev,
Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede, linux-doc,
linux-s390, Peter Oberparleiter, Halil Pasic, Pierre Morel,
Rodrigo Vivi, Vineeth Vijayan, Zhenyu Wang, Zhi Wang, Raj, Ashok,
Dan Williams, Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Mon, Apr 26, 2021 at 04:19:11PM +0200, Christoph Hellwig wrote:
> > +The mediated bus driver's probe function should create a vfio_device on top of
> > +the mdev_device and connect it to an appropriate implementation of vfio_device_ops.
>
> Overly long line.
>
> > +This will provide the 'mdev_supported_types/XX/create' files which can then be used
> > +to trigger the creation of a mdev_device. The created mdev_device will be attached
>
> Two more.
Got it, thanks
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more
2021-04-23 23:02 [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Jason Gunthorpe
` (3 preceding siblings ...)
2021-04-23 23:03 ` [PATCH 10/12] vfio/mdev: Remove mdev_parent_ops Jason Gunthorpe
@ 2021-04-26 16:43 ` Christian Borntraeger
2021-04-26 17:42 ` Jason Gunthorpe
4 siblings, 1 reply; 27+ messages in thread
From: Christian Borntraeger @ 2021-04-26 16:43 UTC (permalink / raw)
To: Jason Gunthorpe, David Airlie, Tony Krowiak, Alex Williamson,
Cornelia Huck, Jonathan Corbet, Daniel Vetter, dri-devel,
Eric Farman, Harald Freudenberger, Vasily Gorbik, Heiko Carstens,
intel-gfx, intel-gvt-dev, Jani Nikula, Joonas Lahtinen, kvm,
Kirti Wankhede, linux-doc, linux-s390, Peter Oberparleiter,
Halil Pasic, Pierre Morel, Rodrigo Vivi, Vineeth Vijayan,
Zhenyu Wang, Zhi Wang
Cc: Raj, Ashok, Dan Williams, Christoph Hellwig, Leon Romanovsky,
Max Gurtovoy, Tarun Gupta
On 24.04.21 01:02, Jason Gunthorpe wrote:
> Prologue
> ========
>
> This is series #3 in part of a larger work that arose from the minor
> remark that the mdev_parent_ops indirection shim is useless and
> complicates things.
>
> It applies on top of Alex's current tree and requires the prior two
> series.
Do you have a tree somewhere?
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more
2021-04-26 16:43 ` [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more Christian Borntraeger
@ 2021-04-26 17:42 ` Jason Gunthorpe
2021-04-27 7:33 ` Christian Borntraeger
0 siblings, 1 reply; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-26 17:42 UTC (permalink / raw)
To: Christian Borntraeger
Cc: David Airlie, Tony Krowiak, Alex Williamson, Cornelia Huck,
Jonathan Corbet, Daniel Vetter, dri-devel, Eric Farman,
Harald Freudenberger, Vasily Gorbik, Heiko Carstens, intel-gfx,
intel-gvt-dev, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Peter Oberparleiter, Halil Pasic,
Pierre Morel, Rodrigo Vivi, Vineeth Vijayan, Zhenyu Wang,
Zhi Wang, Raj, Ashok, Dan Williams, Christoph Hellwig,
Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Mon, Apr 26, 2021 at 06:43:14PM +0200, Christian Borntraeger wrote:
> On 24.04.21 01:02, Jason Gunthorpe wrote:
> > Prologue
> > ========
> >
> > This is series #3 in part of a larger work that arose from the minor
> > remark that the mdev_parent_ops indirection shim is useless and
> > complicates things.
> >
> > It applies on top of Alex's current tree and requires the prior two
> > series.
>
> Do you have a tree somewhere?
[..]
> > A preview of the future series's is here:
> > https://github.com/jgunthorpe/linux/pull/3/commits
Has everything, you'll want to go to:
cover-letter: Remove vfio_mdev.c, mdev_parent_ops and more
As there are additional WIPs in that tree.
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more
2021-04-26 17:42 ` Jason Gunthorpe
@ 2021-04-27 7:33 ` Christian Borntraeger
2021-04-27 23:21 ` Jason Gunthorpe
0 siblings, 1 reply; 27+ messages in thread
From: Christian Borntraeger @ 2021-04-27 7:33 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: David Airlie, Tony Krowiak, Alex Williamson, Cornelia Huck,
Jonathan Corbet, Daniel Vetter, dri-devel, Eric Farman,
Harald Freudenberger, Vasily Gorbik, Heiko Carstens, intel-gfx,
intel-gvt-dev, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Peter Oberparleiter, Halil Pasic,
Pierre Morel, Rodrigo Vivi, Vineeth Vijayan, Zhenyu Wang,
Zhi Wang, Raj, Ashok, Dan Williams, Christoph Hellwig,
Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On 26.04.21 19:42, Jason Gunthorpe wrote:
> On Mon, Apr 26, 2021 at 06:43:14PM +0200, Christian Borntraeger wrote:
>> On 24.04.21 01:02, Jason Gunthorpe wrote:
>>> Prologue
>>> ========
>>>
>>> This is series #3 in part of a larger work that arose from the minor
>>> remark that the mdev_parent_ops indirection shim is useless and
>>> complicates things.
>>>
>>> It applies on top of Alex's current tree and requires the prior two
>>> series.
>>
>> Do you have a tree somewhere?
>
> [..]
>>> A preview of the future series's is here:
>>> https://github.com/jgunthorpe/linux/pull/3/commits
>
> Has everything, you'll want to go to:
> cover-letter: Remove vfio_mdev.c, mdev_parent_ops and more
>
> As there are additional WIPs in that tree.
I gave this a quick spin on s390x vfio-ap and it seems to work ok.
This is really just a quick test, but no obvious problem.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 00/12] Remove vfio_mdev.c, mdev_parent_ops and more
2021-04-27 7:33 ` Christian Borntraeger
@ 2021-04-27 23:21 ` Jason Gunthorpe
0 siblings, 0 replies; 27+ messages in thread
From: Jason Gunthorpe @ 2021-04-27 23:21 UTC (permalink / raw)
To: Christian Borntraeger
Cc: David Airlie, Tony Krowiak, Alex Williamson, Cornelia Huck,
Jonathan Corbet, Daniel Vetter, dri-devel, Eric Farman,
Harald Freudenberger, Vasily Gorbik, Heiko Carstens, intel-gfx,
intel-gvt-dev, Jani Nikula, Joonas Lahtinen, kvm, Kirti Wankhede,
linux-doc, linux-s390, Peter Oberparleiter, Halil Pasic,
Pierre Morel, Rodrigo Vivi, Vineeth Vijayan, Zhenyu Wang,
Zhi Wang, Raj, Ashok, Dan Williams, Christoph Hellwig,
Leon Romanovsky, Max Gurtovoy, Tarun Gupta
On Tue, Apr 27, 2021 at 09:33:56AM +0200, Christian Borntraeger wrote:
> On 26.04.21 19:42, Jason Gunthorpe wrote:
> > On Mon, Apr 26, 2021 at 06:43:14PM +0200, Christian Borntraeger wrote:
> > > On 24.04.21 01:02, Jason Gunthorpe wrote:
> > > > Prologue
> > > > ========
> > > >
> > > > This is series #3 in part of a larger work that arose from the minor
> > > > remark that the mdev_parent_ops indirection shim is useless and
> > > > complicates things.
> > > >
> > > > It applies on top of Alex's current tree and requires the prior two
> > > > series.
> > >
> > > Do you have a tree somewhere?
> >
> > [..]
> > > > A preview of the future series's is here:
> > > > https://github.com/jgunthorpe/linux/pull/3/commits
> >
> > Has everything, you'll want to go to:
> > cover-letter: Remove vfio_mdev.c, mdev_parent_ops and more
> >
> > As there are additional WIPs in that tree.
>
> I gave this a quick spin on s390x vfio-ap and it seems to work ok.
> This is really just a quick test, but no obvious problem.
Great! Thanks
Jason
^ permalink raw reply [flat|nested] 27+ messages in thread