Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174179119
D59554.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D59554.diff
View Options
diff --git a/lib/libpmc/pmc.perf.3 b/lib/libpmc/pmc.perf.3
--- a/lib/libpmc/pmc.perf.3
+++ b/lib/libpmc/pmc.perf.3
@@ -8,7 +8,7 @@
.Os
.Sh NAME
.Nm pmc.perf
-.Nd measurements using the MPERF/APERF effective frequency counters
+.Nd measurements using the MPERF/APERF/IRPERF frequency counters
.Sh LIBRARY
.Lb libpmc
.Sh SYNOPSIS
@@ -38,12 +38,24 @@
scaled by the processor's nominal frequency, yields the
average effective frequency.
.Pp
+AMD processors additionally provide a third fixed-counter machine
+specific register,
+.Va IRPERF
+.Pq Dq Instructions Retired Performance Count ,
+which increments by one for each instruction retired by the core.
+Unlike
+.Va MPERF
+and
+.Va APERF ,
+.Va IRPERF
+is an AMD-only facility and is not available on Intel processors.
+.Pp
The
.Dv PMC_CLASS_PERF
-class exposes these two MSRs as read-only 64-bit counters that may
+class exposes these MSRs as read-only 64-bit counters that may
only be allocated in system-wide counting mode
.Pq Dv PMC_MODE_SC.
-Both counters expose the unmodified contents of the underlying MSRs.
+All counters expose the unmodified contents of the underlying MSRs.
.Pp
It reflects the free-running count of the underlying MSR since the
processor was last reset, and continues to accumulate across
@@ -77,12 +89,22 @@
.It Cm perf-aperf , Cm aperf
The Actual Performance Frequency Clock Count
MSR of the core the counter is bound to.
+.It Cm perf-irperf , Cm irperf
+The Instructions Retired Performance Count
+MSR of the core the counter is bound to.
+This event is only available on AMD processors; it is not
+supported on Intel processors.
+See
+.Sx Availability
+below for the full set of conditions that must hold for this
+event to be present.
.El
.Ss Counter Scope
-.Va MPERF
+.Va MPERF ,
+.Va APERF ,
and
-.Va APERF
-are per-core registers: each core has its own independent pair of
+.Va IRPERF
+are per-core registers: each core has its own independent set of
MSRs, and a PMC of this class always reads the value local to the
CPU it is bound to.
Readings from different cores must not be combined or averaged
@@ -108,10 +130,47 @@
.Xr pmccontrol 8
or
.Xr pmcstat 8 .
+.Pp
+The
+.Cm perf-irperf
+event is further restricted to AMD processors that advertise
+support for the IRPERF MSR in CPUID 8000_0008H bit 1 EBX.
+On processors that do not advertise this bit, including all
+Intel processors, the
+.Cm perf-irperf
+event specifier is not available even though the rest of the
+.Dv PMC_CLASS_PERF
+class may be present.
+.Pp
+Due to erratum #1054
+.Pq Dq Instructions Retired Performance Counter May Be Inaccurate ,
+IRPERF is additionally left disabled on affected AMD Zen 1 parts
+.Pq Family 17h, Models below 30h ,
+even though those processors advertise CPUID support for the MSR.
+It is enabled only for Zen 1 Family 17h Model 30h and later, and for
+all subsequent microarchitectures.
+.Pp
+As with
+.Va MPERF
+and
+.Va APERF ,
+the kernel also verifies, at boot time, that the IRPERF MSR is
+actually incrementing before enabling it; some virtualized
+environments advertise CPUID and erratum-safe family/model
+information without functional MSR support behind it.
+.Pp
+If IRPERF is unavailable for any of the reasons above, the rest of
+the
+.Dv PMC_CLASS_PERF
+class
+.Pq Va MPERF No and Va APERF
+is still registered normally; only the
+.Cm perf-irperf
+event specifier is absent.
.Sh EXAMPLES
-Sample both counters on CPU 0 for five seconds:
+Sample all three counters on CPU 0 for five seconds:
.Bd -literal -offset indent
-pmcstat -c 0 -s perf-mperf -s perf-aperf -w 5
+pmcstat -c 0 -s perf-mperf -s perf-aperf -s perf-irperf -w 5
.Ed
.Sh SEE ALSO
.Xr pmc 3 ,
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -275,6 +275,7 @@
void
initializecpu(void)
{
+ uint64_t irperf1, irperf2;
uint64_t msr;
uint64_t cr4;
@@ -360,6 +361,36 @@
(cpu_stdext_feature2 & CPUID_STDEXT2_RDPID) != 0)
wrmsr(MSR_TSC_AUX, cpu_auxmsr());
+ /*
+ * According to erratum #1054 "Instructions Retired Performance
+ * Counter May Be Inaccurate", the IRPERF feature should be
+ * enabled only for a subset of Zen 1 (Family 17h Models 30h and above)
+ * and all later processors.
+ *
+ * Separately, verify IRPERF is actually incrementing across two
+ * back-to-back reads. This only catches a dead/non-functional MSR
+ * (e.g. a hypervisor or emulator exposing the CPUID feature bit
+ * without real MSR support behind it) -- it cannot detect the
+ * erratum's actual failure mode, a counter that increments but
+ * returns inaccurate values. That case is handled entirely by the
+ * family/model check above.
+ *
+ * This runs on every core (BSP and each AP) via initializecpu();
+ * pmc_amd_initialize() later assumes IRPERF's enabled/disabled state
+ * is consistent across all cores.
+ */
+ if ((amd_extended_feature_extensions & AMDFEID_IRPERF) &&
+ ((CPUID_TO_FAMILY(cpu_id) > 0x17) ||
+ (CPUID_TO_FAMILY(cpu_id) == 0x17 && CPUID_TO_MODEL(cpu_id) >= 0x30))) {
+ wrmsr(MSR_HWCR, rdmsr(MSR_HWCR) | HWCR_IRPERFEN);
+
+ irperf1 = rdmsr(MSR_IRPERF);
+ irperf2 = rdmsr(MSR_IRPERF);
+
+ if (irperf2 <= irperf1)
+ wrmsr(MSR_HWCR, rdmsr(MSR_HWCR) & ~HWCR_IRPERFEN);
+ }
+
if (!IS_BSP())
cpu_init_small_core();
TSEXIT();
diff --git a/sys/amd64/include/pmc_mdep.h b/sys/amd64/include/pmc_mdep.h
--- a/sys/amd64/include/pmc_mdep.h
+++ b/sys/amd64/include/pmc_mdep.h
@@ -67,7 +67,7 @@
* TSC The timestamp counter
* K8 AMD Athlon64 and Opteron PMCs in 64 bit mode.
* IBS AMD IBS
- * PERF AMD/Intel MPERF and APERF
+ * PERF AMD/Intel MPERF, APERF and IRPERF
* IAP Intel Core/Core2/Atom CPUs in 64 bits mode.
* IAF Intel fixed-function PMCs in Core2 and later CPUs.
* UCP Intel Uncore programmable PMCs.
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -1150,8 +1150,21 @@
* cpu_startup() -> startrtclock()), not by hwpmc's TSC PMC class. It is
* set only after confirming both MSRs actually increment (some emulators
* expose the CPUID bit without real MSR support).
+ *
+ * Separately, detect support for the IRPERF MSR (AMD-only). If the
+ * feature is present, HWCR_IRPERFEN should already be set in MSR_HWCR
+ * by initializecpu() at boot, which also accounts for erratum #1054
+ * (IRPERF is left disabled on affected Zen 1 parts) and verifies IRPERF
+ * is actually incrementing on a dead/emulated MSR. This code only reads
+ * back that already-decided state.
+ *
+ * Either condition above causes the PERF class to be registered, so at
+ * least one of MPERF/APERF or IRPERF is expected to be usable when this
+ * branch is taken.
*/
- if ((cpu_power_ecx & CPUID_PERF_STAT) && (tsc_perf_stat == 1)) {
+ if (((cpu_power_ecx & CPUID_PERF_STAT) && (tsc_perf_stat == 1)) ||
+ ((amd_extended_feature_extensions & AMDFEID_IRPERF) &&
+ (rdmsr(MSR_HWCR) & HWCR_IRPERFEN))) {
nclasses++;
}
diff --git a/sys/dev/hwpmc/hwpmc_perf.h b/sys/dev/hwpmc/hwpmc_perf.h
--- a/sys/dev/hwpmc/hwpmc_perf.h
+++ b/sys/dev/hwpmc/hwpmc_perf.h
@@ -3,21 +3,21 @@
*
* SPDX-License-Identifier: BSD-2-Clause
*
- * AMD/Intel MPERF and APERF MSRs counters exposed as an hwpmc(4) PMC class.
+ * AMD/Intel MPERF/APERF MSR counters, and the AMD-only IRPERF counter,
+ * exposed as an hwpmc(4) PMC class.
*/
#ifdef _KERNEL
/*
- * A row per MSR: MPERF and APERF.
+ * A row per MSR: MPERF, APERF and IRPERF.
*/
-#define PERF_NPMCS 2
-#define PERF_MPERF 0
-#define PERF_APERF 1
+#define PERF_NPMCS_TOTAL 3
-extern int tsc_perf_stat;
-extern u_int cpu_power_ecx;
+extern int tsc_perf_stat;
+extern u_int cpu_power_ecx;
+extern u_int amd_extended_feature_extensions;
/*
* Prototypes.
diff --git a/sys/dev/hwpmc/hwpmc_perf.c b/sys/dev/hwpmc/hwpmc_perf.c
--- a/sys/dev/hwpmc/hwpmc_perf.c
+++ b/sys/dev/hwpmc/hwpmc_perf.c
@@ -3,10 +3,11 @@
*
* SPDX-License-Identifier: BSD-2-Clause
*
- * AMD/Intel MPERF and APERF MSRs counters exposed as an hwpmc(4) PMC class.
+ * AMD/Intel MPERF/APERF and AMD-only IRPERF MSR counters exposed as an
+ * hwpmc(4) PMC class.
*
* Read-only, system-scope (PMC_MODE_SC), 64-bit counters reporting
- * MPERF and APERF MSR values.
+ * MPERF/APERF and IRPERF MSR values.
*/
#include <sys/param.h>
@@ -18,31 +19,18 @@
#define PERF_CAPS PMC_CAP_READ
+static int perf_npmcs = 0;
+
struct perf_descr {
struct pmc_descr pm_descr; /* "base class" */
+ enum pmc_event pm_ev;
+ u_int pm_msr;
};
-static const struct perf_descr perf_pmcdesc[PERF_NPMCS] = {
- {
- .pm_descr = {
- .pd_name = "MPERF",
- .pd_class = PMC_CLASS_PERF,
- .pd_caps = PERF_CAPS,
- .pd_width = 64
- },
- },
- {
- .pm_descr = {
- .pd_name = "APERF",
- .pd_class = PMC_CLASS_PERF,
- .pd_caps = PERF_CAPS,
- .pd_width = 64
- }
- }
-};
+static struct perf_descr perf_pmcdesc[PERF_NPMCS_TOTAL];
struct perf_cpu {
- struct pmc_hw tc_hw[PERF_NPMCS];
+ struct pmc_hw tc_hw[PERF_NPMCS_TOTAL];
};
static struct perf_cpu **perf_pcpu;
@@ -54,7 +42,7 @@
{
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS,
+ KASSERT(ri >= 0 && ri < perf_npmcs,
("[perf,%d] illegal row index %d", __LINE__, ri));
if (a->pm_class != PMC_CLASS_PERF)
@@ -69,7 +57,6 @@
* Frequency is an indirect power proxy and could be abused by
* attacks like Hertzbleed.
*/
-
if (priv_check(curthread, PRIV_PMC_SYSTEM) != 0)
return (EPERM);
@@ -78,18 +65,8 @@
if ((a->pm_caps & ~PERF_CAPS) != 0)
return (EPERM);
- switch (ri) {
- case PERF_MPERF:
- if (a->pm_ev != PMC_EV_PERF_MPERF)
- return (EINVAL);
- break;
- case PERF_APERF:
- if (a->pm_ev != PMC_EV_PERF_APERF)
- return (EINVAL);
- break;
- default:
+ if (a->pm_ev != perf_pmcdesc[ri].pm_ev)
return (EINVAL);
- }
return (0);
}
@@ -103,7 +80,7 @@
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal row-index %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal row-index %d",
__LINE__, ri));
phw = &perf_pcpu[cpu]->tc_hw[ri];
@@ -125,7 +102,7 @@
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal row-index %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal row-index %d",
__LINE__, ri));
phw = &perf_pcpu[cpu]->tc_hw[ri];
@@ -150,7 +127,7 @@
{
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal row-index %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal row-index %d",
__LINE__, ri));
*ppm = perf_pcpu[cpu]->tc_hw[ri].phw_pmc;
@@ -161,7 +138,7 @@
static int
perf_get_msr(int ri __diagused, uint32_t *msr __unused)
{
- KASSERT(ri >= 0 && ri < PERF_NPMCS,
+ KASSERT(ri >= 0 && ri < perf_npmcs,
("[perf,%d] ri %d out of range", __LINE__, ri));
return (EINVAL);
@@ -183,7 +160,7 @@
ri = md->pmd_classdep[perf_classindex].pcd_ri;
pc = pmc_pcpu[cpu];
- for (i = 0; i < PERF_NPMCS; i++) {
+ for (i = 0; i < perf_npmcs; i++) {
pc->pc_hwpmcs[i + ri] = NULL;
}
@@ -215,7 +192,7 @@
KASSERT(pc, ("[perf,%d] null generic per-cpu", __LINE__));
- for (i = 0; i < PERF_NPMCS; i++) {
+ for (i = 0; i < perf_npmcs; i++) {
perf_pc->tc_hw[i].phw_state = PMC_PHW_FLAG_IS_ENABLED |
PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i) |
PMC_PHW_FLAG_IS_SHAREABLE;
@@ -232,7 +209,7 @@
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal ri %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal ri %d",
__LINE__, ri));
mode = PMC_TO_MODE(pm);
@@ -242,16 +219,7 @@
PMCDBG1(MDP, REA, 1, "perf-read id=%d", ri);
- switch (ri) {
- case PERF_MPERF:
- *v = rdmsr(MSR_MPERF);
- break;
- case PERF_APERF:
- *v = rdmsr(MSR_APERF);
- break;
- default:
- return (EINVAL);
- }
+ *v = rdmsr(perf_pmcdesc[ri].pm_msr);
return (0);
}
@@ -262,7 +230,7 @@
{
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal row-index %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal row-index %d",
__LINE__, ri));
return (0);
@@ -273,7 +241,7 @@
{
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS,
+ KASSERT(ri >= 0 && ri < perf_npmcs,
("[perf,%d] illegal row-index %d", __LINE__, ri));
KASSERT(perf_pcpu[cpu]->tc_hw[ri].phw_pmc == NULL,
("[perf,%d] PHW pmc non-NULL", __LINE__));
@@ -286,7 +254,7 @@
{
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal row-index %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal row-index %d",
__LINE__, ri));
return (0);
@@ -297,7 +265,7 @@
{
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[perf,%d] illegal CPU value %d", __LINE__, cpu));
- KASSERT(ri >= 0 && ri < PERF_NPMCS, ("[perf,%d] illegal row-index %d",
+ KASSERT(ri >= 0 && ri < perf_npmcs, ("[perf,%d] illegal row-index %d",
__LINE__, ri));
return (0);
@@ -313,6 +281,46 @@
__LINE__, md->pmd_nclass));
if ((cpu_power_ecx & CPUID_PERF_STAT) && (tsc_perf_stat == 1)) {
+ strlcpy(perf_pmcdesc[perf_npmcs].pm_descr.pd_name, "MPERF",
+ PMC_NAME_MAX);
+
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_class = PMC_CLASS_PERF;
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_caps = PERF_CAPS;
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_width = 64;
+ perf_pmcdesc[perf_npmcs].pm_msr = MSR_MPERF;
+ perf_pmcdesc[perf_npmcs].pm_ev = PMC_EV_PERF_MPERF;
+ perf_npmcs++;
+
+ strlcpy(perf_pmcdesc[perf_npmcs].pm_descr.pd_name, "APERF",
+ PMC_NAME_MAX);
+
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_class = PMC_CLASS_PERF;
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_caps = PERF_CAPS;
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_width = 64;
+ perf_pmcdesc[perf_npmcs].pm_msr = MSR_APERF;
+ perf_pmcdesc[perf_npmcs].pm_ev = PMC_EV_PERF_APERF;
+ perf_npmcs++;
+ }
+
+ /*
+ * The IRPERF MSR is supported only for AMD CPUs. The feature is
+ * enabled during the boot on each CPU available if AMDFEID_IRPERF
+ * is set on amd_extended_feature_extensions.
+ */
+ if ((amd_extended_feature_extensions & AMDFEID_IRPERF) &&
+ (rdmsr(MSR_HWCR) & HWCR_IRPERFEN)) {
+ strlcpy(perf_pmcdesc[perf_npmcs].pm_descr.pd_name, "IRPERF",
+ PMC_NAME_MAX);
+
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_class = PMC_CLASS_PERF;
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_caps = PERF_CAPS;
+ perf_pmcdesc[perf_npmcs].pm_descr.pd_width = 64;
+ perf_pmcdesc[perf_npmcs].pm_msr = MSR_IRPERF;
+ perf_pmcdesc[perf_npmcs].pm_ev = PMC_EV_PERF_IRPERF;
+ perf_npmcs++;
+ }
+
+ if (perf_npmcs) {
perf_pcpu = malloc(sizeof(struct perf_cpu *) * maxcpu, M_PMC,
M_ZERO | M_WAITOK);
@@ -320,9 +328,9 @@
perf_classindex = classindex;
pcd = &md->pmd_classdep[classindex];
- pcd->pcd_caps = PMC_CAP_READ;
+ pcd->pcd_caps = PERF_CAPS;
pcd->pcd_class = PMC_CLASS_PERF;
- pcd->pcd_num = PERF_NPMCS;
+ pcd->pcd_num = perf_npmcs;
pcd->pcd_ri = md->pmd_npmc;
pcd->pcd_width = 64;
@@ -339,7 +347,7 @@
pcd->pcd_start_pmc = perf_start_pmc;
pcd->pcd_stop_pmc = perf_stop_pmc;
- md->pmd_npmc += PERF_NPMCS;
+ md->pmd_npmc += perf_npmcs;
}
return (0);
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -62,13 +62,14 @@
#define PMC_EV_RAPL_FIRST PMC_EV_RAPL_ENERGY_PKG
#define PMC_EV_RAPL_LAST PMC_EV_RAPL_ENERGY_DRAM
-/* MPERF / APERF MSRs */
+/* MPERF / APERF / IRPERF MSRs */
#define __PMC_EV_PERF() \
__PMC_EV(PERF, MPERF) \
- __PMC_EV(PERF, APERF)
+ __PMC_EV(PERF, APERF) \
+ __PMC_EV(PERF, IRPERF)
#define PMC_EV_PERF_FIRST PMC_EV_PERF_MPERF
-#define PMC_EV_PERF_LAST PMC_EV_PERF_APERF
+#define PMC_EV_PERF_LAST PMC_EV_PERF_IRPERF
/*
* Software events are dynamically defined.
diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h
--- a/sys/x86/include/specialreg.h
+++ b/sys/x86/include/specialreg.h
@@ -110,6 +110,28 @@
#define EFER_UAIE 0x000100000 /* Upper Address Ignore */
#define EFER_AIBRSE 0x000200000 /* Automatic IBRS */
+/*
+ * Bits in AMD64 special registers. HWCR is 64 bits wide
+ */
+#define HWCR_SMMLOCK 0x00000001 /* SMM code lock (R/W) */
+#define HWCR_TLBCACHEDIS 0x00000008 /* Cacheable memory disable (R/W) */
+#define HWCR_INVDWBINVD 0x00000010 /* INVD to WBINVD conversion (R/W) */
+#define HWCR_ALLOWFERRONNE 0x00000080 /* Allow FERR on NE (R/W) */
+#define HWCR_IGNNEEM 0x00000100 /* IGNNE port emulation enable (R/W) */
+#define HWCR_MONMWAITDIS 0x00000200 /* MONITOR and MWAIT disable (R/W) */
+#define HWCR_MONMWAITUSEREN 0x00000400 /* MONITOR/MWAIT user mode enable (R/W) */
+#define HWCR_SMISPCYCDIS 0x00002000 /* SMI special bus cycle disable */
+#define HWCR_RSMSPCYCDIS 0x00004000 /* RSM special bus cycle disable */
+#define HWCR_WRAP32DIS 0x00020000 /* 32-bit address wrap disable (R/W) */
+#define HWCR_MCSTATUSWREN 0x00040000 /* Machine check status write enable (R/W) */
+#define HWCR_IOCFGGPFAULT 0x00100000 /* IO-space configuration causes a GP fault (R/W) */
+#define HWCR_LOCKTSCTOCURRENTP0 0x00200000 /* Lock the TSC to the current P0 frequency (R/W) */
+#define HWCR_TSCFREQSEL 0x01000000 /* TSC frequency select (R) */
+#define HWCR_CPBDIS 0x02000000 /* Core performance boost disable (R/W) */
+#define HWCR_EFFFREQCNTMWAIT 0x04000000 /* Effective frequency counting during mwait (R/W) */
+#define HWCR_EFFFREQREADONLYLOCK 0x08000000 /* Read-only effective frequency counter lock */
+#define HWCR_IRPERFEN 0x40000000 /* Enable instructions retired counter (R/W) */
+
/*
* Intel Extended Features registers
*/
@@ -1240,6 +1262,7 @@
#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target rip */
#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target rip */
#define MSR_SF_MASK 0xc0000084 /* syscall flags mask */
+#define MSR_IRPERF 0xc00000e9 /* instructions retired performance count */
#define MSR_FSBASE 0xc0000100 /* base address of the %fs "segment" */
#define MSR_GSBASE 0xc0000101 /* base address of the %gs "segment" */
#define MSR_KGSBASE 0xc0000102 /* base address of the kernel %gs */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 2, 4:30 AM (9 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40059736
Default Alt Text
D59554.diff (18 KB)
Attached To
Mode
D59554: hwpmc: Add support for AMD-only IRPERF in hwpmc PERF class
Attached
Detach File
Event Timeline
Log In to Comment