Module Name:    src
Committed By:   jym
Date:           Sun Apr 18 23:47:52 UTC 2010

Modified Files:
        src/sys/arch/amd64/amd64: locore.S machdep.c mptramp.S procfs_machdep.c
        src/sys/arch/i386/i386: genassym.cf machdep.c procfs_machdep.c
        src/sys/arch/i386/isa: npx.c
        src/sys/arch/x86/include: cpu.h cpuvar.h mpbiosreg.h specialreg.h
        src/sys/arch/x86/x86: cpu.c cpu_topology.c identcpu.c mpbios.c patch.c
            pmap.c tsc.c via_padlock.c x86_machdep.c
        src/sys/arch/xen/x86: cpu.c
        src/sys/compat/linux32/arch/amd64: linux32_exec.h
        src/sys/compat/linux32/common: linux32_exec_elf32.c

Log Message:
This patch fixes the NX regression issue observed on amd64 kernels, where
per-page execution right was disabled (therefore leading to the inability
of the kernel to detect fraudulent use of memory mappings marked as not
being executable).

- replace cpu_feature and ci_feature_flags variables by cpu_feature and
ci_feat_val arrays. This makes it cleaner and brings kernel code closer
to the design of cpuctl(8). A warning will be raised for each CPU that
does not expose the same features as the Boot Processor (BP).

- the blacklist of CPU features is now a macro defined in the
specialreg.h header, instead of hardcoding it inside MD initialization
code; fix comments.

- replace checks against CPUID_TSC with the cpu_hascounter() function.

- clean up the code in init_x86_64(), as cpu_feature variables are set
inside cpu_probe().

- use cpu_init_msrs() for i386. It will be eventually used later for NX
feature under i386 PAE kernels.

- remove code that checks for CPUID_NOX in amd64 mptramp.S, this is already
performed by cpu_hatch() through cpu_init_msrs().

- remove cpu_signature and feature_flags members from struct mpbios_proc
(they were never used).

This patch was tested with i386 MONOLITHIC, XEN3PAE_DOM0 and XEN3_DOM0 under
a native i386 host, and amd64 GENERIC, XEN3_DOM0 via QEMU virtual machines.

XXX Should kernel rev be bumped?

XXX A similar patch should be pulled-up for NetBSD-5, hopefully tomorrow.


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.143 -r1.144 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/amd64/amd64/mptramp.S
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/amd64/amd64/procfs_machdep.c
cvs rdiff -u -r1.85 -r1.86 src/sys/arch/i386/i386/genassym.cf
cvs rdiff -u -r1.684 -r1.685 src/sys/arch/i386/i386/machdep.c
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/i386/i386/procfs_machdep.c
cvs rdiff -u -r1.135 -r1.136 src/sys/arch/i386/isa/npx.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/x86/include/cpuvar.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x86/include/mpbiosreg.h
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/x86/include/specialreg.h
cvs rdiff -u -r1.69 -r1.70 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/x86/x86/cpu_topology.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/x86/identcpu.c
cvs rdiff -u -r1.56 -r1.57 src/sys/arch/x86/x86/mpbios.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/x86/x86/patch.c
cvs rdiff -u -r1.106 -r1.107 src/sys/arch/x86/x86/pmap.c
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/x86/x86/tsc.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/x86/x86/via_padlock.c
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.42 -r1.43 src/sys/arch/xen/x86/cpu.c
cvs rdiff -u -r1.2 -r1.3 src/sys/compat/linux32/arch/amd64/linux32_exec.h
cvs rdiff -u -r1.9 -r1.10 src/sys/compat/linux32/common/linux32_exec_elf32.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.56 src/sys/arch/amd64/amd64/locore.S:1.57
--- src/sys/arch/amd64/amd64/locore.S:1.56	Sun Apr 18 15:24:54 2010
+++ src/sys/arch/amd64/amd64/locore.S	Sun Apr 18 23:47:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.56 2010/04/18 15:24:54 jym Exp $	*/
+/*	$NetBSD: locore.S,v 1.57 2010/04/18 23:47:50 jym Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -231,7 +231,7 @@
 #endif
 
 	.globl	_C_LABEL(cpu_id),_C_LABEL(cpu_vendorname), _C_LABEL(cpu_brand_id)
-	.globl	_C_LABEL(cpuid_level),_C_LABEL(cpu_feature),_C_LABEL(cpu_feature2)
+	.globl	_C_LABEL(cpuid_level)
 	.globl	_C_LABEL(esym),_C_LABEL(eblob),_C_LABEL(boothowto)
 	.globl	_C_LABEL(bootinfo),_C_LABEL(atdevbase)
 	.globl	_C_LABEL(PDPpaddr)
@@ -241,10 +241,6 @@
 _C_LABEL(cpu):		.long	0	# are we 386, 386sx, or 486,
 					#   or Pentium, or..
 _C_LABEL(cpu_id):	.long	0	# saved from `cpuid' instruction
-_C_LABEL(cpu_feature):	.long	0	# feature flags from 'cpuid'
-					#   instruction
-_C_LABEL(cpu_feature2):	.long	0	# feature flags from 'cpuid'
-					#   instruction
 _C_LABEL(cpuid_level):	.long	-1	# max. level accepted by 'cpuid'
 					#   instruction
 _C_LABEL(cpu_vendorname):	.space	16	# vendor string returned by `cpuid'
@@ -295,7 +291,7 @@
 gdt64_end:
 
 farjmp64:
-	.long	longmode-KERNBASE
+	.long	_RELOC(longmode)
 	.word	GSEL(GCODE_SEL, SEL_KPL)
 	
 #endif	/* !XEN */
@@ -418,18 +414,11 @@
 	movl	$1,%eax
 	cpuid
 	movl	%eax,RELOC(cpu_id)
-	movl	%edx,RELOC(cpu_feature)
-	movl	%ecx,RELOC(cpu_feature2)
 
 	/* Brand ID is bits 0-7 of %ebx */
 	andl	$255,%ebx
 	movl	%ebx,RELOC(cpu_brand_id)
 
-	/* add AMD specific feature flags */
-	movl	$0x80000001,%eax
-	cpuid
-	orl	%edx,RELOC(cpu_feature)
-
 	/*
 	 * Finished with old stack; load new %esp now instead of later so we
 	 * can trace this code without having to worry about the trace trap

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.143 src/sys/arch/amd64/amd64/machdep.c:1.144
--- src/sys/arch/amd64/amd64/machdep.c:1.143	Mon Mar  1 01:35:11 2010
+++ src/sys/arch/amd64/amd64/machdep.c	Sun Apr 18 23:47:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.143 2010/03/01 01:35:11 jym Exp $	*/
+/*	$NetBSD: machdep.c,v 1.144 2010/04/18 23:47:50 jym Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008
@@ -107,7 +107,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.143 2010/03/01 01:35:11 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.144 2010/04/18 23:47:50 jym Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -1241,21 +1241,24 @@
 #if !defined(REALEXTMEM) && !defined(REALBASEMEM)
 	struct btinfo_memmap *bim;
 #endif
+#endif /* !XEN */
+
 	cpu_probe(&cpu_info_primary);
-#else /* XEN */
-	cpu_probe(&cpu_info_primary);
+
+#ifdef XEN
 	KASSERT(HYPERVISOR_shared_info != NULL);
 	cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
 
 	__PRINTK(("init_x86_64(0x%lx)\n", first_avail));
-	cpu_feature = cpu_info_primary.ci_feature_flags;
-	/* not on Xen... */
-	cpu_feature &= ~(CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR|CPUID_NOX);
 #endif /* XEN */
 
+	cpu_feature[0] &= ~CPUID_FEAT_BLACKLIST;
+	cpu_feature[2] &= ~CPUID_EXT_FEAT_BLACKLIST;
+
 	cpu_init_msrs(&cpu_info_primary, true);
 
 	pcb = lwp_getpcb(&lwp0);
+
 #ifdef XEN
 	pcb->pcb_cr3 = xen_start_info.pt_base - KERNBASE;
 	__PRINTK(("pcb_cr3 0x%lx\n", xen_start_info.pt_base - KERNBASE));
@@ -1348,6 +1351,7 @@
 	pmap_kenter_pa(idt_vaddr, idt_paddr, VM_PROT_READ|VM_PROT_WRITE, 0);
 	pmap_update(pmap_kernel());
 	memset((void *)idt_vaddr, 0, PAGE_SIZE);
+
 #ifndef XEN
 	pmap_changeprot_local(idt_vaddr, VM_PROT_READ);
 #endif

Index: src/sys/arch/amd64/amd64/mptramp.S
diff -u src/sys/arch/amd64/amd64/mptramp.S:1.10 src/sys/arch/amd64/amd64/mptramp.S:1.11
--- src/sys/arch/amd64/amd64/mptramp.S:1.10	Fri Nov 27 03:23:04 2009
+++ src/sys/arch/amd64/amd64/mptramp.S	Sun Apr 18 23:47:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: mptramp.S,v 1.10 2009/11/27 03:23:04 rmind Exp $	*/
+/*	$NetBSD: mptramp.S,v 1.11 2010/04/18 23:47:50 jym Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -223,15 +223,7 @@
 	testq	%rdi, %rdi
 	jz	1b
 
-	movl	_C_LABEL(cpu_feature),%eax
-	andl	$CPUID_NOX,%eax
-	jz	1f
-	movl	$MSR_EFER,%ecx
-	rdmsr
-	orl	$EFER_NXE,%eax
-	wrmsr
 1:
-
 	movq	CPU_INFO_IDLELWP(%rdi),%rsi
 	movq	L_PCB(%rsi),%rsi
 	

Index: src/sys/arch/amd64/amd64/procfs_machdep.c
diff -u src/sys/arch/amd64/amd64/procfs_machdep.c:1.14 src/sys/arch/amd64/amd64/procfs_machdep.c:1.15
--- src/sys/arch/amd64/amd64/procfs_machdep.c:1.14	Mon Jan 18 22:31:14 2010
+++ src/sys/arch/amd64/amd64/procfs_machdep.c	Sun Apr 18 23:47:50 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_machdep.c,v 1.14 2010/01/18 22:31:14 rmind Exp $ */
+/*	$NetBSD: procfs_machdep.c,v 1.15 2010/04/18 23:47:50 jym Exp $ */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.14 2010/01/18 22:31:14 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.15 2010/04/18 23:47:50 jym Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -151,7 +151,7 @@
 	p = featurebuf;
 	left = sizeof(featurebuf);
 	for (i = 0; i < 32; i++) {
-		if ((ci->ci_feature_flags & (1 << i)) && x86_features[i]) {
+		if ((ci->ci_feat_val[0] & (1 << i)) && x86_features[i]) {
 			l = snprintf(p, left, "%s ", x86_features[i]);
 			left -= l;
 			p += l;

Index: src/sys/arch/i386/i386/genassym.cf
diff -u src/sys/arch/i386/i386/genassym.cf:1.85 src/sys/arch/i386/i386/genassym.cf:1.86
--- src/sys/arch/i386/i386/genassym.cf:1.85	Mon Feb 22 23:52:17 2010
+++ src/sys/arch/i386/i386/genassym.cf	Sun Apr 18 23:47:50 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.85 2010/02/22 23:52:17 jym Exp $
+#	$NetBSD: genassym.cf,v 1.86 2010/04/18 23:47:50 jym Exp $
 
 #
 # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -313,7 +313,6 @@
 
 define	CPU_INFO_VENDOR		offsetof(struct cpu_info, ci_vendor[0])
 define	CPU_INFO_SIGNATURE	offsetof(struct cpu_info, ci_signature)
-define	CPU_INFO_FEATURES	offsetof(struct cpu_info, ci_feature_flags)
 
 define	CPU_TLOG_OFFSET		offsetof(struct cpu_info, ci_tlog_offset)
 define	CPU_TLOG_BASE		offsetof(struct cpu_info, ci_tlog_base)

Index: src/sys/arch/i386/i386/machdep.c
diff -u src/sys/arch/i386/i386/machdep.c:1.684 src/sys/arch/i386/i386/machdep.c:1.685
--- src/sys/arch/i386/i386/machdep.c:1.684	Mon Mar  1 01:35:11 2010
+++ src/sys/arch/i386/i386/machdep.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.684 2010/03/01 01:35:11 jym Exp $	*/
+/*	$NetBSD: machdep.c,v 1.685 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.684 2010/03/01 01:35:11 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.685 2010/04/18 23:47:51 jym Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -244,10 +244,6 @@
 
 int	physmem;
 
-unsigned int cpu_feature;
-unsigned int cpu_feature2;
-unsigned int cpu_feature_padlock;
-
 int	cpu_class;
 int	i386_fpu_present;
 int	i386_fpu_exception;
@@ -1298,16 +1294,16 @@
 	cpu_info_primary.ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[0];
 #endif
 	cpu_probe(&cpu_info_primary);
-	cpu_feature = cpu_info_primary.ci_feature_flags;
-	cpu_feature2 = cpu_info_primary.ci_feature2_flags;
-	cpu_feature_padlock = cpu_info_primary.ci_padlock_flags;
 
 	uvm_lwp_setuarea(&lwp0, lwp0uarea);
 	pcb = lwp_getpcb(&lwp0);
 
+	cpu_feature[0] &= ~CPUID_FEAT_BLACKLIST;
+	cpu_feature[2] &= ~CPUID_EXT_FEAT_BLACKLIST;
+
+	cpu_init_msrs(&cpu_info_primary, true);
+
 #ifdef XEN
-	/* not on Xen... */
-	cpu_feature &= ~(CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR|CPUID_NOX);
 	pcb->pcb_cr3 = PDPpaddr - KERNBASE;
 	__PRINTK(("pcb_cr3 0x%lx cr3 0x%lx\n",
 	    PDPpaddr - KERNBASE, xpmap_ptom(PDPpaddr - KERNBASE)));

Index: src/sys/arch/i386/i386/procfs_machdep.c
diff -u src/sys/arch/i386/i386/procfs_machdep.c:1.33 src/sys/arch/i386/i386/procfs_machdep.c:1.34
--- src/sys/arch/i386/i386/procfs_machdep.c:1.33	Mon Jan 18 22:31:14 2010
+++ src/sys/arch/i386/i386/procfs_machdep.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_machdep.c,v 1.33 2010/01/18 22:31:14 rmind Exp $	*/
+/*	$NetBSD: procfs_machdep.c,v 1.34 2010/04/18 23:47:51 jym Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.33 2010/01/18 22:31:14 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.34 2010/04/18 23:47:51 jym Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -114,7 +114,7 @@
 	p = featurebuf;
 	left = sizeof(featurebuf);
 	for (i = 0; i < 32; i++) {
-		if ((ci->ci_feature_flags & (1 << i)) && x86_features[i]) {
+		if ((ci->ci_feat_val[0] & (1 << i)) && x86_features[i]) {
 			l = snprintf(p, left, "%s ", x86_features[i]);
 			left -= l;
 			p += l;

Index: src/sys/arch/i386/isa/npx.c
diff -u src/sys/arch/i386/isa/npx.c:1.135 src/sys/arch/i386/isa/npx.c:1.136
--- src/sys/arch/i386/isa/npx.c:1.135	Sat Nov 21 03:11:01 2009
+++ src/sys/arch/i386/isa/npx.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: npx.c,v 1.135 2009/11/21 03:11:01 rmind Exp $	*/
+/*	$NetBSD: npx.c,v 1.136 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.135 2009/11/21 03:11:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.136 2010/04/18 23:47:51 jym Exp $");
 
 #if 0
 #define IPRINTF(x)	printf x
@@ -123,6 +123,7 @@
 #include <uvm/uvm_extern.h>
 
 #include <machine/cpufunc.h>
+#include <machine/cpuvar.h>
 #include <machine/pcb.h>
 #include <machine/trap.h>
 #include <machine/specialreg.h>
@@ -215,7 +216,7 @@
 	int status;
 	unsigned irqmask;
 
-	if (cpu_feature & CPUID_FPU) {
+	if (cpu_feature[0] & CPUID_FPU) {
 		i386_fpu_exception = 1;
 		return NPX_CPUID;
 	}

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.20 src/sys/arch/x86/include/cpu.h:1.21
--- src/sys/arch/x86/include/cpu.h:1.20	Mon Jan 18 16:40:17 2010
+++ src/sys/arch/x86/include/cpu.h	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.20 2010/01/18 16:40:17 rmind Exp $	*/
+/*	$NetBSD: cpu.h,v 1.21 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -141,15 +141,18 @@
 	uint32_t sc_apic_version;	/* local APIC version */
 
 	uint32_t	ci_signature;	 /* X86 cpuid type */
-	uint32_t	ci_feature_flags;/* X86 %edx CPUID feature bits */
-	uint32_t	ci_feature2_flags;/* X86 %ecx CPUID feature bits */
-	uint32_t	ci_feature3_flags;/* X86 extended %edx feature bits */
-	uint32_t	ci_feature4_flags;/* X86 extended %ecx feature bits */
-	uint32_t	ci_padlock_flags;/* VIA PadLock feature bits */
 	uint32_t	ci_vendor[4];	 /* vendor string */
 	uint32_t	ci_cpu_serial[3]; /* PIII serial number */
 	volatile uint32_t	ci_lapic_counter;
 
+	uint32_t	ci_feat_val[5]; /* X86 CPUID feature bits
+					 *	[0] basic features %edx
+					 *	[1] basic features %ecx
+					 *	[2] extended features %edx
+					 *	[3] extended features %ecx
+					 *	[4] VIA padlock features
+					 */
+	
 	const struct cpu_functions *ci_func;  /* start/stop functions */
 	struct trapframe *ci_ddb_regs;
 
@@ -321,9 +324,6 @@
 
 extern int biosbasemem;
 extern int biosextmem;
-extern unsigned int cpu_feature;
-extern unsigned int cpu_feature2;
-extern unsigned int cpu_feature_padlock;
 extern int cpu;
 extern int cpuid_level;
 extern int cpu_class;

Index: src/sys/arch/x86/include/cpuvar.h
diff -u src/sys/arch/x86/include/cpuvar.h:1.31 src/sys/arch/x86/include/cpuvar.h:1.32
--- src/sys/arch/x86/include/cpuvar.h:1.31	Fri Oct  2 18:50:03 2009
+++ src/sys/arch/x86/include/cpuvar.h	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/* 	$NetBSD: cpuvar.h,v 1.31 2009/10/02 18:50:03 jmcneill Exp $ */
+/* 	$NetBSD: cpuvar.h,v 1.32 2010/04/18 23:47:51 jym Exp $ */
 
 /*-
  * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
@@ -144,6 +144,8 @@
 extern int cpu_vendor;
 extern bool x86_mp_online;
 
+extern uint32_t cpu_feature[5];
+
 #endif
 
 #endif /* !_X86_CPUVAR_H_ */

Index: src/sys/arch/x86/include/mpbiosreg.h
diff -u src/sys/arch/x86/include/mpbiosreg.h:1.5 src/sys/arch/x86/include/mpbiosreg.h:1.6
--- src/sys/arch/x86/include/mpbiosreg.h:1.5	Mon Apr 28 20:23:40 2008
+++ src/sys/arch/x86/include/mpbiosreg.h	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/* 	$NetBSD: mpbiosreg.h,v 1.5 2008/04/28 20:23:40 martin Exp $ */
+/* 	$NetBSD: mpbiosreg.h,v 1.6 2010/04/18 23:47:51 jym Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -94,8 +94,6 @@
 	uint8_t  cpu_flags;
 #define PROCENTRY_FLAG_EN	0x01
 #define PROCENTRY_FLAG_BP	0x02
-	uint32_t  cpu_signature;
-	uint32_t  feature_flags;
 	uint32_t  reserved1;
 	uint32_t  reserved2;
 };

Index: src/sys/arch/x86/include/specialreg.h
diff -u src/sys/arch/x86/include/specialreg.h:1.39 src/sys/arch/x86/include/specialreg.h:1.40
--- src/sys/arch/x86/include/specialreg.h:1.39	Sat Apr  3 23:17:05 2010
+++ src/sys/arch/x86/include/specialreg.h	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: specialreg.h,v 1.39 2010/04/03 23:17:05 jym Exp $	*/
+/*	$NetBSD: specialreg.h,v 1.40 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 1991 The Regents of the University of California.
@@ -84,10 +84,10 @@
 #define CR4_OSXMMEXCPT	0x00000400	/* enable unmasked SSE exceptions */
 
 /*
- * CPUID "features" bits in %edx
+ * CPUID "features" bits
  */
 
-/* Fn00000001 %edx feature */
+/* Fn00000001 %edx features */
 #define	CPUID_FPU	0x00000001	/* processor has an FPU? */
 #define	CPUID_VME	0x00000002	/* has virtual mode (%cr4's VME/PVI) */
 #define	CPUID_DE	0x00000004	/* has debugging extension */
@@ -129,7 +129,7 @@
 
 /* Intel Fn80000001 extended features - %edx */
 #define CPUID_SYSCALL	0x00000800	/* SYSCALL/SYSRET */
-#define CPUID_XD	0x00100000	/* Execute Disable */
+#define CPUID_XD	0x00100000	/* Execute Disable (like CPUID_NOX) */
 #define CPUID_EM64T	0x20000000	/* Intel EM64T */
 
 #define CPUID_INTEL_EXT_FLAGS	"\20\14SYSCALL/SYSRET\25XD\36EM64T"
@@ -258,6 +258,16 @@
 #define CPUID2EXTFAMILY(cpuid)	(((cpuid) >> 20) & 0xff)
 #define CPUID2EXTMODEL(cpuid)	(((cpuid) >> 16) & 0xf)
 
+/* Blacklists of CPUID flags - used to mask certain features */
+#ifdef XEN
+/* Not on Xen */
+#define CPUID_FEAT_BLACKLIST	 (CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR)
+#define CPUID_EXT_FEAT_BLACKLIST (CPUID_NOX)
+#else
+#define CPUID_FEAT_BLACKLIST	 0
+#define CPUID_EXT_FEAT_BLACKLIST 0
+#endif /* XEN */
+
 /*
  * Model-specific registers for the i386 family
  */

Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.69 src/sys/arch/x86/x86/cpu.c:1.70
--- src/sys/arch/x86/x86/cpu.c:1.69	Wed Feb 24 22:37:55 2010
+++ src/sys/arch/x86/x86/cpu.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.69 2010/02/24 22:37:55 dyoung Exp $	*/
+/*	$NetBSD: cpu.c,v 1.70 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.69 2010/02/24 22:37:55 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.70 2010/04/18 23:47:51 jym Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"		/* for MPDEBUG */
@@ -170,6 +170,14 @@
 uint32_t cpus_attached = 0;
 uint32_t cpus_running = 0;
 
+uint32_t cpu_feature[5]; /* X86 CPUID feature bits
+			  *	[0] basic features %edx
+			  *	[1] basic features %ecx
+			  *	[2] extended features %edx
+			  *	[3] extended features %ecx
+			  *	[4] VIA padlock features
+			  */
+
 extern char x86_64_doubleflt_stack[];
 
 bool x86_mp_online;
@@ -451,19 +459,19 @@
 	 * On a P6 or above, enable global TLB caching if the
 	 * hardware supports it.
 	 */
-	if (cpu_feature & CPUID_PGE)
+	if (cpu_feature[0] & CPUID_PGE)
 		lcr4(rcr4() | CR4_PGE);	/* enable global TLB caching */
 
 	/*
 	 * If we have FXSAVE/FXRESTOR, use them.
 	 */
-	if (cpu_feature & CPUID_FXSR) {
+	if (cpu_feature[0] & CPUID_FXSR) {
 		lcr4(rcr4() | CR4_OSFXSR);
 
 		/*
 		 * If we have SSE/SSE2, enable XMM exceptions.
 		 */
-		if (cpu_feature & (CPUID_SSE|CPUID_SSE2))
+		if (cpu_feature[0] & (CPUID_SSE|CPUID_SSE2))
 			lcr4(rcr4() | CR4_OSXMMEXCPT);
 	}
 
@@ -471,7 +479,7 @@
 	/*
 	 * On a P6 or above, initialize MTRR's if the hardware supports them.
 	 */
-	if (cpu_feature & CPUID_MTRR) {
+	if (cpu_feature[0] & CPUID_MTRR) {
 		if ((ci->ci_flags & CPUF_AP) == 0)
 			i686_mtrr_init_first();
 		mtrr_init_cpu(ci);
@@ -535,7 +543,7 @@
 	tsc_tc_init();
 
 	/* Enable zeroing of pages in the idle loop if we have SSE2. */
-	vm_page_zero_enable = ((cpu_feature & CPUID_SSE2) != 0);
+	vm_page_zero_enable = ((cpu_feature[0] & CPUID_SSE2) != 0);
 }
 
 static void
@@ -666,9 +674,7 @@
 	struct pcb *pcb;
 	int s, i;
 
-#ifdef __x86_64__
 	cpu_init_msrs(ci, true);
-#endif
 	cpu_probe(ci);
 
 	ci->ci_data.cpu_cc_freq = cpu_info_primary.ci_data.cpu_cc_freq;
@@ -692,7 +698,7 @@
 	 * We'd like to use 'hlt', but we have interrupts off.
 	 */
 	while ((ci->ci_flags & CPUF_GO) == 0) {
-		if ((ci->ci_feature2_flags & CPUID2_MONITOR) != 0) {
+		if ((cpu_feature[1] & CPUID2_MONITOR) != 0) {
 			x86_monitor(&ci->ci_flags, 0, 0);
 			if ((ci->ci_flags & CPUF_GO) != 0) {
 				continue;
@@ -901,7 +907,7 @@
 
 	memcpy((uint8_t *)cmos_data_mapping + 0x467, dwordptr, 4);
 
-	if ((cpu_feature & CPUID_APIC) == 0) {
+	if ((cpu_feature[0] & CPUID_APIC) == 0) {
 		aprint_error("mp_cpu_start: CPU does not have APIC\n");
 		return ENODEV;
 	}
@@ -956,10 +962,12 @@
 #ifdef __x86_64__
 typedef void (vector)(void);
 extern vector Xsyscall, Xsyscall32;
+#endif
 
 void
 cpu_init_msrs(struct cpu_info *ci, bool full)
 {
+#ifdef __x86_64__
 	wrmsr(MSR_STAR,
 	    ((uint64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
 	    ((uint64_t)LSEL(LSYSRETBASE_SEL, SEL_UPL) << 48));
@@ -972,11 +980,11 @@
 		wrmsr(MSR_GSBASE, (uint64_t)ci);
 		wrmsr(MSR_KERNELGSBASE, 0);
 	}
+#endif	/* __x86_64__ */
 
-	if (cpu_feature & CPUID_NOX)
+	if (cpu_feature[2] & CPUID_NOX)
 		wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE);
 }
-#endif	/* __x86_64__ */
 
 void
 cpu_offline_md(void)
@@ -1051,7 +1059,7 @@
 {
 	uint64_t last_tsc;
 
-	if (ci->ci_feature_flags & CPUID_TSC) {
+	if (cpu_hascounter()) {
 		last_tsc = rdmsr(MSR_TSC);
 		i8254_delay(100000);
 		ci->ci_data.cpu_cc_freq = (rdmsr(MSR_TSC) - last_tsc) * 10;

Index: src/sys/arch/x86/x86/cpu_topology.c
diff -u src/sys/arch/x86/x86/cpu_topology.c:1.3 src/sys/arch/x86/x86/cpu_topology.c:1.4
--- src/sys/arch/x86/x86/cpu_topology.c:1.3	Mon Jan 18 16:40:17 2010
+++ src/sys/arch/x86/x86/cpu_topology.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_topology.c,v 1.3 2010/01/18 16:40:17 rmind Exp $	*/
+/*	$NetBSD: cpu_topology.c,v 1.4 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2009 Mindaugas Rasiukevicius <rmind at NetBSD org>,
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.3 2010/01/18 16:40:17 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.4 2010/04/18 23:47:51 jym Exp $");
 
 #include <sys/param.h>
 #include <sys/bitops.h>
@@ -82,11 +82,12 @@
 	lextmode = descs[0];
 	if (lextmode >= 0x80000001) {
 		x86_cpuid(0x80000001, descs);
-		ci->ci_feature3_flags |= descs[3]; /* edx */
+		ci->ci_feat_val[2] = descs[3]; /* edx */
+		ci->ci_feat_val[3] = descs[2]; /* ecx */
 	}
 
 	/* Check for HTT support.  See notes below regarding AMD. */
-	if ((ci->ci_feature_flags & CPUID_HTT) != 0) {
+	if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
 		/* Maximum number of LPs sharing a cache (ebx[23:16]). */
 		x86_cpuid(1, descs);
 		lp_max = (descs[1] >> 16) & 0xff;
@@ -108,7 +109,7 @@
 		break;
 	case CPUVENDOR_AMD:
 		/* In a case of AMD, HTT flag means CMP support. */
-		if ((ci->ci_feature_flags & CPUID_HTT) == 0) {
+		if ((ci->ci_feat_val[0] & CPUID_HTT) == 0) {
 			core_max = 1;
 			break;
 		}

Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.19 src/sys/arch/x86/x86/identcpu.c:1.20
--- src/sys/arch/x86/x86/identcpu.c:1.19	Sun Apr 18 15:25:53 2010
+++ src/sys/arch/x86/x86/identcpu.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: identcpu.c,v 1.19 2010/04/18 15:25:53 jym Exp $	*/
+/*	$NetBSD: identcpu.c,v 1.20 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.19 2010/04/18 15:25:53 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.20 2010/04/18 23:47:51 jym Exp $");
 
 #include "opt_enhanced_speedstep.h"
 #include "opt_intel_odcm.h"
@@ -266,10 +266,10 @@
 		 * support for global PTEs, instead using bit 9 (APIC)
 		 * rather than bit 13 (i.e. "0x200" vs. 0x2000".  Oops!).
 		 */
-		flag = ci->ci_feature_flags;
+		flag = ci->ci_feat_val[0];
 		if ((flag & CPUID_APIC) != 0)
 			flag = (flag & ~CPUID_APIC) | CPUID_PGE;
-		ci->ci_feature_flags = flag;
+		ci->ci_feat_val[0] = flag;
 	}
 
 	cpu_probe_amd_cache(ci);
@@ -288,8 +288,8 @@
 	x86_cpuid(0x80000000, descs);
 	if (descs[0] >= 0x80000001) {
 		x86_cpuid(0x80000001, descs);
-		ci->ci_feature3_flags |= descs[3]; /* %edx */
-		ci->ci_feature4_flags = descs[2];  /* %ecx */
+		ci->ci_feat_val[3] = descs[2]; /* %ecx */
+		ci->ci_feat_val[2] = descs[3]; /* %edx */
 	}
 
 	cpu_probe_amd_cache(ci);
@@ -358,7 +358,7 @@
 	 * work fine.
 	 */
 	if (ci->ci_signature != 0x552)
-		ci->ci_feature_flags &= ~CPUID_TSC;
+		ci->ci_feat_val[0] &= ~CPUID_TSC;
 
 	/* enable access to ccr4/ccr5 */
 	c3 = cyrix_read_reg(0xC3);
@@ -394,7 +394,7 @@
 
 	if (CPUID2MODEL(ci->ci_signature) == 4) {
 		/* WinChip C6 */
-		ci->ci_feature_flags &= ~CPUID_TSC;
+		ci->ci_feat_val[0] &= ~CPUID_TSC;
 	}
 }
 
@@ -419,7 +419,7 @@
 	/* Determine the extended feature flags. */
 	if (lfunc >= 0x80000001) {
 		x86_cpuid(0x80000001, descs);
-		ci->ci_feature_flags |= descs[3];
+		ci->ci_feat_val[2] = descs[3];
 	}
 
 	if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
@@ -430,40 +430,40 @@
 		    int rng_enable = 0, ace_enable = 0;
 		    x86_cpuid(0xc0000001, descs);
 		    lfunc = descs[3];
-		    ci->ci_padlock_flags = lfunc;
+		    ci->ci_feat_val[4] = lfunc;
 		    /* Check for and enable RNG */
 		    if (lfunc & CPUID_VIA_HAS_RNG) {
 		    	if (!(lfunc & CPUID_VIA_DO_RNG)) {
 			    rng_enable++;
-			    ci->ci_padlock_flags |= CPUID_VIA_HAS_RNG;
+			    ci->ci_feat_val[4] |= CPUID_VIA_HAS_RNG;
 			}
 		    }
 		    /* Check for and enable ACE (AES-CBC) */
 		    if (lfunc & CPUID_VIA_HAS_ACE) {
 			if (!(lfunc & CPUID_VIA_DO_ACE)) {
 			    ace_enable++;
-			    ci->ci_padlock_flags |= CPUID_VIA_DO_ACE;
+			    ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE;
 			}
 		    }
 		    /* Check for and enable SHA */
 		    if (lfunc & CPUID_VIA_HAS_PHE) {
 			if (!(lfunc & CPUID_VIA_DO_PHE)) {
 			    ace_enable++;
-			    ci->ci_padlock_flags |= CPUID_VIA_DO_PHE;
+			    ci->ci_feat_val[4] |= CPUID_VIA_DO_PHE;
 			}
 		    }
 		    /* Check for and enable ACE2 (AES-CTR) */
 		    if (lfunc & CPUID_VIA_HAS_ACE2) {
 			if (!(lfunc & CPUID_VIA_DO_ACE2)) {
 			    ace_enable++;
-			    ci->ci_padlock_flags |= CPUID_VIA_DO_ACE2;
+			    ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE2;
 			}
 		    }
 		    /* Check for and enable PMM (modmult engine) */
 		    if (lfunc & CPUID_VIA_HAS_PMM) {
 			if (!(lfunc & CPUID_VIA_DO_PMM)) {
 			    ace_enable++;
-			    ci->ci_padlock_flags |= CPUID_VIA_DO_PMM;
+			    ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM;
 			}
 		    }
 
@@ -568,6 +568,10 @@
 	if (cpuid_level < 0)
 		return;
 
+	for (i = 0; i < __arraycount(ci->ci_feat_val); i++) {
+		ci->ci_feat_val[i] = 0;
+	}
+
 	x86_cpuid(0, descs);
 	cpuid_level = descs[0];
 	ci->ci_vendor[0] = descs[1];
@@ -606,8 +610,8 @@
 		x86_cpuid(1, descs);
 		ci->ci_signature = descs[0];
 		miscbytes = descs[1];
-		ci->ci_feature2_flags = descs[2];
-		ci->ci_feature_flags = descs[3];
+		ci->ci_feat_val[1] = descs[2];
+		ci->ci_feat_val[0] = descs[3];
 
 		/* Determine family + class. */
 		cpu_class = CPUID2FAMILY(ci->ci_signature) + (CPUCLASS_386 - 3);
@@ -615,7 +619,7 @@
 			cpu_class = CPUCLASS_686;
 
 		/* CLFLUSH line size is next 8 bits */
-		if (ci->ci_feature_flags & CPUID_CFLUSH)
+		if (ci->ci_feat_val[0] & CPUID_CFLUSH)
 			ci->ci_cflush_lsize = ((miscbytes >> 8) & 0xff) << 3;
 		ci->ci_initapicid = (miscbytes >> 24) & 0xff;
 	}
@@ -654,24 +658,33 @@
 
 	x86_cpu_topology(ci);
 
-	if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feature_flags & CPUID_TM) &&
+	if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) &&
 	    (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) {
 		/* Enable thermal monitor 1. */
 		wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) | (1<<3));
 	}
 
 	if (ci == &cpu_info_primary) {
-		/* If first. */
-		cpu_feature = ci->ci_feature_flags;
-		cpu_feature2 = ci->ci_feature2_flags;
-		/* Early patch of text segment. */
+		/* If first. Boot Processor is the cpu_feature reference. */
+		for (i = 0; i < __arraycount(cpu_feature); i++) {
+			cpu_feature[i] = ci->ci_feat_val[i];
+		}
 #ifndef XEN
+		/* Early patch of text segment. */
 		x86_patch(true);
 #endif
 	} else {
-		/* If not first. */
-		cpu_feature &= ci->ci_feature_flags;
-		cpu_feature2 &= ci->ci_feature2_flags;
+		/*
+		 * If not first. Warn about cpu_feature mismatch for
+		 * secondary CPUs.
+		 */
+		for (i = 0; i < __arraycount(cpu_feature); i++) {
+			if (cpu_feature[i] != ci->ci_feat_val[i])
+				aprint_error_dev(ci->ci_dev,
+				    "feature mismatch: cpu_feature[%d] is "
+				    "%#x, but CPU reported %#x\n",
+				    i, cpu_feature[i], ci->ci_feat_val[i]);
+		}
 	}
 }
 
@@ -700,7 +713,7 @@
 
 	if ((cpu_vendor == CPUVENDOR_AMD) /* check enablement of an */
 	  && (device_unit(ci->ci_dev) == 0) /* AMD feature only once */
-	  && ((ci->ci_feature4_flags & CPUID_SVM) == CPUID_SVM)
+	  && ((cpu_feature[3] & CPUID_SVM) == CPUID_SVM)
 #if defined(XEN) && !defined(DOM0OPS)
 	  && (false)  /* on Xen rdmsr is for Dom0 only */
 #endif
@@ -726,22 +739,22 @@
 	}
 
 	/* If we have FXSAVE/FXRESTOR, use them. */
-	if (cpu_feature & CPUID_FXSR) {
+	if (cpu_feature[0] & CPUID_FXSR) {
 		i386_use_fxsave = 1;
 		/*
 		 * If we have SSE/SSE2, enable XMM exceptions, and
 		 * notify userland.
 		 */
-		if (cpu_feature & CPUID_SSE)
+		if (cpu_feature[0] & CPUID_SSE)
 			i386_has_sse = 1;
-		if (cpu_feature & CPUID_SSE2)
+		if (cpu_feature[0] & CPUID_SSE2)
 			i386_has_sse2 = 1;
 	} else
 		i386_use_fxsave = 0;
 #endif	/* i386 */
 
 #ifdef ENHANCED_SPEEDSTEP
-	if (cpu_feature2 & CPUID2_EST) {
+	if (cpu_feature[1] & CPUID2_EST) {
 		if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
 			est_init(cpu_vendor);
 	}

Index: src/sys/arch/x86/x86/mpbios.c
diff -u src/sys/arch/x86/x86/mpbios.c:1.56 src/sys/arch/x86/x86/mpbios.c:1.57
--- src/sys/arch/x86/x86/mpbios.c:1.56	Sat Nov  7 07:27:49 2009
+++ src/sys/arch/x86/x86/mpbios.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: mpbios.c,v 1.56 2009/11/07 07:27:49 cegger Exp $	*/
+/*	$NetBSD: mpbios.c,v 1.57 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpbios.c,v 1.56 2009/11/07 07:27:49 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpbios.c,v 1.57 2010/04/18 23:47:51 jym Exp $");
 
 #include "acpica.h"
 #include "lapic.h"
@@ -732,8 +732,6 @@
 	/* use default addresses */
 	pe.apic_id = lapic_cpu_number();
 	pe.cpu_flags = PROCENTRY_FLAG_EN|PROCENTRY_FLAG_BP;
-	pe.cpu_signature = cpu_info_primary.ci_signature;
-	pe.feature_flags = cpu_info_primary.ci_feature_flags;
 
 	mpbios_cpu((uint8_t *)&pe, self);
 

Index: src/sys/arch/x86/x86/patch.c
diff -u src/sys/arch/x86/x86/patch.c:1.20 src/sys/arch/x86/x86/patch.c:1.21
--- src/sys/arch/x86/x86/patch.c:1.20	Tue Nov  3 20:11:53 2009
+++ src/sys/arch/x86/x86/patch.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: patch.c,v 1.20 2009/11/03 20:11:53 dyoung Exp $	*/
+/*	$NetBSD: patch.c,v 1.21 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.20 2009/11/03 20:11:53 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: patch.c,v 1.21 2010/04/18 23:47:51 jym Exp $");
 
 #include "opt_lockdebug.h"
 #ifdef i386
@@ -174,7 +174,7 @@
 			patchbytes(atomic_lockpatch[i], X86_NOP, -1, -1);
 #endif	/* !LOCKDEBUG */
 	}
-	if (!early && (cpu_feature & CPUID_SSE2) != 0) {
+	if (!early && (cpu_feature[0] & CPUID_SSE2) != 0) {
 		/* Faster memory barriers. */
 		patchfunc(
 		    sse2_lfence, sse2_lfence_end,
@@ -194,7 +194,7 @@
 	 * Patch early and late.  Second time around the 'lock' prefix
 	 * may be gone.
 	 */
-	if ((cpu_feature & CPUID_CX8) != 0) {
+	if ((cpu_feature[0] & CPUID_CX8) != 0) {
 		patchfunc(
 		    _atomic_cas_cx8, _atomic_cas_cx8_end,
 		    _atomic_cas_64, _atomic_cas_64_end,
@@ -204,7 +204,7 @@
 #endif	/* i386 */
 
 #if !defined(SPLDEBUG)
-	if (!early && (cpu_feature & CPUID_CX8) != 0) {
+	if (!early && (cpu_feature[0] & CPUID_CX8) != 0) {
 		/* Faster splx(), mutex_spin_exit(). */
 		patchfunc(
 		    cx8_spllower, cx8_spllower_end,

Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.106 src/sys/arch/x86/x86/pmap.c:1.107
--- src/sys/arch/x86/x86/pmap.c:1.106	Wed Mar 31 19:07:32 2010
+++ src/sys/arch/x86/x86/pmap.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.106 2010/03/31 19:07:32 ad Exp $	*/
+/*	$NetBSD: pmap.c,v 1.107 2010/04/18 23:47:51 jym Exp $	*/
 
 /*
  * Copyright (c) 2007 Manuel Bouyer.
@@ -149,7 +149,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.106 2010/03/31 19:07:32 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.107 2010/04/18 23:47:51 jym Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -1147,7 +1147,7 @@
 		npte |= PG_N;
 
 #ifndef XEN
-	if ((cpu_feature & CPUID_NOX) && !(prot & VM_PROT_EXECUTE))
+	if ((cpu_feature[2] & CPUID_NOX) && !(prot & VM_PROT_EXECUTE))
 		npte |= PG_NX;
 #endif
 	opte = pmap_pte_testset (pte, npte); /* zap! */
@@ -1273,7 +1273,7 @@
 #else
 	unsigned long p1i;
 	vaddr_t kva_end;
-	pt_entry_t pg_nx = (cpu_feature & CPUID_NOX ? PG_NX : 0);
+	pt_entry_t pg_nx = (cpu_feature[2] & CPUID_NOX ? PG_NX : 0);
 #endif
 
 	/*
@@ -1341,7 +1341,7 @@
 	 * (and happens later)
 	 */
 
-	if (cpu_feature & CPUID_PGE) {
+	if (cpu_feature[0] & CPUID_PGE) {
 		pmap_pg_g = PG_G;		/* enable software */
 
 		/* add PG_G attribute to already mapped kernel pages */
@@ -1367,7 +1367,7 @@
 	 * enable large pages if they are supported.
 	 */
 
-	if (cpu_feature & CPUID_PSE) {
+	if (cpu_feature[0] & CPUID_PSE) {
 		paddr_t pa;
 		pd_entry_t *pde;
 		extern char __data_start;
@@ -3115,7 +3115,7 @@
 	zpte = PTESLEW(zero_pte, id);
 	zerova = VASLEW(zerop, id);
 
-	KASSERT(cpu_feature & CPUID_SSE2);
+	KASSERT(cpu_feature[0] & CPUID_SSE2);
 	KASSERT(*zpte == 0);
 
 	pmap_pte_set(zpte, pmap_pa2pte(pa) | PG_V | PG_RW | PG_M | PG_U | PG_k);
@@ -4558,7 +4558,7 @@
 		 * If the CPUs have no notion of global pages then
 		 * reload of %cr3 is sufficient.
 		 */
-		if (pte != 0 && (cpu_feature & CPUID_PGE) == 0)
+		if (pte != 0 && (cpu_feature[0] & CPUID_PGE) == 0)
 			pte = 0;
 
 		if (pm == pmap_kernel()) {

Index: src/sys/arch/x86/x86/tsc.c
diff -u src/sys/arch/x86/x86/tsc.c:1.25 src/sys/arch/x86/x86/tsc.c:1.26
--- src/sys/arch/x86/x86/tsc.c:1.25	Fri Mar 27 19:53:20 2009
+++ src/sys/arch/x86/x86/tsc.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: tsc.c,v 1.25 2009/03/27 19:53:20 drochner Exp $	*/
+/*	$NetBSD: tsc.c,v 1.26 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.25 2009/03/27 19:53:20 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.26 2010/04/18 23:47:51 jym Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -69,7 +69,7 @@
 	uint32_t descs[4];
 	bool safe;
 
-	if ((cpu_feature & CPUID_TSC) == 0) {
+	if (!cpu_hascounter()) {
 		return;
 	}
 
@@ -255,5 +255,5 @@
 cpu_hascounter(void)
 {
 
-	return cpu_feature & CPUID_TSC;
+	return cpu_feature[0] & CPUID_TSC;
 }

Index: src/sys/arch/x86/x86/via_padlock.c
diff -u src/sys/arch/x86/x86/via_padlock.c:1.11 src/sys/arch/x86/x86/via_padlock.c:1.12
--- src/sys/arch/x86/x86/via_padlock.c:1.11	Wed Apr  1 03:56:54 2009
+++ src/sys/arch/x86/x86/via_padlock.c	Sun Apr 18 23:47:51 2010
@@ -1,5 +1,5 @@
 /*	$OpenBSD: via.c,v 1.8 2006/11/17 07:47:56 tom Exp $	*/
-/*	$NetBSD: via_padlock.c,v 1.11 2009/04/01 03:56:54 tls Exp $ */
+/*	$NetBSD: via_padlock.c,v 1.12 2010/04/18 23:47:51 jym Exp $ */
 
 /*-
  * Copyright (c) 2003 Jason Wright
@@ -20,7 +20,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.11 2009/04/01 03:56:54 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.12 2010/04/18 23:47:51 jym Exp $");
 
 #include "rnd.h"
 
@@ -180,10 +180,10 @@
 
 	printf("%s", xxx_via_buffer);
 
-	if (!((cpu_feature_padlock & CPUID_VIA_HAS_ACE) ||
-	      (cpu_feature_padlock & CPUID_VIA_HAS_RNG))) {
+	if (!((cpu_feature[4] & CPUID_VIA_HAS_ACE) ||
+	      (cpu_feature[4] & CPUID_VIA_HAS_RNG))) {
 		printf("PadLock: Nothing (%08x ! %08X ! %08X)\n",
-			cpu_feature_padlock, CPUID_VIA_HAS_ACE,
+			cpu_feature[4], CPUID_VIA_HAS_ACE,
 			CPUID_VIA_HAS_RNG);
 		return;		/* Nothing to see here, move along. */
 	}
@@ -192,12 +192,12 @@
 		return;
 	memset(vp_sc, 0, sizeof(*vp_sc));
 
-	if (cpu_feature_padlock & CPUID_VIA_HAS_RNG) {
+	if (cpu_feature[4] & CPUID_VIA_HAS_RNG) {
 		via_c3_rnd_init(vp_sc);
 		printf("PadLock: RNG attached\n");
 	}
 
-	if (cpu_feature_padlock & CPUID_VIA_HAS_ACE) {
+	if (cpu_feature[4] & CPUID_VIA_HAS_ACE) {
 		via_c3_ace_init(vp_sc);
 		printf("PadLock: AES-CBC attached\n");
 	}

Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.39 src/sys/arch/x86/x86/x86_machdep.c:1.40
--- src/sys/arch/x86/x86/x86_machdep.c:1.39	Tue Feb  9 23:52:13 2010
+++ src/sys/arch/x86/x86/x86_machdep.c	Sun Apr 18 23:47:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_machdep.c,v 1.39 2010/02/09 23:52:13 jym Exp $	*/
+/*	$NetBSD: x86_machdep.c,v 1.40 2010/04/18 23:47:51 jym Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.39 2010/02/09 23:52:13 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.40 2010/04/18 23:47:51 jym Exp $");
 
 #include "opt_modular.h"
 
@@ -335,7 +335,7 @@
 x86_cpu_idle_init(void)
 {
 #ifndef XEN
-	if ((curcpu()->ci_feature2_flags & CPUID2_MONITOR) == 0 ||
+	if ((cpu_feature[1] & CPUID2_MONITOR) == 0 ||
 	    cpu_vendor == CPUVENDOR_AMD) {
 		strlcpy(x86_cpu_idle_text, "halt", sizeof(x86_cpu_idle_text));
 		x86_cpu_idle = x86_cpu_idle_halt;

Index: src/sys/arch/xen/x86/cpu.c
diff -u src/sys/arch/xen/x86/cpu.c:1.42 src/sys/arch/xen/x86/cpu.c:1.43
--- src/sys/arch/xen/x86/cpu.c:1.42	Wed Mar  3 00:09:03 2010
+++ src/sys/arch/xen/x86/cpu.c	Sun Apr 18 23:47:52 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.42 2010/03/03 00:09:03 jym Exp $	*/
+/*	$NetBSD: cpu.c,v 1.43 2010/04/18 23:47:52 jym Exp $	*/
 /* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp  */
 
 /*-
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.42 2010/03/03 00:09:03 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.43 2010/04/18 23:47:52 jym Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -174,6 +174,14 @@
 uint32_t phycpus_attached = 0;
 uint32_t phycpus_running = 0;
 
+uint32_t cpu_feature[5]; /* X86 CPUID feature bits
+			  *	[0] basic features %edx
+			  *	[1] basic features %ecx
+			  *	[2] extended features %edx
+			  *	[3] extended features %ecx
+			  *	[4] VIA padlock features
+			  */
+
 bool x86_mp_online;
 paddr_t mp_trampoline_paddr = MP_TRAMPOLINE;
 
@@ -547,14 +555,14 @@
 	 * On a P6 or above, enable global TLB caching if the
 	 * hardware supports it.
 	 */
-	if (cpu_feature & CPUID_PGE)
+	if (cpu_feature[0] & CPUID_PGE)
 		lcr4(rcr4() | CR4_PGE);	/* enable global TLB caching */
 
 #ifdef XXXMTRR
 	/*
 	 * On a P6 or above, initialize MTRR's if the hardware supports them.
 	 */
-	if (cpu_feature & CPUID_MTRR) {
+	if (cpu_feature[0] & CPUID_MTRR) {
 		if ((ci->ci_flags & CPUF_AP) == 0)
 			i686_mtrr_init_first();
 		mtrr_init_cpu(ci);
@@ -563,13 +571,13 @@
 	/*
 	 * If we have FXSAVE/FXRESTOR, use them.
 	 */
-	if (cpu_feature & CPUID_FXSR) {
+	if (cpu_feature[0] & CPUID_FXSR) {
 		lcr4(rcr4() | CR4_OSFXSR);
 
 		/*
 		 * If we have SSE/SSE2, enable XMM exceptions.
 		 */
-		if (cpu_feature & (CPUID_SSE|CPUID_SSE2))
+		if (cpu_feature[0] & (CPUID_SSE|CPUID_SSE2))
 			lcr4(rcr4() | CR4_OSXMMEXCPT);
 	}
 
@@ -702,19 +710,14 @@
 {
 	struct cpu_info *ci = (struct cpu_info *)v;
 	struct pcb *pcb;
-	uint32_t blacklist_features;
 	int s, i;
 
-#ifdef __x86_64__
-        cpu_init_msrs(ci, true);
-#endif
-
 	cpu_probe(ci);
 
-	/* not on Xen... */
-	blacklist_features = ~(CPUID_PGE|CPUID_PSE|CPUID_MTRR|CPUID_FXSR|CPUID_NOX); /* XXX add CPUID_SVM */
+	cpu_feature[0] &= ~CPUID_FEAT_BLACKLIST;
+	cpu_feature[2] &= ~CPUID_FEAT_EXT_BLACKLIST;
 
-	cpu_feature &= blacklist_features;
+        cpu_init_msrs(ci, true);
 
 	KDASSERT((ci->ci_flags & CPUF_PRESENT) == 0);
 	atomic_or_32(&ci->ci_flags, CPUF_PRESENT);
@@ -992,18 +995,17 @@
 #endif
 }
 
-#ifdef __x86_64__
-
 void
 cpu_init_msrs(struct cpu_info *ci, bool full)
 {
+#ifdef __x86_64__
 	if (full) {
 		HYPERVISOR_set_segment_base (SEGBASE_FS, 0);
 		HYPERVISOR_set_segment_base (SEGBASE_GS_KERNEL, (uint64_t) ci);
 		HYPERVISOR_set_segment_base (SEGBASE_GS_USER, 0);
 	}
-}
 #endif	/* __x86_64__ */
+}
 
 void
 cpu_offline_md(void)

Index: src/sys/compat/linux32/arch/amd64/linux32_exec.h
diff -u src/sys/compat/linux32/arch/amd64/linux32_exec.h:1.2 src/sys/compat/linux32/arch/amd64/linux32_exec.h:1.3
--- src/sys/compat/linux32/arch/amd64/linux32_exec.h:1.2	Mon Aug  7 14:19:57 2006
+++ src/sys/compat/linux32/arch/amd64/linux32_exec.h	Sun Apr 18 23:47:52 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_exec.h,v 1.2 2006/08/07 14:19:57 manu Exp $ */
+/*	$NetBSD: linux32_exec.h,v 1.3 2010/04/18 23:47:52 jym Exp $ */
 
 /*-
  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -46,7 +46,7 @@
 /* Hardware platform identifier string */
 #define LINUX32_PLATFORM "i686" 
 
-#define LINUX32_CPUCAP (curcpu()->ci_feature_flags)
+#define LINUX32_CPUCAP (cpu_feature[0])
 
 /* vsyscall assembly */
 static char linux32_kernel_vsyscall[] = {

Index: src/sys/compat/linux32/common/linux32_exec_elf32.c
diff -u src/sys/compat/linux32/common/linux32_exec_elf32.c:1.9 src/sys/compat/linux32/common/linux32_exec_elf32.c:1.10
--- src/sys/compat/linux32/common/linux32_exec_elf32.c:1.9	Sun Mar 15 15:56:50 2009
+++ src/sys/compat/linux32/common/linux32_exec_elf32.c	Sun Apr 18 23:47:52 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_exec_elf32.c,v 1.9 2009/03/15 15:56:50 cegger Exp $ */
+/*	$NetBSD: linux32_exec_elf32.c,v 1.10 2010/04/18 23:47:52 jym Exp $ */
 
 /*-                     
  * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.9 2009/03/15 15:56:50 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.10 2010/04/18 23:47:52 jym Exp $");
 
 #define	ELFSIZE		32
 
@@ -53,6 +53,7 @@
 #include <compat/netbsd32/netbsd32_exec.h>
 #include <compat/linux32/common/linux32_exec.h>
 
+#include <machine/cpuvar.h>
 #include <machine/frame.h>
 
 #ifdef DEBUG_LINUX

Reply via email to