On Thu, 26 Jul 2018 21:54:16 +0200 Christian Borntraeger <borntraeger@xxxxxxxxxx> wrote: > From: Tony Krowiak <akrowiak@xxxxxxxxxxxxx> > > Registers the matrix device created by the VFIO AP device > driver with the VFIO mediated device framework. > Registering the matrix device will create the sysfs > structures needed to create mediated matrix devices > each of which will be used to configure the AP matrix > for a guest and connect it to the VFIO AP device driver. > > Registering the matrix device with the VFIO mediated device > framework will create the following sysfs structures: > > /sys/devices/vfio_ap I think you need to update this to point to the new location. > ... [matrix] > ...... [mdev_supported_types] > ......... [vfio_ap-passthrough] > ............ create > > To create a mediated device for the AP matrix device, write a UUID > to the create file: > > uuidgen > create > > A symbolic link to the mediated device's directory will be created in the > devices subdirectory named after the generated $uuid: > > /sys/devices/vfio_ap > ... [matrix] > ...... [mdev_supported_types] > ......... [vfio_ap-passthrough] > ............ [devices] > ............... [$uuid] > > Signed-off-by: Tony Krowiak <akrowiak@xxxxxxxxxxxxx> > Reviewed-by: Halil Pasic <pasic@xxxxxxxxxxxxx> > Tested-by: Michael Mueller <mimu@xxxxxxxxxxxxx> > Tested-by: Farhan Ali <alifm@xxxxxxxxxxxxx> > Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx> > --- > MAINTAINERS | 1 + > drivers/s390/crypto/Makefile | 2 +- > drivers/s390/crypto/vfio_ap_drv.c | 27 +++++- > drivers/s390/crypto/vfio_ap_ops.c | 121 ++++++++++++++++++++++++++ > drivers/s390/crypto/vfio_ap_private.h | 46 ++++++++++ > 5 files changed, 195 insertions(+), 2 deletions(-) > create mode 100644 drivers/s390/crypto/vfio_ap_ops.c > > diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c > index ff2b05d2aef1..25636e6bf893 100644 > --- a/drivers/s390/crypto/vfio_ap_drv.c > +++ b/drivers/s390/crypto/vfio_ap_drv.c > @@ -9,6 +9,7 @@ > #include <linux/mod_devicetable.h> > #include <linux/slab.h> > #include <linux/string.h> > +#include <asm/zcrypt.h> > #include "vfio_ap_private.h" > > #define VFIO_AP_ROOT_NAME "vfio_ap" > @@ -33,7 +34,7 @@ struct ap_matrix_dev matrix_dev = { > .misc_dev = { > MISC_DYNAMIC_MINOR, > VFIO_AP_DEV_NAME, > - } > + }, Should go into previous patch? > }; > > /* Only type 10 adapters (CEX4 and later) are supported > @@ -65,6 +66,21 @@ static int vfio_ap_matrix_dev_create(void) > { > int ret; > > + mutex_init(&matrix_dev.lock); > + INIT_LIST_HEAD(&matrix_dev.mdev_list); > + > + /* Test if PQAP(QCI) instruction is available */ > + if (test_facility(12)) { > + ret = ap_qci(&matrix_dev.info); > + if (ret && (ret != -EOPNOTSUPP)) { So, is facility 12 a pre-req for PQAP(QCI)? Can the code work if matrix_dev.info is not populated? > + vfio_ap_mdev_unregister(); > + > + return ret; > + } > + } > + > + atomic_set(&matrix_dev.available_instances, MAX_ZDEV_ENTRIES_EXT); > + > ret = misc_register(&matrix_dev.misc_dev); > if (ret) > return ret; > @@ -99,11 +115,20 @@ int __init vfio_ap_init(void) > return ret; > } > > + ret = vfio_ap_mdev_register(); > + if (ret) { > + ap_driver_unregister(&vfio_ap_drv); > + vfio_ap_matrix_dev_destroy(); > + > + return ret; > + } > + > return 0; > } > > void __exit vfio_ap_exit(void) > { > + vfio_ap_mdev_unregister(); > ap_driver_unregister(&vfio_ap_drv); > vfio_ap_matrix_dev_destroy(); > } > diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c > new file mode 100644 > index 000000000000..e4e8d738a043 > --- /dev/null > +++ b/drivers/s390/crypto/vfio_ap_ops.c > @@ -0,0 +1,121 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Adjunct processor matrix VFIO device driver callbacks. > + * > + * Copyright IBM Corp. 2018 > + */ > +#include <linux/string.h> > +#include <linux/vfio.h> > +#include <linux/device.h> > +#include <linux/list.h> > +#include <linux/ctype.h> > + > +#include "vfio_ap_private.h" > + > +#define VFOP_AP_MDEV_TYPE_HWVIRT "passthrough" typo ^^^^ > +#define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device" (...) > diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h > index 02c878cbd011..c2fd4a3e0ae3 100644 > --- a/drivers/s390/crypto/vfio_ap_private.h > +++ b/drivers/s390/crypto/vfio_ap_private.h > @@ -10,6 +10,10 @@ > > #include <linux/types.h> > #include <linux/miscdevice.h> > +#include <linux/device.h> > +#include <linux/mdev.h> > +#include <linux/delay.h> > +#include <linux/mutex.h> > > #include "ap_bus.h" > > @@ -18,13 +22,55 @@ > > struct ap_matrix_dev { > struct miscdevice misc_dev; > + atomic_t available_instances; > + struct ap_config_info info; > + struct list_head mdev_list; > + struct mutex lock; > }; > > +/** > + * Lockin strategy: take the matix_dev.lock mutex each time we fiddle s/Lockin/Locking/ > + * with state managed by the vfio_ap driver (be it using the > + * mdev_list or be it readin or writing the state of a single s/readin/reading/ > + * ap_matrix_mdev device). It's quite coarse but we don't expect > + * much contention. > + */ > extern struct ap_matrix_dev matrix_dev; > > +/** > + * The AP matrix is comprised of three bit masks identifying the adapters, > + * queues (domains) and control domains that belong to an AP matrix. The bits i s/i/in/ > + * each mask, from least significant to most significant bit, correspond to IDs > + * 0 to 255. When a bit is set, the corresponding ID belongs to the matrix. > + * > + * @apm_max: max adapter number in @apm > + * @apm identifies the AP adapters in the matrix > + * @aqm_max: max domain number in @aqm > + * @aqm identifies the AP queues (domains) in the matrix > + * @adm_max: max domain number in @adm > + * @adm identifies the AP control domains in the matrix > + */ > +struct ap_matrix { > + unsigned long apm_max; > + DECLARE_BITMAP(apm, 256); > + unsigned long aqm_max; > + DECLARE_BITMAP(aqm, 256); > + unsigned long adm_max; > + DECLARE_BITMAP(adm, 256); > +}; > + > +struct ap_matrix_mdev { > + const char *name; > + struct list_head list; > + struct ap_matrix matrix; > +}; > + > static inline struct device *to_device(struct ap_matrix_dev *matrix_dev) > { > return matrix_dev->misc_dev.this_device; > } > > +extern int vfio_ap_mdev_register(void); > +extern void vfio_ap_mdev_unregister(void); > + > #endif /* _VFIO_AP_PRIVATE_H_ */