s390/smp,mcck: fix early IPI handling
authorHeiko Carstens <hca@linux.ibm.com>
Tue, 5 Sep 2023 13:49:37 +0000 (15:49 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 19 Sep 2023 11:26:55 +0000 (13:26 +0200)
Both the external call as well as the emergency signal submask bits in
control register 0 are set before any interrupt handler is registered.

Change the order and first register the interrupt handler and only then
enable the interrupts by setting the corresponding bits in control
register 0.

This prevents that the second part of the machine check handler for
early machine check handling is not executed: the machine check handler
sends an IPI to the CPU it runs on. If the corresponding interrupts are
enabled, but no interrupt handler is present, the interrupt is ignored.

Reviewed-by: Sven Schnelle <svens@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/kernel/early.c
arch/s390/kernel/smp.c

index 442ce0489e1a1e4515fc0576549cb87da23e2d40..3a54733e4fc65b89c1f6bf19f1948b4f8a97857d 100644 (file)
@@ -258,15 +258,9 @@ static inline void save_vector_registers(void)
 #endif
 }
 
-static inline void setup_control_registers(void)
+static inline void setup_low_address_protection(void)
 {
-       unsigned long reg;
-
-       __ctl_store(reg, 0, 0);
-       reg |= CR0_LOW_ADDRESS_PROTECTION;
-       reg |= CR0_EMERGENCY_SIGNAL_SUBMASK;
-       reg |= CR0_EXTERNAL_CALL_SUBMASK;
-       __ctl_load(reg, 0, 0);
+       __ctl_set_bit(0, 28);
 }
 
 static inline void setup_access_registers(void)
@@ -314,7 +308,7 @@ void __init startup_init(void)
        save_vector_registers();
        setup_topology();
        sclp_early_detect();
-       setup_control_registers();
+       setup_low_address_protection();
        setup_access_registers();
        lockdep_on();
 }
index a4edb7ea66ea763d9090844446b2a2d7566d74ef..c63be2efd68952aa754f011db97ad0a6e3e621de 100644 (file)
@@ -1013,12 +1013,12 @@ void __init smp_fill_possible_mask(void)
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-       /* request the 0x1201 emergency signal external interrupt */
        if (register_external_irq(EXT_IRQ_EMERGENCY_SIG, do_ext_call_interrupt))
                panic("Couldn't request external interrupt 0x1201");
-       /* request the 0x1202 external call external interrupt */
+       ctl_set_bit(0, 14);
        if (register_external_irq(EXT_IRQ_EXTERNAL_CALL, do_ext_call_interrupt))
                panic("Couldn't request external interrupt 0x1202");
+       ctl_set_bit(0, 13);
 }
 
 void __init smp_prepare_boot_cpu(void)