2 * Implementation of get_cpuid().
4 * Copyright IBM Corp. 2014, 2018
5 * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
6 * Thomas Richter <tmricht@linux.vnet.ibm.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License (version 2 only)
10 * as published by the Free Software Foundation.
13 #include <sys/types.h>
19 #include "../../util/header.h"
20 #include "../../util/util.h"
22 #define SYSINFO_MANU "Manufacturer:"
23 #define SYSINFO_TYPE "Type:"
24 #define SYSINFO_MODEL "Model:"
25 #define SRVLVL_CPUMF "CPU-MF:"
26 #define SRVLVL_VERSION "version="
27 #define SRVLVL_AUTHORIZATION "authorization="
28 #define SYSINFO "/proc/sysinfo"
29 #define SRVLVL "/proc/service_levels"
31 int get_cpuid(char *buffer
, size_t sz
)
33 char *cp
, *line
= NULL
, *line2
;
34 char type
[8], model
[33], version
[8], manufacturer
[32], authorization
[8];
35 int tpsize
= 0, mdsize
= 0, vssize
= 0, mfsize
= 0, atsize
= 0;
37 unsigned long line_sz
;
42 * Scan /proc/sysinfo line by line and read out values for
43 * Manufacturer:, Type: and Model:, for example:
47 * The first word is the Model Capacity and the second word is
48 * Model (can be omitted). Both words have a maximum size of 16
51 memset(manufacturer
, 0, sizeof(manufacturer
));
52 memset(type
, 0, sizeof(type
));
53 memset(model
, 0, sizeof(model
));
54 memset(version
, 0, sizeof(version
));
55 memset(authorization
, 0, sizeof(authorization
));
57 sysinfo
= fopen(SYSINFO
, "r");
61 while ((read
= getline(&line
, &line_sz
, sysinfo
)) != -1) {
62 if (!strncmp(line
, SYSINFO_MANU
, strlen(SYSINFO_MANU
))) {
63 line2
= line
+ strlen(SYSINFO_MANU
);
65 while ((cp
= strtok_r(line2
, "\n ", &line2
))) {
66 mfsize
+= scnprintf(manufacturer
+ mfsize
,
67 sizeof(manufacturer
) - mfsize
, "%s", cp
);
71 if (!strncmp(line
, SYSINFO_TYPE
, strlen(SYSINFO_TYPE
))) {
72 line2
= line
+ strlen(SYSINFO_TYPE
);
74 while ((cp
= strtok_r(line2
, "\n ", &line2
))) {
75 tpsize
+= scnprintf(type
+ tpsize
,
76 sizeof(type
) - tpsize
, "%s", cp
);
80 if (!strncmp(line
, SYSINFO_MODEL
, strlen(SYSINFO_MODEL
))) {
81 line2
= line
+ strlen(SYSINFO_MODEL
);
83 while ((cp
= strtok_r(line2
, "\n ", &line2
))) {
84 mdsize
+= scnprintf(model
+ mdsize
, sizeof(model
) - mdsize
,
85 "%s%s", model
[0] ? "," : "", cp
);
92 /* Missing manufacturer, type or model information should not happen */
93 if (!manufacturer
[0] || !type
[0] || !model
[0])
97 * Scan /proc/service_levels and return the CPU-MF counter facility
98 * version number and authorization level.
99 * Optional, does not exist on z/VM guests.
101 sysinfo
= fopen(SRVLVL
, "r");
104 while ((read
= getline(&line
, &line_sz
, sysinfo
)) != -1) {
105 if (strncmp(line
, SRVLVL_CPUMF
, strlen(SRVLVL_CPUMF
)))
108 line2
= line
+ strlen(SRVLVL_CPUMF
);
109 while ((cp
= strtok_r(line2
, "\n ", &line2
))) {
110 if (!strncmp(cp
, SRVLVL_VERSION
,
111 strlen(SRVLVL_VERSION
))) {
112 char *sep
= strchr(cp
, '=');
114 vssize
+= scnprintf(version
+ vssize
,
115 sizeof(version
) - vssize
, "%s", sep
+ 1);
117 if (!strncmp(cp
, SRVLVL_AUTHORIZATION
,
118 strlen(SRVLVL_AUTHORIZATION
))) {
119 char *sep
= strchr(cp
, '=');
121 atsize
+= scnprintf(authorization
+ atsize
,
122 sizeof(authorization
) - atsize
, "%s", sep
+ 1);
131 if (version
[0] && authorization
[0] )
132 nbytes
= snprintf(buffer
, sz
, "%s,%s,%s,%s,%s",
133 manufacturer
, type
, model
, version
,
136 nbytes
= snprintf(buffer
, sz
, "%s,%s,%s", manufacturer
, type
,
138 return (nbytes
>= sz
) ? -1 : 0;
141 char *get_cpuid_str(struct perf_pmu
*pmu __maybe_unused
)
143 char *buf
= malloc(128);
145 if (buf
&& get_cpuid(buf
, 128) < 0)