diff mbox series

[SRU,Bionic,1/1] s390/qdio: clear intparm during shutdown

Message ID 1557416191-21935-2-git-send-email-frank.heimes@canonical.com
State New
Headers show
Series [SRU,Bionic,1/1] s390/qdio: clear intparm during shutdown | expand

Commit Message

Frank Heimes May 9, 2019, 3:36 p.m. UTC
From: Julian Wiedmann <jwi@linux.vnet.ibm.com>

BugLink: https://bugs.launchpad.net/bugs/1828394

During shutdown, qdio returns its ccw device back to control by the
upper-layer driver. But there is a remote chance that by the time where the
IRQ handler gets switched back, the interrupt for the preceding
ccw_device_{clear,halt} hasn't been presented yet.
Upper-layer drivers would then need to handle this IRQ - and since the IO
is issued with an intparm, it could very well be confused with whatever
intparm mechanism the driver uses itself (eg intparm == request address).

So when switching over the IRQ handler, also clear the intparm and have
upper-layer drivers deal with any such delayed interrupt as if it was
unsolicited.

Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
(cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa)
Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
---
 drivers/s390/cio/qdio_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Connor Kuehl May 10, 2019, 4:18 p.m. UTC | #1
On 5/9/19 8:36 AM, frank.heimes@canonical.com wrote:
> From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1828394
> 
> During shutdown, qdio returns its ccw device back to control by the
> upper-layer driver. But there is a remote chance that by the time where the
> IRQ handler gets switched back, the interrupt for the preceding
> ccw_device_{clear,halt} hasn't been presented yet.
> Upper-layer drivers would then need to handle this IRQ - and since the IO
> is issued with an intparm, it could very well be confused with whatever
> intparm mechanism the driver uses itself (eg intparm == request address).
> 
> So when switching over the IRQ handler, also clear the intparm and have
> upper-layer drivers deal with any such delayed interrupt as if it was
> unsolicited.
> 
> Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
> Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
> (cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa)
> Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
> ---

Nicely documented description of the problem.

Acked-by: Connor Kuehl <connor.kuehl@canonical.com>

>  drivers/s390/cio/qdio_main.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
> index d76df58..8842be6 100644
> --- a/drivers/s390/cio/qdio_main.c
> +++ b/drivers/s390/cio/qdio_main.c
> @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
>  	qdio_shutdown_thinint(irq_ptr);
>  
>  	/* restore interrupt handler */
> -	if ((void *)cdev->handler == (void *)qdio_int_handler)
> +	if ((void *)cdev->handler == (void *)qdio_int_handler) {
>  		cdev->handler = irq_ptr->orig_handler;
> +		cdev->private->intparm = 0;
> +	}
>  	spin_unlock_irq(get_ccwdev_lock(cdev));
>  
>  	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
>
Kleber Sacilotto de Souza May 13, 2019, 1:53 p.m. UTC | #2
On 5/9/19 5:36 PM, frank.heimes@canonical.com wrote:
> From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1828394
> 
> During shutdown, qdio returns its ccw device back to control by the
> upper-layer driver. But there is a remote chance that by the time where the
> IRQ handler gets switched back, the interrupt for the preceding
> ccw_device_{clear,halt} hasn't been presented yet.
> Upper-layer drivers would then need to handle this IRQ - and since the IO
> is issued with an intparm, it could very well be confused with whatever
> intparm mechanism the driver uses itself (eg intparm == request address).
> 
> So when switching over the IRQ handler, also clear the intparm and have
> upper-layer drivers deal with any such delayed interrupt as if it was
> unsolicited.
> 
> Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
> Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
> (cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa)
> Signed-off-by: Frank Heimes <frank.heimes@canonical.com>

Clean cherry-pick, limited to platform specific driver.

Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>

> ---
>  drivers/s390/cio/qdio_main.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
> index d76df58..8842be6 100644
> --- a/drivers/s390/cio/qdio_main.c
> +++ b/drivers/s390/cio/qdio_main.c
> @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
>  	qdio_shutdown_thinint(irq_ptr);
>  
>  	/* restore interrupt handler */
> -	if ((void *)cdev->handler == (void *)qdio_int_handler)
> +	if ((void *)cdev->handler == (void *)qdio_int_handler) {
>  		cdev->handler = irq_ptr->orig_handler;
> +		cdev->private->intparm = 0;
> +	}
>  	spin_unlock_irq(get_ccwdev_lock(cdev));
>  
>  	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
>
Kleber Sacilotto de Souza May 13, 2019, 2 p.m. UTC | #3
On 5/9/19 5:36 PM, frank.heimes@canonical.com wrote:
> From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1828394
> 
> During shutdown, qdio returns its ccw device back to control by the
> upper-layer driver. But there is a remote chance that by the time where the
> IRQ handler gets switched back, the interrupt for the preceding
> ccw_device_{clear,halt} hasn't been presented yet.
> Upper-layer drivers would then need to handle this IRQ - and since the IO
> is issued with an intparm, it could very well be confused with whatever
> intparm mechanism the driver uses itself (eg intparm == request address).
> 
> So when switching over the IRQ handler, also clear the intparm and have
> upper-layer drivers deal with any such delayed interrupt as if it was
> unsolicited.
> 
> Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
> Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
> (cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa)
> Signed-off-by: Frank Heimes <frank.heimes@canonical.com>
> ---
>  drivers/s390/cio/qdio_main.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
> index d76df58..8842be6 100644
> --- a/drivers/s390/cio/qdio_main.c
> +++ b/drivers/s390/cio/qdio_main.c
> @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
>  	qdio_shutdown_thinint(irq_ptr);
>  
>  	/* restore interrupt handler */
> -	if ((void *)cdev->handler == (void *)qdio_int_handler)
> +	if ((void *)cdev->handler == (void *)qdio_int_handler) {
>  		cdev->handler = irq_ptr->orig_handler;
> +		cdev->private->intparm = 0;
> +	}
>  	spin_unlock_irq(get_ccwdev_lock(cdev));
>  
>  	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
> 

Applied to bionic/master-next branch.

Thanks,
Kleber
diff mbox series

Patch

diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index d76df58..8842be6 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -1218,8 +1218,10 @@  int qdio_shutdown(struct ccw_device *cdev, int how)
 	qdio_shutdown_thinint(irq_ptr);
 
 	/* restore interrupt handler */
-	if ((void *)cdev->handler == (void *)qdio_int_handler)
+	if ((void *)cdev->handler == (void *)qdio_int_handler) {
 		cdev->handler = irq_ptr->orig_handler;
+		cdev->private->intparm = 0;
+	}
 	spin_unlock_irq(get_ccwdev_lock(cdev));
 
 	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);