GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / s390 / cio / vfio_ccw_drv.c
1 /*
2  * VFIO based Physical Subchannel device driver
3  *
4  * Copyright IBM Corp. 2017
5  *
6  * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
7  *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
8  */
9
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/device.h>
13 #include <linux/slab.h>
14 #include <linux/uuid.h>
15 #include <linux/mdev.h>
16
17 #include <asm/isc.h>
18
19 #include "ioasm.h"
20 #include "css.h"
21 #include "vfio_ccw_private.h"
22
23 struct workqueue_struct *vfio_ccw_work_q;
24
25 /*
26  * Helpers
27  */
28 int vfio_ccw_sch_quiesce(struct subchannel *sch)
29 {
30         struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
31         DECLARE_COMPLETION_ONSTACK(completion);
32         int iretry, ret = 0;
33
34         spin_lock_irq(sch->lock);
35         if (!sch->schib.pmcw.ena)
36                 goto out_unlock;
37         ret = cio_disable_subchannel(sch);
38         if (ret != -EBUSY)
39                 goto out_unlock;
40
41         iretry = 255;
42         do {
43
44                 ret = cio_cancel_halt_clear(sch, &iretry);
45
46                 if (ret == -EIO) {
47                         pr_err("vfio_ccw: could not quiesce subchannel 0.%x.%04x!\n",
48                                sch->schid.ssid, sch->schid.sch_no);
49                         break;
50                 }
51
52                 /*
53                  * Flush all I/O and wait for
54                  * cancel/halt/clear completion.
55                  */
56                 private->completion = &completion;
57                 spin_unlock_irq(sch->lock);
58
59                 if (ret == -EBUSY)
60                         wait_for_completion_timeout(&completion, 3*HZ);
61
62                 private->completion = NULL;
63                 flush_workqueue(vfio_ccw_work_q);
64                 spin_lock_irq(sch->lock);
65                 ret = cio_disable_subchannel(sch);
66         } while (ret == -EBUSY);
67 out_unlock:
68         private->state = VFIO_CCW_STATE_NOT_OPER;
69         spin_unlock_irq(sch->lock);
70         return ret;
71 }
72
73 static void vfio_ccw_sch_io_todo(struct work_struct *work)
74 {
75         struct vfio_ccw_private *private;
76         struct irb *irb;
77         bool is_final;
78
79         private = container_of(work, struct vfio_ccw_private, io_work);
80         irb = &private->irb;
81
82         is_final = !(scsw_actl(&irb->scsw) &
83                      (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT));
84         if (scsw_is_solicited(&irb->scsw)) {
85                 cp_update_scsw(&private->cp, &irb->scsw);
86                 if (is_final)
87                         cp_free(&private->cp);
88         }
89         memcpy(private->io_region.irb_area, irb, sizeof(*irb));
90
91         if (private->io_trigger)
92                 eventfd_signal(private->io_trigger, 1);
93
94         if (private->mdev && is_final)
95                 private->state = VFIO_CCW_STATE_IDLE;
96 }
97
98 /*
99  * Css driver callbacks
100  */
101 static void vfio_ccw_sch_irq(struct subchannel *sch)
102 {
103         struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
104
105         inc_irq_stat(IRQIO_CIO);
106         vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
107 }
108
109 static int vfio_ccw_sch_probe(struct subchannel *sch)
110 {
111         struct pmcw *pmcw = &sch->schib.pmcw;
112         struct vfio_ccw_private *private;
113         int ret;
114
115         if (pmcw->qf) {
116                 dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n",
117                          dev_name(&sch->dev));
118                 return -ENODEV;
119         }
120
121         private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
122         if (!private)
123                 return -ENOMEM;
124         private->sch = sch;
125         dev_set_drvdata(&sch->dev, private);
126
127         spin_lock_irq(sch->lock);
128         private->state = VFIO_CCW_STATE_NOT_OPER;
129         sch->isc = VFIO_CCW_ISC;
130         ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
131         spin_unlock_irq(sch->lock);
132         if (ret)
133                 goto out_free;
134
135         ret = vfio_ccw_mdev_reg(sch);
136         if (ret)
137                 goto out_disable;
138
139         INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
140         atomic_set(&private->avail, 1);
141         private->state = VFIO_CCW_STATE_STANDBY;
142
143         return 0;
144
145 out_disable:
146         cio_disable_subchannel(sch);
147 out_free:
148         dev_set_drvdata(&sch->dev, NULL);
149         kfree(private);
150         return ret;
151 }
152
153 static int vfio_ccw_sch_remove(struct subchannel *sch)
154 {
155         struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
156
157         vfio_ccw_sch_quiesce(sch);
158
159         vfio_ccw_mdev_unreg(sch);
160
161         dev_set_drvdata(&sch->dev, NULL);
162
163         kfree(private);
164
165         return 0;
166 }
167
168 static void vfio_ccw_sch_shutdown(struct subchannel *sch)
169 {
170         vfio_ccw_sch_quiesce(sch);
171 }
172
173 /**
174  * vfio_ccw_sch_event - process subchannel event
175  * @sch: subchannel
176  * @process: non-zero if function is called in process context
177  *
178  * An unspecified event occurred for this subchannel. Adjust data according
179  * to the current operational state of the subchannel. Return zero when the
180  * event has been handled sufficiently or -EAGAIN when this function should
181  * be called again in process context.
182  */
183 static int vfio_ccw_sch_event(struct subchannel *sch, int process)
184 {
185         struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
186         unsigned long flags;
187         int rc = -EAGAIN;
188
189         spin_lock_irqsave(sch->lock, flags);
190         if (!device_is_registered(&sch->dev))
191                 goto out_unlock;
192
193         if (work_pending(&sch->todo_work))
194                 goto out_unlock;
195
196         if (cio_update_schib(sch)) {
197                 vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
198                 rc = 0;
199                 goto out_unlock;
200         }
201
202         private = dev_get_drvdata(&sch->dev);
203         if (private->state == VFIO_CCW_STATE_NOT_OPER) {
204                 private->state = private->mdev ? VFIO_CCW_STATE_IDLE :
205                                  VFIO_CCW_STATE_STANDBY;
206         }
207         rc = 0;
208
209 out_unlock:
210         spin_unlock_irqrestore(sch->lock, flags);
211
212         return rc;
213 }
214
215 static struct css_device_id vfio_ccw_sch_ids[] = {
216         { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
217         { /* end of list */ },
218 };
219 MODULE_DEVICE_TABLE(css, vfio_ccw_sch_ids);
220
221 static struct css_driver vfio_ccw_sch_driver = {
222         .drv = {
223                 .name = "vfio_ccw",
224                 .owner = THIS_MODULE,
225         },
226         .subchannel_type = vfio_ccw_sch_ids,
227         .irq = vfio_ccw_sch_irq,
228         .probe = vfio_ccw_sch_probe,
229         .remove = vfio_ccw_sch_remove,
230         .shutdown = vfio_ccw_sch_shutdown,
231         .sch_event = vfio_ccw_sch_event,
232 };
233
234 static int __init vfio_ccw_sch_init(void)
235 {
236         int ret;
237
238         vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw");
239         if (!vfio_ccw_work_q)
240                 return -ENOMEM;
241
242         isc_register(VFIO_CCW_ISC);
243         ret = css_driver_register(&vfio_ccw_sch_driver);
244         if (ret) {
245                 isc_unregister(VFIO_CCW_ISC);
246                 destroy_workqueue(vfio_ccw_work_q);
247         }
248
249         return ret;
250 }
251
252 static void __exit vfio_ccw_sch_exit(void)
253 {
254         css_driver_unregister(&vfio_ccw_sch_driver);
255         isc_unregister(VFIO_CCW_ISC);
256         destroy_workqueue(vfio_ccw_work_q);
257 }
258 module_init(vfio_ccw_sch_init);
259 module_exit(vfio_ccw_sch_exit);
260
261 MODULE_LICENSE("GPL v2");