Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 's390-5.13-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Vasily Gorbik:
"Fix races in vfio-ccw request handling"

* tag 's390-5.13-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
vfio-ccw: Serialize FSM IDLE state with I/O completion
vfio-ccw: Reset FSM state to IDLE inside FSM
vfio-ccw: Check initialized flag in cp_init()

+15 -4
+4
drivers/s390/cio/vfio_ccw_cp.c
··· 638 638 static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 1); 639 639 int ret; 640 640 641 + /* this is an error in the caller */ 642 + if (cp->initialized) 643 + return -EBUSY; 644 + 641 645 /* 642 646 * We only support prefetching the channel program. We assume all channel 643 647 * programs executed by supported guests likewise support prefetching.
+10 -2
drivers/s390/cio/vfio_ccw_drv.c
··· 86 86 struct vfio_ccw_private *private; 87 87 struct irb *irb; 88 88 bool is_final; 89 + bool cp_is_finished = false; 89 90 90 91 private = container_of(work, struct vfio_ccw_private, io_work); 91 92 irb = &private->irb; ··· 95 94 (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)); 96 95 if (scsw_is_solicited(&irb->scsw)) { 97 96 cp_update_scsw(&private->cp, &irb->scsw); 98 - if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) 97 + if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) { 99 98 cp_free(&private->cp); 99 + cp_is_finished = true; 100 + } 100 101 } 101 102 mutex_lock(&private->io_mutex); 102 103 memcpy(private->io_region->irb_area, irb, sizeof(*irb)); 103 104 mutex_unlock(&private->io_mutex); 104 105 105 - if (private->mdev && is_final) 106 + /* 107 + * Reset to IDLE only if processing of a channel program 108 + * has finished. Do not overwrite a possible processing 109 + * state if the final interrupt was for HSCH or CSCH. 110 + */ 111 + if (private->mdev && cp_is_finished) 106 112 private->state = VFIO_CCW_STATE_IDLE; 107 113 108 114 if (private->io_trigger)
+1
drivers/s390/cio/vfio_ccw_fsm.c
··· 318 318 } 319 319 320 320 err_out: 321 + private->state = VFIO_CCW_STATE_IDLE; 321 322 trace_vfio_ccw_fsm_io_request(scsw->cmd.fctl, schid, 322 323 io_region->ret_code, errstr); 323 324 }
-2
drivers/s390/cio/vfio_ccw_ops.c
··· 279 279 } 280 280 281 281 vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ); 282 - if (region->ret_code != 0) 283 - private->state = VFIO_CCW_STATE_IDLE; 284 282 ret = (region->ret_code != 0) ? region->ret_code : count; 285 283 286 284 out_unlock: