On Mon, 1 Jul 2019 12:23:46 -0400 Farhan Ali <alifm@xxxxxxxxxxxxx> wrote: > There is a small window where it's possible that we could be working > on an interrupt (queued in the workqueue) and setting up a channel > program (i.e allocating memory, pinning pages, translating address). > This can lead to allocating and freeing the channel program at the > same time and can cause memory corruption. This can only happen if the interrupt is for a halt/clear operation, right? > > Let's not call cp_free if we are currently processing a channel program. > The only way we know for sure that we don't have a thread setting > up a channel program is when the state is set to VFIO_CCW_STATE_CP_PENDING. I have looked through the code again and I think you are right. > > Signed-off-by: Farhan Ali <alifm@xxxxxxxxxxxxx> > --- > drivers/s390/cio/vfio_ccw_drv.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c > index 4e3a903..0357165 100644 > --- a/drivers/s390/cio/vfio_ccw_drv.c > +++ b/drivers/s390/cio/vfio_ccw_drv.c > @@ -92,7 +92,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) > (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)); > if (scsw_is_solicited(&irb->scsw)) { > cp_update_scsw(&private->cp, &irb->scsw); > - if (is_final) > + if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) Do we actually want to call cp_update_scsw() unconditionally? At this point, we know that we have a solicited interrupt; that may be for several reasons: - Interrupt for something we issued via ssch; it makes sense to update the scsw with the cpa address. - Interrupt for a csch; the cpa address will be unpredictable, even if we did a ssch before. cp_update_scsw() hopefully can deal with that? Given that its purpose is to translate the cpa back, any unpredictable value in the scsw should be fine in the end. - Interrupt for a hsch after we did a ssch; the cpa might be valid (see figure 16-6). - Interrupt for a hsch without a prior ssch; we'll end up with an unpredictable cpa, again. So I *think* we're fine with calling cp_update_scsw() in all cases, even if there's junk in the cpa of the scsw we get from the hardware. Opinions? > cp_free(&private->cp); > } > mutex_lock(&private->io_mutex);