diff -uNr linux-2.6.31/arch/x86/kernel/syscall_table_32.S linux-2.6.31_intelinstr/arch/x86/kernel/syscall_table_32.S
--- linux-2.6.31/arch/x86/kernel/syscall_table_32.S	2009-09-09 19:13:59.000000000 -0300
+++ linux-2.6.31_intelinstr/arch/x86/kernel/syscall_table_32.S	2009-12-02 13:36:02.000000000 -0200
@@ -336,3 +336,7 @@
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
 	.long sys_perf_counter_open
+	.long sys_read_cr4_pce
+	.long sys_rdpmc
+	.long sys_wrmsr
+	.long sys_rdmsr			/* 340 */
diff -uNr linux-2.6.31/arch/x86/kernel/traps.c linux-2.6.31_intelinstr/arch/x86/kernel/traps.c
--- linux-2.6.31/arch/x86/kernel/traps.c	2009-09-09 19:13:59.000000000 -0300
+++ linux-2.6.31_intelinstr/arch/x86/kernel/traps.c	2009-12-02 13:38:19.000000000 -0200
@@ -971,6 +971,10 @@
 		printk("done.\n");
 	}
 
+	printk(KERN_INFO "Enabling PCE flag... ");
+	set_in_cr4(X86_CR4_PCE);
+	printk("done.\n");
+
 	set_system_trap_gate(SYSCALL_VECTOR, &system_call);
 	set_bit(SYSCALL_VECTOR, used_vectors);
 #endif
diff -uNr linux-2.6.31/include/asm-generic/unistd.h linux-2.6.31_intelinstr/include/asm-generic/unistd.h
--- linux-2.6.31/include/asm-generic/unistd.h	2009-09-09 19:13:59.000000000 -0300
+++ linux-2.6.31_intelinstr/include/asm-generic/unistd.h	2009-12-02 15:32:24.000000000 -0200
@@ -623,8 +623,17 @@
 #define __NR_perf_counter_open 241
 __SYSCALL(__NR_perf_counter_open, sys_perf_counter_open)
 
+#define __NR_read_cr4_pce 242
+__SYSCALL(__NR_read_cr4_pce, sys_read_cr4_pce)
+#define __NR_rdpmc 243
+__SYSCALL(__NR_rdpmc, sys_rdpmc)
+#define __NR_wrmsr 244
+__SYSCALL(__NR_wrmsr, sys_wrmsr)
+#define __NR_rdmsr 245
+__SYSCALL(__NR_rdmsr, sys_rdmsr)
+
 #undef __NR_syscalls
-#define __NR_syscalls 242
+#define __NR_syscalls 246
 
 /*
  * All syscalls below here should go away really,
diff -uNr linux-2.6.31/include/linux/syscalls.h linux-2.6.31_intelinstr/include/linux/syscalls.h
--- linux-2.6.31/include/linux/syscalls.h	2009-09-09 19:13:59.000000000 -0300
+++ linux-2.6.31_intelinstr/include/linux/syscalls.h	2009-12-02 15:42:41.000000000 -0200
@@ -761,4 +761,11 @@
 asmlinkage long sys_perf_counter_open(
 		struct perf_counter_attr __user *attr_uptr,
 		pid_t pid, int cpu, int group_fd, unsigned long flags);
+
+
+asmlinkage long sys_read_cr4_pce(void);
+asmlinkage long sys_rdpmc(int event, unsigned long long* ret);
+asmlinkage long sys_wrmsr(unsigned int msr, unsigned low, unsigned high);
+asmlinkage long sys_rdmsr(unsigned int msr, unsigned long long* ret);
+
 #endif
diff -uNr linux-2.6.31/Makefile linux-2.6.31_intelinstr/Makefile
--- linux-2.6.31/Makefile	2009-09-09 19:13:59.000000000 -0300
+++ linux-2.6.31_intelinstr/Makefile	2009-12-02 15:37:52.000000000 -0200
@@ -639,7 +639,7 @@
 
 
 ifeq ($(KBUILD_EXTMOD),)
-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/ mycall/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
diff -uNr linux-2.6.31/mycall/Makefile linux-2.6.31_intelinstr/mycall/Makefile
--- linux-2.6.31/mycall/Makefile	1969-12-31 21:00:00.000000000 -0300
+++ linux-2.6.31_intelinstr/mycall/Makefile	2009-12-02 15:36:00.000000000 -0200
@@ -0,0 +1 @@
+obj-y := mycall.o
diff -uNr linux-2.6.31/mycall/mycall.c linux-2.6.31_intelinstr/mycall/mycall.c
--- linux-2.6.31/mycall/mycall.c	1969-12-31 21:00:00.000000000 -0300
+++ linux-2.6.31_intelinstr/mycall/mycall.c	2009-12-02 15:43:03.000000000 -0200
@@ -0,0 +1,46 @@
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+asmlinkage long sys_read_cr4_pce(void) {
+  unsigned cr4;
+
+  cr4 = read_cr4();
+  cr4 &= X86_CR4_PCE;
+
+  return (long) (cr4 != 0);
+}
+
+asmlinkage long sys_rdpmc(int event, unsigned long long* ret) {
+  unsigned eax, ecx, edx;
+  ecx = event;
+  asm volatile("movl %2, %%ecx\n\t" 
+	       "rdpmc\n\t"
+	       "movl %%eax, %0 \n\t"
+	       "movl %%edx, %1 \n\t"
+	       : "=a" (eax), "=d" (edx)
+	       : "c" (ecx));
+  *ret = edx & 0xff;
+  *ret = (*ret << 32) | eax;
+  return 1;
+}
+
+asmlinkage long sys_wrmsr(unsigned int msr,
+			  unsigned low, unsigned high) {
+  asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+  return (long) msr;
+}
+
+asmlinkage long sys_rdmsr(unsigned int msr,
+			  unsigned long long* ret) {
+  unsigned eax, edx;
+  asm volatile("movl %2, %%ecx\n\t" 
+	       "rdmsr\n\t"
+	       "movl %%eax, %0 \n\t"
+	       "movl %%edx, %1 \n\t"
+	       : "=a" (eax), "=d" (edx)
+	       : "c" (msr));
+  *ret = edx & 0xff;
+  *ret = (*ret << 32) | eax;
+  return 1;
+}
