Commit 98194f08 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86-64 merge

Only bug fixes and making it compile again and a few minor features.
Also one security fix that got lost earlier

- Document boot options
- Better cpu local data
- Emulate FIOQSIZE
- Fix return value of 32bit ipccall
- Various minor style fixes
- Save some memory in apic tables
- Merge with 2.6.0test2/i386
- Readd ioport fix
- Sort exception tables at boot time
- Add local.h
- Fix for_each_cpu on UP
- Add utimes and tgkill system calls for 64bit
- Update defconfig
parent 3d1e8eab
AMD64 specific boot options
There are many others (usually documented in driver documentation), but
only the AMD64 specific ones are listed here.
Machine check
(see the Opteron BIOS&Kernel manual for more details on the banks etc.)
mce=off disable machine check
mce=nok8 disable k8 specific features
mce=disable<NUMBER> disable bank NUMBER
mce=enable<NUMBER> enable bank number
mce=device Enable more machine check options in Northbridge.
Can be useful for device driver debugging.
mce=NUMBER mcheck timer interval number seconds.
Can be also comma separated in a single mce=
nomce (for compatibility with i386): same as mce=off
APICs
nolocalapic Don't use a local or IO-APIC. This should only
be needed if you have a buggy BIOS. The newer
kernels already turn it off by default if the
BIOS didn't enable the local APIC, so it will
be hopefully not needed.
Note this code path is not very well tested, you are on
your own.
apic Use IO-APIC. Default
noapic Don't use the IO-APIC.
Also only lightly tested.
pirq=... See Documentation/i386/IO-APIC.txt
Early Console
syntax: earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
The early console is useful when the kernel crashes before the
normal console is initialized. It is not enabled by
default because it has some cosmetic problems.
Append ,keep to not disable it when the real console takes over.
Only vga or serial at a time, not both.
Currently only ttyS0 and ttyS1 are supported.
Interaction with the standard serial driver is not very good.
The VGA output is eventually overwritten by the real console.
Timing
notsc
Don't use the CPU time stamp counter to read the wall time.
This can be used to work around timing problems on multiprocessor systems
with not properly synchronized CPUs. Only useful with a SMP kernel
report_lost_ticks
Report when timer interrupts are lost because some code turned off
interrupts for too long.
nmi_watchdog=NUMBER
NUMBER can be:
0 don't use an NMI watchdog
1 use the IO-APIC timer for the NMI watchdog
2 use the local APIC for the NMI watchdog using a performance counter. Note
This will use one performance counter and the local APIC's performance
vector.
Idle loop
idle=poll
Don't do power saving in the idle loop using HLT, but poll for rescheduling
event. This will make the CPUs eat a lot more power, but may be useful
to get slightly better performance in multiprocessor benchmarks. It also
makes some profiling using performance counters more accurate.
Rebooting
reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
bios Use the CPU reboto vector for warm reset
warm Don't set the cold reboot flag
cold Set the cold reboto flag
triple Force a triple fault (init)
kbd Use the keyboard controller. cold reset (default)
Using warm reset will be much faster especially on big memory
systems because the BIOS will not go through the memory check.
Disadvantage is that not all hardware will be completely reinitialized
on reboot so there may be boot problems on some systems.
Non Executable Mappings
noexec=on|off
on Enable
off Disable
noforce (default) Don't enable by default for heap/stack/data,
but allow PROT_EXEC to be effective
noexec32=opt{,opt}
Control the no exec default for 32bit processes.
Requires noexec=on or noexec=noforce to be effective.
Valid options:
all,on Heap,stack,data is non executable.
off (default) Heap,stack,data is executable
stack Stack is non executable, heap/data is.
force Don't imply PROT_EXEC for PROT_READ
compat (default) Imply PROT_EXEC for PROT_READ
SMP
nosmp Only use a single CPU
maxcpus=NUMBER only use upto NUMBER CPUs
cpumask=MASK only use cpus with bits set in mask
NUMA
numa=off Only set up a single NUMA node spanning all memory.
ACPI
acpi=off Don't enable ACPI
PCI
pci=off Don't use PCI
pci=conf1 Use conf1 access.
pci=conf2 Use conf2 access.
pci=rom Assign ROMs.
pci=assign-busses Assign busses
pci=irqmask=MASK Set PCI interrupt mask to MASK
pci=lastbus=NUMBER Scan upto NUMBER busses, no matter what the mptable says.
IOMMU
iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
size set size of iommu (in bytes)
noagp don't initialize the AGP driver and use full aperture.
off don't use the IOMMU
leak turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
memaper[=order] allocate an own aperture over RAM with size 32MB^order.
noforce don't force IOMMU usage. Default.
force Force IOMMU
...@@ -24,8 +24,11 @@ CONFIG_SYSVIPC=y ...@@ -24,8 +24,11 @@ CONFIG_SYSVIPC=y
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=16 CONFIG_LOG_BUF_SHIFT=16
# CONFIG_EMBEDDED is not set # CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_FUTEX=y CONFIG_FUTEX=y
CONFIG_EPOLL=y CONFIG_EPOLL=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
# #
# Loadable module support # Loadable module support
...@@ -135,6 +138,7 @@ CONFIG_BLK_DEV_FD=y ...@@ -135,6 +138,7 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_UMEM is not set
CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_SIZE=4096
...@@ -163,6 +167,7 @@ CONFIG_BLK_DEV_IDECD=y ...@@ -163,6 +167,7 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set # CONFIG_IDE_TASK_IOCTL is not set
# CONFIG_IDE_TASKFILE_IO is not set
# #
# IDE chipset support/bugfixes # IDE chipset support/bugfixes
...@@ -379,7 +384,6 @@ CONFIG_NET_PCI=y ...@@ -379,7 +384,6 @@ CONFIG_NET_PCI=y
CONFIG_AMD8111_ETH=y CONFIG_AMD8111_ETH=y
# CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set # CONFIG_B44 is not set
# CONFIG_TC35815 is not set
# CONFIG_DGRS is not set # CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set # CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set # CONFIG_E100 is not set
...@@ -727,6 +731,9 @@ CONFIG_SOUND_ICH=y ...@@ -727,6 +731,9 @@ CONFIG_SOUND_ICH=y
# CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_OSS is not set # CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_ALI5455 is not set
# CONFIG_SOUND_FORTE is not set
# CONFIG_SOUND_AD1980 is not set
# #
# USB support # USB support
...@@ -753,10 +760,8 @@ CONFIG_DEBUG_KERNEL=y ...@@ -753,10 +760,8 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_INIT_DEBUG is not set # CONFIG_INIT_DEBUG is not set
CONFIG_KALLSYMS=y
# CONFIG_FRAME_POINTER is not set # CONFIG_FRAME_POINTER is not set
CONFIG_IOMMU_DEBUG=y # CONFIG_IOMMU_DEBUG is not set
CONFIG_IOMMU_LEAK=y
CONFIG_MCE_DEBUG=y CONFIG_MCE_DEBUG=y
# #
......
...@@ -32,12 +32,14 @@ ...@@ -32,12 +32,14 @@
#define AT_SYSINFO 32 #define AT_SYSINFO 32
#define AT_SYSINFO_EHDR 33 #define AT_SYSINFO_EHDR 33
#if 0 /* disabled for now because the code has still problems */ int sysctl_vsyscall32;
#define ARCH_DLINFO do { \ #define ARCH_DLINFO do { \
if (sysctl_vsyscall32) { \
NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \ NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
} \
} while(0) } while(0)
#endif
struct file; struct file;
struct elf_phdr; struct elf_phdr;
...@@ -202,7 +204,7 @@ static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* ...@@ -202,7 +204,7 @@ static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t*
} }
static inline int static inline int
elf_core_copy_task_fpregs(struct task_struct *tsk, elf_fpregset_t *fpu) elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *xregs, elf_fpregset_t *fpu)
{ {
struct _fpstate_ia32 *fpstate = (void*)fpu; struct _fpstate_ia32 *fpstate = (void*)fpu;
struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0); struct pt_regs *regs = (struct pt_regs *)(tsk->thread.rsp0);
......
...@@ -726,6 +726,7 @@ COMPATIBLE_IOCTL(BNEPCONNADD) ...@@ -726,6 +726,7 @@ COMPATIBLE_IOCTL(BNEPCONNADD)
COMPATIBLE_IOCTL(BNEPCONNDEL) COMPATIBLE_IOCTL(BNEPCONNDEL)
COMPATIBLE_IOCTL(BNEPGETCONNLIST) COMPATIBLE_IOCTL(BNEPGETCONNLIST)
COMPATIBLE_IOCTL(BNEPGETCONNINFO) COMPATIBLE_IOCTL(BNEPGETCONNINFO)
COMPATIBLE_IOCTL(FIOQSIZE)
/* And these ioctls need translation */ /* And these ioctls need translation */
HANDLE_IOCTL(TIOCGDEV, tiocgdev) HANDLE_IOCTL(TIOCGDEV, tiocgdev)
......
...@@ -687,9 +687,7 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) ...@@ -687,9 +687,7 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
return sys_shmget(first, second, third); return sys_shmget(first, second, third);
case SHMCTL: case SHMCTL:
return shmctl32(first, second, (void *)AA(ptr)); return shmctl32(first, second, (void *)AA(ptr));
default:
return -EINVAL;
} }
return -EINVAL; return -ENOSYS;
} }
...@@ -441,9 +441,6 @@ void __init setup_local_APIC (void) ...@@ -441,9 +441,6 @@ void __init setup_local_APIC (void)
#ifdef CONFIG_PM #ifdef CONFIG_PM
#include <linux/device.h>
#include <linux/module.h>
static struct { static struct {
/* 'active' is true if the local APIC was enabled by us and /* 'active' is true if the local APIC was enabled by us and
not the BIOS; this signifies that we are also responsible not the BIOS; this signifies that we are also responsible
...@@ -540,7 +537,6 @@ static struct sysdev_class lapic_sysclass = { ...@@ -540,7 +537,6 @@ static struct sysdev_class lapic_sysclass = {
.suspend = lapic_suspend, .suspend = lapic_suspend,
}; };
/* not static, needed by child devices */
static struct sys_device device_lapic = { static struct sys_device device_lapic = {
.id = 0, .id = 0,
.cls = &lapic_sysclass, .cls = &lapic_sysclass,
......
...@@ -127,9 +127,8 @@ static struct pci_dev *find_k8_nb(void) ...@@ -127,9 +127,8 @@ static struct pci_dev *find_k8_nb(void)
{ {
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { while ((dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, dev)) != NULL) {
if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 && if (dev->bus->number==0 && PCI_SLOT(dev->devfn) == (24U+cpu))
PCI_SLOT(dev->devfn) == (24U+cpu))
return dev; return dev;
} }
return NULL; return NULL;
...@@ -198,7 +197,7 @@ static char *highbits[32] = { ...@@ -198,7 +197,7 @@ static char *highbits[32] = {
[0] = "err cpu1", [0] = "err cpu1",
}; };
static void check_k8_nb(void) static void check_k8_nb(int header)
{ {
struct pci_dev *nb; struct pci_dev *nb;
nb = find_k8_nb(); nb = find_k8_nb();
...@@ -210,6 +209,9 @@ static void check_k8_nb(void) ...@@ -210,6 +209,9 @@ static void check_k8_nb(void)
pci_read_config_dword(nb, 0x4c, &statushigh); pci_read_config_dword(nb, 0x4c, &statushigh);
if (!(statushigh & (1<<31))) if (!(statushigh & (1<<31)))
return; return;
if (header)
printk(KERN_ERR "CPU %d: Silent Northbridge MCE\n", smp_processor_id());
printk(KERN_ERR "Northbridge status %08x%08x\n", printk(KERN_ERR "Northbridge status %08x%08x\n",
statushigh,statuslow); statushigh,statuslow);
...@@ -271,9 +273,12 @@ static void k8_machine_check(struct pt_regs * regs, long error_code) ...@@ -271,9 +273,12 @@ static void k8_machine_check(struct pt_regs * regs, long error_code)
rdmsrl(MSR_IA32_MCG_STATUS, status); rdmsrl(MSR_IA32_MCG_STATUS, status);
if ((status & (1<<2)) == 0) { if ((status & (1<<2)) == 0) {
if (!regs) if (!regs)
check_k8_nb(); check_k8_nb(1);
return; return;
} }
printk(KERN_EMERG "CPU %d: Machine Check Exception: %016Lx\n", smp_processor_id(), status);
if (status & 1) if (status & 1)
printk(KERN_EMERG "MCG_STATUS: unrecoverable\n"); printk(KERN_EMERG "MCG_STATUS: unrecoverable\n");
...@@ -291,7 +296,7 @@ static void k8_machine_check(struct pt_regs * regs, long error_code) ...@@ -291,7 +296,7 @@ static void k8_machine_check(struct pt_regs * regs, long error_code)
if (nbstatus & (1UL<57)) if (nbstatus & (1UL<57))
printk(KERN_EMERG "Unrecoverable condition\n"); printk(KERN_EMERG "Unrecoverable condition\n");
check_k8_nb(); check_k8_nb(0);
if (nbstatus & (1UL<<58)) { if (nbstatus & (1UL<<58)) {
u64 adr; u64 adr;
......
...@@ -307,7 +307,8 @@ ENTRY(empty_bad_pmd_table) ...@@ -307,7 +307,8 @@ ENTRY(empty_bad_pmd_table)
ENTRY(level3_physmem_pgt) ENTRY(level3_physmem_pgt)
.quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ .quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
.org 0xb000 .org 0xb000
#ifdef CONFIG_ACPI_SLEEP
ENTRY(wakeup_level4_pgt) ENTRY(wakeup_level4_pgt)
.quad 0x0000000000102007 /* -> level3_ident_pgt */ .quad 0x0000000000102007 /* -> level3_ident_pgt */
.fill 255,8,0 .fill 255,8,0
...@@ -315,9 +316,9 @@ ENTRY(wakeup_level4_pgt) ...@@ -315,9 +316,9 @@ ENTRY(wakeup_level4_pgt)
.fill 254,8,0 .fill 254,8,0
/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
.quad 0x0000000000103007 /* -> level3_kernel_pgt */ .quad 0x0000000000103007 /* -> level3_kernel_pgt */
#endif
.org 0xc000 .data
.data
.align 16 .align 16
.globl cpu_gdt_descr .globl cpu_gdt_descr
......
...@@ -63,7 +63,7 @@ int nr_ioapic_registers[MAX_IO_APICS]; ...@@ -63,7 +63,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
*/ */
static struct irq_pin_list { static struct irq_pin_list {
int apic, pin, next; short apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE]; } irq_2_pin[PIN_MAP_SIZE];
/* /*
...@@ -1781,3 +1781,21 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq) ...@@ -1781,3 +1781,21 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq)
} }
#endif /*CONFIG_ACPI_BOOT*/ #endif /*CONFIG_ACPI_BOOT*/
#ifndef CONFIG_SMP
void send_IPI_self(int vector)
{
unsigned int cfg;
/*
* Wait for idle.
*/
apic_wait_icr_idle();
cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
apic_write_around(APIC_ICR, cfg);
}
#endif
...@@ -51,42 +51,50 @@ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_ ...@@ -51,42 +51,50 @@ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_
} }
} }
/* /*
* this changes the io permissions bitmap in the current task. * this changes the io permissions bitmap in the current task.
*/ */
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{ {
struct thread_struct * t = &current->thread; struct thread_struct * t = &current->thread;
struct tss_struct * tss; int cpu = get_cpu();
int ret = 0;
if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
return -EINVAL; return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO)) if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
struct tss_struct * tss = init_tss + cpu;
/*
* If it's the first ioperm() call in this thread's lifetime, set the
* IO bitmap up. ioperm() is much less timing critical than clone(),
* this is why we delay this operation until now:
*/
if (!t->io_bitmap_ptr) { if (!t->io_bitmap_ptr) {
t->io_bitmap_ptr = kmalloc((IO_BITMAP_SIZE+1)*4, GFP_KERNEL); t->io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
if (!t->io_bitmap_ptr) { if (!t->io_bitmap_ptr) {
ret = -ENOMEM;
goto out;
}
memset(t->io_bitmap_ptr,0xff,(IO_BITMAP_SIZE+1)*4);
tss = init_tss + get_cpu();
tss->io_map_base = IO_BITMAP_OFFSET;
put_cpu(); put_cpu();
return -ENOMEM;
}
memset(t->io_bitmap_ptr,0xff,IO_BITMAP_BYTES);
} }
tss = init_tss + get_cpu();
/* /*
* do it in the per-thread copy and in the TSS ... * do it in the per-thread copy and in the TSS ...
*/ */
set_bitmap((unsigned long *) t->io_bitmap_ptr, from, num, !turn_on); set_bitmap((unsigned long *) t->io_bitmap_ptr, from, num, !turn_on);
if (tss->io_map_base != IO_BITMAP_OFFSET) {
memcpy(tss->io_bitmap, t->io_bitmap_ptr, sizeof(tss->io_bitmap));
tss->io_map_base = IO_BITMAP_OFFSET;
} else {
set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on); set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on);
}
out:
put_cpu(); put_cpu();
return ret; return 0;
} }
/* /*
......
...@@ -41,8 +41,10 @@ int acpi_found_madt; ...@@ -41,8 +41,10 @@ int acpi_found_madt;
* MP-table. * MP-table.
*/ */
int apic_version [MAX_APICS]; int apic_version [MAX_APICS];
int mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
unsigned long mp_bus_to_cpumask [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1UL };
int mp_current_pci_id = 0; int mp_current_pci_id = 0;
/* I/O APIC entries */ /* I/O APIC entries */
struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
......
...@@ -141,14 +141,14 @@ void disable_lapic_nmi_watchdog(void) ...@@ -141,14 +141,14 @@ void disable_lapic_nmi_watchdog(void)
/* tell do_nmi() and others that we're not active any more */ /* tell do_nmi() and others that we're not active any more */
nmi_watchdog = 0; nmi_watchdog = 0;
} }
void enable_lapic_nmi_watchdog(void) void enable_lapic_nmi_watchdog(void)
{ {
if (nmi_active < 0) { if (nmi_active < 0) {
nmi_watchdog = NMI_LOCAL_APIC; nmi_watchdog = NMI_LOCAL_APIC;
setup_apic_nmi_watchdog(); setup_apic_nmi_watchdog();
} }
} }
void disable_timer_nmi_watchdog(void) void disable_timer_nmi_watchdog(void)
{ {
...@@ -173,8 +173,6 @@ void enable_timer_nmi_watchdog(void) ...@@ -173,8 +173,6 @@ void enable_timer_nmi_watchdog(void)
#ifdef CONFIG_PM #ifdef CONFIG_PM
#include <linux/device.h>
static int nmi_pm_active; /* nmi_active before suspend */ static int nmi_pm_active; /* nmi_active before suspend */
static int lapic_nmi_suspend(struct sys_device *dev, u32 state) static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
......
...@@ -114,32 +114,37 @@ Valid options: ...@@ -114,32 +114,37 @@ Valid options:
__setup("noexec32=", nonx32_setup); __setup("noexec32=", nonx32_setup);
#ifndef __GENERIC_PER_CPU /*
* Great future plan:
unsigned long __per_cpu_offset[NR_CPUS]; * Declare PDA itself and support (irqstack,tss,pml4) as per cpu data.
* Always point %gs to its beginning
*/
void __init setup_per_cpu_areas(void) void __init setup_per_cpu_areas(void)
{ {
unsigned long size, i; int i;
unsigned char *ptr; unsigned long size;
/* Copy section for each CPU (we discard the original) */ /* Copy section for each CPU (we discard the original) */
size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
if (!size) #ifdef CONFIG_MODULES
return; if (size < PERCPU_ENOUGH_ROOM)
size = PERCPU_ENOUGH_ROOM;
ptr = alloc_bootmem(size * NR_CPUS); #endif
for (i = 0; i < NR_CPUS; i++, ptr += size) { /* We don't support CPU hotplug, so only allocate as much as needed here */
/* hide this from the compiler to avoid problems */
unsigned long offset; int maxi = max_t(unsigned, numnodes, num_online_cpus());
asm("subq %[b],%0" : "=r" (offset) : "0" (ptr), [b] "r" (&__per_cpu_start));
__per_cpu_offset[i] = offset; for (i = 0; i < maxi; i++) {
cpu_pda[i].cpudata_offset = offset; /* If possible allocate on the node of the CPU.
memcpy(ptr, __per_cpu_start, size); In case it doesn't exist round-robin nodes. */
unsigned char *ptr = alloc_bootmem_node(NODE_DATA(i % numnodes), size);
if (!ptr)
panic("Cannot allocate cpu data for CPU %d\n", i);
cpu_pda[i].data_offset = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
} }
} }
#endif
void pda_init(int cpu) void pda_init(int cpu)
{ {
...@@ -153,7 +158,7 @@ void pda_init(int cpu) ...@@ -153,7 +158,7 @@ void pda_init(int cpu)
pda->me = pda; pda->me = pda;
pda->cpunumber = cpu; pda->cpunumber = cpu;
pda->irqcount = -1; pda->irqcount = -1;
pda->cpudata_offset = 0; pda->data_offset = 0;
pda->kernelstack = pda->kernelstack =
(unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE;
pda->active_mm = &init_mm; pda->active_mm = &init_mm;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/init.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
/* Simple binary search */ /* Simple binary search */
...@@ -28,3 +29,29 @@ search_extable(const struct exception_table_entry *first, ...@@ -28,3 +29,29 @@ search_extable(const struct exception_table_entry *first,
} }
return NULL; return NULL;
} }
/* When an exception handler is in an non standard section (like __init)
the fixup table can end up unordered. Fix that here. */
static __init int check_extable(void)
{
extern struct exception_table_entry __start___ex_table[];
extern struct exception_table_entry __stop___ex_table[];
struct exception_table_entry *e;
int change;
/* The input is near completely presorted, which makes bubble sort the
best (and simplest) sort algorithm. */
do {
change = 0;
for (e = __start___ex_table+1; e < __stop___ex_table; e++) {
if (e->insn < e[-1].insn) {
struct exception_table_entry tmp = e[-1];
e[-1] = e[0];
e[0] = tmp;
change = 1;
}
}
} while (change != 0);
return 0;
}
core_initcall(check_extable);
...@@ -84,10 +84,6 @@ extern int APIC_init_uniprocessor (void); ...@@ -84,10 +84,6 @@ extern int APIC_init_uniprocessor (void);
extern void disable_APIC_timer(void); extern void disable_APIC_timer(void);
extern void enable_APIC_timer(void); extern void enable_APIC_timer(void);
#ifdef CONFIG_PM
extern struct sys_device device_lapic;
#endif
extern int check_nmi_watchdog (void); extern int check_nmi_watchdog (void);
extern unsigned int nmi_watchdog; extern unsigned int nmi_watchdog;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/string.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/mmu.h> #include <asm/mmu.h>
......
...@@ -164,7 +164,7 @@ static inline void x86_do_profile (struct pt_regs *regs) ...@@ -164,7 +164,7 @@ static inline void x86_do_profile (struct pt_regs *regs)
atomic_inc((atomic_t *)&prof_buffer[rip]); atomic_inc((atomic_t *)&prof_buffer[rip]);
} }
#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */ #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP)
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
if (IO_APIC_IRQ(i)) if (IO_APIC_IRQ(i))
send_IPI_self(IO_APIC_VECTOR(i)); send_IPI_self(IO_APIC_VECTOR(i));
......
#ifndef _ARCH_X8664_LOCAL_H
#define _ARCH_X8664_LOCAL_H
#include <linux/percpu.h>
typedef struct
{
volatile unsigned int counter;
} local_t;
#define LOCAL_INIT(i) { (i) }
#define local_read(v) ((v)->counter)
#define local_set(v,i) (((v)->counter) = (i))
static __inline__ void local_inc(local_t *v)
{
__asm__ __volatile__(
"incl %0"
:"=m" (v->counter)
:"m" (v->counter));
}
static __inline__ void local_dec(local_t *v)
{
__asm__ __volatile__(
"decl %0"
:"=m" (v->counter)
:"m" (v->counter));
}
static __inline__ void local_add(unsigned long i, local_t *v)
{
__asm__ __volatile__(
"addl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
static __inline__ void local_sub(unsigned long i, local_t *v)
{
__asm__ __volatile__(
"subl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
/* On x86, these are no better than the atomic variants. */
#define __local_inc(l) local_inc(l)
#define __local_dec(l) local_dec(l)
#define __local_add(i,l) local_add((i),(l))
#define __local_sub(i,l) local_sub((i),(l))
/* Use these for per-cpu local_t variables: on some archs they are
* much more efficient than these naive implementations. Note they take
* a variable, not an address.
*
* This could be done better if we moved the per cpu data directly
* after GS.
*/
#define cpu_local_read(v) local_read(&__get_cpu_var(v))
#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
#define __cpu_local_inc(v) cpu_local_inc(v)
#define __cpu_local_dec(v) cpu_local_dec(v)
#define __cpu_local_add(i, v) cpu_local_add((i), (v))
#define __cpu_local_sub(i, v) cpu_local_sub((i), (v))
#endif /* _ARCH_I386_LOCAL_H */
...@@ -164,11 +164,9 @@ enum mp_bustype { ...@@ -164,11 +164,9 @@ enum mp_bustype {
MP_BUS_PCI, MP_BUS_PCI,
MP_BUS_MCA MP_BUS_MCA
}; };
extern int mp_bus_id_to_type [MAX_MP_BUSSES]; extern unsigned char mp_bus_id_to_type [MAX_MP_BUSSES];
extern int mp_bus_id_to_node [MAX_MP_BUSSES];
extern int mp_bus_id_to_local [MAX_MP_BUSSES];
extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
extern unsigned long mp_bus_to_cpumask [MAX_MP_BUSSES];
extern unsigned int boot_cpu_physical_apicid; extern unsigned int boot_cpu_physical_apicid;
extern unsigned long phys_cpu_present_map; extern unsigned long phys_cpu_present_map;
...@@ -177,11 +175,9 @@ extern void find_smp_config (void); ...@@ -177,11 +175,9 @@ extern void find_smp_config (void);
extern void get_smp_config (void); extern void get_smp_config (void);
extern int nr_ioapics; extern int nr_ioapics;
extern int apic_version [MAX_APICS]; extern int apic_version [MAX_APICS];
extern int mp_bus_id_to_type [MAX_MP_BUSSES];
extern int mp_irq_entries; extern int mp_irq_entries;
extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
extern int mpc_default_type; extern int mpc_default_type;
extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
extern int mp_current_pci_id; extern int mp_current_pci_id;
extern unsigned long mp_lapic_addr; extern unsigned long mp_lapic_addr;
extern int pic_mode; extern int pic_mode;
......
...@@ -48,4 +48,6 @@ static inline void unset_nmi_pm_callback(struct pm_dev * dev) ...@@ -48,4 +48,6 @@ static inline void unset_nmi_pm_callback(struct pm_dev * dev)
extern void default_do_nmi(struct pt_regs *); extern void default_do_nmi(struct pt_regs *);
extern void default_do_nmi(struct pt_regs *);
#endif /* ASM_NMI_H */ #endif /* ASM_NMI_H */
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
/* Per processor datastructure. %gs points to it while the kernel runs */ /* Per processor datastructure. %gs points to it while the kernel runs */
struct x8664_pda { struct x8664_pda {
struct task_struct *pcurrent; /* Current process */ struct task_struct *pcurrent; /* Current process */
unsigned long cpudata_offset; unsigned long data_offset; /* Per cpu data offset from linker address */
struct x8664_pda *me; /* Pointer to itself */ struct x8664_pda *me; /* Pointer to itself */
unsigned long kernelstack; /* TOS for current process */ unsigned long kernelstack; /* TOS for current process */
unsigned long oldrsp; /* user rsp for system call */ unsigned long oldrsp; /* user rsp for system call */
......
#ifndef __ARCH_I386_PERCPU__ #ifndef _ASM_X8664_PERCPU_H_
#define __ARCH_I386_PERCPU__ #define _ASM_X8664_PERCPU_H_
#include <asm-generic/percpu.h> #include <asm/pda.h>
#endif /* __ARCH_I386_PERCPU__ */ #ifdef CONFIG_SMP
/* Same as the generic code except that we cache the per cpu offset
in the pda. This gives an 3 instruction reference for per cpu data */
#include <linux/compiler.h>
#include <asm/pda.h>
#define __my_cpu_offset() read_pda(data_offset)
#define __per_cpu_offset(cpu) (cpu_pda[cpu].data_offset)
/* Separate out the type, so (int[3], foo) works. */
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(".data.percpu"))) __typeof__(type) name##__per_cpu
/* var is in discarded region: offset to particular copy we want */
#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset(cpu)))
#define __get_cpu_var(var) \
(*RELOC_HIDE(&var##__per_cpu, __my_cpu_offset()))
static inline void percpu_modcopy(void *pcpudst, const void *src,
unsigned long size)
{
unsigned int i;
for (i = 0; i < NR_CPUS; i++)
if (cpu_possible(i))
memcpy(pcpudst + __per_cpu_offset(i), src, size);
}
extern void setup_per_cpu_areas(void);
#else /* ! SMP */
#define DEFINE_PER_CPU(type, name) \
__typeof__(type) name##__per_cpu
#define per_cpu(var, cpu) ((void)cpu, var##__per_cpu)
#define __get_cpu_var(var) var##__per_cpu
#endif /* SMP */
#define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu
#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(var##__per_cpu)
#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(var##__per_cpu)
DECLARE_PER_CPU(struct x8664_pda, per_cpu_pda);
#endif
...@@ -181,6 +181,7 @@ static inline void clear_in_cr4 (unsigned long mask) ...@@ -181,6 +181,7 @@ static inline void clear_in_cr4 (unsigned long mask)
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff. * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
*/ */
#define IO_BITMAP_SIZE 32 #define IO_BITMAP_SIZE 32
#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
#define INVALID_IO_BITMAP_OFFSET 0x8000 #define INVALID_IO_BITMAP_OFFSET 0x8000
......
...@@ -117,7 +117,7 @@ extern inline int safe_smp_processor_id(void) ...@@ -117,7 +117,7 @@ extern inline int safe_smp_processor_id(void)
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
#define stack_smp_processor_id() 0 #define stack_smp_processor_id() 0
#define safe_smp_processor_id() 0 #define safe_smp_processor_id() 0
#define for_each_cpu(x) (x)=0; #define for_each_cpu(x,mask) (void)(mask), (x)=0;
#define cpu_logical_map(x) (x) #define cpu_logical_map(x) (x)
#else #else
#include <asm/thread_info.h> #include <asm/thread_info.h>
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifdef CONFIG_DISCONTIGMEM #ifdef CONFIG_DISCONTIGMEM
#include <asm/mpspec.h>
/* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */ /* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */
extern int fake_node; extern int fake_node;
...@@ -17,6 +19,11 @@ extern unsigned long cpu_online_map; ...@@ -17,6 +19,11 @@ extern unsigned long cpu_online_map;
#define node_to_cpu_mask(node) (fake_node ? cpu_online_map : (1UL << (node))) #define node_to_cpu_mask(node) (fake_node ? cpu_online_map : (1UL << (node)))
#define node_to_memblk(node) (node) #define node_to_memblk(node) (node)
static inline unsigned long pcibus_to_cpumask(int bus)
{
return mp_bus_to_cpumask[bus] & cpu_online_map;
}
#define NODE_BALANCE_RATE 30 /* CHECKME */ #define NODE_BALANCE_RATE 30 /* CHECKME */
#endif #endif
......
...@@ -526,8 +526,12 @@ __SYSCALL(__NR_exit_group, sys_exit_group) ...@@ -526,8 +526,12 @@ __SYSCALL(__NR_exit_group, sys_exit_group)
__SYSCALL(__NR_epoll_wait, sys_epoll_wait) __SYSCALL(__NR_epoll_wait, sys_epoll_wait)
#define __NR_epoll_ctl 233 #define __NR_epoll_ctl 233
__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) __SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
#define __NR_tgkill 234
__SYSCALL(__NR_tgkill, sys_tgkill)
#define __NR_utimes 235
__SYSCALL(__NR_utimes, sys_utimes)
#define __NR_syscall_max __NR_epoll_ctl #define __NR_syscall_max __NR_utimes
#ifndef __NO_STUBS #ifndef __NO_STUBS
/* user-visible error numbers are in the range -1 - -4095 */ /* user-visible error numbers are in the range -1 - -4095 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment