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:
parent
72c00e4a7a
commit
bc0420413d
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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[] = {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user