diff options
author | jhb <jhb@FreeBSD.org> | 2009-08-14 21:05:08 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-08-14 21:05:08 +0000 |
commit | d51166f15e1c08fdaa3df0992553ad5127da220c (patch) | |
tree | 1e489c7e0c2d17d61d5e2834cc3640b7fd564688 /sys/dev/hwpmc | |
parent | 0bf7e62afcd04d831d3e938d18021d02451fd181 (diff) | |
download | FreeBSD-src-d51166f15e1c08fdaa3df0992553ad5127da220c.zip FreeBSD-src-d51166f15e1c08fdaa3df0992553ad5127da220c.tar.gz |
Adjust the handling of the local APIC PMC interrupt vector:
- Provide lapic_disable_pmc(), lapic_enable_pmc(), and lapic_reenable_pmc()
routines in the local APIC code that the hwpmc(4) driver can use to
manage the local APIC PMC interrupt vector.
- Do not enable the local APIC PMC interrupt vector by default when
HWPMC_HOOKS is enabled. Instead, the hwpmc(4) driver explicitly
enables the interrupt when it is succesfully initialized and disables
the interrupt when it is unloaded. This avoids enabling the interrupt
on unsupported CPUs which may result in spurious NMIs.
Reported by: rnoland
Reviewed by: jkoshy
Approved by: re (kib)
MFC after: 2 weeks
Diffstat (limited to 'sys/dev/hwpmc')
-rw-r--r-- | sys/dev/hwpmc/hwpmc_core.c | 7 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_piv.c | 5 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_ppro.c | 5 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_x86.c | 22 |
4 files changed, 19 insertions, 20 deletions
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 214e42c..f84e0f1 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -32,10 +32,13 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/bus.h> #include <sys/pmc.h> #include <sys/pmckern.h> #include <sys/systm.h> +#include <machine/intr_machdep.h> +#include <machine/apicvar.h> #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/specialreg.h> @@ -1771,7 +1774,7 @@ core_intr(int cpu, struct trapframe *tf) } if (found_interrupt) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(found_interrupt ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); @@ -1895,7 +1898,7 @@ core2_intr(int cpu, struct trapframe *tf) (uintmax_t) rdmsr(IA_GLOBAL_OVF_CTRL)); if (found_interrupt) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(found_interrupt ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c index 565be88..8ee8518 100644 --- a/sys/dev/hwpmc/hwpmc_piv.c +++ b/sys/dev/hwpmc/hwpmc_piv.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/bus.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/pmc.h> @@ -39,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <sys/systm.h> +#include <machine/intr_machdep.h> +#include <machine/apicvar.h> #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/cputypes.h> @@ -1537,7 +1540,7 @@ p4_intr(int cpu, struct trapframe *tf) */ if (did_interrupt) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(did_interrupt ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); diff --git a/sys/dev/hwpmc/hwpmc_ppro.c b/sys/dev/hwpmc/hwpmc_ppro.c index 909bfe2..8da185b 100644 --- a/sys/dev/hwpmc/hwpmc_ppro.c +++ b/sys/dev/hwpmc/hwpmc_ppro.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/bus.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/pmc.h> @@ -39,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <sys/systm.h> +#include <machine/intr_machdep.h> +#include <machine/apicvar.h> #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/cputypes.h> @@ -718,7 +721,7 @@ p6_intr(int cpu, struct trapframe *tf) * unmasked after a PMC interrupt. */ if (retval) - pmc_x86_lapic_enable_pmc_interrupt(); + lapic_reenable_pmc(); atomic_add_int(retval ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c index b48a6b0..09d04bb 100644 --- a/sys/dev/hwpmc/hwpmc_x86.c +++ b/sys/dev/hwpmc/hwpmc_x86.c @@ -39,7 +39,8 @@ __FBSDID("$FreeBSD$"); #include <machine/cpu.h> #include <machine/cputypes.h> -#include <machine/apicreg.h> +#include <machine/intr_machdep.h> +#include <machine/apicvar.h> #include <machine/pmc_mdep.h> #include <machine/md_var.h> @@ -47,18 +48,6 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_param.h> #include <vm/pmap.h> -extern volatile lapic_t *lapic; - -void -pmc_x86_lapic_enable_pmc_interrupt(void) -{ - uint32_t value; - - value = lapic->lvt_pcint; - value &= ~APIC_LVT_M; - lapic->lvt_pcint = value; -} - /* * Attempt to walk a user call stack using a too-simple algorithm. * In the general case we need unwind information associated with @@ -252,16 +241,15 @@ pmc_md_initialize() struct pmc_mdep *md; /* determine the CPU kind */ - md = NULL; if (cpu_vendor_id == CPU_VENDOR_AMD) md = pmc_amd_initialize(); else if (cpu_vendor_id == CPU_VENDOR_INTEL) md = pmc_intel_initialize(); else - KASSERT(0, ("[x86,%d] Unknown vendor", __LINE__)); + return (NULL); /* disallow sampling if we do not have an LAPIC */ - if (md != NULL && lapic == NULL) + if (!lapic_enable_pmc()) for (i = 1; i < md->pmd_nclass; i++) md->pmd_classdep[i].pcd_caps &= ~PMC_CAP_INTERRUPT; @@ -271,6 +259,8 @@ pmc_md_initialize() void pmc_md_finalize(struct pmc_mdep *md) { + + lapic_disable_pmc(); if (cpu_vendor_id == CPU_VENDOR_AMD) pmc_amd_finalize(md); else if (cpu_vendor_id == CPU_VENDOR_INTEL) |