Re: Why is PCE not set in CR4?

2003-10-02 Thread Terry Lambert
Bruce M Simpson wrote:
 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.
[ ... ]
 
 This is an extension to the i386_vm86() syscall which will let you turn
 PCE on and off if you're the superuser.

I like this a lot better.

To answer the inevitable question of why: PCE counters are a
scarce resource, and the kernel needs to run interference on
their allocation and deallocation by user space applications, to
avoid collisions between applications; this is the same reason
we have AGP and sound card device drivers in the kernel.

I'm not sure if restricting this to root users is exactly
necessary, but it can't hurt, given that there is a performance
denial of service possible otherwise.

-- Terry
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: Why is PCE not set in CR4?

2003-10-01 Thread Bruce M Simpson
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
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.hWed 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 */
 };
 

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: Why is PCE not set in CR4?

2003-09-30 Thread DoubleF
On Tue, 30 Sep 2003 00:18:19 +0200 Shill [EMAIL PROTECTED] probably wrote:

 Hello all,
 
 I've been playing with my Athlon's timestamp counter for a while,
 and I would like to experiment with the performance-monitoring
 counters now.
 
 I can execute the RDTSC instruction from ring 3 because the TSD
 (TimeStamp Disable) bit in CR4 (Control Register 4) is cleared.
 
 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.

 Is there a reason (security? performance? other?) why FreeBSD does
 not set PCE at boot time?

 On a related subject, is there a way for a kernel module to catch a
 general-protection fault caused by an application trying to execute
 RDMSR or WRMSR, and have the kernel module execute the instruction
 for the application? Or is it cleaner to register two new system
 calls to achieve the same thing?

That would (probably) require adding superuser-configurable permissions
to read/write to a specific MSR, as some of them are critical. I doubt
it's worth creating extra device nodes, and I wonder if there's a
cleaner way to do that. 

-- 
DoubleF
The simpler the instruction, e.g. press here, the
more difficult it will be to open the package.


pgp0.pgp
Description: PGP signature