mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 09:11:07 -04:00
If full width writes to the performance monitoring counters are
supported, use full-width aliases MSRs for writes. This fixes the "[pmc,X] negative increment" assertion on the context switch when clipped counter value is sign-extended. Add definitions for the MSR IA32_PERF_CAPABILITIES needed to detect the feature. PR: 207068 Submitted by: joss.upton@yahoo.com MFC after: 2 weeks
This commit is contained in:
parent
70c1d5a32a
commit
411c83ccd6
2 changed files with 34 additions and 11 deletions
|
|
@ -103,6 +103,7 @@ static int core_iaf_npmc;
|
|||
|
||||
static int core_iap_width;
|
||||
static int core_iap_npmc;
|
||||
static int core_iap_wroffset;
|
||||
|
||||
static int
|
||||
core_pcpu_noop(struct pmc_mdep *md, int cpu)
|
||||
|
|
@ -2473,7 +2474,7 @@ iap_read_pmc(int cpu, int ri, pmc_value_t *v)
|
|||
*v = tmp & ((1ULL << core_iap_width) - 1);
|
||||
|
||||
PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
|
||||
ri, *v);
|
||||
IAP_PMC0 + ri, *v);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -2605,19 +2606,20 @@ iap_write_pmc(int cpu, int ri, pmc_value_t v)
|
|||
("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
|
||||
cpu, ri));
|
||||
|
||||
PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
|
||||
IAP_PMC0 + ri, v);
|
||||
|
||||
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
|
||||
v = iap_reload_count_to_perfctr_value(v);
|
||||
|
||||
v &= (1ULL << core_iap_width) - 1;
|
||||
|
||||
PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
|
||||
IAP_PMC0 + ri, v);
|
||||
|
||||
/*
|
||||
* Write the new value to the counter. The counter will be in
|
||||
* a stopped state when the pcd_write() entry point is called.
|
||||
* Write the new value to the counter (or it's alias). The
|
||||
* counter will be in a stopped state when the pcd_write()
|
||||
* entry point is called.
|
||||
*/
|
||||
|
||||
wrmsr(IAP_PMC0 + ri, v & ((1ULL << core_iap_width) - 1));
|
||||
|
||||
wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -2700,7 +2702,7 @@ core_intr(int cpu, struct trapframe *tf)
|
|||
*/
|
||||
msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
|
||||
wrmsr(IAP_EVSEL0 + ri, msr);
|
||||
wrmsr(IAP_PMC0 + ri, v);
|
||||
wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v);
|
||||
|
||||
if (error)
|
||||
continue;
|
||||
|
|
@ -2814,7 +2816,7 @@ core2_intr(int cpu, struct trapframe *tf)
|
|||
(uintmax_t) v);
|
||||
|
||||
/* Reload sampling count. */
|
||||
wrmsr(IAP_PMC0 + n, v);
|
||||
wrmsr(core_iap_wroffset + IAP_PMC0 + n, v);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2865,6 +2867,18 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override)
|
|||
return (EPROGMISMATCH);
|
||||
}
|
||||
|
||||
core_iap_wroffset = 0;
|
||||
if (cpu_feature2 & CPUID2_PDCM) {
|
||||
if (rdmsr(IA32_PERF_CAPABILITIES) & PERFCAP_FW_WRITE) {
|
||||
PMCDBG0(MDP, INI, 1,
|
||||
"core-init full-width write supported");
|
||||
core_iap_wroffset = IAP_A_PMC0 - IAP_PMC0;
|
||||
} else
|
||||
PMCDBG0(MDP, INI, 1,
|
||||
"core-init full-width write NOT supported");
|
||||
} else
|
||||
PMCDBG0(MDP, INI, 1, "core-init pdcm not supported");
|
||||
|
||||
core_pmcmask = 0;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@
|
|||
#ifndef _DEV_HWPMC_CORE_H_
|
||||
#define _DEV_HWPMC_CORE_H_ 1
|
||||
|
||||
#define IA32_PERF_CAPABILITIES 0x345
|
||||
#define PERFCAP_LBR_FORMAT 0x003f
|
||||
#define PERFCAP_PEBS_TRAP 0x0040
|
||||
#define PERFCAP_PEBS_SAVEARCH 0x0080
|
||||
#define PERFCAP_PEBS_RECFORMAT 0x0f00
|
||||
#define PERFCAP_SMM_FREEZE 0x1000
|
||||
#define PERFCAP_FW_WRITE 0x2000 /* full width write aliases */
|
||||
|
||||
/*
|
||||
* Fixed-function PMCs.
|
||||
*/
|
||||
|
|
@ -101,6 +109,7 @@ struct pmc_md_iap_op_pmcallocate {
|
|||
*/
|
||||
|
||||
#define IAP_PMC0 0x0C1
|
||||
#define IAP_A_PMC0 0x4C1
|
||||
|
||||
/*
|
||||
* IAP_EVSEL(n) is laid out in the following way.
|
||||
|
|
|
|||
Loading…
Reference in a new issue