Commit ab4a3042 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86-64 merge

Mainly lots of bug fixes and a few minor features. One change is that
it uses drivers/Kconfig now like i386. This requires a few minor changes in
outside Kconfig files which I am sending separately.

 - Tighten/fix some code in NUMA node discovery
 - Fix oopses in threaded 32bit coredumps and read correct registers.
 - Merge with 2.6.2rc1
 - Sync arch/x86_64/Kconfig with i386. Uses drivers/Kconfig now.
 - Remove bcopy export
 - Fix check for signal stack for 32bit signals
 - Fix bcopy and exit prototypes for gcc 3.4
 - Fix asm contraint in usercopy.c for gcc 3.4
 - Use rt_sigreturn, not sigreturn for rt sigreturns.
 - Pass si_fault address to 32bit
 - Truncate si_error to 16bit in 32bit emulation to match i386
 - Move IA32 flag switching for 32bit executables to flush_thread
   (code copied from ppc64/sparc64)
 - Print exception trace for strace too, share code.
 - Default to 3GB address space for a.out executables
 - Fix security hole in ptrace. Also fixes some problems with 32bit gdb.
 - Sync mmap address selection algorithm with mm/mmap.c version
 - Disable a.out coredumps completely
 - Fix bug in sigaltstack 32bit emulation. Kylix IDE now works.
 - Move errata 93/BIOS workaround into fault handler.  This should work
   around USB legacy BIOS bugs too, although not completely (we cannot fix
   faults injected by SMM into user space 64bit processes)
 - Quieten some unimplemented 32bit syscall warnings and avoid repeated
   warnings.
 - Set LDT segment limit correctly (fixes problems with some modify_ldt
   user)
 - Remove obsolete ldt rw lock.
 - Remove sys32_modify_ldt. The standard sys_modify_ldt is equivalent.
 - Remove traces of old kgdb support
 - Merge CFI changes from Jim Houston and some other smaller changes The
   kernel assembly functions are described with dwarf2 unwind
   information now, which makes it easier for debuggers to make sense of
   stack backtraces.  The code is only enabled with CONFIG_DEBUG_INFO.
   Note this implies that when you use CONFIG_DEBUG_INFO you may need
   an binutils update.
 - defconfig updated
 - Readd sleep support code (Pavel Machek)
 - Drop fusion and flush workarounds from IOMMU code
 - Add iommu=nofullflush option
 - Rewrite 32bit emulation for siginfo conversion (Joe Korty)
 - Allow remapping of scatterlists after unmap. This fixes some problems
   with the SCSI layer retrying previously mapped sg lists when iommu
   merging was enabled (it's disabled now by default)
 - Port HPET rtc device emulation code from i386
parent c0ade016
......@@ -68,6 +68,9 @@ config HPET_TIMER
If unsure, say Y.
config HPET_EMULATE_RTC
def_bool HPET_TIMER && RTC=y
config GENERIC_ISA_DMA
bool
default y
......@@ -271,51 +274,7 @@ endmenu
menu "Power management options"
config PM
bool "Power Management support"
---help---
"Power Management" means that parts of your computer are shut
off or put into a power conserving "sleep" mode if they are not
being used. There are two competing standards for doing this: APM
and ACPI. If you want to use either one, say Y here and then also
to the requisite support below.
Power Management is most important for battery powered laptop
computers.
Note that, even if you say N here, Linux on the x86 architecture
will issue the hlt instruction if nothing is to be done, thereby
sending the processor to limited sleep and saving power. However
using ACPI will likely save more power.
config SOFTWARE_SUSPEND
bool "Software Suspend (EXPERIMENTAL)"
depends on EXPERIMENTAL && PM && SWAP
---help---
Enable the possibilty of suspending the machine. It doesn't need APM.
You may suspend your machine by 'swsusp' or 'shutdown -z <time>'
(patch for sysvinit needed).
It creates an image which is saved in your active swaps. On the next
boot, pass the 'resume=/path/to/your/swap/file' option and the kernel
will detect the saved image, restore the memory from
it, and then continue to run as before you suspended.
If you don't want the previous state to continue, use the 'noresume'
kernel option. However, note that your partitions will be fsck'd and
you must re-mkswap your swap partitions/files.
Right now you may boot without resuming and then later resume but
in the meantime you cannot use those swap partitions/files which were
involved in suspending. Also in this case there is a risk that buffers
on disk won't match with saved ones.
SMP is supported ``as-is''. There's code for it but doesn't work.
There have been problems reported relating to SCSI.
This option is close to getting stable. However there is still some
absence of features.
For more information take a look at Documentation/power/swsusp.txt.
source kernel/power/Kconfig
source "drivers/acpi/Kconfig"
......@@ -336,8 +295,23 @@ config PCI_DIRECT
# the drivers/pci/msi.c code needs to be fixed first before enabling
config PCI_USE_VECTOR
bool
bool "Vector-based interrupt indexing"
depends on X86_LOCAL_APIC && NOTWORKING
default n
help
This replaces the current existing IRQ-based index interrupt scheme
with the vector-base index scheme. The advantages of vector base
over IRQ base are listed below:
1) Support MSI implementation.
2) Support future IOxAPIC hotplug
Note that this enables MSI, Message Signaled Interrupt, on all
MSI capable device functions detected if users also install the
MSI patch. Message Signal Interrupt enables an MSI-capable
hardware device to send an inbound Memory Write on its PCI bus
instead of asserting IRQ signal on device IRQ pin.
If you don't know what to do here, say N.
source "drivers/pci/Kconfig"
......@@ -396,51 +370,9 @@ config UID16
endmenu
source "drivers/base/Kconfig"
source "drivers/mtd/Kconfig"
source "drivers/parport/Kconfig"
source "drivers/block/Kconfig"
source "drivers/ide/Kconfig"
source "drivers/scsi/Kconfig"
source "drivers/md/Kconfig"
source "drivers/telephony/Kconfig"
source "drivers/message/fusion/Kconfig"
source "drivers/ieee1394/Kconfig"
#Currently not 64-bit safe
#source drivers/message/i2o/Config.in
source "net/Kconfig"
source "drivers/isdn/Kconfig"
# no support for non IDE/SCSI cdroms as they were all ISA only
#
# input before char - char/joystick depends on it. As does USB.
#
source "drivers/input/Kconfig"
source "drivers/char/Kconfig"
source "drivers/misc/Kconfig"
source "drivers/media/Kconfig"
source "fs/Kconfig"
source "drivers/video/Kconfig"
source "sound/Kconfig"
source drivers/Kconfig
source "drivers/usb/Kconfig"
source fs/Kconfig
source "arch/x86_64/oprofile/Kconfig"
......@@ -505,6 +437,7 @@ config DEBUG_INFO
If you say Y here the resulting kernel image will include
debugging info resulting in a larger kernel image.
Say Y here only if you plan to use gdb to debug the kernel.
Please note that this option requires new binutils.
If you don't debug the kernel, you can say N.
config FRAME_POINTER
......
......@@ -49,7 +49,7 @@ CFLAGS += -fno-reorder-blocks
# CFLAGS += -finline-limit=2000
CFLAGS += -Wno-sign-compare
# don't enable this when you use kgdb:
ifneq ($(CONFIG_X86_REMOTE_DEBUG),y)
ifneq ($(CONFIG_DEBUG_INFO),y)
CFLAGS += -fno-asynchronous-unwind-tables
endif
#CFLAGS += $(call check_gcc,-funit-at-a-time,)
......
......@@ -9,6 +9,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_GENERIC_ISA_DMA=y
#
......@@ -26,7 +27,8 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=18
# CONFIG_IKCONFIG is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_FUTEX=y
......@@ -34,6 +36,7 @@ CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
#
# Loadable module support
......@@ -59,7 +62,6 @@ CONFIG_X86_CPUID=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_MTRR=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_SMP=y
# CONFIG_PREEMPT is not set
CONFIG_K8_NUMA=y
......@@ -79,9 +81,9 @@ CONFIG_SOFTWARE_SUSPEND=y
#
# ACPI (Advanced Configuration and Power Interface) Support
#
# CONFIG_ACPI_HT is not set
CONFIG_ACPI=y
CONFIG_ACPI_BOOT=y
CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SLEEP_PROC_FS=y
CONFIG_ACPI_AC=y
......@@ -94,17 +96,23 @@ CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_TOSHIBA=y
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_BUS=y
CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_ACPI_RELAXED_AML is not set
#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
# CONFIG_PCI_USE_VECTOR is not set
# CONFIG_PCI_LEGACY_PROC is not set
# CONFIG_PCI_NAMES is not set
# CONFIG_HOTPLUG is not set
......@@ -115,6 +123,7 @@ CONFIG_PCI_DIRECT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_IA32_EMULATION=y
# CONFIG_IA32_AOUT is not set
CONFIG_COMPAT=y
CONFIG_UID16=y
......@@ -179,7 +188,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
......@@ -246,6 +254,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
......@@ -260,7 +269,7 @@ CONFIG_SCSI_IPS=m
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
#
......@@ -313,7 +322,12 @@ CONFIG_IP_MULTICAST=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_IPV6 is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_NETFILTER is not set
......@@ -325,7 +339,9 @@ CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
......@@ -358,7 +374,7 @@ CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
......@@ -388,7 +404,6 @@ CONFIG_8139TOO=m
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
#
......@@ -421,10 +436,10 @@ CONFIG_TIGON3=y
# CONFIG_NET_RADIO is not set
#
# Token Ring devices (depends on LLC=y)
# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
#
......@@ -442,6 +457,11 @@ CONFIG_TIGON3=y
#
# CONFIG_IRDA is not set
#
# Bluetooth support
#
# CONFIG_BT is not set
#
# ISDN subsystem
#
......@@ -504,6 +524,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_ACPI is not set
CONFIG_SERIAL_8250_NR_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
......@@ -520,7 +541,11 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_I2C is not set
#
# I2C Hardware Sensors Mainboard support
# I2C Algorithms
#
#
# I2C Hardware Bus support
#
#
......@@ -549,7 +574,6 @@ CONFIG_RTC=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set
#
# Ftape, the floppy tape device driver
......@@ -559,6 +583,7 @@ CONFIG_AGP_AMD64=y
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
CONFIG_HANGCHECK_TIMER=y
#
......@@ -619,10 +644,13 @@ CONFIG_ISO9660_FS=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
#
......@@ -647,6 +675,7 @@ CONFIG_RAMFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V4 is not set
......@@ -669,6 +698,11 @@ CONFIG_SUNRPC=y
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
#
# Native Language Support
#
# CONFIG_NLS is not set
#
# Graphics support
#
......@@ -707,13 +741,15 @@ CONFIG_SOUND_PRIME=y
# CONFIG_SOUND_MAESTRO is not set
# CONFIG_SOUND_MAESTRO3 is not set
CONFIG_SOUND_ICH=y
# CONFIG_SOUND_RME96XX is not set
# CONFIG_SOUND_SONICVIBES is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_OSS is not set
# CONFIG_SOUND_ALI5455 is not set
# CONFIG_SOUND_FORTE is not set
# CONFIG_SOUND_RME96XX is not set
# CONFIG_SOUND_AD1980 is not set
#
......@@ -722,11 +758,6 @@ CONFIG_SOUND_ICH=y
# CONFIG_USB is not set
# CONFIG_USB_GADGET is not set
#
# Bluetooth support
#
# CONFIG_BT is not set
#
# Profiling support
#
......@@ -744,8 +775,6 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_FRAME_POINTER is not set
# CONFIG_IOMMU_DEBUG is not set
CONFIG_IOMMU_LEAK=y
CONFIG_MCE_DEBUG=y
#
# Security options
......@@ -760,4 +789,4 @@ CONFIG_MCE_DEBUG=y
#
# Library routines
#
# CONFIG_CRC32 is not set
CONFIG_CRC32=y
......@@ -33,11 +33,14 @@
#include <asm/user32.h>
#undef WARN_OLD
#undef CORE_DUMP /* probably broken */
extern int ia32_setup_arg_pages(struct linux_binprm *bprm);
static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout_library(struct file*);
#if CORE_DUMP
static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
/*
......@@ -92,11 +95,15 @@ static void dump_thread32(struct pt_regs * regs, struct user32 * dump)
#endif
}
#endif
static struct linux_binfmt aout_format = {
.module = THIS_MODULE,
.load_binary = load_aout_binary,
.load_shlib = load_aout_library,
#if CORE_DUMP
.core_dump = aout_core_dump,
#endif
.min_coredump = PAGE_SIZE
};
......@@ -109,6 +116,7 @@ static void set_brk(unsigned long start, unsigned long end)
do_brk(start, end - start);
}
#if CORE_DUMP
/*
* These are the only things you should do on a core-file: use only these
* macros to write out all the necessary info.
......@@ -201,6 +209,7 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
set_fs(fs);
return has_dumped;
}
#endif
/*
* create_aout_tables() parses the env- and arg-strings in new user
......@@ -285,10 +294,11 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
regs->cs = __USER32_CS;
regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
regs->r13 = regs->r14 = regs->r15 = 0;
set_thread_flag(TIF_IA32);
/* OK, This is the point of no return */
set_personality(PER_LINUX);
set_thread_flag(TIF_IA32);
clear_thread_flag(TIF_ABI_PENDING);
current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex));
......
......@@ -197,6 +197,7 @@ static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *re
static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
{
struct pt_regs *pp = (struct pt_regs *)(t->thread.rsp0);
--pp;
ELF_CORE_COPY_REGS((*elfregs), pp);
/* fix wrong segments */
(*elfregs)[7] = t->thread.ds;
......@@ -214,6 +215,8 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr
if (!tsk->used_math)
return 0;
if (!regs)
regs = (struct pt_regs *)tsk->thread.rsp0;
--regs;
if (tsk == current)
unlazy_fpu(tsk);
......@@ -250,6 +253,14 @@ elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
#define ELF_PLATFORM ("i686")
#define SET_PERSONALITY(ex, ibcs2) \
do { \
unsigned long new_flags = 0; \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
new_flags = _TIF_IA32; \
if ((current_thread_info()->flags & _TIF_IA32) \
!= new_flags) \
set_thread_flag(TIF_ABI_PENDING); \
else \
clear_thread_flag(TIF_ABI_PENDING); \
set_personality((ibcs2)?PER_SVR4:current->personality); \
} while (0)
......@@ -323,7 +334,6 @@ static void elf32_init(struct pt_regs *regs)
me->thread.gsindex = 0;
me->thread.ds = __USER_DS;
me->thread.es = __USER_DS;
set_thread_flag(TIF_IA32);
}
int setup_arg_pages(struct linux_binprm *bprm)
......@@ -392,7 +402,7 @@ elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
down_write(&me->mm->mmap_sem);
map_addr = do_mmap(filep, ELF_PAGESTART(addr),
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot,
type|MAP_32BIT,
type,
eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
up_write(&me->mm->mmap_sem);
return(map_addr);
......
......@@ -44,10 +44,10 @@
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
void signal_fault(struct pt_regs *regs, void *frame, char *where);
static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from)
{
int err;
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
return -EFAULT;
/* If you change siginfo_t structure, please make sure that
......@@ -55,21 +55,18 @@ static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
It should never copy any pad contained in the structure
to avoid security leaks, but must copy the generic
3 ints plus the relevant union member. */
if (from->si_code < 0) {
err = __put_user(from->si_signo, &to->si_signo);
err |= __put_user(from->si_errno, &to->si_errno);
err |= __put_user(from->si_code, &to->si_code);
err |= __put_user(from->_sifields._rt._pid, &to->_sifields._rt._pid);
err |= __put_user(from->_sifields._rt._uid, &to->_sifields._rt._uid);
err |= __put_user((u32)(u64)from->_sifields._rt._sigval.sival_ptr,
&to->_sifields._rt._sigval.sival_ptr);
} else {
err = __put_user(from->si_signo, &to->si_signo);
err |= __put_user(from->si_errno, &to->si_errno);
err |= __put_user(from->si_code, &to->si_code);
/* First 32bits of unions are always present. */
err |= __put_user((short)from->si_code, &to->si_code);
if (from->si_code < 0) {
err |= __put_user(from->si_pid, &to->si_pid);
err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr);
} else {
/* First 32bits of unions are always present:
* si_pid === si_band === si_tid === si_addr(LS half) */
err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]);
switch (from->si_code >> 16) {
case __SI_FAULT >> 16:
break;
......@@ -78,18 +75,39 @@ static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
err |= __put_user(from->si_stime, &to->si_stime);
err |= __put_user(from->si_status, &to->si_status);
default:
case __SI_KILL >> 16:
err |= __put_user(from->si_uid, &to->si_uid);
break;
case __SI_POLL >> 16:
err |= __put_user(from->si_band, &to->si_band);
err |= __put_user(from->si_fd, &to->si_fd);
break;
case __SI_TIMER >> 16:
err |= __put_user(from->si_overrun, &to->si_overrun);
err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr);
break;
/* case __SI_RT: This is not generated by the kernel as of now. */
}
}
return err;
}
int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from)
{
int err;
if (!access_ok (VERIFY_READ, from, sizeof(siginfo_t32)))
return -EFAULT;
err = __get_user(to->si_signo, &from->si_signo);
err |= __get_user(to->si_errno, &from->si_errno);
err |= __get_user(to->si_code, &from->si_code);
err |= __get_user(to->si_pid, &from->si_pid);
err |= __get_user(to->si_uid, &from->si_uid);
err |= __get_user((u32)(u64)to->si_ptr, &from->si_ptr);
return err;
}
asmlinkage long
sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs regs)
{
......@@ -134,9 +152,9 @@ sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr,
set_fs(seg);
if (ret >= 0 && uoss_ptr) {
if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
__put_user((u32)(u64)uss.ss_sp, &uoss_ptr->ss_sp) ||
__put_user(uss.ss_flags, &uoss_ptr->ss_flags) ||
__put_user(uss.ss_size, &uoss_ptr->ss_size))
__put_user((u32)(u64)uoss.ss_sp, &uoss_ptr->ss_sp) ||
__put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
__put_user(uoss.ss_size, &uoss_ptr->ss_size))
ret = -EFAULT;
}
return ret;
......@@ -376,7 +394,7 @@ ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
/*
* Determine which stack to use..
*/
static inline void *
static void *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
unsigned long rsp;
......@@ -386,7 +404,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (! on_sig_stack(rsp))
if (sas_ss_flags(rsp) == 0)
rsp = current->sas_ss_sp + current->sas_ss_size;
}
......
......@@ -4,6 +4,7 @@
* Copyright 2000-2002 Andi Kleen, SuSE Labs.
*/
#include <asm/dwarf2.h>
#include <asm/calling.h>
#include <asm/offset.h>
#include <asm/current.h>
......@@ -45,6 +46,7 @@
* with the int 0x80 path.
*/
ENTRY(ia32_cstar_target)
CFI_STARTPROC
swapgs
movl %esp,%r8d
movq %gs:pda_kernelstack,%rsp
......@@ -105,6 +107,7 @@ cstar_tracesys:
cstar_badarg:
movq $-EFAULT,%rax
jmp cstar_sysret
CFI_ENDPROC
/*
* Emulated IA32 system calls via int 0x80.
......@@ -128,6 +131,7 @@ cstar_badarg:
*/
ENTRY(ia32_syscall)
CFI_STARTPROC
swapgs
sti
movl %eax,%eax
......@@ -168,6 +172,7 @@ ni_syscall:
quiet_ni_syscall:
movq $-ENOSYS,%rax
ret
CFI_ENDPROC
.macro PTREGSCALL label, func
.globl \label
......@@ -188,6 +193,7 @@ quiet_ni_syscall:
PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
ENTRY(ia32_ptregs_common)
CFI_STARTPROC
popq %r11
SAVE_REST
movq %r11, %r15
......@@ -198,6 +204,7 @@ ENTRY(ia32_ptregs_common)
je int_ret_from_sys_call /* misbalances the call/ret stack. sorry */
pushq %r11
ret
CFI_ENDPROC
.data
.align 8
......@@ -326,7 +333,7 @@ ia32_sys_call_table:
.quad stub32_clone /* 120 */
.quad sys_setdomainname
.quad sys_uname
.quad sys32_modify_ldt
.quad sys_modify_ldt
.quad sys32_adjtimex
.quad sys32_mprotect /* 125 */
.quad compat_sys_sigprocmask
......@@ -334,10 +341,10 @@ ia32_sys_call_table:
.quad sys_init_module
.quad sys_delete_module
.quad quiet_ni_syscall /* 130 get_kernel_syms */
.quad ni_syscall /* quotactl */
.quad sys32_quotactl /* quotactl */
.quad sys_getpgid
.quad sys_fchdir
.quad ni_syscall /* bdflush */
.quad quiet_ni_syscall /* bdflush */
.quad sys_sysfs /* 135 */
.quad sys_personality
.quad ni_syscall /* for afs_syscall */
......@@ -425,8 +432,8 @@ ia32_sys_call_table:
.quad sys_madvise
.quad sys_getdents64 /* 220 getdents64 */
.quad compat_sys_fcntl64
.quad sys_ni_syscall /* tux */
.quad sys_ni_syscall /* security */
.quad quiet_ni_syscall /* tux */
.quad quiet_ni_syscall /* security */
.quad sys_gettid
.quad sys_readahead /* 225 */
.quad sys_setxattr
......@@ -454,7 +461,7 @@ ia32_sys_call_table:
.quad sys32_io_submit
.quad sys_io_cancel
.quad sys_fadvise64
.quad sys_ni_syscall /* free_huge_pages */
.quad quiet_ni_syscall /* free_huge_pages */
.quad sys_exit_group /* exit_group */
.quad sys_lookup_dcookie
.quad sys_epoll_create
......
......@@ -858,8 +858,13 @@ sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
int sys32_ni_syscall(int call)
{
struct task_struct *me = current;
static char lastcomm[8];
if (strcmp(lastcomm, me->comm)) {
printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call,
current->comm);
strcpy(lastcomm, me->comm);
}
return -ENOSYS;
}
......@@ -1022,84 +1027,6 @@ sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
return ret;
}
siginfo_t32 *
siginfo64to32(siginfo_t32 *d, siginfo_t *s)
{
memset (d, 0, sizeof(siginfo_t32));
d->si_signo = s->si_signo;
d->si_errno = s->si_errno;
d->si_code = s->si_code;
if (s->si_signo >= SIGRTMIN) {
d->si_pid = s->si_pid;
d->si_uid = s->si_uid;
memcpy(&d->si_int, &s->si_int,
sizeof(siginfo_t) - offsetof(siginfo_t,si_int));
} else switch (s->si_signo) {
/* XXX: What about POSIX1.b timers */
case SIGCHLD:
d->si_pid = s->si_pid;
d->si_status = s->si_status;
d->si_utime = s->si_utime;
d->si_stime = s->si_stime;
break;
case SIGSEGV:
case SIGBUS:
case SIGFPE:
case SIGILL:
d->si_addr = (long)(s->si_addr);
// d->si_trapno = s->si_trapno;
break;
case SIGPOLL:
d->si_band = s->si_band;
d->si_fd = s->si_fd;
break;
default:
d->si_pid = s->si_pid;
d->si_uid = s->si_uid;
break;
}
return d;
}
siginfo_t *
siginfo32to64(siginfo_t *d, siginfo_t32 *s)
{
d->si_signo = s->si_signo;
d->si_errno = s->si_errno;
d->si_code = s->si_code;
if (s->si_signo >= SIGRTMIN) {
d->si_pid = s->si_pid;
d->si_uid = s->si_uid;
memcpy(&d->si_int,
&s->si_int,
sizeof(siginfo_t) - offsetof(siginfo_t, si_int));
} else switch (s->si_signo) {
/* XXX: What about POSIX1.b timers */
case SIGCHLD:
d->si_pid = s->si_pid;
d->si_status = s->si_status;
d->si_utime = s->si_utime;
d->si_stime = s->si_stime;
break;
case SIGSEGV:
case SIGBUS:
case SIGFPE:
case SIGILL:
d->si_addr = (void *)A(s->si_addr);
// d->si_trapno = s->si_trapno;
break;
case SIGPOLL:
d->si_band = s->si_band;
d->si_fd = s->si_fd;
break;
default:
d->si_pid = s->si_pid;
d->si_uid = s->si_uid;
break;
}
return d;
}
extern asmlinkage long
sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
const struct timespec *uts, size_t sigsetsize);
......@@ -1114,7 +1041,6 @@ sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
int ret;
mm_segment_t old_fs = get_fs();
siginfo_t info;
siginfo_t32 info32;
if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t)))
return -EFAULT;
......@@ -1126,13 +1052,18 @@ sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
}
if (uts && get_compat_timespec(&t, uts))
return -EFAULT;
if (uinfo) {
/* stop data leak to user space in case of structure fill mismatch
* between sys_rt_sigtimedwait & ia32_copy_siginfo_to_user.
*/
memset(&info, 0, sizeof(info));
}
set_fs (KERNEL_DS);
ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
sigsetsize);
set_fs (old_fs);
if (ret >= 0 && uinfo) {
if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
sizeof(siginfo_t32)))
if (ia32_copy_siginfo_to_user(uinfo, &info))
return -EFAULT;
}
return ret;
......@@ -1145,14 +1076,11 @@ asmlinkage long
sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
{
siginfo_t info;
siginfo_t32 info32;
int ret;
mm_segment_t old_fs = get_fs();
if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))
if (ia32_copy_siginfo_from_user(&info, uinfo))
return -EFAULT;
/* XXX: Is this correct? */
siginfo32to64(&info, &info32);
set_fs (KERNEL_DS);
ret = sys_rt_sigqueueinfo(pid, sig, &info);
set_fs (old_fs);
......@@ -1289,31 +1217,6 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
return ret;
}
extern asmlinkage long sys_modify_ldt(int func, void *ptr,
unsigned long bytecount);
asmlinkage long sys32_modify_ldt(int func, void *ptr, unsigned long bytecount)
{
long ret;
if (func == 0x1 || func == 0x11) {
struct user_desc info;
mm_segment_t old_fs = get_fs();
if (bytecount != sizeof(struct user_desc))
return -EINVAL;
if (copy_from_user(&info, ptr, sizeof(struct user_desc)))
return -EFAULT;
/* lm bit was undefined in the 32bit ABI and programs
give it random values. Force it to zero here. */
info.lm = 0;
set_fs(KERNEL_DS);
ret = sys_modify_ldt(func, &info, bytecount);
set_fs(old_fs);
} else {
ret = sys_modify_ldt(func, ptr, bytecount);
}
return ret;
}
/* Handle adjtimex compatibility. */
struct timex32 {
......@@ -2007,6 +1910,18 @@ long sys32_vm86_warning(void)
return -ENOSYS;
}
long sys32_quotactl(void)
{
struct task_struct *me = current;
static char lastcomm[8];
if (strcmp(lastcomm, me->comm)) {
printk(KERN_INFO "%s: 32bit quotactl not supported on 64 bit kernel\n",
me->comm);
strcpy(lastcomm, me->comm);
}
return -ENOSYS;
}
struct exec_domain ia32_exec_domain = {
.name = "linux/x86",
.pers_low = PER_LINUX32,
......
......@@ -56,6 +56,7 @@
/* address in low memory of the wakeup routine. */
unsigned long acpi_wakeup_address = 0;
unsigned long acpi_video_flags;
extern char wakeup_start, wakeup_end;
extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
......@@ -116,6 +117,22 @@ void __init acpi_reserve_bootmem(void)
printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
}
static int __init acpi_sleep_setup(char *str)
{
while ((str != NULL) && (*str != '\0')) {
if (strncmp(str, "s3_bios", 7) == 0)
acpi_video_flags = 1;
if (strncmp(str, "s3_mode", 7) == 0)
acpi_video_flags |= 2;
str = strchr(str, ',');
if (str != NULL)
str += strspn(str, ", \t");
}
return 1;
}
__setup("acpi_sleep=", acpi_sleep_setup);
#endif /*CONFIG_ACPI_SLEEP*/
void acpi_pci_link_exit(void) {}
......@@ -41,7 +41,19 @@ wakeup_code:
cmpl $0x12345678, %eax
jne bogus_real_magic
testl $1, video_flags - wakeup_code
jz 1f
lcall $0xc000,$3
movw %cs, %ax
movw %ax, %ds # Bios might have played with that
movw %ax, %ss
1:
testl $2, video_flags - wakeup_code
jz 1f
mov video_mode - wakeup_code, %ax
call mode_seta
1:
movw $0xb800, %ax
movw %ax,%fs
......@@ -250,6 +262,7 @@ real_save_gdt: .word 0
.quad 0
real_magic: .quad 0
video_mode: .quad 0
video_flags: .quad 0
bogus_real_magic:
movb $0xba,%al ; outb %al,$0x80
......@@ -382,8 +395,10 @@ ENTRY(acpi_copy_wakeup_routine)
movl %eax, saved_efer
movl %edx, saved_efer2
# movq saved_videomode, %rdx # FIXME: videomode
movq %rdx, video_mode - wakeup_start (,%rdi)
movl saved_video_mode, %edx
movl %edx, video_mode - wakeup_start (,%rdi)
movl acpi_video_flags, %edx
movl %edx, video_flags - wakeup_start (,%rdi)
movq $0x12345678, real_magic - wakeup_start (,%rdi)
movq $0x123456789abcdef0, %rdx
movq %rdx, saved_magic
......
......@@ -34,6 +34,7 @@
#include <asm/smp.h>
#include <asm/cache.h>
#include <asm/errno.h>
#include <asm/dwarf2.h>
#include <asm/calling.h>
#include <asm/offset.h>
#include <asm/msr.h>
......@@ -41,7 +42,6 @@
#include <asm/thread_info.h>
#include <asm/hw_irq.h>
#include <asm/errno.h>
#include <asm/dwarf2.h>
.code64
......@@ -82,22 +82,53 @@
/* push in order ss, rsp, eflags, cs, rip */
xorq %rax, %rax
pushq %rax /* ss */
CFI_ADJUST_CFA_OFFSET 8
pushq %rax /* rsp */
CFI_ADJUST_CFA_OFFSET 8
CFI_OFFSET rip,0
pushq $(1<<9) /* eflags - interrupts on */
CFI_ADJUST_CFA_OFFSET 8
pushq $__KERNEL_CS /* cs */
CFI_ADJUST_CFA_OFFSET 8
pushq \child_rip /* rip */
CFI_ADJUST_CFA_OFFSET 8
CFI_OFFSET rip,0
pushq %rax /* orig rax */
CFI_ADJUST_CFA_OFFSET 8
.endm
.macro UNFAKE_STACK_FRAME
addq $8*6, %rsp
CFI_ADJUST_CFA_OFFSET -(6*8)
.endm
.macro CFI_DEFAULT_STACK
CFI_ADJUST_CFA_OFFSET (SS)
CFI_OFFSET r15,R15-SS
CFI_OFFSET r14,R14-SS
CFI_OFFSET r13,R13-SS
CFI_OFFSET r12,R12-SS
CFI_OFFSET rbp,RBP-SS
CFI_OFFSET rbx,RBX-SS
CFI_OFFSET r11,R11-SS
CFI_OFFSET r10,R10-SS
CFI_OFFSET r9,R9-SS
CFI_OFFSET r8,R8-SS
CFI_OFFSET rax,RAX-SS
CFI_OFFSET rcx,RCX-SS
CFI_OFFSET rdx,RDX-SS
CFI_OFFSET rsi,RSI-SS
CFI_OFFSET rdi,RDI-SS
CFI_OFFSET rsp,RSP-SS
CFI_OFFSET rip,RIP-SS
.endm
/*
* A newly forked process directly context switches into this.
*/
/* rdi: prev */
ENTRY(ret_from_fork)
CFI_STARTPROC
CFI_DEFAULT_STACK
call schedule_tail
GET_THREAD_INFO(%rcx)
bt $TIF_SYSCALL_TRACE,threadinfo_flags(%rcx)
......@@ -115,6 +146,7 @@ rff_trace:
call syscall_trace
GET_THREAD_INFO(%rcx)
jmp rff_action
CFI_ENDPROC
/*
* System call entry. Upto 6 arguments in registers are supported.
......@@ -144,6 +176,7 @@ rff_trace:
*/
ENTRY(system_call)
CFI_STARTPROC
swapgs
movq %rsp,%gs:pda_oldrsp
movq %gs:pda_kernelstack,%rsp
......@@ -283,6 +316,7 @@ int_signal:
int_restore_rest:
RESTORE_REST
jmp int_with_check
CFI_ENDPROC
/*
* Certain special system calls that need to save a complete full stack frame.
......@@ -303,7 +337,9 @@ int_restore_rest:
PTREGSCALL stub_iopl, sys_iopl
ENTRY(ptregscall_common)
CFI_STARTPROC
popq %r11
CFI_ADJUST_CFA_OFFSET -8
SAVE_REST
movq %r11, %r15
FIXUP_TOP_OF_STACK %r11
......@@ -312,10 +348,14 @@ ENTRY(ptregscall_common)
movq %r15, %r11
RESTORE_REST
pushq %r11
CFI_ADJUST_CFA_OFFSET 8
ret
CFI_ENDPROC
ENTRY(stub_execve)
CFI_STARTPROC
popq %r11
CFI_ADJUST_CFA_OFFSET -8
SAVE_REST
movq %r11, %r15
FIXUP_TOP_OF_STACK %r11
......@@ -330,15 +370,18 @@ ENTRY(stub_execve)
ret
exec_32bit:
CFI_ADJUST_CFA_OFFSET REST_SKIP
movq %rax,RAX(%rsp)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
/*
* sigreturn is special because it needs to restore all registers on return.
* This cannot be done with SYSRET, so use the IRET return path instead.
*/
ENTRY(stub_rt_sigreturn)
CFI_STARTPROC
addq $8, %rsp
SAVE_REST
FIXUP_TOP_OF_STACK %r11
......@@ -346,6 +389,7 @@ ENTRY(stub_rt_sigreturn)
movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
/*
* Interrupt entry/exit.
......@@ -357,10 +401,20 @@ ENTRY(stub_rt_sigreturn)
/* 0(%rsp): interrupt number */
.macro interrupt func
CFI_STARTPROC simple
CFI_DEF_CFA rsp,(SS-ORIG_RAX)
CFI_OFFSET rsp,(RSP-SS)
CFI_OFFSET rip,(RIP-SS)
cld
#ifdef CONFIG_X86_REMOTE_DEBUG
#ifdef CONFIG_DEBUG_INFO
SAVE_ALL
movq %rsp,%rdi
/*
* Setup a stack frame pointer. This allows gdb to trace
* back to the original stack.
*/
movq %rsp,%rbp
CFI_DEF_CFA_REGISTER rbp
#else
SAVE_ARGS
leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler
......@@ -382,6 +436,9 @@ ret_from_intr:
popq %rdi
cli
subl $1,%gs:pda_irqcount
#ifdef CONFIG_KGDB
movq RBP(%rdi),%rbp
#endif
leaq ARGOFFSET(%rdi),%rsp
exit_intr:
GET_THREAD_INFO(%rcx)
......@@ -465,6 +522,7 @@ retint_kernel:
movl $0,threadinfo_preempt_count(%rcx)
jmp exit_intr
#endif
CFI_ENDPROC
/*
* APIC interrupts.
......@@ -473,6 +531,7 @@ retint_kernel:
pushq $\num-256
interrupt \func
jmp ret_from_intr
CFI_ENDPROC
.endm
#ifdef CONFIG_SMP
......@@ -518,24 +577,43 @@ ENTRY(spurious_interrupt)
* and the exception handler in %rax.
*/
ENTRY(error_entry)
CFI_STARTPROC simple
CFI_DEF_CFA rsp,(SS-RDI)
CFI_REL_OFFSET rsp,(RSP-RDI)
CFI_REL_OFFSET rip,(RIP-RDI)
/* rdi slot contains rax, oldrax contains error code */
cld
subq $14*8,%rsp
CFI_ADJUST_CFA_OFFSET (14*8)
movq %rsi,13*8(%rsp)
CFI_REL_OFFSET rsi,RSI
movq 14*8(%rsp),%rsi /* load rax from rdi slot */
movq %rdx,12*8(%rsp)
CFI_REL_OFFSET rdx,RDX
movq %rcx,11*8(%rsp)
CFI_REL_OFFSET rcx,RCX
movq %rsi,10*8(%rsp) /* store rax */
CFI_REL_OFFSET rax,RAX
movq %r8, 9*8(%rsp)
CFI_REL_OFFSET r8,R8
movq %r9, 8*8(%rsp)
CFI_REL_OFFSET r9,R9
movq %r10,7*8(%rsp)
CFI_REL_OFFSET r10,R10
movq %r11,6*8(%rsp)
CFI_REL_OFFSET r11,R11
movq %rbx,5*8(%rsp)
CFI_REL_OFFSET rbx,RBX
movq %rbp,4*8(%rsp)
CFI_REL_OFFSET rbp,RBP
movq %r12,3*8(%rsp)
CFI_REL_OFFSET r12,R12
movq %r13,2*8(%rsp)
CFI_REL_OFFSET r13,R13
movq %r14,1*8(%rsp)
CFI_REL_OFFSET r14,R14
movq %r15,(%rsp)
CFI_REL_OFFSET r15,R15
xorl %ebx,%ebx
testl $3,CS(%rsp)
je error_kernelspace
......@@ -561,6 +639,7 @@ error_exit:
swapgs
RESTORE_ARGS 0,8,0
iretq
CFI_ENDPROC
error_kernelspace:
incl %ebx
......@@ -615,6 +694,7 @@ bad_gs:
* rdi: fn, rsi: arg, rdx: flags
*/
ENTRY(kernel_thread)
CFI_STARTPROC
FAKE_STACK_FRAME $child_rip
SAVE_ALL
......@@ -642,6 +722,8 @@ ENTRY(kernel_thread)
RESTORE_ALL
UNFAKE_STACK_FRAME
ret
CFI_ENDPROC
child_rip:
/*
......@@ -671,6 +753,7 @@ child_rip:
* rdi: name, rsi: argv, rdx: envp, fake frame on the stack
*/
ENTRY(execve)
CFI_STARTPROC
FAKE_STACK_FRAME $0
SAVE_ALL
call sys_execve
......@@ -681,6 +764,7 @@ ENTRY(execve)
RESTORE_ARGS
UNFAKE_STACK_FRAME
ret
CFI_ENDPROC
ENTRY(page_fault)
errorentry do_page_fault
......@@ -692,6 +776,7 @@ ENTRY(simd_coprocessor_error)
zeroentry do_simd_coprocessor_error
ENTRY(device_not_available)
CFI_STARTPROC
pushq $-1 #error code
SAVE_ALL
movl $1,%ebx
......@@ -706,11 +791,13 @@ ENTRY(device_not_available)
cmoveq %rcx,%rdx
call *%rdx
jmp error_exit
CFI_ENDPROC
ENTRY(debug)
zeroentry do_debug
ENTRY(nmi)
CFI_STARTPROC
pushq $-1
SAVE_ALL
/* NMI could happen inside the critical section of a swapgs,
......@@ -731,6 +818,7 @@ ENTRY(nmi)
swapgs
2: RESTORE_ALL 8
iretq
CFI_ENDPROC
ENTRY(int3)
zeroentry do_int3
......
......@@ -46,11 +46,6 @@ void __init fpu_init(void)
current->used_math = 0;
}
/*
* The _current_ task is using the FPU for the first time
* so initialize it and set the mxcsr to its default.
* remember the current task has used the FPU.
*/
void init_fpu(struct task_struct *child)
{
if (child->used_math) {
......
......@@ -107,7 +107,6 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
retval = copy_ldt(&mm->context, &old_mm->context);
up(&old_mm->context.sem);
}
rwlock_init(&mm->context.ldtlock);
return retval;
}
......@@ -216,10 +215,8 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
/* Install the new entry ... */
install:
write_lock(&mm->context.ldtlock);
*lp = entry_1;
*(lp+1) = entry_2;
write_unlock(&mm->context.ldtlock);
error = 0;
out_unlock:
......
......@@ -35,6 +35,7 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
BUG_ON(!s->page);
s->dma_address = pci_map_page(hwdev, s->page, s->offset,
s->length, direction);
s->dma_length = s->length;
}
return nents;
}
......@@ -53,7 +54,7 @@ void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg,
struct scatterlist *s = &sg[i];
BUG_ON(s->page == NULL);
BUG_ON(s->dma_address == 0);
pci_unmap_single(dev, s->dma_address, s->length, dir);
pci_unmap_single(dev, s->dma_address, s->dma_length, dir);
}
}
......
......@@ -382,10 +382,12 @@ static int pci_map_sg_nonforce(struct pci_dev *dev, struct scatterlist *sg,
if (i > 0)
pci_unmap_sg(dev, sg, i, dir);
nents = 0;
sg[0].dma_length = 0;
break;
}
}
s->dma_address = addr;
s->dma_length = s->length;
}
flush_gart(dev);
return nents;
......@@ -412,8 +414,9 @@ static int __pci_map_cont(struct scatterlist *sg, int start, int stopat,
*sout = *s;
sout->dma_address = iommu_bus_base;
sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
sout->dma_length = s->length;
} else {
sout->length += s->length;
sout->dma_length += s->length;
}
addr = phys_addr;
......@@ -436,6 +439,7 @@ static inline int pci_map_cont(struct scatterlist *sg, int start, int stopat,
if (!need) {
BUG_ON(stopat - start != 1);
*sout = sg[start];
sout->dma_length = sg[start].length;
return 0;
}
return __pci_map_cont(sg, start, stopat, sout, pages);
......@@ -453,8 +457,6 @@ int pci_map_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, int dir)
unsigned long pages = 0;
int need = 0, nextneed;
unsigned long size = 0;
BUG_ON(dir == PCI_DMA_NONE);
if (nents == 0)
return 0;
......@@ -466,7 +468,6 @@ int pci_map_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, int dir)
s->dma_address = addr;
BUG_ON(s->length == 0);
size += s->length;
nextneed = need_iommu(dev, addr, s->length);
/* Handle the previous not yet processed entries */
......@@ -493,7 +494,7 @@ int pci_map_sg(struct pci_dev *dev, struct scatterlist *sg, int nents, int dir)
out++;
flush_gart(dev);
if (out < nents)
sg[out].length = 0;
sg[out].dma_length = 0;
return out;
error:
......@@ -540,9 +541,9 @@ void pci_unmap_sg(struct pci_dev *dev, struct scatterlist *sg, int nents,
int i;
for (i = 0; i < nents; i++) {
struct scatterlist *s = &sg[i];
if (!s->length)
if (!s->dma_length || !s->length)
break;
pci_unmap_single(dev, s->dma_address, s->length, dir);
pci_unmap_single(dev, s->dma_address, s->dma_length, dir);
}
}
......@@ -800,7 +801,8 @@ fs_initcall(pci_iommu_init);
merge Do SG merging. Implies force (experimental)
nomerge Don't do SG merging.
forcesac For SAC mode for masks <40bits (experimental)
fullflush Flush IOMMU on each allocation (for testing)
fullflush Flush IOMMU on each allocation (default)
nofullflush Don't use IOMMU fullflush
*/
__init int iommu_setup(char *opt)
{
......@@ -838,6 +840,8 @@ __init int iommu_setup(char *opt)
iommu_sac_force = 1;
if (!memcmp(p, "fullflush", 9))
iommu_fullflush = 1;
if (!memcmp(p, "nofullflush", 11))
iommu_fullflush = 0;
#ifdef CONFIG_IOMMU_LEAK
if (!memcmp(p,"leak", 4)) {
leak_trace = 1;
......
......@@ -152,20 +152,6 @@ static int __init idle_setup (char *str)
__setup("idle=", idle_setup);
void idle_warning(void)
{
static int warned;
if (warned)
return;
warned = 1;
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
BUG();
printk(KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n");
printk(KERN_ERR "******* Working around it, but it will cost you a lot of power\n");
printk(KERN_ERR "******* Please consider a BIOS update.\n");
printk(KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n");
}
/* Prints also some state that isn't saved in the pt_regs */
void __show_regs(struct pt_regs * regs)
{
......@@ -234,6 +220,10 @@ void exit_thread(void)
void flush_thread(void)
{
struct task_struct *tsk = current;
struct thread_info *t = current_thread_info();
if (t->flags & _TIF_ABI_PENDING)
t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
tsk->thread.debugreg0 = 0;
tsk->thread.debugreg1 = 0;
......@@ -440,7 +430,6 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *
write_pda(pcurrent, next_p);
write_pda(kernelstack, (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET);
/*
* Now maybe reload the debug registers
*/
......
......@@ -65,43 +65,78 @@ long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigne
return error;
}
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
static void find_start_end(unsigned long flags, unsigned long *begin,
unsigned long *end)
{
struct vm_area_struct *vma;
unsigned long end = TASK_SIZE;
#ifdef CONFIG_IA32_EMULATION
if (test_thread_flag(TIF_IA32)) {
if (!addr)
addr = TASK_UNMAPPED_32;
end = IA32_PAGE_OFFSET;
*begin = TASK_UNMAPPED_32;
*end = IA32_PAGE_OFFSET;
} else
#endif
if (flags & MAP_32BIT) {
/* This is usually used needed to map code in small model, so it needs to
be in the first 31bit. Limit it to that.
This means we need to move the unmapped base down for this case. This can
give conflicts with the heap, but we assume that glibc malloc knows how
to fall back to mmap. Give it 1GB of playground for now. -AK */
if (!addr)
addr = 0x40000000;
end = 0x80000000;
/* This is usually used needed to map code in small
model, so it needs to be in the first 31bit. Limit
it to that. This means we need to move the
unmapped base down for this case. This can give
conflicts with the heap, but we assume that glibc
malloc knows how to fall back to mmap. Give it 1GB
of playground for now. -AK */
*begin = 0x40000000;
*end = 0x80000000;
} else {
if (!addr)
addr = TASK_UNMAPPED_64;
end = TASK_SIZE;
*begin = TASK_UNMAPPED_64;
*end = TASK_SIZE;
}
}
unsigned long
arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long start_addr;
unsigned long begin, end;
find_start_end(flags, &begin, &end);
if (len > end)
return -ENOMEM;
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
if (end - len >= addr &&
(!vma || addr + len <= vma->vm_start))
return addr;
}
addr = mm->free_area_cache;
if (addr < begin)
addr = begin;
start_addr = addr;
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
full_search:
for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
/* At this point: (!vma || addr < vma->vm_end). */
if (end - len < addr)
if (end - len < addr) {
/*
* Start a new search - just in case we missed
* some holes.
*/
if (start_addr != begin) {
start_addr = addr = begin;
goto full_search;
}
return -ENOMEM;
if (!vma || addr + len <= vma->vm_start)
}
if (!vma || addr + len <= vma->vm_start) {
/*
* Remember the place where we stopped the search:
*/
mm->free_area_cache = addr + len;
return addr;
}
addr = vma->vm_end;
}
}
......
......@@ -10,6 +10,7 @@
* Copyright (c) 1998 Andrea Arcangeli
* Copyright (c) 2002 Vojtech Pavlik
* Copyright (c) 2003 Andi Kleen
* RTC support code taken from arch/i386/kernel/timers/time_hpet.c
*
*/
......@@ -28,6 +29,7 @@
#include <asm/vsyscall.h>
#include <asm/timex.h>
#include <asm/proto.h>
#include <asm/hpet.h>
#include <linux/cpufreq.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/apic.h>
......@@ -627,10 +629,10 @@ static int hpet_init(void)
* and period also hpet_tick.
*/
hpet_writel(HPET_T0_ENABLE | HPET_T0_PERIODIC | HPET_T0_SETVAL |
HPET_T0_32BIT, HPET_T0_CFG);
hpet_writel(hpet_tick, HPET_T0_CMP);
hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
HPET_TN_32BIT, HPET_T0_CFG);
hpet_writel(hpet_tick, HPET_T0_CMP);
hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */
/*
* Go!
......@@ -733,3 +735,229 @@ void __init time_init_smp(void)
}
__setup("report_lost_ticks", time_setup);
#ifdef CONFIG_HPET_EMULATE_RTC
/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
* is enabled, we support RTC interrupt functionality in software.
* RTC has 3 kinds of interrupts:
* 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
* is updated
* 2) Alarm Interrupt - generate an interrupt at a specific time of day
* 3) Periodic Interrupt - generate periodic interrupt, with frequencies
* 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
* (1) and (2) above are implemented using polling at a frequency of
* 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
* overhead. (DEFAULT_RTC_INT_FREQ)
* For (3), we use interrupts at 64Hz or user specified periodic
* frequency, whichever is higher.
*/
#include <linux/mc146818rtc.h>
#include <linux/rtc.h>
extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#define DEFAULT_RTC_INT_FREQ 64
#define RTC_NUM_INTS 1
static unsigned long UIE_on;
static unsigned long prev_update_sec;
static unsigned long AIE_on;
static struct rtc_time alarm_time;
static unsigned long PIE_on;
static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
static unsigned long PIE_count;
static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
int is_hpet_enabled(void)
{
return vxtime.hpet_address != 0;
}
/*
* Timer 1 for RTC, we do not use periodic interrupt feature,
* even if HPET supports periodic interrupts on Timer 1.
* The reason being, to set up a periodic interrupt in HPET, we need to
* stop the main counter. And if we do that everytime someone diables/enables
* RTC, we will have adverse effect on main kernel timer running on Timer 0.
* So, for the time being, simulate the periodic interrupt in software.
*
* hpet_rtc_timer_init() is called for the first time and during subsequent
* interuppts reinit happens through hpet_rtc_timer_reinit().
*/
int hpet_rtc_timer_init(void)
{
unsigned int cfg, cnt;
unsigned long flags;
if (!is_hpet_enabled())
return 0;
/*
* Set the counter 1 and enable the interrupts.
*/
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
hpet_rtc_int_freq = PIE_freq;
else
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
local_irq_save(flags);
cnt = hpet_readl(HPET_COUNTER);
cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
hpet_writel(cnt, HPET_T1_CMP);
local_irq_restore(flags);
cfg = hpet_readl(HPET_T1_CFG);
cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
hpet_writel(cfg, HPET_T1_CFG);
return 1;
}
static void hpet_rtc_timer_reinit(void)
{
unsigned int cfg, cnt;
if (!(PIE_on | AIE_on | UIE_on))
return;
if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
hpet_rtc_int_freq = PIE_freq;
else
hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
/* It is more accurate to use the comparator value than current count.*/
cnt = hpet_readl(HPET_T1_CMP);
cnt += hpet_tick*HZ/hpet_rtc_int_freq;
hpet_writel(cnt, HPET_T1_CMP);
cfg = hpet_readl(HPET_T1_CFG);
cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
hpet_writel(cfg, HPET_T1_CFG);
return;
}
/*
* The functions below are called from rtc driver.
* Return 0 if HPET is not being used.
* Otherwise do the necessary changes and return 1.
*/
int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
{
if (!is_hpet_enabled())
return 0;
if (bit_mask & RTC_UIE)
UIE_on = 0;
if (bit_mask & RTC_PIE)
PIE_on = 0;
if (bit_mask & RTC_AIE)
AIE_on = 0;
return 1;
}
int hpet_set_rtc_irq_bit(unsigned long bit_mask)
{
int timer_init_reqd = 0;
if (!is_hpet_enabled())
return 0;
if (!(PIE_on | AIE_on | UIE_on))
timer_init_reqd = 1;
if (bit_mask & RTC_UIE) {
UIE_on = 1;
}
if (bit_mask & RTC_PIE) {
PIE_on = 1;
PIE_count = 0;
}
if (bit_mask & RTC_AIE) {
AIE_on = 1;
}
if (timer_init_reqd)
hpet_rtc_timer_init();
return 1;
}
int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
{
if (!is_hpet_enabled())
return 0;
alarm_time.tm_hour = hrs;
alarm_time.tm_min = min;
alarm_time.tm_sec = sec;
return 1;
}
int hpet_set_periodic_freq(unsigned long freq)
{
if (!is_hpet_enabled())
return 0;
PIE_freq = freq;
PIE_count = 0;
return 1;
}
int hpet_rtc_dropped_irq(void)
{
if (!is_hpet_enabled())
return 0;
return 1;
}
irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct rtc_time curr_time;
unsigned long rtc_int_flag = 0;
int call_rtc_interrupt = 0;
hpet_rtc_timer_reinit();
if (UIE_on | AIE_on) {
rtc_get_rtc_time(&curr_time);
}
if (UIE_on) {
if (curr_time.tm_sec != prev_update_sec) {
/* Set update int info, call real rtc int routine */
call_rtc_interrupt = 1;
rtc_int_flag = RTC_UF;
prev_update_sec = curr_time.tm_sec;
}
}
if (PIE_on) {
PIE_count++;
if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
/* Set periodic int info, call real rtc int routine */
call_rtc_interrupt = 1;
rtc_int_flag |= RTC_PF;
PIE_count = 0;
}
}
if (AIE_on) {
if ((curr_time.tm_sec == alarm_time.tm_sec) &&
(curr_time.tm_min == alarm_time.tm_min) &&
(curr_time.tm_hour == alarm_time.tm_hour)) {
/* Set alarm int info, call real rtc int routine */
call_rtc_interrupt = 1;
rtc_int_flag |= RTC_AF;
}
}
if (call_rtc_interrupt) {
rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
rtc_interrupt(rtc_int_flag, dev_id, regs);
}
return IRQ_HANDLED;
}
#endif
......@@ -405,9 +405,7 @@ static void do_trap(int trapnr, int signr, char *str,
if ((regs->cs & 3) != 0) {
struct task_struct *tsk = current;
if (exception_trace && !(tsk->ptrace & PT_PTRACED) &&
(tsk->sighand->action[signr-1].sa.sa_handler == SIG_IGN ||
(tsk->sighand->action[signr-1].sa.sa_handler == SIG_DFL)))
if (exception_trace && unhandled_signal(tsk, signr))
printk(KERN_INFO
"%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
tsk->comm, tsk->pid, str,
......@@ -491,9 +489,7 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
if ((regs->cs & 3)!=0) {
struct task_struct *tsk = current;
if (exception_trace && !(tsk->ptrace & PT_PTRACED) &&
(tsk->sighand->action[SIGSEGV-1].sa.sa_handler == SIG_IGN ||
(tsk->sighand->action[SIGSEGV-1].sa.sa_handler == SIG_DFL)))
if (exception_trace && unhandled_signal(tsk, SIGSEGV))
printk(KERN_INFO
"%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
tsk->comm, tsk->pid,
......@@ -553,6 +549,8 @@ asmlinkage void default_do_nmi(struct pt_regs * regs)
unsigned char reason = inb(0x61);
if (!(reason & 0xc0)) {
if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) == NOTIFY_BAD)
return;
#ifdef CONFIG_X86_LOCAL_APIC
/*
* Ok, so this is none of the documented NMI sources,
......
......@@ -3,6 +3,7 @@
*/
#include <asm-generic/vmlinux.lds.h>
#include <linux/config.h>
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
......@@ -137,7 +138,9 @@ SECTIONS
/* Sections to be discarded */
/DISCARD/ : {
*(.exitcall.exit)
#ifndef CONFIG_DEBUG_INFO
*(.eh_frame)
#endif
}
/* DWARF 2 */
......
......@@ -149,13 +149,11 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback);
#undef strncpy
#undef strchr
#undef strcmp
#undef bcopy
#undef strcpy
#undef strcat
extern void * memset(void *,int,__kernel_size_t);
extern size_t strlen(const char *);
extern void bcopy(const char * src, char * dest, int count);
extern void * memmove(void * dest,const void *src,size_t count);
extern char * strcpy(char * dest,const char *src);
extern int strcmp(const char * cs,const char * ct);
......@@ -178,7 +176,6 @@ EXPORT_SYMBOL_NOVERS(memchr);
EXPORT_SYMBOL_NOVERS(strrchr);
EXPORT_SYMBOL_NOVERS(strnlen);
EXPORT_SYMBOL_NOVERS(memscan);
EXPORT_SYMBOL_NOVERS(bcopy);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(__memcpy);
......
......@@ -8,6 +8,7 @@
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/dwarf2.h>
#include <asm/calling.h>
#include <asm/rwlock.h>
......@@ -15,18 +16,22 @@
.macro thunk name,func
.globl \name
\name:
CFI_STARTPROC
SAVE_ARGS
call \func
jmp restore
CFI_ENDPROC
.endm
/* rdi: arg1 ... normal C conventions. rax is passed from C. */
.macro thunk_retrax name,func
.globl \name
\name:
CFI_STARTPROC
SAVE_ARGS
call \func
jmp restore_norax
CFI_ENDPROC
.endm
......@@ -43,13 +48,20 @@
thunk_retrax __down_failed_trylock,__down_trylock
thunk __up_wakeup,__up
/* SAVE_ARGS below is used only for the .cfi directives it contains. */
CFI_STARTPROC
SAVE_ARGS
restore:
RESTORE_ARGS
ret
CFI_ENDPROC
CFI_STARTPROC
SAVE_ARGS
restore_norax:
RESTORE_ARGS 1
ret
CFI_ENDPROC
#ifdef CONFIG_SMP
/* Support for read/write spinlocks. */
......
......@@ -88,7 +88,7 @@ unsigned long __clear_user(void *addr, unsigned long size)
" .quad 1b,2b\n"
".previous"
: [size8] "=c"(size), [dst] "=&D" (__d0)
: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst] "(addr),
: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr),
[zero] "r" (0UL), [eight] "r" (8UL));
return size;
}
......
......@@ -32,6 +32,7 @@
#include <asm/tlbflush.h>
#include <asm/proto.h>
#include <asm/kdebug.h>
#include <asm-generic/sections.h>
void bust_spinlocks(int yes)
{
......@@ -169,8 +170,45 @@ void dump_pagetable(unsigned long address)
printk("BAD\n");
}
static inline int unhandled_signal(struct task_struct *tsk, int sig)
static const char errata93_warning[] =
KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
KERN_ERR "******* Please consider a BIOS update.\n"
KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
/* Workaround for K8 erratum #93 & buggy BIOS.
BIOS SMM functions are required to use a specific workaround
to avoid corruption of the 64bit RIP register on C stepping K8.
A lot of BIOS that didn't get tested properly miss this.
The OS sees this as a page fault with the upper 32bits of RIP cleared.
Try to work around it here.
Note we only handle faults in kernel here. */
static int is_errata93(struct pt_regs *regs, unsigned long address)
{
static int warned;
if (address != regs->rip)
return 0;
if ((address >> 32) != 0)
return 0;
address |= 0xffffffffUL << 32;
if ((address >= (u64)_stext && address <= (u64)_etext) ||
(address >= MODULES_VADDR && address <= MODULES_END)) {
if (!warned) {
printk(errata93_warning);
warned = 1;
}
regs->rip = address;
return 1;
}
return 0;
}
int unhandled_signal(struct task_struct *tsk, int sig)
{
/* Warn for strace, but not for gdb */
if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYSGOOD)) == PT_PTRACED)
return 0;
return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
(tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
}
......@@ -331,8 +369,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (is_prefetch(regs, address))
return;
if (exception_trace && !(tsk->ptrace & PT_PTRACED) &&
!unhandled_signal(tsk, SIGSEGV)) {
if (exception_trace && !unhandled_signal(tsk, SIGSEGV)) {
printk(KERN_INFO
"%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
tsk->comm, tsk->pid, address, regs->rip,
......@@ -360,9 +397,16 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
return;
}
/*
* Hall of shame of CPU/BIOS bugs.
*/
if (is_prefetch(regs, address))
return;
if (is_errata93(regs, address))
return;
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
......
......@@ -47,7 +47,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
struct node nodes[MAXNODE];
int nodeid, i, nb;
int found = 0;
int nmax;
u32 reg;
nb = find_northbridge();
if (nb < 0)
......@@ -55,8 +55,10 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb);
nmax = (1 << ((read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3));
numnodes = nmax;
reg = read_pci_config(0, nb, 0, 0x60);
numnodes = ((reg >> 4) & 7) + 1;
printk(KERN_INFO "Number of nodes %d (%x)\n", numnodes, reg);
memset(&nodes,0,sizeof(nodes));
prevbase = 0;
......@@ -66,12 +68,17 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
base = read_pci_config(0, nb, 1, 0x40 + i*8);
limit = read_pci_config(0, nb, 1, 0x44 + i*8);
nodeid = limit & 3;
nodeid = limit & 7;
if ((base & 3) == 0) {
if (i < nmax)
if (i < numnodes)
printk("Skipping disabled node %d\n", i);
continue;
}
if (nodeid >= numnodes) {
printk("Ignoring excess node %d (%x:%x)\n", nodeid,
base, limit);
continue;
}
if (!limit) {
printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i,
......
......@@ -33,18 +33,28 @@
.macro SAVE_ARGS addskip=0,norcx=0
subq $9*8+\addskip,%rsp
CFI_ADJUST_CFA_OFFSET 9*8+\addskip
movq %rdi,8*8(%rsp)
CFI_OFFSET rdi,8*8-(9*8+\addskip)
movq %rsi,7*8(%rsp)
CFI_OFFSET rsi,7*8-(9*8+\addskip)
movq %rdx,6*8(%rsp)
CFI_OFFSET rdx,6*8-(9*8+\addskip)
.if \norcx
.else
movq %rcx,5*8(%rsp)
CFI_OFFSET rcx,5*8-(9*8+\addskip)
.endif
movq %rax,4*8(%rsp)
CFI_OFFSET rax,4*8-(9*8+\addskip)
movq %r8,3*8(%rsp)
CFI_OFFSET r8,3*8-(9*8+\addskip)
movq %r9,2*8(%rsp)
CFI_OFFSET r9,2*8-(9*8+\addskip)
movq %r10,1*8(%rsp)
CFI_OFFSET r10,1*8-(9*8+\addskip)
movq %r11,(%rsp)
CFI_OFFSET r11,-(9*8+\addskip)
.endm
#define ARG_SKIP 9*8
......@@ -69,6 +79,7 @@
movq 8*8(%rsp),%rdi
.if ARG_SKIP+\addskip > 0
addq $ARG_SKIP+\addskip,%rsp
CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
.endif
.endm
......@@ -87,12 +98,19 @@
#define REST_SKIP 6*8
.macro SAVE_REST
subq $REST_SKIP,%rsp
CFI_ADJUST_CFA_OFFSET REST_SKIP
movq %rbx,5*8(%rsp)
CFI_OFFSET rbx,5*8-(REST_SKIP)
movq %rbp,4*8(%rsp)
CFI_OFFSET rbp,4*8-(REST_SKIP)
movq %r12,3*8(%rsp)
CFI_OFFSET r12,3*8-(REST_SKIP)
movq %r13,2*8(%rsp)
CFI_OFFSET r13,2*8-(REST_SKIP)
movq %r14,1*8(%rsp)
CFI_OFFSET r14,1*8-(REST_SKIP)
movq %r15,(%rsp)
CFI_OFFSET r15,0*8-(REST_SKIP)
.endm
.macro RESTORE_REST
......@@ -103,6 +121,7 @@
movq 4*8(%rsp),%rbp
movq 5*8(%rsp),%rbx
addq $REST_SKIP,%rsp
CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
.endm
.macro SAVE_ALL
......
......@@ -118,6 +118,7 @@ static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned
d.base1 = PTR_MIDDLE(tss) & 0xFF;
d.type = type;
d.p = 1;
d.g = 1;
d.limit1 = (size >> 16) & 0xF;
d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF;
d.base3 = PTR_HIGH(tss);
......
......@@ -14,7 +14,7 @@
away for older version.
*/
#ifdef CONFIG_CFI_BINUTILS
#ifdef CONFIG_DEBUG_INFO
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
......@@ -27,23 +27,15 @@
#else
#ifdef __ASSEMBLY__
.macro nothing
.endm
.macro nothing1 a
.endm
.macro nothing2 a,b
.endm
#endif
#define CFI_STARTPROC nothing
#define CFI_ENDPROC nothing
#define CFI_DEF_CFA nothing2
#define CFI_DEF_CFA_REGISTER nothing1
#define CFI_DEF_CFA_OFFSET nothing1
#define CFI_ADJUST_CFA_OFFSET nothing1
#define CFI_OFFSET nothing2
#define CFI_REL_OFFSET nothing2
/* use assembler line comment character # to ignore the arguments. */
#define CFI_STARTPROC #
#define CFI_ENDPROC #
#define CFI_DEF_CFA #
#define CFI_DEF_CFA_REGISTER #
#define CFI_DEF_CFA_OFFSET #
#define CFI_ADJUST_CFA_OFFSET #
#define CFI_OFFSET #
#define CFI_REL_OFFSET #
#endif
......
#ifndef _ASM_X8664_HPET_H
#define _ASM_X8664_HPET_H 1
#include <linux/interrupt.h>
/*
* Documentation on HPET can be found at:
* http://www.intel.com/ial/home/sp/pcmmspec.htm
* ftp://download.intel.com/ial/home/sp/mmts098.pdf
*/
#define HPET_MMAP_SIZE 1024
#define HPET_ID 0x000
#define HPET_PERIOD 0x004
#define HPET_CFG 0x010
#define HPET_STATUS 0x020
#define HPET_COUNTER 0x0f0
#define HPET_T0_CFG 0x100
#define HPET_T0_CMP 0x108
#define HPET_T0_ROUTE 0x110
#define HPET_T1_CFG 0x120
#define HPET_T1_CMP 0x128
#define HPET_T1_ROUTE 0x130
#define HPET_T2_CFG 0x140
#define HPET_T2_CMP 0x148
#define HPET_T2_ROUTE 0x150
#define HPET_ID_VENDOR 0xffff0000
#define HPET_ID_LEGSUP 0x00008000
#define HPET_ID_NUMBER 0x00001f00
#define HPET_ID_REV 0x000000ff
#define HPET_ID_VENDOR_SHIFT 16
#define HPET_ID_VENDOR_8086 0x8086
#define HPET_CFG_ENABLE 0x001
#define HPET_CFG_LEGACY 0x002
#define HPET_TN_ENABLE 0x004
#define HPET_TN_PERIODIC 0x008
#define HPET_TN_PERIODIC_CAP 0x010
#define HPET_TN_SETVAL 0x040
#define HPET_TN_32BIT 0x100
extern int is_hpet_enabled(void);
extern int hpet_rtc_timer_init(void);
#ifdef CONFIG_HPET_EMULATE_RTC
extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec);
extern int hpet_set_periodic_freq(unsigned long freq);
extern int hpet_rtc_dropped_irq(void);
extern int hpet_rtc_timer_init(void);
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#endif /* CONFIG_HPET_EMULATE_RTC */
#endif
......@@ -106,8 +106,6 @@ extern unsigned long io_apic_irqs;
extern atomic_t irq_err_count;
extern atomic_t irq_mis_count;
extern char _stext, _etext;
#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
#define __STR(x) #x
......
......@@ -100,8 +100,11 @@ typedef struct siginfo32 {
/* POSIX.1b timers */
struct {
unsigned int _timer1;
unsigned int _timer2;
int _tid; /* timer id */
int _overrun; /* overrun count */
sigval_t32 _sigval; /* same as below */
int _sys_private; /* not to be passed to user */
int _overrun_incr; /* amount to add to overrun */
} _timer;
/* POSIX.1b signals */
......@@ -164,9 +167,12 @@ struct ustat32 {
#ifdef __KERNEL__
struct user_desc;
struct siginfo_t;
int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info);
int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info);
int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs);
int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from);
int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from);
#endif
#endif /* !CONFIG_IA32_SUPPORT */
......
......@@ -31,6 +31,7 @@ enum die_val {
DIE_TRAP,
DIE_GPF,
DIE_CALL,
DIE_NMI_IPI,
};
static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
......
......@@ -24,11 +24,6 @@ outb_p((addr),RTC_PORT(0)); \
outb_p((val),RTC_PORT(1)); \
})
#ifndef CONFIG_HPET_TIMER
#define RTC_IRQ 8
#else
/* Temporary workaround due to IRQ routing problem. */
#define RTC_IRQ 0
#endif
#endif /* _ASM_MC146818RTC_H */
......@@ -173,7 +173,7 @@ static inline void clear_in_cr4 (unsigned long mask)
* space during mmap's.
*/
#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
#define TASK_UNMAPPED_32 (IA32_PAGE_OFFSET / 3)
#define TASK_UNMAPPED_32 (PAGE_ALIGN(IA32_PAGE_OFFSET / 3))
#define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3)
#define TASK_UNMAPPED_BASE \
(test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64)
......
......@@ -74,6 +74,8 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
extern void check_ioapic(void);
extern int unhandled_signal(struct task_struct *tsk, int sig);
extern unsigned long max_mapnr;
extern unsigned long end_pfn;
extern unsigned long table_start, table_end;
......
......@@ -6,7 +6,7 @@
#define R14 8
#define R13 16
#define R12 24
#define RBP 36
#define RBP 32
#define RBX 40
/* arguments: interrupts/non tracing syscalls only save upto here*/
#define R11 48
......
......@@ -6,6 +6,7 @@ struct scatterlist {
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
unsigned int dma_length;
};
#define ISA_DMA_THRESHOLD (0x00ffffff)
......@@ -16,6 +17,6 @@ struct scatterlist {
* returns.
*/
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->length)
#define sg_dma_len(sg) ((sg)->dma_length)
#endif
......@@ -19,62 +19,12 @@
#define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
#define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
#ifdef CONFIG_X86_REMOTE_DEBUG
/* full frame for the debug stub */
/* Should be replaced with a dwarf2 cie/fde description, then gdb could
figure it out all by itself. */
struct save_context_frame {
unsigned long rbp;
unsigned long rbx;
unsigned long r11;
unsigned long r10;
unsigned long r9;
unsigned long r8;
unsigned long rcx;
unsigned long rdx;
unsigned long r15;
unsigned long r14;
unsigned long r13;
unsigned long r12;
unsigned long rdi;
unsigned long rsi;
unsigned long flags;
};
#define SAVE_CONTEXT \
"pushfq\n\t" \
"subq $14*8,%%rsp\n\t" \
__SAVE(rbx, 12) __SAVE(rdi, 1) \
__SAVE(rdx, 6) __SAVE(rcx, 7) \
__SAVE(r8, 8) __SAVE(r9, 9) \
__SAVE(r12, 2) __SAVE(r13, 3) \
__SAVE(r14, 4) __SAVE(r15, 5) \
__SAVE(r10, 10) __SAVE(r11, 11) \
__SAVE(rsi, 0) __SAVE(rbp, 13) \
#define RESTORE_CONTEXT \
__RESTORE(rbx, 12) __RESTORE(rdi, 1) \
__RESTORE(rdx, 6) __RESTORE(rcx, 7) \
__RESTORE(r12, 2) __RESTORE(r13, 3) \
__RESTORE(r14, 4) __RESTORE(r15, 5) \
__RESTORE(r10, 10) __RESTORE(r11, 11) \
__RESTORE(r8, 8) __RESTORE(r9, 9) \
__RESTORE(rbp, 13) __RESTORE(rsi, 0) \
"addq $14*8,%%rsp\n\t" \
"popfq\n\t"
#define __EXTRA_CLOBBER
#else
/* frame pointer must be last for get_wchan */
#define SAVE_CONTEXT "pushfq ; pushq %%rbp ; movq %%rsi,%%rbp\n\t"
#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popfq\n\t"
#define __EXTRA_CLOBBER \
,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"
#endif
#define switch_to(prev,next,last) \
asm volatile(SAVE_CONTEXT \
......@@ -321,20 +271,7 @@ static inline __u32 cmpxchg4_locked(__u32 *ptr, __u32 old, __u32 new)
#define local_irq_disable() __asm__ __volatile__("cli": : :"memory")
#define local_irq_enable() __asm__ __volatile__("sti": : :"memory")
/* used in the idle loop; sti takes one instruction cycle to complete */
/* Work around BIOS that don't have K8 Errata #93 fixed. */
#define safe_halt() \
asm volatile(" sti\n" \
"1: hlt\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: call idle_warning\n" \
" jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n\t" \
".align 8\n\t" \
".quad 1b,3b\n" \
".previous" ::: "memory")
#define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory")
#define irqs_disabled() \
({ \
......
......@@ -105,6 +105,7 @@ static inline struct thread_info *stack_thread_info(void)
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_IA32 17 /* 32bit process */
#define TIF_FORK 18 /* ret_from_fork */
#define TIF_ABI_PENDING 19
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
......@@ -115,6 +116,7 @@ static inline struct thread_info *stack_thread_info(void)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_IA32 (1<<TIF_IA32)
#define _TIF_FORK (1<<TIF_FORK)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
......
......@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <asm/msr.h>
#include <asm/vsyscall.h>
#include <asm/hpet.h>
#define CLOCK_TICK_RATE 1193182 /* Underlying HZ */
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
......@@ -30,34 +31,6 @@ static inline cycles_t get_cycles (void)
extern unsigned int cpu_khz;
/*
* Documentation on HPET can be found at:
* http://www.intel.com/ial/home/sp/pcmmspec.htm
* ftp://download.intel.com/ial/home/sp/mmts098.pdf
*/
#define HPET_ID 0x000
#define HPET_PERIOD 0x004
#define HPET_CFG 0x010
#define HPET_STATUS 0x020
#define HPET_COUNTER 0x0f0
#define HPET_T0_CFG 0x100
#define HPET_T0_CMP 0x108
#define HPET_T0_ROUTE 0x110
#define HPET_ID_VENDOR 0xffff0000
#define HPET_ID_LEGSUP 0x00008000
#define HPET_ID_NUMBER 0x00000f00
#define HPET_ID_REV 0x000000ff
#define HPET_CFG_ENABLE 0x001
#define HPET_CFG_LEGACY 0x002
#define HPET_T0_ENABLE 0x004
#define HPET_T0_PERIODIC 0x008
#define HPET_T0_SETVAL 0x040
#define HPET_T0_32BIT 0x100
extern struct vxtime_data vxtime;
#endif
......@@ -533,6 +533,8 @@ __SYSCALL(__NR_utimes, sys_utimes)
#define __NR_vserver 236
__SYSCALL(__NR_vserver, sys_ni_syscall)
/* 237,238,239 reserved for NUMA API */
#define __NR_syscall_max __NR_vserver
#ifndef __NO_STUBS
......@@ -694,7 +696,7 @@ static inline long close(unsigned int fd)
}
extern long sys_exit(int) __attribute__((noreturn));
extern inline long exit(int error_code)
extern inline void exit(int error_code)
{
sys_exit(error_code);
}
......
......@@ -8,6 +8,6 @@
#define VSYSCALL32_VSYSCALL ((void *)VSYSCALL32_BASE + 0x400)
#define VSYSCALL32_SIGRETURN ((void *)VSYSCALL32_BASE + 0x500)
#define VSYSCALL32_RTSIGRETURN ((void *)VSYSCALL32_BASE + 0x500)
#define VSYSCALL32_RTSIGRETURN ((void *)VSYSCALL32_BASE + 0x600)
#endif
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