From owner-freebsd-questions@FreeBSD.ORG Wed Oct 1 04:42:02 2003 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D317F16A4B3; Wed, 1 Oct 2003 04:42:02 -0700 (PDT) Received: from arginine.spc.org (arginine.spc.org [195.206.69.236]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5ACB543FDF; Wed, 1 Oct 2003 04:42:01 -0700 (PDT) (envelope-from bms@spc.org) Received: from localhost (localhost [127.0.0.1]) by arginine.spc.org (Postfix) with ESMTP id C1AD1654DD; Wed, 1 Oct 2003 12:41:59 +0100 (BST) Received: from arginine.spc.org ([127.0.0.1]) by localhost (arginine.spc.org [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 70447-01-7; Wed, 1 Oct 2003 12:41:58 +0100 (BST) Received: from saboteur.dek.spc.org (unknown [81.3.72.68]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by arginine.spc.org (Postfix) with ESMTP id 7A68A654E7; Wed, 1 Oct 2003 12:41:58 +0100 (BST) Received: by saboteur.dek.spc.org (Postfix, from userid 1001) id C16861F; Wed, 1 Oct 2003 12:41:56 +0100 (BST) Date: Wed, 1 Oct 2003 12:41:56 +0100 From: Bruce M Simpson To: Grumble Message-ID: <20031001114155.GA12991@saboteur.dek.spc.org> Mail-Followup-To: Grumble , freebsd-questions@freebsd.org, freebsd-hackers@freebsd.org, freebsd-ia32@freebsd.org References: <3F7AA0D8.1080801@kma.eu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="DocE+STaALJfprDB" Content-Disposition: inline In-Reply-To: <3F7AA0D8.1080801@kma.eu.org> cc: freebsd-hackers@freebsd.org cc: freebsd-ia32@freebsd.org cc: freebsd-questions@freebsd.org Subject: Re: Why is PCE not set in CR4? X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Oct 2003 11:42:03 -0000 --DocE+STaALJfprDB Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Oct 01, 2003 at 11:39:36AM +0200, Grumble wrote: > >>However, I am not allowed to use the RDPMC instruction from ring 3 > >>because the PCE (Performance-monitoring Counters Enable) bit is not set. > > > >You can do it with /dev/perfmon. man 4 perfmon. > > I have read the perfmon documentation and source code. For several > reasons, I do not think it is totally adequate in my situation. [snip] Hi, Eat this. Diff attached. Test this and I'll commit it to -CURRENT if you're happy with it. If you can tell me more about what perfmon needs I'll give it love too. This is an extension to the i386_vm86() syscall which will let you turn PCE on and off if you're the superuser. BMS --DocE+STaALJfprDB Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="i386pce.col.diff" Generated by diffcoll on Wed 1 Oct 2003 12:39:07 BST diff -uN src/lib/libc/i386/sys/i386_vm86.2.orig src/lib/libc/i386/sys/i386_vm86.2 --- /usr/src/lib/libc/i386/sys/i386_vm86.2.orig Wed Oct 1 12:13:50 2003 +++ /usr/src/lib/libc/i386/sys/i386_vm86.2 Wed Oct 1 12:36:44 2003 @@ -112,6 +112,26 @@ .Fa state will contain the state of the VME flag on return. .\" .It Dv VM86_SET_VME +.It Dv VM86_GET_PCE +This is used to retrieve the current state of the Pentium(r) processor's +PCE (Performance Counter Enable) flag, which is bit 8 of CR4. +.Bd -literal +struct vm86_pce_args { + int state; /* status */ +}; +.Ed +.Pp +.Fa state +will contain the state of the VME flag on return. +.It Dv VM86_SET_PCE +This is used to set the current state of the PCE flag. +Enabling this bit allows any code to execute the +.Li RDPMC +instruction. +Disabling this bit will allow only code running at protection level 0 to +execute this instruction. +Because this bit has system-wide granularity, it may only be enabled by +the superuser. .El .Pp vm86 mode is entered by calling @@ -133,6 +153,13 @@ .It Bq Er ENOMEM There is not enough memory to initialize the kernel data structures. .El +.Sh BUGS +The +.Dv VM86_SETPCE +and +.Dv VM86_GETPCE +functions are only guaranteed to work for uniprocessor kernels; their +results on SMP systems are undefined. .Sh AUTHORS .An -nosplit This man page was written by diff -uN src/sys/i386/i386/vm86.c.orig src/sys/i386/i386/vm86.c --- /usr/src/sys/i386/i386/vm86.c.orig Wed Oct 1 12:16:23 2003 +++ /usr/src/sys/i386/i386/vm86.c Wed Oct 1 12:39:01 2003 @@ -734,6 +734,29 @@ } break; + case VM86_SET_PCE: { + struct vm86_pce_args sa; + + if ((error = suser(td))) + return (error); + if (!(cpu_feature & CPUID_TSC) || !(cpu_feature & CPUID_MMX)) + return (ENODEV); + if ((error = copyin(ua.sub_args, &sa, sizeof(sa)))) + return (error); + if (sa.state) + load_cr4(rcr4() | CR4_PCE); + else + load_cr4(rcr4() & ~CR4_PCE); + } + break; + + case VM86_GET_PCE: { + struct vm86_pce_args sa; + + sa.state = (rcr4() & CR4_PCE ? 1 : 0); + error = copyout(&sa, ua.sub_args, sizeof(sa)); + } + default: error = EINVAL; } diff -uN src/sys/i386/include/vm86.h.orig src/sys/i386/include/vm86.h --- /usr/src/sys/i386/include/vm86.h.orig Wed Oct 1 12:22:53 2003 +++ /usr/src/sys/i386/include/vm86.h Wed Oct 1 12:37:56 2003 @@ -128,6 +128,8 @@ #define VM86_SET_VME 2 #define VM86_GET_VME 3 #define VM86_INTCALL 4 +#define VM86_SET_PCE 5 +#define VM86_GET_PCE 6 struct vm86_init_args { int debug; /* debug flag */ @@ -136,6 +138,10 @@ }; struct vm86_vme_args { + int state; /* status */ +}; + +struct vm86_pce_args { int state; /* status */ }; --DocE+STaALJfprDB--