Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150972931
D33654.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D33654.diff
View Options
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
@@ -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;
diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c
--- a/sys/dev/hwpmc/hwpmc_arm64.c
+++ b/sys/dev/hwpmc/hwpmc_arm64.c
@@ -218,8 +218,7 @@
if ((READ_SPECIALREG(pmovsclr_el0) & reg) != 0) {
/* Clear Overflow Flag */
WRITE_SPECIALREG(pmovsclr_el0, reg);
- if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- pm->pm_pcpu_state[cpu].pps_overflowcnt++;
+ pm->pm_pcpu_state[cpu].pps_overflowcnt++;
/* Reread counter in case we raced. */
tmp = arm64_pmcn_read(ri);
@@ -228,10 +227,18 @@
intr_restore(s);
PMCDBG2(MDP, REA, 2, "arm64-read id=%d -> %jd", ri, tmp);
- if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- *v = ARMV8_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
- 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 & (1ull << 63)) == 0)
+ tmp = 0;
+ else
+ tmp = ARMV8_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
+ }
+ *v = tmp;
return (0);
}
@@ -379,10 +386,10 @@
retval = 1; /* Found an interrupting PMC. */
- if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
- pm->pm_pcpu_state[cpu].pps_overflowcnt += 1;
+ pm->pm_pcpu_state[cpu].pps_overflowcnt += 1;
+
+ if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
continue;
- }
if (pm->pm_state != PMC_STATE_RUNNING)
continue;
diff --git a/sys/dev/hwpmc/hwpmc_armv7.c b/sys/dev/hwpmc/hwpmc_armv7.c
--- a/sys/dev/hwpmc/hwpmc_armv7.c
+++ b/sys/dev/hwpmc/hwpmc_armv7.c
@@ -189,8 +189,7 @@
if ((cp15_pmovsr_get() & reg) != 0) {
/* Clear Overflow Flag */
cp15_pmovsr_set(reg);
- if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- pm->pm_pcpu_state[cpu].pps_overflowcnt++;
+ 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);
@@ -199,10 +198,18 @@
intr_restore(s);
PMCDBG2(MDP, REA, 2, "armv7-read id=%d -> %jd", ri, tmp);
- if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- *v = ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
- 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 & (1ull << 63)) == 0)
+ tmp = 0;
+ else
+ tmp = ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
+ }
+ *v = tmp;
return 0;
}
@@ -360,10 +367,11 @@
retval = 1; /* Found an interrupting PMC. */
- if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
- pm->pm_pcpu_state[cpu].pps_overflowcnt += 1;
+ pm->pm_pcpu_state[cpu].pps_overflowcnt += 1;
+
+ if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
continue;
- }
+
if (pm->pm_state != PMC_STATE_RUNNING)
continue;
diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c
--- a/sys/dev/hwpmc/hwpmc_uncore.c
+++ b/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
Mon, Apr 6, 6:11 AM (4 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30855546
Default Alt Text
D33654.diff (3 KB)
Attached To
Mode
D33654: hwpmc: Fix amd/arm64/armv7/uncore sampling overflow race
Attached
Detach File
Event Timeline
Log In to Comment