From owner-svn-src-all@FreeBSD.ORG Thu Aug 5 20:40:14 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 32A46106567D; Thu, 5 Aug 2010 20:40:14 +0000 (UTC) (envelope-from gnn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1F8438FC1D; Thu, 5 Aug 2010 20:40:14 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o75KeEHH099951; Thu, 5 Aug 2010 20:40:14 GMT (envelope-from gnn@svn.freebsd.org) Received: (from gnn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o75KeEiX099948; Thu, 5 Aug 2010 20:40:14 GMT (envelope-from gnn@svn.freebsd.org) Message-Id: <201008052040.o75KeEiX099948@svn.freebsd.org> From: "George V. Neville-Neil" Date: Thu, 5 Aug 2010 20:40:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210895 - stable/7/sys/dev/hwpmc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Aug 2010 20:40:14 -0000 Author: gnn Date: Thu Aug 5 20:40:13 2010 New Revision: 210895 URL: http://svn.freebsd.org/changeset/base/210895 Log: MFC: 210621 Make sure that we clear the correct bits when we turn off a PMC. It was possible that we could have turned a bit on but never cleared it. Extend the calls to rdmsr() to all necessary functions, not just those which previously caused a panic. Pointed out by: jhb@ Modified: stable/7/sys/dev/hwpmc/hwpmc_core.c stable/7/sys/dev/hwpmc/hwpmc_core.h Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/dev/hwpmc/hwpmc_core.c ============================================================================== --- stable/7/sys/dev/hwpmc/hwpmc_core.c Thu Aug 5 20:39:52 2010 (r210894) +++ stable/7/sys/dev/hwpmc/hwpmc_core.c Thu Aug 5 20:40:13 2010 (r210895) @@ -168,13 +168,13 @@ core_pcpu_fini(struct pmc_mdep *md, int core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri; for (n = 0; n < npmc; n++) { - msr = rdmsr(IAP_EVSEL0 + n); - wrmsr(IAP_EVSEL0 + n, msr & ~IAP_EVSEL_MASK); + msr = rdmsr(IAP_EVSEL0 + n) & ~IAP_EVSEL_MASK; + wrmsr(IAP_EVSEL0 + n, msr); } if (core_cputype != PMC_CPU_INTEL_CORE) { - msr = rdmsr(IAF_CTRL); - wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK); + msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; + wrmsr(IAF_CTRL, msr); npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num; } @@ -392,13 +392,13 @@ iaf_start_pmc(int cpu, int ri) iafc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl; - msr = rdmsr(IAF_CTRL); + msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK)); do { iafc->pc_resync = 0; iafc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET)); - msr = rdmsr(IA_GLOBAL_CTRL); + msr = rdmsr(IA_GLOBAL_CTRL) & ~IAF_GLOBAL_CTRL_MASK; wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl & IAF_GLOBAL_CTRL_MASK)); } while (iafc->pc_resync != 0); @@ -434,13 +434,13 @@ iaf_stop_pmc(int cpu, int ri) iafc->pc_iafctrl &= ~fc; PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl); - msr = rdmsr(IAF_CTRL); + msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK)); do { iafc->pc_resync = 0; iafc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET)); - msr = rdmsr(IA_GLOBAL_CTRL); + msr = rdmsr(IA_GLOBAL_CTRL) & ~IAF_GLOBAL_CTRL_MASK; wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl & IAF_GLOBAL_CTRL_MASK)); } while (iafc->pc_resync != 0); @@ -473,10 +473,14 @@ iaf_write_pmc(int cpu, int ri, pmc_value if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = iaf_reload_count_to_perfctr_value(v); - msr = rdmsr(IAF_CTRL); - wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK); + /* Turn off fixed counters */ + msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; + wrmsr(IAF_CTRL, msr); + wrmsr(IAF_CTR0 + ri, v & ((1ULL << core_iaf_width) - 1)); - msr = rdmsr(IAF_CTRL); + + /* Turn on fixed counters */ + msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK)); PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx " @@ -1910,15 +1914,17 @@ iap_stop_pmc(int cpu, int ri) PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri); - msr = rdmsr(IAP_EVSEL0 + ri); - wrmsr(IAP_EVSEL0 + ri, msr & IAP_EVSEL_MASK); /* stop hw */ + msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK; + wrmsr(IAP_EVSEL0 + ri, msr); /* stop hw */ if (core_cputype == PMC_CPU_INTEL_CORE) return (0); + msr = 0; do { cc->pc_resync = 0; cc->pc_globalctrl &= ~(1ULL << ri); + msr = rdmsr(IA_GLOBAL_CTRL) & ~IA_GLOBAL_CTRL_MASK; wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl); } while (cc->pc_resync != 0); @@ -2004,7 +2010,7 @@ core_intr(int cpu, struct trapframe *tf) struct pmc *pm; struct core_cpu *cc; int error, found_interrupt, ri; - uint64_t msr = 0; + uint64_t msr; PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); @@ -2036,15 +2042,15 @@ core_intr(int cpu, struct trapframe *tf) * Stop the counter, reload it but only restart it if * the PMC is not stalled. */ - msr = rdmsr(IAP_EVSEL0 + ri); - wrmsr(IAP_EVSEL0 + ri, msr & ~IAP_EVSEL_MASK); + msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK; + wrmsr(IAP_EVSEL0 + ri, msr); wrmsr(IAP_PMC0 + ri, v); if (error) continue; - wrmsr(IAP_EVSEL0 + ri, - pm->pm_md.pm_iap.pm_iap_evsel | IAP_EN); + wrmsr(IAP_EVSEL0 + ri, msr | (pm->pm_md.pm_iap.pm_iap_evsel | + IAP_EN)); } if (found_interrupt) @@ -2060,7 +2066,7 @@ static int core2_intr(int cpu, struct trapframe *tf) { int error, found_interrupt, n; - uint64_t flag, intrstatus, intrenable; + uint64_t flag, intrstatus, intrenable, msr; struct pmc *pm; struct core_cpu *cc; pmc_value_t v; @@ -2091,7 +2097,8 @@ core2_intr(int cpu, struct trapframe *tf /* * Stop PMCs and clear overflow status bits. */ - wrmsr(IA_GLOBAL_CTRL, 0); + msr = rdmsr(IA_GLOBAL_CTRL) & ~IA_GLOBAL_CTRL_MASK; + wrmsr(IA_GLOBAL_CTRL, msr); wrmsr(IA_GLOBAL_OVF_CTRL, intrenable | IA_GLOBAL_STATUS_FLAG_OVFBUF | IA_GLOBAL_STATUS_FLAG_CONDCHG); @@ -2162,7 +2169,7 @@ core2_intr(int cpu, struct trapframe *tf cc->pc_globalctrl |= intrenable; - wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl); + wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl & IA_GLOBAL_CTRL_MASK); PMCDBG(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx " "ovf=%jx", cpu, (uintmax_t) rdmsr(IAF_CTRL), Modified: stable/7/sys/dev/hwpmc/hwpmc_core.h ============================================================================== --- stable/7/sys/dev/hwpmc/hwpmc_core.h Thu Aug 5 20:39:52 2010 (r210894) +++ stable/7/sys/dev/hwpmc/hwpmc_core.h Thu Aug 5 20:40:13 2010 (r210895) @@ -144,6 +144,12 @@ struct pmc_md_iap_op_pmcallocate { /* The mask is only for the fixed porttion of the register. */ #define IAF_GLOBAL_CTRL_MASK 0x0000000700000000 +/* The mask is only for the programmable porttion of the register. */ +#define IAP_GLOBAL_CTRL_MASK 0x00000000ffffffff + +/* The mask is for both the fixed and programmable porttions of the register. */ +#define IA_GLOBAL_CTRL_MASK 0x00000007ffffffff + #define IA_GLOBAL_OVF_CTRL 0x390 #define IA_GLOBAL_STATUS_FLAG_CONDCHG (1ULL << 63)