aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/osf_sys.c2
-rw-r--r--arch/arm/boot/compressed/head.S2
-rw-r--r--arch/arm/configs/ep80219_defconfig1
-rw-r--r--arch/arm/configs/iq31244_defconfig1
-rw-r--r--arch/arm/configs/iq80321_defconfig1
-rw-r--r--arch/arm/configs/iq80331_defconfig1
-rw-r--r--arch/arm/configs/iq80332_defconfig1
-rw-r--r--arch/arm/kernel/entry-armv.S5
-rw-r--r--arch/arm/kernel/signal.c29
-rw-r--r--arch/arm/kernel/signal.h2
-rw-r--r--arch/arm/mach-ixp4xx/common.c3
-rw-r--r--arch/arm/mach-omap1/clock.c44
-rw-r--r--arch/arm/mach-omap1/clock.h168
-rw-r--r--arch/arm/mach-omap1/serial.c6
-rw-r--r--arch/arm/mach-omap2/clock.c32
-rw-r--r--arch/arm/mach-omap2/clock.h12
-rw-r--r--arch/arm/mach-omap2/serial.c12
-rw-r--r--arch/arm/mach-omap2/timer-gp.c2
-rw-r--r--arch/arm/plat-omap/clock.c41
-rw-r--r--arch/arm/plat-omap/gpio.c6
-rw-r--r--arch/arm/plat-omap/mcbsp.c12
-rw-r--r--arch/arm/plat-omap/ocpi.c4
-rw-r--r--arch/frv/kernel/signal.c120
-rw-r--r--arch/i386/defconfig2
-rw-r--r--arch/i386/kernel/quirks.c9
-rw-r--r--arch/i386/kernel/signal.c109
-rw-r--r--arch/i386/kernel/syscall_table.S15
-rw-r--r--arch/ia64/configs/gensparse_defconfig1
-rw-r--r--arch/ia64/configs/tiger_defconfig1
-rw-r--r--arch/ia64/configs/zx1_defconfig1
-rw-r--r--arch/ia64/defconfig1
-rw-r--r--arch/ia64/ia32/sys_ia32.c28
-rw-r--r--arch/ia64/kernel/perfmon.c11
-rw-r--r--arch/ia64/kernel/uncached.c1
-rw-r--r--arch/ia64/sn/include/xtalk/hubdev.h9
-rw-r--r--arch/ia64/sn/kernel/io_init.c54
-rw-r--r--arch/ia64/sn/kernel/mca.c7
-rw-r--r--arch/ia64/sn/kernel/xp_main.c17
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c34
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c17
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c12
-rw-r--r--arch/parisc/configs/a500_defconfig1
-rw-r--r--arch/parisc/configs/c3000_defconfig1
-rw-r--r--arch/powerpc/configs/cell_defconfig1
-rw-r--r--arch/powerpc/configs/g5_defconfig1
-rw-r--r--arch/powerpc/configs/iseries_defconfig1
-rw-r--r--arch/powerpc/configs/maple_defconfig1
-rw-r--r--arch/powerpc/configs/ppc64_defconfig1
-rw-r--r--arch/powerpc/configs/pseries_defconfig1
-rw-r--r--arch/powerpc/kernel/entry_32.S8
-rw-r--r--arch/powerpc/kernel/entry_64.S2
-rw-r--r--arch/powerpc/kernel/signal_32.c76
-rw-r--r--arch/powerpc/kernel/signal_64.c56
-rw-r--r--arch/powerpc/kernel/systbl.S2
-rw-r--r--arch/ppc/configs/bamboo_defconfig1
-rw-r--r--arch/ppc/configs/katana_defconfig1
-rw-r--r--arch/ppc/configs/mpc834x_sys_defconfig1
-rw-r--r--arch/ppc/configs/power3_defconfig1
-rw-r--r--arch/sparc/kernel/entry.S56
-rw-r--r--arch/sparc/kernel/rtrap.S9
-rw-r--r--arch/sparc/kernel/signal.c117
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c2
-rw-r--r--arch/sparc/kernel/systbls.S10
-rw-r--r--arch/sparc64/defconfig25
-rw-r--r--arch/sparc64/kernel/entry.S23
-rw-r--r--arch/sparc64/kernel/process.c4
-rw-r--r--arch/sparc64/kernel/rtrap.S33
-rw-r--r--arch/sparc64/kernel/setup.c2
-rw-r--r--arch/sparc64/kernel/signal.c151
-rw-r--r--arch/sparc64/kernel/signal32.c122
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c4
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c4
-rw-r--r--arch/sparc64/kernel/systbls.S21
-rw-r--r--arch/sparc64/prom/console.c8
-rw-r--r--arch/sparc64/solaris/entry64.S2
-rw-r--r--arch/um/Kconfig27
-rw-r--r--arch/um/Kconfig.i3866
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/drivers/daemon_kern.c4
-rw-r--r--arch/um/drivers/daemon_user.c6
-rw-r--r--arch/um/drivers/fd.c1
-rw-r--r--arch/um/drivers/net_kern.c21
-rw-r--r--arch/um/drivers/ubd_kern.c59
-rw-r--r--arch/um/include/kern_util.h4
-rw-r--r--arch/um/include/longjmp.h19
-rw-r--r--arch/um/include/mode_kern.h15
-rw-r--r--arch/um/include/os.h58
-rw-r--r--arch/um/include/skas/mm_id.h (renamed from arch/um/kernel/skas/include/mm_id.h)0
-rw-r--r--arch/um/include/skas/mmu-skas.h24
-rw-r--r--arch/um/include/skas/mode-skas.h19
-rw-r--r--arch/um/include/skas/mode_kern_skas.h (renamed from arch/um/kernel/skas/include/mode_kern-skas.h)12
-rw-r--r--arch/um/include/skas/proc_mm.h (renamed from arch/um/kernel/skas/include/proc_mm.h)17
-rw-r--r--arch/um/include/skas/skas.h26
-rw-r--r--arch/um/include/skas/stub-data.h (renamed from arch/um/kernel/skas/include/stub-data.h)0
-rw-r--r--arch/um/include/skas/uaccess-skas.h (renamed from arch/um/kernel/skas/include/uaccess-skas.h)11
-rw-r--r--arch/um/include/time_user.h19
-rw-r--r--arch/um/include/tt/debug.h (renamed from arch/um/kernel/tt/include/debug.h)2
-rw-r--r--arch/um/include/tt/mmu-tt.h12
-rw-r--r--arch/um/include/tt/mode-tt.h23
-rw-r--r--arch/um/include/tt/mode_kern_tt.h41
-rw-r--r--arch/um/include/tt/tt.h (renamed from arch/um/kernel/tt/include/tt.h)12
-rw-r--r--arch/um/include/tt/uaccess-tt.h (renamed from arch/um/kernel/tt/include/uaccess-tt.h)11
-rw-r--r--arch/um/include/user.h1
-rw-r--r--arch/um/include/user_util.h18
-rw-r--r--arch/um/kernel/Makefile7
-rw-r--r--arch/um/kernel/exec_kern.c1
-rw-r--r--arch/um/kernel/process_kern.c22
-rw-r--r--arch/um/kernel/sigio_user.c83
-rw-r--r--arch/um/kernel/signal_kern.c91
-rw-r--r--arch/um/kernel/skas/Makefile6
-rw-r--r--arch/um/kernel/skas/include/mmu-skas.h35
-rw-r--r--arch/um/kernel/skas/include/mode-skas.h33
-rw-r--r--arch/um/kernel/skas/include/skas.h49
-rw-r--r--arch/um/kernel/skas/mmu.c8
-rw-r--r--arch/um/kernel/skas/process.c1
-rw-r--r--arch/um/kernel/skas/process_kern.c35
-rw-r--r--arch/um/kernel/skas/uaccess.c2
-rw-r--r--arch/um/kernel/syscall.c4
-rw-r--r--arch/um/kernel/time_kern.c132
-rw-r--r--arch/um/kernel/tt/exec_kern.c1
-rw-r--r--arch/um/kernel/tt/gdb.c1
-rw-r--r--arch/um/kernel/tt/include/mmu-tt.h23
-rw-r--r--arch/um/kernel/tt/process_kern.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/ptrace.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c1
-rw-r--r--arch/um/kernel/tt/trap_user.c5
-rw-r--r--arch/um/os-Linux/Makefile4
-rw-r--r--arch/um/os-Linux/helper.c4
-rw-r--r--arch/um/os-Linux/main.c13
-rw-r--r--arch/um/os-Linux/process.c30
-rw-r--r--arch/um/os-Linux/signal.c218
-rw-r--r--arch/um/os-Linux/skas/Makefile4
-rw-r--r--arch/um/os-Linux/skas/mem.c (renamed from arch/um/kernel/skas/mem_user.c)202
-rw-r--r--arch/um/os-Linux/skas/process.c566
-rw-r--r--arch/um/os-Linux/start_up.c1
-rw-r--r--arch/um/os-Linux/time.c131
-rw-r--r--arch/um/os-Linux/trap.c3
-rw-r--r--arch/um/os-Linux/tt.c49
-rw-r--r--arch/um/os-Linux/uaccess.c4
-rw-r--r--arch/um/os-Linux/util.c (renamed from arch/um/kernel/user_util.c)69
-rw-r--r--arch/um/sys-i386/ldt.c26
-rw-r--r--arch/x86_64/defconfig1
-rw-r--r--arch/x86_64/ia32/ia32entry.S13
-rw-r--r--arch/x86_64/kernel/setup64.c2
144 files changed, 2228 insertions, 1709 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 01fe990d3e54..7fb14f42a125 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -960,7 +960,7 @@ osf_utimes(char __user *filename, struct timeval32 __user *tvs)
960 return -EFAULT; 960 return -EFAULT;
961 } 961 }
962 962
963 return do_utimes(filename, tvs ? ktvs : NULL); 963 return do_utimes(AT_FDCWD, filename, tvs ? ktvs : NULL);
964} 964}
965 965
966#define MAX_SELECT_SECONDS \ 966#define MAX_SELECT_SECONDS \
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index aaa47400eb9c..db3389d8e027 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -334,7 +334,7 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
334 mov r1, #0x12 334 mov r1, #0x12
335 orr r1, r1, #3 << 10 335 orr r1, r1, #3 << 10
336 add r2, r3, #16384 336 add r2, r3, #16384
3371: cmp r1, r8 @ if virt > start of RAM 3371: cmp r1, r9 @ if virt > start of RAM
338 orrhs r1, r1, #0x0c @ set cacheable, bufferable 338 orrhs r1, r1, #0x0c @ set cacheable, bufferable
339 cmp r1, r10 @ if virt > end of RAM 339 cmp r1, r10 @ if virt > end of RAM
340 bichs r1, r1, #0x0c @ clear cacheable, bufferable 340 bichs r1, r1, #0x0c @ clear cacheable, bufferable
diff --git a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/ep80219_defconfig
index fbe312e757cb..3c73b707c2f3 100644
--- a/arch/arm/configs/ep80219_defconfig
+++ b/arch/arm/configs/ep80219_defconfig
@@ -522,6 +522,7 @@ CONFIG_E100=y
522# CONFIG_DL2K is not set 522# CONFIG_DL2K is not set
523CONFIG_E1000=y 523CONFIG_E1000=y
524CONFIG_E1000_NAPI=y 524CONFIG_E1000_NAPI=y
525# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
525# CONFIG_NS83820 is not set 526# CONFIG_NS83820 is not set
526# CONFIG_HAMACHI is not set 527# CONFIG_HAMACHI is not set
527# CONFIG_YELLOWFIN is not set 528# CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig
index c07628ceaf0c..32467160a6df 100644
--- a/arch/arm/configs/iq31244_defconfig
+++ b/arch/arm/configs/iq31244_defconfig
@@ -493,6 +493,7 @@ CONFIG_NETDEVICES=y
493# CONFIG_DL2K is not set 493# CONFIG_DL2K is not set
494CONFIG_E1000=y 494CONFIG_E1000=y
495CONFIG_E1000_NAPI=y 495CONFIG_E1000_NAPI=y
496# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
496# CONFIG_NS83820 is not set 497# CONFIG_NS83820 is not set
497# CONFIG_HAMACHI is not set 498# CONFIG_HAMACHI is not set
498# CONFIG_YELLOWFIN is not set 499# CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig
index 18fa1615fdfd..b000da753c41 100644
--- a/arch/arm/configs/iq80321_defconfig
+++ b/arch/arm/configs/iq80321_defconfig
@@ -415,6 +415,7 @@ CONFIG_NETDEVICES=y
415# CONFIG_DL2K is not set 415# CONFIG_DL2K is not set
416CONFIG_E1000=y 416CONFIG_E1000=y
417CONFIG_E1000_NAPI=y 417CONFIG_E1000_NAPI=y
418# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
418# CONFIG_NS83820 is not set 419# CONFIG_NS83820 is not set
419# CONFIG_HAMACHI is not set 420# CONFIG_HAMACHI is not set
420# CONFIG_YELLOWFIN is not set 421# CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig
index f50035de1fff..46c79e1efe07 100644
--- a/arch/arm/configs/iq80331_defconfig
+++ b/arch/arm/configs/iq80331_defconfig
@@ -496,6 +496,7 @@ CONFIG_NETDEVICES=y
496# CONFIG_DL2K is not set 496# CONFIG_DL2K is not set
497CONFIG_E1000=y 497CONFIG_E1000=y
498CONFIG_E1000_NAPI=y 498CONFIG_E1000_NAPI=y
499# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
499# CONFIG_NS83820 is not set 500# CONFIG_NS83820 is not set
500# CONFIG_HAMACHI is not set 501# CONFIG_HAMACHI is not set
501# CONFIG_YELLOWFIN is not set 502# CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig
index 18b3f372ed68..11959b705d82 100644
--- a/arch/arm/configs/iq80332_defconfig
+++ b/arch/arm/configs/iq80332_defconfig
@@ -496,6 +496,7 @@ CONFIG_NETDEVICES=y
496# CONFIG_DL2K is not set 496# CONFIG_DL2K is not set
497CONFIG_E1000=y 497CONFIG_E1000=y
498CONFIG_E1000_NAPI=y 498CONFIG_E1000_NAPI=y
499# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
499# CONFIG_NS83820 is not set 500# CONFIG_NS83820 is not set
500# CONFIG_HAMACHI is not set 501# CONFIG_HAMACHI is not set
501# CONFIG_YELLOWFIN is not set 502# CONFIG_YELLOWFIN is not set
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 874e6bb79405..d401d908c463 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -735,8 +735,11 @@ __kuser_cmpxchg: @ 0xffff0fc0
735 * The kernel itself must perform the operation. 735 * The kernel itself must perform the operation.
736 * A special ghost syscall is used for that (see traps.c). 736 * A special ghost syscall is used for that (see traps.c).
737 */ 737 */
738 stmfd sp!, {r7, lr}
739 mov r7, #0xff00 @ 0xfff0 into r7 for EABI
740 orr r7, r7, #0xf0
738 swi #0x9ffff0 741 swi #0x9ffff0
739 mov pc, lr 742 ldmfd sp!, {r7, pc}
740 743
741#elif __LINUX_ARM_ARCH__ < 6 744#elif __LINUX_ARM_ARCH__ < 6
742 745
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 765922bcf9e7..a0cd0a90a10d 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -30,15 +30,21 @@
30#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)) 30#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
31 31
32/* 32/*
33 * With EABI, the syscall number has to be loaded into r7.
34 */
35#define MOV_R7_NR_SIGRETURN (0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE))
36#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
37
38/*
33 * For Thumb syscalls, we pass the syscall number via r7. We therefore 39 * For Thumb syscalls, we pass the syscall number via r7. We therefore
34 * need two 16-bit instructions. 40 * need two 16-bit instructions.
35 */ 41 */
36#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) 42#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
37#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) 43#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
38 44
39const unsigned long sigreturn_codes[4] = { 45const unsigned long sigreturn_codes[7] = {
40 SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, 46 MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
41 SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN 47 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
42}; 48};
43 49
44static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); 50static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
@@ -189,7 +195,7 @@ struct aux_sigframe {
189struct sigframe { 195struct sigframe {
190 struct sigcontext sc; 196 struct sigcontext sc;
191 unsigned long extramask[_NSIG_WORDS-1]; 197 unsigned long extramask[_NSIG_WORDS-1];
192 unsigned long retcode; 198 unsigned long retcode[2];
193 struct aux_sigframe aux __attribute__((aligned(8))); 199 struct aux_sigframe aux __attribute__((aligned(8)));
194}; 200};
195 201
@@ -198,7 +204,7 @@ struct rt_sigframe {
198 void __user *puc; 204 void __user *puc;
199 struct siginfo info; 205 struct siginfo info;
200 struct ucontext uc; 206 struct ucontext uc;
201 unsigned long retcode; 207 unsigned long retcode[2];
202 struct aux_sigframe aux __attribute__((aligned(8))); 208 struct aux_sigframe aux __attribute__((aligned(8)));
203}; 209};
204 210
@@ -436,12 +442,13 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
436 if (ka->sa.sa_flags & SA_RESTORER) { 442 if (ka->sa.sa_flags & SA_RESTORER) {
437 retcode = (unsigned long)ka->sa.sa_restorer; 443 retcode = (unsigned long)ka->sa.sa_restorer;
438 } else { 444 } else {
439 unsigned int idx = thumb; 445 unsigned int idx = thumb << 1;
440 446
441 if (ka->sa.sa_flags & SA_SIGINFO) 447 if (ka->sa.sa_flags & SA_SIGINFO)
442 idx += 2; 448 idx += 3;
443 449
444 if (__put_user(sigreturn_codes[idx], rc)) 450 if (__put_user(sigreturn_codes[idx], rc) ||
451 __put_user(sigreturn_codes[idx+1], rc+1))
445 return 1; 452 return 1;
446 453
447 if (cpsr & MODE32_BIT) { 454 if (cpsr & MODE32_BIT) {
@@ -456,7 +463,7 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
456 * the return code written onto the stack. 463 * the return code written onto the stack.
457 */ 464 */
458 flush_icache_range((unsigned long)rc, 465 flush_icache_range((unsigned long)rc,
459 (unsigned long)(rc + 1)); 466 (unsigned long)(rc + 2));
460 467
461 retcode = ((unsigned long)rc) + thumb; 468 retcode = ((unsigned long)rc) + thumb;
462 } 469 }
@@ -488,7 +495,7 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
488 } 495 }
489 496
490 if (err == 0) 497 if (err == 0)
491 err = setup_return(regs, ka, &frame->retcode, frame, usig); 498 err = setup_return(regs, ka, frame->retcode, frame, usig);
492 499
493 return err; 500 return err;
494} 501}
@@ -522,7 +529,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
522 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 529 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
523 530
524 if (err == 0) 531 if (err == 0)
525 err = setup_return(regs, ka, &frame->retcode, frame, usig); 532 err = setup_return(regs, ka, frame->retcode, frame, usig);
526 533
527 if (err == 0) { 534 if (err == 0) {
528 /* 535 /*
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 91d26faca62b..9991049c522d 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -9,4 +9,4 @@
9 */ 9 */
10#define KERN_SIGRETURN_CODE 0xffff0500 10#define KERN_SIGRETURN_CODE 0xffff0500
11 11
12extern const unsigned long sigreturn_codes[4]; 12extern const unsigned long sigreturn_codes[7];
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 6b393691d0e8..4bdc9d4526cd 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -333,6 +333,7 @@ static struct platform_device *ixp46x_devices[] __initdata = {
333}; 333};
334 334
335unsigned long ixp4xx_exp_bus_size; 335unsigned long ixp4xx_exp_bus_size;
336EXPORT_SYMBOL(ixp4xx_exp_bus_size);
336 337
337void __init ixp4xx_sys_init(void) 338void __init ixp4xx_sys_init(void)
338{ 339{
@@ -352,7 +353,7 @@ void __init ixp4xx_sys_init(void)
352 } 353 }
353 } 354 }
354 355
355 printk("IXP4xx: Using %uMiB expansion bus window size\n", 356 printk("IXP4xx: Using %luMiB expansion bus window size\n",
356 ixp4xx_exp_bus_size >> 20); 357 ixp4xx_exp_bus_size >> 20);
357} 358}
358 359
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 9d862f86bba6..75110ba10424 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -50,10 +50,10 @@ static int omap1_clk_enable_dsp_domain(struct clk *clk)
50{ 50{
51 int retval; 51 int retval;
52 52
53 retval = omap1_clk_use(&api_ck.clk); 53 retval = omap1_clk_enable(&api_ck.clk);
54 if (!retval) { 54 if (!retval) {
55 retval = omap1_clk_enable(clk); 55 retval = omap1_clk_enable_generic(clk);
56 omap1_clk_unuse(&api_ck.clk); 56 omap1_clk_disable(&api_ck.clk);
57 } 57 }
58 58
59 return retval; 59 return retval;
@@ -61,9 +61,9 @@ static int omap1_clk_enable_dsp_domain(struct clk *clk)
61 61
62static void omap1_clk_disable_dsp_domain(struct clk *clk) 62static void omap1_clk_disable_dsp_domain(struct clk *clk)
63{ 63{
64 if (omap1_clk_use(&api_ck.clk) == 0) { 64 if (omap1_clk_enable(&api_ck.clk) == 0) {
65 omap1_clk_disable(clk); 65 omap1_clk_disable_generic(clk);
66 omap1_clk_unuse(&api_ck.clk); 66 omap1_clk_disable(&api_ck.clk);
67 } 67 }
68} 68}
69 69
@@ -72,7 +72,7 @@ static int omap1_clk_enable_uart_functional(struct clk *clk)
72 int ret; 72 int ret;
73 struct uart_clk *uclk; 73 struct uart_clk *uclk;
74 74
75 ret = omap1_clk_enable(clk); 75 ret = omap1_clk_enable_generic(clk);
76 if (ret == 0) { 76 if (ret == 0) {
77 /* Set smart idle acknowledgement mode */ 77 /* Set smart idle acknowledgement mode */
78 uclk = (struct uart_clk *)clk; 78 uclk = (struct uart_clk *)clk;
@@ -91,7 +91,7 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
91 uclk = (struct uart_clk *)clk; 91 uclk = (struct uart_clk *)clk;
92 omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr); 92 omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
93 93
94 omap1_clk_disable(clk); 94 omap1_clk_disable_generic(clk);
95} 95}
96 96
97static void omap1_clk_allow_idle(struct clk *clk) 97static void omap1_clk_allow_idle(struct clk *clk)
@@ -230,9 +230,9 @@ static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
230 * Note that DSP_CKCTL virt addr = phys addr, so 230 * Note that DSP_CKCTL virt addr = phys addr, so
231 * we must use __raw_readw() instead of omap_readw(). 231 * we must use __raw_readw() instead of omap_readw().
232 */ 232 */
233 omap1_clk_use(&api_ck.clk); 233 omap1_clk_enable(&api_ck.clk);
234 dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); 234 dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
235 omap1_clk_unuse(&api_ck.clk); 235 omap1_clk_disable(&api_ck.clk);
236 236
237 if (unlikely(clk->rate == clk->parent->rate / dsor)) 237 if (unlikely(clk->rate == clk->parent->rate / dsor))
238 return; /* No change, quick exit */ 238 return; /* No change, quick exit */
@@ -412,12 +412,12 @@ static void omap1_init_ext_clk(struct clk * clk)
412 clk-> rate = 96000000 / dsor; 412 clk-> rate = 96000000 / dsor;
413} 413}
414 414
415static int omap1_clk_use(struct clk *clk) 415static int omap1_clk_enable(struct clk *clk)
416{ 416{
417 int ret = 0; 417 int ret = 0;
418 if (clk->usecount++ == 0) { 418 if (clk->usecount++ == 0) {
419 if (likely(clk->parent)) { 419 if (likely(clk->parent)) {
420 ret = omap1_clk_use(clk->parent); 420 ret = omap1_clk_enable(clk->parent);
421 421
422 if (unlikely(ret != 0)) { 422 if (unlikely(ret != 0)) {
423 clk->usecount--; 423 clk->usecount--;
@@ -432,7 +432,7 @@ static int omap1_clk_use(struct clk *clk)
432 ret = clk->enable(clk); 432 ret = clk->enable(clk);
433 433
434 if (unlikely(ret != 0) && clk->parent) { 434 if (unlikely(ret != 0) && clk->parent) {
435 omap1_clk_unuse(clk->parent); 435 omap1_clk_disable(clk->parent);
436 clk->usecount--; 436 clk->usecount--;
437 } 437 }
438 } 438 }
@@ -440,12 +440,12 @@ static int omap1_clk_use(struct clk *clk)
440 return ret; 440 return ret;
441} 441}
442 442
443static void omap1_clk_unuse(struct clk *clk) 443static void omap1_clk_disable(struct clk *clk)
444{ 444{
445 if (clk->usecount > 0 && !(--clk->usecount)) { 445 if (clk->usecount > 0 && !(--clk->usecount)) {
446 clk->disable(clk); 446 clk->disable(clk);
447 if (likely(clk->parent)) { 447 if (likely(clk->parent)) {
448 omap1_clk_unuse(clk->parent); 448 omap1_clk_disable(clk->parent);
449 if (clk->flags & CLOCK_NO_IDLE_PARENT) 449 if (clk->flags & CLOCK_NO_IDLE_PARENT)
450 if (!cpu_is_omap24xx()) 450 if (!cpu_is_omap24xx())
451 omap1_clk_allow_idle(clk->parent); 451 omap1_clk_allow_idle(clk->parent);
@@ -453,7 +453,7 @@ static void omap1_clk_unuse(struct clk *clk)
453 } 453 }
454} 454}
455 455
456static int omap1_clk_enable(struct clk *clk) 456static int omap1_clk_enable_generic(struct clk *clk)
457{ 457{
458 __u16 regval16; 458 __u16 regval16;
459 __u32 regval32; 459 __u32 regval32;
@@ -492,7 +492,7 @@ static int omap1_clk_enable(struct clk *clk)
492 return 0; 492 return 0;
493} 493}
494 494
495static void omap1_clk_disable(struct clk *clk) 495static void omap1_clk_disable_generic(struct clk *clk)
496{ 496{
497 __u16 regval16; 497 __u16 regval16;
498 __u32 regval32; 498 __u32 regval32;
@@ -654,8 +654,8 @@ late_initcall(omap1_late_clk_reset);
654#endif 654#endif
655 655
656static struct clk_functions omap1_clk_functions = { 656static struct clk_functions omap1_clk_functions = {
657 .clk_use = omap1_clk_use, 657 .clk_enable = omap1_clk_enable,
658 .clk_unuse = omap1_clk_unuse, 658 .clk_disable = omap1_clk_disable,
659 .clk_round_rate = omap1_clk_round_rate, 659 .clk_round_rate = omap1_clk_round_rate,
660 .clk_set_rate = omap1_clk_set_rate, 660 .clk_set_rate = omap1_clk_set_rate,
661}; 661};
@@ -780,9 +780,9 @@ int __init omap1_clk_init(void)
780 * Only enable those clocks we will need, let the drivers 780 * Only enable those clocks we will need, let the drivers
781 * enable other clocks as necessary 781 * enable other clocks as necessary
782 */ 782 */
783 clk_use(&armper_ck.clk); 783 clk_enable(&armper_ck.clk);
784 clk_use(&armxor_ck.clk); 784 clk_enable(&armxor_ck.clk);
785 clk_use(&armtim_ck.clk); /* This should be done by timer code */ 785 clk_enable(&armtim_ck.clk); /* This should be done by timer code */
786 786
787 if (cpu_is_omap1510()) 787 if (cpu_is_omap1510())
788 clk_enable(&arm_gpio_ck); 788 clk_enable(&arm_gpio_ck);
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index f3bdfb50e01a..4f18d1b94449 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -13,8 +13,8 @@
13#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H 13#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
14#define __ARCH_ARM_MACH_OMAP1_CLOCK_H 14#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
15 15
16static int omap1_clk_enable(struct clk * clk); 16static int omap1_clk_enable_generic(struct clk * clk);
17static void omap1_clk_disable(struct clk * clk); 17static void omap1_clk_disable_generic(struct clk * clk);
18static void omap1_ckctl_recalc(struct clk * clk); 18static void omap1_ckctl_recalc(struct clk * clk);
19static void omap1_watchdog_recalc(struct clk * clk); 19static void omap1_watchdog_recalc(struct clk * clk);
20static void omap1_ckctl_recalc_dsp_domain(struct clk * clk); 20static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
@@ -30,8 +30,8 @@ static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
30static void omap1_init_ext_clk(struct clk * clk); 30static void omap1_init_ext_clk(struct clk * clk);
31static int omap1_select_table_rate(struct clk * clk, unsigned long rate); 31static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
32static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); 32static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
33static int omap1_clk_use(struct clk *clk); 33static int omap1_clk_enable(struct clk *clk);
34static void omap1_clk_unuse(struct clk *clk); 34static void omap1_clk_disable(struct clk *clk);
35 35
36struct mpu_rate { 36struct mpu_rate {
37 unsigned long rate; 37 unsigned long rate;
@@ -152,8 +152,8 @@ static struct clk ck_ref = {
152 .rate = 12000000, 152 .rate = 12000000,
153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
154 ALWAYS_ENABLED, 154 ALWAYS_ENABLED,
155 .enable = &omap1_clk_enable, 155 .enable = &omap1_clk_enable_generic,
156 .disable = &omap1_clk_disable, 156 .disable = &omap1_clk_disable_generic,
157}; 157};
158 158
159static struct clk ck_dpll1 = { 159static struct clk ck_dpll1 = {
@@ -161,8 +161,8 @@ static struct clk ck_dpll1 = {
161 .parent = &ck_ref, 161 .parent = &ck_ref,
162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
163 RATE_PROPAGATES | ALWAYS_ENABLED, 163 RATE_PROPAGATES | ALWAYS_ENABLED,
164 .enable = &omap1_clk_enable, 164 .enable = &omap1_clk_enable_generic,
165 .disable = &omap1_clk_disable, 165 .disable = &omap1_clk_disable_generic,
166}; 166};
167 167
168static struct arm_idlect1_clk ck_dpll1out = { 168static struct arm_idlect1_clk ck_dpll1out = {
@@ -173,8 +173,8 @@ static struct arm_idlect1_clk ck_dpll1out = {
173 .enable_reg = (void __iomem *)ARM_IDLECT2, 173 .enable_reg = (void __iomem *)ARM_IDLECT2,
174 .enable_bit = EN_CKOUT_ARM, 174 .enable_bit = EN_CKOUT_ARM,
175 .recalc = &followparent_recalc, 175 .recalc = &followparent_recalc,
176 .enable = &omap1_clk_enable, 176 .enable = &omap1_clk_enable_generic,
177 .disable = &omap1_clk_disable, 177 .disable = &omap1_clk_disable_generic,
178 }, 178 },
179 .idlect_shift = 12, 179 .idlect_shift = 12,
180}; 180};
@@ -186,8 +186,8 @@ static struct clk arm_ck = {
186 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, 186 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
187 .rate_offset = CKCTL_ARMDIV_OFFSET, 187 .rate_offset = CKCTL_ARMDIV_OFFSET,
188 .recalc = &omap1_ckctl_recalc, 188 .recalc = &omap1_ckctl_recalc,
189 .enable = &omap1_clk_enable, 189 .enable = &omap1_clk_enable_generic,
190 .disable = &omap1_clk_disable, 190 .disable = &omap1_clk_disable_generic,
191}; 191};
192 192
193static struct arm_idlect1_clk armper_ck = { 193static struct arm_idlect1_clk armper_ck = {
@@ -200,8 +200,8 @@ static struct arm_idlect1_clk armper_ck = {
200 .enable_bit = EN_PERCK, 200 .enable_bit = EN_PERCK,
201 .rate_offset = CKCTL_PERDIV_OFFSET, 201 .rate_offset = CKCTL_PERDIV_OFFSET,
202 .recalc = &omap1_ckctl_recalc, 202 .recalc = &omap1_ckctl_recalc,
203 .enable = &omap1_clk_enable, 203 .enable = &omap1_clk_enable_generic,
204 .disable = &omap1_clk_disable, 204 .disable = &omap1_clk_disable_generic,
205 }, 205 },
206 .idlect_shift = 2, 206 .idlect_shift = 2,
207}; 207};
@@ -213,8 +213,8 @@ static struct clk arm_gpio_ck = {
213 .enable_reg = (void __iomem *)ARM_IDLECT2, 213 .enable_reg = (void __iomem *)ARM_IDLECT2,
214 .enable_bit = EN_GPIOCK, 214 .enable_bit = EN_GPIOCK,
215 .recalc = &followparent_recalc, 215 .recalc = &followparent_recalc,
216 .enable = &omap1_clk_enable, 216 .enable = &omap1_clk_enable_generic,
217 .disable = &omap1_clk_disable, 217 .disable = &omap1_clk_disable_generic,
218}; 218};
219 219
220static struct arm_idlect1_clk armxor_ck = { 220static struct arm_idlect1_clk armxor_ck = {
@@ -226,8 +226,8 @@ static struct arm_idlect1_clk armxor_ck = {
226 .enable_reg = (void __iomem *)ARM_IDLECT2, 226 .enable_reg = (void __iomem *)ARM_IDLECT2,
227 .enable_bit = EN_XORPCK, 227 .enable_bit = EN_XORPCK,
228 .recalc = &followparent_recalc, 228 .recalc = &followparent_recalc,
229 .enable = &omap1_clk_enable, 229 .enable = &omap1_clk_enable_generic,
230 .disable = &omap1_clk_disable, 230 .disable = &omap1_clk_disable_generic,
231 }, 231 },
232 .idlect_shift = 1, 232 .idlect_shift = 1,
233}; 233};
@@ -241,8 +241,8 @@ static struct arm_idlect1_clk armtim_ck = {
241 .enable_reg = (void __iomem *)ARM_IDLECT2, 241 .enable_reg = (void __iomem *)ARM_IDLECT2,
242 .enable_bit = EN_TIMCK, 242 .enable_bit = EN_TIMCK,
243 .recalc = &followparent_recalc, 243 .recalc = &followparent_recalc,
244 .enable = &omap1_clk_enable, 244 .enable = &omap1_clk_enable_generic,
245 .disable = &omap1_clk_disable, 245 .disable = &omap1_clk_disable_generic,
246 }, 246 },
247 .idlect_shift = 9, 247 .idlect_shift = 9,
248}; 248};
@@ -256,8 +256,8 @@ static struct arm_idlect1_clk armwdt_ck = {
256 .enable_reg = (void __iomem *)ARM_IDLECT2, 256 .enable_reg = (void __iomem *)ARM_IDLECT2,
257 .enable_bit = EN_WDTCK, 257 .enable_bit = EN_WDTCK,
258 .recalc = &omap1_watchdog_recalc, 258 .recalc = &omap1_watchdog_recalc,
259 .enable = &omap1_clk_enable, 259 .enable = &omap1_clk_enable_generic,
260 .disable = &omap1_clk_disable, 260 .disable = &omap1_clk_disable_generic,
261 }, 261 },
262 .idlect_shift = 0, 262 .idlect_shift = 0,
263}; 263};
@@ -272,8 +272,8 @@ static struct clk arminth_ck16xx = {
272 * 272 *
273 * 1510 version is in TC clocks. 273 * 1510 version is in TC clocks.
274 */ 274 */
275 .enable = &omap1_clk_enable, 275 .enable = &omap1_clk_enable_generic,
276 .disable = &omap1_clk_disable, 276 .disable = &omap1_clk_disable_generic,
277}; 277};
278 278
279static struct clk dsp_ck = { 279static struct clk dsp_ck = {
@@ -285,8 +285,8 @@ static struct clk dsp_ck = {
285 .enable_bit = EN_DSPCK, 285 .enable_bit = EN_DSPCK,
286 .rate_offset = CKCTL_DSPDIV_OFFSET, 286 .rate_offset = CKCTL_DSPDIV_OFFSET,
287 .recalc = &omap1_ckctl_recalc, 287 .recalc = &omap1_ckctl_recalc,
288 .enable = &omap1_clk_enable, 288 .enable = &omap1_clk_enable_generic,
289 .disable = &omap1_clk_disable, 289 .disable = &omap1_clk_disable_generic,
290}; 290};
291 291
292static struct clk dspmmu_ck = { 292static struct clk dspmmu_ck = {
@@ -296,8 +296,8 @@ static struct clk dspmmu_ck = {
296 RATE_CKCTL | ALWAYS_ENABLED, 296 RATE_CKCTL | ALWAYS_ENABLED,
297 .rate_offset = CKCTL_DSPMMUDIV_OFFSET, 297 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
298 .recalc = &omap1_ckctl_recalc, 298 .recalc = &omap1_ckctl_recalc,
299 .enable = &omap1_clk_enable, 299 .enable = &omap1_clk_enable_generic,
300 .disable = &omap1_clk_disable, 300 .disable = &omap1_clk_disable_generic,
301}; 301};
302 302
303static struct clk dspper_ck = { 303static struct clk dspper_ck = {
@@ -349,8 +349,8 @@ static struct arm_idlect1_clk tc_ck = {
349 CLOCK_IDLE_CONTROL, 349 CLOCK_IDLE_CONTROL,
350 .rate_offset = CKCTL_TCDIV_OFFSET, 350 .rate_offset = CKCTL_TCDIV_OFFSET,
351 .recalc = &omap1_ckctl_recalc, 351 .recalc = &omap1_ckctl_recalc,
352 .enable = &omap1_clk_enable, 352 .enable = &omap1_clk_enable_generic,
353 .disable = &omap1_clk_disable, 353 .disable = &omap1_clk_disable_generic,
354 }, 354 },
355 .idlect_shift = 6, 355 .idlect_shift = 6,
356}; 356};
@@ -364,8 +364,8 @@ static struct clk arminth_ck1510 = {
364 * 364 *
365 * 16xx version is in MPU clocks. 365 * 16xx version is in MPU clocks.
366 */ 366 */
367 .enable = &omap1_clk_enable, 367 .enable = &omap1_clk_enable_generic,
368 .disable = &omap1_clk_disable, 368 .disable = &omap1_clk_disable_generic,
369}; 369};
370 370
371static struct clk tipb_ck = { 371static struct clk tipb_ck = {
@@ -374,8 +374,8 @@ static struct clk tipb_ck = {
374 .parent = &tc_ck.clk, 374 .parent = &tc_ck.clk,
375 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, 375 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
376 .recalc = &followparent_recalc, 376 .recalc = &followparent_recalc,
377 .enable = &omap1_clk_enable, 377 .enable = &omap1_clk_enable_generic,
378 .disable = &omap1_clk_disable, 378 .disable = &omap1_clk_disable_generic,
379}; 379};
380 380
381static struct clk l3_ocpi_ck = { 381static struct clk l3_ocpi_ck = {
@@ -386,8 +386,8 @@ static struct clk l3_ocpi_ck = {
386 .enable_reg = (void __iomem *)ARM_IDLECT3, 386 .enable_reg = (void __iomem *)ARM_IDLECT3,
387 .enable_bit = EN_OCPI_CK, 387 .enable_bit = EN_OCPI_CK,
388 .recalc = &followparent_recalc, 388 .recalc = &followparent_recalc,
389 .enable = &omap1_clk_enable, 389 .enable = &omap1_clk_enable_generic,
390 .disable = &omap1_clk_disable, 390 .disable = &omap1_clk_disable_generic,
391}; 391};
392 392
393static struct clk tc1_ck = { 393static struct clk tc1_ck = {
@@ -397,8 +397,8 @@ static struct clk tc1_ck = {
397 .enable_reg = (void __iomem *)ARM_IDLECT3, 397 .enable_reg = (void __iomem *)ARM_IDLECT3,
398 .enable_bit = EN_TC1_CK, 398 .enable_bit = EN_TC1_CK,
399 .recalc = &followparent_recalc, 399 .recalc = &followparent_recalc,
400 .enable = &omap1_clk_enable, 400 .enable = &omap1_clk_enable_generic,
401 .disable = &omap1_clk_disable, 401 .disable = &omap1_clk_disable_generic,
402}; 402};
403 403
404static struct clk tc2_ck = { 404static struct clk tc2_ck = {
@@ -408,8 +408,8 @@ static struct clk tc2_ck = {
408 .enable_reg = (void __iomem *)ARM_IDLECT3, 408 .enable_reg = (void __iomem *)ARM_IDLECT3,
409 .enable_bit = EN_TC2_CK, 409 .enable_bit = EN_TC2_CK,
410 .recalc = &followparent_recalc, 410 .recalc = &followparent_recalc,
411 .enable = &omap1_clk_enable, 411 .enable = &omap1_clk_enable_generic,
412 .disable = &omap1_clk_disable, 412 .disable = &omap1_clk_disable_generic,
413}; 413};
414 414
415static struct clk dma_ck = { 415static struct clk dma_ck = {
@@ -419,8 +419,8 @@ static struct clk dma_ck = {
419 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 419 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
420 ALWAYS_ENABLED, 420 ALWAYS_ENABLED,
421 .recalc = &followparent_recalc, 421 .recalc = &followparent_recalc,
422 .enable = &omap1_clk_enable, 422 .enable = &omap1_clk_enable_generic,
423 .disable = &omap1_clk_disable, 423 .disable = &omap1_clk_disable_generic,
424}; 424};
425 425
426static struct clk dma_lcdfree_ck = { 426static struct clk dma_lcdfree_ck = {
@@ -428,8 +428,8 @@ static struct clk dma_lcdfree_ck = {
428 .parent = &tc_ck.clk, 428 .parent = &tc_ck.clk,
429 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 429 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
430 .recalc = &followparent_recalc, 430 .recalc = &followparent_recalc,
431 .enable = &omap1_clk_enable, 431 .enable = &omap1_clk_enable_generic,
432 .disable = &omap1_clk_disable, 432 .disable = &omap1_clk_disable_generic,
433}; 433};
434 434
435static struct arm_idlect1_clk api_ck = { 435static struct arm_idlect1_clk api_ck = {
@@ -441,8 +441,8 @@ static struct arm_idlect1_clk api_ck = {
441 .enable_reg = (void __iomem *)ARM_IDLECT2, 441 .enable_reg = (void __iomem *)ARM_IDLECT2,
442 .enable_bit = EN_APICK, 442 .enable_bit = EN_APICK,
443 .recalc = &followparent_recalc, 443 .recalc = &followparent_recalc,
444 .enable = &omap1_clk_enable, 444 .enable = &omap1_clk_enable_generic,
445 .disable = &omap1_clk_disable, 445 .disable = &omap1_clk_disable_generic,
446 }, 446 },
447 .idlect_shift = 8, 447 .idlect_shift = 8,
448}; 448};
@@ -455,8 +455,8 @@ static struct arm_idlect1_clk lb_ck = {
455 .enable_reg = (void __iomem *)ARM_IDLECT2, 455 .enable_reg = (void __iomem *)ARM_IDLECT2,
456 .enable_bit = EN_LBCK, 456 .enable_bit = EN_LBCK,
457 .recalc = &followparent_recalc, 457 .recalc = &followparent_recalc,
458 .enable = &omap1_clk_enable, 458 .enable = &omap1_clk_enable_generic,
459 .disable = &omap1_clk_disable, 459 .disable = &omap1_clk_disable_generic,
460 }, 460 },
461 .idlect_shift = 4, 461 .idlect_shift = 4,
462}; 462};
@@ -466,8 +466,8 @@ static struct clk rhea1_ck = {
466 .parent = &tc_ck.clk, 466 .parent = &tc_ck.clk,
467 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 467 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
468 .recalc = &followparent_recalc, 468 .recalc = &followparent_recalc,
469 .enable = &omap1_clk_enable, 469 .enable = &omap1_clk_enable_generic,
470 .disable = &omap1_clk_disable, 470 .disable = &omap1_clk_disable_generic,
471}; 471};
472 472
473static struct clk rhea2_ck = { 473static struct clk rhea2_ck = {
@@ -475,8 +475,8 @@ static struct clk rhea2_ck = {
475 .parent = &tc_ck.clk, 475 .parent = &tc_ck.clk,
476 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, 476 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
477 .recalc = &followparent_recalc, 477 .recalc = &followparent_recalc,
478 .enable = &omap1_clk_enable, 478 .enable = &omap1_clk_enable_generic,
479 .disable = &omap1_clk_disable, 479 .disable = &omap1_clk_disable_generic,
480}; 480};
481 481
482static struct clk lcd_ck_16xx = { 482static struct clk lcd_ck_16xx = {
@@ -487,8 +487,8 @@ static struct clk lcd_ck_16xx = {
487 .enable_bit = EN_LCDCK, 487 .enable_bit = EN_LCDCK,
488 .rate_offset = CKCTL_LCDDIV_OFFSET, 488 .rate_offset = CKCTL_LCDDIV_OFFSET,
489 .recalc = &omap1_ckctl_recalc, 489 .recalc = &omap1_ckctl_recalc,
490 .enable = &omap1_clk_enable, 490 .enable = &omap1_clk_enable_generic,
491 .disable = &omap1_clk_disable, 491 .disable = &omap1_clk_disable_generic,
492}; 492};
493 493
494static struct arm_idlect1_clk lcd_ck_1510 = { 494static struct arm_idlect1_clk lcd_ck_1510 = {
@@ -501,8 +501,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
501 .enable_bit = EN_LCDCK, 501 .enable_bit = EN_LCDCK,
502 .rate_offset = CKCTL_LCDDIV_OFFSET, 502 .rate_offset = CKCTL_LCDDIV_OFFSET,
503 .recalc = &omap1_ckctl_recalc, 503 .recalc = &omap1_ckctl_recalc,
504 .enable = &omap1_clk_enable, 504 .enable = &omap1_clk_enable_generic,
505 .disable = &omap1_clk_disable, 505 .disable = &omap1_clk_disable_generic,
506 }, 506 },
507 .idlect_shift = 3, 507 .idlect_shift = 3,
508}; 508};
@@ -518,8 +518,8 @@ static struct clk uart1_1510 = {
518 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ 518 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
519 .set_rate = &omap1_set_uart_rate, 519 .set_rate = &omap1_set_uart_rate,
520 .recalc = &omap1_uart_recalc, 520 .recalc = &omap1_uart_recalc,
521 .enable = &omap1_clk_enable, 521 .enable = &omap1_clk_enable_generic,
522 .disable = &omap1_clk_disable, 522 .disable = &omap1_clk_disable_generic,
523}; 523};
524 524
525static struct uart_clk uart1_16xx = { 525static struct uart_clk uart1_16xx = {
@@ -550,8 +550,8 @@ static struct clk uart2_ck = {
550 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ 550 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
551 .set_rate = &omap1_set_uart_rate, 551 .set_rate = &omap1_set_uart_rate,
552 .recalc = &omap1_uart_recalc, 552 .recalc = &omap1_uart_recalc,
553 .enable = &omap1_clk_enable, 553 .enable = &omap1_clk_enable_generic,
554 .disable = &omap1_clk_disable, 554 .disable = &omap1_clk_disable_generic,
555}; 555};
556 556
557static struct clk uart3_1510 = { 557static struct clk uart3_1510 = {
@@ -565,8 +565,8 @@ static struct clk uart3_1510 = {
565 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ 565 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
566 .set_rate = &omap1_set_uart_rate, 566 .set_rate = &omap1_set_uart_rate,
567 .recalc = &omap1_uart_recalc, 567 .recalc = &omap1_uart_recalc,
568 .enable = &omap1_clk_enable, 568 .enable = &omap1_clk_enable_generic,
569 .disable = &omap1_clk_disable, 569 .disable = &omap1_clk_disable_generic,
570}; 570};
571 571
572static struct uart_clk uart3_16xx = { 572static struct uart_clk uart3_16xx = {
@@ -593,8 +593,8 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
593 RATE_FIXED | ENABLE_REG_32BIT, 593 RATE_FIXED | ENABLE_REG_32BIT,
594 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, 594 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
595 .enable_bit = USB_MCLK_EN_BIT, 595 .enable_bit = USB_MCLK_EN_BIT,
596 .enable = &omap1_clk_enable, 596 .enable = &omap1_clk_enable_generic,
597 .disable = &omap1_clk_disable, 597 .disable = &omap1_clk_disable_generic,
598}; 598};
599 599
600static struct clk usb_hhc_ck1510 = { 600static struct clk usb_hhc_ck1510 = {
@@ -605,8 +605,8 @@ static struct clk usb_hhc_ck1510 = {
605 RATE_FIXED | ENABLE_REG_32BIT, 605 RATE_FIXED | ENABLE_REG_32BIT,
606 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 606 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
607 .enable_bit = USB_HOST_HHC_UHOST_EN, 607 .enable_bit = USB_HOST_HHC_UHOST_EN,
608 .enable = &omap1_clk_enable, 608 .enable = &omap1_clk_enable_generic,
609 .disable = &omap1_clk_disable, 609 .disable = &omap1_clk_disable_generic,
610}; 610};
611 611
612static struct clk usb_hhc_ck16xx = { 612static struct clk usb_hhc_ck16xx = {
@@ -618,8 +618,8 @@ static struct clk usb_hhc_ck16xx = {
618 RATE_FIXED | ENABLE_REG_32BIT, 618 RATE_FIXED | ENABLE_REG_32BIT,
619 .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */, 619 .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
620 .enable_bit = 8 /* UHOST_EN */, 620 .enable_bit = 8 /* UHOST_EN */,
621 .enable = &omap1_clk_enable, 621 .enable = &omap1_clk_enable_generic,
622 .disable = &omap1_clk_disable, 622 .disable = &omap1_clk_disable_generic,
623}; 623};
624 624
625static struct clk usb_dc_ck = { 625static struct clk usb_dc_ck = {
@@ -629,8 +629,8 @@ static struct clk usb_dc_ck = {
629 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED, 629 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
630 .enable_reg = (void __iomem *)SOFT_REQ_REG, 630 .enable_reg = (void __iomem *)SOFT_REQ_REG,
631 .enable_bit = 4, 631 .enable_bit = 4,
632 .enable = &omap1_clk_enable, 632 .enable = &omap1_clk_enable_generic,
633 .disable = &omap1_clk_disable, 633 .disable = &omap1_clk_disable_generic,
634}; 634};
635 635
636static struct clk mclk_1510 = { 636static struct clk mclk_1510 = {
@@ -638,8 +638,8 @@ static struct clk mclk_1510 = {
638 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 638 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
639 .rate = 12000000, 639 .rate = 12000000,
640 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, 640 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
641 .enable = &omap1_clk_enable, 641 .enable = &omap1_clk_enable_generic,
642 .disable = &omap1_clk_disable, 642 .disable = &omap1_clk_disable_generic,
643}; 643};
644 644
645static struct clk mclk_16xx = { 645static struct clk mclk_16xx = {
@@ -651,8 +651,8 @@ static struct clk mclk_16xx = {
651 .set_rate = &omap1_set_ext_clk_rate, 651 .set_rate = &omap1_set_ext_clk_rate,
652 .round_rate = &omap1_round_ext_clk_rate, 652 .round_rate = &omap1_round_ext_clk_rate,
653 .init = &omap1_init_ext_clk, 653 .init = &omap1_init_ext_clk,
654 .enable = &omap1_clk_enable, 654 .enable = &omap1_clk_enable_generic,
655 .disable = &omap1_clk_disable, 655 .disable = &omap1_clk_disable_generic,
656}; 656};
657 657
658static struct clk bclk_1510 = { 658static struct clk bclk_1510 = {
@@ -660,8 +660,8 @@ static struct clk bclk_1510 = {
660 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 660 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
661 .rate = 12000000, 661 .rate = 12000000,
662 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, 662 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
663 .enable = &omap1_clk_enable, 663 .enable = &omap1_clk_enable_generic,
664 .disable = &omap1_clk_disable, 664 .disable = &omap1_clk_disable_generic,
665}; 665};
666 666
667static struct clk bclk_16xx = { 667static struct clk bclk_16xx = {
@@ -673,8 +673,8 @@ static struct clk bclk_16xx = {
673 .set_rate = &omap1_set_ext_clk_rate, 673 .set_rate = &omap1_set_ext_clk_rate,
674 .round_rate = &omap1_round_ext_clk_rate, 674 .round_rate = &omap1_round_ext_clk_rate,
675 .init = &omap1_init_ext_clk, 675 .init = &omap1_init_ext_clk,
676 .enable = &omap1_clk_enable, 676 .enable = &omap1_clk_enable_generic,
677 .disable = &omap1_clk_disable, 677 .disable = &omap1_clk_disable_generic,
678}; 678};
679 679
680static struct clk mmc1_ck = { 680static struct clk mmc1_ck = {
@@ -686,8 +686,8 @@ static struct clk mmc1_ck = {
686 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 686 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
687 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 687 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
688 .enable_bit = 23, 688 .enable_bit = 23,
689 .enable = &omap1_clk_enable, 689 .enable = &omap1_clk_enable_generic,
690 .disable = &omap1_clk_disable, 690 .disable = &omap1_clk_disable_generic,
691}; 691};
692 692
693static struct clk mmc2_ck = { 693static struct clk mmc2_ck = {
@@ -699,8 +699,8 @@ static struct clk mmc2_ck = {
699 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 699 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
700 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 700 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
701 .enable_bit = 20, 701 .enable_bit = 20,
702 .enable = &omap1_clk_enable, 702 .enable = &omap1_clk_enable_generic,
703 .disable = &omap1_clk_disable, 703 .disable = &omap1_clk_disable_generic,
704}; 704};
705 705
706static struct clk virtual_ck_mpu = { 706static struct clk virtual_ck_mpu = {
@@ -711,8 +711,8 @@ static struct clk virtual_ck_mpu = {
711 .recalc = &followparent_recalc, 711 .recalc = &followparent_recalc,
712 .set_rate = &omap1_select_table_rate, 712 .set_rate = &omap1_select_table_rate,
713 .round_rate = &omap1_round_to_table_rate, 713 .round_rate = &omap1_round_to_table_rate,
714 .enable = &omap1_clk_enable, 714 .enable = &omap1_clk_enable_generic,
715 .disable = &omap1_clk_disable, 715 .disable = &omap1_clk_disable_generic,
716}; 716};
717 717
718static struct clk * onchip_clks[] = { 718static struct clk * onchip_clks[] = {
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 7a68f098a025..e924e0c6a4ce 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -146,7 +146,7 @@ void __init omap_serial_init(void)
146 if (IS_ERR(uart1_ck)) 146 if (IS_ERR(uart1_ck))
147 printk("Could not get uart1_ck\n"); 147 printk("Could not get uart1_ck\n");
148 else { 148 else {
149 clk_use(uart1_ck); 149 clk_enable(uart1_ck);
150 if (cpu_is_omap1510()) 150 if (cpu_is_omap1510())
151 clk_set_rate(uart1_ck, 12000000); 151 clk_set_rate(uart1_ck, 12000000);
152 } 152 }
@@ -166,7 +166,7 @@ void __init omap_serial_init(void)
166 if (IS_ERR(uart2_ck)) 166 if (IS_ERR(uart2_ck))
167 printk("Could not get uart2_ck\n"); 167 printk("Could not get uart2_ck\n");
168 else { 168 else {
169 clk_use(uart2_ck); 169 clk_enable(uart2_ck);
170 if (cpu_is_omap1510()) 170 if (cpu_is_omap1510())
171 clk_set_rate(uart2_ck, 12000000); 171 clk_set_rate(uart2_ck, 12000000);
172 else 172 else
@@ -188,7 +188,7 @@ void __init omap_serial_init(void)
188 if (IS_ERR(uart3_ck)) 188 if (IS_ERR(uart3_ck))
189 printk("Could not get uart3_ck\n"); 189 printk("Could not get uart3_ck\n");
190 else { 190 else {
191 clk_use(uart3_ck); 191 clk_enable(uart3_ck);
192 if (cpu_is_omap1510()) 192 if (cpu_is_omap1510())
193 clk_set_rate(uart3_ck, 12000000); 193 clk_set_rate(uart3_ck, 12000000);
194 } 194 }
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 5407b9549150..180f675c9064 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -111,7 +111,7 @@ static void omap2_clk_fixed_enable(struct clk *clk)
111/* Enables clock without considering parent dependencies or use count 111/* Enables clock without considering parent dependencies or use count
112 * REVISIT: Maybe change this to use clk->enable like on omap1? 112 * REVISIT: Maybe change this to use clk->enable like on omap1?
113 */ 113 */
114static int omap2_clk_enable(struct clk * clk) 114static int _omap2_clk_enable(struct clk * clk)
115{ 115{
116 u32 regval32; 116 u32 regval32;
117 117
@@ -150,7 +150,7 @@ static void omap2_clk_fixed_disable(struct clk *clk)
150} 150}
151 151
152/* Disables clock without considering parent dependencies or use count */ 152/* Disables clock without considering parent dependencies or use count */
153static void omap2_clk_disable(struct clk *clk) 153static void _omap2_clk_disable(struct clk *clk)
154{ 154{
155 u32 regval32; 155 u32 regval32;
156 156
@@ -167,23 +167,23 @@ static void omap2_clk_disable(struct clk *clk)
167 __raw_writel(regval32, clk->enable_reg); 167 __raw_writel(regval32, clk->enable_reg);
168} 168}
169 169
170static int omap2_clk_use(struct clk *clk) 170static int omap2_clk_enable(struct clk *clk)
171{ 171{
172 int ret = 0; 172 int ret = 0;
173 173
174 if (clk->usecount++ == 0) { 174 if (clk->usecount++ == 0) {
175 if (likely((u32)clk->parent)) 175 if (likely((u32)clk->parent))
176 ret = omap2_clk_use(clk->parent); 176 ret = omap2_clk_enable(clk->parent);
177 177
178 if (unlikely(ret != 0)) { 178 if (unlikely(ret != 0)) {
179 clk->usecount--; 179 clk->usecount--;
180 return ret; 180 return ret;
181 } 181 }
182 182
183 ret = omap2_clk_enable(clk); 183 ret = _omap2_clk_enable(clk);
184 184
185 if (unlikely(ret != 0) && clk->parent) { 185 if (unlikely(ret != 0) && clk->parent) {
186 omap2_clk_unuse(clk->parent); 186 omap2_clk_disable(clk->parent);
187 clk->usecount--; 187 clk->usecount--;
188 } 188 }
189 } 189 }
@@ -191,12 +191,12 @@ static int omap2_clk_use(struct clk *clk)
191 return ret; 191 return ret;
192} 192}
193 193
194static void omap2_clk_unuse(struct clk *clk) 194static void omap2_clk_disable(struct clk *clk)
195{ 195{
196 if (clk->usecount > 0 && !(--clk->usecount)) { 196 if (clk->usecount > 0 && !(--clk->usecount)) {
197 omap2_clk_disable(clk); 197 _omap2_clk_disable(clk);
198 if (likely((u32)clk->parent)) 198 if (likely((u32)clk->parent))
199 omap2_clk_unuse(clk->parent); 199 omap2_clk_disable(clk->parent);
200 } 200 }
201} 201}
202 202
@@ -873,7 +873,7 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
873 reg = (void __iomem *)src_sel; 873 reg = (void __iomem *)src_sel;
874 874
875 if (clk->usecount > 0) 875 if (clk->usecount > 0)
876 omap2_clk_disable(clk); 876 _omap2_clk_disable(clk);
877 877
878 /* Set new source value (previous dividers if any in effect) */ 878 /* Set new source value (previous dividers if any in effect) */
879 reg_val = __raw_readl(reg) & ~(field_mask << src_off); 879 reg_val = __raw_readl(reg) & ~(field_mask << src_off);
@@ -884,7 +884,7 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
884 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 884 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
885 885
886 if (clk->usecount > 0) 886 if (clk->usecount > 0)
887 omap2_clk_enable(clk); 887 _omap2_clk_enable(clk);
888 888
889 clk->parent = new_parent; 889 clk->parent = new_parent;
890 890
@@ -999,8 +999,6 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
999static struct clk_functions omap2_clk_functions = { 999static struct clk_functions omap2_clk_functions = {
1000 .clk_enable = omap2_clk_enable, 1000 .clk_enable = omap2_clk_enable,
1001 .clk_disable = omap2_clk_disable, 1001 .clk_disable = omap2_clk_disable,
1002 .clk_use = omap2_clk_use,
1003 .clk_unuse = omap2_clk_unuse,
1004 .clk_round_rate = omap2_clk_round_rate, 1002 .clk_round_rate = omap2_clk_round_rate,
1005 .clk_set_rate = omap2_clk_set_rate, 1003 .clk_set_rate = omap2_clk_set_rate,
1006 .clk_set_parent = omap2_clk_set_parent, 1004 .clk_set_parent = omap2_clk_set_parent,
@@ -1045,7 +1043,7 @@ static void __init omap2_disable_unused_clocks(void)
1045 continue; 1043 continue;
1046 1044
1047 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); 1045 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
1048 omap2_clk_disable(ck); 1046 _omap2_clk_disable(ck);
1049 } 1047 }
1050} 1048}
1051late_initcall(omap2_disable_unused_clocks); 1049late_initcall(omap2_disable_unused_clocks);
@@ -1120,10 +1118,10 @@ int __init omap2_clk_init(void)
1120 * Only enable those clocks we will need, let the drivers 1118 * Only enable those clocks we will need, let the drivers
1121 * enable other clocks as necessary 1119 * enable other clocks as necessary
1122 */ 1120 */
1123 clk_use(&sync_32k_ick); 1121 clk_enable(&sync_32k_ick);
1124 clk_use(&omapctrl_ick); 1122 clk_enable(&omapctrl_ick);
1125 if (cpu_is_omap2430()) 1123 if (cpu_is_omap2430())
1126 clk_use(&sdrc_ick); 1124 clk_enable(&sdrc_ick);
1127 1125
1128 return 0; 1126 return 0;
1129} 1127}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 4aeab5591bd3..6cab20b1d3c1 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -24,7 +24,7 @@ static void omap2_propagate_rate(struct clk * clk);
24static void omap2_mpu_recalc(struct clk * clk); 24static void omap2_mpu_recalc(struct clk * clk);
25static int omap2_select_table_rate(struct clk * clk, unsigned long rate); 25static int omap2_select_table_rate(struct clk * clk, unsigned long rate);
26static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate); 26static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate);
27static void omap2_clk_unuse(struct clk *clk); 27static void omap2_clk_disable(struct clk *clk);
28static void omap2_sys_clk_recalc(struct clk * clk); 28static void omap2_sys_clk_recalc(struct clk * clk);
29static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val); 29static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val);
30static u32 omap2_clksel_get_divisor(struct clk *clk); 30static u32 omap2_clksel_get_divisor(struct clk *clk);
@@ -859,7 +859,7 @@ static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
859 859
860static struct clk usb_l4_ick = { /* FS-USB interface clock */ 860static struct clk usb_l4_ick = { /* FS-USB interface clock */
861 .name = "usb_l4_ick", 861 .name = "usb_l4_ick",
862 .parent = &core_ck, 862 .parent = &core_l3_ck,
863 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | 863 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
864 RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP | 864 RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP |
865 CONFIG_PARTICIPANT, 865 CONFIG_PARTICIPANT,
@@ -1045,7 +1045,7 @@ static struct clk gpt1_ick = {
1045 .name = "gpt1_ick", 1045 .name = "gpt1_ick",
1046 .parent = &l4_ck, 1046 .parent = &l4_ck,
1047 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1047 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1048 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, /* Bit4 */ 1048 .enable_reg = (void __iomem *)&CM_ICLKEN_WKUP, /* Bit0 */
1049 .enable_bit = 0, 1049 .enable_bit = 0,
1050 .recalc = &omap2_followparent_recalc, 1050 .recalc = &omap2_followparent_recalc,
1051}; 1051};
@@ -1055,7 +1055,7 @@ static struct clk gpt1_fck = {
1055 .parent = &func_32k_ck, 1055 .parent = &func_32k_ck,
1056 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | 1056 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
1057 CM_WKUP_SEL1, 1057 CM_WKUP_SEL1,
1058 .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP, 1058 .enable_reg = (void __iomem *)&CM_FCLKEN_WKUP, /* Bit0 */
1059 .enable_bit = 0, 1059 .enable_bit = 0,
1060 .src_offset = 0, 1060 .src_offset = 0,
1061 .recalc = &omap2_followparent_recalc, 1061 .recalc = &omap2_followparent_recalc,
@@ -1065,7 +1065,7 @@ static struct clk gpt2_ick = {
1065 .name = "gpt2_ick", 1065 .name = "gpt2_ick",
1066 .parent = &l4_ck, 1066 .parent = &l4_ck,
1067 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1067 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1068 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* bit4 */ 1068 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, /* Bit4 */
1069 .enable_bit = 0, 1069 .enable_bit = 0,
1070 .recalc = &omap2_followparent_recalc, 1070 .recalc = &omap2_followparent_recalc,
1071}; 1071};
@@ -1839,7 +1839,7 @@ static struct clk usb_fck = {
1839 1839
1840static struct clk usbhs_ick = { 1840static struct clk usbhs_ick = {
1841 .name = "usbhs_ick", 1841 .name = "usbhs_ick",
1842 .parent = &l4_ck, 1842 .parent = &core_l3_ck,
1843 .flags = CLOCK_IN_OMAP243X, 1843 .flags = CLOCK_IN_OMAP243X,
1844 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, 1844 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
1845 .enable_bit = 6, 1845 .enable_bit = 6,
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index e1bd46a96e11..24dd374224af 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -119,14 +119,14 @@ void __init omap_serial_init()
119 if (IS_ERR(uart1_ick)) 119 if (IS_ERR(uart1_ick))
120 printk("Could not get uart1_ick\n"); 120 printk("Could not get uart1_ick\n");
121 else { 121 else {
122 clk_use(uart1_ick); 122 clk_enable(uart1_ick);
123 } 123 }
124 124
125 uart1_fck = clk_get(NULL, "uart1_fck"); 125 uart1_fck = clk_get(NULL, "uart1_fck");
126 if (IS_ERR(uart1_fck)) 126 if (IS_ERR(uart1_fck))
127 printk("Could not get uart1_fck\n"); 127 printk("Could not get uart1_fck\n");
128 else { 128 else {
129 clk_use(uart1_fck); 129 clk_enable(uart1_fck);
130 } 130 }
131 break; 131 break;
132 case 1: 132 case 1:
@@ -134,14 +134,14 @@ void __init omap_serial_init()
134 if (IS_ERR(uart2_ick)) 134 if (IS_ERR(uart2_ick))
135 printk("Could not get uart2_ick\n"); 135 printk("Could not get uart2_ick\n");
136 else { 136 else {
137 clk_use(uart2_ick); 137 clk_enable(uart2_ick);
138 } 138 }
139 139
140 uart2_fck = clk_get(NULL, "uart2_fck"); 140 uart2_fck = clk_get(NULL, "uart2_fck");
141 if (IS_ERR(uart2_fck)) 141 if (IS_ERR(uart2_fck))
142 printk("Could not get uart2_fck\n"); 142 printk("Could not get uart2_fck\n");
143 else { 143 else {
144 clk_use(uart2_fck); 144 clk_enable(uart2_fck);
145 } 145 }
146 break; 146 break;
147 case 2: 147 case 2:
@@ -149,14 +149,14 @@ void __init omap_serial_init()
149 if (IS_ERR(uart3_ick)) 149 if (IS_ERR(uart3_ick))
150 printk("Could not get uart3_ick\n"); 150 printk("Could not get uart3_ick\n");
151 else { 151 else {
152 clk_use(uart3_ick); 152 clk_enable(uart3_ick);
153 } 153 }
154 154
155 uart3_fck = clk_get(NULL, "uart3_fck"); 155 uart3_fck = clk_get(NULL, "uart3_fck");
156 if (IS_ERR(uart3_fck)) 156 if (IS_ERR(uart3_fck))
157 printk("Could not get uart3_fck\n"); 157 printk("Could not get uart3_fck\n");
158 else { 158 else {
159 clk_use(uart3_fck); 159 clk_enable(uart3_fck);
160 } 160 }
161 break; 161 break;
162 } 162 }
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 23d36b1c40fe..1d2f5ac2f69b 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -104,7 +104,7 @@ static void __init omap2_gp_timer_init(void)
104 if (IS_ERR(sys_ck)) 104 if (IS_ERR(sys_ck))
105 printk(KERN_ERR "Could not get sys_ck\n"); 105 printk(KERN_ERR "Could not get sys_ck\n");
106 else { 106 else {
107 clk_use(sys_ck); 107 clk_enable(sys_ck);
108 tick_period = clk_get_rate(sys_ck) / 100; 108 tick_period = clk_get_rate(sys_ck) / 100;
109 clk_put(sys_ck); 109 clk_put(sys_ck);
110 } 110 }
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 7ebc5a29db8d..3c2bfc0efdaf 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -34,7 +34,7 @@ DEFINE_SPINLOCK(clockfw_lock);
34static struct clk_functions *arch_clock; 34static struct clk_functions *arch_clock;
35 35
36/*------------------------------------------------------------------------- 36/*-------------------------------------------------------------------------
37 * Standard clock functions defined in asm/hardware/clock.h 37 * Standard clock functions defined in include/linux/clk.h
38 *-------------------------------------------------------------------------*/ 38 *-------------------------------------------------------------------------*/
39 39
40struct clk * clk_get(struct device *dev, const char *id) 40struct clk * clk_get(struct device *dev, const char *id)
@@ -60,12 +60,8 @@ int clk_enable(struct clk *clk)
60 int ret = 0; 60 int ret = 0;
61 61
62 spin_lock_irqsave(&clockfw_lock, flags); 62 spin_lock_irqsave(&clockfw_lock, flags);
63 if (clk->enable) 63 if (arch_clock->clk_enable)
64 ret = clk->enable(clk);
65 else if (arch_clock->clk_enable)
66 ret = arch_clock->clk_enable(clk); 64 ret = arch_clock->clk_enable(clk);
67 else
68 printk(KERN_ERR "Could not enable clock %s\n", clk->name);
69 spin_unlock_irqrestore(&clockfw_lock, flags); 65 spin_unlock_irqrestore(&clockfw_lock, flags);
70 66
71 return ret; 67 return ret;
@@ -77,41 +73,12 @@ void clk_disable(struct clk *clk)
77 unsigned long flags; 73 unsigned long flags;
78 74
79 spin_lock_irqsave(&clockfw_lock, flags); 75 spin_lock_irqsave(&clockfw_lock, flags);
80 if (clk->disable) 76 if (arch_clock->clk_disable)
81 clk->disable(clk);
82 else if (arch_clock->clk_disable)
83 arch_clock->clk_disable(clk); 77 arch_clock->clk_disable(clk);
84 else
85 printk(KERN_ERR "Could not disable clock %s\n", clk->name);
86 spin_unlock_irqrestore(&clockfw_lock, flags); 78 spin_unlock_irqrestore(&clockfw_lock, flags);
87} 79}
88EXPORT_SYMBOL(clk_disable); 80EXPORT_SYMBOL(clk_disable);
89 81
90int clk_use(struct clk *clk)
91{
92 unsigned long flags;
93 int ret = 0;
94
95 spin_lock_irqsave(&clockfw_lock, flags);
96 if (arch_clock->clk_use)
97 ret = arch_clock->clk_use(clk);
98 spin_unlock_irqrestore(&clockfw_lock, flags);
99
100 return ret;
101}
102EXPORT_SYMBOL(clk_use);
103
104void clk_unuse(struct clk *clk)
105{
106 unsigned long flags;
107
108 spin_lock_irqsave(&clockfw_lock, flags);
109 if (arch_clock->clk_unuse)
110 arch_clock->clk_unuse(clk);
111 spin_unlock_irqrestore(&clockfw_lock, flags);
112}
113EXPORT_SYMBOL(clk_unuse);
114
115int clk_get_usecount(struct clk *clk) 82int clk_get_usecount(struct clk *clk)
116{ 83{
117 unsigned long flags; 84 unsigned long flags;
@@ -146,7 +113,7 @@ void clk_put(struct clk *clk)
146EXPORT_SYMBOL(clk_put); 113EXPORT_SYMBOL(clk_put);
147 114
148/*------------------------------------------------------------------------- 115/*-------------------------------------------------------------------------
149 * Optional clock functions defined in asm/hardware/clock.h 116 * Optional clock functions defined in include/linux/clk.h
150 *-------------------------------------------------------------------------*/ 117 *-------------------------------------------------------------------------*/
151 118
152long clk_round_rate(struct clk *clk, unsigned long rate) 119long clk_round_rate(struct clk *clk, unsigned long rate)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index ca3681a824ac..b4d5b9e4bfce 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -853,19 +853,19 @@ static int __init _omap_gpio_init(void)
853 if (IS_ERR(gpio_ick)) 853 if (IS_ERR(gpio_ick))
854 printk("Could not get arm_gpio_ck\n"); 854 printk("Could not get arm_gpio_ck\n");
855 else 855 else
856 clk_use(gpio_ick); 856 clk_enable(gpio_ick);
857 } 857 }
858 if (cpu_is_omap24xx()) { 858 if (cpu_is_omap24xx()) {
859 gpio_ick = clk_get(NULL, "gpios_ick"); 859 gpio_ick = clk_get(NULL, "gpios_ick");
860 if (IS_ERR(gpio_ick)) 860 if (IS_ERR(gpio_ick))
861 printk("Could not get gpios_ick\n"); 861 printk("Could not get gpios_ick\n");
862 else 862 else
863 clk_use(gpio_ick); 863 clk_enable(gpio_ick);
864 gpio_fck = clk_get(NULL, "gpios_fck"); 864 gpio_fck = clk_get(NULL, "gpios_fck");
865 if (IS_ERR(gpio_ick)) 865 if (IS_ERR(gpio_ick))
866 printk("Could not get gpios_fck\n"); 866 printk("Could not get gpios_fck\n");
867 else 867 else
868 clk_use(gpio_fck); 868 clk_enable(gpio_fck);
869 } 869 }
870 870
871#ifdef CONFIG_ARCH_OMAP15XX 871#ifdef CONFIG_ARCH_OMAP15XX
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index be0e0f32a598..1cd2cace7e1b 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -190,11 +190,11 @@ static int omap_mcbsp_check(unsigned int id)
190static void omap_mcbsp_dsp_request(void) 190static void omap_mcbsp_dsp_request(void)
191{ 191{
192 if (cpu_is_omap1510() || cpu_is_omap16xx()) { 192 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
193 clk_use(mcbsp_dsp_ck); 193 clk_enable(mcbsp_dsp_ck);
194 clk_use(mcbsp_api_ck); 194 clk_enable(mcbsp_api_ck);
195 195
196 /* enable 12MHz clock to mcbsp 1 & 3 */ 196 /* enable 12MHz clock to mcbsp 1 & 3 */
197 clk_use(mcbsp_dspxor_ck); 197 clk_enable(mcbsp_dspxor_ck);
198 198
199 /* 199 /*
200 * DSP external peripheral reset 200 * DSP external peripheral reset
@@ -208,9 +208,9 @@ static void omap_mcbsp_dsp_request(void)
208static void omap_mcbsp_dsp_free(void) 208static void omap_mcbsp_dsp_free(void)
209{ 209{
210 if (cpu_is_omap1510() || cpu_is_omap16xx()) { 210 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
211 clk_unuse(mcbsp_dspxor_ck); 211 clk_disable(mcbsp_dspxor_ck);
212 clk_unuse(mcbsp_dsp_ck); 212 clk_disable(mcbsp_dsp_ck);
213 clk_unuse(mcbsp_api_ck); 213 clk_disable(mcbsp_api_ck);
214 } 214 }
215} 215}
216 216
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index e40fcc8b43d4..5cc6775c789c 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -88,7 +88,7 @@ static int __init omap_ocpi_init(void)
88 if (IS_ERR(ocpi_ck)) 88 if (IS_ERR(ocpi_ck))
89 return PTR_ERR(ocpi_ck); 89 return PTR_ERR(ocpi_ck);
90 90
91 clk_use(ocpi_ck); 91 clk_enable(ocpi_ck);
92 ocpi_enable(); 92 ocpi_enable();
93 printk("OMAP OCPI interconnect driver loaded\n"); 93 printk("OMAP OCPI interconnect driver loaded\n");
94 94
@@ -102,7 +102,7 @@ static void __exit omap_ocpi_exit(void)
102 if (!cpu_is_omap16xx()) 102 if (!cpu_is_omap16xx())
103 return; 103 return;
104 104
105 clk_unuse(ocpi_ck); 105 clk_disable(ocpi_ck);
106 clk_put(ocpi_ck); 106 clk_put(ocpi_ck);
107} 107}
108 108
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 5b7146f54fd5..679c1d5cc958 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,74 +35,22 @@ struct fdpic_func_descriptor {
35 unsigned long GOT; 35 unsigned long GOT;
36}; 36};
37 37
38static int do_signal(sigset_t *oldset);
39
40/* 38/*
41 * Atomically swap in the new signal mask, and wait for a signal. 39 * Atomically swap in the new signal mask, and wait for a signal.
42 */ 40 */
43asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 41asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
44{ 42{
45 sigset_t saveset;
46
47 mask &= _BLOCKABLE; 43 mask &= _BLOCKABLE;
48 spin_lock_irq(&current->sighand->siglock); 44 spin_lock_irq(&current->sighand->siglock);
49 saveset = current->blocked; 45 current->saved_sigmask = current->blocked;
50 siginitset(&current->blocked, mask); 46 siginitset(&current->blocked, mask);
51 recalc_sigpending(); 47 recalc_sigpending();
52 spin_unlock_irq(&current->sighand->siglock); 48 spin_unlock_irq(&current->sighand->siglock);
53 49
54 __frame->gr8 = -EINTR; 50 current->state = TASK_INTERRUPTIBLE;
55 while (1) { 51 schedule();
56 current->state = TASK_INTERRUPTIBLE; 52 set_thread_flag(TIF_RESTORE_SIGMASK);
57 schedule(); 53 return -ERESTARTNOHAND;
58 if (do_signal(&saveset))
59 /* return the signal number as the return value of this function
60 * - this is an utterly evil hack. syscalls should not invoke do_signal()
61 * as entry.S sets regs->gr8 to the return value of the system call
62 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
63 * and call waitpid() if SIGCHLD needed discarding
64 * - this only works on the i386 because it passes arguments to the signal
65 * handler on the stack, and the return value in EAX is effectively
66 * discarded
67 */
68 return __frame->gr8;
69 }
70}
71
72asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
73{
74 sigset_t saveset, newset;
75
76 /* XXX: Don't preclude handling different sized sigset_t's. */
77 if (sigsetsize != sizeof(sigset_t))
78 return -EINVAL;
79
80 if (copy_from_user(&newset, unewset, sizeof(newset)))
81 return -EFAULT;
82 sigdelsetmask(&newset, ~_BLOCKABLE);
83
84 spin_lock_irq(&current->sighand->siglock);
85 saveset = current->blocked;
86 current->blocked = newset;
87 recalc_sigpending();
88 spin_unlock_irq(&current->sighand->siglock);
89
90 __frame->gr8 = -EINTR;
91 while (1) {
92 current->state = TASK_INTERRUPTIBLE;
93 schedule();
94 if (do_signal(&saveset))
95 /* return the signal number as the return value of this function
96 * - this is an utterly evil hack. syscalls should not invoke do_signal()
97 * as entry.S sets regs->gr8 to the return value of the system call
98 * - we can't just use sigpending() as we'd have to discard SIG_IGN signals
99 * and call waitpid() if SIGCHLD needed discarding
100 * - this only works on the i386 because it passes arguments to the signal
101 * handler on the stack, and the return value in EAX is effectively
102 * discarded
103 */
104 return __frame->gr8;
105 }
106} 54}
107 55
108asmlinkage int sys_sigaction(int sig, 56asmlinkage int sys_sigaction(int sig,
@@ -372,11 +320,11 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
372 frame->pretcode); 320 frame->pretcode);
373#endif 321#endif
374 322
375 return 1; 323 return 0;
376 324
377give_sigsegv: 325give_sigsegv:
378 force_sig(SIGSEGV, current); 326 force_sig(SIGSEGV, current);
379 return 0; 327 return -EFAULT;
380 328
381} /* end setup_frame() */ 329} /* end setup_frame() */
382 330
@@ -471,11 +419,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
471 frame->pretcode); 419 frame->pretcode);
472#endif 420#endif
473 421
474 return 1; 422 return 0;
475 423
476give_sigsegv: 424give_sigsegv:
477 force_sig(SIGSEGV, current); 425 force_sig(SIGSEGV, current);
478 return 0; 426 return -EFAULT;
479 427
480} /* end setup_rt_frame() */ 428} /* end setup_rt_frame() */
481 429
@@ -516,7 +464,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
516 else 464 else
517 ret = setup_frame(sig, ka, oldset); 465 ret = setup_frame(sig, ka, oldset);
518 466
519 if (ret) { 467 if (ret == 0) {
520 spin_lock_irq(&current->sighand->siglock); 468 spin_lock_irq(&current->sighand->siglock);
521 sigorsets(&current->blocked, &current->blocked, 469 sigorsets(&current->blocked, &current->blocked,
522 &ka->sa.sa_mask); 470 &ka->sa.sa_mask);
@@ -536,10 +484,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
536 * want to handle. Thus you cannot kill init even with a SIGKILL even by 484 * want to handle. Thus you cannot kill init even with a SIGKILL even by
537 * mistake. 485 * mistake.
538 */ 486 */
539static int do_signal(sigset_t *oldset) 487static void do_signal(void)
540{ 488{
541 struct k_sigaction ka; 489 struct k_sigaction ka;
542 siginfo_t info; 490 siginfo_t info;
491 sigset_t *oldset;
543 int signr; 492 int signr;
544 493
545 /* 494 /*
@@ -549,43 +498,62 @@ static int do_signal(sigset_t *oldset)
549 * if so. 498 * if so.
550 */ 499 */
551 if (!user_mode(__frame)) 500 if (!user_mode(__frame))
552 return 1; 501 return;
553 502
554 if (try_to_freeze()) 503 if (try_to_freeze())
555 goto no_signal; 504 goto no_signal;
556 505
557 if (!oldset) 506 if (test_thread_flag(TIF_RESTORE_SIGMASK))
507 oldset = &current->saved_sigmask;
508 else
558 oldset = &current->blocked; 509 oldset = &current->blocked;
559 510
560 signr = get_signal_to_deliver(&info, &ka, __frame, NULL); 511 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
561 if (signr > 0) 512 if (signr > 0) {
562 return handle_signal(signr, &info, &ka, oldset); 513 if (handle_signal(signr, &info, &ka, oldset) == 0) {
514 /* a signal was successfully delivered; the saved
515 * sigmask will have been stored in the signal frame,
516 * and will be restored by sigreturn, so we can simply
517 * clear the TIF_RESTORE_SIGMASK flag */
518 if (test_thread_flag(TIF_RESTORE_SIGMASK))
519 clear_thread_flag(TIF_RESTORE_SIGMASK);
520 }
521
522 return;
523 }
563 524
564no_signal: 525no_signal:
565 /* Did we come from a system call? */ 526 /* Did we come from a system call? */
566 if (__frame->syscallno >= 0) { 527 if (__frame->syscallno >= 0) {
567 /* Restart the system call - no handlers present */ 528 /* Restart the system call - no handlers present */
568 if (__frame->gr8 == -ERESTARTNOHAND || 529 switch (__frame->gr8) {
569 __frame->gr8 == -ERESTARTSYS || 530 case -ERESTARTNOHAND:
570 __frame->gr8 == -ERESTARTNOINTR) { 531 case -ERESTARTSYS:
532 case -ERESTARTNOINTR:
571 __frame->gr8 = __frame->orig_gr8; 533 __frame->gr8 = __frame->orig_gr8;
572 __frame->pc -= 4; 534 __frame->pc -= 4;
573 } 535 break;
574 536
575 if (__frame->gr8 == -ERESTART_RESTARTBLOCK){ 537 case -ERESTART_RESTARTBLOCK:
576 __frame->gr8 = __NR_restart_syscall; 538 __frame->gr8 = __NR_restart_syscall;
577 __frame->pc -= 4; 539 __frame->pc -= 4;
540 break;
578 } 541 }
579 } 542 }
580 543
581 return 0; 544 /* if there's no signal to deliver, we just put the saved sigmask
545 * back */
546 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
547 clear_thread_flag(TIF_RESTORE_SIGMASK);
548 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
549 }
582 550
583} /* end do_signal() */ 551} /* end do_signal() */
584 552
585/*****************************************************************************/ 553/*****************************************************************************/
586/* 554/*
587 * notification of userspace execution resumption 555 * notification of userspace execution resumption
588 * - triggered by current->work.notify_resume 556 * - triggered by the TIF_WORK_MASK flags
589 */ 557 */
590asmlinkage void do_notify_resume(__u32 thread_info_flags) 558asmlinkage void do_notify_resume(__u32 thread_info_flags)
591{ 559{
@@ -594,7 +562,7 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
594 clear_thread_flag(TIF_SINGLESTEP); 562 clear_thread_flag(TIF_SINGLESTEP);
595 563
596 /* deal with pending signal delivery */ 564 /* deal with pending signal delivery */
597 if (thread_info_flags & _TIF_SIGPENDING) 565 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
598 do_signal(NULL); 566 do_signal();
599 567
600} /* end do_notify_resume() */ 568} /* end do_notify_resume() */
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 6a431b926019..3cbe6e9cb9fc 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -644,6 +644,8 @@ CONFIG_8139TOO_PIO=y
644# CONFIG_ACENIC is not set 644# CONFIG_ACENIC is not set
645# CONFIG_DL2K is not set 645# CONFIG_DL2K is not set
646# CONFIG_E1000 is not set 646# CONFIG_E1000 is not set
647# CONFIG_E1000_NAPI is not set
648# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
647# CONFIG_NS83820 is not set 649# CONFIG_NS83820 is not set
648# CONFIG_HAMACHI is not set 650# CONFIG_HAMACHI is not set
649# CONFIG_YELLOWFIN is not set 651# CONFIG_YELLOWFIN is not set
diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c
index aaf89cb2bc51..87ccdac84928 100644
--- a/arch/i386/kernel/quirks.c
+++ b/arch/i386/kernel/quirks.c
@@ -25,8 +25,7 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
25 25
26 /* enable access to config space*/ 26 /* enable access to config space*/
27 pci_read_config_byte(dev, 0xf4, &config); 27 pci_read_config_byte(dev, 0xf4, &config);
28 config |= 0x2; 28 pci_write_config_byte(dev, 0xf4, config|0x2);
29 pci_write_config_byte(dev, 0xf4, config);
30 29
31 /* read xTPR register */ 30 /* read xTPR register */
32 raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); 31 raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
@@ -42,9 +41,9 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
42#endif 41#endif
43 } 42 }
44 43
45 config &= ~0x2; 44 /* put back the original value for config space*/
46 /* disable access to config space*/ 45 if (!(config & 0x2))
47 pci_write_config_byte(dev, 0xf4, config); 46 pci_write_config_byte(dev, 0xf4, config);
48} 47}
49DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); 48DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance);
50DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); 49DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index adcd069db91e..963616d364ec 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -37,51 +37,17 @@
37asmlinkage int 37asmlinkage int
38sys_sigsuspend(int history0, int history1, old_sigset_t mask) 38sys_sigsuspend(int history0, int history1, old_sigset_t mask)
39{ 39{
40 struct pt_regs * regs = (struct pt_regs *) &history0;
41 sigset_t saveset;
42
43 mask &= _BLOCKABLE; 40 mask &= _BLOCKABLE;
44 spin_lock_irq(&current->sighand->siglock); 41 spin_lock_irq(&current->sighand->siglock);
45 saveset = current->blocked; 42 current->saved_sigmask = current->blocked;
46 siginitset(&current->blocked, mask); 43 siginitset(&current->blocked, mask);
47 recalc_sigpending(); 44 recalc_sigpending();
48 spin_unlock_irq(&current->sighand->siglock); 45 spin_unlock_irq(&current->sighand->siglock);
49 46
50 regs->eax = -EINTR; 47 current->state = TASK_INTERRUPTIBLE;
51 while (1) { 48 schedule();
52 current->state = TASK_INTERRUPTIBLE; 49 set_thread_flag(TIF_RESTORE_SIGMASK);
53 schedule(); 50 return -ERESTARTNOHAND;
54 if (do_signal(regs, &saveset))
55 return -EINTR;
56 }
57}
58
59asmlinkage int
60sys_rt_sigsuspend(struct pt_regs regs)
61{
62 sigset_t saveset, newset;
63
64 /* XXX: Don't preclude handling different sized sigset_t's. */
65 if (regs.ecx != sizeof(sigset_t))
66 return -EINVAL;
67
68 if (copy_from_user(&newset, (sigset_t __user *)regs.ebx, sizeof(newset)))
69 return -EFAULT;
70 sigdelsetmask(&newset, ~_BLOCKABLE);
71
72 spin_lock_irq(&current->sighand->siglock);
73 saveset = current->blocked;
74 current->blocked = newset;
75 recalc_sigpending();
76 spin_unlock_irq(&current->sighand->siglock);
77
78 regs.eax = -EINTR;
79 while (1) {
80 current->state = TASK_INTERRUPTIBLE;
81 schedule();
82 if (do_signal(&regs, &saveset))
83 return -EINTR;
84 }
85} 51}
86 52
87asmlinkage int 53asmlinkage int
@@ -433,11 +399,11 @@ static int setup_frame(int sig, struct k_sigaction *ka,
433 current->comm, current->pid, frame, regs->eip, frame->pretcode); 399 current->comm, current->pid, frame, regs->eip, frame->pretcode);
434#endif 400#endif
435 401
436 return 1; 402 return 0;
437 403
438give_sigsegv: 404give_sigsegv:
439 force_sigsegv(sig, current); 405 force_sigsegv(sig, current);
440 return 0; 406 return -EFAULT;
441} 407}
442 408
443static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 409static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -527,11 +493,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
527 current->comm, current->pid, frame, regs->eip, frame->pretcode); 493 current->comm, current->pid, frame, regs->eip, frame->pretcode);
528#endif 494#endif
529 495
530 return 1; 496 return 0;
531 497
532give_sigsegv: 498give_sigsegv:
533 force_sigsegv(sig, current); 499 force_sigsegv(sig, current);
534 return 0; 500 return -EFAULT;
535} 501}
536 502
537/* 503/*
@@ -581,7 +547,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
581 else 547 else
582 ret = setup_frame(sig, ka, oldset, regs); 548 ret = setup_frame(sig, ka, oldset, regs);
583 549
584 if (ret) { 550 if (ret == 0) {
585 spin_lock_irq(&current->sighand->siglock); 551 spin_lock_irq(&current->sighand->siglock);
586 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 552 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
587 if (!(ka->sa.sa_flags & SA_NODEFER)) 553 if (!(ka->sa.sa_flags & SA_NODEFER))
@@ -598,11 +564,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
598 * want to handle. Thus you cannot kill init even with a SIGKILL even by 564 * want to handle. Thus you cannot kill init even with a SIGKILL even by
599 * mistake. 565 * mistake.
600 */ 566 */
601int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) 567static void fastcall do_signal(struct pt_regs *regs)
602{ 568{
603 siginfo_t info; 569 siginfo_t info;
604 int signr; 570 int signr;
605 struct k_sigaction ka; 571 struct k_sigaction ka;
572 sigset_t *oldset;
606 573
607 /* 574 /*
608 * We want the common case to go fast, which 575 * We want the common case to go fast, which
@@ -613,12 +580,14 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
613 * CS suffices. 580 * CS suffices.
614 */ 581 */
615 if (!user_mode(regs)) 582 if (!user_mode(regs))
616 return 1; 583 return;
617 584
618 if (try_to_freeze()) 585 if (try_to_freeze())
619 goto no_signal; 586 goto no_signal;
620 587
621 if (!oldset) 588 if (test_thread_flag(TIF_RESTORE_SIGMASK))
589 oldset = &current->saved_sigmask;
590 else
622 oldset = &current->blocked; 591 oldset = &current->blocked;
623 592
624 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 593 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -628,38 +597,55 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
628 * have been cleared if the watchpoint triggered 597 * have been cleared if the watchpoint triggered
629 * inside the kernel. 598 * inside the kernel.
630 */ 599 */
631 if (unlikely(current->thread.debugreg[7])) { 600 if (unlikely(current->thread.debugreg[7]))
632 set_debugreg(current->thread.debugreg[7], 7); 601 set_debugreg(current->thread.debugreg[7], 7);
633 }
634 602
635 /* Whee! Actually deliver the signal. */ 603 /* Whee! Actually deliver the signal. */
636 return handle_signal(signr, &info, &ka, oldset, regs); 604 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
605 /* a signal was successfully delivered; the saved
606 * sigmask will have been stored in the signal frame,
607 * and will be restored by sigreturn, so we can simply
608 * clear the TIF_RESTORE_SIGMASK flag */
609 if (test_thread_flag(TIF_RESTORE_SIGMASK))
610 clear_thread_flag(TIF_RESTORE_SIGMASK);
611 }
612
613 return;
637 } 614 }
638 615
639 no_signal: 616no_signal:
640 /* Did we come from a system call? */ 617 /* Did we come from a system call? */
641 if (regs->orig_eax >= 0) { 618 if (regs->orig_eax >= 0) {
642 /* Restart the system call - no handlers present */ 619 /* Restart the system call - no handlers present */
643 if (regs->eax == -ERESTARTNOHAND || 620 switch (regs->eax) {
644 regs->eax == -ERESTARTSYS || 621 case -ERESTARTNOHAND:
645 regs->eax == -ERESTARTNOINTR) { 622 case -ERESTARTSYS:
623 case -ERESTARTNOINTR:
646 regs->eax = regs->orig_eax; 624 regs->eax = regs->orig_eax;
647 regs->eip -= 2; 625 regs->eip -= 2;
648 } 626 break;
649 if (regs->eax == -ERESTART_RESTARTBLOCK){ 627
628 case -ERESTART_RESTARTBLOCK:
650 regs->eax = __NR_restart_syscall; 629 regs->eax = __NR_restart_syscall;
651 regs->eip -= 2; 630 regs->eip -= 2;
631 break;
652 } 632 }
653 } 633 }
654 return 0; 634
635 /* if there's no signal to deliver, we just put the saved sigmask
636 * back */
637 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
638 clear_thread_flag(TIF_RESTORE_SIGMASK);
639 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
640 }
655} 641}
656 642
657/* 643/*
658 * notification of userspace execution resumption 644 * notification of userspace execution resumption
659 * - triggered by current->work.notify_resume 645 * - triggered by the TIF_WORK_MASK flags
660 */ 646 */
661__attribute__((regparm(3))) 647__attribute__((regparm(3)))
662void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, 648void do_notify_resume(struct pt_regs *regs, void *_unused,
663 __u32 thread_info_flags) 649 __u32 thread_info_flags)
664{ 650{
665 /* Pending single-step? */ 651 /* Pending single-step? */
@@ -667,9 +653,10 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
667 regs->eflags |= TF_MASK; 653 regs->eflags |= TF_MASK;
668 clear_thread_flag(TIF_SINGLESTEP); 654 clear_thread_flag(TIF_SINGLESTEP);
669 } 655 }
656
670 /* deal with pending signal delivery */ 657 /* deal with pending signal delivery */
671 if (thread_info_flags & _TIF_SIGPENDING) 658 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
672 do_signal(regs,oldset); 659 do_signal(regs);
673 660
674 clear_thread_flag(TIF_IRET); 661 clear_thread_flag(TIF_IRET);
675} 662}
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 6ff3e5243226..1b665928336b 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -294,3 +294,18 @@ ENTRY(sys_call_table)
294 .long sys_inotify_add_watch 294 .long sys_inotify_add_watch
295 .long sys_inotify_rm_watch 295 .long sys_inotify_rm_watch
296 .long sys_migrate_pages 296 .long sys_migrate_pages
297 .long sys_openat /* 295 */
298 .long sys_mkdirat
299 .long sys_mknodat
300 .long sys_fchownat
301 .long sys_futimesat
302 .long sys_newfstatat /* 300 */
303 .long sys_unlinkat
304 .long sys_renameat
305 .long sys_linkat
306 .long sys_symlinkat
307 .long sys_readlinkat /* 305 */
308 .long sys_fchmodat
309 .long sys_faccessat
310 .long sys_pselect6
311 .long sys_ppoll
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
index 1d07d8072ec2..991c07b57c24 100644
--- a/arch/ia64/configs/gensparse_defconfig
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -557,6 +557,7 @@ CONFIG_E100=m
557# CONFIG_DL2K is not set 557# CONFIG_DL2K is not set
558CONFIG_E1000=y 558CONFIG_E1000=y
559# CONFIG_E1000_NAPI is not set 559# CONFIG_E1000_NAPI is not set
560# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
560# CONFIG_NS83820 is not set 561# CONFIG_NS83820 is not set
561# CONFIG_HAMACHI is not set 562# CONFIG_HAMACHI is not set
562# CONFIG_YELLOWFIN is not set 563# CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index b1e8f09e9fd5..6859119bc9dd 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -565,6 +565,7 @@ CONFIG_E100=m
565# CONFIG_DL2K is not set 565# CONFIG_DL2K is not set
566CONFIG_E1000=y 566CONFIG_E1000=y
567# CONFIG_E1000_NAPI is not set 567# CONFIG_E1000_NAPI is not set
568# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
568# CONFIG_NS83820 is not set 569# CONFIG_NS83820 is not set
569# CONFIG_HAMACHI is not set 570# CONFIG_HAMACHI is not set
570# CONFIG_YELLOWFIN is not set 571# CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 0856ca67dd50..53899dc8eb53 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -548,6 +548,7 @@ CONFIG_E100=y
548# CONFIG_DL2K is not set 548# CONFIG_DL2K is not set
549CONFIG_E1000=y 549CONFIG_E1000=y
550# CONFIG_E1000_NAPI is not set 550# CONFIG_E1000_NAPI is not set
551# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
551# CONFIG_NS83820 is not set 552# CONFIG_NS83820 is not set
552# CONFIG_HAMACHI is not set 553# CONFIG_HAMACHI is not set
553# CONFIG_YELLOWFIN is not set 554# CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 275a26c6e5aa..dcbc78a4cfa4 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -565,6 +565,7 @@ CONFIG_E100=m
565# CONFIG_DL2K is not set 565# CONFIG_DL2K is not set
566CONFIG_E1000=y 566CONFIG_E1000=y
567# CONFIG_E1000_NAPI is not set 567# CONFIG_E1000_NAPI is not set
568# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
568# CONFIG_NS83820 is not set 569# CONFIG_NS83820 is not set
569# CONFIG_HAMACHI is not set 570# CONFIG_HAMACHI is not set
570# CONFIG_YELLOWFIN is not set 571# CONFIG_YELLOWFIN is not set
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 3945d378bd7e..70dba1f0e2ee 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -52,9 +52,9 @@
52#include <linux/compat.h> 52#include <linux/compat.h>
53#include <linux/vfs.h> 53#include <linux/vfs.h>
54#include <linux/mman.h> 54#include <linux/mman.h>
55#include <linux/mutex.h>
55 56
56#include <asm/intrinsics.h> 57#include <asm/intrinsics.h>
57#include <asm/semaphore.h>
58#include <asm/types.h> 58#include <asm/types.h>
59#include <asm/uaccess.h> 59#include <asm/uaccess.h>
60#include <asm/unistd.h> 60#include <asm/unistd.h>
@@ -86,7 +86,7 @@
86 * while doing so. 86 * while doing so.
87 */ 87 */
88/* XXX make per-mm: */ 88/* XXX make per-mm: */
89static DECLARE_MUTEX(ia32_mmap_sem); 89static DEFINE_MUTEX(ia32_mmap_mutex);
90 90
91asmlinkage long 91asmlinkage long
92sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, 92sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
@@ -895,11 +895,11 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot
895 prot = get_prot32(prot); 895 prot = get_prot32(prot);
896 896
897#if PAGE_SHIFT > IA32_PAGE_SHIFT 897#if PAGE_SHIFT > IA32_PAGE_SHIFT
898 down(&ia32_mmap_sem); 898 mutex_lock(&ia32_mmap_mutex);
899 { 899 {
900 addr = emulate_mmap(file, addr, len, prot, flags, offset); 900 addr = emulate_mmap(file, addr, len, prot, flags, offset);
901 } 901 }
902 up(&ia32_mmap_sem); 902 mutex_unlock(&ia32_mmap_mutex);
903#else 903#else
904 down_write(&current->mm->mmap_sem); 904 down_write(&current->mm->mmap_sem);
905 { 905 {
@@ -1000,11 +1000,9 @@ sys32_munmap (unsigned int start, unsigned int len)
1000 if (start >= end) 1000 if (start >= end)
1001 return 0; 1001 return 0;
1002 1002
1003 down(&ia32_mmap_sem); 1003 mutex_lock(&ia32_mmap_mutex);
1004 { 1004 ret = sys_munmap(start, end - start);
1005 ret = sys_munmap(start, end - start); 1005 mutex_unlock(&ia32_mmap_mutex);
1006 }
1007 up(&ia32_mmap_sem);
1008#endif 1006#endif
1009 return ret; 1007 return ret;
1010} 1008}
@@ -1056,7 +1054,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot)
1056 if (retval < 0) 1054 if (retval < 0)
1057 return retval; 1055 return retval;
1058 1056
1059 down(&ia32_mmap_sem); 1057 mutex_lock(&ia32_mmap_mutex);
1060 { 1058 {
1061 if (offset_in_page(start)) { 1059 if (offset_in_page(start)) {
1062 /* start address is 4KB aligned but not page aligned. */ 1060 /* start address is 4KB aligned but not page aligned. */
@@ -1080,7 +1078,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot)
1080 retval = sys_mprotect(start, end - start, prot); 1078 retval = sys_mprotect(start, end - start, prot);
1081 } 1079 }
1082 out: 1080 out:
1083 up(&ia32_mmap_sem); 1081 mutex_unlock(&ia32_mmap_mutex);
1084 return retval; 1082 return retval;
1085#endif 1083#endif
1086} 1084}
@@ -1124,11 +1122,9 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
1124 old_len = PAGE_ALIGN(old_end) - addr; 1122 old_len = PAGE_ALIGN(old_end) - addr;
1125 new_len = PAGE_ALIGN(new_end) - addr; 1123 new_len = PAGE_ALIGN(new_end) - addr;
1126 1124
1127 down(&ia32_mmap_sem); 1125 mutex_lock(&ia32_mmap_mutex);
1128 { 1126 ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
1129 ret = sys_mremap(addr, old_len, new_len, flags, new_addr); 1127 mutex_unlock(&ia32_mmap_mutex);
1130 }
1131 up(&ia32_mmap_sem);
1132 1128
1133 if ((ret >= 0) && (old_len < new_len)) { 1129 if ((ret >= 0) && (old_len < new_len)) {
1134 /* mremap expanded successfully */ 1130 /* mremap expanded successfully */
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 2ea4b39efffa..9c5194b385da 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -40,6 +40,7 @@
40#include <linux/bitops.h> 40#include <linux/bitops.h>
41#include <linux/capability.h> 41#include <linux/capability.h>
42#include <linux/rcupdate.h> 42#include <linux/rcupdate.h>
43#include <linux/completion.h>
43 44
44#include <asm/errno.h> 45#include <asm/errno.h>
45#include <asm/intrinsics.h> 46#include <asm/intrinsics.h>
@@ -286,7 +287,7 @@ typedef struct pfm_context {
286 287
287 unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */ 288 unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */
288 289
289 struct semaphore ctx_restart_sem; /* use for blocking notification mode */ 290 struct completion ctx_restart_done; /* use for blocking notification mode */
290 291
291 unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */ 292 unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */
292 unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */ 293 unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */
@@ -1991,7 +1992,7 @@ pfm_close(struct inode *inode, struct file *filp)
1991 /* 1992 /*
1992 * force task to wake up from MASKED state 1993 * force task to wake up from MASKED state
1993 */ 1994 */
1994 up(&ctx->ctx_restart_sem); 1995 complete(&ctx->ctx_restart_done);
1995 1996
1996 DPRINT(("waking up ctx_state=%d\n", state)); 1997 DPRINT(("waking up ctx_state=%d\n", state));
1997 1998
@@ -2706,7 +2707,7 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
2706 /* 2707 /*
2707 * init restart semaphore to locked 2708 * init restart semaphore to locked
2708 */ 2709 */
2709 sema_init(&ctx->ctx_restart_sem, 0); 2710 init_completion(&ctx->ctx_restart_done);
2710 2711
2711 /* 2712 /*
2712 * activation is used in SMP only 2713 * activation is used in SMP only
@@ -3687,7 +3688,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3687 */ 3688 */
3688 if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) { 3689 if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
3689 DPRINT(("unblocking [%d] \n", task->pid)); 3690 DPRINT(("unblocking [%d] \n", task->pid));
3690 up(&ctx->ctx_restart_sem); 3691 complete(&ctx->ctx_restart_done);
3691 } else { 3692 } else {
3692 DPRINT(("[%d] armed exit trap\n", task->pid)); 3693 DPRINT(("[%d] armed exit trap\n", task->pid));
3693 3694
@@ -5089,7 +5090,7 @@ pfm_handle_work(void)
5089 * may go through without blocking on SMP systems 5090 * may go through without blocking on SMP systems
5090 * if restart has been received already by the time we call down() 5091 * if restart has been received already by the time we call down()
5091 */ 5092 */
5092 ret = down_interruptible(&ctx->ctx_restart_sem); 5093 ret = wait_for_completion_interruptible(&ctx->ctx_restart_done);
5093 5094
5094 DPRINT(("after block sleeping ret=%d\n", ret)); 5095 DPRINT(("after block sleeping ret=%d\n", ret));
5095 5096
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index b631cf86ed44..fcd2bad0286f 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -210,6 +210,7 @@ uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
210 210
211 dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end); 211 dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
212 212
213 touch_softlockup_watchdog();
213 memset((char *)start, 0, length); 214 memset((char *)start, 0, length);
214 215
215 node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET); 216 node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET);
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
index 7c88e9a58516..8182583c762c 100644
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -51,6 +51,15 @@ struct sn_flush_device_kernel {
51 struct sn_flush_device_common *common; 51 struct sn_flush_device_common *common;
52}; 52};
53 53
54/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included
55 * for older official PROMs to function on the new kernel base. This struct
56 * will be removed when the next official PROM release occurs. */
57
58struct sn_flush_device_war {
59 struct sn_flush_device_common common;
60 u32 filler; /* older PROMs expect the default size of a spinlock_t */
61};
62
54/* 63/*
55 * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. 64 * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
56 */ 65 */
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 233d55115d33..00700f7e6837 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -165,8 +165,45 @@ sn_pcidev_info_get(struct pci_dev *dev)
165 return NULL; 165 return NULL;
166} 166}
167 167
168/* Older PROM flush WAR
169 *
170 * 01/16/06 -- This war will be in place until a new official PROM is released.
171 * Additionally note that the struct sn_flush_device_war also has to be
172 * removed from arch/ia64/sn/include/xtalk/hubdev.h
173 */
174static u8 war_implemented = 0;
175
176static void sn_device_fixup_war(u64 nasid, u64 widget, int device,
177 struct sn_flush_device_common *common)
178{
179 struct sn_flush_device_war *war_list;
180 struct sn_flush_device_war *dev_entry;
181 struct ia64_sal_retval isrv = {0,0,0,0};
182
183 if (!war_implemented) {
184 printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
185 "PROM flush WAR\n");
186 war_implemented = 1;
187 }
188
189 war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
190 if (!war_list)
191 BUG();
192
193 SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
194 nasid, widget, __pa(war_list), 0, 0, 0 ,0);
195 if (isrv.status)
196 panic("sn_device_fixup_war failed: %s\n",
197 ia64_sal_strerror(isrv.status));
198
199 dev_entry = war_list + device;
200 memcpy(common,dev_entry, sizeof(*common));
201
202 kfree(war_list);
203}
204
168/* 205/*
169 * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for 206 * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
170 * each node in the system. 207 * each node in the system.
171 */ 208 */
172static void sn_fixup_ionodes(void) 209static void sn_fixup_ionodes(void)
@@ -246,8 +283,19 @@ static void sn_fixup_ionodes(void)
246 widget, 283 widget,
247 device, 284 device,
248 (u64)(dev_entry->common)); 285 (u64)(dev_entry->common));
249 if (status) 286 if (status) {
250 BUG(); 287 if (sn_sal_rev() < 0x0450) {
288 /* shortlived WAR for older
289 * PROM images
290 */
291 sn_device_fixup_war(nasid,
292 widget,
293 device,
294 dev_entry->common);
295 }
296 else
297 BUG();
298 }
251 299
252 spin_lock_init(&dev_entry->sfdl_flush_lock); 300 spin_lock_init(&dev_entry->sfdl_flush_lock);
253 } 301 }
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 6546db6abdba..9ab684d1bb55 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/timer.h> 11#include <linux/timer.h>
12#include <linux/vmalloc.h> 12#include <linux/vmalloc.h>
13#include <linux/mutex.h>
13#include <asm/mca.h> 14#include <asm/mca.h>
14#include <asm/sal.h> 15#include <asm/sal.h>
15#include <asm/sn/sn_sal.h> 16#include <asm/sn/sn_sal.h>
@@ -27,7 +28,7 @@ void sn_init_cpei_timer(void);
27/* Printing oemdata from mca uses data that is not passed through SAL, it is 28/* Printing oemdata from mca uses data that is not passed through SAL, it is
28 * global. Only one user at a time. 29 * global. Only one user at a time.
29 */ 30 */
30static DECLARE_MUTEX(sn_oemdata_mutex); 31static DEFINE_MUTEX(sn_oemdata_mutex);
31static u8 **sn_oemdata; 32static u8 **sn_oemdata;
32static u64 *sn_oemdata_size, sn_oemdata_bufsize; 33static u64 *sn_oemdata_size, sn_oemdata_bufsize;
33 34
@@ -89,7 +90,7 @@ static int
89sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, 90sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
90 u64 * oemdata_size) 91 u64 * oemdata_size)
91{ 92{
92 down(&sn_oemdata_mutex); 93 mutex_lock(&sn_oemdata_mutex);
93 sn_oemdata = oemdata; 94 sn_oemdata = oemdata;
94 sn_oemdata_size = oemdata_size; 95 sn_oemdata_size = oemdata_size;
95 sn_oemdata_bufsize = 0; 96 sn_oemdata_bufsize = 0;
@@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
107 *sn_oemdata_size = 0; 108 *sn_oemdata_size = 0;
108 ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); 109 ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
109 } 110 }
110 up(&sn_oemdata_mutex); 111 mutex_unlock(&sn_oemdata_mutex);
111 return 0; 112 return 0;
112} 113}
113 114
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c
index 3be52a34c80f..b7ea46645e12 100644
--- a/arch/ia64/sn/kernel/xp_main.c
+++ b/arch/ia64/sn/kernel/xp_main.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/mutex.h>
22#include <asm/sn/intr.h> 23#include <asm/sn/intr.h>
23#include <asm/sn/sn_sal.h> 24#include <asm/sn/sn_sal.h>
24#include <asm/sn/xp.h> 25#include <asm/sn/xp.h>
@@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
136 137
137 registration = &xpc_registrations[ch_number]; 138 registration = &xpc_registrations[ch_number];
138 139
139 if (down_interruptible(&registration->sema) != 0) { 140 if (mutex_lock_interruptible(&registration->mutex) != 0) {
140 return xpcInterrupted; 141 return xpcInterrupted;
141 } 142 }
142 143
143 /* if XPC_CHANNEL_REGISTERED(ch_number) */ 144 /* if XPC_CHANNEL_REGISTERED(ch_number) */
144 if (registration->func != NULL) { 145 if (registration->func != NULL) {
145 up(&registration->sema); 146 mutex_unlock(&registration->mutex);
146 return xpcAlreadyRegistered; 147 return xpcAlreadyRegistered;
147 } 148 }
148 149
@@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
154 registration->key = key; 155 registration->key = key;
155 registration->func = func; 156 registration->func = func;
156 157
157 up(&registration->sema); 158 mutex_unlock(&registration->mutex);
158 159
159 xpc_interface.connect(ch_number); 160 xpc_interface.connect(ch_number);
160 161
@@ -190,11 +191,11 @@ xpc_disconnect(int ch_number)
190 * figured XPC's users will just turn around and call xpc_disconnect() 191 * figured XPC's users will just turn around and call xpc_disconnect()
191 * again anyways, so we might as well wait, if need be. 192 * again anyways, so we might as well wait, if need be.
192 */ 193 */
193 down(&registration->sema); 194 mutex_lock(&registration->mutex);
194 195
195 /* if !XPC_CHANNEL_REGISTERED(ch_number) */ 196 /* if !XPC_CHANNEL_REGISTERED(ch_number) */
196 if (registration->func == NULL) { 197 if (registration->func == NULL) {
197 up(&registration->sema); 198 mutex_unlock(&registration->mutex);
198 return; 199 return;
199 } 200 }
200 201
@@ -208,7 +209,7 @@ xpc_disconnect(int ch_number)
208 209
209 xpc_interface.disconnect(ch_number); 210 xpc_interface.disconnect(ch_number);
210 211
211 up(&registration->sema); 212 mutex_unlock(&registration->mutex);
212 213
213 return; 214 return;
214} 215}
@@ -250,9 +251,9 @@ xp_init(void)
250 xp_nofault_PIOR_target = SH1_IPI_ACCESS; 251 xp_nofault_PIOR_target = SH1_IPI_ACCESS;
251 } 252 }
252 253
253 /* initialize the connection registration semaphores */ 254 /* initialize the connection registration mutex */
254 for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) { 255 for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
255 sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */ 256 mutex_init(&xpc_registrations[ch_number].mutex);
256 } 257 }
257 258
258 return 0; 259 return 0;
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 0c0a68902409..8d950c778bb6 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -22,6 +22,8 @@
22#include <linux/cache.h> 22#include <linux/cache.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/mutex.h>
26#include <linux/completion.h>
25#include <asm/sn/bte.h> 27#include <asm/sn/bte.h>
26#include <asm/sn/sn_sal.h> 28#include <asm/sn/sn_sal.h>
27#include <asm/sn/xpc.h> 29#include <asm/sn/xpc.h>
@@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
56 atomic_set(&ch->n_to_notify, 0); 58 atomic_set(&ch->n_to_notify, 0);
57 59
58 spin_lock_init(&ch->lock); 60 spin_lock_init(&ch->lock);
59 sema_init(&ch->msg_to_pull_sema, 1); /* mutex */ 61 mutex_init(&ch->msg_to_pull_mutex);
60 sema_init(&ch->wdisconnect_sema, 0); /* event wait */ 62 init_completion(&ch->wdisconnect_wait);
61 63
62 atomic_set(&ch->n_on_msg_allocate_wq, 0); 64 atomic_set(&ch->n_on_msg_allocate_wq, 0);
63 init_waitqueue_head(&ch->msg_allocate_wq); 65 init_waitqueue_head(&ch->msg_allocate_wq);
@@ -534,7 +536,6 @@ static enum xpc_retval
534xpc_allocate_msgqueues(struct xpc_channel *ch) 536xpc_allocate_msgqueues(struct xpc_channel *ch)
535{ 537{
536 unsigned long irq_flags; 538 unsigned long irq_flags;
537 int i;
538 enum xpc_retval ret; 539 enum xpc_retval ret;
539 540
540 541
@@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
552 return ret; 553 return ret;
553 } 554 }
554 555
555 for (i = 0; i < ch->local_nentries; i++) {
556 /* use a semaphore as an event wait queue */
557 sema_init(&ch->notify_queue[i].sema, 0);
558 }
559
560 spin_lock_irqsave(&ch->lock, irq_flags); 556 spin_lock_irqsave(&ch->lock, irq_flags);
561 ch->flags |= XPC_C_SETUP; 557 ch->flags |= XPC_C_SETUP;
562 spin_unlock_irqrestore(&ch->lock, irq_flags); 558 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
799 } 795 }
800 796
801 if (ch->flags & XPC_C_WDISCONNECT) { 797 if (ch->flags & XPC_C_WDISCONNECT) {
802 spin_unlock_irqrestore(&ch->lock, *irq_flags); 798 /* we won't lose the CPU since we're holding ch->lock */
803 up(&ch->wdisconnect_sema); 799 complete(&ch->wdisconnect_wait);
804 spin_lock_irqsave(&ch->lock, *irq_flags);
805
806 } else if (ch->delayed_IPI_flags) { 800 } else if (ch->delayed_IPI_flags) {
807 if (part->act_state != XPC_P_DEACTIVATING) { 801 if (part->act_state != XPC_P_DEACTIVATING) {
808 /* time to take action on any delayed IPI flags */ 802 /* time to take action on any delayed IPI flags */
@@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch)
1092 struct xpc_registration *registration = &xpc_registrations[ch->number]; 1086 struct xpc_registration *registration = &xpc_registrations[ch->number];
1093 1087
1094 1088
1095 if (down_trylock(&registration->sema) != 0) { 1089 if (mutex_trylock(&registration->mutex) == 0) {
1096 return xpcRetry; 1090 return xpcRetry;
1097 } 1091 }
1098 1092
1099 if (!XPC_CHANNEL_REGISTERED(ch->number)) { 1093 if (!XPC_CHANNEL_REGISTERED(ch->number)) {
1100 up(&registration->sema); 1094 mutex_unlock(&registration->mutex);
1101 return xpcUnregistered; 1095 return xpcUnregistered;
1102 } 1096 }
1103 1097
@@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1108 1102
1109 if (ch->flags & XPC_C_DISCONNECTING) { 1103 if (ch->flags & XPC_C_DISCONNECTING) {
1110 spin_unlock_irqrestore(&ch->lock, irq_flags); 1104 spin_unlock_irqrestore(&ch->lock, irq_flags);
1111 up(&registration->sema); 1105 mutex_unlock(&registration->mutex);
1112 return ch->reason; 1106 return ch->reason;
1113 } 1107 }
1114 1108
@@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1140 * channel lock be locked and will unlock and relock 1134 * channel lock be locked and will unlock and relock
1141 * the channel lock as needed. 1135 * the channel lock as needed.
1142 */ 1136 */
1143 up(&registration->sema); 1137 mutex_unlock(&registration->mutex);
1144 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, 1138 XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
1145 &irq_flags); 1139 &irq_flags);
1146 spin_unlock_irqrestore(&ch->lock, irq_flags); 1140 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch)
1155 atomic_inc(&xpc_partitions[ch->partid].nchannels_active); 1149 atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
1156 } 1150 }
1157 1151
1158 up(&registration->sema); 1152 mutex_unlock(&registration->mutex);
1159 1153
1160 1154
1161 /* initiate the connection */ 1155 /* initiate the connection */
@@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2089 enum xpc_retval ret; 2083 enum xpc_retval ret;
2090 2084
2091 2085
2092 if (down_interruptible(&ch->msg_to_pull_sema) != 0) { 2086 if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
2093 /* we were interrupted by a signal */ 2087 /* we were interrupted by a signal */
2094 return NULL; 2088 return NULL;
2095 } 2089 }
@@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2125 2119
2126 XPC_DEACTIVATE_PARTITION(part, ret); 2120 XPC_DEACTIVATE_PARTITION(part, ret);
2127 2121
2128 up(&ch->msg_to_pull_sema); 2122 mutex_unlock(&ch->msg_to_pull_mutex);
2129 return NULL; 2123 return NULL;
2130 } 2124 }
2131 2125
@@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
2134 ch->next_msg_to_pull += nmsgs; 2128 ch->next_msg_to_pull += nmsgs;
2135 } 2129 }
2136 2130
2137 up(&ch->msg_to_pull_sema); 2131 mutex_unlock(&ch->msg_to_pull_mutex);
2138 2132
2139 /* return the message we were looking for */ 2133 /* return the message we were looking for */
2140 msg_offset = (get % ch->remote_nentries) * ch->msg_size; 2134 msg_offset = (get % ch->remote_nentries) * ch->msg_size;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 8930586e0eb4..c75f8aeefc2b 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -55,6 +55,7 @@
55#include <linux/slab.h> 55#include <linux/slab.h>
56#include <linux/delay.h> 56#include <linux/delay.h>
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <linux/completion.h>
58#include <asm/sn/intr.h> 59#include <asm/sn/intr.h>
59#include <asm/sn/sn_sal.h> 60#include <asm/sn/sn_sal.h>
60#include <asm/kdebug.h> 61#include <asm/kdebug.h>
@@ -177,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
177static unsigned long xpc_hb_check_timeout; 178static unsigned long xpc_hb_check_timeout;
178 179
179/* notification that the xpc_hb_checker thread has exited */ 180/* notification that the xpc_hb_checker thread has exited */
180static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); 181static DECLARE_COMPLETION(xpc_hb_checker_exited);
181 182
182/* notification that the xpc_discovery thread has exited */ 183/* notification that the xpc_discovery thread has exited */
183static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); 184static DECLARE_COMPLETION(xpc_discovery_exited);
184 185
185 186
186static struct timer_list xpc_hb_timer; 187static struct timer_list xpc_hb_timer;
@@ -321,7 +322,7 @@ xpc_hb_checker(void *ignore)
321 322
322 323
323 /* mark this thread as having exited */ 324 /* mark this thread as having exited */
324 up(&xpc_hb_checker_exited); 325 complete(&xpc_hb_checker_exited);
325 return 0; 326 return 0;
326} 327}
327 328
@@ -341,7 +342,7 @@ xpc_initiate_discovery(void *ignore)
341 dev_dbg(xpc_part, "discovery thread is exiting\n"); 342 dev_dbg(xpc_part, "discovery thread is exiting\n");
342 343
343 /* mark this thread as having exited */ 344 /* mark this thread as having exited */
344 up(&xpc_discovery_exited); 345 complete(&xpc_discovery_exited);
345 return 0; 346 return 0;
346} 347}
347 348
@@ -893,7 +894,7 @@ xpc_disconnect_wait(int ch_number)
893 continue; 894 continue;
894 } 895 }
895 896
896 (void) down(&ch->wdisconnect_sema); 897 wait_for_completion(&ch->wdisconnect_wait);
897 898
898 spin_lock_irqsave(&ch->lock, irq_flags); 899 spin_lock_irqsave(&ch->lock, irq_flags);
899 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED)); 900 DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
@@ -946,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason)
946 free_irq(SGI_XPC_ACTIVATE, NULL); 947 free_irq(SGI_XPC_ACTIVATE, NULL);
947 948
948 /* wait for the discovery thread to exit */ 949 /* wait for the discovery thread to exit */
949 down(&xpc_discovery_exited); 950 wait_for_completion(&xpc_discovery_exited);
950 951
951 /* wait for the heartbeat checker thread to exit */ 952 /* wait for the heartbeat checker thread to exit */
952 down(&xpc_hb_checker_exited); 953 wait_for_completion(&xpc_hb_checker_exited);
953 954
954 955
955 /* sleep for a 1/3 of a second or so */ 956 /* sleep for a 1/3 of a second or so */
@@ -1367,7 +1368,7 @@ xpc_init(void)
1367 dev_err(xpc_part, "failed while forking discovery thread\n"); 1368 dev_err(xpc_part, "failed while forking discovery thread\n");
1368 1369
1369 /* mark this new thread as a non-starter */ 1370 /* mark this new thread as a non-starter */
1370 up(&xpc_discovery_exited); 1371 complete(&xpc_discovery_exited);
1371 1372
1372 xpc_do_exit(xpcUnloading); 1373 xpc_do_exit(xpcUnloading);
1373 return -EBUSY; 1374 return -EBUSY;
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 77a1262751d3..2fac27049bf6 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -24,13 +24,15 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp)
24{ 24{
25 struct ia64_sal_retval ret_stuff; 25 struct ia64_sal_retval ret_stuff;
26 u64 busnum; 26 u64 busnum;
27 u64 segment;
27 28
28 ret_stuff.status = 0; 29 ret_stuff.status = 0;
29 ret_stuff.v0 = 0; 30 ret_stuff.v0 = 0;
30 31
32 segment = soft->pbi_buscommon.bs_persist_segment;
31 busnum = soft->pbi_buscommon.bs_persist_busnum; 33 busnum = soft->pbi_buscommon.bs_persist_busnum;
32 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum, 34 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment,
33 (u64) device, (u64) resp, 0, 0, 0, 0); 35 busnum, (u64) device, (u64) resp, 0, 0, 0);
34 36
35 return (int)ret_stuff.v0; 37 return (int)ret_stuff.v0;
36} 38}
@@ -41,14 +43,16 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
41{ 43{
42 struct ia64_sal_retval ret_stuff; 44 struct ia64_sal_retval ret_stuff;
43 u64 busnum; 45 u64 busnum;
46 u64 segment;
44 47
45 ret_stuff.status = 0; 48 ret_stuff.status = 0;
46 ret_stuff.v0 = 0; 49 ret_stuff.v0 = 0;
47 50
51 segment = soft->pbi_buscommon.bs_persist_segment;
48 busnum = soft->pbi_buscommon.bs_persist_busnum; 52 busnum = soft->pbi_buscommon.bs_persist_busnum;
49 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE, 53 SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
50 (u64) busnum, (u64) device, (u64) action, 54 segment, busnum, (u64) device, (u64) action,
51 (u64) resp, 0, 0, 0); 55 (u64) resp, 0, 0);
52 56
53 return (int)ret_stuff.v0; 57 return (int)ret_stuff.v0;
54} 58}
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index 955ef5084f3e..959ad3c4e372 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -602,6 +602,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
602# CONFIG_DL2K is not set 602# CONFIG_DL2K is not set
603CONFIG_E1000=m 603CONFIG_E1000=m
604CONFIG_E1000_NAPI=y 604CONFIG_E1000_NAPI=y
605# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
605# CONFIG_NS83820 is not set 606# CONFIG_NS83820 is not set
606# CONFIG_HAMACHI is not set 607# CONFIG_HAMACHI is not set
607# CONFIG_YELLOWFIN is not set 608# CONFIG_YELLOWFIN is not set
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index 9d86b6b1ebd1..0b1c8c1fa8a3 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -626,6 +626,7 @@ CONFIG_ACENIC=m
626# CONFIG_DL2K is not set 626# CONFIG_DL2K is not set
627CONFIG_E1000=m 627CONFIG_E1000=m
628# CONFIG_E1000_NAPI is not set 628# CONFIG_E1000_NAPI is not set
629# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
629# CONFIG_NS83820 is not set 630# CONFIG_NS83820 is not set
630# CONFIG_HAMACHI is not set 631# CONFIG_HAMACHI is not set
631# CONFIG_YELLOWFIN is not set 632# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index b657f7e44762..063b84f2cbea 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -533,6 +533,7 @@ CONFIG_MII=y
533# CONFIG_DL2K is not set 533# CONFIG_DL2K is not set
534CONFIG_E1000=m 534CONFIG_E1000=m
535# CONFIG_E1000_NAPI is not set 535# CONFIG_E1000_NAPI is not set
536# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
536# CONFIG_NS83820 is not set 537# CONFIG_NS83820 is not set
537# CONFIG_HAMACHI is not set 538# CONFIG_HAMACHI is not set
538# CONFIG_YELLOWFIN is not set 539# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index 3c22ccb18519..d6fed3f56580 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -675,6 +675,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
675# CONFIG_DL2K is not set 675# CONFIG_DL2K is not set
676CONFIG_E1000=y 676CONFIG_E1000=y
677# CONFIG_E1000_NAPI is not set 677# CONFIG_E1000_NAPI is not set
678# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
678# CONFIG_NS83820 is not set 679# CONFIG_NS83820 is not set
679# CONFIG_HAMACHI is not set 680# CONFIG_HAMACHI is not set
680# CONFIG_YELLOWFIN is not set 681# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index 751a622fb7a7..c775027947f9 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -567,6 +567,7 @@ CONFIG_ACENIC=m
567# CONFIG_DL2K is not set 567# CONFIG_DL2K is not set
568CONFIG_E1000=m 568CONFIG_E1000=m
569# CONFIG_E1000_NAPI is not set 569# CONFIG_E1000_NAPI is not set
570# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
570# CONFIG_NS83820 is not set 571# CONFIG_NS83820 is not set
571# CONFIG_HAMACHI is not set 572# CONFIG_HAMACHI is not set
572# CONFIG_YELLOWFIN is not set 573# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 07b6d3d23360..68194c03f6d1 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -454,6 +454,7 @@ CONFIG_AMD8111_ETH=y
454# CONFIG_DL2K is not set 454# CONFIG_DL2K is not set
455CONFIG_E1000=y 455CONFIG_E1000=y
456# CONFIG_E1000_NAPI is not set 456# CONFIG_E1000_NAPI is not set
457# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
457# CONFIG_NS83820 is not set 458# CONFIG_NS83820 is not set
458# CONFIG_HAMACHI is not set 459# CONFIG_HAMACHI is not set
459# CONFIG_YELLOWFIN is not set 460# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 0b2b55a79c3c..6f6c6bed1aa5 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -724,6 +724,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
724# CONFIG_DL2K is not set 724# CONFIG_DL2K is not set
725CONFIG_E1000=y 725CONFIG_E1000=y
726# CONFIG_E1000_NAPI is not set 726# CONFIG_E1000_NAPI is not set
727# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
727# CONFIG_NS83820 is not set 728# CONFIG_NS83820 is not set
728# CONFIG_HAMACHI is not set 729# CONFIG_HAMACHI is not set
729# CONFIG_YELLOWFIN is not set 730# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index a50ce0fa9243..aa9893a1f6e8 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -671,6 +671,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
671# CONFIG_DL2K is not set 671# CONFIG_DL2K is not set
672CONFIG_E1000=y 672CONFIG_E1000=y
673# CONFIG_E1000_NAPI is not set 673# CONFIG_E1000_NAPI is not set
674# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
674# CONFIG_NS83820 is not set 675# CONFIG_NS83820 is not set
675# CONFIG_HAMACHI is not set 676# CONFIG_HAMACHI is not set
676# CONFIG_YELLOWFIN is not set 677# CONFIG_YELLOWFIN is not set
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index d8da2a35c0a4..f20a67261ec7 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -227,7 +227,7 @@ ret_from_syscall:
227 MTMSRD(r10) 227 MTMSRD(r10)
228 lwz r9,TI_FLAGS(r12) 228 lwz r9,TI_FLAGS(r12)
229 li r8,-_LAST_ERRNO 229 li r8,-_LAST_ERRNO
230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) 230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
231 bne- syscall_exit_work 231 bne- syscall_exit_work
232 cmplw 0,r3,r8 232 cmplw 0,r3,r8
233 blt+ syscall_exit_cont 233 blt+ syscall_exit_cont
@@ -357,7 +357,7 @@ save_user_nvgprs_cont:
357 lwz r5,_MSR(r1) 357 lwz r5,_MSR(r1)
358 andi. r5,r5,MSR_PR 358 andi. r5,r5,MSR_PR
359 beq ret_from_except 359 beq ret_from_except
360 andi. r0,r9,_TIF_SIGPENDING 360 andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
361 beq ret_from_except 361 beq ret_from_except
362 b do_user_signal 362 b do_user_signal
3638: 3638:
@@ -683,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
683 /* Check current_thread_info()->flags */ 683 /* Check current_thread_info()->flags */
684 rlwinm r9,r1,0,0,(31-THREAD_SHIFT) 684 rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
685 lwz r9,TI_FLAGS(r9) 685 lwz r9,TI_FLAGS(r9)
686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) 686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK)
687 bne do_work 687 bne do_work
688 688
689restore_user: 689restore_user:
@@ -917,7 +917,7 @@ recheck:
917 lwz r9,TI_FLAGS(r9) 917 lwz r9,TI_FLAGS(r9)
918 andi. r0,r9,_TIF_NEED_RESCHED 918 andi. r0,r9,_TIF_NEED_RESCHED
919 bne- do_resched 919 bne- do_resched
920 andi. r0,r9,_TIF_SIGPENDING 920 andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
921 beq restore_user 921 beq restore_user
922do_user_signal: /* r10 contains MSR_KERNEL here */ 922do_user_signal: /* r10 contains MSR_KERNEL here */
923 ori r10,r10,MSR_EE 923 ori r10,r10,MSR_EE
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 542036318866..388f861b8ed1 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -160,7 +160,7 @@ syscall_exit:
160 mtmsrd r10,1 160 mtmsrd r10,1
161 ld r9,TI_FLAGS(r12) 161 ld r9,TI_FLAGS(r12)
162 li r11,-_LAST_ERRNO 162 li r11,-_LAST_ERRNO
163 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR) 163 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK)
164 bne- syscall_exit_work 164 bne- syscall_exit_work
165 cmpld r3,r11 165 cmpld r3,r11
166 ld r5,_CCR(r1) 166 ld r5,_CCR(r1)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 177bba78fb0b..3747ab0dac3f 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -252,8 +252,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs);
252/* 252/*
253 * Atomically swap in the new signal mask, and wait for a signal. 253 * Atomically swap in the new signal mask, and wait for a signal.
254 */ 254 */
255long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, 255long sys_sigsuspend(old_sigset_t mask)
256 struct pt_regs *regs)
257{ 256{
258 sigset_t saveset; 257 sigset_t saveset;
259 258
@@ -264,55 +263,10 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
264 recalc_sigpending(); 263 recalc_sigpending();
265 spin_unlock_irq(&current->sighand->siglock); 264 spin_unlock_irq(&current->sighand->siglock);
266 265
267 regs->result = -EINTR; 266 current->state = TASK_INTERRUPTIBLE;
268 regs->gpr[3] = EINTR; 267 schedule();
269 regs->ccr |= 0x10000000; 268 set_thread_flag(TIF_RESTORE_SIGMASK);
270 while (1) { 269 return -ERESTARTNOHAND;
271 current->state = TASK_INTERRUPTIBLE;
272 schedule();
273 if (do_signal(&saveset, regs)) {
274 set_thread_flag(TIF_RESTOREALL);
275 return 0;
276 }
277 }
278}
279
280long sys_rt_sigsuspend(
281#ifdef CONFIG_PPC64
282 compat_sigset_t __user *unewset,
283#else
284 sigset_t __user *unewset,
285#endif
286 size_t sigsetsize, int p3, int p4,
287 int p6, int p7, struct pt_regs *regs)
288{
289 sigset_t saveset, newset;
290
291 /* XXX: Don't preclude handling different sized sigset_t's. */
292 if (sigsetsize != sizeof(sigset_t))
293 return -EINVAL;
294
295 if (get_sigset_t(&newset, unewset))
296 return -EFAULT;
297 sigdelsetmask(&newset, ~_BLOCKABLE);
298
299 spin_lock_irq(&current->sighand->siglock);
300 saveset = current->blocked;
301 current->blocked = newset;
302 recalc_sigpending();
303 spin_unlock_irq(&current->sighand->siglock);
304
305 regs->result = -EINTR;
306 regs->gpr[3] = EINTR;
307 regs->ccr |= 0x10000000;
308 while (1) {
309 current->state = TASK_INTERRUPTIBLE;
310 schedule();
311 if (do_signal(&saveset, regs)) {
312 set_thread_flag(TIF_RESTOREALL);
313 return 0;
314 }
315 }
316} 270}
317 271
318#ifdef CONFIG_PPC32 272#ifdef CONFIG_PPC32
@@ -1174,7 +1128,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
1174{ 1128{
1175 siginfo_t info; 1129 siginfo_t info;
1176 struct k_sigaction ka; 1130 struct k_sigaction ka;
1177 unsigned int frame, newsp; 1131 unsigned int newsp;
1178 int signr, ret; 1132 int signr, ret;
1179 1133
1180#ifdef CONFIG_PPC32 1134#ifdef CONFIG_PPC32
@@ -1185,11 +1139,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
1185 } 1139 }
1186#endif 1140#endif
1187 1141
1188 if (!oldset) 1142 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1143 oldset = &current->saved_sigmask;
1144 else if (!oldset)
1189 oldset = &current->blocked; 1145 oldset = &current->blocked;
1190 1146
1191 newsp = frame = 0;
1192
1193 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 1147 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1194#ifdef CONFIG_PPC32 1148#ifdef CONFIG_PPC32
1195no_signal: 1149no_signal:
@@ -1219,8 +1173,14 @@ no_signal:
1219 } 1173 }
1220 } 1174 }
1221 1175
1222 if (signr == 0) 1176 if (signr == 0) {
1177 /* No signal to deliver -- put the saved sigmask back */
1178 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1179 clear_thread_flag(TIF_RESTORE_SIGMASK);
1180 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1181 }
1223 return 0; /* no signals delivered */ 1182 return 0; /* no signals delivered */
1183 }
1224 1184
1225 if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size 1185 if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size
1226 && !on_sig_stack(regs->gpr[1])) 1186 && !on_sig_stack(regs->gpr[1]))
@@ -1253,6 +1213,10 @@ no_signal:
1253 sigaddset(&current->blocked, signr); 1213 sigaddset(&current->blocked, signr);
1254 recalc_sigpending(); 1214 recalc_sigpending();
1255 spin_unlock_irq(&current->sighand->siglock); 1215 spin_unlock_irq(&current->sighand->siglock);
1216 /* A signal was successfully delivered; the saved sigmask is in
1217 its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
1218 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1219 clear_thread_flag(TIF_RESTORE_SIGMASK);
1256 } 1220 }
1257 1221
1258 return ret; 1222 return ret;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 7b9d999e2115..b3193116e686 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -67,42 +67,6 @@ struct rt_sigframe {
67 char abigap[288]; 67 char abigap[288];
68} __attribute__ ((aligned (16))); 68} __attribute__ ((aligned (16)));
69 69
70
71/*
72 * Atomically swap in the new signal mask, and wait for a signal.
73 */
74long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4,
75 int p6, int p7, struct pt_regs *regs)
76{
77 sigset_t saveset, newset;
78
79 /* XXX: Don't preclude handling different sized sigset_t's. */
80 if (sigsetsize != sizeof(sigset_t))
81 return -EINVAL;
82
83 if (copy_from_user(&newset, unewset, sizeof(newset)))
84 return -EFAULT;
85 sigdelsetmask(&newset, ~_BLOCKABLE);
86
87 spin_lock_irq(&current->sighand->siglock);
88 saveset = current->blocked;
89 current->blocked = newset;
90 recalc_sigpending();
91 spin_unlock_irq(&current->sighand->siglock);
92
93 regs->result = -EINTR;
94 regs->gpr[3] = EINTR;
95 regs->ccr |= 0x10000000;
96 while (1) {
97 current->state = TASK_INTERRUPTIBLE;
98 schedule();
99 if (do_signal(&saveset, regs)) {
100 set_thread_flag(TIF_RESTOREALL);
101 return 0;
102 }
103 }
104}
105
106long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5, 70long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5,
107 unsigned long r6, unsigned long r7, unsigned long r8, 71 unsigned long r6, unsigned long r7, unsigned long r8,
108 struct pt_regs *regs) 72 struct pt_regs *regs)
@@ -556,11 +520,15 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
556 if (test_thread_flag(TIF_32BIT)) 520 if (test_thread_flag(TIF_32BIT))
557 return do_signal32(oldset, regs); 521 return do_signal32(oldset, regs);
558 522
559 if (!oldset) 523 if (test_thread_flag(TIF_RESTORE_SIGMASK))
524 oldset = &current->saved_sigmask;
525 else if (!oldset)
560 oldset = &current->blocked; 526 oldset = &current->blocked;
561 527
562 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 528 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
563 if (signr > 0) { 529 if (signr > 0) {
530 int ret;
531
564 /* Whee! Actually deliver the signal. */ 532 /* Whee! Actually deliver the signal. */
565 if (TRAP(regs) == 0x0C00) 533 if (TRAP(regs) == 0x0C00)
566 syscall_restart(regs, &ka); 534 syscall_restart(regs, &ka);
@@ -573,7 +541,14 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
573 if (current->thread.dabr) 541 if (current->thread.dabr)
574 set_dabr(current->thread.dabr); 542 set_dabr(current->thread.dabr);
575 543
576 return handle_signal(signr, &ka, &info, oldset, regs); 544 ret = handle_signal(signr, &ka, &info, oldset, regs);
545
546 /* If a signal was successfully delivered, the saved sigmask is in
547 its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
548 if (ret && test_thread_flag(TIF_RESTORE_SIGMASK))
549 clear_thread_flag(TIF_RESTORE_SIGMASK);
550
551 return ret;
577 } 552 }
578 553
579 if (TRAP(regs) == 0x0C00) { /* System Call! */ 554 if (TRAP(regs) == 0x0C00) { /* System Call! */
@@ -589,6 +564,11 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
589 regs->result = 0; 564 regs->result = 0;
590 } 565 }
591 } 566 }
567 /* No signal to deliver -- put the saved sigmask back */
568 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
569 clear_thread_flag(TIF_RESTORE_SIGMASK);
570 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
571 }
592 572
593 return 0; 573 return 0;
594} 574}
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 68013179a503..007b15ee36d2 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -321,3 +321,5 @@ SYSCALL(inotify_add_watch)
321SYSCALL(inotify_rm_watch) 321SYSCALL(inotify_rm_watch)
322SYSCALL(spu_run) 322SYSCALL(spu_run)
323SYSCALL(spu_create) 323SYSCALL(spu_create)
324COMPAT_SYS(pselect6)
325COMPAT_SYS(ppoll)
diff --git a/arch/ppc/configs/bamboo_defconfig b/arch/ppc/configs/bamboo_defconfig
index 0ba4e70d50b6..41fd3938fa5c 100644
--- a/arch/ppc/configs/bamboo_defconfig
+++ b/arch/ppc/configs/bamboo_defconfig
@@ -499,6 +499,7 @@ CONFIG_NATSEMI=y
499# CONFIG_DL2K is not set 499# CONFIG_DL2K is not set
500CONFIG_E1000=y 500CONFIG_E1000=y
501# CONFIG_E1000_NAPI is not set 501# CONFIG_E1000_NAPI is not set
502# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
502# CONFIG_NS83820 is not set 503# CONFIG_NS83820 is not set
503# CONFIG_HAMACHI is not set 504# CONFIG_HAMACHI is not set
504# CONFIG_YELLOWFIN is not set 505# CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/configs/katana_defconfig b/arch/ppc/configs/katana_defconfig
index 0f3bb9af9c22..7311fe6b42de 100644
--- a/arch/ppc/configs/katana_defconfig
+++ b/arch/ppc/configs/katana_defconfig
@@ -488,6 +488,7 @@ CONFIG_E100=y
488# CONFIG_DL2K is not set 488# CONFIG_DL2K is not set
489CONFIG_E1000=y 489CONFIG_E1000=y
490# CONFIG_E1000_NAPI is not set 490# CONFIG_E1000_NAPI is not set
491# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
491# CONFIG_NS83820 is not set 492# CONFIG_NS83820 is not set
492# CONFIG_HAMACHI is not set 493# CONFIG_HAMACHI is not set
493# CONFIG_YELLOWFIN is not set 494# CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/configs/mpc834x_sys_defconfig b/arch/ppc/configs/mpc834x_sys_defconfig
index 673dc64ebcb1..b96a6d6dad0e 100644
--- a/arch/ppc/configs/mpc834x_sys_defconfig
+++ b/arch/ppc/configs/mpc834x_sys_defconfig
@@ -402,6 +402,7 @@ CONFIG_E100=y
402# CONFIG_DL2K is not set 402# CONFIG_DL2K is not set
403CONFIG_E1000=y 403CONFIG_E1000=y
404# CONFIG_E1000_NAPI is not set 404# CONFIG_E1000_NAPI is not set
405# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
405# CONFIG_NS83820 is not set 406# CONFIG_NS83820 is not set
406# CONFIG_HAMACHI is not set 407# CONFIG_HAMACHI is not set
407# CONFIG_YELLOWFIN is not set 408# CONFIG_YELLOWFIN is not set
diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig
index 93da595a4738..a1ef929bca59 100644
--- a/arch/ppc/configs/power3_defconfig
+++ b/arch/ppc/configs/power3_defconfig
@@ -442,6 +442,7 @@ CONFIG_E100=y
442# CONFIG_DL2K is not set 442# CONFIG_DL2K is not set
443CONFIG_E1000=y 443CONFIG_E1000=y
444# CONFIG_E1000_NAPI is not set 444# CONFIG_E1000_NAPI is not set
445# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
445# CONFIG_NS83820 is not set 446# CONFIG_NS83820 is not set
446# CONFIG_HAMACHI is not set 447# CONFIG_HAMACHI is not set
447# CONFIG_YELLOWFIN is not set 448# CONFIG_YELLOWFIN is not set
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 03ecb4e4614e..c51d08d218ef 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1277,62 +1277,6 @@ sys_sigstack:
1277 mov %l5, %o7 1277 mov %l5, %o7
1278 1278
1279 .align 4 1279 .align 4
1280 .globl sys_sigpause
1281sys_sigpause:
1282 /* Note: %o0 already has correct value... */
1283 call do_sigpause
1284 add %sp, STACKFRAME_SZ, %o1
1285
1286 ld [%curptr + TI_FLAGS], %l5
1287 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1288 be 1f
1289 nop
1290
1291 call syscall_trace
1292 nop
1293
12941:
1295 /* We are returning to a signal handler. */
1296 RESTORE_ALL
1297
1298 .align 4
1299 .globl sys_sigsuspend
1300sys_sigsuspend:
1301 call do_sigsuspend
1302 add %sp, STACKFRAME_SZ, %o0
1303
1304 ld [%curptr + TI_FLAGS], %l5
1305 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1306 be 1f
1307 nop
1308
1309 call syscall_trace
1310 nop
1311
13121:
1313 /* We are returning to a signal handler. */
1314 RESTORE_ALL
1315
1316 .align 4
1317 .globl sys_rt_sigsuspend
1318sys_rt_sigsuspend:
1319 /* Note: %o0, %o1 already have correct value... */
1320 call do_rt_sigsuspend
1321 add %sp, STACKFRAME_SZ, %o2
1322
1323 ld [%curptr + TI_FLAGS], %l5
1324 andcc %l5, _TIF_SYSCALL_TRACE, %g0
1325 be 1f
1326 nop
1327
1328 call syscall_trace
1329 nop
1330
13311:
1332 /* We are returning to a signal handler. */
1333 RESTORE_ALL
1334
1335 .align 4
1336 .globl sys_sigreturn 1280 .globl sys_sigreturn
1337sys_sigreturn: 1281sys_sigreturn:
1338 call do_sigreturn 1282 call do_sigreturn
diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
index f7460d897e79..77ca6fd81253 100644
--- a/arch/sparc/kernel/rtrap.S
+++ b/arch/sparc/kernel/rtrap.S
@@ -68,15 +68,14 @@ ret_trap_lockless_ipi:
68 68
69 ld [%curptr + TI_FLAGS], %g2 69 ld [%curptr + TI_FLAGS], %g2
70signal_p: 70signal_p:
71 andcc %g2, (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING), %g0 71 andcc %g2, (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %g0
72 bz,a ret_trap_continue 72 bz,a ret_trap_continue
73 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 73 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
74 74
75 clr %o0 75 mov %l5, %o1
76 mov %l5, %o2 76 mov %l6, %o2
77 mov %l6, %o3
78 call do_signal 77 call do_signal
79 add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr 78 add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
80 79
81 /* Fall through. */ 80 /* Fall through. */
82 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr 81 ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 5f34d7dc2b89..0748d8147bbf 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -35,9 +35,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
35 void *fpqueue, unsigned long *fpqdepth); 35 void *fpqueue, unsigned long *fpqdepth);
36extern void fpload(unsigned long *fpregs, unsigned long *fsr); 36extern void fpload(unsigned long *fpregs, unsigned long *fsr);
37 37
38asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
39 unsigned long orig_o0, int restart_syscall);
40
41/* Signal frames: the original one (compatible with SunOS): 38/* Signal frames: the original one (compatible with SunOS):
42 * 39 *
43 * Set up a signal frame... Make the stack look the way SunOS 40 * Set up a signal frame... Make the stack look the way SunOS
@@ -95,98 +92,30 @@ struct rt_signal_frame {
95#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7))) 92#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame) + 7) & (~7)))
96#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) 93#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
97 94
98/* 95static int _sigpause_common(old_sigset_t set)
99 * atomically swap in the new signal mask, and wait for a signal.
100 * This is really tricky on the Sparc, watch out...
101 */
102asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
103{ 96{
104 sigset_t saveset;
105
106 set &= _BLOCKABLE; 97 set &= _BLOCKABLE;
107 spin_lock_irq(&current->sighand->siglock); 98 spin_lock_irq(&current->sighand->siglock);
108 saveset = current->blocked; 99 current->saved_sigmask = current->blocked;
109 siginitset(&current->blocked, set); 100 siginitset(&current->blocked, set);
110 recalc_sigpending(); 101 recalc_sigpending();
111 spin_unlock_irq(&current->sighand->siglock); 102 spin_unlock_irq(&current->sighand->siglock);
112 103
113 regs->pc = regs->npc; 104 current->state = TASK_INTERRUPTIBLE;
114 regs->npc += 4; 105 schedule();
115 106 set_thread_flag(TIF_RESTORE_SIGMASK);
116 /* Condition codes and return value where set here for sigpause,
117 * and so got used by setup_frame, which again causes sigreturn()
118 * to return -EINTR.
119 */
120 while (1) {
121 current->state = TASK_INTERRUPTIBLE;
122 schedule();
123 /*
124 * Return -EINTR and set condition code here,
125 * so the interrupted system call actually returns
126 * these.
127 */
128 regs->psr |= PSR_C;
129 regs->u_regs[UREG_I0] = EINTR;
130 if (do_signal(&saveset, regs, 0, 0))
131 return;
132 }
133}
134 107
135asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) 108 return -ERESTARTNOHAND;
136{
137 _sigpause_common(set, regs);
138} 109}
139 110
140asmlinkage void do_sigsuspend (struct pt_regs *regs) 111asmlinkage int sys_sigpause(unsigned int set)
141{ 112{
142 _sigpause_common(regs->u_regs[UREG_I0], regs); 113 return _sigpause_common(set);
143} 114}
144 115
145asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, 116asmlinkage int sys_sigsuspend(old_sigset_t set)
146 struct pt_regs *regs)
147{ 117{
148 sigset_t oldset, set; 118 return _sigpause_common(set);
149
150 /* XXX: Don't preclude handling different sized sigset_t's. */
151 if (sigsetsize != sizeof(sigset_t)) {
152 regs->psr |= PSR_C;
153 regs->u_regs[UREG_I0] = EINVAL;
154 return;
155 }
156
157 if (copy_from_user(&set, uset, sizeof(set))) {
158 regs->psr |= PSR_C;
159 regs->u_regs[UREG_I0] = EFAULT;
160 return;
161 }
162
163 sigdelsetmask(&set, ~_BLOCKABLE);
164 spin_lock_irq(&current->sighand->siglock);
165 oldset = current->blocked;
166 current->blocked = set;
167 recalc_sigpending();
168 spin_unlock_irq(&current->sighand->siglock);
169
170 regs->pc = regs->npc;
171 regs->npc += 4;
172
173 /* Condition codes and return value where set here for sigpause,
174 * and so got used by setup_frame, which again causes sigreturn()
175 * to return -EINTR.
176 */
177 while (1) {
178 current->state = TASK_INTERRUPTIBLE;
179 schedule();
180 /*
181 * Return -EINTR and set condition code here,
182 * so the interrupted system call actually returns
183 * these.
184 */
185 regs->psr |= PSR_C;
186 regs->u_regs[UREG_I0] = EINTR;
187 if (do_signal(&oldset, regs, 0, 0))
188 return;
189 }
190} 119}
191 120
192static inline int 121static inline int
@@ -1067,13 +996,13 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
1067 * want to handle. Thus you cannot kill init even with a SIGKILL even by 996 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1068 * mistake. 997 * mistake.
1069 */ 998 */
1070asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, 999asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
1071 unsigned long orig_i0, int restart_syscall)
1072{ 1000{
1073 siginfo_t info; 1001 siginfo_t info;
1074 struct sparc_deliver_cookie cookie; 1002 struct sparc_deliver_cookie cookie;
1075 struct k_sigaction ka; 1003 struct k_sigaction ka;
1076 int signr; 1004 int signr;
1005 sigset_t *oldset;
1077 1006
1078 /* 1007 /*
1079 * XXX Disable svr4 signal handling until solaris emulation works. 1008 * XXX Disable svr4 signal handling until solaris emulation works.
@@ -1089,7 +1018,9 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1089 cookie.restart_syscall = restart_syscall; 1018 cookie.restart_syscall = restart_syscall;
1090 cookie.orig_i0 = orig_i0; 1019 cookie.orig_i0 = orig_i0;
1091 1020
1092 if (!oldset) 1021 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1022 oldset = &current->saved_sigmask;
1023 else
1093 oldset = &current->blocked; 1024 oldset = &current->blocked;
1094 1025
1095 signr = get_signal_to_deliver(&info, &ka, regs, &cookie); 1026 signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
@@ -1098,7 +1029,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1098 syscall_restart(cookie.orig_i0, regs, &ka.sa); 1029 syscall_restart(cookie.orig_i0, regs, &ka.sa);
1099 handle_signal(signr, &ka, &info, oldset, 1030 handle_signal(signr, &ka, &info, oldset,
1100 regs, svr4_signal); 1031 regs, svr4_signal);
1101 return 1; 1032 /* a signal was successfully delivered; the saved
1033 * sigmask will have been stored in the signal frame,
1034 * and will be restored by sigreturn, so we can simply
1035 * clear the TIF_RESTORE_SIGMASK flag.
1036 */
1037 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1038 clear_thread_flag(TIF_RESTORE_SIGMASK);
1039 return;
1102 } 1040 }
1103 if (cookie.restart_syscall && 1041 if (cookie.restart_syscall &&
1104 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 1042 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -1115,7 +1053,14 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
1115 regs->pc -= 4; 1053 regs->pc -= 4;
1116 regs->npc -= 4; 1054 regs->npc -= 4;
1117 } 1055 }
1118 return 0; 1056
1057 /* if there's no signal to deliver, we just put the saved sigmask
1058 * back
1059 */
1060 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1061 clear_thread_flag(TIF_RESTORE_SIGMASK);
1062 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1063 }
1119} 1064}
1120 1065
1121asmlinkage int 1066asmlinkage int
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 0b0d492c953b..19b25399d7e4 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -66,7 +66,6 @@ struct poll {
66 66
67extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *); 67extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *);
68extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *); 68extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *);
69void _sigpause_common (unsigned int set, struct pt_regs *);
70extern void (*__copy_1page)(void *, const void *); 69extern void (*__copy_1page)(void *, const void *);
71extern void __memmove(void *, const void *, __kernel_size_t); 70extern void __memmove(void *, const void *, __kernel_size_t);
72extern void (*bzero_1page)(void *); 71extern void (*bzero_1page)(void *);
@@ -227,7 +226,6 @@ EXPORT_SYMBOL(kunmap_atomic);
227/* Solaris/SunOS binary compatibility */ 226/* Solaris/SunOS binary compatibility */
228EXPORT_SYMBOL(svr4_setcontext); 227EXPORT_SYMBOL(svr4_setcontext);
229EXPORT_SYMBOL(svr4_getcontext); 228EXPORT_SYMBOL(svr4_getcontext);
230EXPORT_SYMBOL(_sigpause_common);
231 229
232EXPORT_SYMBOL(dump_thread); 230EXPORT_SYMBOL(dump_thread);
233 231
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index e457a40838fc..6877ae4cd1d9 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -75,7 +75,10 @@ sys_call_table:
75/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy 75/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
76/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink 76/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
77/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid 77/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
78/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl 78/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
79/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
80/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
81/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
79 82
80#ifdef CONFIG_SUNOS_EMUL 83#ifdef CONFIG_SUNOS_EMUL
81 /* Now the SunOS syscall table. */ 84 /* Now the SunOS syscall table. */
@@ -181,6 +184,11 @@ sunos_sys_table:
181 .long sunos_nosys, sunos_nosys, sunos_nosys 184 .long sunos_nosys, sunos_nosys, sunos_nosys
182 .long sunos_nosys 185 .long sunos_nosys
183/*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys 186/*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys
187 .long sunos_nosys, sunos_nosys, sunos_nosys
188 .long sunos_nosys, sunos_nosys, sunos_nosys
184 .long sunos_nosys 189 .long sunos_nosys
190/*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys
191 .long sunos_nosys, sunos_nosys, sunos_nosys
192 .long sunos_nosys, sunos_nosys, sunos_nosys
185 193
186#endif 194#endif
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index a3fb3376ffa0..9ceddad0fb49 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15 3# Linux kernel version: 2.6.16-rc1
4# Mon Jan 9 14:36:29 2006 4# Wed Jan 18 13:41:02 2006
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -233,6 +233,11 @@ CONFIG_VLAN_8021Q=m
233# CONFIG_ATALK is not set 233# CONFIG_ATALK is not set
234# CONFIG_X25 is not set 234# CONFIG_X25 is not set
235# CONFIG_LAPB is not set 235# CONFIG_LAPB is not set
236
237#
238# TIPC Configuration (EXPERIMENTAL)
239#
240# CONFIG_TIPC is not set
236# CONFIG_NET_DIVERT is not set 241# CONFIG_NET_DIVERT is not set
237# CONFIG_ECONET is not set 242# CONFIG_ECONET is not set
238# CONFIG_WAN_ROUTER is not set 243# CONFIG_WAN_ROUTER is not set
@@ -420,8 +425,7 @@ CONFIG_ISCSI_TCP=m
420# CONFIG_SCSI_QLOGIC_FC is not set 425# CONFIG_SCSI_QLOGIC_FC is not set
421# CONFIG_SCSI_QLOGIC_1280 is not set 426# CONFIG_SCSI_QLOGIC_1280 is not set
422# CONFIG_SCSI_QLOGICPTI is not set 427# CONFIG_SCSI_QLOGICPTI is not set
423CONFIG_SCSI_QLA2XXX=y 428# CONFIG_SCSI_QLA_FC is not set
424# CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set
425# CONFIG_SCSI_LPFC is not set 429# CONFIG_SCSI_LPFC is not set
426# CONFIG_SCSI_DC395x is not set 430# CONFIG_SCSI_DC395x is not set
427# CONFIG_SCSI_DC390T is not set 431# CONFIG_SCSI_DC390T is not set
@@ -529,6 +533,7 @@ CONFIG_NET_PCI=y
529# CONFIG_DL2K is not set 533# CONFIG_DL2K is not set
530CONFIG_E1000=m 534CONFIG_E1000=m
531CONFIG_E1000_NAPI=y 535CONFIG_E1000_NAPI=y
536# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
532# CONFIG_MYRI_SBUS is not set 537# CONFIG_MYRI_SBUS is not set
533# CONFIG_NS83820 is not set 538# CONFIG_NS83820 is not set
534# CONFIG_HAMACHI is not set 539# CONFIG_HAMACHI is not set
@@ -652,7 +657,6 @@ CONFIG_SERIAL_SUNSU_CONSOLE=y
652CONFIG_SERIAL_SUNSAB=m 657CONFIG_SERIAL_SUNSAB=m
653CONFIG_SERIAL_CORE=y 658CONFIG_SERIAL_CORE=y
654CONFIG_SERIAL_CORE_CONSOLE=y 659CONFIG_SERIAL_CORE_CONSOLE=y
655# CONFIG_SERIAL_JSM is not set
656CONFIG_UNIX98_PTYS=y 660CONFIG_UNIX98_PTYS=y
657# CONFIG_LEGACY_PTYS is not set 661# CONFIG_LEGACY_PTYS is not set
658 662
@@ -738,6 +742,12 @@ CONFIG_I2C_ALGOBIT=y
738# CONFIG_I2C_DEBUG_CHIP is not set 742# CONFIG_I2C_DEBUG_CHIP is not set
739 743
740# 744#
745# SPI support
746#
747# CONFIG_SPI is not set
748# CONFIG_SPI_MASTER is not set
749
750#
741# Dallas's 1-wire bus 751# Dallas's 1-wire bus
742# 752#
743# CONFIG_W1 is not set 753# CONFIG_W1 is not set
@@ -1014,6 +1024,7 @@ CONFIG_USB_UHCI_HCD=m
1014# 1024#
1015CONFIG_USB_HID=y 1025CONFIG_USB_HID=y
1016CONFIG_USB_HIDINPUT=y 1026CONFIG_USB_HIDINPUT=y
1027# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1017# CONFIG_HID_FF is not set 1028# CONFIG_HID_FF is not set
1018CONFIG_USB_HIDDEV=y 1029CONFIG_USB_HIDDEV=y
1019# CONFIG_USB_AIPTEK is not set 1030# CONFIG_USB_AIPTEK is not set
@@ -1268,12 +1279,13 @@ CONFIG_KPROBES=y
1268# Kernel hacking 1279# Kernel hacking
1269# 1280#
1270CONFIG_PRINTK_TIME=y 1281CONFIG_PRINTK_TIME=y
1271CONFIG_DEBUG_KERNEL=y
1272CONFIG_MAGIC_SYSRQ=y 1282CONFIG_MAGIC_SYSRQ=y
1283CONFIG_DEBUG_KERNEL=y
1273CONFIG_LOG_BUF_SHIFT=18 1284CONFIG_LOG_BUF_SHIFT=18
1274CONFIG_DETECT_SOFTLOCKUP=y 1285CONFIG_DETECT_SOFTLOCKUP=y
1275CONFIG_SCHEDSTATS=y 1286CONFIG_SCHEDSTATS=y
1276# CONFIG_DEBUG_SLAB is not set 1287# CONFIG_DEBUG_SLAB is not set
1288# CONFIG_DEBUG_MUTEXES is not set
1277# CONFIG_DEBUG_SPINLOCK is not set 1289# CONFIG_DEBUG_SPINLOCK is not set
1278# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1290# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1279# CONFIG_DEBUG_KOBJECT is not set 1291# CONFIG_DEBUG_KOBJECT is not set
@@ -1281,6 +1293,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
1281# CONFIG_DEBUG_INFO is not set 1293# CONFIG_DEBUG_INFO is not set
1282CONFIG_DEBUG_FS=y 1294CONFIG_DEBUG_FS=y
1283# CONFIG_DEBUG_VM is not set 1295# CONFIG_DEBUG_VM is not set
1296CONFIG_FORCED_INLINING=y
1284# CONFIG_RCU_TORTURE_TEST is not set 1297# CONFIG_RCU_TORTURE_TEST is not set
1285# CONFIG_DEBUG_STACK_USAGE is not set 1298# CONFIG_DEBUG_STACK_USAGE is not set
1286# CONFIG_DEBUG_DCFLUSH is not set 1299# CONFIG_DEBUG_DCFLUSH is not set
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 710002991888..e50e56e4ab61 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1416,7 +1416,6 @@ execve_merge:
1416 add %sp, PTREGS_OFF, %o0 1416 add %sp, PTREGS_OFF, %o0
1417 1417
1418 .globl sys_pipe, sys_sigpause, sys_nis_syscall 1418 .globl sys_pipe, sys_sigpause, sys_nis_syscall
1419 .globl sys_sigsuspend, sys_rt_sigsuspend
1420 .globl sys_rt_sigreturn 1419 .globl sys_rt_sigreturn
1421 .globl sys_ptrace 1420 .globl sys_ptrace
1422 .globl sys_sigaltstack 1421 .globl sys_sigaltstack
@@ -1440,28 +1439,6 @@ sys32_sigaltstack:
1440 mov %i6, %o2 1439 mov %i6, %o2
1441#endif 1440#endif
1442 .align 32 1441 .align 32
1443sys_sigsuspend: add %sp, PTREGS_OFF, %o0
1444 call do_sigsuspend
1445 add %o7, 1f-.-4, %o7
1446 nop
1447sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
1448 add %sp, PTREGS_OFF, %o2
1449 call do_rt_sigsuspend
1450 add %o7, 1f-.-4, %o7
1451 nop
1452#ifdef CONFIG_COMPAT
1453 .globl sys32_rt_sigsuspend
1454sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
1455 srl %o0, 0, %o0
1456 add %sp, PTREGS_OFF, %o2
1457 call do_rt_sigsuspend32
1458 add %o7, 1f-.-4, %o7
1459#endif
1460 /* NOTE: %o0 has a correct value already */
1461sys_sigpause: add %sp, PTREGS_OFF, %o1
1462 call do_sigpause
1463 add %o7, 1f-.-4, %o7
1464 nop
1465#ifdef CONFIG_COMPAT 1442#ifdef CONFIG_COMPAT
1466 .globl sys32_sigreturn 1443 .globl sys32_sigreturn
1467sys32_sigreturn: 1444sys32_sigreturn:
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 1dc3650c5cae..059b0d025224 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -164,6 +164,7 @@ void machine_restart(char * cmd)
164 panic("Reboot failed!"); 164 panic("Reboot failed!");
165} 165}
166 166
167#ifdef CONFIG_COMPAT
167static void show_regwindow32(struct pt_regs *regs) 168static void show_regwindow32(struct pt_regs *regs)
168{ 169{
169 struct reg_window32 __user *rw; 170 struct reg_window32 __user *rw;
@@ -189,6 +190,9 @@ static void show_regwindow32(struct pt_regs *regs)
189 r_w.ins[0], r_w.ins[1], r_w.ins[2], r_w.ins[3], 190 r_w.ins[0], r_w.ins[1], r_w.ins[2], r_w.ins[3],
190 r_w.ins[4], r_w.ins[5], r_w.ins[6], r_w.ins[7]); 191 r_w.ins[4], r_w.ins[5], r_w.ins[6], r_w.ins[7]);
191} 192}
193#else
194#define show_regwindow32(regs) do { } while (0)
195#endif
192 196
193static void show_regwindow(struct pt_regs *regs) 197static void show_regwindow(struct pt_regs *regs)
194{ 198{
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 090dcca00d2a..b80eba0081ca 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -53,14 +53,13 @@ __handle_user_windows:
53 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 53 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
54 ldx [%g6 + TI_FLAGS], %l0 54 ldx [%g6 + TI_FLAGS], %l0
55 55
561: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 561: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
57 be,pt %xcc, __handle_user_windows_continue 57 be,pt %xcc, __handle_user_windows_continue
58 nop 58 nop
59 clr %o0 59 mov %l5, %o1
60 mov %l5, %o2 60 mov %l6, %o2
61 mov %l6, %o3 61 add %sp, PTREGS_OFF, %o0
62 add %sp, PTREGS_OFF, %o1 62 mov %l0, %o3
63 mov %l0, %o4
64 63
65 call do_notify_resume 64 call do_notify_resume
66 wrpr %g0, RTRAP_PSTATE, %pstate 65 wrpr %g0, RTRAP_PSTATE, %pstate
@@ -96,15 +95,14 @@ __handle_perfctrs:
96 wrpr %g0, RTRAP_PSTATE, %pstate 95 wrpr %g0, RTRAP_PSTATE, %pstate
97 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 96 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
98 ldx [%g6 + TI_FLAGS], %l0 97 ldx [%g6 + TI_FLAGS], %l0
991: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 981: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
100 99
101 be,pt %xcc, __handle_perfctrs_continue 100 be,pt %xcc, __handle_perfctrs_continue
102 sethi %hi(TSTATE_PEF), %o0 101 sethi %hi(TSTATE_PEF), %o0
103 clr %o0 102 mov %l5, %o1
104 mov %l5, %o2 103 mov %l6, %o2
105 mov %l6, %o3 104 add %sp, PTREGS_OFF, %o0
106 add %sp, PTREGS_OFF, %o1 105 mov %l0, %o3
107 mov %l0, %o4
108 call do_notify_resume 106 call do_notify_resume
109 107
110 wrpr %g0, RTRAP_PSTATE, %pstate 108 wrpr %g0, RTRAP_PSTATE, %pstate
@@ -129,11 +127,10 @@ __handle_userfpu:
129 ba,a,pt %xcc, __handle_userfpu_continue 127 ba,a,pt %xcc, __handle_userfpu_continue
130 128
131__handle_signal: 129__handle_signal:
132 clr %o0 130 mov %l5, %o1
133 mov %l5, %o2 131 mov %l6, %o2
134 mov %l6, %o3 132 add %sp, PTREGS_OFF, %o0
135 add %sp, PTREGS_OFF, %o1 133 mov %l0, %o3
136 mov %l0, %o4
137 call do_notify_resume 134 call do_notify_resume
138 wrpr %g0, RTRAP_PSTATE, %pstate 135 wrpr %g0, RTRAP_PSTATE, %pstate
139 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate 136 wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate
@@ -200,7 +197,7 @@ __handle_preemption_continue:
200 andcc %l1, %o0, %g0 197 andcc %l1, %o0, %g0
201 andcc %l0, _TIF_NEED_RESCHED, %g0 198 andcc %l0, _TIF_NEED_RESCHED, %g0
202 bne,pn %xcc, __handle_preemption 199 bne,pn %xcc, __handle_preemption
203 andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 200 andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0
204 bne,pn %xcc, __handle_signal 201 bne,pn %xcc, __handle_signal
205__handle_signal_continue: 202__handle_signal_continue:
206 ldub [%g6 + TI_WSAVED], %o2 203 ldub [%g6 + TI_WSAVED], %o2
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 250745896aee..054461e6946d 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -561,6 +561,8 @@ static int __init set_preferred_console(void)
561 serial_console = 1; 561 serial_console = 1;
562 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { 562 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
563 serial_console = 2; 563 serial_console = 2;
564 } else if (idev == PROMDEV_IRSC && odev == PROMDEV_ORSC) {
565 serial_console = 3;
564 } else { 566 } else {
565 prom_printf("Inconsistent console: " 567 prom_printf("Inconsistent console: "
566 "input %d, output %d\n", 568 "input %d, output %d\n",
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 60f5dfabb1e1..ca11a4c457d4 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -36,9 +36,6 @@
36 36
37#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 37#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38 38
39static int do_signal(sigset_t *oldset, struct pt_regs * regs,
40 unsigned long orig_o0, int ret_from_syscall);
41
42/* {set, get}context() needed for 64-bit SparcLinux userland. */ 39/* {set, get}context() needed for 64-bit SparcLinux userland. */
43asmlinkage void sparc64_set_context(struct pt_regs *regs) 40asmlinkage void sparc64_set_context(struct pt_regs *regs)
44{ 41{
@@ -242,114 +239,29 @@ struct rt_signal_frame {
242/* Align macros */ 239/* Align macros */
243#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7))) 240#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
244 241
245/* 242static long _sigpause_common(old_sigset_t set)
246 * atomically swap in the new signal mask, and wait for a signal.
247 * This is really tricky on the Sparc, watch out...
248 */
249asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
250{ 243{
251 sigset_t saveset;
252
253#ifdef CONFIG_SPARC32_COMPAT
254 if (test_thread_flag(TIF_32BIT)) {
255 extern asmlinkage void _sigpause32_common(compat_old_sigset_t,
256 struct pt_regs *);
257 _sigpause32_common(set, regs);
258 return;
259 }
260#endif
261 set &= _BLOCKABLE; 244 set &= _BLOCKABLE;
262 spin_lock_irq(&current->sighand->siglock); 245 spin_lock_irq(&current->sighand->siglock);
263 saveset = current->blocked; 246 current->saved_sigmask = current->blocked;
264 siginitset(&current->blocked, set); 247 siginitset(&current->blocked, set);
265 recalc_sigpending(); 248 recalc_sigpending();
266 spin_unlock_irq(&current->sighand->siglock); 249 spin_unlock_irq(&current->sighand->siglock);
267
268 if (test_thread_flag(TIF_32BIT)) {
269 regs->tpc = (regs->tnpc & 0xffffffff);
270 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
271 } else {
272 regs->tpc = regs->tnpc;
273 regs->tnpc += 4;
274 }
275 250
276 /* Condition codes and return value where set here for sigpause, 251 current->state = TASK_INTERRUPTIBLE;
277 * and so got used by setup_frame, which again causes sigreturn() 252 schedule();
278 * to return -EINTR. 253 set_thread_flag(TIF_RESTORE_SIGMASK);
279 */ 254 return -ERESTARTNOHAND;
280 while (1) {
281 current->state = TASK_INTERRUPTIBLE;
282 schedule();
283 /*
284 * Return -EINTR and set condition code here,
285 * so the interrupted system call actually returns
286 * these.
287 */
288 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
289 regs->u_regs[UREG_I0] = EINTR;
290 if (do_signal(&saveset, regs, 0, 0))
291 return;
292 }
293} 255}
294 256
295asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) 257asmlinkage long sys_sigpause(unsigned int set)
296{ 258{
297 _sigpause_common(set, regs); 259 return _sigpause_common(set);
298} 260}
299 261
300asmlinkage void do_sigsuspend(struct pt_regs *regs) 262asmlinkage long sys_sigsuspend(old_sigset_t set)
301{ 263{
302 _sigpause_common(regs->u_regs[UREG_I0], regs); 264 return _sigpause_common(set);
303}
304
305asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs)
306{
307 sigset_t oldset, set;
308
309 /* XXX: Don't preclude handling different sized sigset_t's. */
310 if (sigsetsize != sizeof(sigset_t)) {
311 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
312 regs->u_regs[UREG_I0] = EINVAL;
313 return;
314 }
315 if (copy_from_user(&set, uset, sizeof(set))) {
316 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
317 regs->u_regs[UREG_I0] = EFAULT;
318 return;
319 }
320
321 sigdelsetmask(&set, ~_BLOCKABLE);
322 spin_lock_irq(&current->sighand->siglock);
323 oldset = current->blocked;
324 current->blocked = set;
325 recalc_sigpending();
326 spin_unlock_irq(&current->sighand->siglock);
327
328 if (test_thread_flag(TIF_32BIT)) {
329 regs->tpc = (regs->tnpc & 0xffffffff);
330 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
331 } else {
332 regs->tpc = regs->tnpc;
333 regs->tnpc += 4;
334 }
335
336 /* Condition codes and return value where set here for sigpause,
337 * and so got used by setup_frame, which again causes sigreturn()
338 * to return -EINTR.
339 */
340 while (1) {
341 current->state = TASK_INTERRUPTIBLE;
342 schedule();
343 /*
344 * Return -EINTR and set condition code here,
345 * so the interrupted system call actually returns
346 * these.
347 */
348 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
349 regs->u_regs[UREG_I0] = EINTR;
350 if (do_signal(&oldset, regs, 0, 0))
351 return;
352 }
353} 265}
354 266
355static inline int 267static inline int
@@ -607,26 +519,29 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
607 * want to handle. Thus you cannot kill init even with a SIGKILL even by 519 * want to handle. Thus you cannot kill init even with a SIGKILL even by
608 * mistake. 520 * mistake.
609 */ 521 */
610static int do_signal(sigset_t *oldset, struct pt_regs * regs, 522static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
611 unsigned long orig_i0, int restart_syscall)
612{ 523{
613 siginfo_t info; 524 siginfo_t info;
614 struct signal_deliver_cookie cookie; 525 struct signal_deliver_cookie cookie;
615 struct k_sigaction ka; 526 struct k_sigaction ka;
616 int signr; 527 int signr;
528 sigset_t *oldset;
617 529
618 cookie.restart_syscall = restart_syscall; 530 cookie.restart_syscall = restart_syscall;
619 cookie.orig_i0 = orig_i0; 531 cookie.orig_i0 = orig_i0;
620 532
621 if (!oldset) 533 if (test_thread_flag(TIF_RESTORE_SIGMASK))
534 oldset = &current->saved_sigmask;
535 else
622 oldset = &current->blocked; 536 oldset = &current->blocked;
623 537
624#ifdef CONFIG_SPARC32_COMPAT 538#ifdef CONFIG_SPARC32_COMPAT
625 if (test_thread_flag(TIF_32BIT)) { 539 if (test_thread_flag(TIF_32BIT)) {
626 extern int do_signal32(sigset_t *, struct pt_regs *, 540 extern void do_signal32(sigset_t *, struct pt_regs *,
627 unsigned long, int); 541 unsigned long, int);
628 return do_signal32(oldset, regs, orig_i0, 542 do_signal32(oldset, regs, orig_i0,
629 cookie.restart_syscall); 543 cookie.restart_syscall);
544 return;
630 } 545 }
631#endif 546#endif
632 547
@@ -635,7 +550,15 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
635 if (cookie.restart_syscall) 550 if (cookie.restart_syscall)
636 syscall_restart(orig_i0, regs, &ka.sa); 551 syscall_restart(orig_i0, regs, &ka.sa);
637 handle_signal(signr, &ka, &info, oldset, regs); 552 handle_signal(signr, &ka, &info, oldset, regs);
638 return 1; 553
554 /* a signal was successfully delivered; the saved
555 * sigmask will have been stored in the signal frame,
556 * and will be restored by sigreturn, so we can simply
557 * clear the TIF_RESTORE_SIGMASK flag.
558 */
559 if (test_thread_flag(TIF_RESTORE_SIGMASK))
560 clear_thread_flag(TIF_RESTORE_SIGMASK);
561 return;
639 } 562 }
640 if (cookie.restart_syscall && 563 if (cookie.restart_syscall &&
641 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 564 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -652,15 +575,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
652 regs->tpc -= 4; 575 regs->tpc -= 4;
653 regs->tnpc -= 4; 576 regs->tnpc -= 4;
654 } 577 }
655 return 0; 578
579 /* if there's no signal to deliver, we just put the saved sigmask
580 * back
581 */
582 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
583 clear_thread_flag(TIF_RESTORE_SIGMASK);
584 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
585 }
656} 586}
657 587
658void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, 588void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
659 unsigned long orig_i0, int restart_syscall,
660 unsigned long thread_info_flags) 589 unsigned long thread_info_flags)
661{ 590{
662 if (thread_info_flags & _TIF_SIGPENDING) 591 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
663 do_signal(oldset, regs, orig_i0, restart_syscall); 592 do_signal(regs, orig_i0, restart_syscall);
664} 593}
665 594
666void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) 595void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 009a86e5ded4..708ba9b42cda 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -32,9 +32,6 @@
32 32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34 34
35int do_signal32(sigset_t *oldset, struct pt_regs *regs,
36 unsigned long orig_o0, int ret_from_syscall);
37
38/* Signal frames: the original one (compatible with SunOS): 35/* Signal frames: the original one (compatible with SunOS):
39 * 36 *
40 * Set up a signal frame... Make the stack look the way SunOS 37 * Set up a signal frame... Make the stack look the way SunOS
@@ -226,102 +223,6 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
226 return 0; 223 return 0;
227} 224}
228 225
229/*
230 * atomically swap in the new signal mask, and wait for a signal.
231 * This is really tricky on the Sparc, watch out...
232 */
233asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs)
234{
235 sigset_t saveset;
236
237 set &= _BLOCKABLE;
238 spin_lock_irq(&current->sighand->siglock);
239 saveset = current->blocked;
240 siginitset(&current->blocked, set);
241 recalc_sigpending();
242 spin_unlock_irq(&current->sighand->siglock);
243
244 regs->tpc = regs->tnpc;
245 regs->tnpc += 4;
246 if (test_thread_flag(TIF_32BIT)) {
247 regs->tpc &= 0xffffffff;
248 regs->tnpc &= 0xffffffff;
249 }
250
251 /* Condition codes and return value where set here for sigpause,
252 * and so got used by setup_frame, which again causes sigreturn()
253 * to return -EINTR.
254 */
255 while (1) {
256 current->state = TASK_INTERRUPTIBLE;
257 schedule();
258 /*
259 * Return -EINTR and set condition code here,
260 * so the interrupted system call actually returns
261 * these.
262 */
263 regs->tstate |= TSTATE_ICARRY;
264 regs->u_regs[UREG_I0] = EINTR;
265 if (do_signal32(&saveset, regs, 0, 0))
266 return;
267 }
268}
269
270asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs)
271{
272 sigset_t oldset, set;
273 compat_sigset_t set32;
274
275 /* XXX: Don't preclude handling different sized sigset_t's. */
276 if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) {
277 regs->tstate |= TSTATE_ICARRY;
278 regs->u_regs[UREG_I0] = EINVAL;
279 return;
280 }
281 if (copy_from_user(&set32, compat_ptr(uset), sizeof(set32))) {
282 regs->tstate |= TSTATE_ICARRY;
283 regs->u_regs[UREG_I0] = EFAULT;
284 return;
285 }
286 switch (_NSIG_WORDS) {
287 case 4: set.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
288 case 3: set.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
289 case 2: set.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
290 case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
291 }
292 sigdelsetmask(&set, ~_BLOCKABLE);
293 spin_lock_irq(&current->sighand->siglock);
294 oldset = current->blocked;
295 current->blocked = set;
296 recalc_sigpending();
297 spin_unlock_irq(&current->sighand->siglock);
298
299 regs->tpc = regs->tnpc;
300 regs->tnpc += 4;
301 if (test_thread_flag(TIF_32BIT)) {
302 regs->tpc &= 0xffffffff;
303 regs->tnpc &= 0xffffffff;
304 }
305
306 /* Condition codes and return value where set here for sigpause,
307 * and so got used by setup_frame, which again causes sigreturn()
308 * to return -EINTR.
309 */
310 while (1) {
311 current->state = TASK_INTERRUPTIBLE;
312 schedule();
313 /*
314 * Return -EINTR and set condition code here,
315 * so the interrupted system call actually returns
316 * these.
317 */
318 regs->tstate |= TSTATE_ICARRY;
319 regs->u_regs[UREG_I0] = EINTR;
320 if (do_signal32(&oldset, regs, 0, 0))
321 return;
322 }
323}
324
325static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) 226static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
326{ 227{
327 unsigned long *fpregs = current_thread_info()->fpregs; 228 unsigned long *fpregs = current_thread_info()->fpregs;
@@ -1362,8 +1263,8 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
1362 * want to handle. Thus you cannot kill init even with a SIGKILL even by 1263 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1363 * mistake. 1264 * mistake.
1364 */ 1265 */
1365int do_signal32(sigset_t *oldset, struct pt_regs * regs, 1266void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1366 unsigned long orig_i0, int restart_syscall) 1267 unsigned long orig_i0, int restart_syscall)
1367{ 1268{
1368 siginfo_t info; 1269 siginfo_t info;
1369 struct signal_deliver_cookie cookie; 1270 struct signal_deliver_cookie cookie;
@@ -1380,7 +1281,15 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
1380 syscall_restart32(orig_i0, regs, &ka.sa); 1281 syscall_restart32(orig_i0, regs, &ka.sa);
1381 handle_signal32(signr, &ka, &info, oldset, 1282 handle_signal32(signr, &ka, &info, oldset,
1382 regs, svr4_signal); 1283 regs, svr4_signal);
1383 return 1; 1284
1285 /* a signal was successfully delivered; the saved
1286 * sigmask will have been stored in the signal frame,
1287 * and will be restored by sigreturn, so we can simply
1288 * clear the TIF_RESTORE_SIGMASK flag.
1289 */
1290 if (test_thread_flag(TIF_RESTORE_SIGMASK))
1291 clear_thread_flag(TIF_RESTORE_SIGMASK);
1292 return;
1384 } 1293 }
1385 if (cookie.restart_syscall && 1294 if (cookie.restart_syscall &&
1386 (regs->u_regs[UREG_I0] == ERESTARTNOHAND || 1295 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -1397,7 +1306,14 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
1397 regs->tpc -= 4; 1306 regs->tpc -= 4;
1398 regs->tnpc -= 4; 1307 regs->tnpc -= 4;
1399 } 1308 }
1400 return 0; 1309
1310 /* if there's no signal to deliver, we just put the saved sigmask
1311 * back
1312 */
1313 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
1314 clear_thread_flag(TIF_RESTORE_SIGMASK);
1315 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
1316 }
1401} 1317}
1402 1318
1403struct sigstack32 { 1319struct sigstack32 {
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d177d7e5c9d3..3c06bfb92a8c 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -69,7 +69,6 @@ struct poll {
69 69
70extern void die_if_kernel(char *str, struct pt_regs *regs); 70extern void die_if_kernel(char *str, struct pt_regs *regs);
71extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 71extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
72void _sigpause_common (unsigned int set, struct pt_regs *);
73extern void *__bzero(void *, size_t); 72extern void *__bzero(void *, size_t);
74extern void *__memscan_zero(void *, size_t); 73extern void *__memscan_zero(void *, size_t);
75extern void *__memscan_generic(void *, int, size_t); 74extern void *__memscan_generic(void *, int, size_t);
@@ -236,9 +235,10 @@ EXPORT_SYMBOL(pci_dma_supported);
236/* I/O device mmaping on Sparc64. */ 235/* I/O device mmaping on Sparc64. */
237EXPORT_SYMBOL(io_remap_pfn_range); 236EXPORT_SYMBOL(io_remap_pfn_range);
238 237
238#ifdef CONFIG_COMPAT
239/* Solaris/SunOS binary compatibility */ 239/* Solaris/SunOS binary compatibility */
240EXPORT_SYMBOL(_sigpause_common);
241EXPORT_SYMBOL(verify_compat_iovec); 240EXPORT_SYMBOL(verify_compat_iovec);
241#endif
242 242
243EXPORT_SYMBOL(dump_fpu); 243EXPORT_SYMBOL(dump_fpu);
244EXPORT_SYMBOL(pte_alloc_one_kernel); 244EXPORT_SYMBOL(pte_alloc_one_kernel);
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index d4b7a100cb8a..9264ccbaaafa 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -821,7 +821,7 @@ asmlinkage long sys32_utimes(char __user *filename,
821 return -EFAULT; 821 return -EFAULT;
822 } 822 }
823 823
824 return do_utimes(filename, (tvs ? &ktvs[0] : NULL)); 824 return do_utimes(AT_FDCWD, filename, (tvs ? &ktvs[0] : NULL));
825} 825}
826 826
827/* These are here just in case some old sparc32 binary calls it. */ 827/* These are here just in case some old sparc32 binary calls it. */
@@ -1003,7 +1003,7 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
1003asmlinkage long sparc32_open(const char __user *filename, 1003asmlinkage long sparc32_open(const char __user *filename,
1004 int flags, int mode) 1004 int flags, int mode)
1005{ 1005{
1006 return do_sys_open(filename, flags, mode); 1006 return do_sys_open(AT_FDCWD, filename, flags, mode);
1007} 1007}
1008 1008
1009extern unsigned long do_mremap(unsigned long addr, 1009extern unsigned long do_mremap(unsigned long addr,
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 98d24bc00044..5ed1a17cd5b9 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -41,7 +41,7 @@ sys_call_table32:
41/*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid 41/*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
42 .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall 42 .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
43/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending 43/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
44 .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid 44 .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
45/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall 45/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
46 .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd 46 .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
47/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod 47/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
@@ -76,7 +76,10 @@ sys_call_table32:
76 .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy 76 .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
77/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink 77/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
78 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid 78 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
79/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl 79/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
80 .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
81/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
82 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
80 83
81#endif /* CONFIG_COMPAT */ 84#endif /* CONFIG_COMPAT */
82 85
@@ -142,7 +145,10 @@ sys_call_table:
142 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy 145 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
143/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink 146/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
144 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid 147 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
145/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl 148/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
149 .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
150/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
151 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
146 152
147#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ 153#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
148 defined(CONFIG_SOLARIS_EMUL_MODULE) 154 defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -239,13 +245,20 @@ sunos_sys_table:
239/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys 245/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
240 .word sunos_nosys, sunos_nosys, sunos_nosys 246 .word sunos_nosys, sunos_nosys, sunos_nosys
241 .word sunos_nosys, sunos_nosys, sunos_nosys 247 .word sunos_nosys, sunos_nosys, sunos_nosys
248 .word sunos_nosys
249/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys
242 .word sunos_nosys, sunos_nosys, sunos_nosys 250 .word sunos_nosys, sunos_nosys, sunos_nosys
243 .word sunos_nosys, sunos_nosys, sunos_nosys 251 .word sunos_nosys, sunos_nosys, sunos_nosys
252 .word sunos_nosys
253/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys
244 .word sunos_nosys, sunos_nosys, sunos_nosys 254 .word sunos_nosys, sunos_nosys, sunos_nosys
245 .word sunos_nosys, sunos_nosys, sunos_nosys 255 .word sunos_nosys, sunos_nosys, sunos_nosys
256 .word sunos_nosys
257/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys
246 .word sunos_nosys, sunos_nosys, sunos_nosys 258 .word sunos_nosys, sunos_nosys, sunos_nosys
247 .word sunos_nosys, sunos_nosys, sunos_nosys 259 .word sunos_nosys, sunos_nosys, sunos_nosys
260 .word sunos_nosys
261/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
248 .word sunos_nosys, sunos_nosys, sunos_nosys 262 .word sunos_nosys, sunos_nosys, sunos_nosys
249 .word sunos_nosys, sunos_nosys, sunos_nosys 263 .word sunos_nosys, sunos_nosys, sunos_nosys
250 .word sunos_nosys
251#endif 264#endif
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
index eae5db8dda56..ac6d035dd150 100644
--- a/arch/sparc64/prom/console.c
+++ b/arch/sparc64/prom/console.c
@@ -99,8 +99,12 @@ prom_query_input_device(void)
99 if (!strncmp(propb, "keyboard", 8)) 99 if (!strncmp(propb, "keyboard", 8))
100 return PROMDEV_ITTYA; 100 return PROMDEV_ITTYA;
101 101
102 if (!strncmp (propb, "rsc", 3))
103 return PROMDEV_IRSC;
104
102 if (strncmp (propb, "tty", 3) || !propb[3]) 105 if (strncmp (propb, "tty", 3) || !propb[3])
103 return PROMDEV_I_UNK; 106 return PROMDEV_I_UNK;
107
104 switch (propb[3]) { 108 switch (propb[3]) {
105 case 'a': return PROMDEV_ITTYA; 109 case 'a': return PROMDEV_ITTYA;
106 case 'b': return PROMDEV_ITTYB; 110 case 'b': return PROMDEV_ITTYB;
@@ -136,8 +140,12 @@ prom_query_output_device(void)
136 if (!strncmp(propb, "screen", 6)) 140 if (!strncmp(propb, "screen", 6))
137 return PROMDEV_OTTYA; 141 return PROMDEV_OTTYA;
138 142
143 if (!strncmp (propb, "rsc", 3))
144 return PROMDEV_ORSC;
145
139 if (strncmp (propb, "tty", 3) || !propb[3]) 146 if (strncmp (propb, "tty", 3) || !propb[3])
140 return PROMDEV_O_UNK; 147 return PROMDEV_O_UNK;
148
141 switch (propb[3]) { 149 switch (propb[3]) {
142 case 'a': return PROMDEV_OTTYA; 150 case 'a': return PROMDEV_OTTYA;
143 case 'b': return PROMDEV_OTTYB; 151 case 'b': return PROMDEV_OTTYB;
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
index 4b6ae583c0a3..eb314ed23cdb 100644
--- a/arch/sparc64/solaris/entry64.S
+++ b/arch/sparc64/solaris/entry64.S
@@ -180,6 +180,8 @@ solaris_sigsuspend:
180 nop 180 nop
181 call sys_sigsuspend 181 call sys_sigsuspend
182 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] 182 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
183 b,pt %xcc, ret_from_solaris
184 nop
183 185
184 .globl solaris_getpid 186 .globl solaris_getpid
185solaris_getpid: 187solaris_getpid:
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 8ff3bcbce5fc..5982fe2753e0 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -143,6 +143,7 @@ config HOSTFS
143 143
144config HPPFS 144config HPPFS
145 tristate "HoneyPot ProcFS (EXPERIMENTAL)" 145 tristate "HoneyPot ProcFS (EXPERIMENTAL)"
146 depends on EXPERIMENTAL
146 help 147 help
147 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 148 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
148 entries to be overridden, removed, or fabricated from the host. 149 entries to be overridden, removed, or fabricated from the host.
@@ -155,10 +156,6 @@ config HPPFS
155 You only need this if you are setting up a UML honeypot. Otherwise, 156 You only need this if you are setting up a UML honeypot. Otherwise,
156 it is safe to say 'N' here. 157 it is safe to say 'N' here.
157 158
158 If you are actively using it, please report any problems, since it's
159 getting fixed. In this moment, it is experimental on 2.6 (it works on
160 2.4).
161
162config MCONSOLE 159config MCONSOLE
163 bool "Management console" 160 bool "Management console"
164 default y 161 default y
@@ -243,8 +240,16 @@ config NEST_LEVEL
243 Only change this if you are running nested UMLs. 240 Only change this if you are running nested UMLs.
244 241
245config HIGHMEM 242config HIGHMEM
246 bool "Highmem support" 243 bool "Highmem support (EXPERIMENTAL)"
247 depends on !64BIT 244 depends on !64BIT && EXPERIMENTAL
245 default n
246 help
247 This was used to allow UML to run with big amounts of memory.
248 Currently it is unstable, so if unsure say N.
249
250 To use big amounts of memory, it is recommended to disable TT mode (i.e.
251 CONFIG_MODE_TT) and enable static linking (i.e. CONFIG_STATIC_LINK) -
252 this should allow the guest to use up to 2.75G of memory.
248 253
249config KERNEL_STACK_ORDER 254config KERNEL_STACK_ORDER
250 int "Kernel stack size order" 255 int "Kernel stack size order"
@@ -269,17 +274,13 @@ endmenu
269 274
270source "init/Kconfig" 275source "init/Kconfig"
271 276
272source "net/Kconfig" 277source "drivers/block/Kconfig"
273
274source "drivers/base/Kconfig"
275 278
276source "arch/um/Kconfig.char" 279source "arch/um/Kconfig.char"
277 280
278source "drivers/block/Kconfig" 281source "drivers/base/Kconfig"
279 282
280config NETDEVICES 283source "net/Kconfig"
281 bool
282 default NET
283 284
284source "arch/um/Kconfig.net" 285source "arch/um/Kconfig.net"
285 286
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index c71b39a677aa..ef79ed25aecd 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -22,13 +22,17 @@ config TOP_ADDR
22 default 0x80000000 if HOST_2G_2G 22 default 0x80000000 if HOST_2G_2G
23 23
24config 3_LEVEL_PGTABLES 24config 3_LEVEL_PGTABLES
25 bool "Three-level pagetables" 25 bool "Three-level pagetables (EXPERIMENTAL)"
26 default n 26 default n
27 depends on EXPERIMENTAL
27 help 28 help
28 Three-level pagetables will let UML have more than 4G of physical 29 Three-level pagetables will let UML have more than 4G of physical
29 memory. All the memory that can't be mapped directly will be treated 30 memory. All the memory that can't be mapped directly will be treated
30 as high memory. 31 as high memory.
31 32
33 However, this it experimental on 32-bit architectures, so if unsure say
34 N (on x86-64 it's automatically enabled, instead, as it's safe there).
35
32config STUB_CODE 36config STUB_CODE
33 hex 37 hex
34 default 0xbfffe000 38 default 0xbfffe000
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 45435ff589c1..6430a6383853 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -32,7 +32,7 @@ um-modes-$(CONFIG_MODE_TT) += tt
32um-modes-$(CONFIG_MODE_SKAS) += skas 32um-modes-$(CONFIG_MODE_SKAS) += skas
33 33
34MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ 34MODE_INCLUDE += $(foreach mode,$(um-modes-y),\
35 -I$(srctree)/$(ARCH_DIR)/kernel/$(mode)/include) 35 -I$(srctree)/$(ARCH_DIR)/include/$(mode))
36 36
37MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\ 37MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\
38 $(srctree)/$(ARCH_DIR)/Makefile-$(mode)) 38 $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index 30d285b266af..507e3cbac9d3 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -31,6 +31,10 @@ void daemon_init(struct net_device *dev, void *data)
31 dpri->fd = -1; 31 dpri->fd = -1;
32 dpri->control = -1; 32 dpri->control = -1;
33 dpri->dev = dev; 33 dpri->dev = dev;
34 /* We will free this pointer. If it contains crap we're burned. */
35 dpri->ctl_addr = NULL;
36 dpri->data_addr = NULL;
37 dpri->local_addr = NULL;
34 38
35 printk("daemon backend (uml_switch version %d) - %s:%s", 39 printk("daemon backend (uml_switch version %d) - %s:%s",
36 SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock); 40 SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 1bb085b2824d..c944265955e2 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -158,10 +158,16 @@ static void daemon_remove(void *data)
158 struct daemon_data *pri = data; 158 struct daemon_data *pri = data;
159 159
160 os_close_file(pri->fd); 160 os_close_file(pri->fd);
161 pri->fd = -1;
161 os_close_file(pri->control); 162 os_close_file(pri->control);
163 pri->control = -1;
164
162 kfree(pri->data_addr); 165 kfree(pri->data_addr);
166 pri->data_addr = NULL;
163 kfree(pri->ctl_addr); 167 kfree(pri->ctl_addr);
168 pri->ctl_addr = NULL;
164 kfree(pri->local_addr); 169 kfree(pri->local_addr);
170 pri->local_addr = NULL;
165} 171}
166 172
167int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) 173int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 3296e86a03a5..c41f75e4acb5 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -11,6 +11,7 @@
11#include "user.h" 11#include "user.h"
12#include "user_util.h" 12#include "user_util.h"
13#include "chan_user.h" 13#include "chan_user.h"
14#include "os.h"
14 15
15struct fd_chan { 16struct fd_chan {
16 int fd; 17 int fd;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index fb1f9fb9b871..8ebb2241ad42 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -68,6 +68,11 @@ static int uml_net_rx(struct net_device *dev)
68 return pkt_len; 68 return pkt_len;
69} 69}
70 70
71static void uml_dev_close(void* dev)
72{
73 dev_close( (struct net_device *) dev);
74}
75
71irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) 76irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
72{ 77{
73 struct net_device *dev = dev_id; 78 struct net_device *dev = dev_id;
@@ -80,15 +85,21 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
80 spin_lock(&lp->lock); 85 spin_lock(&lp->lock);
81 while((err = uml_net_rx(dev)) > 0) ; 86 while((err = uml_net_rx(dev)) > 0) ;
82 if(err < 0) { 87 if(err < 0) {
88 DECLARE_WORK(close_work, uml_dev_close, dev);
83 printk(KERN_ERR 89 printk(KERN_ERR
84 "Device '%s' read returned %d, shutting it down\n", 90 "Device '%s' read returned %d, shutting it down\n",
85 dev->name, err); 91 dev->name, err);
86 dev_close(dev); 92 /* dev_close can't be called in interrupt context, and takes
93 * again lp->lock.
94 * And dev_close() can be safely called multiple times on the
95 * same device, since it tests for (dev->flags & IFF_UP). So
96 * there's no harm in delaying the device shutdown. */
97 schedule_work(&close_work);
87 goto out; 98 goto out;
88 } 99 }
89 reactivate_fd(lp->fd, UM_ETH_IRQ); 100 reactivate_fd(lp->fd, UM_ETH_IRQ);
90 101
91 out: 102out:
92 spin_unlock(&lp->lock); 103 spin_unlock(&lp->lock);
93 return(IRQ_HANDLED); 104 return(IRQ_HANDLED);
94} 105}
@@ -317,6 +328,11 @@ static int eth_configure(int n, void *init, char *mac,
317 return 1; 328 return 1;
318 } 329 }
319 330
331 lp = dev->priv;
332 /* This points to the transport private data. It's still clear, but we
333 * must memset it to 0 *now*. Let's help the drivers. */
334 memset(lp, 0, size);
335
320 /* sysfs register */ 336 /* sysfs register */
321 if (!driver_registered) { 337 if (!driver_registered) {
322 platform_driver_register(&uml_net_driver); 338 platform_driver_register(&uml_net_driver);
@@ -358,7 +374,6 @@ static int eth_configure(int n, void *init, char *mac,
358 free_netdev(dev); 374 free_netdev(dev);
359 return 1; 375 return 1;
360 } 376 }
361 lp = dev->priv;
362 377
363 /* lp.user is the first four bytes of the transport data, which 378 /* lp.user is the first four bytes of the transport data, which
364 * has already been initialized. This structure assignment will 379 * has already been initialized. This structure assignment will
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 7696f8d2d89c..101efd26d467 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1103,31 +1103,33 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1103 return(-EINVAL); 1103 return(-EINVAL);
1104} 1104}
1105 1105
1106static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) 1106static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
1107{ 1107{
1108 struct uml_stat buf1, buf2; 1108 struct uml_stat buf1, buf2;
1109 int err; 1109 int err;
1110 1110
1111 if(from_cmdline == NULL) return(1); 1111 if(from_cmdline == NULL)
1112 if(!strcmp(from_cmdline, from_cow)) return(1); 1112 return 0;
1113 if(!strcmp(from_cmdline, from_cow))
1114 return 0;
1113 1115
1114 err = os_stat_file(from_cmdline, &buf1); 1116 err = os_stat_file(from_cmdline, &buf1);
1115 if(err < 0){ 1117 if(err < 0){
1116 printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err); 1118 printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
1117 return(1); 1119 return 0;
1118 } 1120 }
1119 err = os_stat_file(from_cow, &buf2); 1121 err = os_stat_file(from_cow, &buf2);
1120 if(err < 0){ 1122 if(err < 0){
1121 printk("Couldn't stat '%s', err = %d\n", from_cow, -err); 1123 printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
1122 return(1); 1124 return 1;
1123 } 1125 }
1124 if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino)) 1126 if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
1125 return(1); 1127 return 0;
1126 1128
1127 printk("Backing file mismatch - \"%s\" requested,\n" 1129 printk("Backing file mismatch - \"%s\" requested,\n"
1128 "\"%s\" specified in COW header of \"%s\"\n", 1130 "\"%s\" specified in COW header of \"%s\"\n",
1129 from_cmdline, from_cow, cow); 1131 from_cmdline, from_cow, cow);
1130 return(0); 1132 return 1;
1131} 1133}
1132 1134
1133static int backing_file_mismatch(char *file, __u64 size, time_t mtime) 1135static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
@@ -1189,18 +1191,19 @@ int open_ubd_file(char *file, struct openflags *openflags,
1189 unsigned long long size; 1191 unsigned long long size;
1190 __u32 version, align; 1192 __u32 version, align;
1191 char *backing_file; 1193 char *backing_file;
1192 int fd, err, sectorsize, same, mode = 0644; 1194 int fd, err, sectorsize, asked_switch, mode = 0644;
1193 1195
1194 fd = os_open_file(file, *openflags, mode); 1196 fd = os_open_file(file, *openflags, mode);
1195 if(fd < 0){ 1197 if (fd < 0) {
1196 if((fd == -ENOENT) && (create_cow_out != NULL)) 1198 if ((fd == -ENOENT) && (create_cow_out != NULL))
1197 *create_cow_out = 1; 1199 *create_cow_out = 1;
1198 if(!openflags->w || 1200 if (!openflags->w ||
1199 ((fd != -EROFS) && (fd != -EACCES))) return(fd); 1201 ((fd != -EROFS) && (fd != -EACCES)))
1202 return fd;
1200 openflags->w = 0; 1203 openflags->w = 0;
1201 fd = os_open_file(file, *openflags, mode); 1204 fd = os_open_file(file, *openflags, mode);
1202 if(fd < 0) 1205 if (fd < 0)
1203 return(fd); 1206 return fd;
1204 } 1207 }
1205 1208
1206 err = os_lock_file(fd, openflags->w); 1209 err = os_lock_file(fd, openflags->w);
@@ -1209,7 +1212,9 @@ int open_ubd_file(char *file, struct openflags *openflags,
1209 goto out_close; 1212 goto out_close;
1210 } 1213 }
1211 1214
1212 if(backing_file_out == NULL) return(fd); 1215 /* Succesful return case! */
1216 if(backing_file_out == NULL)
1217 return(fd);
1213 1218
1214 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, 1219 err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
1215 &size, &sectorsize, &align, bitmap_offset_out); 1220 &size, &sectorsize, &align, bitmap_offset_out);
@@ -1218,34 +1223,34 @@ int open_ubd_file(char *file, struct openflags *openflags,
1218 "errno = %d\n", file, -err); 1223 "errno = %d\n", file, -err);
1219 goto out_close; 1224 goto out_close;
1220 } 1225 }
1221 if(err) return(fd); 1226 if(err)
1222 1227 return(fd);
1223 if(backing_file_out == NULL) return(fd);
1224 1228
1225 same = same_backing_files(*backing_file_out, backing_file, file); 1229 asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
1226 1230
1227 if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){ 1231 /* Allow switching only if no mismatch. */
1232 if (asked_switch && !backing_file_mismatch(*backing_file_out, size, mtime)) {
1228 printk("Switching backing file to '%s'\n", *backing_file_out); 1233 printk("Switching backing file to '%s'\n", *backing_file_out);
1229 err = write_cow_header(file, fd, *backing_file_out, 1234 err = write_cow_header(file, fd, *backing_file_out,
1230 sectorsize, align, &size); 1235 sectorsize, align, &size);
1231 if(err){ 1236 if (err) {
1232 printk("Switch failed, errno = %d\n", -err); 1237 printk("Switch failed, errno = %d\n", -err);
1233 return(err); 1238 goto out_close;
1234 } 1239 }
1235 } 1240 } else {
1236 else {
1237 *backing_file_out = backing_file; 1241 *backing_file_out = backing_file;
1238 err = backing_file_mismatch(*backing_file_out, size, mtime); 1242 err = backing_file_mismatch(*backing_file_out, size, mtime);
1239 if(err) goto out_close; 1243 if (err)
1244 goto out_close;
1240 } 1245 }
1241 1246
1242 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 1247 cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
1243 bitmap_len_out, data_offset_out); 1248 bitmap_len_out, data_offset_out);
1244 1249
1245 return(fd); 1250 return fd;
1246 out_close: 1251 out_close:
1247 os_close_file(fd); 1252 os_close_file(fd);
1248 return(err); 1253 return err;
1249} 1254}
1250 1255
1251int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, 1256int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 8f4e46d677ab..c649108a9e9f 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -120,8 +120,10 @@ extern void machine_halt(void);
120extern int is_syscall(unsigned long addr); 120extern int is_syscall(unsigned long addr);
121extern void arch_switch(void); 121extern void arch_switch(void);
122extern void free_irq(unsigned int, void *); 122extern void free_irq(unsigned int, void *);
123extern int um_in_interrupt(void);
124extern int cpu(void); 123extern int cpu(void);
124
125/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */
126extern int __cant_sleep(void);
125extern void segv_handler(int sig, union uml_pt_regs *regs); 127extern void segv_handler(int sig, union uml_pt_regs *regs);
126extern void sigio_handler(int sig, union uml_pt_regs *regs); 128extern void sigio_handler(int sig, union uml_pt_regs *regs);
127 129
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
new file mode 100644
index 000000000000..018b3819ab0b
--- /dev/null
+++ b/arch/um/include/longjmp.h
@@ -0,0 +1,19 @@
1#ifndef __UML_LONGJMP_H
2#define __UML_LONGJMP_H
3
4#include <setjmp.h>
5#include "os.h"
6
7#define UML_SIGLONGJMP(buf, val) do { \
8 longjmp(*buf, val); \
9} while(0)
10
11#define UML_SIGSETJMP(buf, enable) ({ \
12 int n; \
13 enable = get_signals(); \
14 n = setjmp(*buf); \
15 if(n != 0) \
16 set_signals(enable); \
17 n; })
18
19#endif
diff --git a/arch/um/include/mode_kern.h b/arch/um/include/mode_kern.h
index 2d88afd0cf16..e7539a8451ef 100644
--- a/arch/um/include/mode_kern.h
+++ b/arch/um/include/mode_kern.h
@@ -9,22 +9,11 @@
9#include "linux/config.h" 9#include "linux/config.h"
10 10
11#ifdef CONFIG_MODE_TT 11#ifdef CONFIG_MODE_TT
12#include "mode_kern-tt.h" 12#include "mode_kern_tt.h"
13#endif 13#endif
14 14
15#ifdef CONFIG_MODE_SKAS 15#ifdef CONFIG_MODE_SKAS
16#include "mode_kern-skas.h" 16#include "mode_kern_skas.h"
17#endif 17#endif
18 18
19#endif 19#endif
20
21/*
22 * Overrides for Emacs so that we follow Linus's tabbing style.
23 * Emacs will notice this stuff at the end of the file and automatically
24 * adjust the settings for this buffer only. This must remain at the end
25 * of the file.
26 * ---------------------------------------------------------------------------
27 * Local variables:
28 * c-file-style: "linux"
29 * End:
30 */
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index dd72d66cf0ed..eb1710b81255 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -11,6 +11,7 @@
11#include "../os/include/file.h" 11#include "../os/include/file.h"
12#include "sysdep/ptrace.h" 12#include "sysdep/ptrace.h"
13#include "kern_util.h" 13#include "kern_util.h"
14#include "skas/mm_id.h"
14 15
15#define OS_TYPE_FILE 1 16#define OS_TYPE_FILE 1
16#define OS_TYPE_DIR 2 17#define OS_TYPE_DIR 2
@@ -190,11 +191,12 @@ extern int os_protect_memory(void *addr, unsigned long len,
190 int r, int w, int x); 191 int r, int w, int x);
191extern int os_unmap_memory(void *addr, int len); 192extern int os_unmap_memory(void *addr, int len);
192extern void os_flush_stdout(void); 193extern void os_flush_stdout(void);
193extern unsigned long long os_usecs(void);
194 194
195/* tt.c 195/* tt.c
196 * for tt mode only (will be deleted in future...) 196 * for tt mode only (will be deleted in future...)
197 */ 197 */
198extern void stop(void);
199extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
198extern int protect_memory(unsigned long addr, unsigned long len, 200extern int protect_memory(unsigned long addr, unsigned long len,
199 int r, int w, int x, int must_succeed); 201 int r, int w, int x, int must_succeed);
200extern void forward_pending_sigio(int target); 202extern void forward_pending_sigio(int target);
@@ -230,9 +232,63 @@ extern void block_signals(void);
230extern void unblock_signals(void); 232extern void unblock_signals(void);
231extern int get_signals(void); 233extern int get_signals(void);
232extern int set_signals(int enable); 234extern int set_signals(int enable);
235extern void os_usr1_signal(int on);
233 236
234/* trap.c */ 237/* trap.c */
235extern void os_fill_handlinfo(struct kern_handlers h); 238extern void os_fill_handlinfo(struct kern_handlers h);
236extern void do_longjmp(void *p, int val); 239extern void do_longjmp(void *p, int val);
237 240
241/* util.c */
242extern void stack_protections(unsigned long address);
243extern void task_protections(unsigned long address);
244extern int raw(int fd);
245extern void setup_machinename(char *machine_out);
246extern void setup_hostinfo(void);
247extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
248
249/* time.c */
250#define BILLION (1000 * 1000 * 1000)
251
252extern void switch_timers(int to_real);
253extern void idle_sleep(int secs);
254extern void enable_timer(void);
255extern void disable_timer(void);
256extern void user_time_init(void);
257extern void uml_idle_timer(void);
258extern unsigned long long os_nsecs(void);
259
260/* skas/mem.c */
261extern long run_syscall_stub(struct mm_id * mm_idp,
262 int syscall, unsigned long *args, long expected,
263 void **addr, int done);
264extern long syscall_stub_data(struct mm_id * mm_idp,
265 unsigned long *data, int data_count,
266 void **addr, void **stub_addr);
267extern int map(struct mm_id * mm_idp, unsigned long virt,
268 unsigned long len, int r, int w, int x, int phys_fd,
269 unsigned long long offset, int done, void **data);
270extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len,
271 int done, void **data);
272extern int protect(struct mm_id * mm_idp, unsigned long addr,
273 unsigned long len, int r, int w, int x, int done,
274 void **data);
275
276/* skas/process.c */
277extern int is_skas_winch(int pid, int fd, void *data);
278extern int start_userspace(unsigned long stub_stack);
279extern int copy_context_skas0(unsigned long stack, int pid);
280extern void userspace(union uml_pt_regs *regs);
281extern void map_stub_pages(int fd, unsigned long code,
282 unsigned long data, unsigned long stack);
283extern void new_thread(void *stack, void **switch_buf_ptr,
284 void **fork_buf_ptr, void (*handler)(int));
285extern void thread_wait(void *sw, void *fb);
286extern void switch_threads(void *me, void *next);
287extern int start_idle_thread(void *stack, void *switch_buf_ptr,
288 void **fork_buf_ptr);
289extern void initial_thread_cb_skas(void (*proc)(void *),
290 void *arg);
291extern void halt_skas(void);
292extern void reboot_skas(void);
293
238#endif 294#endif
diff --git a/arch/um/kernel/skas/include/mm_id.h b/arch/um/include/skas/mm_id.h
index 48dd0989ddaa..48dd0989ddaa 100644
--- a/arch/um/kernel/skas/include/mm_id.h
+++ b/arch/um/include/skas/mm_id.h
diff --git a/arch/um/include/skas/mmu-skas.h b/arch/um/include/skas/mmu-skas.h
new file mode 100644
index 000000000000..d8869a6ef1b4
--- /dev/null
+++ b/arch/um/include/skas/mmu-skas.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_MMU_H
7#define __SKAS_MMU_H
8
9#include "linux/config.h"
10#include "mm_id.h"
11#include "asm/ldt.h"
12
13struct mmu_context_skas {
14 struct mm_id id;
15 unsigned long last_page_table;
16#ifdef CONFIG_3_LEVEL_PGTABLES
17 unsigned long last_pmd;
18#endif
19 uml_ldt_t ldt;
20};
21
22extern void switch_mm_skas(struct mm_id * mm_idp);
23
24#endif
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
new file mode 100644
index 000000000000..260065cfeef1
--- /dev/null
+++ b/arch/um/include/skas/mode-skas.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_SKAS_H__
7#define __MODE_SKAS_H__
8
9#include <sysdep/ptrace.h>
10
11extern unsigned long exec_regs[];
12extern unsigned long exec_fp_regs[];
13extern unsigned long exec_fpx_regs[];
14extern int have_fpx_regs;
15
16extern void sig_handler_common_skas(int sig, void *sc_ptr);
17extern void kill_off_processes_skas(void);
18
19#endif
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/include/skas/mode_kern_skas.h
index c97a80dfe370..63c58739bde0 100644
--- a/arch/um/kernel/skas/include/mode_kern-skas.h
+++ b/arch/um/include/skas/mode_kern_skas.h
@@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags,
18 unsigned long sp, unsigned long stack_top, 18 unsigned long sp, unsigned long stack_top,
19 struct task_struct *p, struct pt_regs *regs); 19 struct task_struct *p, struct pt_regs *regs);
20extern void release_thread_skas(struct task_struct *task); 20extern void release_thread_skas(struct task_struct *task);
21extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
22extern void init_idle_skas(void); 21extern void init_idle_skas(void);
23extern void flush_tlb_kernel_range_skas(unsigned long start, 22extern void flush_tlb_kernel_range_skas(unsigned long start,
24 unsigned long end); 23 unsigned long end);
@@ -39,14 +38,3 @@ extern int thread_pid_skas(struct task_struct *task);
39#define kmem_end_skas (host_task_size - 1024 * 1024) 38#define kmem_end_skas (host_task_size - 1024 * 1024)
40 39
41#endif 40#endif
42
43/*
44 * Overrides for Emacs so that we follow Linus's tabbing style.
45 * Emacs will notice this stuff at the end of the file and automatically
46 * adjust the settings for this buffer only. This must remain at the end
47 * of the file.
48 * ---------------------------------------------------------------------------
49 * Local variables:
50 * c-file-style: "linux"
51 * End:
52 */
diff --git a/arch/um/kernel/skas/include/proc_mm.h b/arch/um/include/skas/proc_mm.h
index cce61a679052..902809209603 100644
--- a/arch/um/kernel/skas/include/proc_mm.h
+++ b/arch/um/include/skas/proc_mm.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -22,13 +22,13 @@ struct mm_mmap {
22 22
23struct mm_munmap { 23struct mm_munmap {
24 unsigned long addr; 24 unsigned long addr;
25 unsigned long len; 25 unsigned long len;
26}; 26};
27 27
28struct mm_mprotect { 28struct mm_mprotect {
29 unsigned long addr; 29 unsigned long addr;
30 unsigned long len; 30 unsigned long len;
31 unsigned int prot; 31 unsigned int prot;
32}; 32};
33 33
34struct proc_mm_op { 34struct proc_mm_op {
@@ -42,14 +42,3 @@ struct proc_mm_op {
42}; 42};
43 43
44#endif 44#endif
45
46/*
47 * Overrides for Emacs so that we follow Linus's tabbing style.
48 * Emacs will notice this stuff at the end of the file and automatically
49 * adjust the settings for this buffer only. This must remain at the end
50 * of the file.
51 * ---------------------------------------------------------------------------
52 * Local variables:
53 * c-file-style: "linux"
54 * End:
55 */
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
new file mode 100644
index 000000000000..86357282d681
--- /dev/null
+++ b/arch/um/include/skas/skas.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_H
7#define __SKAS_H
8
9#include "mm_id.h"
10#include "sysdep/ptrace.h"
11
12extern int userspace_pid[];
13extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
14extern int skas_needs_stub;
15
16extern int user_thread(unsigned long stack, int flags);
17extern void new_thread_proc(void *stack, void (*handler)(int sig));
18extern void new_thread_handler(int sig);
19extern void handle_syscall(union uml_pt_regs *regs);
20extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
21extern int new_mm(unsigned long stack);
22extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
23extern long execute_syscall_skas(void *r);
24extern unsigned long current_stub_stack(void);
25
26#endif
diff --git a/arch/um/kernel/skas/include/stub-data.h b/arch/um/include/skas/stub-data.h
index f6ed92c3727d..f6ed92c3727d 100644
--- a/arch/um/kernel/skas/include/stub-data.h
+++ b/arch/um/include/skas/stub-data.h
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/include/skas/uaccess-skas.h
index 64516c556cdf..224a75f4c025 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/include/skas/uaccess-skas.h
@@ -19,14 +19,3 @@ extern int clear_user_skas(void __user *mem, int len);
19extern int strnlen_user_skas(const void __user *str, int len); 19extern int strnlen_user_skas(const void __user *str, int len);
20 20
21#endif 21#endif
22
23/*
24 * Overrides for Emacs so that we follow Linus's tabbing style.
25 * Emacs will notice this stuff at the end of the file and automatically
26 * adjust the settings for this buffer only. This must remain at the end
27 * of the file.
28 * ---------------------------------------------------------------------------
29 * Local variables:
30 * c-file-style: "linux"
31 * End:
32 */
diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h
deleted file mode 100644
index 17d7ef2141f4..000000000000
--- a/arch/um/include/time_user.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TIME_USER_H__
7#define __TIME_USER_H__
8
9extern void timer(void);
10extern void switch_timers(int to_real);
11extern void idle_sleep(int secs);
12extern void enable_timer(void);
13extern void prepare_timer(void * ptr);
14extern void disable_timer(void);
15extern unsigned long time_lock(void);
16extern void time_unlock(unsigned long);
17extern void user_time_init(void);
18
19#endif
diff --git a/arch/um/kernel/tt/include/debug.h b/arch/um/include/tt/debug.h
index 738435461e13..9778fa838296 100644
--- a/arch/um/kernel/tt/include/debug.h
+++ b/arch/um/include/tt/debug.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
3 * Lars Brinkhoff. 3 * Lars Brinkhoff.
4 * Licensed under the GPL 4 * Licensed under the GPL
diff --git a/arch/um/include/tt/mmu-tt.h b/arch/um/include/tt/mmu-tt.h
new file mode 100644
index 000000000000..572a78b22587
--- /dev/null
+++ b/arch/um/include/tt/mmu-tt.h
@@ -0,0 +1,12 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MMU_H
7#define __TT_MMU_H
8
9struct mmu_context_tt {
10};
11
12#endif
diff --git a/arch/um/include/tt/mode-tt.h b/arch/um/include/tt/mode-tt.h
new file mode 100644
index 000000000000..2823cd56eea2
--- /dev/null
+++ b/arch/um/include/tt/mode-tt.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_TT_H__
7#define __MODE_TT_H__
8
9#include "sysdep/ptrace.h"
10
11enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
12
13extern int tracing_pid;
14
15extern int tracer(int (*init_proc)(void *), void *sp);
16extern void sig_handler_common_tt(int sig, void *sc);
17extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
18extern void reboot_tt(void);
19extern void halt_tt(void);
20extern int is_tracer_winch(int pid, int fd, void *data);
21extern void kill_off_processes_tt(void);
22
23#endif
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
new file mode 100644
index 000000000000..efa0012550d0
--- /dev/null
+++ b/arch/um/include/tt/mode_kern_tt.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MODE_KERN_H__
7#define __TT_MODE_KERN_H__
8
9#include "linux/sched.h"
10#include "asm/page.h"
11#include "asm/ptrace.h"
12#include "asm/uaccess.h"
13
14extern void switch_to_tt(void *prev, void *next);
15extern void flush_thread_tt(void);
16extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
17 unsigned long esp);
18extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
19 unsigned long stack_top, struct task_struct *p,
20 struct pt_regs *regs);
21extern void release_thread_tt(struct task_struct *task);
22extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
23extern void init_idle_tt(void);
24extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
25extern void flush_tlb_kernel_vm_tt(void);
26extern void __flush_tlb_one_tt(unsigned long addr);
27extern void flush_tlb_range_tt(struct vm_area_struct *vma,
28 unsigned long start, unsigned long end);
29extern void flush_tlb_mm_tt(struct mm_struct *mm);
30extern void force_flush_all_tt(void);
31extern long execute_syscall_tt(void *r);
32extern void before_mem_tt(unsigned long brk_start);
33extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
34 unsigned long *task_size_out);
35extern int start_uml_tt(void);
36extern int external_pid_tt(struct task_struct *task);
37extern int thread_pid_tt(struct task_struct *task);
38
39#define kmem_end_tt (host_task_size - ABOVE_KMEM)
40
41#endif
diff --git a/arch/um/kernel/tt/include/tt.h b/arch/um/include/tt/tt.h
index c667b67af405..808521980186 100644
--- a/arch/um/kernel/tt/include/tt.h
+++ b/arch/um/include/tt/tt.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -34,13 +34,3 @@ extern long execute_syscall_tt(void *r);
34 34
35#endif 35#endif
36 36
37/*
38 * Overrides for Emacs so that we follow Linus's tabbing style.
39 * Emacs will notice this stuff at the end of the file and automatically
40 * adjust the settings for this buffer only. This must remain at the end
41 * of the file.
42 * ---------------------------------------------------------------------------
43 * Local variables:
44 * c-file-style: "linux"
45 * End:
46 */
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
index b9bfe9c481c4..b19645f32f24 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/include/tt/uaccess-tt.h
@@ -46,14 +46,3 @@ extern int clear_user_tt(void __user *mem, int len);
46extern int strnlen_user_tt(const void __user *str, int len); 46extern int strnlen_user_tt(const void __user *str, int len);
47 47
48#endif 48#endif
49
50/*
51 * Overrides for Emacs so that we follow Linus's tabbing style.
52 * Emacs will notice this stuff at the end of the file and automatically
53 * adjust the settings for this buffer only. This must remain at the end
54 * of the file.
55 * ---------------------------------------------------------------------------
56 * Local variables:
57 * c-file-style: "linux"
58 * End:
59 */
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index 0f865ef46918..91b0ac4ad88c 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -18,6 +18,7 @@ extern int open_gdb_chan(void);
18extern unsigned long strlcpy(char *, const char *, unsigned long); 18extern unsigned long strlcpy(char *, const char *, unsigned long);
19extern unsigned long strlcat(char *, const char *, unsigned long); 19extern unsigned long strlcat(char *, const char *, unsigned long);
20extern void *um_vmalloc(int size); 20extern void *um_vmalloc(int size);
21extern void *um_vmalloc_atomic(int size);
21extern void vfree(void *ptr); 22extern void vfree(void *ptr);
22 23
23#endif 24#endif
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index c1dbd77b073f..a6f1f176cf84 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -44,10 +44,6 @@ extern unsigned long brk_start;
44extern int pty_output_sigio; 44extern int pty_output_sigio;
45extern int pty_close_sigio; 45extern int pty_close_sigio;
46 46
47extern void stop(void);
48extern void stack_protections(unsigned long address);
49extern void task_protections(unsigned long address);
50extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
51extern void *add_signal_handler(int sig, void (*handler)(int)); 47extern void *add_signal_handler(int sig, void (*handler)(int));
52extern int linux_main(int argc, char **argv); 48extern int linux_main(int argc, char **argv);
53extern void set_cmdline(char *cmd); 49extern void set_cmdline(char *cmd);
@@ -55,8 +51,6 @@ extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
55extern int get_pty(void); 51extern int get_pty(void);
56extern void *um_kmalloc(int size); 52extern void *um_kmalloc(int size);
57extern int switcheroo(int fd, int prot, void *from, void *to, int size); 53extern int switcheroo(int fd, int prot, void *from, void *to, int size);
58extern void setup_machinename(char *machine_out);
59extern void setup_hostinfo(void);
60extern void do_exec(int old_pid, int new_pid); 54extern void do_exec(int old_pid, int new_pid);
61extern void tracer_panic(char *msg, ...); 55extern void tracer_panic(char *msg, ...);
62extern int detach(int pid, int sig); 56extern int detach(int pid, int sig);
@@ -70,18 +64,6 @@ extern int cpu_feature(char *what, char *buf, int len);
70extern int arch_handle_signal(int sig, union uml_pt_regs *regs); 64extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
71extern int arch_fixup(unsigned long address, void *sc_ptr); 65extern int arch_fixup(unsigned long address, void *sc_ptr);
72extern void arch_init_thread(void); 66extern void arch_init_thread(void);
73extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
74extern int raw(int fd); 67extern int raw(int fd);
75 68
76#endif 69#endif
77
78/*
79 * Overrides for Emacs so that we follow Linus's tabbing style.
80 * Emacs will notice this stuff at the end of the file and automatically
81 * adjust the settings for this buffer only. This must remain at the end
82 * of the file.
83 * ---------------------------------------------------------------------------
84 * Local variables:
85 * c-file-style: "linux"
86 * End:
87 */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 193cc2b7448d..693018ba80f1 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -9,9 +9,8 @@ clean-files :=
9obj-y = config.o exec_kern.o exitcode.o \ 9obj-y = config.o exec_kern.o exitcode.o \
10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ 10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ 11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
12 signal_kern.o smp.o syscall_kern.o sysrq.o time.o \ 12 signal_kern.o smp.o syscall_kern.o sysrq.o \
13 time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o \ 13 time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o
14 user_util.o
15 14
16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 15obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
17obj-$(CONFIG_GPROF) += gprof_syms.o 16obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -24,7 +23,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
24 23
25user-objs-$(CONFIG_TTY_LOG) += tty_log.o 24user-objs-$(CONFIG_TTY_LOG) += tty_log.o
26 25
27USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o 26USER_OBJS := $(user-objs-y) config.o tty_log.o
28 27
29include arch/um/scripts/Makefile.rules 28include arch/um/scripts/Makefile.rules
30 29
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index efd222ffe20e..569fe8b9b053 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -17,7 +17,6 @@
17#include "irq_user.h" 17#include "irq_user.h"
18#include "tlb.h" 18#include "tlb.h"
19#include "os.h" 19#include "os.h"
20#include "time_user.h"
21#include "choose-mode.h" 20#include "choose-mode.h"
22#include "mode_kern.h" 21#include "mode_kern.h"
23 22
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 7f13b85d2656..3113cab8675e 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -39,7 +39,6 @@
39#include "init.h" 39#include "init.h"
40#include "irq_user.h" 40#include "irq_user.h"
41#include "mem_user.h" 41#include "mem_user.h"
42#include "time_user.h"
43#include "tlb.h" 42#include "tlb.h"
44#include "frame_kern.h" 43#include "frame_kern.h"
45#include "sigcontext.h" 44#include "sigcontext.h"
@@ -288,17 +287,27 @@ EXPORT_SYMBOL(disable_hlt);
288 287
289void *um_kmalloc(int size) 288void *um_kmalloc(int size)
290{ 289{
291 return(kmalloc(size, GFP_KERNEL)); 290 return kmalloc(size, GFP_KERNEL);
292} 291}
293 292
294void *um_kmalloc_atomic(int size) 293void *um_kmalloc_atomic(int size)
295{ 294{
296 return(kmalloc(size, GFP_ATOMIC)); 295 return kmalloc(size, GFP_ATOMIC);
297} 296}
298 297
299void *um_vmalloc(int size) 298void *um_vmalloc(int size)
300{ 299{
301 return(vmalloc(size)); 300 return vmalloc(size);
301}
302
303void *um_vmalloc_atomic(int size)
304{
305 return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
306}
307
308int __cant_sleep(void) {
309 return in_atomic() || irqs_disabled() || in_interrupt();
310 /* Is in_interrupt() really needed? */
302} 311}
303 312
304unsigned long get_fault_addr(void) 313unsigned long get_fault_addr(void)
@@ -370,11 +379,6 @@ int smp_sigio_handler(void)
370 return(0); 379 return(0);
371} 380}
372 381
373int um_in_interrupt(void)
374{
375 return(in_interrupt());
376}
377
378int cpu(void) 382int cpu(void)
379{ 383{
380 return(current_thread->cpu); 384 return(current_thread->cpu);
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 62e5cfdf2188..f7b18e157d35 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -337,70 +337,103 @@ int ignore_sigio_fd(int fd)
337 return(err); 337 return(err);
338} 338}
339 339
340static int setup_initial_poll(int fd) 340static struct pollfd* setup_initial_poll(int fd)
341{ 341{
342 struct pollfd *p; 342 struct pollfd *p;
343 343
344 p = um_kmalloc_atomic(sizeof(struct pollfd)); 344 p = um_kmalloc(sizeof(struct pollfd));
345 if(p == NULL){ 345 if (p == NULL) {
346 printk("setup_initial_poll : failed to allocate poll\n"); 346 printk("setup_initial_poll : failed to allocate poll\n");
347 return(-1); 347 return NULL;
348 } 348 }
349 *p = ((struct pollfd) { .fd = fd, 349 *p = ((struct pollfd) { .fd = fd,
350 .events = POLLIN, 350 .events = POLLIN,
351 .revents = 0 }); 351 .revents = 0 });
352 current_poll = ((struct pollfds) { .poll = p, 352 return p;
353 .used = 1,
354 .size = 1 });
355 return(0);
356} 353}
357 354
358void write_sigio_workaround(void) 355void write_sigio_workaround(void)
359{ 356{
360 unsigned long stack; 357 unsigned long stack;
358 struct pollfd *p;
361 int err; 359 int err;
360 int l_write_sigio_fds[2];
361 int l_sigio_private[2];
362 int l_write_sigio_pid;
362 363
364 /* We call this *tons* of times - and most ones we must just fail. */
363 sigio_lock(); 365 sigio_lock();
364 if(write_sigio_pid != -1) 366 l_write_sigio_pid = write_sigio_pid;
365 goto out; 367 sigio_unlock();
366 368
367 err = os_pipe(write_sigio_fds, 1, 1); 369 if (l_write_sigio_pid != -1)
370 return;
371
372 err = os_pipe(l_write_sigio_fds, 1, 1);
368 if(err < 0){ 373 if(err < 0){
369 printk("write_sigio_workaround - os_pipe 1 failed, " 374 printk("write_sigio_workaround - os_pipe 1 failed, "
370 "err = %d\n", -err); 375 "err = %d\n", -err);
371 goto out; 376 return;
372 } 377 }
373 err = os_pipe(sigio_private, 1, 1); 378 err = os_pipe(l_sigio_private, 1, 1);
374 if(err < 0){ 379 if(err < 0){
375 printk("write_sigio_workaround - os_pipe 2 failed, " 380 printk("write_sigio_workaround - os_pipe 1 failed, "
376 "err = %d\n", -err); 381 "err = %d\n", -err);
377 goto out_close1; 382 goto out_close1;
378 } 383 }
379 if(setup_initial_poll(sigio_private[1])) 384
385 p = setup_initial_poll(l_sigio_private[1]);
386 if(!p)
380 goto out_close2; 387 goto out_close2;
381 388
382 write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 389 sigio_lock();
390
391 /* Did we race? Don't try to optimize this, please, it's not so likely
392 * to happen, and no more than once at the boot. */
393 if(write_sigio_pid != -1)
394 goto out_unlock;
395
396 write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
383 CLONE_FILES | CLONE_VM, &stack, 0); 397 CLONE_FILES | CLONE_VM, &stack, 0);
384 398
385 if(write_sigio_pid < 0) goto out_close2; 399 if (write_sigio_pid < 0)
400 goto out_clear;
386 401
387 if(write_sigio_irq(write_sigio_fds[0])) 402 if (write_sigio_irq(l_write_sigio_fds[0]))
388 goto out_kill; 403 goto out_kill;
389 404
390 out: 405 /* Success, finally. */
406 memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
407 memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
408
409 current_poll = ((struct pollfds) { .poll = p,
410 .used = 1,
411 .size = 1 });
412
391 sigio_unlock(); 413 sigio_unlock();
392 return; 414 return;
393 415
394 out_kill: 416 out_kill:
395 os_kill_process(write_sigio_pid, 1); 417 l_write_sigio_pid = write_sigio_pid;
396 write_sigio_pid = -1; 418 write_sigio_pid = -1;
419 sigio_unlock();
420 /* Going to call waitpid, avoid holding the lock. */
421 os_kill_process(l_write_sigio_pid, 1);
422 goto out_free;
423
424 out_clear:
425 write_sigio_pid = -1;
426 out_unlock:
427 sigio_unlock();
428 out_free:
429 kfree(p);
397 out_close2: 430 out_close2:
398 os_close_file(sigio_private[0]); 431 os_close_file(l_sigio_private[0]);
399 os_close_file(sigio_private[1]); 432 os_close_file(l_sigio_private[1]);
400 out_close1: 433 out_close1:
401 os_close_file(write_sigio_fds[0]); 434 os_close_file(l_write_sigio_fds[0]);
402 os_close_file(write_sigio_fds[1]); 435 os_close_file(l_write_sigio_fds[1]);
403 sigio_unlock(); 436 return;
404} 437}
405 438
406int read_sigio_fd(int fd) 439int read_sigio_fd(int fd)
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
index 7b0e0e81c161..da17b7541e08 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal_kern.c
@@ -99,31 +99,46 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
99 return err; 99 return err;
100} 100}
101 101
102static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset) 102static int kern_do_signal(struct pt_regs *regs)
103{ 103{
104 struct k_sigaction ka_copy; 104 struct k_sigaction ka_copy;
105 siginfo_t info; 105 siginfo_t info;
106 sigset_t *oldset;
106 int sig, handled_sig = 0; 107 int sig, handled_sig = 0;
107 108
109 if (test_thread_flag(TIF_RESTORE_SIGMASK))
110 oldset = &current->saved_sigmask;
111 else
112 oldset = &current->blocked;
113
108 while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ 114 while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){
109 handled_sig = 1; 115 handled_sig = 1;
110 /* Whee! Actually deliver the signal. */ 116 /* Whee! Actually deliver the signal. */
111 if(!handle_signal(regs, sig, &ka_copy, &info, oldset)) 117 if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){
118 /* a signal was successfully delivered; the saved
119 * sigmask will have been stored in the signal frame,
120 * and will be restored by sigreturn, so we can simply
121 * clear the TIF_RESTORE_SIGMASK flag */
122 if (test_thread_flag(TIF_RESTORE_SIGMASK))
123 clear_thread_flag(TIF_RESTORE_SIGMASK);
112 break; 124 break;
125 }
113 } 126 }
114 127
115 /* Did we come from a system call? */ 128 /* Did we come from a system call? */
116 if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ 129 if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){
117 /* Restart the system call - no handlers present */ 130 /* Restart the system call - no handlers present */
118 if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND || 131 switch(PT_REGS_SYSCALL_RET(regs)){
119 PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS || 132 case -ERESTARTNOHAND:
120 PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){ 133 case -ERESTARTSYS:
134 case -ERESTARTNOINTR:
121 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 135 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
122 PT_REGS_RESTART_SYSCALL(regs); 136 PT_REGS_RESTART_SYSCALL(regs);
123 } 137 break;
124 else if(PT_REGS_SYSCALL_RET(regs) == -ERESTART_RESTARTBLOCK){ 138 case -ERESTART_RESTARTBLOCK:
125 PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall; 139 PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall;
126 PT_REGS_RESTART_SYSCALL(regs); 140 PT_REGS_RESTART_SYSCALL(regs);
141 break;
127 } 142 }
128 } 143 }
129 144
@@ -137,12 +152,19 @@ static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset)
137 if(current->ptrace & PT_DTRACE) 152 if(current->ptrace & PT_DTRACE)
138 current->thread.singlestep_syscall = 153 current->thread.singlestep_syscall =
139 is_syscall(PT_REGS_IP(&current->thread.regs)); 154 is_syscall(PT_REGS_IP(&current->thread.regs));
155
156 /* if there's no signal to deliver, we just put the saved sigmask
157 * back */
158 if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) {
159 clear_thread_flag(TIF_RESTORE_SIGMASK);
160 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
161 }
140 return(handled_sig); 162 return(handled_sig);
141} 163}
142 164
143int do_signal(void) 165int do_signal(void)
144{ 166{
145 return(kern_do_signal(&current->thread.regs, &current->blocked)); 167 return(kern_do_signal(&current->thread.regs));
146} 168}
147 169
148/* 170/*
@@ -150,63 +172,20 @@ int do_signal(void)
150 */ 172 */
151long sys_sigsuspend(int history0, int history1, old_sigset_t mask) 173long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
152{ 174{
153 sigset_t saveset;
154
155 mask &= _BLOCKABLE; 175 mask &= _BLOCKABLE;
156 spin_lock_irq(&current->sighand->siglock); 176 spin_lock_irq(&current->sighand->siglock);
157 saveset = current->blocked; 177 current->saved_sigmask = current->blocked;
158 siginitset(&current->blocked, mask); 178 siginitset(&current->blocked, mask);
159 recalc_sigpending(); 179 recalc_sigpending();
160 spin_unlock_irq(&current->sighand->siglock); 180 spin_unlock_irq(&current->sighand->siglock);
161 181
162 PT_REGS_SYSCALL_RET(&current->thread.regs) = -EINTR; 182 current->state = TASK_INTERRUPTIBLE;
163 while (1) { 183 schedule();
164 current->state = TASK_INTERRUPTIBLE; 184 set_thread_flag(TIF_RESTORE_SIGMASK);
165 schedule(); 185 return -ERESTARTNOHAND;
166 if(kern_do_signal(&current->thread.regs, &saveset))
167 return(-EINTR);
168 }
169}
170
171long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
172{
173 sigset_t saveset, newset;
174
175 /* XXX: Don't preclude handling different sized sigset_t's. */
176 if (sigsetsize != sizeof(sigset_t))
177 return -EINVAL;
178
179 if (copy_from_user(&newset, unewset, sizeof(newset)))
180 return -EFAULT;
181 sigdelsetmask(&newset, ~_BLOCKABLE);
182
183 spin_lock_irq(&current->sighand->siglock);
184 saveset = current->blocked;
185 current->blocked = newset;
186 recalc_sigpending();
187 spin_unlock_irq(&current->sighand->siglock);
188
189 PT_REGS_SYSCALL_RET(&current->thread.regs) = -EINTR;
190 while (1) {
191 current->state = TASK_INTERRUPTIBLE;
192 schedule();
193 if (kern_do_signal(&current->thread.regs, &saveset))
194 return(-EINTR);
195 }
196} 186}
197 187
198long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 188long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
199{ 189{
200 return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs))); 190 return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
201} 191}
202
203/*
204 * Overrides for Emacs so that we follow Linus's tabbing style.
205 * Emacs will notice this stuff at the end of the file and automatically
206 * adjust the settings for this buffer only. This must remain at the end
207 * of the file.
208 * ---------------------------------------------------------------------------
209 * Local variables:
210 * c-file-style: "linux"
211 * End:
212 */
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 7a9fc16d71d4..57181a920d48 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -1,12 +1,12 @@
1# 1#
2# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) 2# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ 6obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \
7 syscall.o tlb.o uaccess.o 7 syscall.o tlb.o uaccess.o
8 8
9USER_OBJS := process.o clone.o 9USER_OBJS := clone.o
10 10
11include arch/um/scripts/Makefile.rules 11include arch/um/scripts/Makefile.rules
12 12
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
deleted file mode 100644
index 44110c521e49..000000000000
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_MMU_H
7#define __SKAS_MMU_H
8
9#include "linux/config.h"
10#include "mm_id.h"
11#include "asm/ldt.h"
12
13struct mmu_context_skas {
14 struct mm_id id;
15 unsigned long last_page_table;
16#ifdef CONFIG_3_LEVEL_PGTABLES
17 unsigned long last_pmd;
18#endif
19 uml_ldt_t ldt;
20};
21
22extern void switch_mm_skas(struct mm_id * mm_idp);
23
24#endif
25
26/*
27 * Overrides for Emacs so that we follow Linus's tabbing style.
28 * Emacs will notice this stuff at the end of the file and automatically
29 * adjust the settings for this buffer only. This must remain at the end
30 * of the file.
31 * ---------------------------------------------------------------------------
32 * Local variables:
33 * c-file-style: "linux"
34 * End:
35 */
diff --git a/arch/um/kernel/skas/include/mode-skas.h b/arch/um/kernel/skas/include/mode-skas.h
deleted file mode 100644
index bcd26a6a3888..000000000000
--- a/arch/um/kernel/skas/include/mode-skas.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_SKAS_H__
7#define __MODE_SKAS_H__
8
9#include <sysdep/ptrace.h>
10
11extern unsigned long exec_regs[];
12extern unsigned long exec_fp_regs[];
13extern unsigned long exec_fpx_regs[];
14extern int have_fpx_regs;
15
16extern void sig_handler_common_skas(int sig, void *sc_ptr);
17extern void halt_skas(void);
18extern void reboot_skas(void);
19extern void kill_off_processes_skas(void);
20extern int is_skas_winch(int pid, int fd, void *data);
21
22#endif
23
24/*
25 * Overrides for Emacs so that we follow Linus's tabbing style.
26 * Emacs will notice this stuff at the end of the file and automatically
27 * adjust the settings for this buffer only. This must remain at the end
28 * of the file.
29 * ---------------------------------------------------------------------------
30 * Local variables:
31 * c-file-style: "linux"
32 * End:
33 */
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
deleted file mode 100644
index 01d489de3986..000000000000
--- a/arch/um/kernel/skas/include/skas.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_H
7#define __SKAS_H
8
9#include "mm_id.h"
10#include "sysdep/ptrace.h"
11
12extern int userspace_pid[];
13extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
14extern int skas_needs_stub;
15
16extern void switch_threads(void *me, void *next);
17extern void thread_wait(void *sw, void *fb);
18extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
19 void (*handler)(int));
20extern int start_idle_thread(void *stack, void *switch_buf_ptr,
21 void **fork_buf_ptr);
22extern int user_thread(unsigned long stack, int flags);
23extern void userspace(union uml_pt_regs *regs);
24extern void new_thread_proc(void *stack, void (*handler)(int sig));
25extern void new_thread_handler(int sig);
26extern void handle_syscall(union uml_pt_regs *regs);
27extern int map(struct mm_id * mm_idp, unsigned long virt,
28 unsigned long len, int r, int w, int x, int phys_fd,
29 unsigned long long offset, int done, void **data);
30extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len,
31 int done, void **data);
32extern int protect(struct mm_id * mm_idp, unsigned long addr,
33 unsigned long len, int r, int w, int x, int done,
34 void **data);
35extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
36extern int new_mm(int from, unsigned long stack);
37extern int start_userspace(unsigned long stub_stack);
38extern int copy_context_skas0(unsigned long stack, int pid);
39extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
40extern long execute_syscall_skas(void *r);
41extern unsigned long current_stub_stack(void);
42extern long run_syscall_stub(struct mm_id * mm_idp,
43 int syscall, unsigned long *args, long expected,
44 void **addr, int done);
45extern long syscall_stub_data(struct mm_id * mm_idp,
46 unsigned long *data, int data_count,
47 void **addr, void **stub_addr);
48
49#endif
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 677871f1b37c..c5c9885a8297 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -78,7 +78,7 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
78 struct mmu_context_skas *from_mm = NULL; 78 struct mmu_context_skas *from_mm = NULL;
79 struct mmu_context_skas *to_mm = &mm->context.skas; 79 struct mmu_context_skas *to_mm = &mm->context.skas;
80 unsigned long stack = 0; 80 unsigned long stack = 0;
81 int from_fd, ret = -ENOMEM; 81 int ret = -ENOMEM;
82 82
83 if(skas_needs_stub){ 83 if(skas_needs_stub){
84 stack = get_zeroed_page(GFP_KERNEL); 84 stack = get_zeroed_page(GFP_KERNEL);
@@ -108,11 +108,7 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
108 from_mm = &current->mm->context.skas; 108 from_mm = &current->mm->context.skas;
109 109
110 if(proc_mm){ 110 if(proc_mm){
111 if(from_mm) 111 ret = new_mm(stack);
112 from_fd = from_mm->id.u.mm_fd;
113 else from_fd = -1;
114
115 ret = new_mm(from_fd, stack);
116 if(ret < 0){ 112 if(ret < 0){
117 printk("init_new_context_skas - new_mm failed, " 113 printk("init_new_context_skas - new_mm failed, "
118 "errno = %d\n", ret); 114 "errno = %d\n", ret);
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 3b3955d84407..eea1c9c4bb0f 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -18,7 +18,6 @@
18#include <asm/types.h> 18#include <asm/types.h>
19#include "user.h" 19#include "user.h"
20#include "ptrace_user.h" 20#include "ptrace_user.h"
21#include "time_user.h"
22#include "sysdep/ptrace.h" 21#include "sysdep/ptrace.h"
23#include "user_util.h" 22#include "user_util.h"
24#include "kern_util.h" 23#include "kern_util.h"
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index dc41c6dc2f34..3f70a2e12f06 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -13,14 +13,12 @@
13#include "asm/uaccess.h" 13#include "asm/uaccess.h"
14#include "asm/atomic.h" 14#include "asm/atomic.h"
15#include "kern_util.h" 15#include "kern_util.h"
16#include "time_user.h"
17#include "skas.h" 16#include "skas.h"
18#include "os.h" 17#include "os.h"
19#include "user_util.h" 18#include "user_util.h"
20#include "tlb.h" 19#include "tlb.h"
21#include "kern.h" 20#include "kern.h"
22#include "mode.h" 21#include "mode.h"
23#include "proc_mm.h"
24#include "registers.h" 22#include "registers.h"
25 23
26void switch_to_skas(void *prev, void *next) 24void switch_to_skas(void *prev, void *next)
@@ -34,7 +32,7 @@ void switch_to_skas(void *prev, void *next)
34 if(current->pid == 0) 32 if(current->pid == 0)
35 switch_timers(0); 33 switch_timers(0);
36 34
37 switch_threads(&from->thread.mode.skas.switch_buf, 35 switch_threads(&from->thread.mode.skas.switch_buf,
38 to->thread.mode.skas.switch_buf); 36 to->thread.mode.skas.switch_buf);
39 37
40 if(current->pid == 0) 38 if(current->pid == 0)
@@ -50,8 +48,8 @@ void new_thread_handler(int sig)
50 48
51 fn = current->thread.request.u.thread.proc; 49 fn = current->thread.request.u.thread.proc;
52 arg = current->thread.request.u.thread.arg; 50 arg = current->thread.request.u.thread.arg;
53 change_sig(SIGUSR1, 1); 51 os_usr1_signal(1);
54 thread_wait(&current->thread.mode.skas.switch_buf, 52 thread_wait(&current->thread.mode.skas.switch_buf,
55 current->thread.mode.skas.fork_buf); 53 current->thread.mode.skas.fork_buf);
56 54
57 if(current->thread.prev_sched != NULL) 55 if(current->thread.prev_sched != NULL)
@@ -82,8 +80,8 @@ void release_thread_skas(struct task_struct *task)
82 80
83void fork_handler(int sig) 81void fork_handler(int sig)
84{ 82{
85 change_sig(SIGUSR1, 1); 83 os_usr1_signal(1);
86 thread_wait(&current->thread.mode.skas.switch_buf, 84 thread_wait(&current->thread.mode.skas.switch_buf,
87 current->thread.mode.skas.fork_buf); 85 current->thread.mode.skas.fork_buf);
88 86
89 force_flush_all(); 87 force_flush_all();
@@ -93,13 +91,13 @@ void fork_handler(int sig)
93 schedule_tail(current->thread.prev_sched); 91 schedule_tail(current->thread.prev_sched);
94 current->thread.prev_sched = NULL; 92 current->thread.prev_sched = NULL;
95 93
96 /* Handle any immediate reschedules or signals */ 94/* Handle any immediate reschedules or signals */
97 interrupt_end(); 95 interrupt_end();
98 userspace(&current->thread.regs.regs); 96 userspace(&current->thread.regs.regs);
99} 97}
100 98
101int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, 99int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
102 unsigned long stack_top, struct task_struct * p, 100 unsigned long stack_top, struct task_struct * p,
103 struct pt_regs *regs) 101 struct pt_regs *regs)
104{ 102{
105 void (*handler)(int); 103 void (*handler)(int);
@@ -123,27 +121,14 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
123 return(0); 121 return(0);
124} 122}
125 123
126extern void map_stub_pages(int fd, unsigned long code, 124int new_mm(unsigned long stack)
127 unsigned long data, unsigned long stack);
128int new_mm(int from, unsigned long stack)
129{ 125{
130 struct proc_mm_op copy; 126 int fd;
131 int n, fd;
132 127
133 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); 128 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
134 if(fd < 0) 129 if(fd < 0)
135 return(fd); 130 return(fd);
136 131
137 if(from != -1){
138 copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
139 .u =
140 { .copy_segments = from } } );
141 n = os_write_file(fd, &copy, sizeof(copy));
142 if(n != sizeof(copy))
143 printk("new_mm : /proc/mm copy_segments failed, "
144 "err = %d\n", -n);
145 }
146
147 if(skas_needs_stub) 132 if(skas_needs_stub)
148 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); 133 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
149 134
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index a5a47528dec7..5992c3257167 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -13,7 +13,7 @@
13#include "asm/pgtable.h" 13#include "asm/pgtable.h"
14#include "asm/uaccess.h" 14#include "asm/uaccess.h"
15#include "kern_util.h" 15#include "kern_util.h"
16#include "user_util.h" 16#include "os.h"
17 17
18extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 18extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
19 pte_t *pte_out); 19 pte_t *pte_out);
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 1429c131879d..1731d90e6850 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -25,12 +25,12 @@ int record_syscall_start(int syscall)
25 syscall_record[index].syscall = syscall; 25 syscall_record[index].syscall = syscall;
26 syscall_record[index].pid = current_pid(); 26 syscall_record[index].pid = current_pid();
27 syscall_record[index].result = 0xdeadbeef; 27 syscall_record[index].result = 0xdeadbeef;
28 syscall_record[index].start = os_usecs(); 28 syscall_record[index].start = os_nsecs();
29 return(index); 29 return(index);
30} 30}
31 31
32void record_syscall_end(int index, long result) 32void record_syscall_end(int index, long result)
33{ 33{
34 syscall_record[index].result = result; 34 syscall_record[index].result = result;
35 syscall_record[index].end = os_usecs(); 35 syscall_record[index].end = os_nsecs();
36} 36}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 020ca79b8d33..3c7626cdba4b 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -13,12 +13,12 @@
13#include "linux/interrupt.h" 13#include "linux/interrupt.h"
14#include "linux/init.h" 14#include "linux/init.h"
15#include "linux/delay.h" 15#include "linux/delay.h"
16#include "linux/hrtimer.h"
16#include "asm/irq.h" 17#include "asm/irq.h"
17#include "asm/param.h" 18#include "asm/param.h"
18#include "asm/current.h" 19#include "asm/current.h"
19#include "kern_util.h" 20#include "kern_util.h"
20#include "user_util.h" 21#include "user_util.h"
21#include "time_user.h"
22#include "mode.h" 22#include "mode.h"
23#include "os.h" 23#include "os.h"
24 24
@@ -39,7 +39,7 @@ unsigned long long sched_clock(void)
39int timer_irq_inited = 0; 39int timer_irq_inited = 0;
40 40
41static int first_tick; 41static int first_tick;
42static unsigned long long prev_usecs; 42static unsigned long long prev_nsecs;
43#ifdef CONFIG_UML_REAL_TIME_CLOCK 43#ifdef CONFIG_UML_REAL_TIME_CLOCK
44static long long delta; /* Deviation per interval */ 44static long long delta; /* Deviation per interval */
45#endif 45#endif
@@ -58,23 +58,23 @@ void timer_irq(union uml_pt_regs *regs)
58 if(first_tick){ 58 if(first_tick){
59#ifdef CONFIG_UML_REAL_TIME_CLOCK 59#ifdef CONFIG_UML_REAL_TIME_CLOCK
60 /* We've had 1 tick */ 60 /* We've had 1 tick */
61 unsigned long long usecs = os_usecs(); 61 unsigned long long nsecs = os_nsecs();
62 62
63 delta += usecs - prev_usecs; 63 delta += nsecs - prev_nsecs;
64 prev_usecs = usecs; 64 prev_nsecs = nsecs;
65 65
66 /* Protect against the host clock being set backwards */ 66 /* Protect against the host clock being set backwards */
67 if(delta < 0) 67 if(delta < 0)
68 delta = 0; 68 delta = 0;
69 69
70 ticks += (delta * HZ) / MILLION; 70 ticks += (delta * HZ) / BILLION;
71 delta -= (ticks * MILLION) / HZ; 71 delta -= (ticks * BILLION) / HZ;
72#else 72#else
73 ticks = 1; 73 ticks = 1;
74#endif 74#endif
75 } 75 }
76 else { 76 else {
77 prev_usecs = os_usecs(); 77 prev_nsecs = os_nsecs();
78 first_tick = 1; 78 first_tick = 1;
79 } 79 }
80 80
@@ -84,49 +84,102 @@ void timer_irq(union uml_pt_regs *regs)
84 } 84 }
85} 85}
86 86
87void boot_timer_handler(int sig) 87void do_boot_timer_handler(struct sigcontext * sc)
88{ 88{
89 struct pt_regs regs; 89 struct pt_regs regs;
90 90
91 CHOOSE_MODE((void) 91 CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc),
92 (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
93 (void) (regs.regs.skas.is_user = 0)); 92 (void) (regs.regs.skas.is_user = 0));
94 do_timer(&regs); 93 do_timer(&regs);
95} 94}
96 95
96static DEFINE_SPINLOCK(timer_spinlock);
97
98static unsigned long long local_offset = 0;
99
100static inline unsigned long long get_time(void)
101{
102 unsigned long long nsecs;
103 unsigned long flags;
104
105 spin_lock_irqsave(&timer_spinlock, flags);
106 nsecs = os_nsecs();
107 nsecs += local_offset;
108 spin_unlock_irqrestore(&timer_spinlock, flags);
109
110 return nsecs;
111}
112
97irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) 113irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
98{ 114{
115 unsigned long long nsecs;
99 unsigned long flags; 116 unsigned long flags;
100 117
101 do_timer(regs); 118 do_timer(regs);
119
102 write_seqlock_irqsave(&xtime_lock, flags); 120 write_seqlock_irqsave(&xtime_lock, flags);
103 timer(); 121 nsecs = get_time() + local_offset;
122 xtime.tv_sec = nsecs / NSEC_PER_SEC;
123 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
104 write_sequnlock_irqrestore(&xtime_lock, flags); 124 write_sequnlock_irqrestore(&xtime_lock, flags);
125
105 return(IRQ_HANDLED); 126 return(IRQ_HANDLED);
106} 127}
107 128
108long um_time(int __user *tloc) 129long um_time(int __user *tloc)
109{ 130{
110 struct timeval now; 131 long ret = get_time() / NSEC_PER_SEC;
111 132
112 do_gettimeofday(&now); 133 if((tloc != NULL) && put_user(ret, tloc))
113 if (tloc) { 134 return -EFAULT;
114 if (put_user(now.tv_sec, tloc)) 135
115 now.tv_sec = -EFAULT; 136 return ret;
116 } 137}
117 return now.tv_sec; 138
139void do_gettimeofday(struct timeval *tv)
140{
141 unsigned long long nsecs = get_time();
142
143 tv->tv_sec = nsecs / NSEC_PER_SEC;
144 /* Careful about calculations here - this was originally done as
145 * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
146 * which gave bogus (> 1000000) values. Dunno why, suspect gcc
147 * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
148 * problem that I missed.
149 */
150 nsecs -= tv->tv_sec * NSEC_PER_SEC;
151 tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC;
152}
153
154static inline void set_time(unsigned long long nsecs)
155{
156 unsigned long long now;
157 unsigned long flags;
158
159 spin_lock_irqsave(&timer_spinlock, flags);
160 now = os_nsecs();
161 local_offset = nsecs - now;
162 spin_unlock_irqrestore(&timer_spinlock, flags);
163
164 clock_was_set();
118} 165}
119 166
120long um_stime(int __user *tptr) 167long um_stime(int __user *tptr)
121{ 168{
122 int value; 169 int value;
123 struct timespec new;
124 170
125 if (get_user(value, tptr)) 171 if (get_user(value, tptr))
126 return -EFAULT; 172 return -EFAULT;
127 new.tv_sec = value; 173
128 new.tv_nsec = 0; 174 set_time((unsigned long long) value * NSEC_PER_SEC);
129 do_settimeofday(&new); 175
176 return 0;
177}
178
179int do_settimeofday(struct timespec *tv)
180{
181 set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec);
182
130 return 0; 183 return 0;
131} 184}
132 185
@@ -134,29 +187,15 @@ void timer_handler(int sig, union uml_pt_regs *regs)
134{ 187{
135 local_irq_disable(); 188 local_irq_disable();
136 irq_enter(); 189 irq_enter();
137 update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), 190 update_process_times(CHOOSE_MODE(
138 (regs)->skas.is_user)); 191 (UPT_SC(regs) && user_context(UPT_SP(regs))),
192 (regs)->skas.is_user));
139 irq_exit(); 193 irq_exit();
140 local_irq_enable(); 194 local_irq_enable();
141 if(current_thread->cpu == 0) 195 if(current_thread->cpu == 0)
142 timer_irq(regs); 196 timer_irq(regs);
143} 197}
144 198
145static DEFINE_SPINLOCK(timer_spinlock);
146
147unsigned long time_lock(void)
148{
149 unsigned long flags;
150
151 spin_lock_irqsave(&timer_spinlock, flags);
152 return(flags);
153}
154
155void time_unlock(unsigned long flags)
156{
157 spin_unlock_irqrestore(&timer_spinlock, flags);
158}
159
160int __init timer_init(void) 199int __init timer_init(void)
161{ 200{
162 int err; 201 int err;
@@ -171,14 +210,3 @@ int __init timer_init(void)
171} 210}
172 211
173__initcall(timer_init); 212__initcall(timer_init);
174
175/*
176 * Overrides for Emacs so that we follow Linus's tabbing style.
177 * Emacs will notice this stuff at the end of the file and automatically
178 * adjust the settings for this buffer only. This must remain at the end
179 * of the file.
180 * ---------------------------------------------------------------------------
181 * Local variables:
182 * c-file-style: "linux"
183 * End:
184 */
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 8f40e4838736..5c1e4cc1c049 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -13,7 +13,6 @@
13#include "user_util.h" 13#include "user_util.h"
14#include "kern_util.h" 14#include "kern_util.h"
15#include "irq_user.h" 15#include "irq_user.h"
16#include "time_user.h"
17#include "mem_user.h" 16#include "mem_user.h"
18#include "os.h" 17#include "os.h"
19#include "tlb.h" 18#include "tlb.h"
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
index 37e22d71a0d9..786e4edd86c5 100644
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -20,6 +20,7 @@
20#include "user_util.h" 20#include "user_util.h"
21#include "tt.h" 21#include "tt.h"
22#include "sysdep/thread.h" 22#include "sysdep/thread.h"
23#include "os.h"
23 24
24extern int debugger_pid; 25extern int debugger_pid;
25extern int debugger_fd; 26extern int debugger_fd;
diff --git a/arch/um/kernel/tt/include/mmu-tt.h b/arch/um/kernel/tt/include/mmu-tt.h
deleted file mode 100644
index 0440510ab3fe..000000000000
--- a/arch/um/kernel/tt/include/mmu-tt.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MMU_H
7#define __TT_MMU_H
8
9struct mmu_context_tt {
10};
11
12#endif
13
14/*
15 * Overrides for Emacs so that we follow Linus's tabbing style.
16 * Emacs will notice this stuff at the end of the file and automatically
17 * adjust the settings for this buffer only. This must remain at the end
18 * of the file.
19 * ---------------------------------------------------------------------------
20 * Local variables:
21 * c-file-style: "linux"
22 * End:
23 */
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 62535303aa27..295c1ac817b3 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -18,7 +18,6 @@
18#include "os.h" 18#include "os.h"
19#include "kern.h" 19#include "kern.h"
20#include "sigcontext.h" 20#include "sigcontext.h"
21#include "time_user.h"
22#include "mem_user.h" 21#include "mem_user.h"
23#include "tlb.h" 22#include "tlb.h"
24#include "mode.h" 23#include "mode.h"
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
index 528a5fc8d887..03774427d468 100644
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ b/arch/um/kernel/tt/ptproxy/ptrace.c
@@ -20,6 +20,7 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml
20#include "kern_util.h" 20#include "kern_util.h"
21#include "ptrace_user.h" 21#include "ptrace_user.h"
22#include "tt.h" 22#include "tt.h"
23#include "os.h"
23 24
24long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2, 25long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
25 long arg3, long arg4, pid_t child, int *ret) 26 long arg3, long arg4, pid_t child, int *ret)
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
index a5f0e01e214e..99f178319d03 100644
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ b/arch/um/kernel/tt/ptproxy/sysdep.c
@@ -15,6 +15,7 @@ terms and conditions.
15#include "ptrace_user.h" 15#include "ptrace_user.h"
16#include "user_util.h" 16#include "user_util.h"
17#include "user.h" 17#include "user.h"
18#include "os.h"
18 19
19int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, 20int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
20 long *arg5) 21 long *arg5)
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index a414c529fbcd..b5d9d64d91e4 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -18,7 +18,7 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
18{ 18{
19 struct sigcontext *sc = sc_ptr; 19 struct sigcontext *sc = sc_ptr;
20 struct tt_regs save_regs, *r; 20 struct tt_regs save_regs, *r;
21 int save_errno = errno, is_user; 21 int save_errno = errno, is_user = 0;
22 void (*handler)(int, union uml_pt_regs *); 22 void (*handler)(int, union uml_pt_regs *);
23 23
24 /* This is done because to allow SIGSEGV to be delivered inside a SEGV 24 /* This is done because to allow SIGSEGV to be delivered inside a SEGV
@@ -35,7 +35,8 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
35 GET_FAULTINFO_FROM_SC(r->faultinfo, sc); 35 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
36 } 36 }
37 save_regs = *r; 37 save_regs = *r;
38 is_user = user_context(SC_SP(sc)); 38 if (sc)
39 is_user = user_context(SC_SP(sc));
39 r->sc = sc; 40 r->sc = sc;
40 if(sig != SIGUSR2) 41 if(sig != SIGUSR2)
41 r->syscall = -1; 42 r->syscall = -1;
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 40c7d6b1df68..08a4e628b24c 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -5,12 +5,12 @@
5 5
6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
7 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \ 7 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
8 drivers/ sys-$(SUBARCH)/ 8 util.o drivers/ sys-$(SUBARCH)/
9 9
10obj-$(CONFIG_MODE_SKAS) += skas/ 10obj-$(CONFIG_MODE_SKAS) += skas/
11 11
12USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 12USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
13 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o 13 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o util.o
14 14
15elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 15elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
16CFLAGS_elf_aux.o += -I$(objtree)/arch/um 16CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index 36cc8475bcda..6490a4ff40ac 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -60,7 +60,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
60 60
61 if((stack_out != NULL) && (*stack_out != 0)) 61 if((stack_out != NULL) && (*stack_out != 0))
62 stack = *stack_out; 62 stack = *stack_out;
63 else stack = alloc_stack(0, um_in_interrupt()); 63 else stack = alloc_stack(0, __cant_sleep());
64 if(stack == 0) 64 if(stack == 0)
65 return(-ENOMEM); 65 return(-ENOMEM);
66 66
@@ -124,7 +124,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
124 unsigned long stack, sp; 124 unsigned long stack, sp;
125 int pid, status, err; 125 int pid, status, err;
126 126
127 stack = alloc_stack(stack_order, um_in_interrupt()); 127 stack = alloc_stack(stack_order, __cant_sleep());
128 if(stack == 0) return(-ENOMEM); 128 if(stack == 0) return(-ENOMEM);
129 129
130 sp = stack + (page_size() << stack_order) - sizeof(void *); 130 sp = stack + (page_size() << stack_order) - sizeof(void *);
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 172c8474453c..2878e89a674f 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -16,7 +16,6 @@
16#include "user_util.h" 16#include "user_util.h"
17#include "kern_util.h" 17#include "kern_util.h"
18#include "mem_user.h" 18#include "mem_user.h"
19#include "time_user.h"
20#include "irq_user.h" 19#include "irq_user.h"
21#include "user.h" 20#include "user.h"
22#include "init.h" 21#include "init.h"
@@ -82,20 +81,8 @@ extern void scan_elf_aux( char **envp);
82int main(int argc, char **argv, char **envp) 81int main(int argc, char **argv, char **envp)
83{ 82{
84 char **new_argv; 83 char **new_argv;
85 sigset_t mask;
86 int ret, i, err; 84 int ret, i, err;
87 85
88 /* Enable all signals except SIGIO - in some environments, we can
89 * enter with some signals blocked
90 */
91
92 sigemptyset(&mask);
93 sigaddset(&mask, SIGIO);
94 if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
95 perror("sigprocmask");
96 exit(1);
97 }
98
99#ifdef UML_CONFIG_CMDLINE_ON_HOST 86#ifdef UML_CONFIG_CMDLINE_ON_HOST
100 /* Allocate memory for thread command lines */ 87 /* Allocate memory for thread command lines */
101 if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ 88 if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 39815c6b5e45..7f5e2dac2a35 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -18,6 +18,7 @@
18#include "process.h" 18#include "process.h"
19#include "irq_user.h" 19#include "irq_user.h"
20#include "kern_util.h" 20#include "kern_util.h"
21#include "longjmp.h"
21 22
22#define ARBITRARY_ADDR -1 23#define ARBITRARY_ADDR -1
23#define FAILURE_PID -1 24#define FAILURE_PID -1
@@ -205,24 +206,13 @@ void init_new_thread_signals(int altstack)
205 206
206int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) 207int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
207{ 208{
208 sigjmp_buf buf; 209 sigjmp_buf buf;
209 int n; 210 int n, enable;
210 211
211 *jmp_ptr = &buf; 212 *jmp_ptr = &buf;
212 n = sigsetjmp(buf, 1); 213 n = UML_SIGSETJMP(&buf, enable);
213 if(n != 0) 214 if(n != 0)
214 return(n); 215 return(n);
215 (*fn)(arg); 216 (*fn)(arg);
216 return(0); 217 return(0);
217} 218}
218
219/*
220 * Overrides for Emacs so that we follow Linus's tabbing style.
221 * Emacs will notice this stuff at the end of the file and automatically
222 * adjust the settings for this buffer only. This must remain at the end
223 * of the file.
224 * ---------------------------------------------------------------------------
225 * Local variables:
226 * c-file-style: "linux"
227 * End:
228 */
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index c1f46a0fef13..f11b3124a0c8 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -12,32 +12,66 @@
12#include <string.h> 12#include <string.h>
13#include <sys/mman.h> 13#include <sys/mman.h>
14#include "user_util.h" 14#include "user_util.h"
15#include "kern_util.h"
16#include "user.h" 15#include "user.h"
17#include "signal_kern.h" 16#include "signal_kern.h"
18#include "sysdep/sigcontext.h" 17#include "sysdep/sigcontext.h"
19#include "sysdep/signal.h" 18#include "sysdep/signal.h"
20#include "sigcontext.h" 19#include "sigcontext.h"
21#include "time_user.h"
22#include "mode.h" 20#include "mode.h"
21#include "os.h"
22
23/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
24 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
25 * be able to profile all of UML, not just the non-critical sections. If
26 * profiling is not thread-safe, then that is not my problem. We can disable
27 * profiling when SMP is enabled in that case.
28 */
29#define SIGIO_BIT 0
30#define SIGIO_MASK (1 << SIGIO_BIT)
31
32#define SIGVTALRM_BIT 1
33#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
34
35#define SIGALRM_BIT 2
36#define SIGALRM_MASK (1 << SIGALRM_BIT)
37
38static int signals_enabled = 1;
39static int pending = 0;
23 40
24void sig_handler(ARCH_SIGHDLR_PARAM) 41void sig_handler(ARCH_SIGHDLR_PARAM)
25{ 42{
26 struct sigcontext *sc; 43 struct sigcontext *sc;
44 int enabled;
45
46 /* Must be the first thing that this handler does - x86_64 stores
47 * the sigcontext in %rdx, and we need to save it before it has a
48 * chance to get trashed.
49 */
27 50
28 ARCH_GET_SIGCONTEXT(sc, sig); 51 ARCH_GET_SIGCONTEXT(sc, sig);
52
53 enabled = signals_enabled;
54 if(!enabled && (sig == SIGIO)){
55 pending |= SIGIO_MASK;
56 return;
57 }
58
59 block_signals();
60
29 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, 61 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
30 sig, sc); 62 sig, sc);
63
64 set_signals(enabled);
31} 65}
32 66
33extern int timer_irq_inited; 67extern int timer_irq_inited;
34 68
35void alarm_handler(ARCH_SIGHDLR_PARAM) 69static void real_alarm_handler(int sig, struct sigcontext *sc)
36{ 70{
37 struct sigcontext *sc; 71 if(!timer_irq_inited){
38 72 signals_enabled = 1;
39 ARCH_GET_SIGCONTEXT(sc, sig); 73 return;
40 if(!timer_irq_inited) return; 74 }
41 75
42 if(sig == SIGALRM) 76 if(sig == SIGALRM)
43 switch_timers(0); 77 switch_timers(0);
@@ -47,6 +81,52 @@ void alarm_handler(ARCH_SIGHDLR_PARAM)
47 81
48 if(sig == SIGALRM) 82 if(sig == SIGALRM)
49 switch_timers(1); 83 switch_timers(1);
84
85}
86
87void alarm_handler(ARCH_SIGHDLR_PARAM)
88{
89 struct sigcontext *sc;
90 int enabled;
91
92 ARCH_GET_SIGCONTEXT(sc, sig);
93
94 enabled = signals_enabled;
95 if(!signals_enabled){
96 if(sig == SIGVTALRM)
97 pending |= SIGVTALRM_MASK;
98 else pending |= SIGALRM_MASK;
99
100 return;
101 }
102
103 block_signals();
104
105 real_alarm_handler(sig, sc);
106 set_signals(enabled);
107}
108
109extern void do_boot_timer_handler(struct sigcontext * sc);
110
111void boot_timer_handler(ARCH_SIGHDLR_PARAM)
112{
113 struct sigcontext *sc;
114 int enabled;
115
116 ARCH_GET_SIGCONTEXT(sc, sig);
117
118 enabled = signals_enabled;
119 if(!enabled){
120 if(sig == SIGVTALRM)
121 pending |= SIGVTALRM_MASK;
122 else pending |= SIGALRM_MASK;
123 return;
124 }
125
126 block_signals();
127
128 do_boot_timer_handler(sc);
129 set_signals(enabled);
50} 130}
51 131
52void set_sigstack(void *sig_stack, int size) 132void set_sigstack(void *sig_stack, int size)
@@ -73,6 +153,7 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
73{ 153{
74 struct sigaction action; 154 struct sigaction action;
75 va_list ap; 155 va_list ap;
156 sigset_t sig_mask;
76 int mask; 157 int mask;
77 158
78 va_start(ap, flags); 159 va_start(ap, flags);
@@ -85,7 +166,12 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
85 action.sa_flags = flags; 166 action.sa_flags = flags;
86 action.sa_restorer = NULL; 167 action.sa_restorer = NULL;
87 if(sigaction(sig, &action, NULL) < 0) 168 if(sigaction(sig, &action, NULL) < 0)
88 panic("sigaction failed"); 169 panic("sigaction failed - errno = %d\n", errno);
170
171 sigemptyset(&sig_mask);
172 sigaddset(&sig_mask, sig);
173 if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
174 panic("sigprocmask failed - errno = %d\n", errno);
89} 175}
90 176
91int change_sig(int signal, int on) 177int change_sig(int signal, int on)
@@ -98,89 +184,77 @@ int change_sig(int signal, int on)
98 return(!sigismember(&old, signal)); 184 return(!sigismember(&old, signal));
99} 185}
100 186
101/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
102 * disable profiling; it's safe because the profiling code does not interact
103 * with the kernel code at all.*/
104
105static void change_signals(int type)
106{
107 sigset_t mask;
108
109 sigemptyset(&mask);
110 sigaddset(&mask, SIGVTALRM);
111 sigaddset(&mask, SIGALRM);
112 sigaddset(&mask, SIGIO);
113 if(sigprocmask(type, &mask, NULL) < 0)
114 panic("Failed to change signal mask - errno = %d", errno);
115}
116
117void block_signals(void) 187void block_signals(void)
118{ 188{
119 change_signals(SIG_BLOCK); 189 signals_enabled = 0;
120} 190}
121 191
122void unblock_signals(void) 192void unblock_signals(void)
123{ 193{
124 change_signals(SIG_UNBLOCK); 194 int save_pending;
125}
126 195
127/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled 196 if(signals_enabled == 1)
128 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to 197 return;
129 * be able to profile all of UML, not just the non-critical sections. If
130 * profiling is not thread-safe, then that is not my problem. We can disable
131 * profiling when SMP is enabled in that case.
132 */
133#define SIGIO_BIT 0
134#define SIGVTALRM_BIT 1
135 198
136static int enable_mask(sigset_t *mask) 199 /* We loop because the IRQ handler returns with interrupts off. So,
137{ 200 * interrupts may have arrived and we need to re-enable them and
138 int sigs; 201 * recheck pending.
202 */
203 while(1){
204 /* Save and reset save_pending after enabling signals. This
205 * way, pending won't be changed while we're reading it.
206 */
207 signals_enabled = 1;
208
209 save_pending = pending;
210 if(save_pending == 0)
211 return;
212
213 pending = 0;
214
215 /* We have pending interrupts, so disable signals, as the
216 * handlers expect them off when they are called. They will
217 * be enabled again above.
218 */
219
220 signals_enabled = 0;
139 221
140 sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT; 222 /* Deal with SIGIO first because the alarm handler might
141 sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT; 223 * schedule, leaving the pending SIGIO stranded until we come
142 sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT; 224 * back here.
143 return(sigs); 225 */
226 if(save_pending & SIGIO_MASK)
227 CHOOSE_MODE_PROC(sig_handler_common_tt,
228 sig_handler_common_skas, SIGIO, NULL);
229
230 if(save_pending & SIGALRM_MASK)
231 real_alarm_handler(SIGALRM, NULL);
232
233 if(save_pending & SIGVTALRM_MASK)
234 real_alarm_handler(SIGVTALRM, NULL);
235 }
144} 236}
145 237
146int get_signals(void) 238int get_signals(void)
147{ 239{
148 sigset_t mask; 240 return signals_enabled;
149
150 if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
151 panic("Failed to get signal mask");
152 return(enable_mask(&mask));
153} 241}
154 242
155int set_signals(int enable) 243int set_signals(int enable)
156{ 244{
157 sigset_t mask;
158 int ret; 245 int ret;
246 if(signals_enabled == enable)
247 return enable;
159 248
160 sigemptyset(&mask); 249 ret = signals_enabled;
161 if(enable & (1 << SIGIO_BIT)) 250 if(enable)
162 sigaddset(&mask, SIGIO); 251 unblock_signals();
163 if(enable & (1 << SIGVTALRM_BIT)){ 252 else block_signals();
164 sigaddset(&mask, SIGVTALRM);
165 sigaddset(&mask, SIGALRM);
166 }
167 253
168 /* This is safe - sigprocmask is guaranteed to copy locally the 254 return ret;
169 * value of new_set, do his work and then, at the end, write to 255}
170 * old_set.
171 */
172 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
173 panic("Failed to enable signals");
174 ret = enable_mask(&mask);
175 sigemptyset(&mask);
176 if((enable & (1 << SIGIO_BIT)) == 0)
177 sigaddset(&mask, SIGIO);
178 if((enable & (1 << SIGVTALRM_BIT)) == 0){
179 sigaddset(&mask, SIGVTALRM);
180 sigaddset(&mask, SIGALRM);
181 }
182 if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
183 panic("Failed to block signals");
184 256
185 return(ret); 257void os_usr1_signal(int on)
258{
259 change_sig(SIGUSR1, on);
186} 260}
diff --git a/arch/um/os-Linux/skas/Makefile b/arch/um/os-Linux/skas/Makefile
index eab5386d60a7..5fd8d4dad66a 100644
--- a/arch/um/os-Linux/skas/Makefile
+++ b/arch/um/os-Linux/skas/Makefile
@@ -3,8 +3,8 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := trap.o 6obj-y := mem.o process.o trap.o
7 7
8USER_OBJS := trap.o 8USER_OBJS := mem.o process.o trap.o
9 9
10include arch/um/scripts/Makefile.rules 10include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/skas/mem_user.c b/arch/um/os-Linux/skas/mem.c
index 1d89640bd502..9890e9090f58 100644
--- a/arch/um/kernel/skas/mem_user.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -32,7 +32,7 @@ extern void wait_stub_done(int pid, int sig, char * fname);
32static inline unsigned long *check_init_stack(struct mm_id * mm_idp, 32static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
33 unsigned long *stack) 33 unsigned long *stack)
34{ 34{
35 if(stack == NULL){ 35 if(stack == NULL) {
36 stack = (unsigned long *) mm_idp->stack + 2; 36 stack = (unsigned long *) mm_idp->stack + 2;
37 *stack = 0; 37 *stack = 0;
38 } 38 }
@@ -45,13 +45,14 @@ int single_count = 0;
45int multi_count = 0; 45int multi_count = 0;
46int multi_op_count = 0; 46int multi_op_count = 0;
47 47
48static long do_syscall_stub(struct mm_id *mm_idp, void **addr) 48static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
49{ 49{
50 unsigned long regs[MAX_REG_NR]; 50 unsigned long regs[MAX_REG_NR];
51 unsigned long *data; 51 int n;
52 unsigned long *syscall;
53 long ret, offset; 52 long ret, offset;
54 int n, pid = mm_idp->u.pid; 53 unsigned long * data;
54 unsigned long * syscall;
55 int pid = mm_idp->u.pid;
55 56
56 if(proc_mm) 57 if(proc_mm)
57#warning Need to look up userspace_pid by cpu 58#warning Need to look up userspace_pid by cpu
@@ -59,10 +60,11 @@ static long do_syscall_stub(struct mm_id *mm_idp, void **addr)
59 60
60 multi_count++; 61 multi_count++;
61 62
62 get_safe_registers(regs); 63 get_safe_registers(regs);
63 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + 64 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
64 ((unsigned long) &batch_syscall_stub - 65 ((unsigned long) &batch_syscall_stub -
65 (unsigned long) &__syscall_stub_start); 66 (unsigned long) &__syscall_stub_start);
67
66 n = ptrace_setregs(pid, regs); 68 n = ptrace_setregs(pid, regs);
67 if(n < 0) 69 if(n < 0)
68 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", 70 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
@@ -80,6 +82,8 @@ static long do_syscall_stub(struct mm_id *mm_idp, void **addr)
80 if (offset) { 82 if (offset) {
81 data = (unsigned long *)(mm_idp->stack + 83 data = (unsigned long *)(mm_idp->stack +
82 offset - UML_CONFIG_STUB_DATA); 84 offset - UML_CONFIG_STUB_DATA);
85 printk("do_syscall_stub : ret = %d, offset = %d, "
86 "data = 0x%x\n", ret, offset, data);
83 syscall = (unsigned long *)((unsigned long)data + data[0]); 87 syscall = (unsigned long *)((unsigned long)data + data[0]);
84 printk("do_syscall_stub: syscall %ld failed, return value = " 88 printk("do_syscall_stub: syscall %ld failed, return value = "
85 "0x%lx, expected return value = 0x%lx\n", 89 "0x%lx, expected return value = 0x%lx\n",
@@ -107,32 +111,32 @@ static long do_syscall_stub(struct mm_id *mm_idp, void **addr)
107 111
108long run_syscall_stub(struct mm_id * mm_idp, int syscall, 112long run_syscall_stub(struct mm_id * mm_idp, int syscall,
109 unsigned long *args, long expected, void **addr, 113 unsigned long *args, long expected, void **addr,
110 int done) 114 int done)
111{ 115{
112 unsigned long *stack = check_init_stack(mm_idp, *addr); 116 unsigned long *stack = check_init_stack(mm_idp, *addr);
113 117
114 if(done && *addr == NULL) 118 if(done && *addr == NULL)
115 single_count++; 119 single_count++;
116 120
117 *stack += sizeof(long); 121 *stack += sizeof(long);
118 stack += *stack / sizeof(long); 122 stack += *stack / sizeof(long);
119 123
120 *stack++ = syscall; 124 *stack++ = syscall;
121 *stack++ = args[0]; 125 *stack++ = args[0];
122 *stack++ = args[1]; 126 *stack++ = args[1];
123 *stack++ = args[2]; 127 *stack++ = args[2];
124 *stack++ = args[3]; 128 *stack++ = args[3];
125 *stack++ = args[4]; 129 *stack++ = args[4];
126 *stack++ = args[5]; 130 *stack++ = args[5];
127 *stack++ = expected; 131 *stack++ = expected;
128 *stack = 0; 132 *stack = 0;
129 multi_op_count++; 133 multi_op_count++;
130 134
131 if(!done && ((((unsigned long) stack) & ~PAGE_MASK) < 135 if(!done && ((((unsigned long) stack) & ~PAGE_MASK) <
132 PAGE_SIZE - 10 * sizeof(long))){ 136 PAGE_SIZE - 10 * sizeof(long))){
133 *addr = stack; 137 *addr = stack;
134 return 0; 138 return 0;
135 } 139 }
136 140
137 return do_syscall_stub(mm_idp, addr); 141 return do_syscall_stub(mm_idp, addr);
138} 142}
@@ -150,7 +154,7 @@ long syscall_stub_data(struct mm_id * mm_idp,
150 if((((unsigned long) *addr) & ~PAGE_MASK) >= 154 if((((unsigned long) *addr) & ~PAGE_MASK) >=
151 PAGE_SIZE - (10 + data_count) * sizeof(long)) { 155 PAGE_SIZE - (10 + data_count) * sizeof(long)) {
152 ret = do_syscall_stub(mm_idp, addr); 156 ret = do_syscall_stub(mm_idp, addr);
153 /* in case of error, don't overwrite data on stack */ 157 /* in case of error, don't overwrite data on stack */
154 if(ret) 158 if(ret)
155 return ret; 159 return ret;
156 } 160 }
@@ -172,39 +176,39 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
172 int r, int w, int x, int phys_fd, unsigned long long offset, 176 int r, int w, int x, int phys_fd, unsigned long long offset,
173 int done, void **data) 177 int done, void **data)
174{ 178{
175 int prot, ret; 179 int prot, ret;
176 180
177 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 181 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
178 (x ? PROT_EXEC : 0); 182 (x ? PROT_EXEC : 0);
179 183
180 if(proc_mm){ 184 if(proc_mm){
181 struct proc_mm_op map; 185 struct proc_mm_op map;
182 int fd = mm_idp->u.mm_fd; 186 int fd = mm_idp->u.mm_fd;
183 187
184 map = ((struct proc_mm_op) { .op = MM_MMAP, 188 map = ((struct proc_mm_op) { .op = MM_MMAP,
185 .u = 189 .u =
186 { .mmap = 190 { .mmap =
187 { .addr = virt, 191 { .addr = virt,
188 .len = len, 192 .len = len,
189 .prot = prot, 193 .prot = prot,
190 .flags = MAP_SHARED | 194 .flags = MAP_SHARED |
191 MAP_FIXED, 195 MAP_FIXED,
192 .fd = phys_fd, 196 .fd = phys_fd,
193 .offset= offset 197 .offset= offset
194 } } } ); 198 } } } );
195 ret = os_write_file(fd, &map, sizeof(map)); 199 ret = os_write_file(fd, &map, sizeof(map));
196 if(ret != sizeof(map)) 200 if(ret != sizeof(map))
197 printk("map : /proc/mm map failed, err = %d\n", -ret); 201 printk("map : /proc/mm map failed, err = %d\n", -ret);
198 else ret = 0; 202 else ret = 0;
199 } 203 }
200 else { 204 else {
201 unsigned long args[] = { virt, len, prot, 205 unsigned long args[] = { virt, len, prot,
202 MAP_SHARED | MAP_FIXED, phys_fd, 206 MAP_SHARED | MAP_FIXED, phys_fd,
203 MMAP_OFFSET(offset) }; 207 MMAP_OFFSET(offset) };
204 208
205 ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt, 209 ret = run_syscall_stub(mm_idp, STUB_MMAP_NR, args, virt,
206 data, done); 210 data, done);
207 } 211 }
208 212
209 return ret; 213 return ret;
210} 214}
@@ -212,68 +216,66 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
212int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, 216int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
213 void **data) 217 void **data)
214{ 218{
215 int ret; 219 int ret;
216 220
217 if(proc_mm){ 221 if(proc_mm){
218 struct proc_mm_op unmap; 222 struct proc_mm_op unmap;
219 int fd = mm_idp->u.mm_fd; 223 int fd = mm_idp->u.mm_fd;
220 224
221 unmap = ((struct proc_mm_op) { .op = MM_MUNMAP, 225 unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
222 .u = 226 .u =
223 { .munmap = 227 { .munmap =
224 { .addr = 228 { .addr =
225 (unsigned long) addr, 229 (unsigned long) addr,
226 .len = len } } } ); 230 .len = len } } } );
227 ret = os_write_file(fd, &unmap, sizeof(unmap)); 231 ret = os_write_file(fd, &unmap, sizeof(unmap));
228 if(ret != sizeof(unmap)) 232 if(ret != sizeof(unmap))
229 printk("unmap - proc_mm write returned %d\n", ret); 233 printk("unmap - proc_mm write returned %d\n", ret);
230 else ret = 0; 234 else ret = 0;
231 } 235 }
232 else { 236 else {
233 unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0, 237 unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
234 0 }; 238 0 };
235 239
236 ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0, 240 ret = run_syscall_stub(mm_idp, __NR_munmap, args, 0,
237 data, done); 241 data, done);
238 if(ret < 0) 242 }
239 printk("munmap stub failed, errno = %d\n", ret);
240 }
241 243
242 return ret; 244 return ret;
243} 245}
244 246
245int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, 247int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
246 int r, int w, int x, int done, void **data) 248 int r, int w, int x, int done, void **data)
247{ 249{
248 struct proc_mm_op protect; 250 struct proc_mm_op protect;
249 int prot, ret; 251 int prot, ret;
250 252
251 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 253 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
252 (x ? PROT_EXEC : 0); 254 (x ? PROT_EXEC : 0);
253 255 if(proc_mm){
254 if(proc_mm){ 256 int fd = mm_idp->u.mm_fd;
255 int fd = mm_idp->u.mm_fd; 257
256 protect = ((struct proc_mm_op) { .op = MM_MPROTECT, 258 protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
257 .u = 259 .u =
258 { .mprotect = 260 { .mprotect =
259 { .addr = 261 { .addr =
260 (unsigned long) addr, 262 (unsigned long) addr,
261 .len = len, 263 .len = len,
262 .prot = prot } } } ); 264 .prot = prot } } } );
263 265
264 ret = os_write_file(fd, &protect, sizeof(protect)); 266 ret = os_write_file(fd, &protect, sizeof(protect));
265 if(ret != sizeof(protect)) 267 if(ret != sizeof(protect))
266 printk("protect failed, err = %d", -ret); 268 printk("protect failed, err = %d", -ret);
267 else ret = 0; 269 else ret = 0;
268 } 270 }
269 else { 271 else {
270 unsigned long args[] = { addr, len, prot, 0, 0, 0 }; 272 unsigned long args[] = { addr, len, prot, 0, 0, 0 };
271 273
272 ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0, 274 ret = run_syscall_stub(mm_idp, __NR_mprotect, args, 0,
273 data, done); 275 data, done);
274 } 276 }
275 277
276 return ret; 278 return ret;
277} 279}
278 280
279void before_mem_skas(unsigned long unused) 281void before_mem_skas(unsigned long unused)
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
new file mode 100644
index 000000000000..120a21c5883f
--- /dev/null
+++ b/arch/um/os-Linux/skas/process.c
@@ -0,0 +1,566 @@
1/*
2 * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <string.h>
8#include <unistd.h>
9#include <errno.h>
10#include <signal.h>
11#include <setjmp.h>
12#include <sched.h>
13#include "ptrace_user.h"
14#include <sys/wait.h>
15#include <sys/mman.h>
16#include <sys/user.h>
17#include <sys/time.h>
18#include <asm/unistd.h>
19#include <asm/types.h>
20#include "user.h"
21#include "sysdep/ptrace.h"
22#include "user_util.h"
23#include "kern_util.h"
24#include "skas.h"
25#include "stub-data.h"
26#include "mm_id.h"
27#include "sysdep/sigcontext.h"
28#include "sysdep/stub.h"
29#include "os.h"
30#include "proc_mm.h"
31#include "skas_ptrace.h"
32#include "chan_user.h"
33#include "registers.h"
34#include "mem.h"
35#include "uml-config.h"
36#include "process.h"
37#include "longjmp.h"
38
39int is_skas_winch(int pid, int fd, void *data)
40{
41 if(pid != os_getpgrp())
42 return(0);
43
44 register_winch_irq(-1, fd, -1, data);
45 return(1);
46}
47
48void wait_stub_done(int pid, int sig, char * fname)
49{
50 int n, status, err;
51
52 do {
53 if ( sig != -1 ) {
54 err = ptrace(PTRACE_CONT, pid, 0, sig);
55 if(err)
56 panic("%s : continue failed, errno = %d\n",
57 fname, errno);
58 }
59 sig = 0;
60
61 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
62 } while((n >= 0) && WIFSTOPPED(status) &&
63 ((WSTOPSIG(status) == SIGVTALRM) ||
64 /* running UML inside a detached screen can cause
65 * SIGWINCHes
66 */
67 (WSTOPSIG(status) == SIGWINCH)));
68
69 if((n < 0) || !WIFSTOPPED(status) ||
70 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
71 unsigned long regs[HOST_FRAME_SIZE];
72
73 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
74 printk("Failed to get registers from stub, "
75 "errno = %d\n", errno);
76 else {
77 int i;
78
79 printk("Stub registers -\n");
80 for(i = 0; i < HOST_FRAME_SIZE; i++)
81 printk("\t%d - %lx\n", i, regs[i]);
82 }
83 panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
84 "pid = %d, n = %d, errno = %d, status = 0x%x\n",
85 fname, pid, n, errno, status);
86 }
87}
88
89extern unsigned long current_stub_stack(void);
90
91void get_skas_faultinfo(int pid, struct faultinfo * fi)
92{
93 int err;
94
95 if(ptrace_faultinfo){
96 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
97 if(err)
98 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
99 "errno = %d\n", errno);
100
101 /* Special handling for i386, which has different structs */
102 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
103 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
104 sizeof(struct faultinfo) -
105 sizeof(struct ptrace_faultinfo));
106 }
107 else {
108 wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
109
110 /* faultinfo is prepared by the stub-segv-handler at start of
111 * the stub stack page. We just have to copy it.
112 */
113 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
114 }
115}
116
117static void handle_segv(int pid, union uml_pt_regs * regs)
118{
119 get_skas_faultinfo(pid, &regs->skas.faultinfo);
120 segv(regs->skas.faultinfo, 0, 1, NULL);
121}
122
123/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
124static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
125{
126 int err, status;
127
128 /* Mark this as a syscall */
129 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
130
131 if (!local_using_sysemu)
132 {
133 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
134 __NR_getpid);
135 if(err < 0)
136 panic("handle_trap - nullifying syscall failed errno = %d\n",
137 errno);
138
139 err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
140 if(err < 0)
141 panic("handle_trap - continuing to end of syscall failed, "
142 "errno = %d\n", errno);
143
144 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
145 if((err < 0) || !WIFSTOPPED(status) ||
146 (WSTOPSIG(status) != SIGTRAP + 0x80))
147 panic("handle_trap - failed to wait at end of syscall, "
148 "errno = %d, status = %d\n", errno, status);
149 }
150
151 handle_syscall(regs);
152}
153
154extern int __syscall_stub_start;
155
156static int userspace_tramp(void *stack)
157{
158 void *addr;
159
160 ptrace(PTRACE_TRACEME, 0, 0, 0);
161
162 init_new_thread_signals(1);
163 enable_timer();
164
165 if(!proc_mm){
166 /* This has a pte, but it can't be mapped in with the usual
167 * tlb_flush mechanism because this is part of that mechanism
168 */
169 int fd;
170 __u64 offset;
171 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
172 addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
173 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
174 if(addr == MAP_FAILED){
175 printk("mapping mmap stub failed, errno = %d\n",
176 errno);
177 exit(1);
178 }
179
180 if(stack != NULL){
181 fd = phys_mapping(to_phys(stack), &offset);
182 addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
183 PROT_READ | PROT_WRITE,
184 MAP_FIXED | MAP_SHARED, fd, offset);
185 if(addr == MAP_FAILED){
186 printk("mapping segfault stack failed, "
187 "errno = %d\n", errno);
188 exit(1);
189 }
190 }
191 }
192 if(!ptrace_faultinfo && (stack != NULL)){
193 unsigned long v = UML_CONFIG_STUB_CODE +
194 (unsigned long) stub_segv_handler -
195 (unsigned long) &__syscall_stub_start;
196
197 set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
198 set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
199 SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
200 SIGUSR1, -1);
201 }
202
203 os_stop_process(os_getpid());
204 return(0);
205}
206
207/* Each element set once, and only accessed by a single processor anyway */
208#undef NR_CPUS
209#define NR_CPUS 1
210int userspace_pid[NR_CPUS];
211
212int start_userspace(unsigned long stub_stack)
213{
214 void *stack;
215 unsigned long sp;
216 int pid, status, n, flags;
217
218 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
219 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
220 if(stack == MAP_FAILED)
221 panic("start_userspace : mmap failed, errno = %d", errno);
222 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
223
224 flags = CLONE_FILES | SIGCHLD;
225 if(proc_mm) flags |= CLONE_VM;
226 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
227 if(pid < 0)
228 panic("start_userspace : clone failed, errno = %d", errno);
229
230 do {
231 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
232 if(n < 0)
233 panic("start_userspace : wait failed, errno = %d",
234 errno);
235 } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
236
237 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
238 panic("start_userspace : expected SIGSTOP, got status = %d",
239 status);
240
241 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
242 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n",
243 errno);
244
245 if(munmap(stack, PAGE_SIZE) < 0)
246 panic("start_userspace : munmap failed, errno = %d\n", errno);
247
248 return(pid);
249}
250
251void userspace(union uml_pt_regs *regs)
252{
253 int err, status, op, pid = userspace_pid[0];
254 int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
255
256 while(1){
257 restore_registers(pid, regs);
258
259 /* Now we set local_using_sysemu to be used for one loop */
260 local_using_sysemu = get_using_sysemu();
261
262 op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
263
264 err = ptrace(op, pid, 0, 0);
265 if(err)
266 panic("userspace - could not resume userspace process, "
267 "pid=%d, ptrace operation = %d, errno = %d\n",
268 op, errno);
269
270 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
271 if(err < 0)
272 panic("userspace - waitpid failed, errno = %d\n",
273 errno);
274
275 regs->skas.is_user = 1;
276 save_registers(pid, regs);
277 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
278
279 if(WIFSTOPPED(status)){
280 switch(WSTOPSIG(status)){
281 case SIGSEGV:
282 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
283 user_signal(SIGSEGV, regs, pid);
284 else handle_segv(pid, regs);
285 break;
286 case SIGTRAP + 0x80:
287 handle_trap(pid, regs, local_using_sysemu);
288 break;
289 case SIGTRAP:
290 relay_signal(SIGTRAP, regs);
291 break;
292 case SIGIO:
293 case SIGVTALRM:
294 case SIGILL:
295 case SIGBUS:
296 case SIGFPE:
297 case SIGWINCH:
298 user_signal(WSTOPSIG(status), regs, pid);
299 break;
300 default:
301 printk("userspace - child stopped with signal "
302 "%d\n", WSTOPSIG(status));
303 }
304 pid = userspace_pid[0];
305 interrupt_end();
306
307 /* Avoid -ERESTARTSYS handling in host */
308 if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
309 PT_SYSCALL_NR(regs->skas.regs) = -1;
310 }
311 }
312}
313#define INIT_JMP_NEW_THREAD 0
314#define INIT_JMP_REMOVE_SIGSTACK 1
315#define INIT_JMP_CALLBACK 2
316#define INIT_JMP_HALT 3
317#define INIT_JMP_REBOOT 4
318
319int copy_context_skas0(unsigned long new_stack, int pid)
320{
321 int err;
322 unsigned long regs[MAX_REG_NR];
323 unsigned long current_stack = current_stub_stack();
324 struct stub_data *data = (struct stub_data *) current_stack;
325 struct stub_data *child_data = (struct stub_data *) new_stack;
326 __u64 new_offset;
327 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
328
329 /* prepare offset and fd of child's stack as argument for parent's
330 * and child's mmap2 calls
331 */
332 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
333 .fd = new_fd,
334 .timer = ((struct itimerval)
335 { { 0, 1000000 / hz() },
336 { 0, 1000000 / hz() }})});
337 get_safe_registers(regs);
338
339 /* Set parent's instruction pointer to start of clone-stub */
340 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
341 (unsigned long) stub_clone_handler -
342 (unsigned long) &__syscall_stub_start;
343 regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
344 sizeof(void *);
345#ifdef __SIGNAL_FRAMESIZE
346 regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
347#endif
348 err = ptrace_setregs(pid, regs);
349 if(err < 0)
350 panic("copy_context_skas0 : PTRACE_SETREGS failed, "
351 "pid = %d, errno = %d\n", pid, errno);
352
353 /* set a well known return code for detection of child write failure */
354 child_data->err = 12345678;
355
356 /* Wait, until parent has finished its work: read child's pid from
357 * parent's stack, and check, if bad result.
358 */
359 wait_stub_done(pid, 0, "copy_context_skas0");
360
361 pid = data->err;
362 if(pid < 0)
363 panic("copy_context_skas0 - stub-parent reports error %d\n",
364 pid);
365
366 /* Wait, until child has finished too: read child's result from
367 * child's stack and check it.
368 */
369 wait_stub_done(pid, -1, "copy_context_skas0");
370 if (child_data->err != UML_CONFIG_STUB_DATA)
371 panic("copy_context_skas0 - stub-child reports error %d\n",
372 child_data->err);
373
374 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
375 (void *)PTRACE_O_TRACESYSGOOD) < 0)
376 panic("copy_context_skas0 : PTRACE_OLDSETOPTIONS failed, "
377 "errno = %d\n", errno);
378
379 return pid;
380}
381
382/*
383 * This is used only, if stub pages are needed, while proc_mm is
384 * availabl. Opening /proc/mm creates a new mm_context, which lacks
385 * the stub-pages. Thus, we map them using /proc/mm-fd
386 */
387void map_stub_pages(int fd, unsigned long code,
388 unsigned long data, unsigned long stack)
389{
390 struct proc_mm_op mmop;
391 int n;
392 __u64 code_offset;
393 int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),
394 &code_offset);
395
396 mmop = ((struct proc_mm_op) { .op = MM_MMAP,
397 .u =
398 { .mmap =
399 { .addr = code,
400 .len = PAGE_SIZE,
401 .prot = PROT_EXEC,
402 .flags = MAP_FIXED | MAP_PRIVATE,
403 .fd = code_fd,
404 .offset = code_offset
405 } } });
406 n = os_write_file(fd, &mmop, sizeof(mmop));
407 if(n != sizeof(mmop))
408 panic("map_stub_pages : /proc/mm map for code failed, "
409 "err = %d\n", -n);
410
411 if ( stack ) {
412 __u64 map_offset;
413 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
414 mmop = ((struct proc_mm_op)
415 { .op = MM_MMAP,
416 .u =
417 { .mmap =
418 { .addr = data,
419 .len = PAGE_SIZE,
420 .prot = PROT_READ | PROT_WRITE,
421 .flags = MAP_FIXED | MAP_SHARED,
422 .fd = map_fd,
423 .offset = map_offset
424 } } });
425 n = os_write_file(fd, &mmop, sizeof(mmop));
426 if(n != sizeof(mmop))
427 panic("map_stub_pages : /proc/mm map for data failed, "
428 "err = %d\n", -n);
429 }
430}
431
432void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
433 void (*handler)(int))
434{
435 unsigned long flags;
436 sigjmp_buf switch_buf, fork_buf;
437 int enable;
438
439 *switch_buf_ptr = &switch_buf;
440 *fork_buf_ptr = &fork_buf;
441
442 /* Somewhat subtle - siglongjmp restores the signal mask before doing
443 * the longjmp. This means that when jumping from one stack to another
444 * when the target stack has interrupts enabled, an interrupt may occur
445 * on the source stack. This is bad when starting up a process because
446 * it's not supposed to get timer ticks until it has been scheduled.
447 * So, we disable interrupts around the sigsetjmp to ensure that
448 * they can't happen until we get back here where they are safe.
449 */
450 flags = get_signals();
451 block_signals();
452 if(UML_SIGSETJMP(&fork_buf, enable) == 0)
453 new_thread_proc(stack, handler);
454
455 remove_sigstack();
456
457 set_signals(flags);
458}
459
460void thread_wait(void *sw, void *fb)
461{
462 sigjmp_buf buf, **switch_buf = sw, *fork_buf;
463 int enable;
464
465 *switch_buf = &buf;
466 fork_buf = fb;
467 if(UML_SIGSETJMP(&buf, enable) == 0)
468 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
469}
470
471void switch_threads(void *me, void *next)
472{
473 sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
474 int enable;
475
476 *me_ptr = &my_buf;
477 if(UML_SIGSETJMP(&my_buf, enable) == 0)
478 UML_SIGLONGJMP(next_buf, 1);
479}
480
481static sigjmp_buf initial_jmpbuf;
482
483/* XXX Make these percpu */
484static void (*cb_proc)(void *arg);
485static void *cb_arg;
486static sigjmp_buf *cb_back;
487
488int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
489{
490 sigjmp_buf **switch_buf = switch_buf_ptr;
491 int n, enable;
492
493 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
494 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
495 SIGVTALRM, -1);
496
497 *fork_buf_ptr = &initial_jmpbuf;
498 n = UML_SIGSETJMP(&initial_jmpbuf, enable);
499 switch(n){
500 case INIT_JMP_NEW_THREAD:
501 new_thread_proc((void *) stack, new_thread_handler);
502 break;
503 case INIT_JMP_REMOVE_SIGSTACK:
504 remove_sigstack();
505 break;
506 case INIT_JMP_CALLBACK:
507 (*cb_proc)(cb_arg);
508 UML_SIGLONGJMP(cb_back, 1);
509 break;
510 case INIT_JMP_HALT:
511 kmalloc_ok = 0;
512 return(0);
513 case INIT_JMP_REBOOT:
514 kmalloc_ok = 0;
515 return(1);
516 default:
517 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
518 }
519 UML_SIGLONGJMP(*switch_buf, 1);
520}
521
522void initial_thread_cb_skas(void (*proc)(void *), void *arg)
523{
524 sigjmp_buf here;
525 int enable;
526
527 cb_proc = proc;
528 cb_arg = arg;
529 cb_back = &here;
530
531 block_signals();
532 if(UML_SIGSETJMP(&here, enable) == 0)
533 UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
534 unblock_signals();
535
536 cb_proc = NULL;
537 cb_arg = NULL;
538 cb_back = NULL;
539}
540
541void halt_skas(void)
542{
543 block_signals();
544 UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
545}
546
547void reboot_skas(void)
548{
549 block_signals();
550 UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
551}
552
553void switch_mm_skas(struct mm_id *mm_idp)
554{
555 int err;
556
557#warning need cpu pid in switch_mm_skas
558 if(proc_mm){
559 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
560 mm_idp->u.mm_fd);
561 if(err)
562 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
563 "errno = %d\n", errno);
564 }
565 else userspace_pid[0] = mm_idp->u.pid;
566}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b47e5e71d1a5..6c5b17ed59e1 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -29,7 +29,6 @@
29#include "irq_user.h" 29#include "irq_user.h"
30#include "ptrace_user.h" 30#include "ptrace_user.h"
31#include "mem_user.h" 31#include "mem_user.h"
32#include "time_user.h"
33#include "init.h" 32#include "init.h"
34#include "os.h" 33#include "os.h"
35#include "uml-config.h" 34#include "uml-config.h"
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index cf30a39bc484..6f7626775acb 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -1,21 +1,128 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
1#include <stdlib.h> 7#include <stdlib.h>
8#include <unistd.h>
9#include <time.h>
2#include <sys/time.h> 10#include <sys/time.h>
11#include <signal.h>
12#include <errno.h>
13#include "user_util.h"
14#include "kern_util.h"
15#include "user.h"
16#include "process.h"
17#include "kern_constants.h"
18#include "os.h"
19
20/* XXX This really needs to be declared and initialized in a kernel file since
21 * it's in <linux/time.h>
22 */
23extern struct timespec wall_to_monotonic;
24
25static void set_interval(int timer_type)
26{
27 int usec = 1000000/hz();
28 struct itimerval interval = ((struct itimerval) { { 0, usec },
29 { 0, usec } });
30
31 if(setitimer(timer_type, &interval, NULL) == -1)
32 panic("setitimer failed - errno = %d\n", errno);
33}
34
35void enable_timer(void)
36{
37 set_interval(ITIMER_VIRTUAL);
38}
39
40void disable_timer(void)
41{
42 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
43 if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
44 (setitimer(ITIMER_REAL, &disable, NULL) < 0))
45 printk("disnable_timer - setitimer failed, errno = %d\n",
46 errno);
47 /* If there are signals already queued, after unblocking ignore them */
48 set_handler(SIGALRM, SIG_IGN, 0, -1);
49 set_handler(SIGVTALRM, SIG_IGN, 0, -1);
50}
51
52void switch_timers(int to_real)
53{
54 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
55 struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
56 { 0, 1000000/hz() }});
57 int old, new;
58
59 if(to_real){
60 old = ITIMER_VIRTUAL;
61 new = ITIMER_REAL;
62 }
63 else {
64 old = ITIMER_REAL;
65 new = ITIMER_VIRTUAL;
66 }
67
68 if((setitimer(old, &disable, NULL) < 0) ||
69 (setitimer(new, &enable, NULL)))
70 printk("switch_timers - setitimer failed, errno = %d\n",
71 errno);
72}
3 73
4unsigned long long os_usecs(void) 74void uml_idle_timer(void)
75{
76 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
77 panic("Couldn't unset SIGVTALRM handler");
78
79 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
80 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
81 set_interval(ITIMER_REAL);
82}
83
84extern void ktime_get_ts(struct timespec *ts);
85#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
86
87void time_init(void)
88{
89 struct timespec now;
90
91 if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
92 panic("Couldn't set SIGVTALRM handler");
93 set_interval(ITIMER_VIRTUAL);
94
95 do_posix_clock_monotonic_gettime(&now);
96 wall_to_monotonic.tv_sec = -now.tv_sec;
97 wall_to_monotonic.tv_nsec = -now.tv_nsec;
98}
99
100unsigned long long os_nsecs(void)
5{ 101{
6 struct timeval tv; 102 struct timeval tv;
7 103
8 gettimeofday(&tv, NULL); 104 gettimeofday(&tv, NULL);
9 return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec); 105 return((unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000);
10} 106}
11 107
12/* 108void idle_sleep(int secs)
13 * Overrides for Emacs so that we follow Linus's tabbing style. 109{
14 * Emacs will notice this stuff at the end of the file and automatically 110 struct timespec ts;
15 * adjust the settings for this buffer only. This must remain at the end 111
16 * of the file. 112 ts.tv_sec = secs;
17 * --------------------------------------------------------------------------- 113 ts.tv_nsec = 0;
18 * Local variables: 114 nanosleep(&ts, NULL);
19 * c-file-style: "linux" 115}
20 * End: 116
21 */ 117/* XXX This partly duplicates init_irq_signals */
118
119void user_time_init(void)
120{
121 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
122 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
123 SIGALRM, SIGUSR2, -1);
124 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
125 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
126 SIGVTALRM, SIGUSR2, -1);
127 set_interval(ITIMER_VIRTUAL);
128}
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index 321e1c8e227d..a9f6b26f9828 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -10,6 +10,7 @@
10#include "user_util.h" 10#include "user_util.h"
11#include "os.h" 11#include "os.h"
12#include "mode.h" 12#include "mode.h"
13#include "longjmp.h"
13 14
14void usr2_handler(int sig, union uml_pt_regs *regs) 15void usr2_handler(int sig, union uml_pt_regs *regs)
15{ 16{
@@ -36,5 +37,5 @@ void do_longjmp(void *b, int val)
36{ 37{
37 sigjmp_buf *buf = b; 38 sigjmp_buf *buf = b;
38 39
39 siglongjmp(*buf, val); 40 UML_SIGLONGJMP(buf, val);
40} 41}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index cb2648b79d0f..919d19f11537 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -27,7 +27,6 @@
27#include "sysdep/sigcontext.h" 27#include "sysdep/sigcontext.h"
28#include "irq_user.h" 28#include "irq_user.h"
29#include "ptrace_user.h" 29#include "ptrace_user.h"
30#include "time_user.h"
31#include "init.h" 30#include "init.h"
32#include "os.h" 31#include "os.h"
33#include "uml-config.h" 32#include "uml-config.h"
@@ -63,6 +62,54 @@ void kill_child_dead(int pid)
63 } while(1); 62 } while(1);
64} 63}
65 64
65void stop(void)
66{
67 while(1) sleep(1000000);
68}
69
70int wait_for_stop(int pid, int sig, int cont_type, void *relay)
71{
72 sigset_t *relay_signals = relay;
73 int status, ret;
74
75 while(1){
76 CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
77 if((ret < 0) ||
78 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
79 if(ret < 0){
80 printk("wait failed, errno = %d\n",
81 errno);
82 }
83 else if(WIFEXITED(status))
84 printk("process %d exited with status %d\n",
85 pid, WEXITSTATUS(status));
86 else if(WIFSIGNALED(status))
87 printk("process %d exited with signal %d\n",
88 pid, WTERMSIG(status));
89 else if((WSTOPSIG(status) == SIGVTALRM) ||
90 (WSTOPSIG(status) == SIGALRM) ||
91 (WSTOPSIG(status) == SIGIO) ||
92 (WSTOPSIG(status) == SIGPROF) ||
93 (WSTOPSIG(status) == SIGCHLD) ||
94 (WSTOPSIG(status) == SIGWINCH) ||
95 (WSTOPSIG(status) == SIGINT)){
96 ptrace(cont_type, pid, 0, WSTOPSIG(status));
97 continue;
98 }
99 else if((relay_signals != NULL) &&
100 sigismember(relay_signals, WSTOPSIG(status))){
101 ptrace(cont_type, pid, 0, WSTOPSIG(status));
102 continue;
103 }
104 else printk("process %d stopped with signal %d\n",
105 pid, WSTOPSIG(status));
106 panic("wait_for_stop failed to wait for %d to stop "
107 "with %d\n", pid, sig);
108 }
109 return(status);
110 }
111}
112
66/* 113/*
67 *------------------------- 114 *-------------------------
68 * only for tt mode (will be deleted in future...) 115 * only for tt mode (will be deleted in future...)
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index 38d710158c3d..166fb66995df 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -6,6 +6,7 @@
6 6
7#include <setjmp.h> 7#include <setjmp.h>
8#include <string.h> 8#include <string.h>
9#include "longjmp.h"
9 10
10unsigned long __do_user_copy(void *to, const void *from, int n, 11unsigned long __do_user_copy(void *to, const void *from, int n,
11 void **fault_addr, void **fault_catcher, 12 void **fault_addr, void **fault_catcher,
@@ -13,10 +14,11 @@ unsigned long __do_user_copy(void *to, const void *from, int n,
13 int n), int *faulted_out) 14 int n), int *faulted_out)
14{ 15{
15 unsigned long *faddrp = (unsigned long *) fault_addr, ret; 16 unsigned long *faddrp = (unsigned long *) fault_addr, ret;
17 int enable;
16 18
17 sigjmp_buf jbuf; 19 sigjmp_buf jbuf;
18 *fault_catcher = &jbuf; 20 *fault_catcher = &jbuf;
19 if(sigsetjmp(jbuf, 1) == 0){ 21 if(UML_SIGSETJMP(&jbuf, enable) == 0){
20 (*op)(to, from, n); 22 (*op)(to, from, n);
21 ret = 0; 23 ret = 0;
22 *faulted_out = 0; 24 *faulted_out = 0;
diff --git a/arch/um/kernel/user_util.c b/arch/um/os-Linux/util.c
index 4c231161f257..e32065e2fdc8 100644
--- a/arch/um/kernel/user_util.c
+++ b/arch/um/os-Linux/util.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -29,17 +29,14 @@
29#include "init.h" 29#include "init.h"
30#include "ptrace_user.h" 30#include "ptrace_user.h"
31#include "uml-config.h" 31#include "uml-config.h"
32 32#include "os.h"
33void stop(void) 33#include "longjmp.h"
34{
35 while(1) sleep(1000000);
36}
37 34
38void stack_protections(unsigned long address) 35void stack_protections(unsigned long address)
39{ 36{
40 int prot = PROT_READ | PROT_WRITE | PROT_EXEC; 37 int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
41 38
42 if(mprotect((void *) address, page_size(), prot) < 0) 39 if(mprotect((void *) address, page_size(), prot) < 0)
43 panic("protecting stack failed, errno = %d", errno); 40 panic("protecting stack failed, errno = %d", errno);
44} 41}
45 42
@@ -59,49 +56,6 @@ void task_protections(unsigned long address)
59 panic("protecting stack failed, errno = %d", errno); 56 panic("protecting stack failed, errno = %d", errno);
60} 57}
61 58
62int wait_for_stop(int pid, int sig, int cont_type, void *relay)
63{
64 sigset_t *relay_signals = relay;
65 int status, ret;
66
67 while(1){
68 CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
69 if((ret < 0) ||
70 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
71 if(ret < 0){
72 printk("wait failed, errno = %d\n",
73 errno);
74 }
75 else if(WIFEXITED(status))
76 printk("process %d exited with status %d\n",
77 pid, WEXITSTATUS(status));
78 else if(WIFSIGNALED(status))
79 printk("process %d exited with signal %d\n",
80 pid, WTERMSIG(status));
81 else if((WSTOPSIG(status) == SIGVTALRM) ||
82 (WSTOPSIG(status) == SIGALRM) ||
83 (WSTOPSIG(status) == SIGIO) ||
84 (WSTOPSIG(status) == SIGPROF) ||
85 (WSTOPSIG(status) == SIGCHLD) ||
86 (WSTOPSIG(status) == SIGWINCH) ||
87 (WSTOPSIG(status) == SIGINT)){
88 ptrace(cont_type, pid, 0, WSTOPSIG(status));
89 continue;
90 }
91 else if((relay_signals != NULL) &&
92 sigismember(relay_signals, WSTOPSIG(status))){
93 ptrace(cont_type, pid, 0, WSTOPSIG(status));
94 continue;
95 }
96 else printk("process %d stopped with signal %d\n",
97 pid, WSTOPSIG(status));
98 panic("wait_for_stop failed to wait for %d to stop "
99 "with %d\n", pid, sig);
100 }
101 return(status);
102 }
103}
104
105int raw(int fd) 59int raw(int fd)
106{ 60{
107 struct termios tt; 61 struct termios tt;
@@ -113,7 +67,7 @@ int raw(int fd)
113 67
114 cfmakeraw(&tt); 68 cfmakeraw(&tt);
115 69
116 CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt)); 70 CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
117 if(err < 0) 71 if(err < 0)
118 return -errno; 72 return -errno;
119 73
@@ -149,7 +103,7 @@ void setup_hostinfo(void)
149 103
150int setjmp_wrapper(void (*proc)(void *, void *), ...) 104int setjmp_wrapper(void (*proc)(void *, void *), ...)
151{ 105{
152 va_list args; 106 va_list args;
153 sigjmp_buf buf; 107 sigjmp_buf buf;
154 int n; 108 int n;
155 109
@@ -161,14 +115,3 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
161 va_end(args); 115 va_end(args);
162 return(n); 116 return(n);
163} 117}
164
165/*
166 * Overrides for Emacs so that we follow Linus's tabbing style.
167 * Emacs will notice this stuff at the end of the file and automatically
168 * adjust the settings for this buffer only. This must remain at the end
169 * of the file.
170 * ---------------------------------------------------------------------------
171 * Local variables:
172 * c-file-style: "linux"
173 * End:
174 */
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 17746b4c08ff..0cdfd4481d5e 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -16,6 +16,8 @@
16#include "choose-mode.h" 16#include "choose-mode.h"
17#include "kern.h" 17#include "kern.h"
18#include "mode_kern.h" 18#include "mode_kern.h"
19#include "proc_mm.h"
20#include "os.h"
19 21
20extern int modify_ldt(int func, void *ptr, unsigned long bytecount); 22extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
21 23
@@ -456,13 +458,14 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
456 int i; 458 int i;
457 long page, err=0; 459 long page, err=0;
458 void *addr = NULL; 460 void *addr = NULL;
461 struct proc_mm_op copy;
459 462
460 memset(&desc, 0, sizeof(desc));
461 463
462 if(!ptrace_ldt) 464 if(!ptrace_ldt)
463 init_MUTEX(&new_mm->ldt.semaphore); 465 init_MUTEX(&new_mm->ldt.semaphore);
464 466
465 if(!from_mm){ 467 if(!from_mm){
468 memset(&desc, 0, sizeof(desc));
466 /* 469 /*
467 * We have to initialize a clean ldt. 470 * We have to initialize a clean ldt.
468 */ 471 */
@@ -494,8 +497,26 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
494 } 497 }
495 } 498 }
496 new_mm->ldt.entry_count = 0; 499 new_mm->ldt.entry_count = 0;
500
501 goto out;
497 } 502 }
498 else if (!ptrace_ldt) { 503
504 if(proc_mm){
505 /* We have a valid from_mm, so we now have to copy the LDT of
506 * from_mm to new_mm, because using proc_mm an new mm with
507 * an empty/default LDT was created in new_mm()
508 */
509 copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
510 .u =
511 { .copy_segments =
512 from_mm->id.u.mm_fd } } );
513 i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy));
514 if(i != sizeof(copy))
515 printk("new_mm : /proc/mm copy_segments failed, "
516 "err = %d\n", -i);
517 }
518
519 if(!ptrace_ldt) {
499 /* Our local LDT is used to supply the data for 520 /* Our local LDT is used to supply the data for
500 * modify_ldt(READLDT), if PTRACE_LDT isn't available, 521 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
501 * i.e., we have to use the stub for modify_ldt, which 522 * i.e., we have to use the stub for modify_ldt, which
@@ -524,6 +545,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
524 up(&from_mm->ldt.semaphore); 545 up(&from_mm->ldt.semaphore);
525 } 546 }
526 547
548 out:
527 return err; 549 return err;
528} 550}
529 551
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 5231fe83ea4b..09a3eb743315 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -646,6 +646,7 @@ CONFIG_8139TOO=y
646# CONFIG_DL2K is not set 646# CONFIG_DL2K is not set
647CONFIG_E1000=y 647CONFIG_E1000=y
648# CONFIG_E1000_NAPI is not set 648# CONFIG_E1000_NAPI is not set
649# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
649# CONFIG_NS83820 is not set 650# CONFIG_NS83820 is not set
650# CONFIG_HAMACHI is not set 651# CONFIG_HAMACHI is not set
651# CONFIG_YELLOWFIN is not set 652# CONFIG_YELLOWFIN is not set
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 58f5bfb52c63..f05c2a802489 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -672,6 +672,19 @@ ia32_sys_call_table:
672 .quad sys_inotify_add_watch 672 .quad sys_inotify_add_watch
673 .quad sys_inotify_rm_watch 673 .quad sys_inotify_rm_watch
674 .quad sys_migrate_pages 674 .quad sys_migrate_pages
675 .quad compat_sys_openat /* 295 */
676 .quad sys_mkdirat
677 .quad sys_mknodat
678 .quad sys_fchownat
679 .quad sys_futimesat
680 .quad compat_sys_newfstatat /* 300 */
681 .quad sys_unlinkat
682 .quad sys_renameat
683 .quad sys_linkat
684 .quad sys_symlinkat
685 .quad sys_readlinkat /* 305 */
686 .quad sys_fchmodat
687 .quad sys_faccessat
675ia32_syscall_end: 688ia32_syscall_end:
676 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 689 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
677 .quad ni_syscall 690 .quad ni_syscall
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 8ac4db09610a..70f1bb808a20 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -146,7 +146,7 @@ void pda_init(int cpu)
146 pda->irqstackptr += IRQSTACKSIZE-64; 146 pda->irqstackptr += IRQSTACKSIZE-64;
147} 147}
148 148
149char boot_exception_stacks[(N_EXCEPTION_STACKS - 2) * EXCEPTION_STKSZ + DEBUG_STKSZ] 149char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]
150__attribute__((section(".bss.page_aligned"))); 150__attribute__((section(".bss.page_aligned")));
151 151
152/* May not be marked __init: used by software suspend */ 152/* May not be marked __init: used by software suspend */