root/tools/perf/arch/s390/util/header.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_cpuid
  2. get_cpuid_str

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Implementation of get_cpuid().
   4  *
   5  * Copyright IBM Corp. 2014, 2018
   6  * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
   7  *            Thomas Richter <tmricht@linux.vnet.ibm.com>
   8  */
   9 
  10 #include <sys/types.h>
  11 #include <errno.h>
  12 #include <unistd.h>
  13 #include <stdio.h>
  14 #include <string.h>
  15 #include <linux/ctype.h>
  16 #include <linux/kernel.h>
  17 #include <linux/zalloc.h>
  18 
  19 #include "../../util/header.h"
  20 
  21 #define SYSINFO_MANU    "Manufacturer:"
  22 #define SYSINFO_TYPE    "Type:"
  23 #define SYSINFO_MODEL   "Model:"
  24 #define SRVLVL_CPUMF    "CPU-MF:"
  25 #define SRVLVL_VERSION  "version="
  26 #define SRVLVL_AUTHORIZATION    "authorization="
  27 #define SYSINFO         "/proc/sysinfo"
  28 #define SRVLVL          "/proc/service_levels"
  29 
  30 int get_cpuid(char *buffer, size_t sz)
  31 {
  32         char *cp, *line = NULL, *line2;
  33         char type[8], model[33], version[8], manufacturer[32], authorization[8];
  34         int tpsize = 0, mdsize = 0, vssize = 0, mfsize = 0, atsize = 0;
  35         int read;
  36         unsigned long line_sz;
  37         size_t nbytes;
  38         FILE *sysinfo;
  39 
  40         /*
  41          * Scan /proc/sysinfo line by line and read out values for
  42          * Manufacturer:, Type: and Model:, for example:
  43          * Manufacturer:    IBM
  44          * Type:            2964
  45          * Model:           702              N96
  46          * The first word is the Model Capacity and the second word is
  47          * Model (can be omitted). Both words have a maximum size of 16
  48          * bytes.
  49          */
  50         memset(manufacturer, 0, sizeof(manufacturer));
  51         memset(type, 0, sizeof(type));
  52         memset(model, 0, sizeof(model));
  53         memset(version, 0, sizeof(version));
  54         memset(authorization, 0, sizeof(authorization));
  55 
  56         sysinfo = fopen(SYSINFO, "r");
  57         if (sysinfo == NULL)
  58                 return errno;
  59 
  60         while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
  61                 if (!strncmp(line, SYSINFO_MANU, strlen(SYSINFO_MANU))) {
  62                         line2 = line + strlen(SYSINFO_MANU);
  63 
  64                         while ((cp = strtok_r(line2, "\n ", &line2))) {
  65                                 mfsize += scnprintf(manufacturer + mfsize,
  66                                                     sizeof(manufacturer) - mfsize, "%s", cp);
  67                         }
  68                 }
  69 
  70                 if (!strncmp(line, SYSINFO_TYPE, strlen(SYSINFO_TYPE))) {
  71                         line2 = line + strlen(SYSINFO_TYPE);
  72 
  73                         while ((cp = strtok_r(line2, "\n ", &line2))) {
  74                                 tpsize += scnprintf(type + tpsize,
  75                                                     sizeof(type) - tpsize, "%s", cp);
  76                         }
  77                 }
  78 
  79                 if (!strncmp(line, SYSINFO_MODEL, strlen(SYSINFO_MODEL))) {
  80                         line2 = line + strlen(SYSINFO_MODEL);
  81 
  82                         while ((cp = strtok_r(line2, "\n ", &line2))) {
  83                                 mdsize += scnprintf(model + mdsize, sizeof(model) - mdsize,
  84                                                     "%s%s", model[0] ? "," : "", cp);
  85                         }
  86                         break;
  87                 }
  88         }
  89         fclose(sysinfo);
  90 
  91         /* Missing manufacturer, type or model information should not happen */
  92         if (!manufacturer[0] || !type[0] || !model[0])
  93                 return EINVAL;
  94 
  95         /*
  96          * Scan /proc/service_levels and return the CPU-MF counter facility
  97          * version number and authorization level.
  98          * Optional, does not exist on z/VM guests.
  99          */
 100         sysinfo = fopen(SRVLVL, "r");
 101         if (sysinfo == NULL)
 102                 goto skip_sysinfo;
 103         while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
 104                 if (strncmp(line, SRVLVL_CPUMF, strlen(SRVLVL_CPUMF)))
 105                         continue;
 106 
 107                 line2 = line + strlen(SRVLVL_CPUMF);
 108                 while ((cp = strtok_r(line2, "\n ", &line2))) {
 109                         if (!strncmp(cp, SRVLVL_VERSION,
 110                                      strlen(SRVLVL_VERSION))) {
 111                                 char *sep = strchr(cp, '=');
 112 
 113                                 vssize += scnprintf(version + vssize,
 114                                                     sizeof(version) - vssize, "%s", sep + 1);
 115                         }
 116                         if (!strncmp(cp, SRVLVL_AUTHORIZATION,
 117                                      strlen(SRVLVL_AUTHORIZATION))) {
 118                                 char *sep = strchr(cp, '=');
 119 
 120                                 atsize += scnprintf(authorization + atsize,
 121                                                     sizeof(authorization) - atsize, "%s", sep + 1);
 122                         }
 123                 }
 124         }
 125         fclose(sysinfo);
 126 
 127 skip_sysinfo:
 128         free(line);
 129 
 130         if (version[0] && authorization[0] )
 131                 nbytes = snprintf(buffer, sz, "%s,%s,%s,%s,%s",
 132                                   manufacturer, type, model, version,
 133                                   authorization);
 134         else
 135                 nbytes = snprintf(buffer, sz, "%s,%s,%s", manufacturer, type,
 136                                   model);
 137         return (nbytes >= sz) ? ENOBUFS : 0;
 138 }
 139 
 140 char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
 141 {
 142         char *buf = malloc(128);
 143 
 144         if (buf && get_cpuid(buf, 128))
 145                 zfree(&buf);
 146         return buf;
 147 }

/* [<][>][^][v][top][bottom][index][help] */