summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-12-04 19:23:34 -0800
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-04 19:23:34 -0800
commit91f433cacc9d1ae95ae46ce26d7bcf3a724c72d0 (patch)
tree058a5961548d489fdaffdbcfb7b34893946d37cf
parent15a4cb9c25df05a5d4844e80a1aea83d66165868 (diff)
parent0004a9dfeaa709a7f853487aba19932c9b1a87c8 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] Cleanup memory barriers for weakly ordered systems. [MIPS] Alchemy: Automatically enable CONFIG_RESOURCES_64BIT for PCI configs. [MIPS] Unify csum_partial.S [MIPS] SWARM: Fix a typo in #error directives [MIPS] Fix atomic.h build errors. [MIPS] Use SYSVIPC_COMPAT to fix various problems on N32 [MIPS] klconfig add missing bracket
-rw-r--r--arch/mips/Kconfig18
-rw-r--r--arch/mips/kernel/linux32.c578
-rw-r--r--arch/mips/kernel/scall64-n32.S14
-rw-r--r--arch/mips/kernel/smp.c6
-rw-r--r--arch/mips/lib-32/Makefile2
-rw-r--r--arch/mips/lib-32/csum_partial.S240
-rw-r--r--arch/mips/lib-64/Makefile2
-rw-r--r--arch/mips/lib-64/csum_partial.S242
-rw-r--r--arch/mips/lib/Makefile4
-rw-r--r--arch/mips/lib/csum_partial.S258
-rw-r--r--arch/mips/sibyte/swarm/setup.c8
-rw-r--r--include/asm-mips/atomic.h39
-rw-r--r--include/asm-mips/barrier.h132
-rw-r--r--include/asm-mips/bitops.h27
-rw-r--r--include/asm-mips/compat.h68
-rw-r--r--include/asm-mips/futex.h22
-rw-r--r--include/asm-mips/sn/klconfig.h2
-rw-r--r--include/asm-mips/spinlock.h53
-rw-r--r--include/asm-mips/system.h156
19 files changed, 605 insertions, 1266 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 27f83e642968..4d64960be035 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -16,6 +16,7 @@ config MIPS_MTX1
bool "4G Systems MTX-1 board"
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
select SOC_AU1500
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -32,6 +33,7 @@ config MIPS_PB1000
select SOC_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
select SWAP_IO_SPACE
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -41,6 +43,7 @@ config MIPS_PB1100
select SOC_AU1100
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
select SWAP_IO_SPACE
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -50,6 +53,7 @@ config MIPS_PB1500
select SOC_AU1500
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -59,6 +63,7 @@ config MIPS_PB1550
select DMA_NONCOHERENT
select HW_HAS_PCI
select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -67,6 +72,7 @@ config MIPS_PB1200
select SOC_AU1200
select DMA_NONCOHERENT
select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -75,6 +81,7 @@ config MIPS_DB1000
select SOC_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -91,6 +98,7 @@ config MIPS_DB1500
select DMA_NONCOHERENT
select HW_HAS_PCI
select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -101,6 +109,7 @@ config MIPS_DB1550
select HW_HAS_PCI
select DMA_NONCOHERENT
select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -1268,6 +1277,7 @@ config CPU_RM9000
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
+ select WEAK_ORDERING
config CPU_SB1
bool "SB1"
@@ -1276,6 +1286,7 @@ config CPU_SB1
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
+ select WEAK_ORDERING
endchoice
@@ -1336,6 +1347,8 @@ config SYS_HAS_CPU_RM9000
config SYS_HAS_CPU_SB1
bool
+config WEAK_ORDERING
+ bool
endmenu
#
@@ -1940,6 +1953,11 @@ config COMPAT
depends on MIPS32_COMPAT
default y
+config SYSVIPC_COMPAT
+ bool
+ depends on COMPAT && SYSVIPC
+ default y
+
config MIPS32_O32
bool "Kernel support for o32 binaries"
depends on MIPS32_COMPAT
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 7a3ebbeba1f3..b061c9aa6302 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -382,531 +382,6 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
return ret;
}
-struct msgbuf32 { s32 mtype; char mtext[1]; };
-
-struct ipc_perm32
-{
- key_t key;
- __compat_uid_t uid;
- __compat_gid_t gid;
- __compat_uid_t cuid;
- __compat_gid_t cgid;
- compat_mode_t mode;
- unsigned short seq;
-};
-
-struct ipc64_perm32 {
- key_t key;
- __compat_uid_t uid;
- __compat_gid_t gid;
- __compat_uid_t cuid;
- __compat_gid_t cgid;
- compat_mode_t mode;
- unsigned short seq;
- unsigned short __pad1;
- unsigned int __unused1;
- unsigned int __unused2;
-};
-
-struct semid_ds32 {
- struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- compat_time_t sem_otime; /* last semop time */
- compat_time_t 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;
- compat_time_t sem_otime;
- compat_time_t sem_ctime;
- unsigned int sem_nsems;
- unsigned int __unused1;
- unsigned int __unused2;
-};
-
-struct msqid_ds32
-{
- struct ipc_perm32 msg_perm;
- u32 msg_first;
- u32 msg_last;
- compat_time_t msg_stime;
- compat_time_t msg_rtime;
- compat_time_t msg_ctime;
- u32 wwait;
- u32 rwait;
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- compat_ipc_pid_t msg_lspid;
- compat_ipc_pid_t msg_lrpid;
-};
-
-struct msqid64_ds32 {
- struct ipc64_perm32 msg_perm;
- compat_time_t msg_stime;
- unsigned int __unused1;
- compat_time_t msg_rtime;
- unsigned int __unused2;
- compat_time_t msg_ctime;
- unsigned int __unused3;
- unsigned int msg_cbytes;
- unsigned int msg_qnum;
- unsigned int msg_qbytes;
- compat_pid_t msg_lspid;
- compat_pid_t msg_lrpid;
- unsigned int __unused4;
- unsigned int __unused5;
-};
-
-struct shmid_ds32 {
- struct ipc_perm32 shm_perm;
- int shm_segsz;
- compat_time_t shm_atime;
- compat_time_t shm_dtime;
- compat_time_t shm_ctime;
- compat_ipc_pid_t shm_cpid;
- compat_ipc_pid_t shm_lpid;
- unsigned short shm_nattch;
-};
-
-struct shmid64_ds32 {
- struct ipc64_perm32 shm_perm;
- compat_size_t shm_segsz;
- compat_time_t shm_atime;
- compat_time_t shm_dtime;
- compat_time_t shm_ctime;
- compat_pid_t shm_cpid;
- compat_pid_t shm_lpid;
- unsigned int shm_nattch;
- unsigned int __unused1;
- unsigned int __unused2;
-};
-
-struct ipc_kludge32 {
- u32 msgp;
- s32 msgtyp;
-};
-
-static int
-do_sys32_semctl(int first, int second, int third, void __user *uptr)
-{
- union semun fourth;
- u32 pad;
- int err, err2;
- struct semid64_ds s;
- mm_segment_t old_fs;
-
- if (!uptr)
- return -EINVAL;
- err = -EFAULT;
- if (get_user (pad, (u32 __user *)uptr))
- return err;
- if ((third & ~IPC_64) == SETVAL)
- fourth.val = (int)pad;
- else
- fourth.__pad = (void __user *)A(pad);
- switch (third & ~IPC_64) {
- 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 = (struct semid64_ds __user *)&s;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_semctl(first, second, third | IPC_64, fourth);
- set_fs(old_fs);
-
- if (third & IPC_64) {
- struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) 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 __user *usp32 = (struct semid_ds32 __user *) 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;
-
- default:
- err = - EINVAL;
- break;
- }
-
- return err;
-}
-
-static int
-do_sys32_msgsnd (int first, int second, int third, void __user *uptr)
-{
- struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr;
- struct msgbuf *p;
- mm_segment_t old_fs;
- int err;
-
- if (second < 0)
- return -EINVAL;
- p = kmalloc (second + sizeof (struct msgbuf)
- + 4, GFP_USER);
- if (!p)
- return -ENOMEM;
- err = get_user (p->mtype, &up->mtype);
- if (err)
- goto out;
- 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, (struct msgbuf __user *)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 __user *uptr)
-{
- struct msgbuf32 __user *up;
- struct msgbuf *p;
- mm_segment_t old_fs;
- int err;
-
- if (!version) {
- struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr;
- struct ipc_kludge32 ipck;
-
- err = -EINVAL;
- if (!uptr)
- goto out;
- err = -EFAULT;
- if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
- goto out;
- uptr = (void __user *)AA(ipck.msgp);
- msgtyp = ipck.msgtyp;
- }
-
- if (second < 0)
- return -EINVAL;
- 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, (struct msgbuf __user *)p, second + 4, msgtyp, third);
- set_fs (old_fs);
- if (err < 0)
- goto free_then_out;
- up = (struct msgbuf32 __user *)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
-do_sys32_msgctl (int first, int second, void __user *uptr)
-{
- int err = -EINVAL, err2;
- struct msqid64_ds m;
- struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr;
- struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr;
- mm_segment_t old_fs;
-
- switch (second & ~IPC_64) {
- case IPC_INFO:
- case IPC_RMID:
- case MSG_INFO:
- err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr);
- break;
-
- case IPC_SET:
- if (second & IPC_64) {
- if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
- err = -EFAULT;
- break;
- }
- 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 {
- if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
- err = -EFAULT;
- break;
- }
- 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 | IPC_64, (struct msqid_ds __user *)&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, (struct msqid_ds __user *)&m);
- set_fs(old_fs);
- if (second & IPC_64) {
- if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
- err = -EFAULT;
- break;
- }
- err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
- err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
- err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
- err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
- err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
- err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
- err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
- err2 |= __put_user(m.msg_stime, &up64->msg_stime);
- err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
- err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
- err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
- err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
- err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
- err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
- err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
- if (err2)
- err = -EFAULT;
- } else {
- if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
- err = -EFAULT;
- break;
- }
- err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
- err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
- err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
- err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
- err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
- err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
- err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
- err2 |= __put_user(m.msg_stime, &up32->msg_stime);
- err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
- err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
- err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
- err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
- err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
- err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
- err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
- if (err2)
- err = -EFAULT;
- }
- break;
- }
-
- return err;
-}
-
-static int
-do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
-{
- unsigned long raddr;
- u32 __user *uaddr = (u32 __user *)A((u32)third);
- int err = -EINVAL;
-
- if (version == 1)
- return err;
- err = do_shmat (first, uptr, second, &raddr);
- if (err)
- return err;
- err = put_user (raddr, uaddr);
- return err;
-}
-
-struct shm_info32 {
- int used_ids;
- u32 shm_tot, shm_rss, shm_swp;
- u32 swap_attempts, swap_successes;
-};
-
-static int
-do_sys32_shmctl (int first, int second, void __user *uptr)
-{
- struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr;
- struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr;
- struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr;
- int err = -EFAULT, err2;
- struct shmid64_ds s64;
- mm_segment_t old_fs;
- struct shm_info si;
- struct shmid_ds s;
-
- switch (second & ~IPC_64) {
- case IPC_INFO:
- second = IPC_INFO; /* So that we don't have to translate it */
- case IPC_RMID:
- case SHM_LOCK:
- case SHM_UNLOCK:
- err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr);
- break;
- case IPC_SET:
- if (second & IPC_64) {
- 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 {
- 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 & ~IPC_64, (struct shmid_ds __user *)&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 __user *) &s64);
- set_fs(old_fs);
- if (err < 0)
- break;
- if (second & IPC_64) {
- if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
- err = -EFAULT;
- break;
- }
- 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 {
- if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
- err = -EFAULT;
- break;
- }
- 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);
- }
- if (err2)
- err = -EFAULT;
- break;
-
- case SHM_INFO:
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_shmctl(first, second, (void __user *)&si);
- set_fs(old_fs);
- if (err < 0)
- 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;
-
- default:
- err = -EINVAL;
- break;
- }
-
- return err;
-}
-
-static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems,
- const struct compat_timespec __user *timeout32)
-{
- struct compat_timespec t32;
- struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64));
-
- if (copy_from_user(&t32, timeout32, sizeof(t32)))
- return -EFAULT;
-
- if (put_user(t32.tv_sec, &t64->tv_sec) ||
- put_user(t32.tv_nsec, &t64->tv_nsec))
- return -EFAULT;
-
- return sys_semtimedop(semid, tsems, nsems, t64);
-}
-
asmlinkage long
sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
{
@@ -918,48 +393,43 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
switch (call) {
case SEMOP:
/* struct sembuf is the same on 32 and 64bit :)) */
- err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
- NULL);
+ err = sys_semtimedop(first, compat_ptr(ptr), second, NULL);
break;
case SEMTIMEDOP:
- err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
- (const struct compat_timespec __user *)AA(fifth));
+ err = compat_sys_semtimedop(first, compat_ptr(ptr), second,
+ compat_ptr(fifth));
break;
case SEMGET:
- err = sys_semget (first, second, third);
+ err = sys_semget(first, second, third);
break;
case SEMCTL:
- err = do_sys32_semctl (first, second, third,
- (void __user *)AA(ptr));
+ err = compat_sys_semctl(first, second, third, compat_ptr(ptr));
break;
-
case MSGSND:
- err = do_sys32_msgsnd (first, second, third,
- (void __user *)AA(ptr));
+ err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
break;
case MSGRCV:
- err = do_sys32_msgrcv (first, second, fifth, third,
- version, (void __user *)AA(ptr));
+ err = compat_sys_msgrcv(first, second, fifth, third,
+ version, compat_ptr(ptr));
break;
case MSGGET:
- err = sys_msgget ((key_t) first, second);
+ err = sys_msgget((key_t) first, second);
break;
case MSGCTL:
- err = do_sys32_msgctl (first, second, (void __user *)AA(ptr));
+ err = compat_sys_msgctl(first, second, compat_ptr(ptr));
break;
-
case SHMAT:
- err = do_sys32_shmat (first, second, third,
- version, (void __user *)AA(ptr));
+ err = compat_sys_shmat(first, second, third, version,
+ compat_ptr(ptr));
break;
case SHMDT:
- err = sys_shmdt ((char __user *)A(ptr));
+ err = sys_shmdt(compat_ptr(ptr));
break;
case SHMGET:
- err = sys_shmget (first, (unsigned)second, third);
+ err = sys_shmget(first, (unsigned)second, third);
break;
case SHMCTL:
- err = do_sys32_shmctl (first, second, (void __user *)AA(ptr));
+ err = compat_sys_shmctl(first, second, compat_ptr(ptr));
break;
default:
err = -EINVAL;
@@ -969,18 +439,16 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
return err;
}
-asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,
- int shmflg, int32_t __user *addr)
+#ifdef CONFIG_MIPS32_N32
+asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg)
{
- unsigned long raddr;
- int err;
-
- err = do_shmat(shmid, shmaddr, shmflg, &raddr);
- if (err)
- return err;
-
- return put_user(raddr, addr);
+ /* compat_sys_semctl expects a pointer to union semun */
+ u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
+ if (put_user(ptr_to_compat(arg.__pad), uptr))
+ return -EFAULT;
+ return compat_sys_semctl(semid, semnum, cmd, uptr);
}
+#endif
struct sysctl_args32
{
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 5b18f265d75b..34567d81f940 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -149,8 +149,8 @@ EXPORT(sysn32_call_table)
PTR sys_mincore
PTR sys_madvise
PTR sys_shmget
- PTR sys32_shmat
- PTR sys_shmctl /* 6030 */
+ PTR sys_shmat
+ PTR compat_sys_shmctl /* 6030 */
PTR sys_dup
PTR sys_dup2
PTR sys_pause
@@ -184,12 +184,12 @@ EXPORT(sysn32_call_table)
PTR sys32_newuname
PTR sys_semget
PTR sys_semop
- PTR sys_semctl
+ PTR sysn32_semctl
PTR sys_shmdt /* 6065 */
PTR sys_msgget
- PTR sys_msgsnd
- PTR sys_msgrcv
- PTR sys_msgctl
+ PTR compat_sys_msgsnd
+ PTR compat_sys_msgrcv
+ PTR compat_sys_msgctl
PTR compat_sys_fcntl /* 6070 */
PTR sys_flock
PTR sys_fsync
@@ -335,7 +335,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_fcntl64
PTR sys_set_tid_address
PTR sys_restart_syscall
- PTR sys_semtimedop /* 6215 */
+ PTR compat_sys_semtimedop /* 6215 */
PTR sys_fadvise64_64
PTR compat_sys_statfs64
PTR compat_sys_fstatfs64
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 49db516789e0..f2a8701e414d 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -172,7 +172,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
spin_lock(&smp_call_lock);
call_data = &data;
- mb();
+ smp_mb();
/* Send a message to all other CPUs and wait for them to respond */
for_each_online_cpu(i)
@@ -204,7 +204,7 @@ void smp_call_function_interrupt(void)
* Notify initiating CPU that I've grabbed the data and am
* about to execute the function.
*/
- mb();
+ smp_mb();
atomic_inc(&call_data->started);
/*
@@ -215,7 +215,7 @@ void smp_call_function_interrupt(void)
irq_exit();
if (wait) {
- mb();
+ smp_mb();
atomic_inc(&call_data->finished);
}
}
diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile
index ad285786e74b..dcd4d2ed2ac4 100644
--- a/arch/mips/lib-32/Makefile
+++ b/arch/mips/lib-32/Makefile
@@ -2,7 +2,7 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial.o memset.o watch.o
+lib-y += memset.o watch.o
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
diff --git a/arch/mips/lib-32/csum_partial.S b/arch/mips/lib-32/csum_partial.S
deleted file mode 100644
index ea257dbdcc40..000000000000
--- a/arch/mips/lib-32/csum_partial.S
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998 Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-
-#define ADDC(sum,reg) \
- addu sum, reg; \
- sltu v1, sum, reg; \
- addu sum, v1
-
-#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
- lw t0, (offset + 0x00)(src); \
- lw t1, (offset + 0x04)(src); \
- lw t2, (offset + 0x08)(src); \
- lw t3, (offset + 0x0c)(src); \
- ADDC(sum, t0); \
- ADDC(sum, t1); \
- ADDC(sum, t2); \
- ADDC(sum, t3); \
- lw t0, (offset + 0x10)(src); \
- lw t1, (offset + 0x14)(src); \
- lw t2, (offset + 0x18)(src); \
- lw t3, (offset + 0x1c)(src); \
- ADDC(sum, t0); \
- ADDC(sum, t1); \
- ADDC(sum, t2); \
- ADDC(sum, t3); \
-
-/*
- * a0: source address
- * a1: length of the area to checksum
- * a2: partial checksum
- */
-
-#define src a0
-#define dest a1
-#define sum v0
-
- .text
- .set noreorder
-
-/* unknown src alignment and < 8 bytes to go */
-small_csumcpy:
- move a1, t2
-
- andi t0, a1, 4
- beqz t0, 1f
- andi t0, a1, 2
-
- /* Still a full word to go */
- ulw t1, (src)
- addiu src, 4
- ADDC(sum, t1)
-
-1: move t1, zero
- beqz t0, 1f
- andi t0, a1, 1
-
- /* Still a halfword to go */
- ulhu t1, (src)
- addiu src, 2
-
-1: beqz t0, 1f
- sll t1, t1, 16
-
- lbu t2, (src)
- nop
-
-#ifdef __MIPSEB__
- sll t2, t2, 8
-#endif
- or t1, t2
-
-1: ADDC(sum, t1)
-
- /* fold checksum */
- sll v1, sum, 16
- addu sum, v1
- sltu v1, sum, v1
- srl sum, sum, 16
- addu sum, v1
-
- /* odd buffer alignment? */
- beqz t7, 1f
- nop
- sll v1, sum, 8
- srl sum, sum, 8
- or sum, v1
- andi sum, 0xffff
-1:
- .set reorder
- /* Add the passed partial csum. */
- ADDC(sum, a2)
- jr ra
- .set noreorder
-
-/* ------------------------------------------------------------------------- */
-
- .align 5
-LEAF(csum_partial)
- move sum, zero
- move t7, zero
-
- sltiu t8, a1, 0x8
- bnez t8, small_csumcpy /* < 8 bytes to copy */
- move t2, a1
-
- beqz a1, out
- andi t7, src, 0x1 /* odd buffer? */
-
-hword_align:
- beqz t7, word_align
- andi t8, src, 0x2
-
- lbu t0, (src)
- subu a1, a1, 0x1
-#ifdef __MIPSEL__
- sll t0, t0, 8
-#endif
- ADDC(sum, t0)
- addu src, src, 0x1
- andi t8, src, 0x2
-
-word_align:
- beqz t8, dword_align
- sltiu t8, a1, 56
-
- lhu t0, (src)
- subu a1, a1, 0x2
- ADDC(sum, t0)
- sltiu t8, a1, 56
- addu src, src, 0x2
-
-dword_align:
- bnez t8, do_end_words
- move t8, a1
-
- andi t8, src, 0x4
- beqz t8, qword_align
- andi t8, src, 0x8
-
- lw t0, 0x00(src)
- subu a1, a1, 0x4
- ADDC(sum, t0)
- addu src, src, 0x4
- andi t8, src, 0x8
-
-qword_align:
- beqz t8, oword_align
- andi t8, src, 0x10
-
- lw t0, 0x00(src)
- lw t1, 0x04(src)
- subu a1, a1, 0x8
- ADDC(sum, t0)
- ADDC(sum, t1)
- addu src, src, 0x8
- andi t8, src, 0x10
-
-oword_align:
- beqz t8, begin_movement
- srl t8, a1, 0x7
-
- lw t3, 0x08(src)
- lw t4, 0x0c(src)
- lw t0, 0x00(src)
- lw t1, 0x04(src)
- ADDC(sum, t3)
- ADDC(sum, t4)
- ADDC(sum, t0)
- ADDC(sum, t1)
- subu a1, a1, 0x10
- addu src, src, 0x10
- srl t8, a1, 0x7
-
-begin_movement:
- beqz t8, 1f
- andi t2, a1, 0x40
-
-move_128bytes:
- CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
- CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
- CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
- CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
- subu t8, t8, 0x01
- bnez t8, move_128bytes
- addu src, src, 0x80
-
-1:
- beqz t2, 1f
- andi t2, a1, 0x20
-
-move_64bytes:
- CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
- CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
- addu src, src, 0x40
-
-1:
- beqz t2, do_end_words
- andi t8, a1, 0x1c
-
-move_32bytes:
- CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
- andi t8, a1, 0x1c
- addu src, src, 0x20
-
-do_end_words:
- beqz t8, maybe_end_cruft
- srl t8, t8, 0x2
-
-end_words:
- lw t0, (src)
- subu t8, t8, 0x1
- ADDC(sum, t0)
- bnez t8, end_words
- addu src, src, 0x4
-
-maybe_end_cruft:
- andi t2, a1, 0x3
-
-small_memcpy:
- j small_csumcpy; move a1, t2
- beqz t2, out
- move a1, t2
-
-end_bytes:
- lb t0, (src)
- subu a1, a1, 0x1
- bnez a2, end_bytes
- addu src, src, 0x1
-
-out:
- jr ra
- move v0, sum
- END(csum_partial)
diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile
index ad285786e74b..dcd4d2ed2ac4 100644
--- a/arch/mips/lib-64/Makefile
+++ b/arch/mips/lib-64/Makefile
@@ -2,7 +2,7 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial.o memset.o watch.o
+lib-y += memset.o watch.o
obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
diff --git a/arch/mips/lib-64/csum_partial.S b/arch/mips/lib-64/csum_partial.S
deleted file mode 100644
index 25aba660cc9c..000000000000
--- a/arch/mips/lib-64/csum_partial.S
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Quick'n'dirty IP checksum ...
- *
- * Copyright (C) 1998, 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-
-#define ADDC(sum,reg) \
- addu sum, reg; \
- sltu v1, sum, reg; \
- addu sum, v1
-
-#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
- lw t0, (offset + 0x00)(src); \
- lw t1, (offset + 0x04)(src); \
- lw t2, (offset + 0x08)(src); \
- lw t3, (offset + 0x0c)(src); \
- ADDC(sum, t0); \
- ADDC(sum, t1); \
- ADDC(sum, t2); \
- ADDC(sum, t3); \
- lw t0, (offset + 0x10)(src); \
- lw t1, (offset + 0x14)(src); \
- lw t2, (offset + 0x18)(src); \
- lw t3, (offset + 0x1c)(src); \
- ADDC(sum, t0); \
- ADDC(sum, t1); \
- ADDC(sum, t2); \
- ADDC(sum, t3); \
-
-/*
- * a0: source address
- * a1: length of the area to checksum
- * a2: partial checksum
- */
-
-#define src a0
-#define sum v0
-
- .text
- .set noreorder
-
-/* unknown src alignment and < 8 bytes to go */
-small_csumcpy:
- move a1, ta2
-
- andi ta0, a1, 4
- beqz ta0, 1f
- andi ta0, a1, 2
-
- /* Still a full word to go */
- ulw ta1, (src)
- daddiu src, 4
- ADDC(sum, ta1)
-
-1: move ta1, zero
- beqz ta0, 1f
- andi ta0, a1, 1
-
- /* Still a halfword to go */
- ulhu ta1, (src)
- daddiu src, 2
-
-1: beqz ta0, 1f
- sll ta1, ta1, 16
-
- lbu ta2, (src)
- nop
-
-#ifdef __MIPSEB__
- sll ta2, ta2, 8
-#endif
- or ta1, ta2
-
-1: ADDC(sum, ta1)
-
- /* fold checksum */
- sll v1, sum, 16
- addu sum, v1
- sltu v1, sum, v1
- srl sum, sum, 16
- addu sum, v1
-
- /* odd buffer alignment? */
- beqz t3, 1f
- nop
- sll v1, sum, 8
- srl sum, sum, 8
- or sum, v1
- andi sum, 0xffff
-1:
- .set reorder
- /* Add the passed partial csum. */
- ADDC(sum, a2)
- jr ra
- .set noreorder
-
-/* ------------------------------------------------------------------------- */
-
- .align 5
-LEAF(csum_partial)
- move sum, zero
- move t3, zero
-
- sltiu t8, a1, 0x8
- bnez t8, small_csumcpy /* < 8 bytes to copy */
- move ta2, a1
-
- beqz a1, out
- andi t3, src, 0x1 /* odd buffer? */
-
-hword_align:
- beqz t3, word_align
- andi t8, src, 0x2
-
- lbu ta0, (src)
- dsubu a1, a1, 0x1
-#ifdef __MIPSEL__
- sll ta0, ta0, 8
-#endif
- ADDC(sum, ta0)
- daddu src, src, 0x1
- andi t8, src, 0x2
-
-word_align:
- beqz t8, dword_align
- sltiu t8, a1, 56
-
- lhu ta0, (src)
- dsubu a1, a1, 0x2
- ADDC(sum, ta0)
- sltiu t8, a1, 56
- daddu src, src, 0x2
-
-dword_align:
- bnez t8, do_end_words
- move t8, a1
-
- andi t8, src, 0x4
- beqz t8, qword_align
- andi t8, src, 0x8
-
- lw ta0, 0x00(src)
- dsubu a1, a1, 0x4
- ADDC(sum, ta0)
- daddu src, src, 0x4
- andi t8, src, 0x8
-
-qword_align:
- beqz t8, oword_align
- andi t8, src, 0x10
-
- lw ta0, 0x00(src)
- lw ta1, 0x04(src)
- dsubu a1, a1, 0x8
- ADDC(sum, ta0)
- ADDC(sum, ta1)
- daddu src, src, 0x8
- andi t8, src, 0x10
-
-oword_align:
- beqz t8, begin_movement
- dsrl t8, a1, 0x7
-
- lw ta3, 0x08(src)
- lw t0, 0x0c(src)
- lw ta0, 0x00(src)
- lw ta1, 0x04(src)
- ADDC(sum, ta3)
- ADDC(sum, t0)
- ADDC(sum, ta0)
- ADDC(sum, ta1)
- dsubu a1, a1, 0x10
- daddu src, src, 0x10
- dsrl t8, a1, 0x7
-
-begin_movement:
- beqz t8, 1f
- andi ta2, a1, 0x40
-
-move_128bytes:
- CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
- CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
- CSUM_BIGCHUNK(src, 0x40, sum, ta0, ta1, ta3, t0)
- CSUM_BIGCHUNK(src, 0x60, sum, ta0, ta1, ta3, t0)
- dsubu t8, t8, 0x01
- bnez t8, move_128bytes
- daddu src, src, 0x80
-
-1:
- beqz ta2, 1f
- andi ta2, a1, 0x20
-
-move_64bytes:
- CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
- CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
- daddu src, src, 0x40
-
-1:
- beqz ta2, do_end_words
- andi t8, a1, 0x1c
-
-move_32bytes:
- CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
- andi t8, a1, 0x1c
- daddu src, src, 0x20
-
-do_end_words:
- beqz t8, maybe_end_cruft
- dsrl t8, t8, 0x2
-
-end_words:
- lw ta0, (src)
- dsubu t8, t8, 0x1
- ADDC(sum, ta0)
- bnez t8, end_words
- daddu src, src, 0x4
-
-maybe_end_cruft:
- andi ta2, a1, 0x3
-
-small_memcpy:
- j small_csumcpy; move a1, ta2 /* XXX ??? */
- beqz t2, out
- move a1, ta2
-
-end_bytes:
- lb ta0, (src)
- dsubu a1, a1, 0x1
- bnez a2, end_bytes
- daddu src, src, 0x1
-
-out:
- jr ra
- move v0, sum
- END(csum_partial)
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index b225543f5302..888b61ea12fe 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,8 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \
- strnlen_user.o uncached.o
+lib-y += csum_partial.o csum_partial_copy.o memcpy.o promlib.o \
+ strlen_user.o strncpy_user.o strnlen_user.o uncached.o
obj-y += iomap.o
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
new file mode 100644
index 000000000000..15611d9df7ac
--- /dev/null
+++ b/arch/mips/lib/csum_partial.S
@@ -0,0 +1,258 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Quick'n'dirty IP checksum ...
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#ifdef CONFIG_64BIT
+#define T0 ta0
+#define T1 ta1
+#define T2 ta2
+#define T3 ta3
+#define T4 t0
+#define T7 t3
+#else
+#define T0 t0
+#define T1 t1
+#define T2 t2
+#define T3 t3
+#define T4 t4
+#define T7 t7
+#endif
+
+#define ADDC(sum,reg) \
+ addu sum, reg; \
+ sltu v1, sum, reg; \
+ addu sum, v1
+
+#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \
+ lw _t0, (offset + 0x00)(src); \
+ lw _t1, (offset + 0x04)(src); \
+ lw _t2, (offset + 0x08)(src); \
+ lw _t3, (offset + 0x0c)(src); \
+ ADDC(sum, _t0); \
+ ADDC(sum, _t1); \
+ ADDC(sum, _t2); \
+ ADDC(sum, _t3); \
+ lw _t0, (offset + 0x10)(src); \
+ lw _t1, (offset + 0x14)(src); \
+ lw _t2, (offset + 0x18)(src); \
+ lw _t3, (offset + 0x1c)(src); \
+ ADDC(sum, _t0); \
+ ADDC(sum, _t1); \
+ ADDC(sum, _t2); \
+ ADDC(sum, _t3); \
+
+/*
+ * a0: source address
+ * a1: length of the area to checksum
+ * a2: partial checksum
+ */
+
+#define src a0
+#define sum v0
+
+ .text
+ .set noreorder
+
+/* unknown src alignment and < 8 bytes to go */
+small_csumcpy:
+ move a1, T2
+
+ andi T0, a1, 4
+ beqz T0, 1f
+ andi T0, a1, 2
+
+ /* Still a full word to go */
+ ulw T1, (src)
+ PTR_ADDIU src, 4
+ ADDC(sum, T1)
+
+1: move T1, zero
+ beqz T0, 1f
+ andi T0, a1, 1
+
+ /* Still a halfword to go */
+ ulhu T1, (src)
+ PTR_ADDIU src, 2
+
+1: beqz T0, 1f
+ sll T1, T1, 16
+
+ lbu T2, (src)
+ nop
+
+#ifdef __MIPSEB__
+ sll T2, T2, 8
+#endif
+ or T1, T2
+
+1: ADDC(sum, T1)
+
+ /* fold checksum */
+ sll v1, sum, 16
+ addu sum, v1
+ sltu v1, sum, v1
+ srl sum, sum, 16
+ addu sum, v1
+
+ /* odd buffer alignment? */
+ beqz T7, 1f
+ nop
+ sll v1, sum, 8
+ srl sum, sum, 8
+ or sum, v1
+ andi sum, 0xffff
+1:
+ .set reorder
+ /* Add the passed partial csum. */
+ ADDC(sum, a2)
+ jr ra
+ .set noreorder
+
+/* ------------------------------------------------------------------------- */
+
+ .align 5
+LEAF(csum_partial)
+ move sum, zero
+ move T7, zero
+
+ sltiu t8, a1, 0x8
+ bnez t8, small_csumcpy /* < 8 bytes to copy */
+ move T2, a1
+
+ beqz a1, out
+ andi T7, src, 0x1 /* odd buffer? */
+
+hword_align:
+ beqz T7, word_align
+ andi t8, src, 0x2
+
+ lbu T0, (src)
+ LONG_SUBU a1, a1, 0x1
+#ifdef __MIPSEL__
+ sll T0, T0, 8
+#endif
+ ADDC(sum, T0)
+ PTR_ADDU src, src, 0x1
+ andi t8, src, 0x2
+
+word_align:
+ beqz t8, dword_align
+ sltiu t8, a1, 56
+
+ lhu T0, (src)
+ LONG_SUBU a1, a1, 0x2
+ ADDC(sum, T0)
+ sltiu t8, a1, 56
+ PTR_ADDU src, src, 0x2
+
+dword_align:
+ bnez t8, do_end_words
+ move t8, a1
+
+ andi t8, src, 0x4
+ beqz t8, qword_align
+ andi t8, src, 0x8
+
+ lw T0, 0x00(src)
+ LONG_SUBU a1, a1, 0x4
+ ADDC(sum, T0)
+ PTR_ADDU src, src, 0x4
+ andi t8, src, 0x8
+
+qword_align:
+ beqz t8, oword_align
+ andi t8, src, 0x10
+
+ lw T0, 0x00(src)
+ lw T1, 0x04(src)
+ LONG_SUBU a1, a1, 0x8
+ ADDC(sum, T0)
+ ADDC(sum, T1)
+ PTR_ADDU src, src, 0x8
+ andi t8, src, 0x10
+
+oword_align:
+ beqz t8, begin_movement
+ LONG_SRL t8, a1, 0x7
+
+ lw T3, 0x08(src)
+ lw T4, 0x0c(src)
+ lw T0, 0x00(src)
+ lw T1, 0x04(src)
+ ADDC(sum, T3)
+ ADDC(sum, T4)
+ ADDC(sum, T0)
+ ADDC(sum, T1)
+ LONG_SUBU a1, a1, 0x10
+ PTR_ADDU src, src, 0x10
+ LONG_SRL t8, a1, 0x7
+
+begin_movement:
+ beqz t8, 1f
+ andi T2, a1, 0x40
+
+move_128bytes:
+ CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
+ CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4)
+ CSUM_BIGCHUNK(src, 0x40, sum, T0, T1, T3, T4)
+ CSUM_BIGCHUNK(src, 0x60, sum, T0, T1, T3, T4)
+ LONG_SUBU t8, t8, 0x01
+ bnez t8, move_128bytes
+ PTR_ADDU src, src, 0x80
+
+1:
+ beqz T2, 1f
+ andi T2, a1, 0x20
+
+move_64bytes:
+ CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
+ CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4)
+ PTR_ADDU src, src, 0x40
+
+1:
+ beqz T2, do_end_words
+ andi t8, a1, 0x1c
+
+move_32bytes:
+ CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
+ andi t8, a1, 0x1c
+ PTR_ADDU src, src, 0x20
+
+do_end_words:
+ beqz t8, maybe_end_cruft
+ LONG_SRL t8, t8, 0x2
+
+end_words:
+ lw T0, (src)
+ LONG_SUBU t8, t8, 0x1
+ ADDC(sum, T0)
+ bnez t8, end_words
+ PTR_ADDU src, src, 0x4
+
+maybe_end_cruft:
+ andi T2, a1, 0x3
+
+small_memcpy:
+ j small_csumcpy; move a1, T2 /* XXX ??? */
+ beqz t2, out
+ move a1, T2
+
+end_bytes:
+ lb T0, (src)
+ LONG_SUBU a1, a1, 0x1
+ bnez a2, end_bytes
+ PTR_ADDU src, src, 0x1
+
+out:
+ jr ra
+ move v0, sum
+ END(csum_partial)
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index ac342f5643c9..defa1f1452ad 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -43,7 +43,7 @@
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
#include <asm/sibyte/sb1250_regs.h>
#else
-#error invalid SiByte board configuation
+#error invalid SiByte board configuration
#endif
#include <asm/sibyte/sb1250_genbus.h>
#include <asm/sibyte/board.h>
@@ -53,7 +53,7 @@ extern void bcm1480_setup(void);
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
extern void sb1250_setup(void);
#else
-#error invalid SiByte board configuation
+#error invalid SiByte board configuration
#endif
extern int xicor_probe(void);
@@ -90,7 +90,7 @@ void __init plat_timer_setup(struct irqaction *irq)
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
sb1250_time_init();
#else
-#error invalid SiByte board configuation
+#error invalid SiByte board configuration
#endif
}
@@ -111,7 +111,7 @@ void __init plat_mem_setup(void)
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
sb1250_setup();
#else
-#error invalid SiByte board configuation
+#error invalid SiByte board configuration
#endif
panic_timeout = 5; /* For debug. */
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 7978d8e11647..c1a2409bb52a 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -15,6 +15,7 @@
#define _ASM_ATOMIC_H
#include <linux/irqflags.h>
+#include <asm/barrier.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
@@ -130,6 +131,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
{
unsigned long result;
+ smp_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
@@ -140,7 +143,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
" sc %0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -155,7 +157,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
" sc %0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -170,6 +171,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
local_irq_restore(flags);
}
+ smp_mb();
+
return result;
}
@@ -177,6 +180,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
{
unsigned long result;
+ smp_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
@@ -187,7 +192,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
" sc %0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -202,7 +206,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
" sc %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -217,6 +220,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
local_irq_restore(flags);
}
+ smp_mb();
+
return result;
}
@@ -232,6 +237,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
{
unsigned long result;
+ smp_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
@@ -245,7 +252,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
" .set reorder \n"
- " sync \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -264,7 +270,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
" .set reorder \n"
- " sync \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -281,6 +286,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
local_irq_restore(flags);
}
+ smp_mb();
+
return result;
}
@@ -375,7 +382,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
#ifdef CONFIG_64BIT
-typedef struct { volatile __s64 counter; } atomic64_t;
+typedef struct { volatile long counter; } atomic64_t;
#define ATOMIC64_INIT(i) { (i) }
@@ -484,6 +491,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
{
unsigned long result;
+ smp_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
@@ -494,7 +503,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
" scd %0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -509,7 +517,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
" scd %0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -524,6 +531,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
local_irq_restore(flags);
}
+ smp_mb();
+
return result;
}
@@ -531,6 +540,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
{
unsigned long result;
+ smp_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
@@ -541,7 +552,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
" scd %0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -556,7 +566,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
" scd %0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
- " sync \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter)
@@ -571,6 +580,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
local_irq_restore(flags);
}
+ smp_mb();
+
return result;
}
@@ -586,6 +597,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
{
unsigned long result;
+ smp_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
@@ -599,7 +612,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" beqzl %0, 1b \n"
" dsubu %0, %1, %3 \n"
" .set reorder \n"
- " sync \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -618,7 +630,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
" beqz %0, 1b \n"
" dsubu %0, %1, %3 \n"
" .set reorder \n"
- " sync \n"
"1: \n"
" .set mips0 \n"
: "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -635,6 +646,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
local_irq_restore(flags);
}
+ smp_mb();
+
return result;
}
diff --git a/include/asm-mips/barrier.h b/include/asm-mips/barrier.h
new file mode 100644
index 000000000000..ed82631b0017
--- /dev/null
+++ b/include/asm-mips/barrier.h
@@ -0,0 +1,132 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_BARRIER_H
+#define __ASM_BARRIER_H
+
+/*
+ * read_barrier_depends - Flush all pending reads that subsequents reads
+ * depend on.
+ *
+ * No data-dependent reads from memory-like regions are ever reordered
+ * over this barrier. All reads preceding this primitive are guaranteed
+ * to access memory (but not necessarily other CPUs' caches) before any
+ * reads following this primitive that depend on the data return by
+ * any of the preceding reads. This primitive is much lighter weight than
+ * rmb() on most CPUs, and is never heavier weight than is
+ * rmb().
+ *
+ * These ordering constraints are respected by both the local CPU
+ * and the compiler.
+ *
+ * Ordering is not guaranteed by anything other than these primitives,
+ * not even by data dependencies. See the documentation for
+ * memory_barrier() for examples and URLs to more information.
+ *
+ * For example, the following code would force ordering (the initial
+ * value of "a" is zero, "b" is one, and "p" is "&a"):
+ *
+ * <programlisting>
+ * CPU 0 CPU 1
+ *
+ * b = 2;
+ * memory_barrier();
+ * p = &b; q = p;
+ * read_barrier_depends();
+ * d = *q;
+ * </programlisting>
+ *
+ * because the read of "*q" depends on the read of "p" and these
+ * two reads are separated by a read_barrier_depends(). However,
+ * the following code, with the same initial values for "a" and "b":
+ *
+ * <programlisting>
+ * CPU 0 CPU 1
+ *
+ * a = 2;
+ * memory_barrier();
+ * b = 3; y = b;
+ * read_barrier_depends();
+ * x = a;
+ * </programlisting>
+ *
+ * does not enforce ordering, since there is no data dependency between
+ * the read of "a" and the read of "b". Therefore, on some CPUs, such
+ * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
+ * in cases like this where there are no data dependencies.
+ */
+
+#define read_barrier_depends() do { } while(0)
+#define smp_read_barrier_depends() do { } while(0)
+
+#ifdef CONFIG_CPU_HAS_SYNC
+#define __sync() \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ ".set mips2\n\t" \
+ "sync\n\t" \
+ ".set pop" \
+ : /* no output */ \
+ : /* no input */ \
+ : "memory")
+#else
+#define __sync() do { } while(0)
+#endif
+
+#define __fast_iob() \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "lw $0,%0\n\t" \
+ "nop\n\t" \
+ ".set pop" \
+ : /* no output */ \
+ : "m" (*(int *)CKSEG1) \
+ : "memory")
+
+#define fast_wmb() __sync()
+#define fast_rmb() __sync()
+#define fast_mb() __sync()
+#define fast_iob() \
+ do { \
+ __sync(); \
+ __fast_iob(); \
+ } while (0)
+
+#ifdef CONFIG_CPU_HAS_WB
+
+#include <asm/wbflush.h>
+
+#define wmb() fast_wmb()
+#define rmb() fast_rmb()
+#define mb() wbflush()
+#define iob() wbflush()
+
+#else /* !CONFIG_CPU_HAS_WB */
+
+#define wmb() fast_wmb()
+#define rmb() fast_rmb()
+#define mb() fast_mb()
+#define iob() fast_iob()
+
+#endif /* !CONFIG_CPU_HAS_WB */
+
+#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
+#define __WEAK_ORDERING_MB " sync \n"
+#else
+#define __WEAK_ORDERING_MB " \n"
+#endif
+
+#define smp_mb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
+#define smp_rmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
+#define smp_wmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
+
+#define set_mb(var, value) \
+ do { var = value; smp_mb(); } while (0)
+
+#endif /* __ASM_BARRIER_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index b9007411b60f..06445de1324b 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 1994 - 1997, 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (c) 1994 - 1997, 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
* Copyright (c) 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_BITOPS_H
@@ -12,6 +12,7 @@
#include <linux/compiler.h>
#include <linux/irqflags.h>
#include <linux/types.h>
+#include <asm/barrier.h>
#include <asm/bug.h>
#include <asm/byteorder.h> /* sigh ... */
#include <asm/cpu-features.h>
@@ -204,9 +205,6 @@ static inline int test_and_set_bit(unsigned long nr,
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -226,9 +224,6 @@ static inline int test_and_set_bit(unsigned long nr,
" " __SC "%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -250,6 +245,8 @@ static inline int test_and_set_bit(unsigned long nr,
return retval;
}
+
+ smp_mb();
}
/*
@@ -275,9 +272,6 @@ static inline int test_and_clear_bit(unsigned long nr,
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -298,9 +292,6 @@ static inline int test_and_clear_bit(unsigned long nr,
" " __SC "%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -322,6 +313,8 @@ static inline int test_and_clear_bit(unsigned long nr,
return retval;
}
+
+ smp_mb();
}
/*
@@ -346,9 +339,6 @@ static inline int test_and_change_bit(unsigned long nr,
" " __SC "%2, %1 \n"
" beqzl %2, 1b \n"
" and %2, %0, %3 \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -368,9 +358,6 @@ static inline int test_and_change_bit(unsigned long nr,
" " __SC "\t%2, %1 \n"
" beqz %2, 1b \n"
" and %2, %0, %3 \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set pop \n"
: "=&r" (temp), "=m" (*m), "=&r" (res)
: "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -391,6 +378,8 @@ static inline int test_and_change_bit(unsigned long nr,
return retval;
}
+
+ smp_mb();
}
#include <asm-generic/bitops/non-atomic.h>
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
index 900f472fdd2b..55a0152feb08 100644
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -32,6 +32,7 @@ typedef struct {
s32 val[2];
} compat_fsid_t;
typedef s32 compat_timer_t;
+typedef s32 compat_key_t;
typedef s32 compat_int_t;
typedef s32 compat_long_t;
@@ -146,4 +147,71 @@ static inline void __user *compat_alloc_user_space(long len)
return (void __user *) (regs->regs[29] - len);
}
+struct compat_ipc64_perm {
+ compat_key_t key;
+ __compat_uid32_t uid;
+ __compat_gid32_t gid;
+ __compat_uid32_t cuid;
+ __compat_gid32_t cgid;
+ compat_mode_t mode;
+ unsigned short seq;
+ unsigned short __pad2;
+ compat_ulong_t __unused1;
+ compat_ulong_t __unused2;
+};
+
+struct compat_semid64_ds {
+ struct compat_ipc64_perm sem_perm;
+ compat_time_t sem_otime;
+ compat_time_t sem_ctime;
+ compat_ulong_t sem_nsems;
+ compat_ulong_t __unused1;
+ compat_ulong_t __unused2;
+};
+
+struct compat_msqid64_ds {
+ struct compat_ipc64_perm msg_perm;
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused1;
+#endif
+ compat_time_t msg_stime;
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused1;
+#endif
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused2;
+#endif
+ compat_time_t msg_rtime;
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused2;
+#endif
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused3;
+#endif
+ compat_time_t msg_ctime;
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused3;
+#endif
+ compat_ulong_t msg_cbytes;
+ compat_ulong_t msg_qnum;
+ compat_ulong_t msg_qbytes;
+ compat_pid_t msg_lspid;
+ compat_pid_t msg_lrpid;
+ compat_ulong_t __unused4;
+ compat_ulong_t __unused5;
+};
+
+struct compat_shmid64_ds {
+ struct compat_ipc64_perm shm_perm;
+ compat_size_t shm_segsz;
+ compat_time_t shm_atime;
+ compat_time_t shm_dtime;
+ compat_time_t shm_ctime;
+ compat_pid_t shm_cpid;
+ compat_pid_t shm_lpid;
+ compat_ulong_t shm_nattch;
+ compat_ulong_t __unused1;
+ compat_ulong_t __unused2;
+};
+
#endif /* _ASM_COMPAT_H */
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index ed023eae0674..927a216bd530 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -1,19 +1,21 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
#ifndef _ASM_FUTEX_H
#define _ASM_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
+#include <asm/barrier.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
#include <asm/war.h>
-#ifdef CONFIG_SMP
-#define __FUTEX_SMP_SYNC " sync \n"
-#else
-#define __FUTEX_SMP_SYNC
-#endif
-
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
{ \
if (cpu_has_llsc && R10000_LLSC_WAR) { \
@@ -27,7 +29,7 @@
" .set mips3 \n" \
"2: sc $1, %2 \n" \
" beqzl $1, 1b \n" \
- __FUTEX_SMP_SYNC \
+ __WEAK_ORDERING_MB \
"3: \n" \
" .set pop \n" \
" .set mips0 \n" \
@@ -53,7 +55,7 @@
" .set mips3 \n" \
"2: sc $1, %2 \n" \
" beqz $1, 1b \n" \
- __FUTEX_SMP_SYNC \
+ __WEAK_ORDERING_MB \
"3: \n" \
" .set pop \n" \
" .set mips0 \n" \
@@ -150,7 +152,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
" .set mips3 \n"
"2: sc $1, %1 \n"
" beqzl $1, 1b \n"
- __FUTEX_SMP_SYNC
+ __WEAK_ORDERING_MB
"3: \n"
" .set pop \n"
" .section .fixup,\"ax\" \n"
@@ -177,7 +179,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
" .set mips3 \n"
"2: sc $1, %1 \n"
" beqz $1, 1b \n"
- __FUTEX_SMP_SYNC
+ __WEAK_ORDERING_MB
"3: \n"
" .set pop \n"
" .section .fixup,\"ax\" \n"
diff --git a/include/asm-mips/sn/klconfig.h b/include/asm-mips/sn/klconfig.h
index b63cd0655b3d..15d70ca56187 100644
--- a/include/asm-mips/sn/klconfig.h
+++ b/include/asm-mips/sn/klconfig.h
@@ -176,7 +176,7 @@ typedef struct kl_config_hdr {
/* --- New Macros for the changed kl_config_hdr_t structure --- */
#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\
- (unsigned long)_k + (_k->ch_malloc_hdr_off)))
+ ((unsigned long)_k + (_k->ch_malloc_hdr_off)))
#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index c8d5587467bb..fc3217fc1118 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -3,12 +3,13 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 06 by Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_SPINLOCK_H
#define _ASM_SPINLOCK_H
+#include <asm/barrier.h>
#include <asm/war.h>
/*
@@ -40,7 +41,6 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
" sc %1, %0 \n"
" beqzl %1, 1b \n"
" nop \n"
- " sync \n"
" .set reorder \n"
: "=m" (lock->lock), "=&r" (tmp)
: "m" (lock->lock)
@@ -53,19 +53,22 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
" li %1, 1 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " sync \n"
+ " nop \n"
" .set reorder \n"
: "=m" (lock->lock), "=&r" (tmp)
: "m" (lock->lock)
: "memory");
}
+
+ smp_mb();
}
static inline void __raw_spin_unlock(raw_spinlock_t *lock)
{
+ smp_mb();
+
__asm__ __volatile__(
" .set noreorder # __raw_spin_unlock \n"
- " sync \n"
" sw $0, %0 \n"
" .set\treorder \n"
: "=m" (lock->lock)
@@ -86,7 +89,6 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
" beqzl %2, 1b \n"
" nop \n"
" andi %2, %0, 1 \n"
- " sync \n"
" .set reorder"
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
: "m" (lock->lock)
@@ -99,13 +101,14 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
" sc %2, %1 \n"
" beqz %2, 1b \n"
" andi %2, %0, 1 \n"
- " sync \n"
" .set reorder"
: "=&r" (temp), "=m" (lock->lock), "=&r" (res)
: "m" (lock->lock)
: "memory");
}
+ smp_mb();
+
return res == 0;
}
@@ -143,7 +146,6 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
" sc %1, %0 \n"
" beqzl %1, 1b \n"
" nop \n"
- " sync \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -156,12 +158,14 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
" addu %1, 1 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " sync \n"
+ " nop \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
: "memory");
}
+
+ smp_mb();
}
/* Note the use of sub, not subu which will make the kernel die with an
@@ -171,13 +175,14 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
unsigned int tmp;
+ smp_mb();
+
if (R10000_LLSC_WAR) {
__asm__ __volatile__(
"1: ll %1, %2 # __raw_read_unlock \n"
" sub %1, 1 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " sync \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
: "memory");
@@ -188,7 +193,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
" sub %1, 1 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " sync \n"
+ " nop \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -208,7 +213,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " sync \n"
+ " nop \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
@@ -221,18 +226,22 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " sync \n"
+ " nop \n"
" .set reorder \n"
: "=m" (rw->lock), "=&r" (tmp)
: "m" (rw->lock)
: "memory");
}
+
+ smp_mb();
}
static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
+ smp_mb();
+
__asm__ __volatile__(
- " sync # __raw_write_unlock \n"
+ " # __raw_write_unlock \n"
" sw $0, %0 \n"
: "=m" (rw->lock)
: "m" (rw->lock)
@@ -252,11 +261,10 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
" bnez %1, 2f \n"
" addu %1, 1 \n"
" sc %1, %0 \n"
- " beqzl %1, 1b \n"
" .set reorder \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
+ " beqzl %1, 1b \n"
+ " nop \n"
+ __WEAK_ORDERING_MB
" li %2, 1 \n"
"2: \n"
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
@@ -271,10 +279,9 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
" addu %1, 1 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
+ " nop \n"
" .set reorder \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
+ __WEAK_ORDERING_MB
" li %2, 1 \n"
"2: \n"
: "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
@@ -299,7 +306,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqzl %1, 1b \n"
- " sync \n"
+ " nop \n"
+ __WEAK_ORDERING_MB
" li %2, 1 \n"
" .set reorder \n"
"2: \n"
@@ -315,7 +323,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" beqz %1, 1b \n"
- " sync \n"
+ " nop \n"
+ __WEAK_ORDERING_MB
" li %2, 1 \n"
" .set reorder \n"
"2: \n"
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 3056feed5a36..9428057a50cf 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
* Copyright (C) 1996 by Paul M. Antoine
* Copyright (C) 1999 Silicon Graphics
* Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
@@ -16,132 +16,12 @@
#include <linux/irqflags.h>
#include <asm/addrspace.h>
+#include <asm/barrier.h>
#include <asm/cpu-features.h>
#include <asm/dsp.h>
#include <asm/ptrace.h>
#include <asm/war.h>
-/*
- * read_barrier_depends - Flush all pending reads that subsequents reads
- * depend on.
- *
- * No data-dependent reads from memory-like regions are ever reordered
- * over this barrier. All reads preceding this primitive are guaranteed
- * to access memory (but not necessarily other CPUs' caches) before any
- * reads following this primitive that depend on the data return by
- * any of the preceding reads. This primitive is much lighter weight than
- * rmb() on most CPUs, and is never heavier weight than is
- * rmb().
- *
- * These ordering constraints are respected by both the local CPU
- * and the compiler.
- *
- * Ordering is not guaranteed by anything other than these primitives,
- * not even by data dependencies. See the documentation for
- * memory_barrier() for examples and URLs to more information.
- *
- * For example, the following code would force ordering (the initial
- * value of "a" is zero, "b" is one, and "p" is "&a"):
- *
- * <programlisting>
- * CPU 0 CPU 1
- *
- * b = 2;
- * memory_barrier();
- * p = &b; q = p;
- * read_barrier_depends();
- * d = *q;
- * </programlisting>
- *
- * because the read of "*q" depends on the read of "p" and these
- * two reads are separated by a read_barrier_depends(). However,
- * the following code, with the same initial values for "a" and "b":
- *
- * <programlisting>
- * CPU 0 CPU 1
- *
- * a = 2;
- * memory_barrier();
- * b = 3; y = b;
- * read_barrier_depends();
- * x = a;
- * </programlisting>
- *
- * does not enforce ordering, since there is no data dependency between
- * the read of "a" and the read of "b". Therefore, on some CPUs, such
- * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
- * in cases like this where there are no data dependencies.
- */
-
-#define read_barrier_depends() do { } while(0)
-
-#ifdef CONFIG_CPU_HAS_SYNC
-#define __sync() \
- __asm__ __volatile__( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- ".set mips2\n\t" \
- "sync\n\t" \
- ".set pop" \
- : /* no output */ \
- : /* no input */ \
- : "memory")
-#else
-#define __sync() do { } while(0)
-#endif
-
-#define __fast_iob() \
- __asm__ __volatile__( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- "lw $0,%0\n\t" \
- "nop\n\t" \
- ".set pop" \
- : /* no output */ \
- : "m" (*(int *)CKSEG1) \
- : "memory")
-
-#define fast_wmb() __sync()
-#define fast_rmb() __sync()
-#define fast_mb() __sync()
-#define fast_iob() \
- do { \
- __sync(); \
- __fast_iob(); \
- } while (0)
-
-#ifdef CONFIG_CPU_HAS_WB
-
-#include <asm/wbflush.h>
-
-#define wmb() fast_wmb()
-#define rmb() fast_rmb()
-#define mb() wbflush()
-#define iob() wbflush()
-
-#else /* !CONFIG_CPU_HAS_WB */
-
-#define wmb() fast_wmb()
-#define rmb() fast_rmb()
-#define mb() fast_mb()
-#define iob() fast_iob()
-
-#endif /* !CONFIG_CPU_HAS_WB */
-
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_read_barrier_depends() read_barrier_depends()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#define smp_read_barrier_depends() do { } while(0)
-#endif
-
-#define set_mb(var, value) \
-do { var = value; mb(); } while (0)
/*
* switch_to(n) should switch tasks to task nr n, first
@@ -217,9 +97,6 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
" .set mips3 \n"
" sc %2, %1 \n"
" beqzl %2, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
@@ -235,9 +112,6 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
" .set mips3 \n"
" sc %2, %1 \n"
" beqz %2, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
@@ -251,6 +125,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
local_irq_restore(flags); /* implies memory barrier */
}
+ smp_mb();
+
return retval;
}
@@ -268,9 +144,6 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
" move %2, %z4 \n"
" scd %2, %1 \n"
" beqzl %2, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
@@ -284,9 +157,6 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
" move %2, %z4 \n"
" scd %2, %1 \n"
" beqz %2, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
" .set mips0 \n"
: "=&r" (retval), "=m" (*m), "=&r" (dummy)
: "R" (*m), "Jr" (val)
@@ -300,6 +170,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
local_irq_restore(flags); /* implies memory barrier */
}
+ smp_mb();
+
return retval;
}
#else
@@ -345,9 +217,6 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
" .set mips3 \n"
" sc $1, %1 \n"
" beqzl $1, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
"2: \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
@@ -365,9 +234,6 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
" .set mips3 \n"
" sc $1, %1 \n"
" beqz $1, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
"2: \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
@@ -383,6 +249,8 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
local_irq_restore(flags); /* implies memory barrier */
}
+ smp_mb();
+
return retval;
}
@@ -402,9 +270,6 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
" move $1, %z4 \n"
" scd $1, %1 \n"
" beqzl $1, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
"2: \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
@@ -420,9 +285,6 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
" move $1, %z4 \n"
" scd $1, %1 \n"
" beqz $1, 1b \n"
-#ifdef CONFIG_SMP
- " sync \n"
-#endif
"2: \n"
" .set pop \n"
: "=&r" (retval), "=R" (*m)
@@ -438,6 +300,8 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
local_irq_restore(flags); /* implies memory barrier */
}
+ smp_mb();
+
return retval;
}
#else