Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Copyright IBM Corp. 2001, 2009
0004  *  Author(s): Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
0005  *         Martin Schwidefsky <schwidefsky@de.ibm.com>,
0006  */
0007 
0008 #include <linux/debugfs.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mm.h>
0011 #include <linux/proc_fs.h>
0012 #include <linux/seq_file.h>
0013 #include <linux/init.h>
0014 #include <linux/delay.h>
0015 #include <linux/export.h>
0016 #include <linux/slab.h>
0017 #include <asm/asm-extable.h>
0018 #include <asm/ebcdic.h>
0019 #include <asm/debug.h>
0020 #include <asm/sysinfo.h>
0021 #include <asm/cpcmd.h>
0022 #include <asm/topology.h>
0023 #include <asm/fpu/api.h>
0024 
0025 int topology_max_mnest;
0026 
0027 static inline int __stsi(void *sysinfo, int fc, int sel1, int sel2, int *lvl)
0028 {
0029     int r0 = (fc << 28) | sel1;
0030     int rc = 0;
0031 
0032     asm volatile(
0033         "   lr  0,%[r0]\n"
0034         "   lr  1,%[r1]\n"
0035         "   stsi    0(%[sysinfo])\n"
0036         "0: jz  2f\n"
0037         "1: lhi %[rc],%[retval]\n"
0038         "2: lr  %[r0],0\n"
0039         EX_TABLE(0b, 1b)
0040         : [r0] "+d" (r0), [rc] "+d" (rc)
0041         : [r1] "d" (sel2),
0042           [sysinfo] "a" (sysinfo),
0043           [retval] "K" (-EOPNOTSUPP)
0044         : "cc", "0", "1", "memory");
0045     *lvl = ((unsigned int) r0) >> 28;
0046     return rc;
0047 }
0048 
0049 /*
0050  * stsi - store system information
0051  *
0052  * Returns the current configuration level if function code 0 was specified.
0053  * Otherwise returns 0 on success or a negative value on error.
0054  */
0055 int stsi(void *sysinfo, int fc, int sel1, int sel2)
0056 {
0057     int lvl, rc;
0058 
0059     rc = __stsi(sysinfo, fc, sel1, sel2, &lvl);
0060     if (rc)
0061         return rc;
0062     return fc ? 0 : lvl;
0063 }
0064 EXPORT_SYMBOL(stsi);
0065 
0066 #ifdef CONFIG_PROC_FS
0067 
0068 static bool convert_ext_name(unsigned char encoding, char *name, size_t len)
0069 {
0070     switch (encoding) {
0071     case 1: /* EBCDIC */
0072         EBCASC(name, len);
0073         break;
0074     case 2: /* UTF-8 */
0075         break;
0076     default:
0077         return false;
0078     }
0079     return true;
0080 }
0081 
0082 static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info)
0083 {
0084     int i;
0085 
0086     if (stsi(info, 1, 1, 1))
0087         return;
0088     EBCASC(info->manufacturer, sizeof(info->manufacturer));
0089     EBCASC(info->type, sizeof(info->type));
0090     EBCASC(info->model, sizeof(info->model));
0091     EBCASC(info->sequence, sizeof(info->sequence));
0092     EBCASC(info->plant, sizeof(info->plant));
0093     EBCASC(info->model_capacity, sizeof(info->model_capacity));
0094     EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
0095     EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
0096     seq_printf(m, "Manufacturer:         %-16.16s\n", info->manufacturer);
0097     seq_printf(m, "Type:                 %-4.4s\n", info->type);
0098     if (info->lic)
0099         seq_printf(m, "LIC Identifier:       %016lx\n", info->lic);
0100     /*
0101      * Sigh: the model field has been renamed with System z9
0102      * to model_capacity and a new model field has been added
0103      * after the plant field. To avoid confusing older programs
0104      * the "Model:" prints "model_capacity model" or just
0105      * "model_capacity" if the model string is empty .
0106      */
0107     seq_printf(m, "Model:                %-16.16s", info->model_capacity);
0108     if (info->model[0] != '\0')
0109         seq_printf(m, " %-16.16s", info->model);
0110     seq_putc(m, '\n');
0111     seq_printf(m, "Sequence Code:        %-16.16s\n", info->sequence);
0112     seq_printf(m, "Plant:                %-4.4s\n", info->plant);
0113     seq_printf(m, "Model Capacity:       %-16.16s %08u\n",
0114            info->model_capacity, info->model_cap_rating);
0115     if (info->model_perm_cap_rating)
0116         seq_printf(m, "Model Perm. Capacity: %-16.16s %08u\n",
0117                info->model_perm_cap,
0118                info->model_perm_cap_rating);
0119     if (info->model_temp_cap_rating)
0120         seq_printf(m, "Model Temp. Capacity: %-16.16s %08u\n",
0121                info->model_temp_cap,
0122                info->model_temp_cap_rating);
0123     if (info->ncr)
0124         seq_printf(m, "Nominal Cap. Rating:  %08u\n", info->ncr);
0125     if (info->npr)
0126         seq_printf(m, "Nominal Perm. Rating: %08u\n", info->npr);
0127     if (info->ntr)
0128         seq_printf(m, "Nominal Temp. Rating: %08u\n", info->ntr);
0129     if (info->cai) {
0130         seq_printf(m, "Capacity Adj. Ind.:   %d\n", info->cai);
0131         seq_printf(m, "Capacity Ch. Reason:  %d\n", info->ccr);
0132         seq_printf(m, "Capacity Transient:   %d\n", info->t);
0133     }
0134     if (info->p) {
0135         for (i = 1; i <= ARRAY_SIZE(info->typepct); i++) {
0136             seq_printf(m, "Type %d Percentage:    %d\n",
0137                    i, info->typepct[i - 1]);
0138         }
0139     }
0140 }
0141 
0142 static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
0143 {
0144     int i;
0145 
0146     seq_putc(m, '\n');
0147     if (!MACHINE_HAS_TOPOLOGY)
0148         return;
0149     if (stsi(info, 15, 1, topology_max_mnest))
0150         return;
0151     seq_printf(m, "CPU Topology HW:     ");
0152     for (i = 0; i < TOPOLOGY_NR_MAG; i++)
0153         seq_printf(m, " %d", info->mag[i]);
0154     seq_putc(m, '\n');
0155 #ifdef CONFIG_SCHED_TOPOLOGY
0156     store_topology(info);
0157     seq_printf(m, "CPU Topology SW:     ");
0158     for (i = 0; i < TOPOLOGY_NR_MAG; i++)
0159         seq_printf(m, " %d", info->mag[i]);
0160     seq_putc(m, '\n');
0161 #endif
0162 }
0163 
0164 static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info)
0165 {
0166     struct sysinfo_1_2_2_extension *ext;
0167     int i;
0168 
0169     if (stsi(info, 1, 2, 2))
0170         return;
0171     ext = (struct sysinfo_1_2_2_extension *)
0172         ((unsigned long) info + info->acc_offset);
0173     seq_printf(m, "CPUs Total:           %d\n", info->cpus_total);
0174     seq_printf(m, "CPUs Configured:      %d\n", info->cpus_configured);
0175     seq_printf(m, "CPUs Standby:         %d\n", info->cpus_standby);
0176     seq_printf(m, "CPUs Reserved:        %d\n", info->cpus_reserved);
0177     if (info->mt_installed) {
0178         seq_printf(m, "CPUs G-MTID:          %d\n", info->mt_gtid);
0179         seq_printf(m, "CPUs S-MTID:          %d\n", info->mt_stid);
0180     }
0181     /*
0182      * Sigh 2. According to the specification the alternate
0183      * capability field is a 32 bit floating point number
0184      * if the higher order 8 bits are not zero. Printing
0185      * a floating point number in the kernel is a no-no,
0186      * always print the number as 32 bit unsigned integer.
0187      * The user-space needs to know about the strange
0188      * encoding of the alternate cpu capability.
0189      */
0190     seq_printf(m, "Capability:           %u", info->capability);
0191     if (info->format == 1)
0192         seq_printf(m, " %u", ext->alt_capability);
0193     seq_putc(m, '\n');
0194     if (info->nominal_cap)
0195         seq_printf(m, "Nominal Capability:   %d\n", info->nominal_cap);
0196     if (info->secondary_cap)
0197         seq_printf(m, "Secondary Capability: %d\n", info->secondary_cap);
0198     for (i = 2; i <= info->cpus_total; i++) {
0199         seq_printf(m, "Adjustment %02d-way:    %u",
0200                i, info->adjustment[i-2]);
0201         if (info->format == 1)
0202             seq_printf(m, " %u", ext->alt_adjustment[i-2]);
0203         seq_putc(m, '\n');
0204     }
0205 }
0206 
0207 static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info)
0208 {
0209     if (stsi(info, 2, 2, 2))
0210         return;
0211     EBCASC(info->name, sizeof(info->name));
0212     seq_putc(m, '\n');
0213     seq_printf(m, "LPAR Number:          %d\n", info->lpar_number);
0214     seq_printf(m, "LPAR Characteristics: ");
0215     if (info->characteristics & LPAR_CHAR_DEDICATED)
0216         seq_printf(m, "Dedicated ");
0217     if (info->characteristics & LPAR_CHAR_SHARED)
0218         seq_printf(m, "Shared ");
0219     if (info->characteristics & LPAR_CHAR_LIMITED)
0220         seq_printf(m, "Limited ");
0221     seq_putc(m, '\n');
0222     seq_printf(m, "LPAR Name:            %-8.8s\n", info->name);
0223     seq_printf(m, "LPAR Adjustment:      %d\n", info->caf);
0224     seq_printf(m, "LPAR CPUs Total:      %d\n", info->cpus_total);
0225     seq_printf(m, "LPAR CPUs Configured: %d\n", info->cpus_configured);
0226     seq_printf(m, "LPAR CPUs Standby:    %d\n", info->cpus_standby);
0227     seq_printf(m, "LPAR CPUs Reserved:   %d\n", info->cpus_reserved);
0228     seq_printf(m, "LPAR CPUs Dedicated:  %d\n", info->cpus_dedicated);
0229     seq_printf(m, "LPAR CPUs Shared:     %d\n", info->cpus_shared);
0230     if (info->mt_installed) {
0231         seq_printf(m, "LPAR CPUs G-MTID:     %d\n", info->mt_gtid);
0232         seq_printf(m, "LPAR CPUs S-MTID:     %d\n", info->mt_stid);
0233         seq_printf(m, "LPAR CPUs PS-MTID:    %d\n", info->mt_psmtid);
0234     }
0235     if (convert_ext_name(info->vsne, info->ext_name, sizeof(info->ext_name))) {
0236         seq_printf(m, "LPAR Extended Name:   %-.256s\n", info->ext_name);
0237         seq_printf(m, "LPAR UUID:            %pUb\n", &info->uuid);
0238     }
0239 }
0240 
0241 static void print_ext_name(struct seq_file *m, int lvl,
0242                struct sysinfo_3_2_2 *info)
0243 {
0244     size_t len = sizeof(info->ext_names[lvl]);
0245 
0246     if (!convert_ext_name(info->vm[lvl].evmne, info->ext_names[lvl], len))
0247         return;
0248     seq_printf(m, "VM%02d Extended Name:   %-.256s\n", lvl,
0249            info->ext_names[lvl]);
0250 }
0251 
0252 static void print_uuid(struct seq_file *m, int i, struct sysinfo_3_2_2 *info)
0253 {
0254     if (uuid_is_null(&info->vm[i].uuid))
0255         return;
0256     seq_printf(m, "VM%02d UUID:            %pUb\n", i, &info->vm[i].uuid);
0257 }
0258 
0259 static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info)
0260 {
0261     int i;
0262 
0263     if (stsi(info, 3, 2, 2))
0264         return;
0265     for (i = 0; i < info->count; i++) {
0266         EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
0267         EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
0268         seq_putc(m, '\n');
0269         seq_printf(m, "VM%02d Name:            %-8.8s\n", i, info->vm[i].name);
0270         seq_printf(m, "VM%02d Control Program: %-16.16s\n", i, info->vm[i].cpi);
0271         seq_printf(m, "VM%02d Adjustment:      %d\n", i, info->vm[i].caf);
0272         seq_printf(m, "VM%02d CPUs Total:      %d\n", i, info->vm[i].cpus_total);
0273         seq_printf(m, "VM%02d CPUs Configured: %d\n", i, info->vm[i].cpus_configured);
0274         seq_printf(m, "VM%02d CPUs Standby:    %d\n", i, info->vm[i].cpus_standby);
0275         seq_printf(m, "VM%02d CPUs Reserved:   %d\n", i, info->vm[i].cpus_reserved);
0276         print_ext_name(m, i, info);
0277         print_uuid(m, i, info);
0278     }
0279 }
0280 
0281 static int sysinfo_show(struct seq_file *m, void *v)
0282 {
0283     void *info = (void *)get_zeroed_page(GFP_KERNEL);
0284     int level;
0285 
0286     if (!info)
0287         return 0;
0288     level = stsi(NULL, 0, 0, 0);
0289     if (level >= 1)
0290         stsi_1_1_1(m, info);
0291     if (level >= 1)
0292         stsi_15_1_x(m, info);
0293     if (level >= 1)
0294         stsi_1_2_2(m, info);
0295     if (level >= 2)
0296         stsi_2_2_2(m, info);
0297     if (level >= 3)
0298         stsi_3_2_2(m, info);
0299     free_page((unsigned long)info);
0300     return 0;
0301 }
0302 
0303 static int __init sysinfo_create_proc(void)
0304 {
0305     proc_create_single("sysinfo", 0444, NULL, sysinfo_show);
0306     return 0;
0307 }
0308 device_initcall(sysinfo_create_proc);
0309 
0310 #endif /* CONFIG_PROC_FS */
0311 
0312 /*
0313  * Service levels interface.
0314  */
0315 
0316 static DECLARE_RWSEM(service_level_sem);
0317 static LIST_HEAD(service_level_list);
0318 
0319 int register_service_level(struct service_level *slr)
0320 {
0321     struct service_level *ptr;
0322 
0323     down_write(&service_level_sem);
0324     list_for_each_entry(ptr, &service_level_list, list)
0325         if (ptr == slr) {
0326             up_write(&service_level_sem);
0327             return -EEXIST;
0328         }
0329     list_add_tail(&slr->list, &service_level_list);
0330     up_write(&service_level_sem);
0331     return 0;
0332 }
0333 EXPORT_SYMBOL(register_service_level);
0334 
0335 int unregister_service_level(struct service_level *slr)
0336 {
0337     struct service_level *ptr, *next;
0338     int rc = -ENOENT;
0339 
0340     down_write(&service_level_sem);
0341     list_for_each_entry_safe(ptr, next, &service_level_list, list) {
0342         if (ptr != slr)
0343             continue;
0344         list_del(&ptr->list);
0345         rc = 0;
0346         break;
0347     }
0348     up_write(&service_level_sem);
0349     return rc;
0350 }
0351 EXPORT_SYMBOL(unregister_service_level);
0352 
0353 static void *service_level_start(struct seq_file *m, loff_t *pos)
0354 {
0355     down_read(&service_level_sem);
0356     return seq_list_start(&service_level_list, *pos);
0357 }
0358 
0359 static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
0360 {
0361     return seq_list_next(p, &service_level_list, pos);
0362 }
0363 
0364 static void service_level_stop(struct seq_file *m, void *p)
0365 {
0366     up_read(&service_level_sem);
0367 }
0368 
0369 static int service_level_show(struct seq_file *m, void *p)
0370 {
0371     struct service_level *slr;
0372 
0373     slr = list_entry(p, struct service_level, list);
0374     slr->seq_print(m, slr);
0375     return 0;
0376 }
0377 
0378 static const struct seq_operations service_level_seq_ops = {
0379     .start      = service_level_start,
0380     .next       = service_level_next,
0381     .stop       = service_level_stop,
0382     .show       = service_level_show
0383 };
0384 
0385 static void service_level_vm_print(struct seq_file *m,
0386                    struct service_level *slr)
0387 {
0388     char *query_buffer, *str;
0389 
0390     query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
0391     if (!query_buffer)
0392         return;
0393     cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
0394     str = strchr(query_buffer, '\n');
0395     if (str)
0396         *str = 0;
0397     seq_printf(m, "VM: %s\n", query_buffer);
0398     kfree(query_buffer);
0399 }
0400 
0401 static struct service_level service_level_vm = {
0402     .seq_print = service_level_vm_print
0403 };
0404 
0405 static __init int create_proc_service_level(void)
0406 {
0407     proc_create_seq("service_levels", 0, NULL, &service_level_seq_ops);
0408     if (MACHINE_IS_VM)
0409         register_service_level(&service_level_vm);
0410     return 0;
0411 }
0412 subsys_initcall(create_proc_service_level);
0413 
0414 /*
0415  * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
0416  */
0417 void s390_adjust_jiffies(void)
0418 {
0419     struct sysinfo_1_2_2 *info;
0420     unsigned long capability;
0421     struct kernel_fpu fpu;
0422 
0423     info = (void *) get_zeroed_page(GFP_KERNEL);
0424     if (!info)
0425         return;
0426 
0427     if (stsi(info, 1, 2, 2) == 0) {
0428         /*
0429          * Major sigh. The cpu capability encoding is "special".
0430          * If the first 9 bits of info->capability are 0 then it
0431          * is a 32 bit unsigned integer in the range 0 .. 2^23.
0432          * If the first 9 bits are != 0 then it is a 32 bit float.
0433          * In addition a lower value indicates a proportionally
0434          * higher cpu capacity. Bogomips are the other way round.
0435          * To get to a halfway suitable number we divide 1e7
0436          * by the cpu capability number. Yes, that means a floating
0437          * point division ..
0438          */
0439         kernel_fpu_begin(&fpu, KERNEL_FPR);
0440         asm volatile(
0441             "   sfpc    %3\n"
0442             "   l   %0,%1\n"
0443             "   tmlh    %0,0xff80\n"
0444             "   jnz 0f\n"
0445             "   cefbr   %%f2,%0\n"
0446             "   j   1f\n"
0447             "0: le  %%f2,%1\n"
0448             "1: cefbr   %%f0,%2\n"
0449             "   debr    %%f0,%%f2\n"
0450             "   cgebr   %0,5,%%f0\n"
0451             : "=&d" (capability)
0452             : "Q" (info->capability), "d" (10000000), "d" (0)
0453             : "cc"
0454             );
0455         kernel_fpu_end(&fpu, KERNEL_FPR);
0456     } else
0457         /*
0458          * Really old machine without stsi block for basic
0459          * cpu information. Report 42.0 bogomips.
0460          */
0461         capability = 42;
0462     loops_per_jiffy = capability * (500000/HZ);
0463     free_page((unsigned long) info);
0464 }
0465 
0466 /*
0467  * calibrate the delay loop
0468  */
0469 void calibrate_delay(void)
0470 {
0471     s390_adjust_jiffies();
0472     /* Print the good old Bogomips line .. */
0473     printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
0474            "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
0475            (loops_per_jiffy/(5000/HZ)) % 100);
0476 }
0477 
0478 #ifdef CONFIG_DEBUG_FS
0479 
0480 #define STSI_FILE(fc, s1, s2)                              \
0481 static int stsi_open_##fc##_##s1##_##s2(struct inode *inode, struct file *file)\
0482 {                                          \
0483     file->private_data = (void *) get_zeroed_page(GFP_KERNEL);         \
0484     if (!file->private_data)                           \
0485         return -ENOMEM;                            \
0486     if (stsi(file->private_data, fc, s1, s2)) {                \
0487         free_page((unsigned long)file->private_data);              \
0488         file->private_data = NULL;                     \
0489         return -EACCES;                            \
0490     }                                      \
0491     return nonseekable_open(inode, file);                      \
0492 }                                          \
0493                                            \
0494 static const struct file_operations stsi_##fc##_##s1##_##s2##_fs_ops = {       \
0495     .open       = stsi_open_##fc##_##s1##_##s2,                \
0496     .release    = stsi_release,                        \
0497     .read       = stsi_read,                           \
0498     .llseek     = no_llseek,                           \
0499 };
0500 
0501 static int stsi_release(struct inode *inode, struct file *file)
0502 {
0503     free_page((unsigned long)file->private_data);
0504     return 0;
0505 }
0506 
0507 static ssize_t stsi_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
0508 {
0509     return simple_read_from_buffer(buf, size, ppos, file->private_data, PAGE_SIZE);
0510 }
0511 
0512 STSI_FILE( 1, 1, 1);
0513 STSI_FILE( 1, 2, 1);
0514 STSI_FILE( 1, 2, 2);
0515 STSI_FILE( 2, 2, 1);
0516 STSI_FILE( 2, 2, 2);
0517 STSI_FILE( 3, 2, 2);
0518 STSI_FILE(15, 1, 2);
0519 STSI_FILE(15, 1, 3);
0520 STSI_FILE(15, 1, 4);
0521 STSI_FILE(15, 1, 5);
0522 STSI_FILE(15, 1, 6);
0523 
0524 struct stsi_file {
0525     const struct file_operations *fops;
0526     char *name;
0527 };
0528 
0529 static struct stsi_file stsi_file[] __initdata = {
0530     {.fops = &stsi_1_1_1_fs_ops,  .name =  "1_1_1"},
0531     {.fops = &stsi_1_2_1_fs_ops,  .name =  "1_2_1"},
0532     {.fops = &stsi_1_2_2_fs_ops,  .name =  "1_2_2"},
0533     {.fops = &stsi_2_2_1_fs_ops,  .name =  "2_2_1"},
0534     {.fops = &stsi_2_2_2_fs_ops,  .name =  "2_2_2"},
0535     {.fops = &stsi_3_2_2_fs_ops,  .name =  "3_2_2"},
0536     {.fops = &stsi_15_1_2_fs_ops, .name = "15_1_2"},
0537     {.fops = &stsi_15_1_3_fs_ops, .name = "15_1_3"},
0538     {.fops = &stsi_15_1_4_fs_ops, .name = "15_1_4"},
0539     {.fops = &stsi_15_1_5_fs_ops, .name = "15_1_5"},
0540     {.fops = &stsi_15_1_6_fs_ops, .name = "15_1_6"},
0541 };
0542 
0543 static u8 stsi_0_0_0;
0544 
0545 static __init int stsi_init_debugfs(void)
0546 {
0547     struct dentry *stsi_root;
0548     struct stsi_file *sf;
0549     int lvl, i;
0550 
0551     stsi_root = debugfs_create_dir("stsi", arch_debugfs_dir);
0552     lvl = stsi(NULL, 0, 0, 0);
0553     if (lvl > 0)
0554         stsi_0_0_0 = lvl;
0555     debugfs_create_u8("0_0_0", 0400, stsi_root, &stsi_0_0_0);
0556     for (i = 0; i < ARRAY_SIZE(stsi_file); i++) {
0557         sf = &stsi_file[i];
0558         debugfs_create_file(sf->name, 0400, stsi_root, NULL, sf->fops);
0559     }
0560     if (IS_ENABLED(CONFIG_SCHED_TOPOLOGY) && MACHINE_HAS_TOPOLOGY) {
0561         char link_to[10];
0562 
0563         sprintf(link_to, "15_1_%d", topology_mnest_limit());
0564         debugfs_create_symlink("topology", stsi_root, link_to);
0565     }
0566     return 0;
0567 }
0568 device_initcall(stsi_init_debugfs);
0569 
0570 #endif /* CONFIG_DEBUG_FS */