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.
This commit is contained in:
jym 2010-04-18 23:47:50 +00:00
parent 72c00e4a7a
commit bc0420413d
24 changed files with 185 additions and 171 deletions

View File

@ -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 @@ _C_LABEL(lapic_isr):
#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(lapic_isr):
_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_start:
gdt64_end:
farjmp64:
.long longmode-KERNBASE
.long _RELOC(longmode)
.word GSEL(GCODE_SEL, SEL_KPL)
#endif /* !XEN */
@ -418,18 +414,11 @@ start: movw $0x1234,0x472 # warm boot
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

View File

@ -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 @@ init_x86_64(paddr_t first_avail)
#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 @@ init_x86_64(paddr_t first_avail)
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

View File

@ -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 @@ _C_LABEL(cpu_spinup_trampoline_end): #end of code copied to MP_TRAMPOLINE
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

View File

@ -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 @@ procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, int *len)
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;

View File

@ -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_CC_SKEW offsetof(struct cpu_info, ci_data.cpu_cc_skew)
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)

View File

@ -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 @@ struct mtrr_funcs *mtrr_funcs;
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 @@ init386(paddr_t first_avail)
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)));

View File

@ -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 @@ procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, int *len)
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;

View File

@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.135 2009/11/21 03:11:01 rmind Exp $");
#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 @@ npxprobe1(bus_space_tag_t iot, bus_space_handle_t ioh, int irq)
int status;
unsigned irqmask;
if (cpu_feature & CPUID_FPU) {
if (cpu_feature[0] & CPUID_FPU) {
i386_fpu_exception = 1;
return NPX_CPUID;
}

View File

@ -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 @@ struct cpu_info {
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 @@ struct timeval;
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;

View File

@ -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 @@ void cpu_get_tsc_freq(struct cpu_info *);
extern int cpu_vendor;
extern bool x86_mp_online;
extern uint32_t cpu_feature[5];
#endif
#endif /* !_X86_CPUVAR_H_ */

View File

@ -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 @@ struct mpbios_proc {
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;
};

View File

@ -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
*/

View File

@ -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 @@ static void cpu_init_idle_lwp(struct cpu_info *);
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 @@ cpu_init(struct cpu_info *ci)
* 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 @@ cpu_init(struct cpu_info *ci)
/*
* 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 @@ cpu_boot_secondary_processors(void)
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 @@ cpu_hatch(void *v)
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 @@ cpu_hatch(void *v)
* 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 @@ mp_cpu_start(struct cpu_info *ci, paddr_t target)
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 @@ mp_cpu_start_cleanup(struct cpu_info *ci)
#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 @@ cpu_init_msrs(struct cpu_info *ci, bool full)
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 @@ cpu_get_tsc_freq(struct cpu_info *ci)
{
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;

View File

@ -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 @@ x86_cpu_topology(struct cpu_info *ci)
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 @@ x86_cpu_topology(struct cpu_info *ci)
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;
}

View File

@ -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 @@ cpu_probe_k5(struct cpu_info *ci)
* 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 @@ cpu_probe_k678(struct cpu_info *ci)
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 @@ cpu_probe_cyrix_cmn(struct cpu_info *ci)
* 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 @@ cpu_probe_winchip(struct cpu_info *ci)
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 @@ cpu_probe_c3(struct cpu_info *ci)
/* 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 @@ cpu_probe_c3(struct cpu_info *ci)
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 @@ cpu_probe(struct cpu_info *ci)
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 @@ cpu_probe(struct cpu_info *ci)
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_probe(struct cpu_info *ci)
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 @@ cpu_probe(struct cpu_info *ci)
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 @@ cpu_identify(struct cpu_info *ci)
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 @@ cpu_identify(struct cpu_info *ci)
}
/* 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);
}

View File

@ -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 @@ mpbios_cpus(device_t self)
/* 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);

View File

@ -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 @@ x86_patch(bool early)
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 @@ x86_patch(bool early)
* 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 @@ x86_patch(bool early)
#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,

View File

@ -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 @@ pmap_kenter_ma(vaddr_t va, paddr_t ma, vm_prot_t prot, u_int flags)
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 @@ pmap_bootstrap(vaddr_t kva_start)
#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 @@ pmap_bootstrap(vaddr_t kva_start)
* (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 @@ pmap_bootstrap(vaddr_t kva_start)
* 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 @@ pmap_pageidlezero(paddr_t pa)
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 @@ pmap_tlb_shootdown(struct pmap *pm, vaddr_t sva, vaddr_t eva, pt_entry_t pte)
* 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()) {

View File

@ -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 @@ tsc_tc_init(void)
uint32_t descs[4];
bool safe;
if ((cpu_feature & CPUID_TSC) == 0) {
if (!cpu_hascounter()) {
return;
}
@ -255,5 +255,5 @@ int
cpu_hascounter(void)
{
return cpu_feature & CPUID_TSC;
return cpu_feature[0] & CPUID_TSC;
}

View File

@ -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 @@ via_padlock_attach(void)
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 @@ via_padlock_attach(void)
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");
}

View File

@ -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 @@ void
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;

View File

@ -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 cpus_running = 0;
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 @@ cpu_init(struct cpu_info *ci)
* 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 @@ cpu_init(struct cpu_info *ci)
/*
* 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 @@ cpu_hatch(void *v)
{
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 @@ mp_cpu_start_cleanup(struct cpu_info *ci)
#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)

View File

@ -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[] = {

View File

@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.9 2009/03/15 15:56:50 cegge
#include <compat/netbsd32/netbsd32_exec.h>
#include <compat/linux32/common/linux32_exec.h>
#include <machine/cpuvar.h>
#include <machine/frame.h>
#ifdef DEBUG_LINUX