123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Adjunct processor matrix VFIO device driver callbacks.
- *
- * Copyright IBM Corp. 2018
- *
- * Author(s): Tony Krowiak <akrowiak@linux.ibm.com>
- * Halil Pasic <pasic@linux.ibm.com>
- * Pierre Morel <pmorel@linux.ibm.com>
- */
- #include <linux/string.h>
- #include <linux/vfio.h>
- #include <linux/device.h>
- #include <linux/list.h>
- #include <linux/ctype.h>
- #include <asm/zcrypt.h>
- #include "vfio_ap_private.h"
- #define VFIO_AP_MDEV_TYPE_HWVIRT "passthrough"
- #define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device"
- static void vfio_ap_matrix_init(struct ap_config_info *info,
- struct ap_matrix *matrix)
- {
- matrix->apm_max = info->apxa ? info->Na : 63;
- matrix->aqm_max = info->apxa ? info->Nd : 15;
- matrix->adm_max = info->apxa ? info->Nd : 15;
- }
- static int vfio_ap_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
- {
- struct ap_matrix_mdev *matrix_mdev;
- 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;
- }
- vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->matrix);
- mdev_set_drvdata(mdev, matrix_mdev);
- mutex_lock(&matrix_dev->lock);
- list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
- mutex_unlock(&matrix_dev->lock);
- return 0;
- }
- static int vfio_ap_mdev_remove(struct mdev_device *mdev)
- {
- struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev);
- mutex_lock(&matrix_dev->lock);
- 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 kobject *kobj, struct device *dev, char *buf)
- {
- return sprintf(buf, "%s\n", VFIO_AP_MDEV_NAME_HWVIRT);
- }
- MDEV_TYPE_ATTR_RO(name);
- static ssize_t available_instances_show(struct kobject *kobj,
- struct device *dev, char *buf)
- {
- return sprintf(buf, "%d\n",
- atomic_read(&matrix_dev->available_instances));
- }
- MDEV_TYPE_ATTR_RO(available_instances);
- static ssize_t device_api_show(struct kobject *kobj, struct device *dev,
- char *buf)
- {
- return sprintf(buf, "%s\n", VFIO_DEVICE_API_AP_STRING);
- }
- MDEV_TYPE_ATTR_RO(device_api);
- static struct attribute *vfio_ap_mdev_type_attrs[] = {
- &mdev_type_attr_name.attr,
- &mdev_type_attr_device_api.attr,
- &mdev_type_attr_available_instances.attr,
- NULL,
- };
- static struct attribute_group vfio_ap_mdev_hwvirt_type_group = {
- .name = VFIO_AP_MDEV_TYPE_HWVIRT,
- .attrs = vfio_ap_mdev_type_attrs,
- };
- static struct attribute_group *vfio_ap_mdev_type_groups[] = {
- &vfio_ap_mdev_hwvirt_type_group,
- NULL,
- };
- static const struct mdev_parent_ops vfio_ap_matrix_ops = {
- .owner = THIS_MODULE,
- .supported_type_groups = vfio_ap_mdev_type_groups,
- .create = vfio_ap_mdev_create,
- .remove = vfio_ap_mdev_remove,
- };
- int vfio_ap_mdev_register(void)
- {
- atomic_set(&matrix_dev->available_instances, MAX_ZDEV_ENTRIES_EXT);
- return mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_ops);
- }
- void vfio_ap_mdev_unregister(void)
- {
- mdev_unregister_device(&matrix_dev->device);
- }
|