|
4 | 4 | #include <stdio.h>
|
5 | 5 | #include <stdlib.h>
|
6 | 6 | #include <string.h>
|
| 7 | +#include <regex.h> |
7 | 8 |
|
8 | 9 | #include "../../util/header.h"
|
9 | 10 |
|
@@ -70,9 +71,72 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
|
70 | 71 | {
|
71 | 72 | char *buf = malloc(128);
|
72 | 73 |
|
73 |
| - if (buf && __get_cpuid(buf, 128, "%s-%u-%X$") < 0) { |
| 74 | + if (buf && __get_cpuid(buf, 128, "%s-%u-%X-%X$") < 0) { |
74 | 75 | free(buf);
|
75 | 76 | return NULL;
|
76 | 77 | }
|
77 | 78 | return buf;
|
78 | 79 | }
|
| 80 | + |
| 81 | +/* Full CPUID format for x86 is vendor-family-model-stepping */ |
| 82 | +static bool is_full_cpuid(const char *id) |
| 83 | +{ |
| 84 | + const char *tmp = id; |
| 85 | + int count = 0; |
| 86 | + |
| 87 | + while ((tmp = strchr(tmp, '-')) != NULL) { |
| 88 | + count++; |
| 89 | + tmp++; |
| 90 | + } |
| 91 | + |
| 92 | + if (count == 3) |
| 93 | + return true; |
| 94 | + |
| 95 | + return false; |
| 96 | +} |
| 97 | + |
| 98 | +int strcmp_cpuid_str(const char *mapcpuid, const char *id) |
| 99 | +{ |
| 100 | + regex_t re; |
| 101 | + regmatch_t pmatch[1]; |
| 102 | + int match; |
| 103 | + bool full_mapcpuid = is_full_cpuid(mapcpuid); |
| 104 | + bool full_cpuid = is_full_cpuid(id); |
| 105 | + |
| 106 | + /* |
| 107 | + * Full CPUID format is required to identify a platform. |
| 108 | + * Error out if the cpuid string is incomplete. |
| 109 | + */ |
| 110 | + if (full_mapcpuid && !full_cpuid) { |
| 111 | + pr_info("Invalid CPUID %s. Full CPUID is required, " |
| 112 | + "vendor-family-model-stepping\n", id); |
| 113 | + return 1; |
| 114 | + } |
| 115 | + |
| 116 | + if (regcomp(&re, mapcpuid, REG_EXTENDED) != 0) { |
| 117 | + /* Warn unable to generate match particular string. */ |
| 118 | + pr_info("Invalid regular expression %s\n", mapcpuid); |
| 119 | + return 1; |
| 120 | + } |
| 121 | + |
| 122 | + match = !regexec(&re, id, 1, pmatch, 0); |
| 123 | + regfree(&re); |
| 124 | + if (match) { |
| 125 | + size_t match_len = (pmatch[0].rm_eo - pmatch[0].rm_so); |
| 126 | + size_t cpuid_len; |
| 127 | + |
| 128 | + /* If the full CPUID format isn't required, |
| 129 | + * ignoring the stepping. |
| 130 | + */ |
| 131 | + if (!full_mapcpuid && full_cpuid) |
| 132 | + cpuid_len = strrchr(id, '-') - id; |
| 133 | + else |
| 134 | + cpuid_len = strlen(id); |
| 135 | + |
| 136 | + /* Verify the entire string matched. */ |
| 137 | + if (match_len == cpuid_len) |
| 138 | + return 0; |
| 139 | + } |
| 140 | + |
| 141 | + return 1; |
| 142 | +} |
0 commit comments