summaryrefslogtreecommitdiff
path: root/static/freebsd/man4/hwpmc.4 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man4/hwpmc.4 3.html')
-rw-r--r--static/freebsd/man4/hwpmc.4 3.html755
1 files changed, 755 insertions, 0 deletions
diff --git a/static/freebsd/man4/hwpmc.4 3.html b/static/freebsd/man4/hwpmc.4 3.html
new file mode 100644
index 00000000..a1ad831b
--- /dev/null
+++ b/static/freebsd/man4/hwpmc.4 3.html
@@ -0,0 +1,755 @@
+<table class="head">
+ <tr>
+ <td class="head-ltitle">HWPMC(4)</td>
+ <td class="head-vol">Device Drivers Manual</td>
+ <td class="head-rtitle">HWPMC(4)</td>
+ </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<p class="Pp"><code class="Nm">hwpmc</code> &#x2014; <span class="Nd">Hardware
+ Performance Monitoring Counter support</span></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
+<p class="Pp">The following option must be present in the kernel configuration
+ file:</p>
+<div class="Bd Pp Bd-indent"><code class="Cd">options HWPMC_HOOKS</code></div>
+<p class="Pp">Additionally, for i386 systems:</p>
+<div class="Bd Pp Bd-indent"><code class="Cd">device apic</code></div>
+<p class="Pp">To load the driver as a module at boot time:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>sysrc kld_list+=hwpmc</pre>
+</div>
+<p class="Pp">Alternatively, to compile the driver into the kernel:</p>
+<div class="Bd Pp Bd-indent"><code class="Cd">device hwpmc</code></div>
+<p class="Pp">To enable debugging features (see
+ <a class="Sx" href="#DEBUGGING">DEBUGGING</a>):</p>
+<div class="Bd Pp Bd-indent"><code class="Cd">options KTR</code>
+<br/>
+<code class="Cd">options KTR_COMPILE=(KTR_SUBSYS)</code>
+<br/>
+<code class="Cd">options KTR_MASK=(KTR_SUBSYS)</code>
+<br/>
+<code class="Cd">options HWPMC_DEBUG</code></div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+<p class="Pp">The <code class="Nm">hwpmc</code> driver virtualizes the hardware
+ performance monitoring facilities in modern CPUs and provides support for
+ using these facilities from user level processes.</p>
+<p class="Pp">The driver supports multi-processor systems.</p>
+<p class="Pp">PMCs are allocated using the
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request. A successful
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request will return a handle to
+ the requesting process. Subsequent operations on the allocated PMC use this
+ handle to denote the specific PMC. A process that has successfully allocated
+ a PMC is termed an &#x201C;owner process&#x201D;.</p>
+<p class="Pp">PMCs may be allocated with process or system scope.</p>
+<dl class="Bl-tag">
+ <dt id="Process-scope"><a class="permalink" href="#Process-scope"><i class="Em">Process-scope</i></a></dt>
+ <dd>The PMC is active only when a thread belonging to a process it is attached
+ to is scheduled on a CPU.</dd>
+ <dt id="System-scope"><a class="permalink" href="#System-scope"><i class="Em">System-scope</i></a></dt>
+ <dd>The PMC operates independently of processes and measures hardware events
+ for the system as a whole.</dd>
+</dl>
+<p class="Pp">PMCs may be allocated for counting or for sampling:</p>
+<dl class="Bl-tag">
+ <dt id="Counting"><a class="permalink" href="#Counting"><i class="Em">Counting</i></a></dt>
+ <dd>In counting modes, the PMCs count hardware events. These counts are
+ retrievable using the <code class="Dv">PMC_OP_PMCREAD</code> system call
+ on all architectures. Some architectures offer faster methods of reading
+ these counts.</dd>
+ <dt id="Sampling"><a class="permalink" href="#Sampling"><i class="Em">Sampling</i></a></dt>
+ <dd>In sampling modes, the PMCs are configured to sample the CPU instruction
+ pointer (and optionally to capture the call chain leading up to the
+ sampled instruction pointer) after a configurable number of hardware
+ events have been observed. Instruction pointer samples and call chain
+ records are usually directed to a log file for subsequent analysis.</dd>
+</dl>
+<p class="Pp">Scope and operational mode are orthogonal; a PMC may thus be
+ configured to operate in one of the following four modes:</p>
+<dl class="Bl-tag">
+ <dt>Process-scope, counting</dt>
+ <dd>These PMCs count hardware events whenever a thread in their attached
+ process is scheduled on a CPU. These PMCs normally count from zero, but
+ the initial count may be set using the
+ <code class="Dv">PMC_OP_SETCOUNT</code> operation. Applications can read
+ the value of the PMC anytime using the
+ <code class="Dv">PMC_OP_PMCRW</code> operation.</dd>
+ <dt>Process-scope, sampling</dt>
+ <dd>These PMCs sample the target processes instruction pointer after they have
+ seen the configured number of hardware events. The PMCs only count events
+ when a thread belonging to their attached process is active. The desired
+ frequency of sampling is set using the
+ <code class="Dv">PMC_OP_SETCOUNT</code> operation prior to starting the
+ PMC. Log files are configured using the
+ <code class="Dv">PMC_OP_CONFIGURELOG</code> operation.</dd>
+ <dt>System-scope, counting</dt>
+ <dd>These PMCs count hardware events seen by them independent of the processes
+ that are executing. The current count on these PMCs can be read using the
+ <code class="Dv">PMC_OP_PMCRW</code> request. These PMCs normally count
+ from zero, but the initial count may be set using the
+ <code class="Dv">PMC_OP_SETCOUNT</code> operation.</dd>
+ <dt>System-scope, sampling</dt>
+ <dd>These PMCs will periodically sample the instruction pointer of the CPU
+ they are allocated on, and will write the sample to a log for further
+ processing. The desired frequency of sampling is set using the
+ <code class="Dv">PMC_OP_SETCOUNT</code> operation prior to starting the
+ PMC. Log files are configured using the
+ <code class="Dv">PMC_OP_CONFIGURELOG</code> operation.
+ <p class="Pp">System-wide statistical sampling can only be enabled by a
+ process with super-user privileges.</p>
+ </dd>
+</dl>
+<p class="Pp">Processes are allowed to allocate as many PMCs as the hardware and
+ current operating conditions permit. Processes may mix allocations of
+ system-wide and process-private PMCs. Multiple processes may be using PMCs
+ simultaneously.</p>
+<p class="Pp">Allocated PMCs are started using the
+ <code class="Dv">PMC_OP_PMCSTART</code> operation, and stopped using the
+ <code class="Dv">PMC_OP_PMCSTOP</code> operation. Stopping and starting a
+ PMC is permitted at any time the owner process has a valid handle to the
+ PMC.</p>
+<p class="Pp">Process-private PMCs need to be attached to a target process
+ before they can be used. Attaching a process to a PMC is done using the
+ <code class="Dv">PMC_OP_PMCATTACH</code> operation. An already attached PMC
+ may be detached from its target process using the converse
+ <code class="Dv">PMC_OP_PMCDETACH</code> operation. Issuing a
+ <code class="Dv">PMC_OP_PMCSTART</code> operation on an as yet unattached
+ PMC will cause it to be attached to its owner process. The following rules
+ determine whether a given process may attach a PMC to another target
+ process:</p>
+<ul class="Bl-bullet Bl-compact">
+ <li>A non-jailed process with super-user privileges is allowed to attach to
+ any other process in the system.</li>
+ <li>Other processes are only allowed to attach to targets that they would be
+ able to attach to for debugging (as determined by
+ <a class="Xr">p_candebug(9)</a>).</li>
+</ul>
+<p class="Pp">PMCs are released using <code class="Dv">PMC_OP_PMCRELEASE</code>.
+ After a successful <code class="Dv">PMC_OP_PMCRELEASE</code> operation the
+ handle to the PMC will become invalid.</p>
+<section class="Ss">
+<h2 class="Ss" id="Modifier_Flags"><a class="permalink" href="#Modifier_Flags">Modifier
+ Flags</a></h2>
+<p class="Pp">The <code class="Dv">PMC_OP_PMCALLOCATE</code> operation supports
+ the following flags that modify the behavior of an allocated PMC:</p>
+<dl class="Bl-tag">
+ <dt id="PMC_F_CALLCHAIN"><a class="permalink" href="#PMC_F_CALLCHAIN"><code class="Dv">PMC_F_CALLCHAIN</code></a></dt>
+ <dd>This modifier informs sampling PMCs to record a callchain when capturing a
+ sample. The maximum depth to which call chains are recorded is specified
+ by the <var class="Va">kern.hwpmc.callchaindepth</var> kernel
+ tunable.</dd>
+ <dt id="PMC_F_DESCENDANTS"><a class="permalink" href="#PMC_F_DESCENDANTS"><code class="Dv">PMC_F_DESCENDANTS</code></a></dt>
+ <dd>This modifier is valid only for a PMC being allocated in process-private
+ mode. It signifies that the PMC will track hardware events for its target
+ process and the target's current and future descendants.</dd>
+ <dt id="PMC_F_LOG_PROCCSW"><a class="permalink" href="#PMC_F_LOG_PROCCSW"><code class="Dv">PMC_F_LOG_PROCCSW</code></a></dt>
+ <dd>This modifier is valid only for a PMC being allocated in process-private
+ mode. When this modifier is present, at every context switch,
+ <code class="Nm">hwpmc</code> will log a record containing the number of
+ hardware events seen by the target process when it was scheduled on the
+ CPU.</dd>
+ <dt id="PMC_F_LOG_PROCEXIT"><a class="permalink" href="#PMC_F_LOG_PROCEXIT"><code class="Dv">PMC_F_LOG_PROCEXIT</code></a></dt>
+ <dd>This modifier is valid only for a PMC being allocated in process-private
+ mode. With this modifier present, <code class="Nm">hwpmc</code> will
+ maintain per-process counts for each target process attached to a PMC. At
+ process exit time, a record containing the target process' PID and the
+ accumulated per-process count for that process will be written to the
+ configured log file.</dd>
+</dl>
+<p class="Pp">Modifiers <code class="Dv">PMC_F_LOG_PROCEXIT</code> and
+ <code class="Dv">PMC_F_LOG_PROCCSW</code> may be used in combination with
+ modifier <code class="Dv">PMC_F_DESCENDANTS</code> to track the behavior of
+ complex pipelines of processes. PMCs with modifiers
+ <code class="Dv">PMC_F_LOG_PROCEXIT</code> and
+ <code class="Dv">PMC_F_LOG_PROCCSW</code> cannot be started until their
+ owner process has configured a log file.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="Signals"><a class="permalink" href="#Signals">Signals</a></h2>
+<p class="Pp">The <code class="Nm">hwpmc</code> driver may deliver signals to
+ processes that have allocated PMCs:</p>
+<dl class="Bl-tag">
+ <dt id="SIGIO"><a class="permalink" href="#SIGIO"><code class="Dv">SIGIO</code></a></dt>
+ <dd>A <code class="Dv">PMC_OP_PMCRW</code> operation was attempted on a
+ process-private PMC that does not have attached target processes.</dd>
+ <dt id="SIGBUS"><a class="permalink" href="#SIGBUS"><code class="Dv">SIGBUS</code></a></dt>
+ <dd>The <code class="Nm">hwpmc</code> driver is being unloaded from the
+ kernel.</dd>
+</dl>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="PMC_ROW_DISPOSITIONS"><a class="permalink" href="#PMC_ROW_DISPOSITIONS">PMC
+ ROW DISPOSITIONS</a></h2>
+<p class="Pp">A PMC row is defined as the set of PMC resources at the same
+ hardware address in the CPUs in a system. Since process scope PMCs need to
+ move between CPUs following their target threads, allocation of a process
+ scope PMC reserves all PMCs in a PMC row for use only with process scope
+ PMCs. Accordingly a PMC row will be in one of the following
+ dispositions:</p>
+<dl class="Bl-tag Bl-compact">
+ <dt id="PMC_DISP_FREE"><a class="permalink" href="#PMC_DISP_FREE"><code class="Dv">PMC_DISP_FREE</code></a></dt>
+ <dd>Hardware counters in this row are free and may be use to satisfy either of
+ system scope or process scope allocation requests.</dd>
+ <dt id="PMC_DISP_THREAD"><a class="permalink" href="#PMC_DISP_THREAD"><code class="Dv">PMC_DISP_THREAD</code></a></dt>
+ <dd>Hardware counters in this row are in use by process scope PMCs and are
+ only available for process scope allocation requests.</dd>
+ <dt id="PMC_DISP_STANDALONE"><a class="permalink" href="#PMC_DISP_STANDALONE"><code class="Dv">PMC_DISP_STANDALONE</code></a></dt>
+ <dd>Some hardware counters in this row have been administratively disabled or
+ are in use by system scope PMCs. Non-disabled hardware counters in such a
+ row may be used for satisfying system scope allocation requests. No
+ process scope PMCs will use hardware counters in this row.</dd>
+</dl>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="COMPATIBILITY"><a class="permalink" href="#COMPATIBILITY">COMPATIBILITY</a></h1>
+<p class="Pp">The API and ABI documented in this manual page may change in the
+ future. This interface is intended to be consumed by the
+ <a class="Xr">pmc(3)</a> library; other consumers are unsupported.
+ Applications targeting PMCs should use the <a class="Xr">pmc(3)</a> library
+ API.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="PROGRAMMING_API"><a class="permalink" href="#PROGRAMMING_API">PROGRAMMING
+ API</a></h1>
+<p class="Pp">The <code class="Nm">hwpmc</code> driver operates using a system
+ call number that is dynamically allotted to it when it is loaded into the
+ kernel.</p>
+<p class="Pp">The <code class="Nm">hwpmc</code> driver supports the following
+ operations:</p>
+<dl class="Bl-tag">
+ <dt id="PMC_OP_CONFIGURELOG"><a class="permalink" href="#PMC_OP_CONFIGURELOG"><code class="Dv">PMC_OP_CONFIGURELOG</code></a></dt>
+ <dd>Configure a log file for PMCs that require a log file. The
+ <code class="Nm">hwpmc</code> driver will write log data to this file
+ asynchronously. If it encounters an error, logging will be stopped and the
+ error code encountered will be saved for subsequent retrieval by a
+ <code class="Dv">PMC_OP_FLUSHLOG</code> request.</dd>
+ <dt id="PMC_OP_FLUSHLOG"><a class="permalink" href="#PMC_OP_FLUSHLOG"><code class="Dv">PMC_OP_FLUSHLOG</code></a></dt>
+ <dd>Transfer buffered log data inside <code class="Nm">hwpmc</code> to a
+ configured output file. This operation returns to the caller after the
+ write operation has returned. The returned error code reflects any pending
+ error state inside <code class="Nm">hwpmc</code>.</dd>
+ <dt id="PMC_OP_GETCAPS"><a class="permalink" href="#PMC_OP_GETCAPS"><code class="Dv">PMC_OP_GETCAPS</code></a></dt>
+ <dd>Retrieve the capabilities associated with a specific PMC counter. Some
+ capabilities may be limited to specific indices (i.e., not available
+ across all counters within a class).</dd>
+ <dt id="PMC_OP_GETCPUINFO"><a class="permalink" href="#PMC_OP_GETCPUINFO"><code class="Dv">PMC_OP_GETCPUINFO</code></a></dt>
+ <dd>Retrieve information about the highest possible CPU number for the system,
+ and the number of hardware performance monitoring counters available per
+ CPU.</dd>
+ <dt id="PMC_OP_GETDRIVERSTATS"><a class="permalink" href="#PMC_OP_GETDRIVERSTATS"><code class="Dv">PMC_OP_GETDRIVERSTATS</code></a></dt>
+ <dd>Retrieve module statistics (for analyzing the behavior of
+ <code class="Nm">hwpmc</code> itself).</dd>
+ <dt id="PMC_OP_GETMODULEVERSION"><a class="permalink" href="#PMC_OP_GETMODULEVERSION"><code class="Dv">PMC_OP_GETMODULEVERSION</code></a></dt>
+ <dd>Retrieve the version number of API.</dd>
+ <dt id="PMC_OP_GETPMCINFO"><a class="permalink" href="#PMC_OP_GETPMCINFO"><code class="Dv">PMC_OP_GETPMCINFO</code></a></dt>
+ <dd>Retrieve information about the current state of the PMCs on a given
+ CPU.</dd>
+ <dt id="PMC_OP_PMCADMIN"><a class="permalink" href="#PMC_OP_PMCADMIN"><code class="Dv">PMC_OP_PMCADMIN</code></a></dt>
+ <dd>Set the administrative state (i.e., whether enabled or disabled) for the
+ hardware PMCs managed by the <code class="Nm">hwpmc</code> driver. The
+ invoking process needs to possess the
+ <code class="Dv">PRIV_PMC_MANAGE</code> privilege.</dd>
+ <dt id="PMC_OP_PMCALLOCATE"><a class="permalink" href="#PMC_OP_PMCALLOCATE"><code class="Dv">PMC_OP_PMCALLOCATE</code></a></dt>
+ <dd>Allocate and configure a PMC. On successful allocation, a handle to the
+ PMC (a 32 bit value) is returned.</dd>
+ <dt id="PMC_OP_PMCATTACH"><a class="permalink" href="#PMC_OP_PMCATTACH"><code class="Dv">PMC_OP_PMCATTACH</code></a></dt>
+ <dd>Attach a process mode PMC to a target process. The PMC will be active
+ whenever a thread in the target process is scheduled on a CPU.
+ <p class="Pp">If the <code class="Dv">PMC_F_DESCENDANTS</code> flag had been
+ specified at PMC allocation time, then the PMC is attached to all
+ current and future descendants of the target process.</p>
+ </dd>
+ <dt id="PMC_OP_PMCDETACH"><a class="permalink" href="#PMC_OP_PMCDETACH"><code class="Dv">PMC_OP_PMCDETACH</code></a></dt>
+ <dd>Detach a PMC from its target process.</dd>
+ <dt id="PMC_OP_PMCRELEASE"><a class="permalink" href="#PMC_OP_PMCRELEASE"><code class="Dv">PMC_OP_PMCRELEASE</code></a></dt>
+ <dd>Release a PMC.</dd>
+ <dt id="PMC_OP_PMCRW"><a class="permalink" href="#PMC_OP_PMCRW"><code class="Dv">PMC_OP_PMCRW</code></a></dt>
+ <dd>Read and write a PMC. This operation is valid only for PMCs configured in
+ counting modes.</dd>
+ <dt id="PMC_OP_SETCOUNT"><a class="permalink" href="#PMC_OP_SETCOUNT"><code class="Dv">PMC_OP_SETCOUNT</code></a></dt>
+ <dd>Set the initial count (for counting mode PMCs) or the desired sampling
+ rate (for sampling mode PMCs).</dd>
+ <dt id="PMC_OP_PMCSTART"><a class="permalink" href="#PMC_OP_PMCSTART"><code class="Dv">PMC_OP_PMCSTART</code></a></dt>
+ <dd>Start a PMC.</dd>
+ <dt id="PMC_OP_PMCSTOP"><a class="permalink" href="#PMC_OP_PMCSTOP"><code class="Dv">PMC_OP_PMCSTOP</code></a></dt>
+ <dd>Stop a PMC.</dd>
+ <dt id="PMC_OP_WRITELOG"><a class="permalink" href="#PMC_OP_WRITELOG"><code class="Dv">PMC_OP_WRITELOG</code></a></dt>
+ <dd>Insert a timestamped user record into the log file.</dd>
+</dl>
+<section class="Ss">
+<h2 class="Ss" id="i386_Specific_API"><a class="permalink" href="#i386_Specific_API">i386
+ Specific API</a></h2>
+<p class="Pp">Some i386 family CPUs support the RDPMC instruction which allows a
+ user process to read a PMC value without needing to invoke a
+ <code class="Dv">PMC_OP_PMCRW</code> operation. On such CPUs, the machine
+ address associated with an allocated PMC is retrievable using the
+ <code class="Dv">PMC_OP_PMCX86GETMSR</code> system call.</p>
+<dl class="Bl-tag">
+ <dt id="PMC_OP_PMCX86GETMSR"><a class="permalink" href="#PMC_OP_PMCX86GETMSR"><code class="Dv">PMC_OP_PMCX86GETMSR</code></a></dt>
+ <dd>Retrieve the MSR (machine specific register) number associated with the
+ given PMC handle.
+ <p class="Pp">The PMC needs to be in process-private mode and allocated
+ without the <code class="Dv">PMC_F_DESCENDANTS</code> modifier flag, and
+ should be attached only to its owner process at the time of the
+ call.</p>
+ </dd>
+</dl>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="amd64_Specific_API"><a class="permalink" href="#amd64_Specific_API">amd64
+ Specific API</a></h2>
+<p class="Pp">AMD64 CPUs support the RDPMC instruction which allows a user
+ process to read a PMC value without needing to invoke a
+ <code class="Dv">PMC_OP_PMCRW</code> operation. The machine address
+ associated with an allocated PMC is retrievable using the
+ <code class="Dv">PMC_OP_PMCX86GETMSR</code> system call.</p>
+<dl class="Bl-tag">
+ <dt id="PMC_OP_PMCX86GETMSR~2"><a class="permalink" href="#PMC_OP_PMCX86GETMSR~2"><code class="Dv">PMC_OP_PMCX86GETMSR</code></a></dt>
+ <dd>Retrieve the MSR (machine specific register) number associated with the
+ given PMC handle.
+ <p class="Pp">The PMC needs to be in process-private mode and allocated
+ without the <code class="Dv">PMC_F_DESCENDANTS</code> modifier flag, and
+ should be attached only to its owner process at the time of the
+ call.</p>
+ </dd>
+</dl>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYSCTL_VARIABLES_AND_LOADER_TUNABLES"><a class="permalink" href="#SYSCTL_VARIABLES_AND_LOADER_TUNABLES">SYSCTL
+ VARIABLES AND LOADER TUNABLES</a></h1>
+<p class="Pp">The behavior of <code class="Nm">hwpmc</code> is influenced by the
+ following <a class="Xr">sysctl(8)</a> and <a class="Xr">loader(8)</a>
+ tunables:</p>
+<dl class="Bl-tag">
+ <dt id="kern.hwpmc.callchaindepth"><var class="Va">kern.hwpmc.callchaindepth</var>
+ (integer, read-only)</dt>
+ <dd>The maximum number of call chain records to capture per sample. The
+ default is 8.</dd>
+ <dt id="kern.hwpmc.debugflags"><var class="Va">kern.hwpmc.debugflags</var>
+ (string, read-write)</dt>
+ <dd>(Only available if the <code class="Nm">hwpmc</code> driver was compiled
+ with <code class="Fl">-DDEBUG</code>.) Control the verbosity of debug
+ messages from the <code class="Nm">hwpmc</code> driver.</dd>
+ <dt id="kern.hwpmc.hashsize"><var class="Va">kern.hwpmc.hashsize</var>
+ (integer, read-only)</dt>
+ <dd>The number of rows in the hash tables used to keep track of owner and
+ target processes. The default is 16.</dd>
+ <dt id="kern.hwpmc.logbuffersize"><var class="Va">kern.hwpmc.logbuffersize</var>
+ (integer, read-only)</dt>
+ <dd>The size in kilobytes of each log buffer used by
+ <code class="Nm">hwpmc</code>'s logging function. The default buffer size
+ is 256KB. The maximum value is 16MB.</dd>
+ <dt id="kern.hwpmc.mincount"><var class="Va">kern.hwpmc.mincount</var>
+ (integer, read-write)</dt>
+ <dd>The minimum sampling rate for sampling mode PMCs. The default count is
+ 1000 events.</dd>
+ <dt id="kern.hwpmc.mtxpoolsize"><var class="Va">kern.hwpmc.mtxpoolsize</var>
+ (integer, read-only)</dt>
+ <dd>The size of the spin mutex pool used by the PMC driver. The default is
+ 32.</dd>
+ <dt id="kern.hwpmc.nbuffers_pcpu"><var class="Va">kern.hwpmc.nbuffers_pcpu</var>
+ (integer, read-only)</dt>
+ <dd>The number of log buffers per CPU used by <code class="Nm">hwpmc</code>
+ for logging. The default is 32. The product of
+ <var class="Va">kern.hwpmc.nbuffers_pcpu</var> and
+ <var class="Va">kern.hwpmc.logbuffersize</var> must not exceed 32MB per
+ CPU.</dd>
+ <dt id="kern.hwpmc.nsamples"><var class="Va">kern.hwpmc.nsamples</var>
+ (integer, read-only)</dt>
+ <dd>The number of entries in the per-CPU ring buffer used during sampling. The
+ default is 512.</dd>
+ <dt id="security.bsd.unprivileged_syspmcs"><var class="Va">security.bsd.unprivileged_syspmcs</var>
+ (boolean, read-write)</dt>
+ <dd>If set to non-zero, allow unprivileged processes to allocate system-wide
+ PMCs. The default value is 0.</dd>
+ <dt id="security.bsd.unprivileged_proc_debug"><var class="Va">security.bsd.unprivileged_proc_debug</var>
+ (boolean, read-write)</dt>
+ <dd>If set to 0, the <code class="Nm">hwpmc</code> driver will only allow
+ privileged processes to attach PMCs to other processes.</dd>
+</dl>
+<p class="Pp">These variables may be set in the kernel environment using
+ <a class="Xr">kenv(1)</a> before <code class="Nm">hwpmc</code> is
+ loaded.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="IMPLEMENTATION_NOTES"><a class="permalink" href="#IMPLEMENTATION_NOTES">IMPLEMENTATION
+ NOTES</a></h1>
+<section class="Ss">
+<h2 class="Ss" id="SMP_Symmetry"><a class="permalink" href="#SMP_Symmetry">SMP
+ Symmetry</a></h2>
+<p class="Pp">The kernel driver requires all physical CPUs in an SMP system to
+ have identical performance monitoring counter hardware.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="Sparse_CPU_Numbering"><a class="permalink" href="#Sparse_CPU_Numbering">Sparse
+ CPU Numbering</a></h2>
+<p class="Pp">On platforms that sparsely number CPUs and which support
+ hot-plugging of CPUs, requests that specify non-existent or disabled CPUs
+ will fail with an error. Applications allocating system-scope PMCs need to
+ be aware of the possibility of such transient failures.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="x86_TSC_Handling"><a class="permalink" href="#x86_TSC_Handling">x86
+ TSC Handling</a></h2>
+<p class="Pp">Historically, on the x86 architecture,
+ <span class="Ux">FreeBSD</span> has permitted user processes running at a
+ processor CPL of 3 to read the TSC using the RDTSC instruction. The
+ <code class="Nm">hwpmc</code> driver preserves this behavior.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="Intel_P4/HTT_Handling"><a class="permalink" href="#Intel_P4/HTT_Handling">Intel
+ P4/HTT Handling</a></h2>
+<p class="Pp">On CPUs with HTT support, Intel P4 PMCs are capable of qualifying
+ only a subset of hardware events on a per-logical CPU basis. Consequently,
+ if HTT is enabled on a system with Intel Pentium P4 PMCs, then the
+ <code class="Nm">hwpmc</code> driver will reject allocation requests for
+ process-private PMCs that request counting of hardware events that cannot be
+ counted separately for each logical CPU.</p>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DIAGNOSTICS"><a class="permalink" href="#DIAGNOSTICS">DIAGNOSTICS</a></h1>
+<dl class="Bl-diag">
+ <dt>hwpmc: [class/npmc/capabilities]...</dt>
+ <dd>Announce the presence of <var class="Va">npmc</var> PMCs of class
+ <var class="Va">class</var>, with capabilities described by bit string
+ <var class="Va">capabilities</var>.</dd>
+ <dt>hwpmc: kernel version (0x%x) does not match module version (0x%x).</dt>
+ <dd>The module loading process failed because a version mismatch was detected
+ between the currently executing kernel and the module being loaded.</dd>
+ <dt>hwpmc: this kernel has not been compiled with 'options HWPMC_HOOKS'.</dt>
+ <dd>The module loading process failed because the currently executing kernel
+ was not configured with the required configuration option
+ <code class="Dv">HWPMC_HOOKS</code>.</dd>
+ <dt>hwpmc: tunable hashsize=%d must be greater than zero.</dt>
+ <dd>A negative value was supplied for tunable
+ <var class="Va">kern.hwpmc.hashsize</var>.</dd>
+ <dt>hwpmc: logbuffersize=%d must be greater than zero and less than or equal
+ to %d, resetting to %d.</dt>
+ <dd>A negative value was supplied for tunable
+ <var class="Va">kern.hwpmc.logbuffersize</var>.</dd>
+ <dt>hwpmc: nbuffers_pcpu=%d must be greater than zero, resetting to %d.</dt>
+ <dd>A negative value was supplied for tunable
+ <var class="Va">kern.hwpmc.nbuffers_pcpu</var>.</dd>
+ <dt>hwpmc: tunable nsamples=%d out of range.</dt>
+ <dd>The value for tunable <var class="Va">kern.hwpmc.nsamples</var> was
+ negative or greater than 65535.</dd>
+ <dt>hwpmc: nbuffers_pcpu=%d * logbuffersize=%d exceeds %dMB per CPU limit,
+ resetting to defaults (%d * %d).</dt>
+ <dd>The product of tunables <var class="Va">kern.hwpmc.nbuffers_pcpu</var> and
+ <var class="Va">kern.hwpmc.logbuffersize</var> exceeds the maximum per-CPU
+ memory limit. Both tunables are reset to their compiled defaults.</dd>
+</dl>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DEBUGGING"><a class="permalink" href="#DEBUGGING">DEBUGGING</a></h1>
+<p class="Pp">The <code class="Nm">hwpmc</code> module can be configured to
+ record trace entries using the <a class="Xr">ktr(4)</a> interface. This is
+ useful for debugging the driver's functionality, primarily during
+ development. This debugging functionality is not enabled by default, and
+ requires recompiling the kernel and <code class="Nm">hwpmc</code> module
+ after adding the following to the kernel config:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre><code class="Cd">options KTR</code>
+<code class="Cd">options KTR_COMPILE=(KTR_SUBSYS)</code>
+<code class="Cd">options KTR_MASK=(KTR_SUBSYS)</code>
+<code class="Cd">options HWPMC_DEBUG</code></pre>
+</div>
+<p class="Pp">This alone is not enough to enable tracing; one must also
+ configure the <var class="Va">kern.hwpmc.debugflags</var>
+ <a class="Xr">sysctl(8)</a> variable, which provides fine-grained control
+ over which types of events are logged to the trace buffer.</p>
+<p class="Pp"><code class="Nm">hwpmc</code> trace events are grouped by 'major'
+ and 'minor' flag types. The major flag names are as follows:</p>
+<p class="Pp"></p>
+<div class="Bd-indent">
+<dl class="Bl-tag Bl-compact">
+ <dt>cpu</dt>
+ <dd>CPU events</dd>
+ <dt>csw</dt>
+ <dd>Context switch events</dd>
+ <dt>logging</dt>
+ <dd>Logging events</dd>
+ <dt>md</dt>
+ <dd>Machine-dependent/class-dependent events</dd>
+ <dt>module</dt>
+ <dd>Miscellaneous events</dd>
+ <dt>owner</dt>
+ <dd>PMC owner events</dd>
+ <dt>pmc</dt>
+ <dd>PMC management events</dd>
+ <dt>process</dt>
+ <dd>Process events</dd>
+ <dt>sampling</dt>
+ <dd>Sampling events</dd>
+</dl>
+</div>
+<p class="Pp">The minor flags for each major flag group can vary. The individual
+ minor flag names are:</p>
+<div class="Bd Pp Bd-indent">allocaterow, allocate, attach, bind, config, exec,
+ exit, find, flush, fork, getbuf, hook, init, intr, linktarget, mayberemove,
+ ops, read, register, release, remove, sample, scheduleio, select, signal, swi,
+ swo, start, stop, syscall, unlinktarget, write</div>
+<p class="Pp">The <var class="Va">kern.hwpmc.debugflags</var> variable is a
+ string with a custom format. The string should contain a space-separated
+ list of event specifiers. Each event specifier consists of the major flag
+ name, followed by an equal sign (=), followed by a comma-separated list of
+ minor event types. To track all events for a major group, an asterisk (*)
+ can be given instead of minor event names.</p>
+<p class="Pp">For example, to trace all allocation and release events, set
+ <var class="Va">debugflags</var> as follows:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>kern.hwpmc.debugflags=&quot;pmc=allocate,release md=allocate,release&quot;</pre>
+</div>
+<p class="Pp">To trace all events in the process and context switch major flag
+ groups:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>kern.hwpmc.debugflags=&quot;process=* csw=*&quot;</pre>
+</div>
+<p class="Pp">To disable all trace events, set the variable to an empty
+ string.</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>kern.hwpmc.debugflags=&quot;&quot;</pre>
+</div>
+<p class="Pp">Trace events are recorded by <a class="Xr">ktr(4)</a>, and can be
+ inspected at run-time using the <a class="Xr">ktrdump(8)</a> utility, or at
+ the <a class="Xr">ddb(4)</a> prompt after a panic with the 'show ktr'
+ command.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="ERRORS"><a class="permalink" href="#ERRORS">ERRORS</a></h1>
+<p class="Pp">A command issued to the <code class="Nm">hwpmc</code> driver may
+ fail with the following errors:</p>
+<dl class="Bl-tag">
+ <dt id="EAGAIN">[<a class="permalink" href="#EAGAIN"><code class="Er">EAGAIN</code></a>]</dt>
+ <dd>Helper process creation failed for a
+ <code class="Dv">PMC_OP_CONFIGURELOG</code> request due to a temporary
+ resource shortage in the kernel.</dd>
+ <dt id="EBUSY">[<a class="permalink" href="#EBUSY"><code class="Er">EBUSY</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_CONFIGURELOG</code> operation was requested
+ while an existing log was active.</dd>
+ <dt id="EBUSY~2">[<a class="permalink" href="#EBUSY~2"><code class="Er">EBUSY</code></a>]</dt>
+ <dd>A DISABLE operation was requested using the
+ <code class="Dv">PMC_OP_PMCADMIN</code> request for a set of hardware
+ resources currently in use for process-private PMCs.</dd>
+ <dt id="EBUSY~3">[<a class="permalink" href="#EBUSY~3"><code class="Er">EBUSY</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCADMIN</code> operation was requested on an
+ active system mode PMC.</dd>
+ <dt id="EBUSY~4">[<a class="permalink" href="#EBUSY~4"><code class="Er">EBUSY</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCATTACH</code> operation was requested for a
+ target process that already had another PMC using the same hardware
+ resources attached to it.</dd>
+ <dt id="EBUSY~5">[<a class="permalink" href="#EBUSY~5"><code class="Er">EBUSY</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCRW</code> request writing a new value was
+ issued on a PMC that was active.</dd>
+ <dt id="EBUSY~6">[<a class="permalink" href="#EBUSY~6"><code class="Er">EBUSY</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCSETCOUNT</code> request was issued on a PMC
+ that was active.</dd>
+ <dt id="EDOOFUS">[<a class="permalink" href="#EDOOFUS"><code class="Er">EDOOFUS</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCSTART</code> operation was requested without
+ a log file being configured for a PMC allocated with
+ <code class="Dv">PMC_F_LOG_PROCCSW</code> and
+ <code class="Dv">PMC_F_LOG_PROCEXIT</code> modifiers.</dd>
+ <dt id="EDOOFUS~2">[<a class="permalink" href="#EDOOFUS~2"><code class="Er">EDOOFUS</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCSTART</code> operation was requested on a
+ system-wide sampling PMC without a log file being configured.</dd>
+ <dt id="EEXIST">[<a class="permalink" href="#EEXIST"><code class="Er">EEXIST</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCATTACH</code> request was reissued for a
+ target process that already is the target of this PMC.</dd>
+ <dt id="EFAULT">[<a class="permalink" href="#EFAULT"><code class="Er">EFAULT</code></a>]</dt>
+ <dd>A bad address was passed in to the driver.</dd>
+ <dt id="EINVAL">[<a class="permalink" href="#EINVAL"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid PMC handle was specified.</dd>
+ <dt id="EINVAL~2">[<a class="permalink" href="#EINVAL~2"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid CPU number was passed in for a
+ <code class="Dv">PMC_OP_GETPMCINFO</code> operation.</dd>
+ <dt id="EINVAL~3">[<a class="permalink" href="#EINVAL~3"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>The <var class="Ar">pm_flags</var> argument to a
+ <code class="Dv">PMC_OP_CONFIGURELOG</code> request contained unknown
+ flags.</dd>
+ <dt id="EINVAL~4">[<a class="permalink" href="#EINVAL~4"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_CONFIGURELOG</code> request to de-configure a
+ log file was issued without a log file being configured.</dd>
+ <dt id="EINVAL~5">[<a class="permalink" href="#EINVAL~5"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_FLUSHLOG</code> request was issued without a log
+ file being configured.</dd>
+ <dt id="EINVAL~6">[<a class="permalink" href="#EINVAL~6"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid CPU number was passed in for a
+ <code class="Dv">PMC_OP_PMCADMIN</code> operation.</dd>
+ <dt id="EINVAL~7">[<a class="permalink" href="#EINVAL~7"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid operation request was passed in for a
+ <code class="Dv">PMC_OP_PMCADMIN</code> operation.</dd>
+ <dt id="EINVAL~8">[<a class="permalink" href="#EINVAL~8"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid PMC ID was passed in for a
+ <code class="Dv">PMC_OP_PMCADMIN</code> operation.</dd>
+ <dt id="EINVAL~9">[<a class="permalink" href="#EINVAL~9"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A suitable PMC matching the parameters passed in to a
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request could not be
+ allocated.</dd>
+ <dt id="EINVAL~10">[<a class="permalink" href="#EINVAL~10"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid PMC mode was requested during a
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request.</dd>
+ <dt id="EINVAL~11">[<a class="permalink" href="#EINVAL~11"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>An invalid CPU number was specified during a
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request.</dd>
+ <dt id="EINVAL~12">[<a class="permalink" href="#EINVAL~12"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A CPU other than <code class="Dv">PMC_CPU_ANY</code> was specified in a
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request for a process-private
+ PMC.</dd>
+ <dt id="EINVAL~13">[<a class="permalink" href="#EINVAL~13"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A CPU number of <code class="Dv">PMC_CPU_ANY</code> was specified in a
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request for a system-wide
+ PMC.</dd>
+ <dt id="EINVAL~14">[<a class="permalink" href="#EINVAL~14"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>The <var class="Ar">pm_flags</var> argument to an
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request contained unknown
+ flags.</dd>
+ <dt id="EINVAL~15">[<a class="permalink" href="#EINVAL~15"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>(On Intel Pentium 4 CPUs with HTT support) A
+ <code class="Dv">PMC_OP_PMCALLOCATE</code> request for a process-private
+ PMC was issued for an event that does not support counting on a
+ per-logical CPU basis.</dd>
+ <dt id="EINVAL~16">[<a class="permalink" href="#EINVAL~16"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A PMC allocated for system-wide operation was specified with a
+ <code class="Dv">PMC_OP_PMCATTACH</code> or
+ <code class="Dv">PMC_OP_PMCDETACH</code> request.</dd>
+ <dt id="EINVAL~17">[<a class="permalink" href="#EINVAL~17"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>The <var class="Ar">pm_pid</var> argument to a
+ <code class="Dv">PMC_OP_PMCATTACH</code> or
+ <code class="Dv">PMC_OP_PMCDETACH</code> request specified an illegal
+ process ID.</dd>
+ <dt id="EINVAL~18">[<a class="permalink" href="#EINVAL~18"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCDETACH</code> request was issued for a PMC
+ not attached to the target process.</dd>
+ <dt id="EINVAL~19">[<a class="permalink" href="#EINVAL~19"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>Argument <var class="Ar">pm_flags</var> to a
+ <code class="Dv">PMC_OP_PMCRW</code> request contained illegal flags.</dd>
+ <dt id="EINVAL~20">[<a class="permalink" href="#EINVAL~20"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCX86GETMSR</code> operation was requested for
+ a PMC not in process-virtual mode, or for a PMC that is not solely
+ attached to its owner process, or for a PMC that was allocated with flag
+ <code class="Dv">PMC_F_DESCENDANTS</code>.</dd>
+ <dt id="EINVAL~21">[<a class="permalink" href="#EINVAL~21"><code class="Er">EINVAL</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_WRITELOG</code> request was issued for an owner
+ process without a log file configured.</dd>
+ <dt id="ENOMEM">[<a class="permalink" href="#ENOMEM"><code class="Er">ENOMEM</code></a>]</dt>
+ <dd>The system was not able to allocate kernel memory.</dd>
+ <dt id="ENOSYS">[<a class="permalink" href="#ENOSYS"><code class="Er">ENOSYS</code></a>]</dt>
+ <dd>(On i386 and amd64 architectures) A
+ <code class="Dv">PMC_OP_PMCX86GETMSR</code> operation was requested for
+ hardware that does not support reading PMCs directly with the RDPMC
+ instruction.</dd>
+ <dt id="ENXIO">[<a class="permalink" href="#ENXIO"><code class="Er">ENXIO</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_GETPMCINFO</code> operation was requested for an
+ absent or disabled CPU.</dd>
+ <dt id="ENXIO~2">[<a class="permalink" href="#ENXIO~2"><code class="Er">ENXIO</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCALLOCATE</code> operation specified
+ allocation of a system-wide PMC on an absent or disabled CPU.</dd>
+ <dt id="ENXIO~3">[<a class="permalink" href="#ENXIO~3"><code class="Er">ENXIO</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCSTART</code> or
+ <code class="Dv">PMC_OP_PMCSTOP</code> request was issued for a
+ system-wide PMC that was allocated on a CPU that is currently absent or
+ disabled.</dd>
+ <dt id="EOPNOTSUPP">[<a class="permalink" href="#EOPNOTSUPP"><code class="Er">EOPNOTSUPP</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCALLOCATE</code> request was issued for PMC
+ capabilities not supported by the specified PMC class.</dd>
+ <dt id="EOPNOTSUPP~2">[<a class="permalink" href="#EOPNOTSUPP~2"><code class="Er">EOPNOTSUPP</code></a>]</dt>
+ <dd>(i386 architectures) A sampling mode PMC was requested on a CPU lacking an
+ APIC.</dd>
+ <dt id="EPERM">[<a class="permalink" href="#EPERM"><code class="Er">EPERM</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCADMIN</code> request was issued by a process
+ without super-user privilege or by a jailed super-user process.</dd>
+ <dt id="EPERM~2">[<a class="permalink" href="#EPERM~2"><code class="Er">EPERM</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCATTACH</code> operation was issued for a
+ target process that the current process does not have permission to attach
+ to.</dd>
+ <dt id="EPERM~3">[<a class="permalink" href="#EPERM~3"><code class="Er">EPERM</code></a>]</dt>
+ <dd>(i386 and amd64 architectures) A <code class="Dv">PMC_OP_PMCATTACH</code>
+ operation was issued on a PMC whose MSR has been retrieved using
+ <code class="Dv">PMC_OP_PMCX86GETMSR</code>.</dd>
+ <dt id="ESRCH">[<a class="permalink" href="#ESRCH"><code class="Er">ESRCH</code></a>]</dt>
+ <dd>A process issued a PMC operation request without having allocated any
+ PMCs.</dd>
+ <dt id="ESRCH~2">[<a class="permalink" href="#ESRCH~2"><code class="Er">ESRCH</code></a>]</dt>
+ <dd>A process issued a PMC operation request after the PMC was detached from
+ all of its target processes.</dd>
+ <dt id="ESRCH~3">[<a class="permalink" href="#ESRCH~3"><code class="Er">ESRCH</code></a>]</dt>
+ <dd>A <code class="Dv">PMC_OP_PMCATTACH</code> or
+ <code class="Dv">PMC_OP_PMCDETACH</code> request specified a non-existent
+ process ID.</dd>
+ <dt id="ESRCH~4">[<a class="permalink" href="#ESRCH~4"><code class="Er">ESRCH</code></a>]</dt>
+ <dd>The target process for a <code class="Dv">PMC_OP_PMCDETACH</code>
+ operation is not being monitored by <code class="Nm">hwpmc</code>.</dd>
+</dl>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+ ALSO</a></h1>
+<p class="Pp"><a class="Xr">kenv(1)</a>, <a class="Xr">pmc(3)</a>,
+ <a class="Xr">pmclog(3)</a>, <a class="Xr">ddb(4)</a>,
+ <a class="Xr">ktr(4)</a>, <a class="Xr">kldload(8)</a>,
+ <a class="Xr">ktrdump(8)</a>, <a class="Xr">pmccontrol(8)</a>,
+ <a class="Xr">pmcstat(8)</a>, <a class="Xr">sysctl(8)</a>,
+ <a class="Xr">kproc_create(9)</a>, <a class="Xr">p_candebug(9)</a></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
+<p class="Pp">The <code class="Nm">hwpmc</code> driver first appeared in
+ <span class="Ux">FreeBSD 6.0</span>.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
+<p class="Pp">The <code class="Nm">hwpmc</code> driver was written by
+ <span class="An">Joseph Koshy</span>
+ &lt;<a class="Mt" href="mailto:jkoshy@FreeBSD.org">jkoshy@FreeBSD.org</a>&gt;.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="BUGS"><a class="permalink" href="#BUGS">BUGS</a></h1>
+<p class="Pp">The driver samples the state of the kernel's logical processor
+ support at the time of initialization (i.e., at module load time). On CPUs
+ supporting logical processors, the driver could misbehave if logical
+ processors are subsequently enabled or disabled while the driver is
+ active.</p>
+<p class="Pp">On the i386 architecture, the driver requires that the local APIC
+ on the CPU be enabled for sampling mode to be supported. Many
+ single-processor motherboards keep the APIC disabled in BIOS; on such
+ systems <code class="Nm">hwpmc</code> will not support sampling PMCs.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SECURITY_CONSIDERATIONS"><a class="permalink" href="#SECURITY_CONSIDERATIONS">SECURITY
+ CONSIDERATIONS</a></h1>
+<p class="Pp">PMCs may be used to monitor the actual behavior of the system on
+ hardware. In situations where this constitutes an undesirable information
+ leak, the following options are available:</p>
+<ol class="Bl-enum">
+ <li>Set the <a class="Xr">sysctl(8)</a> tunable
+ <var class="Va">security.bsd.unprivileged_syspmcs</var> to 0. This ensures
+ that unprivileged processes cannot allocate system-wide PMCs and thus
+ cannot observe the hardware behavior of the system as a whole. This
+ tunable may also be set at boot time using <a class="Xr">loader(8)</a>, or
+ with <a class="Xr">kenv(1)</a> prior to loading the
+ <code class="Nm">hwpmc</code> driver into the kernel.</li>
+ <li>Set the <a class="Xr">sysctl(8)</a> tunable
+ <var class="Va">security.bsd.unprivileged_proc_debug</var> to 0. This will
+ ensure that an unprivileged process cannot attach a PMC to any process
+ other than itself and thus cannot observe the hardware behavior of other
+ processes with the same credentials.</li>
+</ol>
+<p class="Pp">System administrators should note that on IA-32 platforms
+ <span class="Ux">FreeBSD</span> makes the content of the IA-32 TSC counter
+ available to all processes via the RDTSC instruction.</p>
+</section>
+</div>
+<table class="foot">
+ <tr>
+ <td class="foot-date">July 8, 2023</td>
+ <td class="foot-os">FreeBSD 15.0</td>
+ </tr>
+</table>