diff options
author | Mike Larkin <mlarkin@cvs.openbsd.org> | 2016-04-14 07:00:25 +0000 |
---|---|---|
committer | Mike Larkin <mlarkin@cvs.openbsd.org> | 2016-04-14 07:00:25 +0000 |
commit | 9a51b0e7eb49be04049010d6b98ffa106e258530 (patch) | |
tree | 795824a5fb4a7cd8d4b2ade868eca1f685d30a25 /sys/arch/i386 | |
parent | 8383767e7eac6536f2e262d04c97c6b5be037cde (diff) |
Use cpuid function 0xa to determine presence of general purpose
architectural performance counters, instead of cpu family/model values.
Fixes a panic seen on some hypervisors when pctr(1) is used when the
hypervisor masks out the counters.
Reported by Hiltjo Posthuma, thanks.
ok mikeb@, guenther@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/pctr.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/arch/i386/i386/pctr.c b/sys/arch/i386/i386/pctr.c index 0d0dbee7ce0..ef693864de2 100644 --- a/sys/arch/i386/i386/pctr.c +++ b/sys/arch/i386/i386/pctr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pctr.c,v 1.27 2014/03/29 18:09:29 guenther Exp $ */ +/* $OpenBSD: pctr.c,v 1.28 2016/04/14 07:00:24 mlarkin Exp $ */ /* * Pentium performance counter driver for OpenBSD. @@ -24,20 +24,22 @@ #define PCTR_AMD_NUM PCTR_NUM #define PCTR_INTEL_NUM 2 /* Intel supports only 2 counters */ +#define PCTR_INTEL_VERSION_MASK 0xff #define usetsc (cpu_feature & CPUID_TSC) #define usep5ctr (pctr_isintel && (((cpu_id >> 8) & 15) == 5) && \ (((cpu_id >> 4) & 15) > 0)) -#define usepctr ((pctr_isamd || pctr_isintel) && \ - ((cpu_id >> 8) & 15) >= 6) +#define usepctr ((pctr_isamd && ((cpu_id >> 8) & 15) >= 6) || \ + (pctr_isintel && \ + (pctr_intel_cap & PCTR_INTEL_VERSION_MASK) >= 1)) int pctr_isamd; int pctr_isintel; +uint32_t pctr_intel_cap; static int p5ctrsel(int fflag, u_int cmd, u_int fn); static int pctrsel(int fflag, u_int cmd, u_int fn); static void pctrrd(struct pctrst *); -static void pctrrd(struct pctrst *); static void p5ctrrd(struct pctrst *st) @@ -73,13 +75,16 @@ pctrrd(struct pctrst *st) void pctrattach(int num) { + uint32_t dummy; if (num > 1) return; pctr_isamd = (strcmp(cpu_vendor, "AuthenticAMD") == 0); - if (!pctr_isamd) + if (!pctr_isamd) { pctr_isintel = (strcmp(cpu_vendor, "GenuineIntel") == 0); + CPUID(0xa, pctr_intel_cap, dummy, dummy, dummy); + } if (usepctr) { /* Enable RDTSC and RDPMC instructions from user-level. */ |