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