MSR (Model-Specific Register) control
21 Jan 1999
Richard Gooch
<rgooch AT atnf DOT csiro DOT au>

MSRs provide access to internal processor functions and allow you to
control the behaviour of the processor. While the set of MSRs is
highly model-dependent, there is a reasonably generic interface which
may be used to read and write these registers. The CONFIG_MSR option
allows you to compile the device driver which provides access to these
registers from user space. The driver creates the /dev/cpu/msr device
file. By using ioctl() functions on this device you can read and write
specified MSRs.

A separate user space library is available from:
http://www.atnf.csiro.au/~rgooch/linux/
which mimics the MSR interface available in kernel space. This makes
it very easy to write code which manipulates MSRs, as all code
development can be done from userspace. Once the code has been
developed and tested, it can be incorporated into a kernel device
driver with very few changes. Apart from being more convenient, it is
also safer, as you can write your code without worring about
generating an Oops, a Panic or generally messing with kernel data
structures.

There is one caveat, however: if you incorrectly programme a MSR, the
behaviour of the processor is undefined. At best, your programme will
fail as you try to write to an undefined MSR. At worst, you could
trigger an internal fault and cause the processor to cook itself. That
said, chances are the worst will not happen, because modern processors
should not do anything harmful to themselves, no matter how they are
programmed. But you have been warned: carry on at your own risk.
===============================================================================
Performance monitoring interface control
21 Jan 1999
Richard Gooch
<rgooch AT atnf DOT csiro DOT au>

Many processors provide special Performance Monitoring Counters (PMCs)
for the purposes of system or application tuning. You can usually
count mundane events such as the number of floating point multiplies,
to more exotic events such as the number of cache misses when reading
data. If you have a programme which is not running as fast as you
expected, performance monitoring can provide useful insights. The
CONFIG_PERFMON option allows you to compile the device driver which
provides a slightly simplified interface to these features. The driver
creates the /dev/cpu/perfmon%u device files (one file per performance
counter).

In general, you can also gain access to these facilities using the
interface created by CONFIG_MSR, but that interface is harder to use
and buggy programmes using it are more likely to crash your machine.

Because this is a cruel world, the kinds of events you can monitor
vary greatly from one model processor to another. This interface tries
to make no assumptions about the kinds of events supported, it just
provides a generic interface for selecting which events are to be
counted and easy access to the counters themselves. It is up to the
programmer to know which event codes are available for different model
processors.

If you read one of the device files, the current counter value is
output in ASCII hexadecimal format. A set of ioctl() operations allows
you to select which event a counter will count.

The counters can operate in one of two modes: "global" (or basic) and
"virtual" (or per-process). In global mode, the PMCs count events for
all processes on the system. On a system which is idle except for the
application you wish to monitor, this is the easiest mode of
operation. On a busy system, you may wish to consider enabling virtual
mode. In this mode, each process (or thread) has it's own set of
private (virtual) PMCs, which are saved and restored across context
switches. Naturally, when you read the device files you only see the
PMCs for the reading process and not an aggregate of the whole
system. If you wish to inspect the PMCs of another process, you need
to use the ptrace(2) interface. Note that the same type of event is
counted for all processes for each PMC.
NOTE: VIRTUAL MODE IS NOT YET IMPLEMENTED.

A separate user space library is available from:
http://www.atnf.csiro.au/~rgooch/linux/
which provides a simple and convenient interface to the device
driver. In addition, header files are provided which have symbolic
definitions for the event codes for some processor models.