diff options
| author | Anton Blanchard <anton@samba.org> | 2003-07-22 10:12:05 +1000 |
|---|---|---|
| committer | Anton Blanchard <anton@samba.org> | 2003-07-22 10:12:05 +1000 |
| commit | a479e93c6d500c18f3eaef369bb790bb3a5da0b8 (patch) | |
| tree | 0800410a9d2925b83fecd2db89bef24af946b461 | |
| parent | 2c420d4a174456d57626fc09f752cb7a83752e08 (diff) | |
| parent | 8673f4ab8402bd62dd61fe25bc65226d9b7ae962 (diff) | |
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/tmp3
| -rw-r--r-- | arch/ppc64/boot/Makefile | 2 | ||||
| -rw-r--r-- | arch/ppc64/boot/div64.S | 59 | ||||
| -rw-r--r-- | arch/ppc64/boot/prom.c | 1 | ||||
| -rw-r--r-- | arch/ppc64/kernel/misc.S | 28 | ||||
| -rw-r--r-- | arch/ppc64/kernel/sys_ppc32.c | 65 | ||||
| -rw-r--r-- | arch/ppc64/kernel/syscalls.c | 7 | ||||
| -rw-r--r-- | arch/ppc64/mm/fault.c | 2 | ||||
| -rw-r--r-- | include/asm-ppc64/ipc.h | 1 | ||||
| -rw-r--r-- | include/asm-ppc64/smp.h | 2 | ||||
| -rw-r--r-- | include/asm-ppc64/unistd.h | 7 |
10 files changed, 168 insertions, 6 deletions
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index 80192d5aefb2..12e242f5eec0 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -33,7 +33,7 @@ BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(obj)/zImage.lds BOOTOBJCOPY := $(CROSS32_COMPILE)objcopy OBJCOPYFLAGS := contents,alloc,load,readonly,data -src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c +src-boot := crt0.S string.S prom.c main.c zlib.c imagesize.c div64.S src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) diff --git a/arch/ppc64/boot/div64.S b/arch/ppc64/boot/div64.S new file mode 100644 index 000000000000..f3224d2d6659 --- /dev/null +++ b/arch/ppc64/boot/div64.S @@ -0,0 +1,59 @@ +/* + * Divide a 64-bit unsigned number by a 32-bit unsigned number. + * This routine assumes that the top 32 bits of the dividend are + * non-zero to start with. + * On entry, r3 points to the dividend, which get overwritten with + * the 64-bit quotient, and r4 contains the divisor. + * On exit, r3 contains the remainder. + * + * Copyright (C) 2002 Paul Mackerras, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <asm/ppc_asm.h> +#include <asm/processor.h> + + .globl __div64_32 +__div64_32: + lwz r5,0(r3) # get the dividend into r5/r6 + lwz r6,4(r3) + cmplw r5,r4 + li r7,0 + li r8,0 + blt 1f + divwu r7,r5,r4 # if dividend.hi >= divisor, + mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor + subf. r5,r0,r5 # dividend.hi %= divisor + beq 3f +1: mr r11,r5 # here dividend.hi != 0 + andis. r0,r5,0xc000 + bne 2f + cntlzw r0,r5 # we are shifting the dividend right + li r10,-1 # to make it < 2^32, and shifting + srw r10,r10,r0 # the divisor right the same amount, + add r9,r4,r10 # rounding up (so the estimate cannot + andc r11,r6,r10 # ever be too large, only too small) + andc r9,r9,r10 + or r11,r5,r11 + rotlw r9,r9,r0 + rotlw r11,r11,r0 + divwu r11,r11,r9 # then we divide the shifted quantities +2: mullw r10,r11,r4 # to get an estimate of the quotient, + mulhwu r9,r11,r4 # multiply the estimate by the divisor, + subfc r6,r10,r6 # take the product from the divisor, + add r8,r8,r11 # and add the estimate to the accumulated + subfe. r5,r9,r5 # quotient + bne 1b +3: cmplw r6,r4 + blt 4f + divwu r0,r6,r4 # perform the remaining 32-bit division + mullw r10,r0,r4 # and get the remainder + add r8,r8,r0 + subf r6,r10,r6 +4: stw r7,0(r3) # return the quotient in *r3 + stw r8,4(r3) + mr r3,r6 # return the remainder in r3 + blr diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index 2c620f105896..55ffaef76aae 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -11,6 +11,7 @@ #include <linux/string.h> #include <linux/ctype.h> +#define BITS_PER_LONG 32 #include <asm/div64.h> int (*prom)(void *); diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 299cbfc6b227..61746717aaec 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -838,6 +838,20 @@ _GLOBAL(sys_call_table32) .llong .sys_epoll_ctl .llong .sys_epoll_wait .llong .sys_remap_file_pages + .llong .sys_ni_syscall /* 240 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 245 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys32_tgkill /* 250 */ + .llong .sys32_utimes + .llong .sys_statfs64 + .llong .sys_fstatfs64 .balign 8 _GLOBAL(sys_call_table) @@ -1081,3 +1095,17 @@ _GLOBAL(sys_call_table) .llong .sys_epoll_ctl .llong .sys_epoll_wait .llong .sys_remap_file_pages + .llong .sys_timer_create /* 240 */ + .llong .sys_timer_settime + .llong .sys_timer_gettime + .llong .sys_timer_getoverrun + .llong .sys_timer_delete + .llong .sys_clock_settime /* 245 */ + .llong .sys_clock_gettime + .llong .sys_clock_getres + .llong .sys_clock_nanosleep + .llong .sys_ni_syscall + .llong .sys_tgkill /* 250 */ + .llong .sys_utimes + .llong .sys_statfs64 + .llong .sys_fstatfs64 diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 8fbde0fa5b14..7f107d1f5245 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -1773,6 +1773,22 @@ do_sys32_shmctl(int first, int second, void *uptr) return err; } +static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems, + const struct compat_timespec *timeout32) +{ + struct compat_timespec t32; + struct timespec *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); +} + /* * Note: it is necessary to treat first_parm, second_parm, and * third_parm as unsigned ints, with the corresponding cast to a @@ -1795,8 +1811,12 @@ asmlinkage long sys32_ipc(u32 call, u32 first_parm, u32 second_parm, u32 third_p case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semop(first, (struct sembuf *)AA(ptr), - second); + err = sys_semtimedop(first, (struct sembuf *)AA(ptr), + second, NULL); + break; + case SEMTIMEDOP: + err = sys32_semtimedop(first, (struct sembuf *)AA(ptr), second, + (const struct compat_timespec *)AA(fifth)); break; case SEMGET: err = sys_semget(first, second, third); @@ -2777,6 +2797,47 @@ long sys32_io_submit(aio_context_t ctx_id, u32 number, u32 *iocbpp) return i ? i : ret; } +int get_compat_timeval(struct timeval *tv, struct compat_timeval *ctv) +{ + return (verify_area(VERIFY_READ, ctv, sizeof(*ctv)) || + __get_user(tv->tv_sec, &ctv->tv_sec) || + __get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0; +} + +long sys32_utimes(char *filename, struct compat_timeval *tvs) +{ + char *kfilename; + struct timeval ktvs[2]; + mm_segment_t old_fs; + long ret; + + kfilename = getname(filename); + ret = PTR_ERR(kfilename); + if (!IS_ERR(kfilename)) { + if (tvs) { + if (get_compat_timeval(&ktvs[0], &tvs[0]) || + get_compat_timeval(&ktvs[1], &tvs[1])) + return -EFAULT; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = do_utimes(kfilename, (tvs ? &ktvs[0] : NULL)); + set_fs(old_fs); + + putname(kfilename); + } + return ret; +} + +extern long sys_tgkill(int tgid, int pid, int sig); + +long sys32_tgkill(u32 tgid, u32 pid, int sig) +{ + /* sign extend tgid, pid */ + return sys_tgkill((int)tgid, (int)pid, sig); +} + /* * long long munging: * The 32 bit ABI passes long longs in an odd even register pair. diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index b8263b76ee07..39d49bd422e2 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c @@ -66,7 +66,12 @@ sys_ipc (uint call, int first, int second, long third, void *ptr, long fifth) ret = -ENOSYS; switch (call) { case SEMOP: - ret = sys_semop (first, (struct sembuf *)ptr, second); + ret = sys_semtimedop (first, (struct sembuf *)ptr, second, + NULL); + break; + case SEMTIMEDOP: + ret = sys_semtimedop (first, (struct sembuf *)ptr, second, + (const struct timespec *) fifth); break; case SEMGET: ret = sys_semget (first, second, third); diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c index 5e20e3ab45aa..1ef8cdd46f42 100644 --- a/arch/ppc64/mm/fault.c +++ b/arch/ppc64/mm/fault.c @@ -66,6 +66,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, */ if (regs->trap == 0x400) error_code &= 0x48200000; + else if (regs->trap != 0x300) /* ensure error_code is 0 on SLB miss */ + error_code = 0; #ifdef CONFIG_DEBUG_KERNEL if (debugger_fault_handler && (regs->trap == 0x300 || diff --git a/include/asm-ppc64/ipc.h b/include/asm-ppc64/ipc.h index f4e1841af35d..cfb82f0f5360 100644 --- a/include/asm-ppc64/ipc.h +++ b/include/asm-ppc64/ipc.h @@ -19,6 +19,7 @@ struct ipc_kludge { #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h index 20732ead9ee8..865f83ad1f55 100644 --- a/include/asm-ppc64/smp.h +++ b/include/asm-ppc64/smp.h @@ -44,7 +44,7 @@ static inline unsigned int num_online_cpus(void) return hweight64(cpu_online_map); } -static inline unsigned int any_online_cpu(unsigned int mask) +static inline unsigned int any_online_cpu(unsigned long mask) { if (mask & cpu_online_map) return __ffs(mask & cpu_online_map); diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h index 102e846a80ab..76871826eca0 100644 --- a/include/asm-ppc64/unistd.h +++ b/include/asm-ppc64/unistd.h @@ -259,8 +259,13 @@ #define __NR_clock_gettime 246 #define __NR_clock_getres 247 #define __NR_clock_nanosleep 248 +#define __NR_swapcontext 249 +#define __NR_tgkill 250 +#define __NR_utimes 251 +#define __NR_statfs64 252 +#define __NR_fstatfs64 253 -#define __NR_syscalls 239 +#define __NR_syscalls 254 #ifdef __KERNEL__ #define NR_syscalls __NR_syscalls #endif |
