Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142083368
D33654.id100563.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D33654.id100563.diff
View Options
Index: sys/dev/hwpmc/hwpmc_amd.c
===================================================================
--- sys/dev/hwpmc/hwpmc_amd.c
+++ sys/dev/hwpmc/hwpmc_amd.c
@@ -431,9 +431,18 @@
tmp = rdmsr(pd->pm_perfctr); /* RDMSR serializes */
PMCDBG2(MDP,REA,2,"amd-read (pre-munge) id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(mode)) {
- /* Sign extend 48 bit value to 64 bits. */
- tmp = (pmc_value_t) (((int64_t) tmp << 16) >> 16);
- tmp = AMD_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
+ /*
+ * Clamp value to 0 if the counter just overflowed,
+ * otherwise the returned reload count would wrap to a
+ * huge value.
+ */
+ if ((tmp & (1ULL << 47)) == 0)
+ tmp = 0;
+ else {
+ /* Sign extend 48 bit value to 64 bits. */
+ tmp = (pmc_value_t) (((int64_t) tmp << 16) >> 16);
+ tmp = AMD_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
+ }
}
*v = tmp;
Index: sys/dev/hwpmc/hwpmc_arm64.c
===================================================================
--- sys/dev/hwpmc/hwpmc_arm64.c
+++ sys/dev/hwpmc/hwpmc_arm64.c
@@ -218,11 +218,19 @@
if ((READ_SPECIALREG(pmovsclr_el0) & reg) != 0) {
/* Clear Overflow Flag */
WRITE_SPECIALREG(pmovsclr_el0, reg);
- if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
+ /*
+ * Clamp value to 0 if the counter just overflowed,
+ * otherwise the returned reload count would wrap to a
+ * huge value.
+ */
+ tmp = 0;
+ } else {
pm->pm_pcpu_state[cpu].pps_overflowcnt++;
- /* Reread counter in case we raced. */
- tmp = arm64_pmcn_read(ri);
+ /* Reread counter in case we raced. */
+ tmp = arm64_pmcn_read(ri);
+ }
}
tmp += 0x100000000llu * pm->pm_pcpu_state[cpu].pps_overflowcnt;
intr_restore(s);
Index: sys/dev/hwpmc/hwpmc_armv7.c
===================================================================
--- sys/dev/hwpmc/hwpmc_armv7.c
+++ sys/dev/hwpmc/hwpmc_armv7.c
@@ -189,11 +189,20 @@
if ((cp15_pmovsr_get() & reg) != 0) {
/* Clear Overflow Flag */
cp15_pmovsr_set(reg);
- if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
+ /*
+ * Clamp value to 0 if the counter just overflowed,
+ * otherwise the returned reload count would wrap to a
+ * huge value.
+ */
+ tmp = 0;
+ } else {
pm->pm_pcpu_state[cpu].pps_overflowcnt++;
- /* Reread counter in case we raced. */
- tmp = armv7_pmcn_read(ri, pm->pm_md.pm_armv7.pm_armv7_evsel);
+ /* Reread counter in case we raced. */
+ tmp = armv7_pmcn_read(ri,
+ pm->pm_md.pm_armv7.pm_armv7_evsel);
+ }
}
tmp += 0x100000000llu * pm->pm_pcpu_state[cpu].pps_overflowcnt;
intr_restore(s);
Index: sys/dev/hwpmc/hwpmc_mips.c
===================================================================
--- sys/dev/hwpmc/hwpmc_mips.c
+++ sys/dev/hwpmc/hwpmc_mips.c
@@ -127,10 +127,23 @@
tmp = mips_pmcn_read(ri);
PMCDBG2(MDP,REA,2,"mips-read id=%d -> %jd", ri, tmp);
- if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- *v = tmp - (1UL << (mips_pmc_spec.ps_counter_width - 1));
- else
- *v = tmp;
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
+ /*
+ * Clamp value to 0 if the counter just overflowed,
+ * otherwise the returned reload count would wrap to a
+ * huge value.
+ */
+ if ((tmp & (1UL << (mips_pmc_spec.ps_counter_width - 1))) == 0)
+ tmp = 0;
+ else {
+ /* Sign extend value to 64 bits. */
+ tmp = (pmc_value_t) (((int64_t) tmp
+ << (64 - mips_pmc_spec.ps_counter_width))
+ >> (64 - mips_pmc_spec.ps_counter_width));
+ tmp = -tmp;
+ }
+ }
+ *v = tmp;
return 0;
}
@@ -147,8 +160,13 @@
pm = mips_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc;
- if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- v = (1UL << (mips_pmc_spec.ps_counter_width - 1)) - v;
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
+ v = -v;
+ /* Truncate from 64 bits. */
+ v = (pmc_value_t) (((uint64_t) v
+ << (64 - mips_pmc_spec.ps_counter_width))
+ >> (64 - mips_pmc_spec.ps_counter_width));
+ }
PMCDBG3(MDP,WRI,1,"mips-write cpu=%d ri=%d v=%jx", cpu, ri, v);
Index: sys/dev/hwpmc/hwpmc_uncore.c
===================================================================
--- sys/dev/hwpmc/hwpmc_uncore.c
+++ sys/dev/hwpmc/hwpmc_uncore.c
@@ -175,6 +175,10 @@
static pmc_value_t
ucf_perfctr_value_to_reload_count(pmc_value_t v)
{
+
+ /* If the PMC has overflowed, return a reload count of zero. */
+ if ((v & (1ULL << (uncore_ucf_width - 1))) == 0)
+ return (0);
v &= (1ULL << uncore_ucf_width) - 1;
return (1ULL << uncore_ucf_width) - v;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 16, 9:30 PM (17 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27670056
Default Alt Text
D33654.id100563.diff (4 KB)
Attached To
Mode
D33654: hwpmc: Fix amd/arm64/armv7/uncore sampling overflow race
Attached
Detach File
Event Timeline
Log In to Comment