diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp
index 1eb340c..b021955 100644
--- a/src/cpu/cpu.cpp
+++ b/src/cpu/cpu.cpp
@@ -57,6 +57,7 @@ class perf_power_bundle: public perf_bundle
static class abstract_cpu * new_package(int package, int cpu, char * vendor, int family, int model)
{
+ uint64_t msr;
class abstract_cpu *ret = NULL;
class cpudevice *cpudev;
char packagename[128];
@@ -71,15 +72,19 @@ static class abstract_cpu * new_package(int package, int cpu, char * vendor, int
case 0x25: /* Westmere */
case 0x27: /* Medfield Atom*/
case 0x2C: /* Westmere */
- ret = new class nhm_package;
+ if (read_msr(cpu, MSR_APERF, &msr) >= 0)
+ ret = new class nhm_package;
break;
case 0x2A: /* SNB */
case 0x2D: /* SNB Xeon */
case 0x3A: /* IVB */
case 0x3C:
case 0x3D: /* IVB Xeon */
- has_c2c7_res = 1;
- ret = new class nhm_package;
+ if (read_msr(cpu, MSR_PKG_C7_RESIDENCY, &msr) >= 0)
+ {
+ has_c2c7_res = 1;
+ ret = new class nhm_package;
+ }
break;
}
}
@@ -99,6 +104,7 @@ static class abstract_cpu * new_package(int package, int cpu, char * vendor, int
static class abstract_cpu * new_core(int core, int cpu, char * vendor, int family, int model)
{
+ uint64_t msr;
class abstract_cpu *ret = NULL;
if (strcmp(vendor, "GenuineIntel") == 0) {
@@ -116,7 +122,8 @@ static class abstract_cpu * new_core(int core, int cpu, char * vendor, int famil
case 0x3A: /* IVB */
case 0x3C:
case 0x3D: /* IVB Xeon */
- ret = new class nhm_core;
+ if (read_msr(cpu, MSR_APERF, &msr) >= 0)
+ ret = new class nhm_core;
}
}
@@ -142,6 +149,7 @@ static class abstract_cpu * new_i965_gpu(void)
static class abstract_cpu * new_cpu(int number, char * vendor, int family, int model)
{
+ uint64_t msr;
class abstract_cpu * ret = NULL;
if (strcmp(vendor, "GenuineIntel") == 0) {
@@ -159,7 +167,8 @@ static class abstract_cpu * new_cpu(int number, char * vendor, int family, int m
case 0x3A: /* IVB */
case 0x3C:
case 0x3D: /* IVB Xeon */
- ret = new class nhm_cpu;
+ if (read_msr(number, MSR_APERF, &msr) >= 0)
+ ret = new class nhm_cpu;
}
}
diff --git a/src/cpu/intel_cpus.cpp b/src/cpu/intel_cpus.cpp
index 2b78d31..8d5f51a 100644
--- a/src/cpu/intel_cpus.cpp
+++ b/src/cpu/intel_cpus.cpp
@@ -49,30 +49,15 @@ static uint64_t get_msr(int cpu, uint64_t offset)
{
ssize_t retval;
uint64_t msr;
- int fd;
- char msr_path[256];
- fd = sprintf(msr_path, "/dev/cpu/%d/msr", cpu);
-
- if (access(msr_path, R_OK) != 0){
- fd = sprintf(msr_path, "/dev/msr%d", cpu);
-
- if (access(msr_path, R_OK) != 0){
- fprintf(stderr, _("msr reg not found"));
- exit(-2);
- }
- }
-
- fd = open(msr_path, O_RDONLY);
-
- retval = pread(fd, &msr, sizeof msr, offset);
- if (retval != sizeof msr) {
+ retval = read_msr(cpu, offset, &msr);
+ if (retval < 0) {
reset_display();
- fprintf(stderr, _("pread cpu%d 0x%llx : "), cpu, (unsigned long long)offset);
+ fprintf(stderr, _("read_msr cpu%d 0x%llx : "), cpu, (unsigned long long)offset);
fprintf(stderr, "%s\n", strerror(errno));
exit(-2);
}
- close(fd);
+
return msr;
}
diff --git a/src/lib.cpp b/src/lib.cpp
index 723517a..6993088 100644
--- a/src/lib.cpp
+++ b/src/lib.cpp
@@ -56,6 +56,7 @@ extern "C" {
#include <limits>
#include <math.h>
#include <ncurses.h>
+#include <fcntl.h>
static int kallsyms_read = 0;
@@ -450,3 +451,36 @@ int get_user_input(char *buf, unsigned sz)
/* to distinguish between getnstr error and empty line */
return ret || strlen(buf);
}
+
+int read_msr(int cpu, uint64_t offset, uint64_t *value)
+{
+ ssize_t retval;
+ uint64_t msr;
+ int fd;
+ char msr_path[256];
+
+ sprintf(msr_path, "/dev/cpu/%d/msr", cpu);
+
+ if (access(msr_path, R_OK) != 0){
+ sprintf(msr_path, "/dev/msr%d", cpu);
+
+ if (access(msr_path, R_OK) != 0){
+ fprintf(stderr,
+ _("Model-specific registers (MSR)\
+ not found (try enabling CONFIG_X86_MSR).\n"));
+ return -1;
+ }
+ }
+
+ fd = open(msr_path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ retval = pread(fd, &msr, sizeof msr, offset);
+ close(fd);
+ if (retval != sizeof msr) {
+ return -1;
+ }
+ *value = msr;
+
+ return retval;
+}
diff --git a/src/lib.h b/src/lib.h
index de2de5a..1c9ca42 100644
--- a/src/lib.h
+++ b/src/lib.h
@@ -74,5 +74,6 @@ typedef void (*callback)(const char*);
extern void process_directory(const char *d_name, callback fn);
extern int utf_ok;
extern int get_user_input(char *buf, unsigned sz);
+extern int read_msr(int cpu, uint64_t offset, uint64_t *value);
#endif