]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/wti: Introduce infrastructure for warning track interrupt
authorTobias Huschle <huschle@linux.ibm.com>
Mon, 12 Aug 2024 11:39:27 +0000 (13:39 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 29 Aug 2024 20:56:34 +0000 (22:56 +0200)
The warning-track interrupt (wti) provides a notification that the
receiving CPU will be pre-empted from its physical CPU within a short
time frame. This time frame is called grace period and depends on the
machine type. Giving up the CPU on time may prevent a task to get stuck
while holding a resource.

Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Reviewed-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Tobias Huschle <huschle@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/ctlreg.h
arch/s390/include/asm/diag.h
arch/s390/include/asm/irq.h
arch/s390/include/asm/sclp.h
arch/s390/kernel/diag.c
arch/s390/kernel/irq.c
drivers/s390/char/sclp_early.c

index 72a9556d04f3b04e40ee01be2d77c028f005041d..e6527f51ad0b5640d8d980dad8bb379bf05a9971 100644 (file)
@@ -202,8 +202,9 @@ union ctlreg0 {
                unsigned long      : 3;
                unsigned long ccc  : 1; /* Cryptography counter control */
                unsigned long pec  : 1; /* PAI extension control */
-               unsigned long      : 17;
-               unsigned long      : 3;
+               unsigned long      : 15;
+               unsigned long wti  : 1; /* Warning-track */
+               unsigned long      : 4;
                unsigned long lap  : 1; /* Low-address-protection control */
                unsigned long      : 4;
                unsigned long edat : 1; /* Enhanced-DAT-enablement control */
index c0d43512f4fc66ed319f234370a230bb0b0f1b89..e1316e181230197b11939b961ffde78927271ff0 100644 (file)
@@ -38,6 +38,7 @@ enum diag_stat_enum {
        DIAG_STAT_X308,
        DIAG_STAT_X318,
        DIAG_STAT_X320,
+       DIAG_STAT_X49C,
        DIAG_STAT_X500,
        NR_DIAG_STAT
 };
@@ -363,4 +364,12 @@ void _diag0c_amode31(unsigned long rx);
 void _diag308_reset_amode31(void);
 int _diag8c_amode31(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
 
+/* diag 49c subcodes */
+enum diag49c_sc {
+       DIAG49C_SUBC_ACK = 0,
+       DIAG49C_SUBC_REG = 1
+};
+
+int diag49c(unsigned long subcode);
+
 #endif /* _ASM_S390_DIAG_H */
index 54b42817f70a65718d0111e5d7edc9ef04583432..d9e705f4a697e05069f2e895b3fc6a1279b00a9e 100644 (file)
@@ -47,6 +47,7 @@ enum interruption_class {
        IRQEXT_CMS,
        IRQEXT_CMC,
        IRQEXT_FTP,
+       IRQEXT_WTI,
        IRQIO_CIO,
        IRQIO_DAS,
        IRQIO_C15,
@@ -99,6 +100,7 @@ int unregister_external_irq(u16 code, ext_int_handler_t handler);
 enum irq_subclass {
        IRQ_SUBCLASS_MEASUREMENT_ALERT = 5,
        IRQ_SUBCLASS_SERVICE_SIGNAL = 9,
+       IRQ_SUBCLASS_WARNING_TRACK = 33,
 };
 
 #define CR0_IRQ_SUBCLASS_MASK                                    \
index da3dad18fe507237b13d84b60d4d6212a0ffc5f4..eb00fa1771da07a564dbc35bb9baba24c3ecdd95 100644 (file)
@@ -72,6 +72,7 @@ struct sclp_info {
        unsigned char has_core_type : 1;
        unsigned char has_sprp : 1;
        unsigned char has_hvs : 1;
+       unsigned char has_wti : 1;
        unsigned char has_esca : 1;
        unsigned char has_sief2 : 1;
        unsigned char has_64bscao : 1;
index ac7b8c8e3133106e963960f9f718e3c82d7726f7..007e1795670e8ab0b2d73e265ef15d3c229ad233 100644 (file)
@@ -52,6 +52,7 @@ static const struct diag_desc diag_map[NR_DIAG_STAT] = {
        [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" },
        [DIAG_STAT_X318] = { .code = 0x318, .name = "CP Name and Version Codes" },
        [DIAG_STAT_X320] = { .code = 0x320, .name = "Certificate Store" },
+       [DIAG_STAT_X49C] = { .code = 0x49c, .name = "Warning-Track Interruption" },
        [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" },
 };
 
@@ -303,3 +304,19 @@ int diag26c(void *req, void *resp, enum diag26c_sc subcode)
        return diag_amode31_ops.diag26c(virt_to_phys(req), virt_to_phys(resp), subcode);
 }
 EXPORT_SYMBOL(diag26c);
+
+int diag49c(unsigned long subcode)
+{
+       int rc;
+
+       diag_stat_inc(DIAG_STAT_X49C);
+       asm volatile(
+               "       diag    %[subcode],0,0x49c\n"
+               "       ipm     %[rc]\n"
+               "       srl     %[rc],28\n"
+               : [rc] "=d" (rc)
+               : [subcode] "d" (subcode)
+               : "cc");
+       return rc;
+}
+EXPORT_SYMBOL(diag49c);
index 1af5a08d72abe47412000b8325bf8763d4d6bc42..2639a3d12736a81d94c5d712ac52b6bceea5d1ae 100644 (file)
@@ -76,6 +76,7 @@ static const struct irq_class irqclass_sub_desc[] = {
        {.irq = IRQEXT_CMS, .name = "CMS", .desc = "[EXT] CPU-Measurement: Sampling"},
        {.irq = IRQEXT_CMC, .name = "CMC", .desc = "[EXT] CPU-Measurement: Counter"},
        {.irq = IRQEXT_FTP, .name = "FTP", .desc = "[EXT] HMC FTP Service"},
+       {.irq = IRQEXT_WTI, .name = "WTI", .desc = "[EXT] Warning Track"},
        {.irq = IRQIO_CIO,  .name = "CIO", .desc = "[I/O] Common I/O Layer Interrupt"},
        {.irq = IRQIO_DAS,  .name = "DAS", .desc = "[I/O] DASD"},
        {.irq = IRQIO_C15,  .name = "C15", .desc = "[I/O] 3215"},
index 07df04af82f2ee6a1d7f8630d47657394325e6b9..29156455970e99c3f42b6c14bf213548308032e7 100644 (file)
@@ -44,6 +44,7 @@ static void __init sclp_early_facilities_detect(void)
        sclp.has_ibs = !!(sccb->fac117 & 0x20);
        sclp.has_gisaf = !!(sccb->fac118 & 0x08);
        sclp.has_hvs = !!(sccb->fac119 & 0x80);
+       sclp.has_wti = !!(sccb->fac119 & 0x40);
        sclp.has_kss = !!(sccb->fac98 & 0x01);
        sclp.has_aisii = !!(sccb->fac118 & 0x40);
        sclp.has_aeni = !!(sccb->fac118 & 0x20);