Linux 5.1.15
[linux/fpc-iii.git] / drivers / s390 / crypto / vfio_ap_drv.c
blobe9824c35c34f789de7404e52dc0a48e04080fd9c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * VFIO based AP device driver
5 * Copyright IBM Corp. 2018
7 * Author(s): Tony Krowiak <akrowiak@linux.ibm.com>
8 */
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14 #include <asm/facility.h>
15 #include "vfio_ap_private.h"
17 #define VFIO_AP_ROOT_NAME "vfio_ap"
18 #define VFIO_AP_DEV_NAME "matrix"
20 MODULE_AUTHOR("IBM Corporation");
21 MODULE_DESCRIPTION("VFIO AP device driver, Copyright IBM Corp. 2018");
22 MODULE_LICENSE("GPL v2");
24 static struct ap_driver vfio_ap_drv;
26 struct ap_matrix_dev *matrix_dev;
28 /* Only type 10 adapters (CEX4 and later) are supported
29 * by the AP matrix device driver
31 static struct ap_device_id ap_queue_ids[] = {
32 { .dev_type = AP_DEVICE_TYPE_CEX4,
33 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
34 { .dev_type = AP_DEVICE_TYPE_CEX5,
35 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
36 { .dev_type = AP_DEVICE_TYPE_CEX6,
37 .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
38 { /* end of sibling */ },
41 MODULE_DEVICE_TABLE(vfio_ap, ap_queue_ids);
43 static int vfio_ap_queue_dev_probe(struct ap_device *apdev)
45 return 0;
48 static void vfio_ap_queue_dev_remove(struct ap_device *apdev)
50 /* Nothing to do yet */
53 static void vfio_ap_matrix_dev_release(struct device *dev)
55 struct ap_matrix_dev *matrix_dev = dev_get_drvdata(dev);
57 kfree(matrix_dev);
60 static int matrix_bus_match(struct device *dev, struct device_driver *drv)
62 return 1;
65 static struct bus_type matrix_bus = {
66 .name = "matrix",
67 .match = &matrix_bus_match,
70 static struct device_driver matrix_driver = {
71 .name = "vfio_ap",
72 .bus = &matrix_bus,
73 .suppress_bind_attrs = true,
76 static int vfio_ap_matrix_dev_create(void)
78 int ret;
79 struct device *root_device;
81 root_device = root_device_register(VFIO_AP_ROOT_NAME);
82 if (IS_ERR(root_device))
83 return PTR_ERR(root_device);
85 ret = bus_register(&matrix_bus);
86 if (ret)
87 goto bus_register_err;
89 matrix_dev = kzalloc(sizeof(*matrix_dev), GFP_KERNEL);
90 if (!matrix_dev) {
91 ret = -ENOMEM;
92 goto matrix_alloc_err;
95 /* Fill in config info via PQAP(QCI), if available */
96 if (test_facility(12)) {
97 ret = ap_qci(&matrix_dev->info);
98 if (ret)
99 goto matrix_alloc_err;
102 mutex_init(&matrix_dev->lock);
103 INIT_LIST_HEAD(&matrix_dev->mdev_list);
105 dev_set_name(&matrix_dev->device, "%s", VFIO_AP_DEV_NAME);
106 matrix_dev->device.parent = root_device;
107 matrix_dev->device.bus = &matrix_bus;
108 matrix_dev->device.release = vfio_ap_matrix_dev_release;
109 matrix_dev->vfio_ap_drv = &vfio_ap_drv;
111 ret = device_register(&matrix_dev->device);
112 if (ret)
113 goto matrix_reg_err;
115 ret = driver_register(&matrix_driver);
116 if (ret)
117 goto matrix_drv_err;
119 return 0;
121 matrix_drv_err:
122 device_unregister(&matrix_dev->device);
123 matrix_reg_err:
124 put_device(&matrix_dev->device);
125 matrix_alloc_err:
126 bus_unregister(&matrix_bus);
127 bus_register_err:
128 root_device_unregister(root_device);
129 return ret;
132 static void vfio_ap_matrix_dev_destroy(void)
134 struct device *root_device = matrix_dev->device.parent;
136 driver_unregister(&matrix_driver);
137 device_unregister(&matrix_dev->device);
138 bus_unregister(&matrix_bus);
139 root_device_unregister(root_device);
142 static int __init vfio_ap_init(void)
144 int ret;
146 /* If there are no AP instructions, there is nothing to pass through. */
147 if (!ap_instructions_available())
148 return -ENODEV;
150 ret = vfio_ap_matrix_dev_create();
151 if (ret)
152 return ret;
154 memset(&vfio_ap_drv, 0, sizeof(vfio_ap_drv));
155 vfio_ap_drv.probe = vfio_ap_queue_dev_probe;
156 vfio_ap_drv.remove = vfio_ap_queue_dev_remove;
157 vfio_ap_drv.ids = ap_queue_ids;
159 ret = ap_driver_register(&vfio_ap_drv, THIS_MODULE, VFIO_AP_DRV_NAME);
160 if (ret) {
161 vfio_ap_matrix_dev_destroy();
162 return ret;
165 ret = vfio_ap_mdev_register();
166 if (ret) {
167 ap_driver_unregister(&vfio_ap_drv);
168 vfio_ap_matrix_dev_destroy();
170 return ret;
173 return 0;
176 static void __exit vfio_ap_exit(void)
178 vfio_ap_mdev_unregister();
179 ap_driver_unregister(&vfio_ap_drv);
180 vfio_ap_matrix_dev_destroy();
183 module_init(vfio_ap_init);
184 module_exit(vfio_ap_exit);