105 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Implementation of get_cpuid().4 *5 * Author: Nikita Shubin <n.shubin@yadro.com>6 */7 8#include <stdio.h>9#include <stdlib.h>10#include <api/fs/fs.h>11#include <errno.h>12#include "../../util/debug.h"13#include "../../util/header.h"14 15#define CPUINFO_MVEN "mvendorid"16#define CPUINFO_MARCH "marchid"17#define CPUINFO_MIMP "mimpid"18#define CPUINFO "/proc/cpuinfo"19 20static char *_get_field(const char *line)21{22 char *line2, *nl;23 24 line2 = strrchr(line, ' ');25 if (!line2)26 return NULL;27 28 line2++;29 nl = strrchr(line, '\n');30 if (!nl)31 return NULL;32 33 return strndup(line2, nl - line2);34}35 36static char *_get_cpuid(void)37{38 char *line = NULL;39 char *mvendorid = NULL;40 char *marchid = NULL;41 char *mimpid = NULL;42 char *cpuid = NULL;43 int read;44 size_t line_sz;45 FILE *cpuinfo;46 47 cpuinfo = fopen(CPUINFO, "r");48 if (cpuinfo == NULL)49 return cpuid;50 51 while ((read = getline(&line, &line_sz, cpuinfo)) != -1) {52 if (!strncmp(line, CPUINFO_MVEN, strlen(CPUINFO_MVEN))) {53 mvendorid = _get_field(line);54 if (!mvendorid)55 goto free;56 } else if (!strncmp(line, CPUINFO_MARCH, strlen(CPUINFO_MARCH))) {57 marchid = _get_field(line);58 if (!marchid)59 goto free;60 } else if (!strncmp(line, CPUINFO_MIMP, strlen(CPUINFO_MIMP))) {61 mimpid = _get_field(line);62 if (!mimpid)63 goto free;64 65 break;66 }67 }68 69 if (!mvendorid || !marchid || !mimpid)70 goto free;71 72 if (asprintf(&cpuid, "%s-%s-%s", mvendorid, marchid, mimpid) < 0)73 cpuid = NULL;74 75free:76 fclose(cpuinfo);77 free(mvendorid);78 free(marchid);79 free(mimpid);80 81 return cpuid;82}83 84int get_cpuid(char *buffer, size_t sz)85{86 char *cpuid = _get_cpuid();87 int ret = 0;88 89 if (sz < strlen(cpuid)) {90 ret = -EINVAL;91 goto free;92 }93 94 scnprintf(buffer, sz, "%s", cpuid);95free:96 free(cpuid);97 return ret;98}99 100char *101get_cpuid_str(struct perf_pmu *pmu __maybe_unused)102{103 return _get_cpuid();104}105