summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Kleen <ak@muc.de>2002-06-17 20:27:16 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-06-17 20:27:16 -0700
commitb068ec41ff5c343330ca11a25347918accb66c2a (patch)
treea7a5e3adb0cfd9ca1dec3ba98341270c6f53011a
parent9343c8e266dfe2e80578c592ade7825f5183af34 (diff)
[PATCH] x86-64 merge
x86_64 core updates. - Make it compile again (switch_to macros etc., add dummy suspend.h) - reenable strength reduce optimization - Fix ramdisk (patch from Mikael Pettersson) - Some merges from i386 - Reimplement lazy iobitmap allocation. I reimplemented it based on bcrl's idea. - Fix IPC 32bit emulation to actually work and move into own file - New fixed mtrr.c from DaveJ ported from 2.4 and reenable it. - Move tlbstate into PDA. - Add some changes that got lost during the last merge. - new memset that seems to actually work. - Align signal handler stack frames to 16 bytes. - Some more minor bugfixes.
-rw-r--r--arch/x86_64/Makefile6
-rw-r--r--arch/x86_64/boot/Makefile4
-rw-r--r--arch/x86_64/config.in4
-rw-r--r--arch/x86_64/ia32/Makefile5
-rw-r--r--arch/x86_64/ia32/ipc32.c645
-rw-r--r--arch/x86_64/ia32/sys_ia32.c416
-rw-r--r--arch/x86_64/kernel/ioport.c23
-rw-r--r--arch/x86_64/kernel/mtrr.c454
-rw-r--r--arch/x86_64/kernel/process.c33
-rw-r--r--arch/x86_64/kernel/setup64.c3
-rw-r--r--arch/x86_64/kernel/signal.c56
-rw-r--r--arch/x86_64/kernel/smp.c22
-rw-r--r--arch/x86_64/kernel/vsyscall.c2
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c2
-rw-r--r--arch/x86_64/lib/Makefile2
-rw-r--r--arch/x86_64/lib/memset.S76
-rw-r--r--include/asm-x86_64/i387.h11
-rw-r--r--include/asm-x86_64/ia32.h2
-rw-r--r--include/asm-x86_64/ipc.h30
-rw-r--r--include/asm-x86_64/mmu_context.h12
-rw-r--r--include/asm-x86_64/msr.h21
-rw-r--r--include/asm-x86_64/mtrr.h42
-rw-r--r--include/asm-x86_64/pda.h2
-rw-r--r--include/asm-x86_64/processor.h11
-rw-r--r--include/asm-x86_64/spinlock.h6
-rw-r--r--include/asm-x86_64/string.h13
-rw-r--r--include/asm-x86_64/suspend.h6
-rw-r--r--include/asm-x86_64/system.h7
-rw-r--r--include/asm-x86_64/timex.h2
-rw-r--r--include/asm-x86_64/tlbflush.h9
30 files changed, 1018 insertions, 909 deletions
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 3968f838fe7c..46fe5228c782 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -43,15 +43,9 @@ CFLAGS += -mcmodel=kernel
CFLAGS += -pipe
# this makes reading assembly source easier
CFLAGS += -fno-reorder-blocks
-# needed for later gcc 3.1
CFLAGS += -finline-limit=2000
-# needed for earlier gcc 3.1
-#CFLAGS += -fno-strength-reduce
#CFLAGS += -g
-# prevent gcc from keeping the stack 16 byte aligned (FIXME)
-#CFLAGS += -mpreferred-stack-boundary=2
-
HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
SUBDIRS := arch/x86_64/tools $(SUBDIRS) arch/x86_64/kernel arch/x86_64/mm arch/x86_64/lib
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
index a82cabc11223..9549b65aaae7 100644
--- a/arch/x86_64/boot/Makefile
+++ b/arch/x86_64/boot/Makefile
@@ -21,10 +21,6 @@ ROOT_DEV := CURRENT
SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
-# If you want the RAM disk device, define this to be the size in blocks.
-
-RAMDISK := -DRAMDISK=512
-
# ---------------------------------------------------------------------------
BOOT_INCL = $(TOPDIR)/include/linux/config.h \
diff --git a/arch/x86_64/config.in b/arch/x86_64/config.in
index 8605598747a8..829a74f439ad 100644
--- a/arch/x86_64/config.in
+++ b/arch/x86_64/config.in
@@ -47,8 +47,7 @@ define_bool CONFIG_EISA n
define_bool CONFIG_X86_IO_APIC y
define_bool CONFIG_X86_LOCAL_APIC y
-#currently broken:
-#bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
+bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
bool 'Symmetric multi-processing support' CONFIG_SMP
if [ "$CONFIG_SMP" = "n" ]; then
bool 'Preemptible Kernel' CONFIG_PREEMPT
@@ -226,6 +225,7 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Additional run-time checks' CONFIG_CHECKING
bool ' Debug __init statements' CONFIG_INIT_DEBUG
+ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
fi
endmenu
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
index 45c356b60cb5..00e69a2d0060 100644
--- a/arch/x86_64/ia32/Makefile
+++ b/arch/x86_64/ia32/Makefile
@@ -9,8 +9,9 @@ export-objs := ia32_ioctl.o sys_ia32.o
all: ia32.o
O_TARGET := ia32.o
-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o \
- ia32_binfmt.o fpu32.o socket32.o ptrace32.o
+obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
+ ia32_signal.o \
+ ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o
clean::
diff --git a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c
new file mode 100644
index 000000000000..2d322dda88ef
--- /dev/null
+++ b/arch/x86_64/ia32/ipc32.c
@@ -0,0 +1,645 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/slab.h>
+#include <linux/ipc.h>
+#include <asm/mman.h>
+#include <asm/types.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <asm/ipc.h>
+
+#include <asm/ia32.h>
+
+/*
+ * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
+ *
+ * This is really horribly ugly.
+ */
+
+struct msgbuf32 {
+ s32 mtype;
+ char mtext[1];
+};
+
+struct ipc_perm32 {
+ int key;
+ __kernel_uid_t32 uid;
+ __kernel_gid_t32 gid;
+ __kernel_uid_t32 cuid;
+ __kernel_gid_t32 cgid;
+ unsigned short mode;
+ unsigned short seq;
+};
+
+struct ipc64_perm32 {
+ unsigned key;
+ __kernel_uid32_t32 uid;
+ __kernel_gid32_t32 gid;
+ __kernel_uid32_t32 cuid;
+ __kernel_gid32_t32 cgid;
+ unsigned short mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned int unused1;
+ unsigned int unused2;
+};
+
+struct semid_ds32 {
+ struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t32 sem_otime; /* last semop time */
+ __kernel_time_t32 sem_ctime; /* last change time */
+ u32 sem_base; /* ptr to first semaphore in array */
+ u32 sem_pending; /* pending operations to be processed */
+ u32 sem_pending_last; /* last pending operation */
+ u32 undo; /* undo requests on this array */
+ unsigned short sem_nsems; /* no. of semaphores in array */
+};
+
+struct semid64_ds32 {
+ struct ipc64_perm32 sem_perm;
+ __kernel_time_t32 sem_otime;
+ unsigned int __unused1;
+ __kernel_time_t32 sem_ctime;
+ unsigned int __unused2;
+ unsigned int sem_nsems;
+ unsigned int __unused3;
+ unsigned int __unused4;
+};
+
+struct msqid_ds32 {
+ struct ipc_perm32 msg_perm;
+ u32 msg_first;
+ u32 msg_last;
+ __kernel_time_t32 msg_stime;
+ __kernel_time_t32 msg_rtime;
+ __kernel_time_t32 msg_ctime;
+ u32 wwait;
+ u32 rwait;
+ unsigned short msg_cbytes;
+ unsigned short msg_qnum;
+ unsigned short msg_qbytes;
+ __kernel_ipc_pid_t32 msg_lspid;
+ __kernel_ipc_pid_t32 msg_lrpid;
+};
+
+struct msqid64_ds32 {
+ struct ipc64_perm32 msg_perm;
+ __kernel_time_t32 msg_stime;
+ unsigned int __unused1;
+ __kernel_time_t32 msg_rtime;
+ unsigned int __unused2;
+ __kernel_time_t32 msg_ctime;
+ unsigned int __unused3;
+ unsigned int msg_cbytes;
+ unsigned int msg_qnum;
+ unsigned int msg_qbytes;
+ __kernel_pid_t32 msg_lspid;
+ __kernel_pid_t32 msg_lrpid;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
+
+struct shmid_ds32 {
+ struct ipc_perm32 shm_perm;
+ int shm_segsz;
+ __kernel_time_t32 shm_atime;
+ __kernel_time_t32 shm_dtime;
+ __kernel_time_t32 shm_ctime;
+ __kernel_ipc_pid_t32 shm_cpid;
+ __kernel_ipc_pid_t32 shm_lpid;
+ unsigned short shm_nattch;
+};
+
+struct shmid64_ds32 {
+ struct ipc64_perm32 shm_perm;
+ __kernel_size_t32 shm_segsz;
+ __kernel_time_t32 shm_atime;
+ unsigned int __unused1;
+ __kernel_time_t32 shm_dtime;
+ unsigned int __unused2;
+ __kernel_time_t32 shm_ctime;
+ unsigned int __unused3;
+ __kernel_pid_t32 shm_cpid;
+ __kernel_pid_t32 shm_lpid;
+ unsigned int shm_nattch;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
+
+struct shminfo64_32 {
+ unsigned int shmmax;
+ unsigned int shmmin;
+ unsigned int shmmni;
+ unsigned int shmseg;
+ unsigned int shmall;
+ unsigned int __unused1;
+ unsigned int __unused2;
+ unsigned int __unused3;
+ unsigned int __unused4;
+};
+
+struct shm_info32 {
+ int used_ids;
+ u32 shm_tot, shm_rss, shm_swp;
+ u32 swap_attempts, swap_successes;
+};
+
+struct ipc_kludge {
+ struct msgbuf *msgp;
+ int msgtyp;
+};
+
+
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)(__x))
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+#define IPCOP_MASK(__x) (1UL << (__x))
+
+static int
+ipc_parse_version32 (int *cmd)
+{
+ if (*cmd & IPC_64) {
+ *cmd ^= IPC_64;
+ return IPC_64;
+ } else {
+ return IPC_OLD;
+ }
+}
+
+static int
+semctl32 (int first, int second, int third, void *uptr)
+{
+ union semun fourth;
+ u32 pad;
+ int err = 0, err2;
+ struct semid64_ds s;
+ mm_segment_t old_fs;
+ int version = ipc_parse_version32(&third);
+
+ if (!uptr)
+ return -EINVAL;
+ if (get_user(pad, (u32 *)uptr))
+ return -EFAULT;
+ if (third == SETVAL)
+ fourth.val = (int)pad;
+ else
+ fourth.__pad = (void *)A(pad);
+ switch (third) {
+ case IPC_INFO:
+ case IPC_RMID:
+ case IPC_SET:
+ case SEM_INFO:
+ case GETVAL:
+ case GETPID:
+ case GETNCNT:
+ case GETZCNT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
+ err = sys_semctl(first, second, third, fourth);
+ break;
+
+ case IPC_STAT:
+ case SEM_STAT:
+ fourth.__pad = &s;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_semctl(first, second|IPC_64, third, fourth);
+ set_fs(old_fs);
+
+ if (version == IPC_64) {
+ struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
+
+ if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
+ err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
+ err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
+ err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
+ err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
+ err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
+ err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
+ err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
+ err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
+ err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
+ } else {
+ struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
+
+ if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
+ err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
+ err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
+ err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
+ err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
+ err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
+ err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
+ err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
+ err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
+ err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
+ }
+ if (err2)
+ err = -EFAULT;
+ break;
+ }
+ return err;
+}
+
+static int
+do_sys32_msgsnd (int first, int second, int third, void *uptr)
+{
+ struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+ struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+ mm_segment_t old_fs;
+ int err;
+
+ if (!p)
+ return -ENOMEM;
+ err = get_user(p->mtype, &up->mtype);
+ err |= copy_from_user(p->mtext, &up->mtext, second);
+ if (err)
+ goto out;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgsnd(first, p, second, third);
+ set_fs(old_fs);
+ out:
+ kfree(p);
+ return err;
+}
+
+static int
+do_sys32_msgrcv (int first, int second, int msgtyp, int third, int version, void *uptr)
+{
+ struct msgbuf32 *up;
+ struct msgbuf *p;
+ mm_segment_t old_fs;
+ int err;
+
+ if (!version) {
+ struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
+ struct ipc_kludge ipck;
+
+ err = -EINVAL;
+ if (!uptr)
+ goto out;
+ err = -EFAULT;
+ if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge)))
+ goto out;
+ uptr = (void *)A(ipck.msgp);
+ msgtyp = ipck.msgtyp;
+ }
+ err = -ENOMEM;
+ p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+ if (!p)
+ goto out;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgrcv(first, p, second + 4, msgtyp, third);
+ set_fs(old_fs);
+ if (err < 0)
+ goto free_then_out;
+ up = (struct msgbuf32 *)uptr;
+ if (put_user(p->mtype, &up->mtype) || copy_to_user(&up->mtext, p->mtext, err))
+ err = -EFAULT;
+free_then_out:
+ kfree(p);
+out:
+ return err;
+}
+
+static int
+msgctl32 (int first, int second, void *uptr)
+{
+ int err = -EINVAL, err2;
+ struct msqid_ds m;
+ struct msqid64_ds m64;
+ struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
+ struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
+ mm_segment_t old_fs;
+ int version = ipc_parse_version32(&second);
+
+ switch (second) {
+ case IPC_INFO:
+ case IPC_RMID:
+ case MSG_INFO:
+ err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
+ break;
+
+ case IPC_SET:
+ if (version == IPC_64) {
+ err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
+ err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
+ err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
+ err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
+ } else {
+ err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
+ err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
+ err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
+ err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
+ }
+ if (err)
+ break;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgctl(first, second, &m);
+ set_fs(old_fs);
+ break;
+
+ case IPC_STAT:
+ case MSG_STAT:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgctl(first, second|IPC_64, (void *) &m64);
+ set_fs(old_fs);
+
+ if (version == IPC_64) {
+ if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(m64.msg_perm.key, &up64->msg_perm.key);
+ err2 |= __put_user(m64.msg_perm.uid, &up64->msg_perm.uid);
+ err2 |= __put_user(m64.msg_perm.gid, &up64->msg_perm.gid);
+ err2 |= __put_user(m64.msg_perm.cuid, &up64->msg_perm.cuid);
+ err2 |= __put_user(m64.msg_perm.cgid, &up64->msg_perm.cgid);
+ err2 |= __put_user(m64.msg_perm.mode, &up64->msg_perm.mode);
+ err2 |= __put_user(m64.msg_perm.seq, &up64->msg_perm.seq);
+ err2 |= __put_user(m64.msg_stime, &up64->msg_stime);
+ err2 |= __put_user(m64.msg_rtime, &up64->msg_rtime);
+ err2 |= __put_user(m64.msg_ctime, &up64->msg_ctime);
+ err2 |= __put_user(m64.msg_cbytes, &up64->msg_cbytes);
+ err2 |= __put_user(m64.msg_qnum, &up64->msg_qnum);
+ err2 |= __put_user(m64.msg_qbytes, &up64->msg_qbytes);
+ err2 |= __put_user(m64.msg_lspid, &up64->msg_lspid);
+ err2 |= __put_user(m64.msg_lrpid, &up64->msg_lrpid);
+ if (err2)
+ err = -EFAULT;
+ } else {
+ if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(m64.msg_perm.key, &up32->msg_perm.key);
+ err2 |= __put_user(m64.msg_perm.uid, &up32->msg_perm.uid);
+ err2 |= __put_user(m64.msg_perm.gid, &up32->msg_perm.gid);
+ err2 |= __put_user(m64.msg_perm.cuid, &up32->msg_perm.cuid);
+ err2 |= __put_user(m64.msg_perm.cgid, &up32->msg_perm.cgid);
+ err2 |= __put_user(m64.msg_perm.mode, &up32->msg_perm.mode);
+ err2 |= __put_user(m64.msg_perm.seq, &up32->msg_perm.seq);
+ err2 |= __put_user(m64.msg_stime, &up32->msg_stime);
+ err2 |= __put_user(m64.msg_rtime, &up32->msg_rtime);
+ err2 |= __put_user(m64.msg_ctime, &up32->msg_ctime);
+ err2 |= __put_user(m64.msg_cbytes, &up32->msg_cbytes);
+ err2 |= __put_user(m64.msg_qnum, &up32->msg_qnum);
+ err2 |= __put_user(m64.msg_qbytes, &up32->msg_qbytes);
+ err2 |= __put_user(m64.msg_lspid, &up32->msg_lspid);
+ err2 |= __put_user(m64.msg_lrpid, &up32->msg_lrpid);
+ if (err2)
+ err = -EFAULT;
+ }
+ break;
+ }
+ return err;
+}
+
+static int
+shmat32 (int first, int second, int third, int version, void *uptr)
+{
+ unsigned long raddr;
+ u32 *uaddr = (u32 *)A((u32)third);
+ int err;
+
+ if (version == 1)
+ return -EINVAL; /* iBCS2 emulator entry point: unsupported */
+ err = sys_shmat(first, uptr, second, &raddr);
+ if (err)
+ return err;
+ return put_user(raddr, uaddr);
+}
+
+static int put_shmid64(struct shmid64_ds *s64p, void *uptr, int version)
+{
+ int err2;
+#define s64 (*s64p)
+ if (version == IPC_64) {
+ struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
+
+ if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
+ return -EFAULT;
+
+ err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
+ err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
+ err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
+ err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
+ err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
+ err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
+ err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
+ err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
+ err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
+ err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
+ err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
+ err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
+ err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
+ err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
+ } else {
+ struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
+
+ if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32)))
+ return -EFAULT;
+
+ err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
+ err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
+ err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
+ err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
+ err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
+ err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
+ err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
+ err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
+ err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
+ err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
+ err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
+ err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
+ err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
+ err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
+ }
+#undef s64
+ return err2 ? -EFAULT : 0;
+}
+static int
+shmctl32 (int first, int second, void *uptr)
+{
+ int err = -EFAULT, err2;
+ struct shmid_ds s;
+ struct shmid64_ds s64;
+ mm_segment_t old_fs;
+ struct shm_info32 *uip = (struct shm_info32 *)uptr;
+ struct shm_info si;
+ int version = ipc_parse_version32(&second);
+ struct shminfo64 smi;
+ struct shminfo *usi32 = (struct shminfo *) uptr;
+ struct shminfo64_32 *usi64 = (struct shminfo64_32 *) uptr;
+
+ switch (second) {
+ case IPC_INFO:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second|IPC_64, (struct shmid_ds *)&smi);
+ set_fs(old_fs);
+
+ if (version == IPC_64) {
+ if (!access_ok(VERIFY_WRITE, usi64, sizeof(*usi64))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(smi.shmmax, &usi64->shmmax);
+ err2 |= __put_user(smi.shmmin, &usi64->shmmin);
+ err2 |= __put_user(smi.shmmni, &usi64->shmmni);
+ err2 |= __put_user(smi.shmseg, &usi64->shmseg);
+ err2 |= __put_user(smi.shmall, &usi64->shmall);
+ } else {
+ if (!access_ok(VERIFY_WRITE, usi32, sizeof(*usi32))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(smi.shmmax, &usi32->shmmax);
+ err2 |= __put_user(smi.shmmin, &usi32->shmmin);
+ err2 |= __put_user(smi.shmmni, &usi32->shmmni);
+ err2 |= __put_user(smi.shmseg, &usi32->shmseg);
+ err2 |= __put_user(smi.shmall, &usi32->shmall);
+ }
+ if (err2)
+ err = -EFAULT;
+ break;
+
+ case IPC_RMID:
+ case SHM_LOCK:
+ case SHM_UNLOCK:
+ err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
+ break;
+
+ case IPC_SET:
+ if (version == IPC_64) {
+ struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
+ err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
+ err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
+ err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
+ } else {
+ struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
+ err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
+ err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
+ err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
+ }
+ if (err)
+ break;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second, &s);
+ set_fs(old_fs);
+ break;
+
+ case IPC_STAT:
+ case SHM_STAT:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second|IPC_64, (void *) &s64);
+ set_fs(old_fs);
+
+ if (err < 0)
+ break;
+ err2 = put_shmid64(&s64, uptr, version);
+ if (err2)
+ err = err2;
+ break;
+
+ case SHM_INFO:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second, (void *)&si);
+ set_fs(old_fs);
+ if (err < 0)
+ break;
+
+ if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(si.used_ids, &uip->used_ids);
+ err2 |= __put_user(si.shm_tot, &uip->shm_tot);
+ err2 |= __put_user(si.shm_rss, &uip->shm_rss);
+ err2 |= __put_user(si.shm_swp, &uip->shm_swp);
+ err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
+ err2 |= __put_user(si.swap_successes, &uip->swap_successes);
+ if (err2)
+ err = -EFAULT;
+ break;
+
+ }
+ return err;
+}
+
+asmlinkage long
+sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
+{
+ int version;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ switch (call) {
+ case SEMOP:
+ /* struct sembuf is the same on 32 and 64bit :)) */
+ return sys_semop(first, (struct sembuf *)AA(ptr), second);
+ case SEMGET:
+ return sys_semget(first, second, third);
+ case SEMCTL:
+ return semctl32(first, second, third, (void *)AA(ptr));
+
+ case MSGSND:
+ return do_sys32_msgsnd(first, second, third, (void *)AA(ptr));
+ case MSGRCV:
+ return do_sys32_msgrcv(first, second, fifth, third, version, (void *)AA(ptr));
+ case MSGGET:
+ return sys_msgget((key_t) first, second);
+ case MSGCTL:
+ return msgctl32(first, second, (void *)AA(ptr));
+
+ case SHMAT:
+ return shmat32(first, second, third, version, (void *)AA(ptr));
+ break;
+ case SHMDT:
+ return sys_shmdt((char *)AA(ptr));
+ case SHMGET:
+ return sys_shmget(first, second, third);
+ case SHMCTL:
+ return shmctl32(first, second, (void *)AA(ptr));
+
+ default:
+ return -EINVAL;
+ }
+ return -EINVAL;
+}
+
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index 35060b86a54a..85aaed5ec40a 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -1119,422 +1119,6 @@ sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
}
/*
- * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
- *
- * This is really horribly ugly.
- */
-
-struct msgbuf32 { s32 mtype; char mtext[1]; };
-
-struct ipc_perm32
-{
- key_t key;
- __kernel_uid_t32 uid;
- __kernel_gid_t32 gid;
- __kernel_uid_t32 cuid;
- __kernel_gid_t32 cgid;
- __kernel_mode_t32 mode;
- unsigned short seq;
-};
-
-struct semid_ds32 {
- struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
- u32 sem_base; /* ptr to first semaphore in array */
- u32 sem_pending; /* pending operations to be processed */
- u32 sem_pending_last; /* last pending operation */
- u32 undo; /* undo requests on this array */
- unsigned short sem_nsems; /* no. of semaphores in array */
-};
-
-struct msqid_ds32
-{
- struct ipc_perm32 msg_perm;
- u32 msg_first;
- u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
- u32 wwait;
- u32 rwait;
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- __kernel_ipc_pid_t32 msg_lspid;
- __kernel_ipc_pid_t32 msg_lrpid;
-};
-
-struct shmid_ds32 {
- struct ipc_perm32 shm_perm;
- int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
- __kernel_ipc_pid_t32 shm_cpid;
- __kernel_ipc_pid_t32 shm_lpid;
- unsigned short shm_nattch;
-};
-
-#define IPCOP_MASK(__x) (1UL << (__x))
-
-static int
-do_sys32_semctl(int first, int second, int third, void *uptr)
-{
- union semun fourth;
- u32 pad;
- int err;
- struct semid64_ds s;
- struct semid_ds32 *usp;
- mm_segment_t old_fs;
-
- if (!uptr)
- return -EINVAL;
- err = -EFAULT;
- if (get_user (pad, (u32 *)uptr))
- return err;
- if(third == SETVAL)
- fourth.val = (int)pad;
- else
- fourth.__pad = (void *)A(pad);
-
- switch (third) {
-
- case IPC_INFO:
- case IPC_RMID:
- case IPC_SET:
- case SEM_INFO:
- case GETVAL:
- case GETPID:
- case GETNCNT:
- case GETZCNT:
- case GETALL:
- case SETVAL:
- case SETALL:
- err = sys_semctl (first, second, third, fourth);
- break;
-
- case IPC_STAT:
- case SEM_STAT:
- usp = (struct semid_ds32 *)A(pad);
- fourth.__pad = &s;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_semctl (first, second, third, fourth);
- set_fs (old_fs);
- if (verify_area(VERIFY_WRITE, usp, sizeof(struct semid_ds32)) ||
- __put_user(s.sem_perm.key, &usp->sem_perm.key) ||
- __put_user(s.sem_perm.uid, &usp->sem_perm.uid) ||
- __put_user(s.sem_perm.gid, &usp->sem_perm.gid) ||
- __put_user(s.sem_perm.cuid, &usp->sem_perm.cuid) ||
- __put_user (s.sem_perm.cgid, &usp->sem_perm.cgid) ||
- __put_user (s.sem_perm.mode, &usp->sem_perm.mode) ||
- __put_user (s.sem_perm.seq, &usp->sem_perm.seq) ||
- __put_user (s.sem_otime, &usp->sem_otime) ||
- __put_user (s.sem_ctime, &usp->sem_ctime) ||
- __put_user (s.sem_nsems, &usp->sem_nsems))
- return -EFAULT;
- break;
-
- }
-
- return err;
-}
-
-static int
-do_sys32_msgsnd (int first, int second, int third, void *uptr)
-{
- struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
- + 4, GFP_USER);
- struct msgbuf32 *up = (struct msgbuf32 *)uptr;
- mm_segment_t old_fs;
- int err;
-
- if (!p)
- return -ENOMEM;
- err = verify_area(VERIFY_READ, up, sizeof(struct msgbuf32));
- if (err)
- goto out;
- err = __get_user (p->mtype, &up->mtype);
- err |= __copy_from_user (p->mtext, &up->mtext, second);
- if (err)
- goto out;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgsnd (first, p, second, third);
- set_fs (old_fs);
-out:
- kfree (p);
- return err;
-}
-
-static int
-do_sys32_msgrcv (int first, int second, int msgtyp, int third,
- int version, void *uptr)
-{
- struct msgbuf32 *up;
- struct msgbuf *p;
- mm_segment_t old_fs;
- int err;
-
- if (!version) {
- struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
- struct ipc_kludge ipck;
-
- err = -EINVAL;
- if (!uptr)
- goto out;
- err = -EFAULT;
- if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
- goto out;
- uptr = (void *)A(ipck.msgp);
- msgtyp = ipck.msgtyp;
- }
- err = -ENOMEM;
- p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
- if (!p)
- goto out;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgrcv (first, p, second + 4, msgtyp, third);
- set_fs (old_fs);
- if (err < 0)
- goto free_then_out;
- up = (struct msgbuf32 *)uptr;
- if (verify_area(VERIFY_WRITE, up, sizeof(struct msgbuf32)) ||
- __put_user (p->mtype, &up->mtype) ||
- __copy_to_user (&up->mtext, p->mtext, err))
- err = -EFAULT;
-free_then_out:
- kfree (p);
-out:
- return err;
-}
-
-static int
-do_sys32_msgctl (int first, int second, void *uptr)
-{
- int err = -EINVAL;
- struct msqid_ds m;
- struct msqid64_ds m64;
- struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
- mm_segment_t old_fs;
-
- switch (second) {
-
- case IPC_INFO:
- case IPC_RMID:
- case MSG_INFO:
- err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
- break;
-
- case IPC_SET:
- err = verify_area(VERIFY_READ, up, sizeof(struct msqid_ds32));
- if (err)
- break;
- err = __get_user (m.msg_perm.uid, &up->msg_perm.uid);
- err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
- err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
- err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
- if (err)
- break;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgctl (first, second, &m);
- set_fs (old_fs);
- break;
-
- case IPC_STAT:
- case MSG_STAT:
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgctl (first, second, (void *) &m64);
- set_fs (old_fs);
- if (verify_area(VERIFY_WRITE, up, sizeof(struct msqid_ds32)) ||
- __put_user (m64.msg_perm.key, &up->msg_perm.key) ||
- __put_user(m64.msg_perm.uid, &up->msg_perm.uid) ||
- __put_user(m64.msg_perm.gid, &up->msg_perm.gid) ||
- __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid) ||
- __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid) ||
- __put_user(m64.msg_perm.mode, &up->msg_perm.mode) ||
- __put_user(m64.msg_perm.seq, &up->msg_perm.seq) ||
- __put_user(m64.msg_stime, &up->msg_stime) ||
- __put_user(m64.msg_rtime, &up->msg_rtime) ||
- __put_user(m64.msg_ctime, &up->msg_ctime) ||
- __put_user(m64.msg_cbytes, &up->msg_cbytes) ||
- __put_user(m64.msg_qnum, &up->msg_qnum) ||
- __put_user(m64.msg_qbytes, &up->msg_qbytes) ||
- __put_user(m64.msg_lspid, &up->msg_lspid) ||
- __put_user(m64.msg_lrpid, &up->msg_lrpid))
- return -EFAULT;
- break;
-
- }
-
- return err;
-}
-
-static int
-do_sys32_shmat (int first, int second, int third, int version, void *uptr)
-{
- unsigned long raddr;
- u32 *uaddr = (u32 *)A((u32)third);
- int err = -EINVAL;
-
- if (version == 1)
- return err;
- err = sys_shmat (first, uptr, second, &raddr);
- if (err)
- return err;
- err = put_user (raddr, uaddr);
- return err;
-}
-
-static int
-do_sys32_shmctl (int first, int second, void *uptr)
-{
- int err = -EFAULT;
- struct shmid_ds s;
- struct shmid64_ds s64;
- struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
- mm_segment_t old_fs;
- struct shm_info32 {
- int used_ids;
- u32 shm_tot, shm_rss, shm_swp;
- u32 swap_attempts, swap_successes;
- } *uip = (struct shm_info32 *)uptr;
- struct shm_info si;
-
- switch (second) {
-
- case IPC_INFO:
- case IPC_RMID:
- case SHM_LOCK:
- case SHM_UNLOCK:
- err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
- break;
- case IPC_SET:
- err = verify_area(VERIFY_READ, up, sizeof(struct shmid_ds32));
- if (err)
- break;
- err = __get_user (s.shm_perm.uid, &up->shm_perm.uid);
- err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
- err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
- if (err)
- break;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, &s);
- set_fs (old_fs);
- break;
-
- case IPC_STAT:
- case SHM_STAT:
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, (void *) &s64);
- set_fs (old_fs);
- if (err < 0)
- break;
- if (verify_area(VERIFY_WRITE, up, sizeof(struct shmid_ds32)) ||
- __put_user (s64.shm_perm.key, &up->shm_perm.key) ||
- __put_user (s64.shm_perm.uid, &up->shm_perm.uid) ||
- __put_user (s64.shm_perm.gid, &up->shm_perm.gid) ||
- __put_user (s64.shm_perm.cuid, &up->shm_perm.cuid) ||
- __put_user (s64.shm_perm.cgid, &up->shm_perm.cgid) ||
- __put_user (s64.shm_perm.mode, &up->shm_perm.mode) ||
- __put_user (s64.shm_perm.seq, &up->shm_perm.seq) ||
- __put_user (s64.shm_atime, &up->shm_atime) ||
- __put_user (s64.shm_dtime, &up->shm_dtime) ||
- __put_user (s64.shm_ctime, &up->shm_ctime) ||
- __put_user (s64.shm_segsz, &up->shm_segsz) ||
- __put_user (s64.shm_nattch, &up->shm_nattch) ||
- __put_user (s64.shm_cpid, &up->shm_cpid) ||
- __put_user (s64.shm_lpid, &up->shm_lpid))
- return -EFAULT;
- break;
-
- case SHM_INFO:
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, (void *)&si);
- set_fs (old_fs);
- if (err < 0)
- break;
- if (verify_area(VERIFY_WRITE, uip, sizeof(struct shm_info32)) ||
- __put_user (si.used_ids, &uip->used_ids) ||
- __put_user (si.shm_tot, &uip->shm_tot) ||
- __put_user (si.shm_rss, &uip->shm_rss) ||
- __put_user (si.shm_swp, &uip->shm_swp) ||
- __put_user (si.swap_attempts, &uip->swap_attempts) ||
- __put_user (si.swap_successes, &uip->swap_successes))
- return -EFAULT;
- break;
-
- }
- return err;
-}
-
-asmlinkage long
-sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
-{
- int version, err;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
-
- case SEMOP:
- /* struct sembuf is the same on 32 and 64bit :)) */
- err = sys_semop (first, (struct sembuf *)AA(ptr),
- second);
- break;
- case SEMGET:
- err = sys_semget (first, second, third);
- break;
- case SEMCTL:
- err = do_sys32_semctl (first, second, third,
- (void *)AA(ptr));
- break;
-
- case MSGSND:
- err = do_sys32_msgsnd (first, second, third,
- (void *)AA(ptr));
- break;
- case MSGRCV:
- err = do_sys32_msgrcv (first, second, fifth, third,
- version, (void *)AA(ptr));
- break;
- case MSGGET:
- err = sys_msgget ((key_t) first, second);
- break;
- case MSGCTL:
- err = do_sys32_msgctl (first, second, (void *)AA(ptr));
- break;
-
- case SHMAT:
- err = do_sys32_shmat (first, second, third,
- version, (void *)AA(ptr));
- break;
- case SHMDT:
- err = sys_shmdt ((char *)AA(ptr));
- break;
- case SHMGET:
- err = sys_shmget (first, second, third);
- break;
- case SHMCTL:
- err = do_sys32_shmctl (first, second, (void *)AA(ptr));
- break;
- default:
- err = -EINVAL;
- break;
- }
-
- return err;
-}
-
-/*
* sys_time() can be implemented in user-level using
* sys_gettimeofday(). IA64 did this but i386 Linux did not
* so we have to implement this system call here.
diff --git a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c
index a0ab1a1ee68e..b8ad4c6d3709 100644
--- a/arch/x86_64/kernel/ioport.c
+++ b/arch/x86_64/kernel/ioport.c
@@ -14,6 +14,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
+#include <linux/slab.h>
/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
@@ -61,27 +62,19 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM;
- /*
- * 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->ioperm) {
- /*
- * just in case ...
- */
- memset(t->io_bitmap,0xff,(IO_BITMAP_SIZE+1)*4);
- t->ioperm = 1;
- /*
- * this activates it in the TSS
- */
+
+ if (!t->io_bitmap_ptr) {
+ t->io_bitmap_ptr = kmalloc((IO_BITMAP_SIZE+1)*4, GFP_KERNEL);
+ if (!t->io_bitmap_ptr)
+ return -ENOMEM;
+ memset(t->io_bitmap_ptr,0xff,(IO_BITMAP_SIZE+1)*4);
tss->io_map_base = IO_BITMAP_OFFSET;
}
/*
* do it in the per-thread copy and in the TSS ...
*/
- set_bitmap((unsigned long *) t->io_bitmap, from, num, !turn_on);
+ set_bitmap((unsigned long *) t->io_bitmap_ptr, from, num, !turn_on);
set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on);
return 0;
diff --git a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
index 1f36d262b618..b0c43563a30a 100644
--- a/arch/x86_64/kernel/mtrr.c
+++ b/arch/x86_64/kernel/mtrr.c
@@ -19,10 +19,14 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
(For earlier history, see arch/i386/kernel/mtrr.c)
- September 2001 Dave Jones <davej@suse.de>
+ v2.00 September 2001 Dave Jones <davej@suse.de>
Initial rewrite for x86-64.
-
+ Removal of non-Intel style MTRR code.
+ v2.01 June 2002 Dave Jones <davej@suse.de>
+ Removal of redundant abstraction layer.
+ 64-bit fixes.
*/
+
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
@@ -60,35 +64,19 @@
#include <asm/hardirq.h>
#include <linux/irq.h>
-#define MTRR_VERSION "2.00 (20020207)"
+#define MTRR_VERSION "2.01 (20020605)"
#define TRUE 1
#define FALSE 0
-#define MTRRcap_MSR 0x0fe
-#define MTRRdefType_MSR 0x2ff
-
-#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
-#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
+#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
#define NUM_FIXED_RANGES 88
-#define MTRRfix64K_00000_MSR 0x250
-#define MTRRfix16K_80000_MSR 0x258
-#define MTRRfix16K_A0000_MSR 0x259
-#define MTRRfix4K_C0000_MSR 0x268
-#define MTRRfix4K_C8000_MSR 0x269
-#define MTRRfix4K_D0000_MSR 0x26a
-#define MTRRfix4K_D8000_MSR 0x26b
-#define MTRRfix4K_E0000_MSR 0x26c
-#define MTRRfix4K_E8000_MSR 0x26d
-#define MTRRfix4K_F0000_MSR 0x26e
-#define MTRRfix4K_F8000_MSR 0x26f
-#ifdef CONFIG_SMP
#define MTRR_CHANGE_MASK_FIXED 0x01
#define MTRR_CHANGE_MASK_VARIABLE 0x02
#define MTRR_CHANGE_MASK_DEFTYPE 0x04
-#endif
typedef u8 mtrr_type;
@@ -97,49 +85,43 @@ typedef u8 mtrr_type;
#ifdef CONFIG_SMP
#define set_mtrr(reg,base,size,type) set_mtrr_smp (reg, base, size, type)
#else
-#define set_mtrr(reg,base,size,type) (*set_mtrr_up) (reg, base, size, type, \
- TRUE)
+#define set_mtrr(reg,base,size,type) set_mtrr_up (reg, base, size, type, TRUE)
#endif
#if defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS)
#define USERSPACE_INTERFACE
#endif
-#ifndef USERSPACE_INTERFACE
-#define compute_ascii() while (0)
-#endif
-
#ifdef USERSPACE_INTERFACE
static char *ascii_buffer;
static unsigned int ascii_buf_bytes;
-#endif
-static unsigned int *usage_table;
-static DECLARE_MUTEX (main_lock);
-
-/* Private functions */
-#ifdef USERSPACE_INTERFACE
static void compute_ascii (void);
+#else
+#define compute_ascii() while (0)
#endif
+static unsigned int *usage_table;
+static DECLARE_MUTEX (mtrr_lock);
+
struct set_mtrr_context {
- unsigned long flags;
- unsigned long deftype_lo;
- unsigned long deftype_hi;
- unsigned long cr4val;
+ u32 deftype_lo;
+ u32 deftype_hi;
+ u64 flags;
+ u64 cr4val;
};
/* Put the processor into a state where MTRRs can be safely set */
static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
{
- unsigned long cr0;
+ u64 cr0;
/* Disable interrupts locally */
__save_flags(ctxt->flags);
__cli();
/* Save value of CR4 and clear Page Global Enable (bit 7) */
- if (cpu_has_ge) {
+ if (cpu_has_pge) {
ctxt->cr4val = read_cr4();
write_cr4(ctxt->cr4val & ~(1UL << 7));
}
@@ -152,8 +134,8 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
wbinvd();
/* Disable MTRRs, and set the default type to uncached */
- rdmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
- wrmsr(MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
+ rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
+ wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
}
@@ -164,7 +146,7 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
wbinvd();
/* Restore MTRRdefType */
- wrmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
+ wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
@@ -181,9 +163,9 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
/* This function returns the number of variable MTRRs */
static unsigned int get_num_var_ranges (void)
{
- unsigned long config, dummy;
+ u32 config, dummy;
- rdmsr (MTRRcap_MSR, config, dummy);
+ rdmsr (MSR_MTRRcap, config, dummy);
return (config & 0xff);
}
@@ -191,21 +173,21 @@ static unsigned int get_num_var_ranges (void)
/* Returns non-zero if we have the write-combining memory type */
static int have_wrcomb (void)
{
- unsigned long config, dummy;
+ u32 config, dummy;
- rdmsr (MTRRcap_MSR, config, dummy);
+ rdmsr (MSR_MTRRcap, config, dummy);
return (config & (1 << 10));
}
-static u32 size_or_mask, size_and_mask;
+static u64 size_or_mask, size_and_mask;
-static void get_mtrr (unsigned int reg, unsigned long *base,
- unsigned long *size, mtrr_type * type)
+static void get_mtrr (unsigned int reg, u64 *base, u32 *size, mtrr_type * type)
{
- unsigned long mask_lo, mask_hi, base_lo, base_hi;
+ u32 mask_lo, mask_hi, base_lo, base_hi;
+ u64 newsize;
- rdmsr (MTRRphysMask_MSR (reg), mask_lo, mask_hi);
+ rdmsr (MSR_MTRRphysMask(reg), mask_lo, mask_hi);
if ((mask_lo & 0x800) == 0) {
/* Invalid (i.e. free) range */
*base = 0;
@@ -214,32 +196,29 @@ static void get_mtrr (unsigned int reg, unsigned long *base,
return;
}
- rdmsr (MTRRphysBase_MSR (reg), base_lo, base_hi);
+ rdmsr (MSR_MTRRphysBase(reg), base_lo, base_hi);
/* Work out the shifted address mask. */
- mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
- | mask_lo >> PAGE_SHIFT;
-
- /* This works correctly if size is a power of two, i.e. a
- contiguous range. */
- *size = -mask_lo;
+ newsize = (u64) mask_hi << 32 | (mask_lo & ~0x800);
+ newsize = ~newsize+1;
+ *size = (u32) newsize >> PAGE_SHIFT;
*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
*type = base_lo & 0xff;
}
-static void set_mtrr_up (unsigned int reg, unsigned long base,
- unsigned long size, mtrr_type type, int do_safe)
-/* [SUMMARY] Set variable MTRR register on the local CPU.
- <reg> The register to set.
- <base> The base address of the region.
- <size> The size of the region. If this is 0 the region is disabled.
- <type> The type of the region.
- <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
- be done externally.
- [RETURNS] Nothing.
-*/
+/*
+ * Set variable MTRR register on the local CPU.
+ * <reg> The register to set.
+ * <base> The base address of the region.
+ * <size> The size of the region. If this is 0 the region is disabled.
+ * <type> The type of the region.
+ * <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
+ * be done externally.
+ */
+static void set_mtrr_up (unsigned int reg, u64 base,
+ u32 size, mtrr_type type, int do_safe)
{
struct set_mtrr_context ctxt;
@@ -249,12 +228,12 @@ static void set_mtrr_up (unsigned int reg, unsigned long base,
if (size == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
- wrmsr (MTRRphysMask_MSR (reg), 0, 0);
+ wrmsr (MSR_MTRRphysMask(reg), 0, 0);
} else {
- wrmsr (MTRRphysBase_MSR (reg), base << PAGE_SHIFT | type,
+ wrmsr (MSR_MTRRphysBase(reg), base << PAGE_SHIFT | type,
(base & size_and_mask) >> (32 - PAGE_SHIFT));
- wrmsr (MTRRphysMask_MSR (reg), -size << PAGE_SHIFT | 0x800,
- (-size & size_and_mask) >> (32 - PAGE_SHIFT));
+ wrmsr (MSR_MTRRphysMask(reg), (-size-1) << PAGE_SHIFT | 0x800,
+ ((-size-1) & size_and_mask) >> (32 - PAGE_SHIFT));
}
if (do_safe)
set_mtrr_done (&ctxt);
@@ -264,41 +243,40 @@ static void set_mtrr_up (unsigned int reg, unsigned long base,
#ifdef CONFIG_SMP
struct mtrr_var_range {
- unsigned long base_lo;
- unsigned long base_hi;
- unsigned long mask_lo;
- unsigned long mask_hi;
+ u32 base_lo;
+ u32 base_hi;
+ u32 mask_lo;
+ u32 mask_hi;
};
/* Get the MSR pair relating to a var range */
static void __init get_mtrr_var_range (unsigned int index,
struct mtrr_var_range *vr)
{
- rdmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi);
- rdmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi);
+ rdmsr (MSR_MTRRphysBase(index), vr->base_lo, vr->base_hi);
+ rdmsr (MSR_MTRRphysMask(index), vr->mask_lo, vr->mask_hi);
}
/* Set the MSR pair relating to a var range. Returns TRUE if
changes are made */
-static int __init
-set_mtrr_var_range_testing (unsigned int index, struct mtrr_var_range *vr)
+static int __init set_mtrr_var_range_testing (unsigned int index,
+ struct mtrr_var_range *vr)
{
- unsigned int lo, hi;
+ u32 lo, hi;
int changed = FALSE;
- rdmsr (MTRRphysBase_MSR (index), lo, hi);
- if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
- || (vr->base_hi & 0xfUL) != (hi & 0xfUL)) {
- wrmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi);
+ rdmsr (MSR_MTRRphysBase(index), lo, hi);
+ if ((vr->base_lo & 0xfffff0ff) != (lo & 0xfffff0ff)
+ || (vr->base_hi & 0x000fffff) != (hi & 0x000fffff)) {
+ wrmsr (MSR_MTRRphysBase(index), vr->base_lo, vr->base_hi);
changed = TRUE;
}
- rdmsr (MTRRphysMask_MSR (index), lo, hi);
-
- if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
- || (vr->mask_hi & 0xfUL) != (hi & 0xfUL)) {
- wrmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi);
+ rdmsr (MSR_MTRRphysMask(index), lo, hi);
+ if ((vr->mask_lo & 0xfffff800) != (lo & 0xfffff800)
+ || (vr->mask_hi & 0x000fffff) != (hi & 0x000fffff)) {
+ wrmsr (MSR_MTRRphysMask(index), vr->mask_lo, vr->mask_hi);
changed = TRUE;
}
return changed;
@@ -307,45 +285,50 @@ set_mtrr_var_range_testing (unsigned int index, struct mtrr_var_range *vr)
static void __init get_fixed_ranges (mtrr_type * frs)
{
- unsigned long *p = (unsigned long *) frs;
+ u32 *p = (u32 *) frs;
int i;
- rdmsr (MTRRfix64K_00000_MSR, p[0], p[1]);
+ rdmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
for (i = 0; i < 2; i++)
- rdmsr (MTRRfix16K_80000_MSR + i, p[2 + i * 2], p[3 + i * 2]);
+ rdmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
for (i = 0; i < 8; i++)
- rdmsr (MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]);
+ rdmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
}
static int __init set_fixed_ranges_testing (mtrr_type * frs)
{
- unsigned long *p = (unsigned long *) frs;
+ u32 *p = (u32 *) frs;
int changed = FALSE;
int i;
- unsigned long lo, hi;
+ u32 lo, hi;
- rdmsr (MTRRfix64K_00000_MSR, lo, hi);
+ printk (KERN_INFO "mtrr: rdmsr 64K_00000\n");
+ rdmsr (MSR_MTRRfix64K_00000, lo, hi);
if (p[0] != lo || p[1] != hi) {
- wrmsr (MTRRfix64K_00000_MSR, p[0], p[1]);
+ printk (KERN_INFO "mtrr: Writing %x:%x to 64K MSR. lohi were %x:%x\n", p[0], p[1], lo, hi);
+ wrmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
changed = TRUE;
}
+ printk (KERN_INFO "mtrr: rdmsr 16K_80000\n");
for (i = 0; i < 2; i++) {
- rdmsr (MTRRfix16K_80000_MSR + i, lo, hi);
+ rdmsr (MSR_MTRRfix16K_80000 + i, lo, hi);
if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
- wrmsr (MTRRfix16K_80000_MSR + i, p[2 + i * 2],
- p[3 + i * 2]);
+ printk (KERN_INFO "mtrr: Writing %x:%x to 16K MSR%d. lohi were %x:%x\n", p[2 + i * 2], p[3 + i * 2], i, lo, hi );
+ wrmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
changed = TRUE;
}
}
+ printk (KERN_INFO "mtrr: rdmsr 4K_C0000\n");
for (i = 0; i < 8; i++) {
- rdmsr (MTRRfix4K_C0000_MSR + i, lo, hi);
+ rdmsr (MSR_MTRRfix4K_C0000 + i, lo, hi);
+ printk (KERN_INFO "mtrr: MTRRfix4K_C0000+%d = %x:%x\n", i, lo, hi);
if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
- wrmsr (MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
- p[7 + i * 2]);
+ printk (KERN_INFO "mtrr: Writing %x:%x to 4K MSR%d. lohi were %x:%x\n", p[6 + i * 2], p[7 + i * 2], i, lo, hi);
+ wrmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
changed = TRUE;
}
}
@@ -357,8 +340,8 @@ struct mtrr_state {
unsigned int num_var_ranges;
struct mtrr_var_range *var_ranges;
mtrr_type fixed_ranges[NUM_FIXED_RANGES];
- unsigned char enabled;
mtrr_type def_type;
+ unsigned char enabled;
};
@@ -367,9 +350,9 @@ static void __init get_mtrr_state (struct mtrr_state *state)
{
unsigned int nvrs, i;
struct mtrr_var_range *vrs;
- unsigned long lo, dummy;
+ u32 lo, dummy;
- nvrs = state->num_var_ranges = get_num_var_ranges ();
+ nvrs = state->num_var_ranges = get_num_var_ranges();
vrs = state->var_ranges
= kmalloc (nvrs * sizeof (struct mtrr_var_range), GFP_KERNEL);
if (vrs == NULL)
@@ -379,7 +362,7 @@ static void __init get_mtrr_state (struct mtrr_state *state)
get_mtrr_var_range (i, &vrs[i]);
get_fixed_ranges (state->fixed_ranges);
- rdmsr (MTRRdefType_MSR, lo, dummy);
+ rdmsr (MSR_MTRRdefType, lo, dummy);
state->def_type = (lo & 0xff);
state->enabled = (lo & 0xc00) >> 10;
}
@@ -393,17 +376,18 @@ static void __init finalize_mtrr_state (struct mtrr_state *state)
}
-static unsigned long __init set_mtrr_state (struct mtrr_state *state,
+/*
+ * Set the MTRR state for this CPU.
+ * <state> The MTRR state information to read.
+ * <ctxt> Some relevant CPU context.
+ * [NOTE] The CPU must already be in a safe state for MTRR changes.
+ * [RETURNS] 0 if no changes made, else a mask indication what was changed.
+ */
+static u64 __init set_mtrr_state (struct mtrr_state *state,
struct set_mtrr_context *ctxt)
-/* [SUMMARY] Set the MTRR state for this CPU.
- <state> The MTRR state information to read.
- <ctxt> Some relevant CPU context.
- [NOTE] The CPU must already be in a safe state for MTRR changes.
- [RETURNS] 0 if no changes made, else a mask indication what was changed.
-*/
{
unsigned int i;
- unsigned long change_mask = 0;
+ u64 change_mask = 0;
for (i = 0; i < state->num_var_ranges; i++)
if (set_mtrr_var_range_testing (i, &state->var_ranges[i]))
@@ -428,16 +412,16 @@ static volatile int wait_barrier_execute = FALSE;
static volatile int wait_barrier_cache_enable = FALSE;
struct set_mtrr_data {
- unsigned long smp_base;
- unsigned long smp_size;
+ u64 smp_base;
+ u32 smp_size;
unsigned int smp_reg;
mtrr_type smp_type;
};
+/*
+ * Synchronisation handler. Executed by "other" CPUs.
+ */
static void ipi_handler (void *info)
-/* [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
- [RETURNS] Nothing.
-*/
{
struct set_mtrr_data *data = info;
struct set_mtrr_context ctxt;
@@ -449,7 +433,7 @@ static void ipi_handler (void *info)
barrier ();
/* The master has cleared me to execute */
- (*set_mtrr_up) (data->smp_reg, data->smp_base, data->smp_size,
+ set_mtrr_up (data->smp_reg, data->smp_base, data->smp_size,
data->smp_type, FALSE);
/* Notify master CPU that I've executed the function */
@@ -462,8 +446,7 @@ static void ipi_handler (void *info)
}
-static void set_mtrr_smp (unsigned int reg, unsigned long base,
- unsigned long size, mtrr_type type)
+static void set_mtrr_smp (unsigned int reg, u64 base, u32 size, mtrr_type type)
{
struct set_mtrr_data data;
struct set_mtrr_context ctxt;
@@ -490,7 +473,7 @@ static void set_mtrr_smp (unsigned int reg, unsigned long base,
/* Set up for completion wait and then release other CPUs to change MTRRs */
atomic_set (&undone_count, smp_num_cpus - 1);
wait_barrier_execute = FALSE;
- (*set_mtrr_up) (reg, base, size, type, FALSE);
+ set_mtrr_up (reg, base, size, type, FALSE);
/* Now wait for other CPUs to complete the function */
while (atomic_read (&undone_count) > 0)
@@ -505,7 +488,7 @@ static void set_mtrr_smp (unsigned int reg, unsigned long base,
/* Some BIOS's are fucked and don't set all MTRRs the same! */
-static void __init mtrr_state_warn (unsigned long mask)
+static void __init mtrr_state_warn (u32 mask)
{
if (!mask)
return;
@@ -521,7 +504,7 @@ static void __init mtrr_state_warn (unsigned long mask)
#endif /* CONFIG_SMP */
-static char inline * attrib_to_str (int x)
+static inline char * attrib_to_str (int x)
{
return (x <= 6) ? mtrr_strings[x] : "?";
}
@@ -551,21 +534,20 @@ static void __init init_table (void)
}
-static int generic_get_free_region (unsigned long base,
- unsigned long size)
-/* [SUMMARY] Get a free MTRR.
- <base> The starting (base) address of the region.
- <size> The size (in bytes) of the region.
- [RETURNS] The index of the region on success, else -1 on error.
+/*
+ * Get a free MTRR.
+ * returns the index of the region on success, else -1 on error.
*/
+static int get_free_region(void)
{
int i, max;
mtrr_type ltype;
- unsigned long lbase, lsize;
+ u64 lbase;
+ u32 lsize;
max = get_num_var_ranges ();
for (i = 0; i < max; ++i) {
- (*get_mtrr) (i, &lbase, &lsize, &ltype);
+ get_mtrr (i, &lbase, &lsize, &ltype);
if (lsize == 0)
return i;
}
@@ -573,22 +555,19 @@ static int generic_get_free_region (unsigned long base,
}
-static int (*get_free_region) (unsigned long base,
- unsigned long size) = generic_get_free_region;
-
/**
* mtrr_add_page - Add a memory type region
* @base: Physical base address of region in pages (4 KB)
* @size: Physical size of region in pages (4 KB)
* @type: Type of MTRR desired
* @increment: If this is true do usage counting on the region
+ * Returns The MTRR register on success, else a negative number
+ * indicating the error code.
*
- * Memory type region registers control the caching on newer Intel and
- * non Intel processors. This function allows drivers to request an
- * MTRR is added. The details and hardware specifics of each processor's
- * implementation are hidden from the caller, but nevertheless the
- * caller should expect to need to provide a power of two size on an
- * equivalent power of two boundary.
+ * Memory type region registers control the caching on newer
+ * processors. This function allows drivers to request an MTRR is added.
+ * The caller should expect to need to provide a power of two size on
+ * an equivalent power of two boundary.
*
* If the region cannot be added either because all regions are in use
* or the CPU cannot support it a negative value is returned. On success
@@ -596,42 +575,28 @@ static int (*get_free_region) (unsigned long base,
* as a cookie only.
*
* On a multiprocessor machine the changes are made to all processors.
- * This is required on x86 by the Intel processors.
*
* The available types are
*
* %MTRR_TYPE_UNCACHABLE - No caching
- *
* %MTRR_TYPE_WRBACK - Write data back in bursts whenever
- *
* %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
- *
* %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
*
* BUGS: Needs a quiet flag for the cases where drivers do not mind
* failures and do not wish system log messages to be sent.
*/
-int mtrr_add_page (unsigned long base, unsigned long size,
- unsigned int type, char increment)
+int mtrr_add_page (u64 base, u32 size, unsigned int type, char increment)
{
-/* [SUMMARY] Add an MTRR entry.
- <base> The starting (base, in pages) address of the region.
- <size> The size of the region. (in pages)
- <type> The type of the new region.
- <increment> If true and the region already exists, the usage count will be
- incremented.
- [RETURNS] The MTRR register on success, else a negative number indicating
- the error code.
- [NOTE] This routine uses a spinlock.
-*/
int i, max;
mtrr_type ltype;
- unsigned long lbase, lsize, last;
+ u64 lbase, last;
+ u32 lsize;
if (base + size < 0x100) {
printk (KERN_WARNING
- "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
+ "mtrr: cannot set region below 1 MiB (0x%lx000,0x%x000)\n",
base, size);
return -EINVAL;
}
@@ -644,7 +609,7 @@ int mtrr_add_page (unsigned long base, unsigned long size,
if (lbase != last) {
printk (KERN_WARNING
- "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
+ "mtrr: base(0x%lx000) is not aligned on a size(0x%x000) boundary\n",
base, size);
return -EINVAL;
}
@@ -655,7 +620,7 @@ int mtrr_add_page (unsigned long base, unsigned long size,
}
/* If the type is WC, check that this processor supports it */
- if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb ()) {
+ if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
printk (KERN_WARNING
"mtrr: your processor doesn't support write-combining\n");
return -ENOSYS;
@@ -669,9 +634,9 @@ int mtrr_add_page (unsigned long base, unsigned long size,
increment = increment ? 1 : 0;
max = get_num_var_ranges ();
/* Search for existing MTRR */
- down (&main_lock);
+ down (&mtrr_lock);
for (i = 0; i < max; ++i) {
- (*get_mtrr) (i, &lbase, &lsize, &ltype);
+ get_mtrr (i, &lbase, &lsize, &ltype);
if (base >= lbase + lsize)
continue;
if ((base < lbase) && (base + size <= lbase))
@@ -679,41 +644,41 @@ int mtrr_add_page (unsigned long base, unsigned long size,
/* At this point we know there is some kind of overlap/enclosure */
if ((base < lbase) || (base + size > lbase + lsize)) {
- up (&main_lock);
+ up (&mtrr_lock);
printk (KERN_WARNING
- "mtrr: 0x%lx000,0x%lx000 overlaps existing"
- " 0x%lx000,0x%lx000\n", base, size, lbase,
- lsize);
+ "mtrr: 0x%lx000,0x%x000 overlaps existing"
+ " 0x%lx000,0x%x000\n", base, size, lbase, lsize);
return -EINVAL;
}
/* New region is enclosed by an existing region */
if (ltype != type) {
if (type == MTRR_TYPE_UNCACHABLE)
continue;
- up (&main_lock);
+ up (&mtrr_lock);
printk
- ("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
- base, size, attrib_to_str (ltype),
+ ("mtrr: type mismatch for %lx000,%x000 old: %s new: %s\n",
+ base, size,
+ attrib_to_str (ltype),
attrib_to_str (type));
return -EINVAL;
}
if (increment)
++usage_table[i];
compute_ascii ();
- up (&main_lock);
+ up (&mtrr_lock);
return i;
}
/* Search for an empty MTRR */
- i = (*get_free_region) (base, size);
+ i = get_free_region();
if (i < 0) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: no more MTRRs available\n");
return i;
}
set_mtrr (i, base, size, type);
usage_table[i] = 1;
compute_ascii ();
- up (&main_lock);
+ up (&mtrr_lock);
return i;
}
@@ -724,13 +689,13 @@ int mtrr_add_page (unsigned long base, unsigned long size,
* @size: Physical size of region
* @type: Type of MTRR desired
* @increment: If this is true do usage counting on the region
+ * Return the MTRR register on success, else a negative numbe
+ * indicating the error code.
*
- * Memory type region registers control the caching on newer Intel and
- * non Intel processors. This function allows drivers to request an
- * MTRR is added. The details and hardware specifics of each processor's
- * implementation are hidden from the caller, but nevertheless the
- * caller should expect to need to provide a power of two size on an
- * equivalent power of two boundary.
+ * Memory type region registers control the caching on newer processors.
+ * This function allows drivers to request an MTRR is added.
+ * The caller should expect to need to provide a power of two size on
+ * an equivalent power of two boundary.
*
* If the region cannot be added either because all regions are in use
* or the CPU cannot support it a negative value is returned. On success
@@ -743,33 +708,19 @@ int mtrr_add_page (unsigned long base, unsigned long size,
* The available types are
*
* %MTRR_TYPE_UNCACHABLE - No caching
- *
* %MTRR_TYPE_WRBACK - Write data back in bursts whenever
- *
* %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
- *
* %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
*
* BUGS: Needs a quiet flag for the cases where drivers do not mind
* failures and do not wish system log messages to be sent.
*/
-int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
- char increment)
+int mtrr_add (u64 base, u32 size, unsigned int type, char increment)
{
-/* [SUMMARY] Add an MTRR entry.
- <base> The starting (base) address of the region.
- <size> The size (in bytes) of the region.
- <type> The type of the new region.
- <increment> If true and the region already exists, the usage count will be
- incremented.
- [RETURNS] The MTRR register on success, else a negative number indicating
- the error code.
-*/
-
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk ("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
return mtrr_add_page (base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
@@ -792,55 +743,46 @@ int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
* code.
*/
-int mtrr_del_page (int reg, unsigned long base, unsigned long size)
-/* [SUMMARY] Delete MTRR/decrement usage count.
- <reg> The register. If this is less than 0 then <<base>> and <<size>> must
- be supplied.
- <base> The base address of the region. This is ignored if <<reg>> is >= 0.
- <size> The size of the region. This is ignored if <<reg>> is >= 0.
- [RETURNS] The register on success, else a negative number indicating
- the error code.
- [NOTE] This routine uses a spinlock.
-*/
+int mtrr_del_page (int reg, u64 base, u32 size)
{
int i, max;
mtrr_type ltype;
- unsigned long lbase, lsize;
+ u64 lbase;
+ u32 lsize;
max = get_num_var_ranges ();
- down (&main_lock);
+ down (&mtrr_lock);
if (reg < 0) {
/* Search for existing MTRR */
for (i = 0; i < max; ++i) {
- (*get_mtrr) (i, &lbase, &lsize, &ltype);
+ get_mtrr (i, &lbase, &lsize, &ltype);
if (lbase == base && lsize == size) {
reg = i;
break;
}
}
if (reg < 0) {
- up (&main_lock);
- printk ("mtrr: no MTRR for %lx000,%lx000 found\n", base,
- size);
+ up (&mtrr_lock);
+ printk ("mtrr: no MTRR for %lx000,%x000 found\n", base, size);
return -EINVAL;
}
}
if (reg >= max) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: register: %d too big\n", reg);
return -EINVAL;
}
- (*get_mtrr) (reg, &lbase, &lsize, &ltype);
+ get_mtrr (reg, &lbase, &lsize, &ltype);
if (lsize < 1) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: MTRR %d not used\n", reg);
return -EINVAL;
}
if (usage_table[reg] < 1) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: reg: %d has count=0\n", reg);
return -EINVAL;
}
@@ -848,7 +790,7 @@ int mtrr_del_page (int reg, unsigned long base, unsigned long size)
if (--usage_table[reg] < 1)
set_mtrr (reg, 0, 0, 0);
compute_ascii ();
- up (&main_lock);
+ up (&mtrr_lock);
return reg;
}
@@ -868,19 +810,11 @@ int mtrr_del_page (int reg, unsigned long base, unsigned long size)
* code.
*/
-int mtrr_del (int reg, unsigned long base, unsigned long size)
-/* [SUMMARY] Delete MTRR/decrement usage count.
- <reg> The register. If this is less than 0 then <<base>> and <<size>> must
- be supplied.
- <base> The base address of the region. This is ignored if <<reg>> is >= 0.
- <size> The size of the region. This is ignored if <<reg>> is >= 0.
- [RETURNS] The register on success, else a negative number indicating
- the error code.
-*/
+int mtrr_del (int reg, u64 base, u32 size)
{
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk ("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
return mtrr_del_page (reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
@@ -889,8 +823,8 @@ int mtrr_del (int reg, unsigned long base, unsigned long size)
#ifdef USERSPACE_INTERFACE
-static int mtrr_file_add (unsigned long base, unsigned long size,
- unsigned int type, char increment, struct file *file, int page)
+static int mtrr_file_add (u64 base, u32 size, unsigned int type,
+ struct file *file, int page)
{
int reg, max;
unsigned int *fcount = file->private_data;
@@ -910,7 +844,7 @@ static int mtrr_file_add (unsigned long base, unsigned long size,
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk
("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
base >>= PAGE_SHIFT;
@@ -925,7 +859,7 @@ static int mtrr_file_add (unsigned long base, unsigned long size,
}
-static int mtrr_file_del (unsigned long base, unsigned long size,
+static int mtrr_file_del (u64 base, u32 size,
struct file *file, int page)
{
int reg;
@@ -935,7 +869,7 @@ static int mtrr_file_del (unsigned long base, unsigned long size,
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk
("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
base >>= PAGE_SHIFT;
@@ -977,9 +911,9 @@ static ssize_t mtrr_write (struct file *file, const char *buf,
"disable=%d"
*/
{
- int i, err;
- unsigned long reg;
- unsigned long long base, size;
+ int i, err, reg;
+ u64 base;
+ u32 size;
char *ptr;
char line[LINE_SIZE];
@@ -1027,7 +961,7 @@ static ssize_t mtrr_write (struct file *file, const char *buf,
if ((base & 0xfff) || (size & 0xfff)) {
printk ("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%Lx base: 0x%Lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
@@ -1046,9 +980,7 @@ static ssize_t mtrr_write (struct file *file, const char *buf,
continue;
base >>= PAGE_SHIFT;
size >>= PAGE_SHIFT;
- err =
- mtrr_add_page ((unsigned long) base, (unsigned long) size,
- i, 1);
+ err = mtrr_add_page ((u64) base, size, i, 1);
if (err < 0)
return err;
return len;
@@ -1076,7 +1008,7 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
return -EFAULT;
err =
- mtrr_file_add (sentry.base, sentry.size, sentry.type, 1,
+ mtrr_file_add (sentry.base, sentry.size, sentry.type,
file, 0);
if (err < 0)
return err;
@@ -1117,7 +1049,7 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
return -EFAULT;
if (gentry.regnum >= get_num_var_ranges ())
return -EINVAL;
- (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
+ get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type);
/* Hide entries that go above 4GB */
if (gentry.base + gentry.size > 0x100000
@@ -1139,7 +1071,7 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
return -EFAULT;
err =
- mtrr_file_add (sentry.base, sentry.size, sentry.type, 1,
+ mtrr_file_add (sentry.base, sentry.size, sentry.type,
file, 1);
if (err < 0)
return err;
@@ -1180,7 +1112,7 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
return -EFAULT;
if (gentry.regnum >= get_num_var_ranges ())
return -EINVAL;
- (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
+ get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type);
gentry.type = type;
if (copy_to_user ((void *) arg, &gentry, sizeof gentry))
@@ -1199,7 +1131,6 @@ static int mtrr_close (struct inode *ino, struct file *file)
if (fcount == NULL)
return 0;
- lock_kernel ();
max = get_num_var_ranges ();
for (i = 0; i < max; ++i) {
while (fcount[i] > 0) {
@@ -1208,7 +1139,6 @@ static int mtrr_close (struct inode *ino, struct file *file)
--fcount[i];
}
}
- unlock_kernel ();
kfree (fcount);
file->private_data = NULL;
return 0;
@@ -1234,12 +1164,13 @@ static void compute_ascii (void)
char factor;
int i, max;
mtrr_type type;
- unsigned long base, size;
+ u64 base;
+ u32 size;
ascii_buf_bytes = 0;
max = get_num_var_ranges ();
for (i = 0; i < max; i++) {
- (*get_mtrr) (i, &base, &size, &type);
+ get_mtrr (i, &base, &size, &type);
if (size == 0)
usage_table[i] = 0;
else {
@@ -1253,11 +1184,10 @@ static void compute_ascii (void)
}
sprintf
(ascii_buffer + ascii_buf_bytes,
- "reg%02i: base=0x%05lx000 (%4liMB), size=%4li%cB: %s, count=%d\n",
+ "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n",
i, base, base >> (20 - PAGE_SHIFT), size, factor,
attrib_to_str (type), usage_table[i]);
- ascii_buf_bytes +=
- strlen (ascii_buffer + ascii_buf_bytes);
+ ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
}
}
devfs_set_file_size (devfs_handle, ascii_buf_bytes);
@@ -1283,22 +1213,16 @@ static void __init mtrr_setup (void)
if ((cpuid_eax (0x80000000) >= 0x80000008)) {
u32 phys_addr;
phys_addr = cpuid_eax (0x80000008) & 0xff;
- size_or_mask =
- ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
- size_and_mask = ~size_or_mask & 0xfff00000;
- } else {
- /* FIXME: This is to make it work on Athlon during debugging. */
- size_or_mask = 0xff000000; /* 36 bits */
- size_and_mask = 0x00f00000;
+ size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
+ size_and_mask = ~size_or_mask & 0xfffffffffff00000;
}
-
printk ("mtrr: detected mtrr type: x86-64\n");
}
}
#ifdef CONFIG_SMP
-static volatile unsigned long smp_changes_mask __initdata = 0;
+static volatile u32 smp_changes_mask __initdata = 0;
static struct mtrr_state smp_mtrr_state __initdata = { 0, 0 };
void __init mtrr_init_boot_cpu (void)
@@ -1310,7 +1234,8 @@ void __init mtrr_init_boot_cpu (void)
void __init mtrr_init_secondary_cpu (void)
{
- unsigned long mask, count;
+ u64 mask;
+ int count;
struct set_mtrr_context ctxt;
/* Note that this is not ideal, since the cache is only flushed/disabled
@@ -1357,4 +1282,3 @@ int __init mtrr_init (void)
init_table ();
return 0;
}
-
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index e233b3557ce5..f00fff0638de 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -39,6 +39,7 @@
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/ctype.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -320,9 +321,6 @@ void show_regs(struct pt_regs * regs)
printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
}
-#define __STR(x) #x
-#define __STR2(x) __STR(x)
-
extern void load_gs_index(unsigned);
/*
@@ -330,7 +328,13 @@ extern void load_gs_index(unsigned);
*/
void exit_thread(void)
{
- /* nothing to do ... */
+ struct task_struct *me = current;
+ if (me->thread.io_bitmap_ptr) {
+ kfree(me->thread.io_bitmap_ptr);
+ me->thread.io_bitmap_ptr = NULL;
+ (init_tss + smp_processor_id())->io_map_base =
+ INVALID_IO_BITMAP_OFFSET;
+ }
}
void flush_thread(void)
@@ -392,6 +396,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
unlazy_fpu(current);
p->thread.i387 = current->thread.i387;
+ if (unlikely(me->thread.io_bitmap_ptr != NULL)) {
+ p->thread.io_bitmap_ptr = kmalloc((IO_BITMAP_SIZE+1)*4, GFP_KERNEL);
+ if (!p->thread.io_bitmap_ptr)
+ return -ENOMEM;
+ memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
+ (IO_BITMAP_SIZE+1)*4);
+ }
+
return 0;
}
@@ -491,21 +503,14 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/*
* Handle the IO bitmap
*/
- if (unlikely(prev->ioperm || next->ioperm)) {
- if (next->ioperm) {
+ if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
+ if (next->io_bitmap_ptr) {
/*
* 4 cachelines copy ... not good, but not that
* bad either. Anyone got something better?
* This only affects processes which use ioperm().
- * [Putting the TSSs into 4k-tlb mapped regions
- * and playing VM tricks to switch the IO bitmap
- * is not really acceptable.]
- * On x86-64 we could put multiple bitmaps into
- * the GDT and just switch offsets
- * This would require ugly special cases on overflow
- * though -AK
*/
- memcpy(tss->io_bitmap, next->io_bitmap,
+ memcpy(tss->io_bitmap, next->io_bitmap_ptr,
IO_BITMAP_SIZE*sizeof(u32));
tss->io_map_base = IO_BITMAP_OFFSET;
} else {
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index f6c296dce4b5..66ae787c8d19 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -91,6 +91,9 @@ void pda_init(int cpu)
pda->me = pda;
pda->cpudata_offset = 0;
+ pda->active_mm = &init_mm;
+ pda->mmu_state = 0;
+
asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
}
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 98b653afe853..229592faf805 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -84,7 +84,6 @@ struct rt_sigframe
char *pretcode;
struct ucontext uc;
struct siginfo info;
- struct _fpstate fpstate;
};
static int
@@ -186,8 +185,7 @@ badframe:
*/
static int
-setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
- struct pt_regs *regs, unsigned long mask)
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask)
{
int tmp, err = 0;
struct task_struct *me = current;
@@ -221,20 +219,17 @@ setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
err |= __put_user(mask, &sc->oldmask);
err |= __put_user(me->thread.cr2, &sc->cr2);
- tmp = save_i387(fpstate);
- if (tmp < 0)
- err = 1;
- else
- err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
-
return err;
}
/*
* Determine which stack to use..
*/
-static inline struct rt_sigframe *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs)
+
+#define round_down(p, r) ((void *) ((unsigned long)((p) - (r) + 1) & ~((r)-1)))
+
+static void *
+get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
{
unsigned long rsp;
@@ -247,22 +242,34 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs)
rsp = current->sas_ss_sp + current->sas_ss_size;
}
- rsp = (rsp - sizeof(struct _fpstate)) & ~(15UL);
- rsp -= offsetof(struct rt_sigframe, fpstate);
-
- return (struct rt_sigframe *) rsp;
+ return round_down(rsp - size, 16);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
{
- struct rt_sigframe *frame;
+ struct rt_sigframe *frame = NULL;
+ struct _fpstate *fp = NULL;
int err = 0;
- frame = get_sigframe(ka, regs);
+ if (current->used_math) {
+ fp = get_stack(ka, regs, sizeof(struct _fpstate));
+ frame = round_down((char *)fp - sizeof(struct rt_sigframe), 16) - 8;
- if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) {
goto give_sigsegv;
+ }
+
+ if (save_i387(fp) < 0)
+ err |= -1;
+ }
+
+ if (!frame)
+ frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
+ goto give_sigsegv;
+ }
if (ka->sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, info);
@@ -278,14 +285,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(sas_ss_flags(regs->rsp),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
- regs, set->sig[0]);
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+ err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
- if (err) {
- goto give_sigsegv;
- }
-
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
/* x86-64 should always use SA_RESTORER. */
@@ -297,7 +300,6 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err) {
- printk("fault 3\n");
goto give_sigsegv;
}
@@ -305,7 +307,6 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax);
#endif
-
/* Set up registers for signal handler */
{
struct exec_domain *ed = current_thread_info()->exec_domain;
@@ -320,9 +321,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
next argument after the signal number on the stack. */
regs->rsi = (unsigned long)&frame->info;
regs->rdx = (unsigned long)&frame->uc;
- regs->rsp = (unsigned long) frame;
regs->rip = (unsigned long) ka->sa.sa_handler;
+ regs->rsp = (unsigned long)frame;
+
set_fs(USER_DS);
regs->eflags &= ~TF_MASK;
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 3d6e8a406b54..f0d99edfec0e 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -25,8 +25,6 @@
/* The 'big kernel lock' */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
-struct tlb_state cpu_tlbstate[NR_CPUS] = {[0 ... NR_CPUS-1] = { &init_mm, 0 }};
-
/*
* the following functions deal with sending IPIs between CPUs.
*
@@ -147,9 +145,9 @@ static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED;
*/
static void inline leave_mm (unsigned long cpu)
{
- if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
+ if (read_pda(mmu_state) == TLBSTATE_OK)
BUG();
- clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
+ clear_bit(cpu, &read_pda(active_mm)->cpu_vm_mask);
__flush_tlb();
}
@@ -164,18 +162,18 @@ static void inline leave_mm (unsigned long cpu)
* the other cpus, but smp_invalidate_interrupt ignore flush ipis
* for the wrong mm, and in the worst case we perform a superflous
* tlb flush.
- * 1a2) set cpu_tlbstate to TLBSTATE_OK
+ * 1a2) set cpu mmu_state to TLBSTATE_OK
* Now the smp_invalidate_interrupt won't call leave_mm if cpu0
* was in lazy tlb mode.
- * 1a3) update cpu_tlbstate[].active_mm
+ * 1a3) update cpu active_mm
* Now cpu0 accepts tlb flushes for the new mm.
* 1a4) set_bit(cpu, &new_mm->cpu_vm_mask);
* Now the other cpus will send tlb flush ipis.
* 1a4) change cr3.
* 1b) thread switch without mm change
- * cpu_tlbstate[].active_mm is correct, cpu0 already handles
+ * cpu active_mm is correct, cpu0 already handles
* flush ipis.
- * 1b1) set cpu_tlbstate to TLBSTATE_OK
+ * 1b1) set cpu mmu_state to TLBSTATE_OK
* 1b2) test_and_set the cpu bit in cpu_vm_mask.
* Atomically set the bit [other cpus will start sending flush ipis],
* and test the bit.
@@ -188,7 +186,7 @@ static void inline leave_mm (unsigned long cpu)
* runs in kernel space, the cpu could load tlb entries for user space
* pages.
*
- * The good news is that cpu_tlbstate is local to each cpu, no
+ * The good news is that cpu mmu_state is local to each cpu, no
* write/read ordering problems.
*/
@@ -216,8 +214,8 @@ asmlinkage void smp_invalidate_interrupt (void)
* BUG();
*/
- if (flush_mm == cpu_tlbstate[cpu].active_mm) {
- if (cpu_tlbstate[cpu].state == TLBSTATE_OK) {
+ if (flush_mm == read_pda(active_mm)) {
+ if (read_pda(mmu_state) == TLBSTATE_OK) {
if (flush_va == FLUSH_ALL)
local_flush_tlb();
else
@@ -335,7 +333,7 @@ static inline void do_flush_tlb_all_local(void)
unsigned long cpu = smp_processor_id();
__flush_tlb_all();
- if (cpu_tlbstate[cpu].state == TLBSTATE_LAZY)
+ if (read_pda(mmu_state) == TLBSTATE_LAZY)
leave_mm(cpu);
}
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index b292ca527a8a..e576e9f98ec5 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -47,7 +47,7 @@
#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
-#define NO_VSYSCALL 1
+//#define NO_VSYSCALL 1
#ifdef NO_VSYSCALL
#include <asm/unistd.h>
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 9d88edb5c62d..2bbb7d8238b5 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -189,3 +189,5 @@ EXPORT_SYMBOL_NOVERS(do_softirq_thunk);
void out_of_line_bug(void);
EXPORT_SYMBOL(out_of_line_bug);
+
+EXPORT_SYMBOL(init_level4_pgt);
diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
index 8fbcee522aeb..6791678212ed 100644
--- a/arch/x86_64/lib/Makefile
+++ b/arch/x86_64/lib/Makefile
@@ -12,7 +12,7 @@ obj-y = csum-partial.o csum-copy.o csum-wrappers.o delay.o \
thunk.o io.o clear_page.o copy_page.o
obj-y += memcpy.o
obj-y += memmove.o
-#obj-y += memset.o
+obj-y += memset.o
obj-y += copy_user.o
export-objs := io.o csum-wrappers.o csum-partial.o
diff --git a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
index 1c5d73cd73b8..44ce1223d832 100644
--- a/arch/x86_64/lib/memset.S
+++ b/arch/x86_64/lib/memset.S
@@ -1,6 +1,4 @@
-/* Copyright 2002 Andi Kleen, SuSE Labs */
-
- // #define FIX_ALIGNMENT 1
+/* Copyright 2002 Andi Kleen */
/*
* ISO C memset - set a memory block to a byte value.
@@ -11,51 +9,51 @@
*
* rax original destination
*/
- .globl ____memset
+ .globl __memset
+ .globl memset
.p2align
-____memset:
- movq %rdi,%r10 /* save destination for return address */
- movq %rdx,%r11 /* save count */
+memset:
+__memset:
+ movq %rdi,%r10
+ movq %rdx,%r11
/* expand byte value */
- movzbl %sil,%ecx /* zero extend char value */
- movabs $0x0101010101010101,%rax /* expansion pattern */
- mul %rcx /* expand with rax, clobbers rdx */
+ movzbl %sil,%ecx
+ movabs $0x0101010101010101,%rax
+ mul %rcx /* with rax, clobbers rdx */
-#ifdef FIX_ALIGNMENT
/* align dst */
movl %edi,%r9d
- andl $7,%r9d /* test unaligned bits */
+ andl $7,%r9d
jnz bad_alignment
after_bad_alignment:
-#endif
- movq %r11,%rcx /* restore count */
- shrq $6,%rcx /* divide by 64 */
- jz handle_tail /* block smaller than 64 bytes? */
- movl $64,%r8d /* CSE loop block size */
+ movq %r11,%rcx
+ movl $64,%r8d
+ shrq $6,%rcx
+ jz handle_tail
loop_64:
- movnti %rax,0*8(%rdi)
- movnti %rax,1*8(%rdi)
- movnti %rax,2*8(%rdi)
- movnti %rax,3*8(%rdi)
- movnti %rax,4*8(%rdi)
- movnti %rax,5*8(%rdi)
- movnti %rax,6*8(%rdi)
- movnti %rax,7*8(%rdi) /* clear 64 byte blocks */
- addq %r8,%rdi /* increase pointer by 64 bytes */
- loop loop_64 /* decrement rcx and if not zero loop */
+ movnti %rax,(%rdi)
+ movnti %rax,8(%rdi)
+ movnti %rax,16(%rdi)
+ movnti %rax,24(%rdi)
+ movnti %rax,32(%rdi)
+ movnti %rax,40(%rdi)
+ movnti %rax,48(%rdi)
+ movnti %rax,56(%rdi)
+ addq %r8,%rdi
+ loop loop_64
/* Handle tail in loops. The loops should be faster than hard
to predict jump tables. */
handle_tail:
movl %r11d,%ecx
- andl $63,%ecx
- shrl $3,%ecx
+ andl $63&(~7),%ecx
jz handle_7
+ shrl $3,%ecx
loop_8:
- movnti %rax,(%rdi) /* long words */
+ movnti %rax,(%rdi)
addq $8,%rdi
loop loop_8
@@ -64,22 +62,20 @@ handle_7:
andl $7,%ecx
jz ende
loop_1:
- movb %al,(%rdi) /* bytes */
- incq %rdi
+ movb %al,(%rdi)
+ addq $1,%rdi
loop loop_1
ende:
movq %r10,%rax
ret
-#ifdef FIX_ALIGNMENT
bad_alignment:
- andq $-8,%r11 /* shorter than 8 bytes */
- jz handle_7 /* if yes handle it in the tail code */
- movnti %rax,(%rdi) /* unaligned store of 8 bytes */
+ cmpq $7,%r11
+ jbe handle_7
+ movnti %rax,(%rdi) /* unaligned store */
movq $8,%r8
- subq %r9,%r8 /* compute alignment (8-misalignment) */
- addq %r8,%rdi /* fix destination */
- subq %r8,%r11 /* fix count */
+ subq %r9,%r8
+ addq %r8,%rdi
+ subq %r8,%r11
jmp after_bad_alignment
-#endif
diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
index edb75edb063e..2a0292c00b54 100644
--- a/include/asm-x86_64/i387.h
+++ b/include/asm-x86_64/i387.h
@@ -16,11 +16,22 @@
#include <asm/processor.h>
#include <asm/sigcontext.h>
#include <asm/user.h>
+#include <asm/thread_info.h>
extern void fpu_init(void);
extern void init_fpu(void);
int save_i387(struct _fpstate *buf);
+static inline int need_signal_i387(struct task_struct *me)
+{
+ if (!me->used_math)
+ return 0;
+ me->used_math = 0;
+ if (!test_thread_flag(TIF_USEDFPU))
+ return 0;
+ return 1;
+}
+
/*
* FPU lazy state save handling...
*/
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
index e57c2e593007..7830bf40cfd4 100644
--- a/include/asm-x86_64/ia32.h
+++ b/include/asm-x86_64/ia32.h
@@ -18,7 +18,9 @@ typedef int __kernel_clock_t32;
typedef int __kernel_pid_t32;
typedef unsigned short __kernel_ipc_pid_t32;
typedef unsigned short __kernel_uid_t32;
+typedef unsigned __kernel_uid32_t32;
typedef unsigned short __kernel_gid_t32;
+typedef unsigned __kernel_gid32_t32;
typedef unsigned short __kernel_dev_t32;
typedef unsigned int __kernel_ino_t32;
typedef unsigned short __kernel_mode_t32;
diff --git a/include/asm-x86_64/ipc.h b/include/asm-x86_64/ipc.h
index 49ea4fdc19b4..2ca5773be061 100644
--- a/include/asm-x86_64/ipc.h
+++ b/include/asm-x86_64/ipc.h
@@ -1,34 +1,6 @@
#ifndef __i386_IPC_H__
#define __i386_IPC_H__
-/*
- * These are used to wrap system calls on x86.
- *
- * See arch/i386/kernel/sys_i386.c for ugly details..
- *
- * (on x86-64 only used for 32bit emulation)
- */
-
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
+/* dummy */
#endif
diff --git a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h
index e9f6d661cf4c..e21f0e6721f8 100644
--- a/include/asm-x86_64/mmu_context.h
+++ b/include/asm-x86_64/mmu_context.h
@@ -19,8 +19,8 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
{
- if(cpu_tlbstate[cpu].state == TLBSTATE_OK)
- cpu_tlbstate[cpu].state = TLBSTATE_LAZY;
+ if (read_pda(mmu_state) == TLBSTATE_OK)
+ write_pda(mmu_state, TLBSTATE_LAZY);
}
#else
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
@@ -35,8 +35,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
/* stop flush ipis for the previous mm */
clear_bit(cpu, &prev->cpu_vm_mask);
#ifdef CONFIG_SMP
- cpu_tlbstate[cpu].state = TLBSTATE_OK;
- cpu_tlbstate[cpu].active_mm = next;
+ write_pda(mmu_state, TLBSTATE_OK);
+ write_pda(active_mm, next);
#endif
set_bit(cpu, &next->cpu_vm_mask);
/* Re-load page tables */
@@ -48,8 +48,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
}
#ifdef CONFIG_SMP
else {
- cpu_tlbstate[cpu].state = TLBSTATE_OK;
- if(cpu_tlbstate[cpu].active_mm != next)
+ write_pda(mmu_state, TLBSTATE_OK);
+ if (read_pda(active_mm) != next)
out_of_line_bug();
if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
/* We were in lazy tlb mode and leave_mm disabled
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index 7e522c2f4846..4085cc8c5dbe 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -95,6 +95,7 @@
#define MSR_IA32_PERFCTR0 0xc1
#define MSR_IA32_PERFCTR1 0xc2
+#define MSR_MTRRcap 0x0fe
#define MSR_IA32_BBL_CR_CTL 0x119
#define MSR_IA32_MCG_CAP 0x179
@@ -110,6 +111,19 @@
#define MSR_IA32_LASTINTFROMIP 0x1dd
#define MSR_IA32_LASTINTTOIP 0x1de
+#define MSR_MTRRfix64K_00000 0x250
+#define MSR_MTRRfix16K_80000 0x258
+#define MSR_MTRRfix16K_A0000 0x259
+#define MSR_MTRRfix4K_C0000 0x268
+#define MSR_MTRRfix4K_C8000 0x269
+#define MSR_MTRRfix4K_D0000 0x26a
+#define MSR_MTRRfix4K_D8000 0x26b
+#define MSR_MTRRfix4K_E0000 0x26c
+#define MSR_MTRRfix4K_E8000 0x26d
+#define MSR_MTRRfix4K_F0000 0x26e
+#define MSR_MTRRfix4K_F8000 0x26f
+#define MSR_MTRRdefType 0x2ff
+
#define MSR_IA32_MC0_CTL 0x400
#define MSR_IA32_MC0_STATUS 0x401
#define MSR_IA32_MC0_ADDR 0x402
@@ -171,11 +185,4 @@
#define MSR_IA32_APICBASE_ENABLE (1<<11)
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
-
-#define MSR_IA32_THERM_CONTROL 0x19a
-#define MSR_IA32_THERM_INTERRUPT 0x19b
-#define MSR_IA32_THERM_STATUS 0x19c
-#define MSR_IA32_MISC_ENABLE 0x1a0
-
-
#endif
diff --git a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h
index ff3ea870d0d6..6505d7bd6ece 100644
--- a/include/asm-x86_64/mtrr.h
+++ b/include/asm-x86_64/mtrr.h
@@ -30,16 +30,16 @@
struct mtrr_sentry
{
- unsigned long base; /* Base address */
- unsigned long size; /* Size of region */
+ __u64 base; /* Base address */
+ __u32 size; /* Size of region */
unsigned int type; /* Type of region */
};
struct mtrr_gentry
{
+ __u64 base; /* Base address */
+ __u32 size; /* Size of region */
unsigned int regnum; /* Register number */
- unsigned long base; /* Base address */
- unsigned long size; /* Size of region */
unsigned int type; /* Type of region */
};
@@ -81,46 +81,38 @@ static char *mtrr_strings[MTRR_NUM_TYPES] =
#ifdef __KERNEL__
/* The following functions are for use by other drivers */
-# ifdef CONFIG_MTRR
-extern int mtrr_add (unsigned long base, unsigned long size,
- unsigned int type, char increment);
-extern int mtrr_add_page (unsigned long base, unsigned long size,
- unsigned int type, char increment);
-extern int mtrr_del (int reg, unsigned long base, unsigned long size);
-extern int mtrr_del_page (int reg, unsigned long base, unsigned long size);
-extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
-# else
-static __inline__ int mtrr_add (unsigned long base, unsigned long size,
+#ifdef CONFIG_MTRR
+extern int mtrr_add (__u64 base, __u32 size, unsigned int type, char increment);
+extern int mtrr_add_page (__u64 base, __u32 size, unsigned int type, char increment);
+extern int mtrr_del (int reg, __u64 base, __u32 size);
+extern int mtrr_del_page (int reg, __u64 base, __u32 size);
+#else
+static __inline__ int mtrr_add (__u64 base, __u32 size,
unsigned int type, char increment)
{
return -ENODEV;
}
-static __inline__ int mtrr_add_page (unsigned long base, unsigned long size,
+static __inline__ int mtrr_add_page (__u64 base, __u32 size,
unsigned int type, char increment)
{
return -ENODEV;
}
-static __inline__ int mtrr_del (int reg, unsigned long base,
- unsigned long size)
+static __inline__ int mtrr_del (int reg, __u64 base, __u32 size)
{
return -ENODEV;
}
-static __inline__ int mtrr_del_page (int reg, unsigned long base,
- unsigned long size)
+static __inline__ int mtrr_del_page (int reg, __u64 base, __u32 size)
{
return -ENODEV;
}
-
-static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;}
-
-# endif
+#endif
/* The following functions are for initialisation: don't use them! */
extern int mtrr_init (void);
-# if defined(CONFIG_SMP) && defined(CONFIG_MTRR)
+#if defined(CONFIG_SMP) && defined(CONFIG_MTRR)
extern void mtrr_init_boot_cpu (void);
extern void mtrr_init_secondary_cpu (void);
-# endif
+#endif
#endif
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index 7ff508346013..eb38cf70fb90 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -22,6 +22,8 @@ struct x8664_pda {
unsigned int __local_bh_count;
unsigned int __nmi_count; /* arch dependent */
struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
+ struct mm_struct *active_mm;
+ int mmu_state;
} ____cacheline_aligned;
#define PDA_STACKOFFSET (5*8)
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 4cda0f055a5f..03875338aedf 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -45,21 +45,12 @@ struct cpuinfo_x86 {
__u8 x86_vendor; /* CPU vendor */
__u8 x86_model;
__u8 x86_mask;
- /* We know that wp_works_ok = 1, hlt_works_ok = 1, hard_math = 1,
- etc... */
- char wp_works_ok; /* It doesn't on 386's */
- char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */
- char hard_math;
- char rfu;
int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */
__u32 x86_capability[NCAPINTS];
char x86_vendor_id[16];
char x86_model_id[64];
int x86_cache_size; /* in KB - valid for CPUS which support this
call */
- int fdiv_bug;
- int f00f_bug;
- int coma_bug;
unsigned long loops_per_jiffy;
} ____cacheline_aligned;
@@ -323,7 +314,7 @@ struct thread_struct {
/* IO permissions. the bitmap could be moved into the GDT, that would make
switch faster for a limited number of ioperm using tasks. -AK */
int ioperm;
- u32 io_bitmap[IO_BITMAP_SIZE+1];
+ u32 *io_bitmap_ptr;
};
#define INIT_THREAD { \
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
index 6f1d71c65a68..a276217b88a3 100644
--- a/include/asm-x86_64/spinlock.h
+++ b/include/asm-x86_64/spinlock.h
@@ -15,7 +15,7 @@ extern int printk(const char * fmt, ...)
typedef struct {
volatile unsigned int lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
+#if SPINLOCK_DEBUG
unsigned magic;
#endif
} spinlock_t;
@@ -39,7 +39,7 @@ typedef struct {
* We make no fairness assumptions. They have a cost.
*/
-#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0)
+#define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0)
#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
#define spin_lock_string \
@@ -62,7 +62,7 @@ typedef struct {
static inline int _raw_spin_trylock(spinlock_t *lock)
{
- char oldval;
+ signed char oldval;
__asm__ __volatile__(
"xchgb %b0,%1"
:"=q" (oldval), "=m" (lock->lock)
diff --git a/include/asm-x86_64/string.h b/include/asm-x86_64/string.h
index ec456eadb674..27876b9da06a 100644
--- a/include/asm-x86_64/string.h
+++ b/include/asm-x86_64/string.h
@@ -40,18 +40,9 @@ extern void *__memcpy(void *to, const void *from, size_t len);
__ret = __builtin_memcpy((dst),(src),__len); \
__ret; })
-#if 0
+
#define __HAVE_ARCH_MEMSET
-extern void *__memset(void *mem, int val, size_t len);
-#define memset(dst,val,len) \
- ({ size_t __len = (len); \
- void *__ret; \
- if (__builtin_constant_p(len) && __len >= 64) \
- __ret = __memset((dst),(val),__len); \
- else \
- __ret = __builtin_memset((dst),(val),__len); \
- __ret; })
-#endif
+#define memset __builtin_memset
#define __HAVE_ARCH_MEMMOVE
void * memmove(void * dest,const void *src,size_t count);
diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h
new file mode 100644
index 000000000000..9f065f8fe33d
--- /dev/null
+++ b/include/asm-x86_64/suspend.h
@@ -0,0 +1,6 @@
+#ifndef SUSPEND_H
+#define SUSPEND_H 1
+
+/* dummy for now */
+
+#endif
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 1df84d087823..9d6c6f1f48d5 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -13,7 +13,10 @@
#define LOCK_PREFIX ""
#endif
-#define prepare_to_switch() do {} while(0)
+#define prepare_arch_schedule(prev) do { } while(0)
+#define finish_arch_schedule(prev) do { } while(0)
+#define prepare_arch_switch(rq) do { } while(0)
+#define finish_arch_switch(rq) spin_unlock_irq(&(rq)->lock)
#define __STR(x) #x
#define STR(x) __STR(x)
@@ -41,7 +44,7 @@
__POP(rax) __POP(r15) __POP(r14) __POP(r13) __POP(r12) __POP(r11) __POP(r10) \
__POP(r9) __POP(r8)
-#define switch_to(prev,next) \
+#define switch_to(prev,next,last) \
asm volatile(SAVE_CONTEXT \
"movq %%rsp,%[prevrsp]\n\t" \
"movq %[nextrsp],%%rsp\n\t" \
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
index b87680d9e51a..98bddc2d805a 100644
--- a/include/asm-x86_64/timex.h
+++ b/include/asm-x86_64/timex.h
@@ -48,6 +48,4 @@ static inline cycles_t get_cycles (void)
extern unsigned int cpu_khz;
-#define ARCH_HAS_JIFFIES_64
-
#endif
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86_64/tlbflush.h
index 3f086b2d03b3..2e811ac262af 100644
--- a/include/asm-x86_64/tlbflush.h
+++ b/include/asm-x86_64/tlbflush.h
@@ -106,15 +106,6 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
#define TLBSTATE_OK 1
#define TLBSTATE_LAZY 2
-struct tlb_state
-{
- struct mm_struct *active_mm;
- int state;
- char __cacheline_padding[24];
-};
-extern struct tlb_state cpu_tlbstate[NR_CPUS];
-
-
#endif
#define flush_tlb_kernel_range(start, end) flush_tlb_all()