aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/sclp.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2011-05-26 03:48:23 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2011-05-26 03:48:24 -0400
commitdf7997ab1ca82ae3c37a2f5eb98613fc24527f95 (patch)
tree51794f46cb7fc7fa4db8fbadb8feb265fc8ef499 /drivers/s390/char/sclp.c
parent902050bcdece6191565c055539e82c5cc534feed (diff)
[S390] irq: fix service signal external interrupt handling
Interrupt sources like pfault, sclp, dasd_diag and virtio all use the service signal external interrupt subclass mask in control register 0 to enable and disable the corresponding interrupt. Because no reference counting is implemented each subsystem thinks it is the only user of subclass and sets and clears the bit like it wants. This leads to case that unloading the dasd diag module under z/VM causes both sclp and pfault interrupts to be masked. The result will be locked up system sooner or later. Fix this by introducing a new way to set (register) and clear (unregister) the service signal subclass mask bit in cr0. Also convert all drivers. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp.c')
-rw-r--r--drivers/s390/char/sclp.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index b76c61f82485..b37b98cbbd00 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -885,12 +885,12 @@ sclp_check_interface(void)
885 spin_unlock_irqrestore(&sclp_lock, flags); 885 spin_unlock_irqrestore(&sclp_lock, flags);
886 /* Enable service-signal interruption - needs to happen 886 /* Enable service-signal interruption - needs to happen
887 * with IRQs enabled. */ 887 * with IRQs enabled. */
888 ctl_set_bit(0, 9); 888 service_subclass_irq_register();
889 /* Wait for signal from interrupt or timeout */ 889 /* Wait for signal from interrupt or timeout */
890 sclp_sync_wait(); 890 sclp_sync_wait();
891 /* Disable service-signal interruption - needs to happen 891 /* Disable service-signal interruption - needs to happen
892 * with IRQs enabled. */ 892 * with IRQs enabled. */
893 ctl_clear_bit(0,9); 893 service_subclass_irq_unregister();
894 spin_lock_irqsave(&sclp_lock, flags); 894 spin_lock_irqsave(&sclp_lock, flags);
895 del_timer(&sclp_request_timer); 895 del_timer(&sclp_request_timer);
896 if (sclp_init_req.status == SCLP_REQ_DONE && 896 if (sclp_init_req.status == SCLP_REQ_DONE &&
@@ -1070,7 +1070,7 @@ sclp_init(void)
1070 spin_unlock_irqrestore(&sclp_lock, flags); 1070 spin_unlock_irqrestore(&sclp_lock, flags);
1071 /* Enable service-signal external interruption - needs to happen with 1071 /* Enable service-signal external interruption - needs to happen with
1072 * IRQs enabled. */ 1072 * IRQs enabled. */
1073 ctl_set_bit(0, 9); 1073 service_subclass_irq_register();
1074 sclp_init_mask(1); 1074 sclp_init_mask(1);
1075 return 0; 1075 return 0;
1076 1076