Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/perf/arch/s390/util/header.c
26292 views
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 <[email protected]>
7
* Thomas Richter <[email protected]>
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, struct perf_cpu cpu __maybe_unused)
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_cpu cpu)
141
{
142
char *buf = malloc(128);
143
144
if (buf && get_cpuid(buf, 128, cpu))
145
zfree(&buf);
146
return buf;
147
}
148
149