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