PATCH: Lossless performance meas. with MSRs of i586

Harald Hoyer (Hoyer@hot.spotline.de)
Fri, 05 Jun 1998 14:15:55 +0200


This is a multi-part message in MIME format.
--------------FB85815A33FA456C556221C4
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

Hi,

this patch (attached) applies to linux-2.1.104pre1 (maybe also to 2.1.103). It
is not supposed to go in the 2.2 kernel.
# export POSIXLY_CORRECT=1
# cd /usr/src/linux
# patch -p1 -u </foo/bar/msr-104.patch

POSIXLY_CORRECT=1 must be set (for my version of patch) to understand the
cvs-diff format.

TODO: Support for i686

Happy measurement.....

Please report bugs, successes, etc.

linux/Documentation/msr.txt:

Performance Counter MSR (support for Linux by Harald Hoyer) :
-------------------------------------------------------------

If you have an Intel 586, you may specify CONFIG_MSR in your config.
It provides you access to Performance Counters by a per task basis
by the file /proc/<pid>/msr .

You can read from it:

# cat /proc/<pid>/msr
CESR 0
CTR0 0
CTR1 0

or write to it:

# echo "$[0x970096],0,0,0,0,0" >/proc/<pid>/msr
# cat /proc/<pid>/msr
CESR 0x970096
CTR0 0x0463b
CTR1 0x01561

This lets you monitor various events without loss of speed. You also
can specify whether you want to record in kernel, user or both protection
levels.

the format for writing is:
CESR_LOW,CESR_HIGH,CTR0_LOW,CTR0_HIGH,CTR1_LOW,CTR1_HIGH

According to the Intel Architecture Specification:

CESR_LOW:
bit 0..5 ES0 Event selector for Counter 0
bit 16..21 ES1 Event selector for Counter 1
bit 6..8 CC0 Counter control for Counter 0
bit 22..24 CC1 Counter control for Counter 1
bit 9 PC0 Pin control 0
bit 25 PC1 Pin control 1

CESR_HIGH: always 0

CCn:
000 Count nothing (counter disabled)
001 Count event while CPL is 0, 1, or 2 (Kernel level)
010 Count event while CPL 3 (User level)
011 Count event regardless of CPL (Kernel and User level)
100 Count nothing (counter disabled)
101 Count clocks while CPL is 0, 1, or 2 (Kernel level)
110 Count clocks while CPL 3 (User level)
111 Count clocks regardless of CPL (Kernel and User level)

ES0,ES1: Event/Counter number see Table A-2 in the System Programming Guide

some interesting ones:

0x16 count every instruction
0x17 count every instruction in the V-pipe
(number of instructions that were paired)

-------------------------------------------------------------------------------

/* Small example program, demonstrating the use of the performance counters
*
* Author: Harald Hoyer mailto:HarryH@Royal.Net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*
*/

#include <stdio.h>
#include <asm/msr.h>

main()
{
unsigned long val[2],pair[2],i;
char buf[4096];

FILE *fptr;


if(!(fptr = fopen("/proc/self/msr","r+b")))
exit(10);

fprintf(fptr, "%lu,0,0,0,0,0\n", ES0(0x16)|CC0(2)|ES1(0x17)|CC1(2));

fclose(fptr);

rdtsc(val[0],val[1]);
printf("tsc = %Lu\n", *((unsigned long long *)val));

rdpmc(0, val[0],val[1]);
printf("instr = %Lu\n", *((unsigned long long *)val));

rdpmc(1, pair[0],pair[1]);
printf("paired= %Lu\n", *((unsigned long long *)pair));

printf("%.2lf%% paired\n",
(double)((double)(*((unsigned long long *)pair))
/(double)(*((unsigned long long *)val))));

printf("\n");

if(!(fptr = fopen("/proc/self/msr","r+b")))
exit(10);

while(!feof(fptr)) {
if(fgets(buf, 4095, fptr))
printf("%s", buf);
}
fclose(fptr);
}

-- 
»»»» Harald Hoyer ««»» mailto:HarryH@Royal.Net ««»» http://hot.spotline.de ««««
···············································································
Today is the first day of the rest of your lossage.
--------------FB85815A33FA456C556221C4
Content-Type: text/plain; charset=us-ascii; name="msr-104.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="msr-104.patch"

Index: linux/CREDITS =================================================================== RCS file: /home/saturn/Develop//linux/CREDITS,v retrieving revision 1.1.1.69.2.1 retrieving revision 1.1.1.69.2.2 diff -u -r1.1.1.69.2.1 -r1.1.1.69.2.2 --- CREDITS 1998/06/04 21:06:51 1.1.1.69.2.1 +++ CREDITS 1998/06/05 11:43:44 1.1.1.69.2.2 @@ -765,6 +765,7 @@ W: http://home.pages.de/~saturn D: ip_masq_quake D: md boot support +D: msr performance counters S: Alleenstrasse 27 S: D-71679 Asperg S: Germany Index: linux/Documentation/Configure.help =================================================================== RCS file: /home/saturn/Develop//linux/Documentation/Configure.help,v retrieving revision 1.1.1.58.2.1 retrieving revision 1.1.1.58.2.2 diff -u -r1.1.1.58.2.1 -r1.1.1.58.2.2 --- Configure.help 1998/06/04 21:07:14 1.1.1.58.2.1 +++ Configure.help 1998/06/05 11:43:45 1.1.1.58.2.2 @@ -7187,6 +7187,17 @@ could lock up. See Documentation/mtrr.txt for more information. +MSR control and configuration +CONFIG_MSR + On Intel Pentium systems the Machine Specific Registers (MSRs) + CESR, CTR0, CTR1 may be used to measure counts or clocks of + various events, specified by Intel. This is e.g. useful for measuring + instruction pairing in the two Pentium pipes while optimizing your + programs. + This option creates a /proc/<pid>/msr file which may be used to + manipulate your MSRs. Compiling this as a module is not available. + See Documentation/msr.txt for more information. + Main CPU frequency, only for DEC alpha machine CONFIG_FT_ALPHA_CLOCK On some DEC Alpha machines the CPU clock frequency cannot be Index: linux/Documentation/msr.txt =================================================================== RCS file: msr.txt diff -N msr.txt --- /dev/null Thu Feb 12 15:20:26 1998 +++ /tmp/cvs12561eaa Fri Jun 5 13:45:27 1998 @@ -0,0 +1,118 @@ +Performance Counter MSR (support for Linux by Harald Hoyer) : +------------------------------------------------------------- + +If you have an Intel 586, you may specify CONFIG_MSR in your config. +It provides you access to Performance Counters by a per task basis +by the file /proc/<pid>/msr . + +You can read from it: + +# cat /proc/<pid>/msr +CESR 0 +CTR0 0 +CTR1 0 + +or write to it: + +# echo "$[0x970096],0,0,0,0,0" >/proc/<pid>/msr +# cat /proc/<pid>/msr +CESR 0x970096 +CTR0 0x0463b +CTR1 0x01561 + +This lets you monitor various events without loss of speed. You also +can specify wether you want to record in kernel, user or both protection +levels. + +the format for writing is: +CESR_LOW,CESR_HIGH,CTR0_LOW,CTR0_HIGH,CTR1_LOW,CTR1_HIGH + +According to the Intel Architecture Specification: + +CESR_LOW: + bit 0..5 ES0 Event selector for Counter 0 + bit 16..21 ES1 Event selector for Counter 1 + bit 6..8 CC0 Counter control for Counter 0 + bit 22..24 CC1 Counter control for Counter 1 + bit 9 PC0 Pin control 0 + bit 25 PC1 Pin control 1 + +CESR_HIGH: always 0 + +CCn: + 000 Count nothing (counter disabled) + 001 Count event while CPL is 0, 1, or 2 (Kernel level) + 010 Count event while CPL 3 (User level) + 011 Count event regardless of CPL (Kernel and User level) + 100 Count nothing (counter disabled) + 101 Count clocks while CPL is 0, 1, or 2 (Kernel level) + 110 Count clocks while CPL 3 (User level) + 111 Count clocks regardless of CPL (Kernel and User level) + + +ES0,ES1: Event/Counter number see Table A-2 in the System Programming Guide + + some interesting ones: + + 0x16 count every instruction + 0x17 count every instruction in the V-pipe + (number of instructions that were paired) +------------------------------------------------------------------------------- +/* Small example program, demonstrating the use of the performance counters + * + * Author: Harald Hoyer mailto:HarryH@Royal.Net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * + */ + + +#include <stdio.h> +#include <asm/msr.h> + +main() +{ + unsigned long val[2],pair[2],i; + char buf[4096]; + + FILE *fptr; + + + if(!(fptr = fopen("/proc/self/msr","r+b"))) + exit(10); + + fprintf(fptr, "%lu,0,0,0,0,0\n", ES0(0x16)|CC0(2)|ES1(0x17)|CC1(2)); + + fclose(fptr); + + rdtsc(val[0],val[1]); + printf("tsc = %Lu\n", *((unsigned long long *)val)); + + rdpmc(0, val[0],val[1]); + printf("instr = %Lu\n", *((unsigned long long *)val)); + + rdpmc(1, pair[0],pair[1]); + printf("paired= %Lu\n", *((unsigned long long *)pair)); + + printf("%.2lf%% paired\n", + (double)((double)(*((unsigned long long *)pair)) + /(double)(*((unsigned long long *)val)))); + + printf("\n"); + + if(!(fptr = fopen("/proc/self/msr","r+b"))) + exit(10); + + while(!feof(fptr)) { + if(fgets(buf, 4095, fptr)) + printf("%s", buf); + } + fclose(fptr); +} + + +-- Harald Hoyer <HarryH@Royal.Net> Index: linux/arch/i386/config.in =================================================================== RCS file: /home/saturn/Develop//linux/arch/i386/config.in,v retrieving revision 1.1.1.23 retrieving revision 1.1.1.23.4.1 diff -u -r1.1.1.23 -r1.1.1.23.4.1 --- config.in 1998/05/01 14:08:28 1.1.1.23 +++ config.in 1998/06/05 08:40:33 1.1.1.23.4.1 @@ -19,6 +19,9 @@ bool 'Math emulation' CONFIG_MATH_EMULATION if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR + if [ "$CONFIG_M586" = "y" ]; then + bool 'MSR (Machine specific registers) support' CONFIG_MSR + fi fi endmenu Index: linux/arch/i386/mm/init.c =================================================================== RCS file: /home/saturn/Develop//linux/arch/i386/mm/init.c,v retrieving revision 1.1.1.18.2.1 retrieving revision 1.1.1.18.2.3 diff -u -r1.1.1.18.2.1 -r1.1.1.18.2.3 --- init.c 1998/06/04 21:08:20 1.1.1.18.2.1 +++ init.c 1998/06/05 08:40:34 1.1.1.18.2.3 @@ -106,33 +106,6 @@ extern char _text, _etext, _edata, __bss_start, _end; extern char __init_begin, __init_end; -#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ -#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ -#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ -#define X86_CR4_DE 0x0008 /* enable debugging extensions */ -#define X86_CR4_PSE 0x0010 /* enable page size extensions */ -#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ -#define X86_CR4_MCE 0x0040 /* Machine check enable */ -#define X86_CR4_PGE 0x0080 /* enable global pages */ -#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ - -#define X86_FEATURE_FPU 0x0001 /* internal FPU */ -#define X86_FEATURE_VME 0x0002 /* vm86 extensions */ -#define X86_FEATURE_DE 0x0004 /* debugging extensions */ -#define X86_FEATURE_PSE 0x0008 /* Page size extensions */ -#define X86_FEATURE_TSC 0x0010 /* Time stamp counter */ -#define X86_FEATURE_MSR 0x0020 /* RDMSR/WRMSR */ -#define X86_FEATURE_PAE 0x0040 /* Physical address extension */ -#define X86_FEATURE_MCE 0x0080 /* Machine check exception */ -#define X86_FEATURE_CXS 0x0100 /* cmpxchg8 available */ -#define X86_FEATURE_APIC 0x0200 /* internal APIC */ -#define X86_FEATURE_10 0x0400 -#define X86_FEATURE_11 0x0800 -#define X86_FEATURE_MTRR 0x1000 /* memory type registers */ -#define X86_FEATURE_PGE 0x2000 /* Global page */ -#define X86_FEATURE_MCA 0x4000 /* Machine Check Architecture */ -#define X86_FEATURE_CMOV 0x8000 /* Cmov/fcomi */ - /* * Save the cr4 feature set we're using (ie * Pentium 4MB enable and PPro Global page @@ -197,6 +170,12 @@ smp_scan_config(address, 0x1000); } #endif + + + if (boot_cpu_data.x86_capability & X86_FEATURE_MSR) { + set_in_cr4(X86_CR4_PCE); + } + start_mem = PAGE_ALIGN(start_mem); address = PAGE_OFFSET; pg_dir = swapper_pg_dir; Index: linux/fs/proc/array.c =================================================================== RCS file: /home/saturn/Develop//linux/fs/proc/array.c,v retrieving revision 1.1.1.30 retrieving revision 1.1.1.30.2.3 diff -u -r1.1.1.30 -r1.1.1.30.2.3 --- array.c 1998/05/08 08:29:51 1.1.1.30 +++ array.c 1998/06/05 11:43:57 1.1.1.30.2.3 @@ -35,9 +35,13 @@ * - Incorporation and non-SMP safe operation * of forissier patch in 2.1.78 by * Hans Marcus <crowbar@concepts.nl> + * + * Harald Hoyer : added msr performance counters + * <HarryH@Royal.Net> */ #include <linux/types.h> +#include <linux/ctype.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -56,6 +60,7 @@ #include <linux/slab.h> #include <linux/smp.h> #include <linux/signal.h> +#include <linux/msr.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -1183,8 +1188,96 @@ return len; } + +#endif + +#ifdef CONFIG_MSR +#include <asm/processor.h> + +static int get_pidmsr(int pid, char * buffer) +{ + struct task_struct * tsk = current ; + int len; + + read_lock(&tasklist_lock); + if (pid != tsk->pid) + tsk = find_task_by_pid(pid); + read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ + + if (tsk == NULL) + return 0; + + + if(tsk->msr.cpu_t == 586) { + rdmsr(CESR, tsk->msr.regs.i586_p.l.cesr_l, + tsk->msr.regs.i586_p.l.cesr_h); + rdmsr(CTR0, tsk->msr.regs.i586_p.l.ctr0_l, + tsk->msr.regs.i586_p.l.ctr0_h); + rdmsr(CTR1, tsk->msr.regs.i586_p.l.ctr1_l, + tsk->msr.regs.i586_p.l.ctr1_h); + + len = sprintf(buffer, + "CESR 0x%lx\n" + "CTR0 0x%lx%lx\n" + "CTR1 0x%lx%lx\n", + tsk->msr.regs.i586_p.l.cesr_l, + tsk->msr.regs.i586_p.l.ctr0_h, + tsk->msr.regs.i586_p.l.ctr0_l, + tsk->msr.regs.i586_p.l.ctr1_h, + tsk->msr.regs.i586_p.l.ctr1_l); + return len; + } + else { + return sprintf(buffer, "CESR 0\nCTR0 0\nCTR1 0\n"); + } +} + + +static char *get_longs(char *str, unsigned long *longs, int num) +{ + char *cur = str; + int i=0; + + while (cur && isdigit(*cur) && i < num) { + longs[i++] = simple_strtoul(cur,NULL,0); + if ((cur = strchr(cur,',')) != NULL) + cur++; + } + return(cur); +} + +static int put_pidmsr(int pid, char * buffer, int len) +{ + struct task_struct * tsk = current ; + + read_lock(&tasklist_lock); + + if (pid != tsk->pid) + tsk = find_task_by_pid(pid); + + read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ + + if (tsk == NULL) + return -EBADF; + + if (boot_cpu_data.x86_capability & X86_FEATURE_MSR) { + tsk->msr.cpu_t = 586; + + get_longs(buffer, (unsigned long *)&tsk->msr.regs.i586_p.l, 6); + + wrmsr(CESR, tsk->msr.regs.i586_p.l.cesr_l, + tsk->msr.regs.i586_p.l.cesr_h); + wrmsr(CTR0, tsk->msr.regs.i586_p.l.ctr0_l, + tsk->msr.regs.i586_p.l.ctr0_h); + wrmsr(CTR1, tsk->msr.regs.i586_p.l.ctr1_l, + tsk->msr.regs.i586_p.l.ctr1_h); + return len; + } + else return -ENXIO; +} #endif + #ifdef CONFIG_MODULES extern int get_module_list(char *); extern int get_ksyms_list(char *, char **, off_t, int); @@ -1311,6 +1404,10 @@ case PROC_PID_CPU: return get_pidcpu(pid, page); #endif +#ifdef CONFIG_MSR + case PROC_PID_MSR: + return get_pidmsr(pid, page); +#endif } return -EBADF; } @@ -1376,10 +1473,70 @@ return count; } +static int put_process_array(char * page, int pid, int type, int len) +{ + switch (type) { +#ifdef CONFIG_MSR + case PROC_PID_MSR: + return put_pidmsr(pid, page, len); +#endif + } + return -EBADF; +} + +static ssize_t array_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct inode * inode = file->f_dentry->d_inode; + char *page; + char c; + const char *p=buf; + ssize_t len=0; + unsigned int type, pid; + struct proc_dir_entry *dp; + + if (count > PROC_BLOCK_SIZE) + count = PROC_BLOCK_SIZE; + if (!(page = (char *)__get_free_page(GFP_KERNEL))) + return -ENOMEM; + type = inode->i_ino; + pid = type >> 16; + type &= 0x0000ffff; + + dp = (struct proc_dir_entry *) inode->u.generic_ip; + + if (!dp ) + return -ENOTDIR; + + while (len < count) { + if(get_user(c, p++)) + return -EFAULT; + if (c == 0 || c == '\n') + break; + len++; + } + + if(len == 0) + return count; + + if (len > PAGE_SIZE-2) + len = PAGE_SIZE-2; + + if(copy_from_user(page, buf, len)) + return -EFAULT; + + page[len-1]=0; + + len = put_process_array((char *) page, pid, type, len); + + free_page((unsigned long)page); + return len; +} + static struct file_operations proc_array_operations = { NULL, /* array_lseek */ array_read, - NULL, /* array_write */ + array_write, NULL, /* array_readdir */ NULL, /* array_poll */ NULL, /* array_ioctl */ Index: linux/fs/proc/base.c =================================================================== RCS file: /home/saturn/Develop//linux/fs/proc/base.c,v retrieving revision 1.1.1.10 retrieving revision 1.1.1.10.6.3 diff -u -r1.1.1.10 -r1.1.1.10.6.3 --- base.c 1998/04/24 20:05:36 1.1.1.10 +++ base.c 1998/06/05 11:43:58 1.1.1.10.6.3 @@ -169,6 +169,15 @@ }; #endif +#ifdef CONFIG_MSR +static struct proc_dir_entry proc_pid_msr = { + PROC_PID_MSR, 3, "msr", + S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, +}; +#endif + void proc_base_init(void) { #if CONFIG_AP1000 @@ -188,14 +197,7 @@ #ifdef __SMP__ proc_register(&proc_pid, &proc_pid_cpu); #endif +#ifdef CONFIG_MSR + proc_register(&proc_pid, &proc_pid_msr); +#endif }; - - - - - - - - - - Index: linux/include/asm-i386/msr.h =================================================================== RCS file: msr.h diff -N msr.h --- /dev/null Thu Feb 12 15:20:26 1998 +++ /tmp/cvs12561paa Fri Jun 5 13:46:38 1998 @@ -0,0 +1,93 @@ +/* + * Machine Specific Register of i586 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998 + */ + +#ifndef __ASM_MSR_H +#define __ASM_MSR_H + +#ifndef rdmsr +#define rdmsr(msr,val1,val2) \ + __asm__ __volatile__("rdmsr" \ + : "=a" (val1), "=d" (val2) \ + : "c" (msr)) +#endif + +#ifndef rdpmc +#define rdpmc(ctrno,val1,val2) \ + __asm__ __volatile__("rdpmc" \ + : "=a" (val1), "=d" (val2) \ + : "c" (ctrno)) +#endif + +#ifndef rdtsc +#define rdtsc(val1,val2) \ + __asm__ __volatile__("rdtsc" \ + : "=a" (val1), "=d" (val2) \ + : /* */) +#endif + +#ifndef wrmsr +#define wrmsr(msr,val1,val2) \ + __asm__ __volatile__("wrmsr" \ + : /* no outputs */ \ + : "c" (msr), "a" (val1), "d" (val2)) +#endif + +#define CESR 0x11 +#define CTR0 0x12 +#define CTR1 0x13 + +#define ES0(a) (a&31L) +#define CC0(a) ((a&7L)<<6) +#define ES1(a) ((a&31L)<<16) +#define CC1(a) ((a&7L)<<22) + +#ifdef __KERNEL__ + +#ifndef CONFIG_MSR +#error asm/msr.h included but CONFIG_MSR not set +#endif + +#define msr_switch_to(prev, next) do { \ + if(prev->msr.cpu_t == 586) { \ + rdmsr(CESR, prev->msr.regs.i586_p.l.cesr_l, prev->msr.regs.i586_p.l.cesr_h); \ + rdmsr(CTR0, prev->msr.regs.i586_p.l.ctr0_l, prev->msr.regs.i586_p.l.ctr0_h); \ + rdmsr(CTR1, prev->msr.regs.i586_p.l.ctr1_l, prev->msr.regs.i586_p.l.ctr1_h); \ + } \ + if(next->msr.cpu_t == 586) { \ + wrmsr(CESR, next->msr.regs.i586_p.l.cesr_l, next->msr.regs.i586_p.l.cesr_h); \ + wrmsr(CTR0, next->msr.regs.i586_p.l.ctr0_l, next->msr.regs.i586_p.l.ctr0_h); \ + wrmsr(CTR1, next->msr.regs.i586_p.l.ctr1_l, next->msr.regs.i586_p.l.ctr1_h); \ + } \ +} while (0) + + +struct msrreg_s { + int cpu_t; + union { + union { + struct { + unsigned long long cesr; + unsigned long long ctr0; + unsigned long long ctr1; + } ll; + struct { + unsigned long cesr_l, cesr_h; + unsigned long ctr0_l, ctr0_h; + unsigned long ctr1_l, ctr1_h; + } l; + } i586_p; + struct { + int none; /* TODO */ + } i686_p; + } regs; +}; +#endif + +#endif Index: linux/include/asm-i386/processor.h =================================================================== RCS file: /home/saturn/Develop//linux/include/asm-i386/processor.h,v retrieving revision 1.1.1.23 retrieving revision 1.1.1.23.2.1 diff -u -r1.1.1.23 -r1.1.1.23.2.1 --- processor.h 1998/05/22 09:34:56 1.1.1.23 +++ processor.h 1998/06/05 08:40:45 1.1.1.23.2.1 @@ -44,6 +44,34 @@ #define X86_VENDOR_CENTAUR 5 #define X86_VENDOR_UNKNOWN 0xff +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x0008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x0010 /* enable page size extensions */ +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x0040 /* Machine check enable */ +#define X86_CR4_PGE 0x0080 /* enable global pages */ +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ + +#define X86_FEATURE_FPU 0x0001 /* internal FPU */ +#define X86_FEATURE_VME 0x0002 /* vm86 extensions */ +#define X86_FEATURE_DE 0x0004 /* debugging extensions */ +#define X86_FEATURE_PSE 0x0008 /* Page size extensions */ +#define X86_FEATURE_TSC 0x0010 /* Time stamp counter */ +#define X86_FEATURE_MSR 0x0020 /* RDMSR/WRMSR */ +#define X86_FEATURE_PAE 0x0040 /* Physical address extension */ +#define X86_FEATURE_MCE 0x0080 /* Machine check exception */ +#define X86_FEATURE_CXS 0x0100 /* cmpxchg8 available */ +#define X86_FEATURE_APIC 0x0200 /* internal APIC */ +#define X86_FEATURE_10 0x0400 +#define X86_FEATURE_11 0x0800 +#define X86_FEATURE_MTRR 0x1000 /* memory type registers */ +#define X86_FEATURE_PGE 0x2000 /* Global page */ +#define X86_FEATURE_MCA 0x4000 /* Machine Check Architecture */ +#define X86_FEATURE_CMOV 0x8000 /* Cmov/fcomi */ + + extern struct cpuinfo_x86 boot_cpu_data; #ifdef __SMP__ Index: linux/include/asm-i386/system.h =================================================================== RCS file: /home/saturn/Develop//linux/include/asm-i386/system.h,v retrieving revision 1.1.1.21 retrieving revision 1.1.1.21.6.3 diff -u -r1.1.1.21 -r1.1.1.21.6.3 --- system.h 1998/04/24 21:51:15 1.1.1.21 +++ system.h 1998/06/05 11:44:01 1.1.1.21.6.3 @@ -2,6 +2,7 @@ #define __ASM_SYSTEM_H #include <asm/segment.h> +#include <linux/msr.h> /* * Entry into gdt where to find first TSS. GDT layout: @@ -80,6 +81,8 @@ : /* no output */ \ :"m" (*(((char *)&next->tss.tr)-4)), \ "c" (next)); \ + /* switch msr registers */ \ + msr_switch_to(prev,next); \ /* Now maybe reload the debug registers */ \ if(prev->debugreg[7]){ \ loaddebug(prev,0); \ @@ -101,6 +104,8 @@ : /* no outputs */ \ :"m" (*(((char *)&next->tss.tr)-4)), \ "r" (prev), "r" (next)); \ + /* switch msr registers */ \ + msr_switch_to(prev,next); \ /* Now maybe reload the debug registers */ \ if(prev->debugreg[7]){ \ loaddebug(prev,0); \ Index: linux/include/linux/proc_fs.h =================================================================== RCS file: /home/saturn/Develop//linux/include/linux/proc_fs.h,v retrieving revision 1.1.1.38 retrieving revision 1.1.1.38.2.2 diff -u -r1.1.1.38 -r1.1.1.38.2.2 --- proc_fs.h 1998/05/15 05:57:57 1.1.1.38 +++ proc_fs.h 1998/06/05 11:44:02 1.1.1.38.2.2 @@ -71,6 +71,9 @@ PROC_PID_RINGBUF, #endif PROC_PID_CPU, +#ifdef CONFIG_MSR + PROC_PID_MSR, +#endif }; enum pid_subdirectory_inos { Index: linux/include/linux/sched.h =================================================================== RCS file: /home/saturn/Develop//linux/include/linux/sched.h,v retrieving revision 1.1.1.36 retrieving revision 1.1.1.36.2.3 diff -u -r1.1.1.36 -r1.1.1.36.2.3 --- sched.h 1998/05/22 09:35:34 1.1.1.36 +++ sched.h 1998/06/05 11:44:03 1.1.1.36.2.3 @@ -106,6 +106,8 @@ #include <asm/spinlock.h> +#include <linux/msr.h> + /* * This serializes "schedule()" and also protects * the run-queue from deletions/modifications (but @@ -291,6 +293,10 @@ int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ /* Spinlocks for various pieces or per-task state. */ spinlock_t sigmask_lock; /* Protects signal and blocked */ + +#ifdef CONFIG_MSR + struct msrreg_s msr; /* Performance register */ +#endif }; /* @@ -366,7 +372,7 @@ /* mm */ &init_mm, \ /* signals */ &init_signals, {{0}}, {{0}}, NULL, &init_task.sigqueue, \ /* SMP */ 0,0,0,0, \ -/* locks */ INIT_LOCKS \ +/* locks */ INIT_LOCKS, \ } union task_union {

--------------FB85815A33FA456C556221C4--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu