Skip to content

Commit 785d21b

Browse files
committed
Merge tag 'vfio-v6.2-rc1' of https://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Replace deprecated git://github.com link in MAINTAINERS (Palmer Dabbelt) - Simplify vfio/mlx5 with module_pci_driver() helper (Shang XiaoJing) - Drop unnecessary buffer from ACPI call (Rafael Mendonca) - Correct latent missing include issue in iova-bitmap and fix support for unaligned bitmaps. Follow-up with better fix through refactor (Joao Martins) - Rework ccw mdev driver to split private data from parent structure, better aligning with the mdev lifecycle and allowing us to remove a temporary workaround (Eric Farman) - Add an interface to get an estimated migration data size for a device, allowing userspace to make informed decisions, ex. more accurately predicting VM downtime (Yishai Hadas) - Fix minor typo in vfio/mlx5 array declaration (Yishai Hadas) - Simplify module and Kconfig through consolidating SPAPR/EEH code and config options and folding virqfd module into main vfio module (Jason Gunthorpe) - Fix error path from device_register() across all vfio mdev and sample drivers (Alex Williamson) - Define migration pre-copy interface and implement for vfio/mlx5 devices, allowing portions of the device state to be saved while the device continues operation, towards reducing the stop-copy state size (Jason Gunthorpe, Yishai Hadas, Shay Drory) - Implement pre-copy for hisi_acc devices (Shameer Kolothum) - Fixes to mdpy mdev driver remove path and error path on probe (Shang XiaoJing) - vfio/mlx5 fixes for incorrect return after copy_to_user() fault and incorrect buffer freeing (Dan Carpenter) * tag 'vfio-v6.2-rc1' of https://github.com/awilliam/linux-vfio: (42 commits) vfio/mlx5: error pointer dereference in error handling vfio/mlx5: fix error code in mlx5vf_precopy_ioctl() samples: vfio-mdev: Fix missing pci_disable_device() in mdpy_fb_probe() hisi_acc_vfio_pci: Enable PRE_COPY flag hisi_acc_vfio_pci: Move the dev compatibility tests for early check hisi_acc_vfio_pci: Introduce support for PRE_COPY state transitions hisi_acc_vfio_pci: Add support for precopy IOCTL vfio/mlx5: Enable MIGRATION_PRE_COPY flag vfio/mlx5: Fallback to STOP_COPY upon specific PRE_COPY error vfio/mlx5: Introduce multiple loads vfio/mlx5: Consider temporary end of stream as part of PRE_COPY vfio/mlx5: Introduce vfio precopy ioctl implementation vfio/mlx5: Introduce SW headers for migration states vfio/mlx5: Introduce device transitions of PRE_COPY vfio/mlx5: Refactor to use queue based data chunks vfio/mlx5: Refactor migration file state vfio/mlx5: Refactor MKEY usage vfio/mlx5: Refactor PD usage vfio/mlx5: Enforce a single SAVE command at a time vfio: Extend the device migration protocol with PRE_COPY ...
2 parents 8fa590b + 70be6f3 commit 785d21b

34 files changed

+1792
-646
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21781,7 +21781,7 @@ M: Alex Williamson <[email protected]>
2178121781
R: Cornelia Huck <[email protected]>
2178221782
2178321783
S: Maintained
21784-
T: git git://github.com/awilliam/linux-vfio.git
21784+
T: git https://github.com/awilliam/linux-vfio.git
2178521785
F: Documentation/ABI/testing/sysfs-devices-vfio-dev
2178621786
F: Documentation/driver-api/vfio.rst
2178721787
F: drivers/vfio/

drivers/gpu/drm/i915/gvt/kvmgt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1465,7 +1465,6 @@ static void intel_vgpu_release_dev(struct vfio_device *vfio_dev)
14651465
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
14661466

14671467
intel_gvt_destroy_vgpu(vgpu);
1468-
vfio_free_device(vfio_dev);
14691468
}
14701469

14711470
static const struct vfio_device_ops intel_vgpu_dev_ops = {

drivers/s390/cio/vfio_ccw_chp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ static ssize_t vfio_ccw_schib_region_read(struct vfio_ccw_private *private,
1616
char __user *buf, size_t count,
1717
loff_t *ppos)
1818
{
19+
struct subchannel *sch = to_subchannel(private->vdev.dev->parent);
1920
unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS;
2021
loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
2122
struct ccw_schib_region *region;
@@ -27,12 +28,12 @@ static ssize_t vfio_ccw_schib_region_read(struct vfio_ccw_private *private,
2728
mutex_lock(&private->io_mutex);
2829
region = private->region[i].data;
2930

30-
if (cio_update_schib(private->sch)) {
31+
if (cio_update_schib(sch)) {
3132
ret = -ENODEV;
3233
goto out;
3334
}
3435

35-
memcpy(region, &private->sch->schib, sizeof(*region));
36+
memcpy(region, &sch->schib, sizeof(*region));
3637

3738
if (copy_to_user(buf, (void *)region + pos, count)) {
3839
ret = -EFAULT;

drivers/s390/cio/vfio_ccw_drv.c

Lines changed: 74 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
#include "vfio_ccw_private.h"
2424

2525
struct workqueue_struct *vfio_ccw_work_q;
26-
static struct kmem_cache *vfio_ccw_io_region;
27-
static struct kmem_cache *vfio_ccw_cmd_region;
28-
static struct kmem_cache *vfio_ccw_schib_region;
29-
static struct kmem_cache *vfio_ccw_crw_region;
26+
struct kmem_cache *vfio_ccw_io_region;
27+
struct kmem_cache *vfio_ccw_cmd_region;
28+
struct kmem_cache *vfio_ccw_schib_region;
29+
struct kmem_cache *vfio_ccw_crw_region;
3030

3131
debug_info_t *vfio_ccw_debug_msg_id;
3232
debug_info_t *vfio_ccw_debug_trace_id;
@@ -36,10 +36,19 @@ debug_info_t *vfio_ccw_debug_trace_id;
3636
*/
3737
int vfio_ccw_sch_quiesce(struct subchannel *sch)
3838
{
39-
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
39+
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
40+
struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
4041
DECLARE_COMPLETION_ONSTACK(completion);
4142
int iretry, ret = 0;
4243

44+
/*
45+
* Probably an impossible situation, after being called through
46+
* FSM callbacks. But in the event it did, register a warning
47+
* and return as if things were fine.
48+
*/
49+
if (WARN_ON(!private))
50+
return 0;
51+
4352
iretry = 255;
4453
do {
4554

@@ -70,7 +79,7 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch)
7079
return ret;
7180
}
7281

73-
static void vfio_ccw_sch_io_todo(struct work_struct *work)
82+
void vfio_ccw_sch_io_todo(struct work_struct *work)
7483
{
7584
struct vfio_ccw_private *private;
7685
struct irb *irb;
@@ -106,7 +115,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
106115
eventfd_signal(private->io_trigger, 1);
107116
}
108117

109-
static void vfio_ccw_crw_todo(struct work_struct *work)
118+
void vfio_ccw_crw_todo(struct work_struct *work)
110119
{
111120
struct vfio_ccw_private *private;
112121

@@ -121,90 +130,39 @@ static void vfio_ccw_crw_todo(struct work_struct *work)
121130
*/
122131
static void vfio_ccw_sch_irq(struct subchannel *sch)
123132
{
124-
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
133+
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
134+
struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
135+
136+
/*
137+
* The subchannel should still be disabled at this point,
138+
* so an interrupt would be quite surprising. As with an
139+
* interrupt while the FSM is closed, let's attempt to
140+
* disable the subchannel again.
141+
*/
142+
if (!private) {
143+
VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: unexpected interrupt\n",
144+
sch->schid.cssid, sch->schid.ssid,
145+
sch->schid.sch_no);
146+
147+
cio_disable_subchannel(sch);
148+
return;
149+
}
125150

126151
inc_irq_stat(IRQIO_CIO);
127152
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
128153
}
129154

130-
static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch)
155+
static void vfio_ccw_free_parent(struct device *dev)
131156
{
132-
struct vfio_ccw_private *private;
157+
struct vfio_ccw_parent *parent = container_of(dev, struct vfio_ccw_parent, dev);
133158

134-
private = kzalloc(sizeof(*private), GFP_KERNEL);
135-
if (!private)
136-
return ERR_PTR(-ENOMEM);
137-
138-
private->sch = sch;
139-
mutex_init(&private->io_mutex);
140-
private->state = VFIO_CCW_STATE_STANDBY;
141-
INIT_LIST_HEAD(&private->crw);
142-
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
143-
INIT_WORK(&private->crw_work, vfio_ccw_crw_todo);
144-
145-
private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
146-
GFP_KERNEL);
147-
if (!private->cp.guest_cp)
148-
goto out_free_private;
149-
150-
private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
151-
GFP_KERNEL | GFP_DMA);
152-
if (!private->io_region)
153-
goto out_free_cp;
154-
155-
private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region,
156-
GFP_KERNEL | GFP_DMA);
157-
if (!private->cmd_region)
158-
goto out_free_io;
159-
160-
private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region,
161-
GFP_KERNEL | GFP_DMA);
162-
163-
if (!private->schib_region)
164-
goto out_free_cmd;
165-
166-
private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region,
167-
GFP_KERNEL | GFP_DMA);
168-
169-
if (!private->crw_region)
170-
goto out_free_schib;
171-
return private;
172-
173-
out_free_schib:
174-
kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
175-
out_free_cmd:
176-
kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
177-
out_free_io:
178-
kmem_cache_free(vfio_ccw_io_region, private->io_region);
179-
out_free_cp:
180-
kfree(private->cp.guest_cp);
181-
out_free_private:
182-
mutex_destroy(&private->io_mutex);
183-
kfree(private);
184-
return ERR_PTR(-ENOMEM);
159+
kfree(parent);
185160
}
186161

187-
static void vfio_ccw_free_private(struct vfio_ccw_private *private)
188-
{
189-
struct vfio_ccw_crw *crw, *temp;
190-
191-
list_for_each_entry_safe(crw, temp, &private->crw, next) {
192-
list_del(&crw->next);
193-
kfree(crw);
194-
}
195-
196-
kmem_cache_free(vfio_ccw_crw_region, private->crw_region);
197-
kmem_cache_free(vfio_ccw_schib_region, private->schib_region);
198-
kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
199-
kmem_cache_free(vfio_ccw_io_region, private->io_region);
200-
kfree(private->cp.guest_cp);
201-
mutex_destroy(&private->io_mutex);
202-
kfree(private);
203-
}
204162
static int vfio_ccw_sch_probe(struct subchannel *sch)
205163
{
206164
struct pmcw *pmcw = &sch->schib.pmcw;
207-
struct vfio_ccw_private *private;
165+
struct vfio_ccw_parent *parent;
208166
int ret = -ENOMEM;
209167

210168
if (pmcw->qf) {
@@ -213,50 +171,62 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
213171
return -ENODEV;
214172
}
215173

216-
private = vfio_ccw_alloc_private(sch);
217-
if (IS_ERR(private))
218-
return PTR_ERR(private);
174+
parent = kzalloc(sizeof(*parent), GFP_KERNEL);
175+
if (!parent)
176+
return -ENOMEM;
177+
178+
dev_set_name(&parent->dev, "parent");
179+
parent->dev.parent = &sch->dev;
180+
parent->dev.release = &vfio_ccw_free_parent;
181+
ret = device_register(&parent->dev);
182+
if (ret)
183+
goto out_free;
219184

220-
dev_set_drvdata(&sch->dev, private);
185+
dev_set_drvdata(&sch->dev, parent);
221186

222-
private->mdev_type.sysfs_name = "io";
223-
private->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
224-
private->mdev_types[0] = &private->mdev_type;
225-
ret = mdev_register_parent(&private->parent, &sch->dev,
187+
parent->mdev_type.sysfs_name = "io";
188+
parent->mdev_type.pretty_name = "I/O subchannel (Non-QDIO)";
189+
parent->mdev_types[0] = &parent->mdev_type;
190+
ret = mdev_register_parent(&parent->parent, &sch->dev,
226191
&vfio_ccw_mdev_driver,
227-
private->mdev_types, 1);
192+
parent->mdev_types, 1);
228193
if (ret)
229-
goto out_free;
194+
goto out_unreg;
230195

231196
VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n",
232197
sch->schid.cssid, sch->schid.ssid,
233198
sch->schid.sch_no);
234199
return 0;
235200

201+
out_unreg:
202+
device_del(&parent->dev);
236203
out_free:
204+
put_device(&parent->dev);
237205
dev_set_drvdata(&sch->dev, NULL);
238-
vfio_ccw_free_private(private);
239206
return ret;
240207
}
241208

242209
static void vfio_ccw_sch_remove(struct subchannel *sch)
243210
{
244-
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
211+
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
245212

246-
mdev_unregister_parent(&private->parent);
213+
mdev_unregister_parent(&parent->parent);
247214

215+
device_unregister(&parent->dev);
248216
dev_set_drvdata(&sch->dev, NULL);
249217

250-
vfio_ccw_free_private(private);
251-
252218
VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n",
253219
sch->schid.cssid, sch->schid.ssid,
254220
sch->schid.sch_no);
255221
}
256222

257223
static void vfio_ccw_sch_shutdown(struct subchannel *sch)
258224
{
259-
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
225+
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
226+
struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
227+
228+
if (WARN_ON(!private))
229+
return;
260230

261231
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
262232
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
@@ -274,7 +244,8 @@ static void vfio_ccw_sch_shutdown(struct subchannel *sch)
274244
*/
275245
static int vfio_ccw_sch_event(struct subchannel *sch, int process)
276246
{
277-
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
247+
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
248+
struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
278249
unsigned long flags;
279250
int rc = -EAGAIN;
280251

@@ -287,8 +258,10 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process)
287258

288259
rc = 0;
289260

290-
if (cio_update_schib(sch))
291-
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
261+
if (cio_update_schib(sch)) {
262+
if (private)
263+
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
264+
}
292265

293266
out_unlock:
294267
spin_unlock_irqrestore(sch->lock, flags);
@@ -326,14 +299,15 @@ static void vfio_ccw_queue_crw(struct vfio_ccw_private *private,
326299
static int vfio_ccw_chp_event(struct subchannel *sch,
327300
struct chp_link *link, int event)
328301
{
329-
struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
302+
struct vfio_ccw_parent *parent = dev_get_drvdata(&sch->dev);
303+
struct vfio_ccw_private *private = dev_get_drvdata(&parent->dev);
330304
int mask = chp_ssd_get_mask(&sch->ssd_info, link);
331305
int retry = 255;
332306

333307
if (!private || !mask)
334308
return 0;
335309

336-
trace_vfio_ccw_chp_event(private->sch->schid, mask, event);
310+
trace_vfio_ccw_chp_event(sch->schid, mask, event);
337311
VFIO_CCW_MSG_EVENT(2, "sch %x.%x.%04x: mask=0x%x event=%d\n",
338312
sch->schid.cssid,
339313
sch->schid.ssid, sch->schid.sch_no,

0 commit comments

Comments
 (0)