diff options
Diffstat (limited to 'arch')
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 |
337 | 1: cmp r1, r8 @ if virt > start of RAM | 337 | 1: 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 |
523 | CONFIG_E1000=y | 523 | CONFIG_E1000=y |
524 | CONFIG_E1000_NAPI=y | 524 | CONFIG_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 |
494 | CONFIG_E1000=y | 494 | CONFIG_E1000=y |
495 | CONFIG_E1000_NAPI=y | 495 | CONFIG_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 |
416 | CONFIG_E1000=y | 416 | CONFIG_E1000=y |
417 | CONFIG_E1000_NAPI=y | 417 | CONFIG_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 |
497 | CONFIG_E1000=y | 497 | CONFIG_E1000=y |
498 | CONFIG_E1000_NAPI=y | 498 | CONFIG_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 |
497 | CONFIG_E1000=y | 497 | CONFIG_E1000=y |
498 | CONFIG_E1000_NAPI=y | 498 | CONFIG_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 | ||
39 | const unsigned long sigreturn_codes[4] = { | 45 | const 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 | ||
44 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); | 50 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); |
@@ -189,7 +195,7 @@ struct aux_sigframe { | |||
189 | struct sigframe { | 195 | struct 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 | ||
12 | extern const unsigned long sigreturn_codes[4]; | 12 | extern 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 | ||
335 | unsigned long ixp4xx_exp_bus_size; | 335 | unsigned long ixp4xx_exp_bus_size; |
336 | EXPORT_SYMBOL(ixp4xx_exp_bus_size); | ||
336 | 337 | ||
337 | void __init ixp4xx_sys_init(void) | 338 | void __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 | ||
62 | static void omap1_clk_disable_dsp_domain(struct clk *clk) | 62 | static 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 | ||
97 | static void omap1_clk_allow_idle(struct clk *clk) | 97 | static 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 | ||
415 | static int omap1_clk_use(struct clk *clk) | 415 | static 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 | ||
443 | static void omap1_clk_unuse(struct clk *clk) | 443 | static 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 | ||
456 | static int omap1_clk_enable(struct clk *clk) | 456 | static 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 | ||
495 | static void omap1_clk_disable(struct clk *clk) | 495 | static 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 | ||
656 | static struct clk_functions omap1_clk_functions = { | 656 | static 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 | ||
16 | static int omap1_clk_enable(struct clk * clk); | 16 | static int omap1_clk_enable_generic(struct clk * clk); |
17 | static void omap1_clk_disable(struct clk * clk); | 17 | static void omap1_clk_disable_generic(struct clk * clk); |
18 | static void omap1_ckctl_recalc(struct clk * clk); | 18 | static void omap1_ckctl_recalc(struct clk * clk); |
19 | static void omap1_watchdog_recalc(struct clk * clk); | 19 | static void omap1_watchdog_recalc(struct clk * clk); |
20 | static void omap1_ckctl_recalc_dsp_domain(struct clk * clk); | 20 | static 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); | |||
30 | static void omap1_init_ext_clk(struct clk * clk); | 30 | static void omap1_init_ext_clk(struct clk * clk); |
31 | static int omap1_select_table_rate(struct clk * clk, unsigned long rate); | 31 | static int omap1_select_table_rate(struct clk * clk, unsigned long rate); |
32 | static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); | 32 | static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); |
33 | static int omap1_clk_use(struct clk *clk); | 33 | static int omap1_clk_enable(struct clk *clk); |
34 | static void omap1_clk_unuse(struct clk *clk); | 34 | static void omap1_clk_disable(struct clk *clk); |
35 | 35 | ||
36 | struct mpu_rate { | 36 | struct 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 | ||
159 | static struct clk ck_dpll1 = { | 159 | static 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 | ||
168 | static struct arm_idlect1_clk ck_dpll1out = { | 168 | static 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 | ||
193 | static struct arm_idlect1_clk armper_ck = { | 193 | static 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 | ||
220 | static struct arm_idlect1_clk armxor_ck = { | 220 | static 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 | ||
279 | static struct clk dsp_ck = { | 279 | static 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 | ||
292 | static struct clk dspmmu_ck = { | 292 | static 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 | ||
303 | static struct clk dspper_ck = { | 303 | static 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 | ||
371 | static struct clk tipb_ck = { | 371 | static 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 | ||
381 | static struct clk l3_ocpi_ck = { | 381 | static 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 | ||
393 | static struct clk tc1_ck = { | 393 | static 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 | ||
404 | static struct clk tc2_ck = { | 404 | static 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 | ||
415 | static struct clk dma_ck = { | 415 | static 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 | ||
426 | static struct clk dma_lcdfree_ck = { | 426 | static 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 | ||
435 | static struct arm_idlect1_clk api_ck = { | 435 | static 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 | ||
473 | static struct clk rhea2_ck = { | 473 | static 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 | ||
482 | static struct clk lcd_ck_16xx = { | 482 | static 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 | ||
494 | static struct arm_idlect1_clk lcd_ck_1510 = { | 494 | static 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 | ||
525 | static struct uart_clk uart1_16xx = { | 525 | static 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 | ||
557 | static struct clk uart3_1510 = { | 557 | static 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 | ||
572 | static struct uart_clk uart3_16xx = { | 572 | static 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 | ||
600 | static struct clk usb_hhc_ck1510 = { | 600 | static 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 | ||
612 | static struct clk usb_hhc_ck16xx = { | 612 | static 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 | ||
625 | static struct clk usb_dc_ck = { | 625 | static 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 | ||
636 | static struct clk mclk_1510 = { | 636 | static 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 | ||
645 | static struct clk mclk_16xx = { | 645 | static 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 | ||
658 | static struct clk bclk_1510 = { | 658 | static 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 | ||
667 | static struct clk bclk_16xx = { | 667 | static 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 | ||
680 | static struct clk mmc1_ck = { | 680 | static 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 | ||
693 | static struct clk mmc2_ck = { | 693 | static 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 | ||
706 | static struct clk virtual_ck_mpu = { | 706 | static 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 | ||
718 | static struct clk * onchip_clks[] = { | 718 | static 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 | */ |
114 | static int omap2_clk_enable(struct clk * clk) | 114 | static 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 */ |
153 | static void omap2_clk_disable(struct clk *clk) | 153 | static 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 | ||
170 | static int omap2_clk_use(struct clk *clk) | 170 | static 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 | ||
194 | static void omap2_clk_unuse(struct clk *clk) | 194 | static 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) | |||
999 | static struct clk_functions omap2_clk_functions = { | 999 | static 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 | } |
1051 | late_initcall(omap2_disable_unused_clocks); | 1049 | late_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); | |||
24 | static void omap2_mpu_recalc(struct clk * clk); | 24 | static void omap2_mpu_recalc(struct clk * clk); |
25 | static int omap2_select_table_rate(struct clk * clk, unsigned long rate); | 25 | static int omap2_select_table_rate(struct clk * clk, unsigned long rate); |
26 | static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate); | 26 | static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate); |
27 | static void omap2_clk_unuse(struct clk *clk); | 27 | static void omap2_clk_disable(struct clk *clk); |
28 | static void omap2_sys_clk_recalc(struct clk * clk); | 28 | static void omap2_sys_clk_recalc(struct clk * clk); |
29 | static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val); | 29 | static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val); |
30 | static u32 omap2_clksel_get_divisor(struct clk *clk); | 30 | static 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 | ||
860 | static struct clk usb_l4_ick = { /* FS-USB interface clock */ | 860 | static 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 | ||
1840 | static struct clk usbhs_ick = { | 1840 | static 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); | |||
34 | static struct clk_functions *arch_clock; | 34 | static 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 | ||
40 | struct clk * clk_get(struct device *dev, const char *id) | 40 | struct 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 | } |
88 | EXPORT_SYMBOL(clk_disable); | 80 | EXPORT_SYMBOL(clk_disable); |
89 | 81 | ||
90 | int 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 | } | ||
102 | EXPORT_SYMBOL(clk_use); | ||
103 | |||
104 | void 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 | } | ||
113 | EXPORT_SYMBOL(clk_unuse); | ||
114 | |||
115 | int clk_get_usecount(struct clk *clk) | 82 | int 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) | |||
146 | EXPORT_SYMBOL(clk_put); | 113 | EXPORT_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 | ||
152 | long clk_round_rate(struct clk *clk, unsigned long rate) | 119 | long 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) | |||
190 | static void omap_mcbsp_dsp_request(void) | 190 | static 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) | |||
208 | static void omap_mcbsp_dsp_free(void) | 208 | static 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 | ||
38 | static 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 | */ |
43 | asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) | 41 | asmlinkage 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(¤t->sighand->siglock); | 44 | spin_lock_irq(¤t->sighand->siglock); |
49 | saveset = current->blocked; | 45 | current->saved_sigmask = current->blocked; |
50 | siginitset(¤t->blocked, mask); | 46 | siginitset(¤t->blocked, mask); |
51 | recalc_sigpending(); | 47 | recalc_sigpending(); |
52 | spin_unlock_irq(¤t->sighand->siglock); | 48 | spin_unlock_irq(¤t->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 | |||
72 | asmlinkage 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(¤t->sighand->siglock); | ||
85 | saveset = current->blocked; | ||
86 | current->blocked = newset; | ||
87 | recalc_sigpending(); | ||
88 | spin_unlock_irq(¤t->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 | ||
108 | asmlinkage int sys_sigaction(int sig, | 56 | asmlinkage 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 | ||
377 | give_sigsegv: | 325 | give_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 | ||
476 | give_sigsegv: | 424 | give_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(¤t->sighand->siglock); | 468 | spin_lock_irq(¤t->sighand->siglock); |
521 | sigorsets(¤t->blocked, ¤t->blocked, | 469 | sigorsets(¤t->blocked, ¤t->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 | */ |
539 | static int do_signal(sigset_t *oldset) | 487 | static 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 = ¤t->saved_sigmask; | ||
508 | else | ||
558 | oldset = ¤t->blocked; | 509 | oldset = ¤t->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 | ||
564 | no_signal: | 525 | no_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, ¤t->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 | */ |
590 | asmlinkage void do_notify_resume(__u32 thread_info_flags) | 558 | asmlinkage 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 | } |
49 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); | 48 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); |
50 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); | 49 | DECLARE_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 @@ | |||
37 | asmlinkage int | 37 | asmlinkage int |
38 | sys_sigsuspend(int history0, int history1, old_sigset_t mask) | 38 | sys_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(¤t->sighand->siglock); | 41 | spin_lock_irq(¤t->sighand->siglock); |
45 | saveset = current->blocked; | 42 | current->saved_sigmask = current->blocked; |
46 | siginitset(¤t->blocked, mask); | 43 | siginitset(¤t->blocked, mask); |
47 | recalc_sigpending(); | 44 | recalc_sigpending(); |
48 | spin_unlock_irq(¤t->sighand->siglock); | 45 | spin_unlock_irq(¤t->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 | |||
59 | asmlinkage int | ||
60 | sys_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(¤t->sighand->siglock); | ||
73 | saveset = current->blocked; | ||
74 | current->blocked = newset; | ||
75 | recalc_sigpending(); | ||
76 | spin_unlock_irq(¤t->sighand->siglock); | ||
77 | |||
78 | regs.eax = -EINTR; | ||
79 | while (1) { | ||
80 | current->state = TASK_INTERRUPTIBLE; | ||
81 | schedule(); | ||
82 | if (do_signal(®s, &saveset)) | ||
83 | return -EINTR; | ||
84 | } | ||
85 | } | 51 | } |
86 | 52 | ||
87 | asmlinkage int | 53 | asmlinkage 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 | ||
438 | give_sigsegv: | 404 | give_sigsegv: |
439 | force_sigsegv(sig, current); | 405 | force_sigsegv(sig, current); |
440 | return 0; | 406 | return -EFAULT; |
441 | } | 407 | } |
442 | 408 | ||
443 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 409 | static 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 | ||
532 | give_sigsegv: | 498 | give_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(¤t->sighand->siglock); | 551 | spin_lock_irq(¤t->sighand->siglock); |
586 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 552 | sigorsets(¤t->blocked,¤t->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 | */ |
601 | int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) | 567 | static 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 = ¤t->saved_sigmask; | ||
590 | else | ||
622 | oldset = ¤t->blocked; | 591 | oldset = ¤t->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: | 616 | no_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, ¤t->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))) |
662 | void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | 648 | void 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 |
558 | CONFIG_E1000=y | 558 | CONFIG_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 |
566 | CONFIG_E1000=y | 566 | CONFIG_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 |
549 | CONFIG_E1000=y | 549 | CONFIG_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 |
566 | CONFIG_E1000=y | 566 | CONFIG_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: */ |
89 | static DECLARE_MUTEX(ia32_mmap_sem); | 89 | static DEFINE_MUTEX(ia32_mmap_mutex); |
90 | 90 | ||
91 | asmlinkage long | 91 | asmlinkage long |
92 | sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, | 92 | sys32_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(¤t->mm->mmap_sem); | 904 | down_write(¤t->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 | |||
58 | struct 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 | */ | ||
174 | static u8 war_implemented = 0; | ||
175 | |||
176 | static 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 | */ |
172 | static void sn_fixup_ionodes(void) | 209 | static 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 | */ |
30 | static DECLARE_MUTEX(sn_oemdata_mutex); | 31 | static DEFINE_MUTEX(sn_oemdata_mutex); |
31 | static u8 **sn_oemdata; | 32 | static u8 **sn_oemdata; |
32 | static u64 *sn_oemdata_size, sn_oemdata_bufsize; | 33 | static u64 *sn_oemdata_size, sn_oemdata_bufsize; |
33 | 34 | ||
@@ -89,7 +90,7 @@ static int | |||
89 | sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, | 90 | sn_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(®istration->sema) != 0) { | 140 | if (mutex_lock_interruptible(®istration->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(®istration->sema); | 146 | mutex_unlock(®istration->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(®istration->sema); | 158 | mutex_unlock(®istration->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(®istration->sema); | 194 | mutex_lock(®istration->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(®istration->sema); | 198 | mutex_unlock(®istration->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(®istration->sema); | 212 | mutex_unlock(®istration->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 | |||
534 | xpc_allocate_msgqueues(struct xpc_channel *ch) | 536 | xpc_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(®istration->sema) != 0) { | 1089 | if (mutex_trylock(®istration->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(®istration->sema); | 1094 | mutex_unlock(®istration->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(®istration->sema); | 1105 | mutex_unlock(®istration->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(®istration->sema); | 1137 | mutex_unlock(®istration->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(®istration->sema); | 1152 | mutex_unlock(®istration->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); | |||
177 | static unsigned long xpc_hb_check_timeout; | 178 | static 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 */ |
180 | static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); | 181 | static 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 */ |
183 | static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); | 184 | static DECLARE_COMPLETION(xpc_discovery_exited); |
184 | 185 | ||
185 | 186 | ||
186 | static struct timer_list xpc_hb_timer; | 187 | static 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 |
603 | CONFIG_E1000=m | 603 | CONFIG_E1000=m |
604 | CONFIG_E1000_NAPI=y | 604 | CONFIG_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 |
627 | CONFIG_E1000=m | 627 | CONFIG_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 |
534 | CONFIG_E1000=m | 534 | CONFIG_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 |
676 | CONFIG_E1000=y | 676 | CONFIG_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 |
568 | CONFIG_E1000=m | 568 | CONFIG_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 |
455 | CONFIG_E1000=y | 455 | CONFIG_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 |
725 | CONFIG_E1000=y | 725 | CONFIG_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 |
672 | CONFIG_E1000=y | 672 | CONFIG_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 |
363 | 8: | 363 | 8: |
@@ -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 | ||
689 | restore_user: | 689 | restore_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 |
922 | do_user_signal: /* r10 contains MSR_KERNEL here */ | 922 | do_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 | */ |
255 | long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, | 255 | long 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(¤t->sighand->siglock); | 264 | spin_unlock_irq(¤t->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 | |||
280 | long 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(¤t->sighand->siglock); | ||
300 | saveset = current->blocked; | ||
301 | current->blocked = newset; | ||
302 | recalc_sigpending(); | ||
303 | spin_unlock_irq(¤t->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 = ¤t->saved_sigmask; | ||
1144 | else if (!oldset) | ||
1189 | oldset = ¤t->blocked; | 1145 | oldset = ¤t->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 |
1195 | no_signal: | 1149 | no_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, ¤t->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(¤t->blocked, signr); | 1213 | sigaddset(¤t->blocked, signr); |
1254 | recalc_sigpending(); | 1214 | recalc_sigpending(); |
1255 | spin_unlock_irq(¤t->sighand->siglock); | 1215 | spin_unlock_irq(¤t->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 | */ | ||
74 | long 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(¤t->sighand->siglock); | ||
88 | saveset = current->blocked; | ||
89 | current->blocked = newset; | ||
90 | recalc_sigpending(); | ||
91 | spin_unlock_irq(¤t->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 | |||
106 | long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r5, | 70 | long 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 = ¤t->saved_sigmask; | ||
525 | else if (!oldset) | ||
560 | oldset = ¤t->blocked; | 526 | oldset = ¤t->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, ¤t->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) | |||
321 | SYSCALL(inotify_rm_watch) | 321 | SYSCALL(inotify_rm_watch) |
322 | SYSCALL(spu_run) | 322 | SYSCALL(spu_run) |
323 | SYSCALL(spu_create) | 323 | SYSCALL(spu_create) |
324 | COMPAT_SYS(pselect6) | ||
325 | COMPAT_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 |
500 | CONFIG_E1000=y | 500 | CONFIG_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 |
489 | CONFIG_E1000=y | 489 | CONFIG_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 |
403 | CONFIG_E1000=y | 403 | CONFIG_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 |
443 | CONFIG_E1000=y | 443 | CONFIG_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 | ||
1281 | sys_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 | |||
1294 | 1: | ||
1295 | /* We are returning to a signal handler. */ | ||
1296 | RESTORE_ALL | ||
1297 | |||
1298 | .align 4 | ||
1299 | .globl sys_sigsuspend | ||
1300 | sys_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 | |||
1312 | 1: | ||
1313 | /* We are returning to a signal handler. */ | ||
1314 | RESTORE_ALL | ||
1315 | |||
1316 | .align 4 | ||
1317 | .globl sys_rt_sigsuspend | ||
1318 | sys_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 | |||
1331 | 1: | ||
1332 | /* We are returning to a signal handler. */ | ||
1333 | RESTORE_ALL | ||
1334 | |||
1335 | .align 4 | ||
1336 | .globl sys_sigreturn | 1280 | .globl sys_sigreturn |
1337 | sys_sigreturn: | 1281 | sys_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 |
70 | signal_p: | 70 | signal_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); |
36 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); | 36 | extern void fpload(unsigned long *fpregs, unsigned long *fsr); |
37 | 37 | ||
38 | asmlinkage 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 | /* | 95 | static 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 | */ | ||
102 | asmlinkage 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(¤t->sighand->siglock); | 98 | spin_lock_irq(¤t->sighand->siglock); |
108 | saveset = current->blocked; | 99 | current->saved_sigmask = current->blocked; |
109 | siginitset(¤t->blocked, set); | 100 | siginitset(¤t->blocked, set); |
110 | recalc_sigpending(); | 101 | recalc_sigpending(); |
111 | spin_unlock_irq(¤t->sighand->siglock); | 102 | spin_unlock_irq(¤t->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 | ||
135 | asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) | 108 | return -ERESTARTNOHAND; |
136 | { | ||
137 | _sigpause_common(set, regs); | ||
138 | } | 109 | } |
139 | 110 | ||
140 | asmlinkage void do_sigsuspend (struct pt_regs *regs) | 111 | asmlinkage 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 | ||
145 | asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | 116 | asmlinkage 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(¤t->sighand->siglock); | ||
165 | oldset = current->blocked; | ||
166 | current->blocked = set; | ||
167 | recalc_sigpending(); | ||
168 | spin_unlock_irq(¤t->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 | ||
192 | static inline int | 121 | static 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 | */ |
1070 | asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, | 999 | asmlinkage 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 = ¤t->saved_sigmask; | ||
1023 | else | ||
1093 | oldset = ¤t->blocked; | 1024 | oldset = ¤t->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, ¤t->saved_sigmask, NULL); | ||
1063 | } | ||
1119 | } | 1064 | } |
1120 | 1065 | ||
1121 | asmlinkage int | 1066 | asmlinkage 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 | ||
67 | extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *); | 67 | extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *); |
68 | extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *); | 68 | extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *); |
69 | void _sigpause_common (unsigned int set, struct pt_regs *); | ||
70 | extern void (*__copy_1page)(void *, const void *); | 69 | extern void (*__copy_1page)(void *, const void *); |
71 | extern void __memmove(void *, const void *, __kernel_size_t); | 70 | extern void __memmove(void *, const void *, __kernel_size_t); |
72 | extern void (*bzero_1page)(void *); | 71 | extern void (*bzero_1page)(void *); |
@@ -227,7 +226,6 @@ EXPORT_SYMBOL(kunmap_atomic); | |||
227 | /* Solaris/SunOS binary compatibility */ | 226 | /* Solaris/SunOS binary compatibility */ |
228 | EXPORT_SYMBOL(svr4_setcontext); | 227 | EXPORT_SYMBOL(svr4_setcontext); |
229 | EXPORT_SYMBOL(svr4_getcontext); | 228 | EXPORT_SYMBOL(svr4_getcontext); |
230 | EXPORT_SYMBOL(_sigpause_common); | ||
231 | 229 | ||
232 | EXPORT_SYMBOL(dump_thread); | 230 | EXPORT_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 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_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 |
423 | CONFIG_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 |
530 | CONFIG_E1000=m | 534 | CONFIG_E1000=m |
531 | CONFIG_E1000_NAPI=y | 535 | CONFIG_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 | |||
652 | CONFIG_SERIAL_SUNSAB=m | 657 | CONFIG_SERIAL_SUNSAB=m |
653 | CONFIG_SERIAL_CORE=y | 658 | CONFIG_SERIAL_CORE=y |
654 | CONFIG_SERIAL_CORE_CONSOLE=y | 659 | CONFIG_SERIAL_CORE_CONSOLE=y |
655 | # CONFIG_SERIAL_JSM is not set | ||
656 | CONFIG_UNIX98_PTYS=y | 660 | CONFIG_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 | # |
1015 | CONFIG_USB_HID=y | 1025 | CONFIG_USB_HID=y |
1016 | CONFIG_USB_HIDINPUT=y | 1026 | CONFIG_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 |
1018 | CONFIG_USB_HIDDEV=y | 1029 | CONFIG_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 | # |
1270 | CONFIG_PRINTK_TIME=y | 1281 | CONFIG_PRINTK_TIME=y |
1271 | CONFIG_DEBUG_KERNEL=y | ||
1272 | CONFIG_MAGIC_SYSRQ=y | 1282 | CONFIG_MAGIC_SYSRQ=y |
1283 | CONFIG_DEBUG_KERNEL=y | ||
1273 | CONFIG_LOG_BUF_SHIFT=18 | 1284 | CONFIG_LOG_BUF_SHIFT=18 |
1274 | CONFIG_DETECT_SOFTLOCKUP=y | 1285 | CONFIG_DETECT_SOFTLOCKUP=y |
1275 | CONFIG_SCHEDSTATS=y | 1286 | CONFIG_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 |
1282 | CONFIG_DEBUG_FS=y | 1294 | CONFIG_DEBUG_FS=y |
1283 | # CONFIG_DEBUG_VM is not set | 1295 | # CONFIG_DEBUG_VM is not set |
1296 | CONFIG_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 |
1443 | sys_sigsuspend: add %sp, PTREGS_OFF, %o0 | ||
1444 | call do_sigsuspend | ||
1445 | add %o7, 1f-.-4, %o7 | ||
1446 | nop | ||
1447 | sys_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 | ||
1454 | sys32_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 */ | ||
1461 | sys_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 |
1467 | sys32_sigreturn: | 1444 | sys32_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 | ||
167 | static void show_regwindow32(struct pt_regs *regs) | 168 | static 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 | ||
193 | static void show_regwindow(struct pt_regs *regs) | 197 | static 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 | ||
56 | 1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 | 56 | 1: 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 |
99 | 1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 | 98 | 1: 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 | ||
39 | static 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. */ |
43 | asmlinkage void sparc64_set_context(struct pt_regs *regs) | 40 | asmlinkage 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 | /* | 242 | static 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 | */ | ||
249 | asmlinkage 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(¤t->sighand->siglock); | 245 | spin_lock_irq(¤t->sighand->siglock); |
263 | saveset = current->blocked; | 246 | current->saved_sigmask = current->blocked; |
264 | siginitset(¤t->blocked, set); | 247 | siginitset(¤t->blocked, set); |
265 | recalc_sigpending(); | 248 | recalc_sigpending(); |
266 | spin_unlock_irq(¤t->sighand->siglock); | 249 | spin_unlock_irq(¤t->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 | ||
295 | asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs) | 257 | asmlinkage long sys_sigpause(unsigned int set) |
296 | { | 258 | { |
297 | _sigpause_common(set, regs); | 259 | return _sigpause_common(set); |
298 | } | 260 | } |
299 | 261 | ||
300 | asmlinkage void do_sigsuspend(struct pt_regs *regs) | 262 | asmlinkage 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 | |||
305 | asmlinkage 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(¤t->sighand->siglock); | ||
323 | oldset = current->blocked; | ||
324 | current->blocked = set; | ||
325 | recalc_sigpending(); | ||
326 | spin_unlock_irq(¤t->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 | ||
355 | static inline int | 267 | static 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 | */ |
610 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, | 522 | static 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 = ¤t->saved_sigmask; | ||
535 | else | ||
622 | oldset = ¤t->blocked; | 536 | oldset = ¤t->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, ¤t->saved_sigmask, NULL); | ||
585 | } | ||
656 | } | 586 | } |
657 | 587 | ||
658 | void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, | 588 | void 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 | ||
666 | void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) | 595 | void 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 | ||
35 | int 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 | */ | ||
233 | asmlinkage 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(¤t->sighand->siglock); | ||
239 | saveset = current->blocked; | ||
240 | siginitset(¤t->blocked, set); | ||
241 | recalc_sigpending(); | ||
242 | spin_unlock_irq(¤t->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 | |||
270 | asmlinkage 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(¤t->sighand->siglock); | ||
294 | oldset = current->blocked; | ||
295 | current->blocked = set; | ||
296 | recalc_sigpending(); | ||
297 | spin_unlock_irq(¤t->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 | |||
325 | static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | 226 | static 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 | */ |
1365 | int do_signal32(sigset_t *oldset, struct pt_regs * regs, | 1266 | void 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, ¤t->saved_sigmask, NULL); | ||
1316 | } | ||
1401 | } | 1317 | } |
1402 | 1318 | ||
1403 | struct sigstack32 { | 1319 | struct 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 | ||
70 | extern void die_if_kernel(char *str, struct pt_regs *regs); | 70 | extern void die_if_kernel(char *str, struct pt_regs *regs); |
71 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | 71 | extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); |
72 | void _sigpause_common (unsigned int set, struct pt_regs *); | ||
73 | extern void *__bzero(void *, size_t); | 72 | extern void *__bzero(void *, size_t); |
74 | extern void *__memscan_zero(void *, size_t); | 73 | extern void *__memscan_zero(void *, size_t); |
75 | extern void *__memscan_generic(void *, int, size_t); | 74 | extern 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. */ |
237 | EXPORT_SYMBOL(io_remap_pfn_range); | 236 | EXPORT_SYMBOL(io_remap_pfn_range); |
238 | 237 | ||
238 | #ifdef CONFIG_COMPAT | ||
239 | /* Solaris/SunOS binary compatibility */ | 239 | /* Solaris/SunOS binary compatibility */ |
240 | EXPORT_SYMBOL(_sigpause_common); | ||
241 | EXPORT_SYMBOL(verify_compat_iovec); | 240 | EXPORT_SYMBOL(verify_compat_iovec); |
241 | #endif | ||
242 | 242 | ||
243 | EXPORT_SYMBOL(dump_fpu); | 243 | EXPORT_SYMBOL(dump_fpu); |
244 | EXPORT_SYMBOL(pte_alloc_one_kernel); | 244 | EXPORT_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) | |||
1003 | asmlinkage long sparc32_open(const char __user *filename, | 1003 | asmlinkage 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 | ||
1009 | extern unsigned long do_mremap(unsigned long addr, | 1009 | extern 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 |
185 | solaris_getpid: | 187 | solaris_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 | ||
144 | config HPPFS | 144 | config 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 | |||
162 | config MCONSOLE | 159 | config 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 | ||
245 | config HIGHMEM | 242 | config 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 | ||
249 | config KERNEL_STACK_ORDER | 254 | config KERNEL_STACK_ORDER |
250 | int "Kernel stack size order" | 255 | int "Kernel stack size order" |
@@ -269,17 +274,13 @@ endmenu | |||
269 | 274 | ||
270 | source "init/Kconfig" | 275 | source "init/Kconfig" |
271 | 276 | ||
272 | source "net/Kconfig" | 277 | source "drivers/block/Kconfig" |
273 | |||
274 | source "drivers/base/Kconfig" | ||
275 | 278 | ||
276 | source "arch/um/Kconfig.char" | 279 | source "arch/um/Kconfig.char" |
277 | 280 | ||
278 | source "drivers/block/Kconfig" | 281 | source "drivers/base/Kconfig" |
279 | 282 | ||
280 | config NETDEVICES | 283 | source "net/Kconfig" |
281 | bool | ||
282 | default NET | ||
283 | 284 | ||
284 | source "arch/um/Kconfig.net" | 285 | source "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 | ||
24 | config 3_LEVEL_PGTABLES | 24 | config 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 | |||
32 | config STUB_CODE | 36 | config 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 | |||
32 | um-modes-$(CONFIG_MODE_SKAS) += skas | 32 | um-modes-$(CONFIG_MODE_SKAS) += skas |
33 | 33 | ||
34 | MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ | 34 | MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ |
35 | -I$(srctree)/$(ARCH_DIR)/kernel/$(mode)/include) | 35 | -I$(srctree)/$(ARCH_DIR)/include/$(mode)) |
36 | 36 | ||
37 | MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\ | 37 | MAKEFILES-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 | ||
167 | int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) | 173 | int 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 | ||
15 | struct fd_chan { | 16 | struct 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 | ||
71 | static void uml_dev_close(void* dev) | ||
72 | { | ||
73 | dev_close( (struct net_device *) dev); | ||
74 | } | ||
75 | |||
71 | irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 76 | irqreturn_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: | 102 | out: |
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(¨_net_driver); | 338 | platform_driver_register(¨_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 | ||
1106 | static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) | 1106 | static 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 | ||
1133 | static int backing_file_mismatch(char *file, __u64 size, time_t mtime) | 1135 | static 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, §orsize, &align, bitmap_offset_out); | 1220 | &size, §orsize, &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 | ||
1251 | int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, | 1256 | int 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); | |||
120 | extern int is_syscall(unsigned long addr); | 120 | extern int is_syscall(unsigned long addr); |
121 | extern void arch_switch(void); | 121 | extern void arch_switch(void); |
122 | extern void free_irq(unsigned int, void *); | 122 | extern void free_irq(unsigned int, void *); |
123 | extern int um_in_interrupt(void); | ||
124 | extern int cpu(void); | 123 | extern int cpu(void); |
124 | |||
125 | /* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */ | ||
126 | extern int __cant_sleep(void); | ||
125 | extern void segv_handler(int sig, union uml_pt_regs *regs); | 127 | extern void segv_handler(int sig, union uml_pt_regs *regs); |
126 | extern void sigio_handler(int sig, union uml_pt_regs *regs); | 128 | extern 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); |
191 | extern int os_unmap_memory(void *addr, int len); | 192 | extern int os_unmap_memory(void *addr, int len); |
192 | extern void os_flush_stdout(void); | 193 | extern void os_flush_stdout(void); |
193 | extern 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 | */ |
198 | extern void stop(void); | ||
199 | extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); | ||
198 | extern int protect_memory(unsigned long addr, unsigned long len, | 200 | extern 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); |
200 | extern void forward_pending_sigio(int target); | 202 | extern void forward_pending_sigio(int target); |
@@ -230,9 +232,63 @@ extern void block_signals(void); | |||
230 | extern void unblock_signals(void); | 232 | extern void unblock_signals(void); |
231 | extern int get_signals(void); | 233 | extern int get_signals(void); |
232 | extern int set_signals(int enable); | 234 | extern int set_signals(int enable); |
235 | extern void os_usr1_signal(int on); | ||
233 | 236 | ||
234 | /* trap.c */ | 237 | /* trap.c */ |
235 | extern void os_fill_handlinfo(struct kern_handlers h); | 238 | extern void os_fill_handlinfo(struct kern_handlers h); |
236 | extern void do_longjmp(void *p, int val); | 239 | extern void do_longjmp(void *p, int val); |
237 | 240 | ||
241 | /* util.c */ | ||
242 | extern void stack_protections(unsigned long address); | ||
243 | extern void task_protections(unsigned long address); | ||
244 | extern int raw(int fd); | ||
245 | extern void setup_machinename(char *machine_out); | ||
246 | extern void setup_hostinfo(void); | ||
247 | extern int setjmp_wrapper(void (*proc)(void *, void *), ...); | ||
248 | |||
249 | /* time.c */ | ||
250 | #define BILLION (1000 * 1000 * 1000) | ||
251 | |||
252 | extern void switch_timers(int to_real); | ||
253 | extern void idle_sleep(int secs); | ||
254 | extern void enable_timer(void); | ||
255 | extern void disable_timer(void); | ||
256 | extern void user_time_init(void); | ||
257 | extern void uml_idle_timer(void); | ||
258 | extern unsigned long long os_nsecs(void); | ||
259 | |||
260 | /* skas/mem.c */ | ||
261 | extern long run_syscall_stub(struct mm_id * mm_idp, | ||
262 | int syscall, unsigned long *args, long expected, | ||
263 | void **addr, int done); | ||
264 | extern long syscall_stub_data(struct mm_id * mm_idp, | ||
265 | unsigned long *data, int data_count, | ||
266 | void **addr, void **stub_addr); | ||
267 | extern 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); | ||
270 | extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, | ||
271 | int done, void **data); | ||
272 | extern 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 */ | ||
277 | extern int is_skas_winch(int pid, int fd, void *data); | ||
278 | extern int start_userspace(unsigned long stub_stack); | ||
279 | extern int copy_context_skas0(unsigned long stack, int pid); | ||
280 | extern void userspace(union uml_pt_regs *regs); | ||
281 | extern void map_stub_pages(int fd, unsigned long code, | ||
282 | unsigned long data, unsigned long stack); | ||
283 | extern void new_thread(void *stack, void **switch_buf_ptr, | ||
284 | void **fork_buf_ptr, void (*handler)(int)); | ||
285 | extern void thread_wait(void *sw, void *fb); | ||
286 | extern void switch_threads(void *me, void *next); | ||
287 | extern int start_idle_thread(void *stack, void *switch_buf_ptr, | ||
288 | void **fork_buf_ptr); | ||
289 | extern void initial_thread_cb_skas(void (*proc)(void *), | ||
290 | void *arg); | ||
291 | extern void halt_skas(void); | ||
292 | extern 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 | |||
13 | struct 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 | |||
22 | extern 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 | |||
11 | extern unsigned long exec_regs[]; | ||
12 | extern unsigned long exec_fp_regs[]; | ||
13 | extern unsigned long exec_fpx_regs[]; | ||
14 | extern int have_fpx_regs; | ||
15 | |||
16 | extern void sig_handler_common_skas(int sig, void *sc_ptr); | ||
17 | extern 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); |
20 | extern void release_thread_skas(struct task_struct *task); | 20 | extern void release_thread_skas(struct task_struct *task); |
21 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); | ||
22 | extern void init_idle_skas(void); | 21 | extern void init_idle_skas(void); |
23 | extern void flush_tlb_kernel_range_skas(unsigned long start, | 22 | extern 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 | ||
23 | struct mm_munmap { | 23 | struct mm_munmap { |
24 | unsigned long addr; | 24 | unsigned long addr; |
25 | unsigned long len; | 25 | unsigned long len; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct mm_mprotect { | 28 | struct 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 | ||
34 | struct proc_mm_op { | 34 | struct 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 | |||
12 | extern int userspace_pid[]; | ||
13 | extern int proc_mm, ptrace_faultinfo, ptrace_ldt; | ||
14 | extern int skas_needs_stub; | ||
15 | |||
16 | extern int user_thread(unsigned long stack, int flags); | ||
17 | extern void new_thread_proc(void *stack, void (*handler)(int sig)); | ||
18 | extern void new_thread_handler(int sig); | ||
19 | extern void handle_syscall(union uml_pt_regs *regs); | ||
20 | extern void user_signal(int sig, union uml_pt_regs *regs, int pid); | ||
21 | extern int new_mm(unsigned long stack); | ||
22 | extern void get_skas_faultinfo(int pid, struct faultinfo * fi); | ||
23 | extern long execute_syscall_skas(void *r); | ||
24 | extern 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); | |||
19 | extern int strnlen_user_skas(const void __user *str, int len); | 19 | extern 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 | |||
9 | extern void timer(void); | ||
10 | extern void switch_timers(int to_real); | ||
11 | extern void idle_sleep(int secs); | ||
12 | extern void enable_timer(void); | ||
13 | extern void prepare_timer(void * ptr); | ||
14 | extern void disable_timer(void); | ||
15 | extern unsigned long time_lock(void); | ||
16 | extern void time_unlock(unsigned long); | ||
17 | extern 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 | |||
9 | struct 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 | |||
11 | enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; | ||
12 | |||
13 | extern int tracing_pid; | ||
14 | |||
15 | extern int tracer(int (*init_proc)(void *), void *sp); | ||
16 | extern void sig_handler_common_tt(int sig, void *sc); | ||
17 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); | ||
18 | extern void reboot_tt(void); | ||
19 | extern void halt_tt(void); | ||
20 | extern int is_tracer_winch(int pid, int fd, void *data); | ||
21 | extern 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 | |||
14 | extern void switch_to_tt(void *prev, void *next); | ||
15 | extern void flush_thread_tt(void); | ||
16 | extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, | ||
17 | unsigned long esp); | ||
18 | extern 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); | ||
21 | extern void release_thread_tt(struct task_struct *task); | ||
22 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); | ||
23 | extern void init_idle_tt(void); | ||
24 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); | ||
25 | extern void flush_tlb_kernel_vm_tt(void); | ||
26 | extern void __flush_tlb_one_tt(unsigned long addr); | ||
27 | extern void flush_tlb_range_tt(struct vm_area_struct *vma, | ||
28 | unsigned long start, unsigned long end); | ||
29 | extern void flush_tlb_mm_tt(struct mm_struct *mm); | ||
30 | extern void force_flush_all_tt(void); | ||
31 | extern long execute_syscall_tt(void *r); | ||
32 | extern void before_mem_tt(unsigned long brk_start); | ||
33 | extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | ||
34 | unsigned long *task_size_out); | ||
35 | extern int start_uml_tt(void); | ||
36 | extern int external_pid_tt(struct task_struct *task); | ||
37 | extern 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); | |||
46 | extern int strnlen_user_tt(const void __user *str, int len); | 46 | extern 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); | |||
18 | extern unsigned long strlcpy(char *, const char *, unsigned long); | 18 | extern unsigned long strlcpy(char *, const char *, unsigned long); |
19 | extern unsigned long strlcat(char *, const char *, unsigned long); | 19 | extern unsigned long strlcat(char *, const char *, unsigned long); |
20 | extern void *um_vmalloc(int size); | 20 | extern void *um_vmalloc(int size); |
21 | extern void *um_vmalloc_atomic(int size); | ||
21 | extern void vfree(void *ptr); | 22 | extern 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; | |||
44 | extern int pty_output_sigio; | 44 | extern int pty_output_sigio; |
45 | extern int pty_close_sigio; | 45 | extern int pty_close_sigio; |
46 | 46 | ||
47 | extern void stop(void); | ||
48 | extern void stack_protections(unsigned long address); | ||
49 | extern void task_protections(unsigned long address); | ||
50 | extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); | ||
51 | extern void *add_signal_handler(int sig, void (*handler)(int)); | 47 | extern void *add_signal_handler(int sig, void (*handler)(int)); |
52 | extern int linux_main(int argc, char **argv); | 48 | extern int linux_main(int argc, char **argv); |
53 | extern void set_cmdline(char *cmd); | 49 | extern void set_cmdline(char *cmd); |
@@ -55,8 +51,6 @@ extern void input_cb(void (*proc)(void *), void *arg, int arg_len); | |||
55 | extern int get_pty(void); | 51 | extern int get_pty(void); |
56 | extern void *um_kmalloc(int size); | 52 | extern void *um_kmalloc(int size); |
57 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 53 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
58 | extern void setup_machinename(char *machine_out); | ||
59 | extern void setup_hostinfo(void); | ||
60 | extern void do_exec(int old_pid, int new_pid); | 54 | extern void do_exec(int old_pid, int new_pid); |
61 | extern void tracer_panic(char *msg, ...); | 55 | extern void tracer_panic(char *msg, ...); |
62 | extern int detach(int pid, int sig); | 56 | extern int detach(int pid, int sig); |
@@ -70,18 +64,6 @@ extern int cpu_feature(char *what, char *buf, int len); | |||
70 | extern int arch_handle_signal(int sig, union uml_pt_regs *regs); | 64 | extern int arch_handle_signal(int sig, union uml_pt_regs *regs); |
71 | extern int arch_fixup(unsigned long address, void *sc_ptr); | 65 | extern int arch_fixup(unsigned long address, void *sc_ptr); |
72 | extern void arch_init_thread(void); | 66 | extern void arch_init_thread(void); |
73 | extern int setjmp_wrapper(void (*proc)(void *, void *), ...); | ||
74 | extern int raw(int fd); | 67 | extern 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 := | |||
9 | obj-y = config.o exec_kern.o exitcode.o \ | 9 | obj-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 | ||
16 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 15 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
17 | obj-$(CONFIG_GPROF) += gprof_syms.o | 16 | obj-$(CONFIG_GPROF) += gprof_syms.o |
@@ -24,7 +23,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/ | |||
24 | 23 | ||
25 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 24 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
26 | 25 | ||
27 | USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o | 26 | USER_OBJS := $(user-objs-y) config.o tty_log.o |
28 | 27 | ||
29 | include arch/um/scripts/Makefile.rules | 28 | include 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 | ||
289 | void *um_kmalloc(int size) | 288 | void *um_kmalloc(int size) |
290 | { | 289 | { |
291 | return(kmalloc(size, GFP_KERNEL)); | 290 | return kmalloc(size, GFP_KERNEL); |
292 | } | 291 | } |
293 | 292 | ||
294 | void *um_kmalloc_atomic(int size) | 293 | void *um_kmalloc_atomic(int size) |
295 | { | 294 | { |
296 | return(kmalloc(size, GFP_ATOMIC)); | 295 | return kmalloc(size, GFP_ATOMIC); |
297 | } | 296 | } |
298 | 297 | ||
299 | void *um_vmalloc(int size) | 298 | void *um_vmalloc(int size) |
300 | { | 299 | { |
301 | return(vmalloc(size)); | 300 | return vmalloc(size); |
301 | } | ||
302 | |||
303 | void *um_vmalloc_atomic(int size) | ||
304 | { | ||
305 | return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL); | ||
306 | } | ||
307 | |||
308 | int __cant_sleep(void) { | ||
309 | return in_atomic() || irqs_disabled() || in_interrupt(); | ||
310 | /* Is in_interrupt() really needed? */ | ||
302 | } | 311 | } |
303 | 312 | ||
304 | unsigned long get_fault_addr(void) | 313 | unsigned long get_fault_addr(void) |
@@ -370,11 +379,6 @@ int smp_sigio_handler(void) | |||
370 | return(0); | 379 | return(0); |
371 | } | 380 | } |
372 | 381 | ||
373 | int um_in_interrupt(void) | ||
374 | { | ||
375 | return(in_interrupt()); | ||
376 | } | ||
377 | |||
378 | int cpu(void) | 382 | int 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 | ||
340 | static int setup_initial_poll(int fd) | 340 | static 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 | ||
358 | void write_sigio_workaround(void) | 355 | void 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 | ||
406 | int read_sigio_fd(int fd) | 439 | int 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 | ||
102 | static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset) | 102 | static 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 = ¤t->saved_sigmask; | ||
111 | else | ||
112 | oldset = ¤t->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(¤t->thread.regs)); | 154 | is_syscall(PT_REGS_IP(¤t->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, ¤t->saved_sigmask, NULL); | ||
161 | } | ||
140 | return(handled_sig); | 162 | return(handled_sig); |
141 | } | 163 | } |
142 | 164 | ||
143 | int do_signal(void) | 165 | int do_signal(void) |
144 | { | 166 | { |
145 | return(kern_do_signal(¤t->thread.regs, ¤t->blocked)); | 167 | return(kern_do_signal(¤t->thread.regs)); |
146 | } | 168 | } |
147 | 169 | ||
148 | /* | 170 | /* |
@@ -150,63 +172,20 @@ int do_signal(void) | |||
150 | */ | 172 | */ |
151 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask) | 173 | long 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(¤t->sighand->siglock); | 176 | spin_lock_irq(¤t->sighand->siglock); |
157 | saveset = current->blocked; | 177 | current->saved_sigmask = current->blocked; |
158 | siginitset(¤t->blocked, mask); | 178 | siginitset(¤t->blocked, mask); |
159 | recalc_sigpending(); | 179 | recalc_sigpending(); |
160 | spin_unlock_irq(¤t->sighand->siglock); | 180 | spin_unlock_irq(¤t->sighand->siglock); |
161 | 181 | ||
162 | PT_REGS_SYSCALL_RET(¤t->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(¤t->thread.regs, &saveset)) | ||
167 | return(-EINTR); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | long 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(¤t->sighand->siglock); | ||
184 | saveset = current->blocked; | ||
185 | current->blocked = newset; | ||
186 | recalc_sigpending(); | ||
187 | spin_unlock_irq(¤t->sighand->siglock); | ||
188 | |||
189 | PT_REGS_SYSCALL_RET(¤t->thread.regs) = -EINTR; | ||
190 | while (1) { | ||
191 | current->state = TASK_INTERRUPTIBLE; | ||
192 | schedule(); | ||
193 | if (kern_do_signal(¤t->thread.regs, &saveset)) | ||
194 | return(-EINTR); | ||
195 | } | ||
196 | } | 186 | } |
197 | 187 | ||
198 | long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) | 188 | long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) |
199 | { | 189 | { |
200 | return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs))); | 190 | return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->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 | ||
6 | obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ | 6 | obj-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 | ||
9 | USER_OBJS := process.o clone.o | 9 | USER_OBJS := clone.o |
10 | 10 | ||
11 | include arch/um/scripts/Makefile.rules | 11 | include 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 | |||
13 | struct 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 | |||
22 | extern 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 | |||
11 | extern unsigned long exec_regs[]; | ||
12 | extern unsigned long exec_fp_regs[]; | ||
13 | extern unsigned long exec_fpx_regs[]; | ||
14 | extern int have_fpx_regs; | ||
15 | |||
16 | extern void sig_handler_common_skas(int sig, void *sc_ptr); | ||
17 | extern void halt_skas(void); | ||
18 | extern void reboot_skas(void); | ||
19 | extern void kill_off_processes_skas(void); | ||
20 | extern 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 | |||
12 | extern int userspace_pid[]; | ||
13 | extern int proc_mm, ptrace_faultinfo, ptrace_ldt; | ||
14 | extern int skas_needs_stub; | ||
15 | |||
16 | extern void switch_threads(void *me, void *next); | ||
17 | extern void thread_wait(void *sw, void *fb); | ||
18 | extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | ||
19 | void (*handler)(int)); | ||
20 | extern int start_idle_thread(void *stack, void *switch_buf_ptr, | ||
21 | void **fork_buf_ptr); | ||
22 | extern int user_thread(unsigned long stack, int flags); | ||
23 | extern void userspace(union uml_pt_regs *regs); | ||
24 | extern void new_thread_proc(void *stack, void (*handler)(int sig)); | ||
25 | extern void new_thread_handler(int sig); | ||
26 | extern void handle_syscall(union uml_pt_regs *regs); | ||
27 | extern 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); | ||
30 | extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, | ||
31 | int done, void **data); | ||
32 | extern 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); | ||
35 | extern void user_signal(int sig, union uml_pt_regs *regs, int pid); | ||
36 | extern int new_mm(int from, unsigned long stack); | ||
37 | extern int start_userspace(unsigned long stub_stack); | ||
38 | extern int copy_context_skas0(unsigned long stack, int pid); | ||
39 | extern void get_skas_faultinfo(int pid, struct faultinfo * fi); | ||
40 | extern long execute_syscall_skas(void *r); | ||
41 | extern unsigned long current_stub_stack(void); | ||
42 | extern long run_syscall_stub(struct mm_id * mm_idp, | ||
43 | int syscall, unsigned long *args, long expected, | ||
44 | void **addr, int done); | ||
45 | extern 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 = ¤t->mm->context.skas; | 108 | from_mm = ¤t->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 | ||
26 | void switch_to_skas(void *prev, void *next) | 24 | void 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(¤t->thread.mode.skas.switch_buf, | 52 | thread_wait(¤t->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 | ||
83 | void fork_handler(int sig) | 81 | void fork_handler(int sig) |
84 | { | 82 | { |
85 | change_sig(SIGUSR1, 1); | 83 | os_usr1_signal(1); |
86 | thread_wait(¤t->thread.mode.skas.switch_buf, | 84 | thread_wait(¤t->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(¤t->thread.regs.regs); | 96 | userspace(¤t->thread.regs.regs); |
99 | } | 97 | } |
100 | 98 | ||
101 | int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, | 99 | int 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 | ||
126 | extern void map_stub_pages(int fd, unsigned long code, | 124 | int new_mm(unsigned long stack) |
127 | unsigned long data, unsigned long stack); | ||
128 | int 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, ©, 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 | ||
18 | extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | 18 | extern 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 | ||
32 | void record_syscall_end(int index, long result) | 32 | void 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) | |||
39 | int timer_irq_inited = 0; | 39 | int timer_irq_inited = 0; |
40 | 40 | ||
41 | static int first_tick; | 41 | static int first_tick; |
42 | static unsigned long long prev_usecs; | 42 | static unsigned long long prev_nsecs; |
43 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | 43 | #ifdef CONFIG_UML_REAL_TIME_CLOCK |
44 | static long long delta; /* Deviation per interval */ | 44 | static 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 | ||
87 | void boot_timer_handler(int sig) | 87 | void 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(®s.regs) = sc), |
92 | (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)), | ||
93 | (void) (regs.regs.skas.is_user = 0)); | 92 | (void) (regs.regs.skas.is_user = 0)); |
94 | do_timer(®s); | 93 | do_timer(®s); |
95 | } | 94 | } |
96 | 95 | ||
96 | static DEFINE_SPINLOCK(timer_spinlock); | ||
97 | |||
98 | static unsigned long long local_offset = 0; | ||
99 | |||
100 | static 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 | |||
97 | irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) | 113 | irqreturn_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 | ||
108 | long um_time(int __user *tloc) | 129 | long 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 | |
139 | void 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 | |||
154 | static 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 | ||
120 | long um_stime(int __user *tptr) | 167 | long 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 | |||
179 | int 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 | ||
145 | static DEFINE_SPINLOCK(timer_spinlock); | ||
146 | |||
147 | unsigned long time_lock(void) | ||
148 | { | ||
149 | unsigned long flags; | ||
150 | |||
151 | spin_lock_irqsave(&timer_spinlock, flags); | ||
152 | return(flags); | ||
153 | } | ||
154 | |||
155 | void time_unlock(unsigned long flags) | ||
156 | { | ||
157 | spin_unlock_irqrestore(&timer_spinlock, flags); | ||
158 | } | ||
159 | |||
160 | int __init timer_init(void) | 199 | int __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 | ||
24 | extern int debugger_pid; | 25 | extern int debugger_pid; |
25 | extern int debugger_fd; | 26 | extern 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 | |||
9 | struct 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 | ||
24 | long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2, | 25 | long 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 | ||
19 | int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, | 20 | int 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 | ||
6 | obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ | 6 | obj-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 | ||
10 | obj-$(CONFIG_MODE_SKAS) += skas/ | 10 | obj-$(CONFIG_MODE_SKAS) += skas/ |
11 | 11 | ||
12 | USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ | 12 | USER_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 | ||
15 | elf_aux.o: $(ARCH_DIR)/kernel-offsets.h | 15 | elf_aux.o: $(ARCH_DIR)/kernel-offsets.h |
16 | CFLAGS_elf_aux.o += -I$(objtree)/arch/um | 16 | CFLAGS_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); | |||
82 | int main(int argc, char **argv, char **envp) | 81 | int 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 | ||
206 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 207 | int 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 | |||
38 | static int signals_enabled = 1; | ||
39 | static int pending = 0; | ||
23 | 40 | ||
24 | void sig_handler(ARCH_SIGHDLR_PARAM) | 41 | void 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 | ||
33 | extern int timer_irq_inited; | 67 | extern int timer_irq_inited; |
34 | 68 | ||
35 | void alarm_handler(ARCH_SIGHDLR_PARAM) | 69 | static 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 | |||
87 | void 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 | |||
109 | extern void do_boot_timer_handler(struct sigcontext * sc); | ||
110 | |||
111 | void 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 | ||
52 | void set_sigstack(void *sig_stack, int size) | 132 | void 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 | ||
91 | int change_sig(int signal, int on) | 177 | int 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 | |||
105 | static 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 | |||
117 | void block_signals(void) | 187 | void block_signals(void) |
118 | { | 188 | { |
119 | change_signals(SIG_BLOCK); | 189 | signals_enabled = 0; |
120 | } | 190 | } |
121 | 191 | ||
122 | void unblock_signals(void) | 192 | void 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 | ||
136 | static 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 | ||
146 | int get_signals(void) | 238 | int 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 | ||
155 | int set_signals(int enable) | 243 | int 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); | 257 | void 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 | ||
6 | obj-y := trap.o | 6 | obj-y := mem.o process.o trap.o |
7 | 7 | ||
8 | USER_OBJS := trap.o | 8 | USER_OBJS := mem.o process.o trap.o |
9 | 9 | ||
10 | include arch/um/scripts/Makefile.rules | 10 | include 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); | |||
32 | static inline unsigned long *check_init_stack(struct mm_id * mm_idp, | 32 | static 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; | |||
45 | int multi_count = 0; | 45 | int multi_count = 0; |
46 | int multi_op_count = 0; | 46 | int multi_op_count = 0; |
47 | 47 | ||
48 | static long do_syscall_stub(struct mm_id *mm_idp, void **addr) | 48 | static 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 | ||
108 | long run_syscall_stub(struct mm_id * mm_idp, int syscall, | 112 | long 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, | |||
212 | int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, | 216 | int 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 | ||
245 | int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, | 247 | int 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 | ||
279 | void before_mem_skas(unsigned long unused) | 281 | void 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 | |||
39 | int 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 | |||
48 | void 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 | |||
89 | extern unsigned long current_stub_stack(void); | ||
90 | |||
91 | void 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 | |||
117 | static void handle_segv(int pid, union uml_pt_regs * regs) | ||
118 | { | ||
119 | get_skas_faultinfo(pid, ®s->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)*/ | ||
124 | static 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 | |||
154 | extern int __syscall_stub_start; | ||
155 | |||
156 | static 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 | ||
210 | int userspace_pid[NR_CPUS]; | ||
211 | |||
212 | int 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 | |||
251 | void 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 | |||
319 | int 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 | */ | ||
387 | void 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 | |||
432 | void 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 | |||
460 | void 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 | |||
471 | void 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 | |||
481 | static sigjmp_buf initial_jmpbuf; | ||
482 | |||
483 | /* XXX Make these percpu */ | ||
484 | static void (*cb_proc)(void *arg); | ||
485 | static void *cb_arg; | ||
486 | static sigjmp_buf *cb_back; | ||
487 | |||
488 | int 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 | |||
522 | void 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 | |||
541 | void halt_skas(void) | ||
542 | { | ||
543 | block_signals(); | ||
544 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); | ||
545 | } | ||
546 | |||
547 | void reboot_skas(void) | ||
548 | { | ||
549 | block_signals(); | ||
550 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); | ||
551 | } | ||
552 | |||
553 | void 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 | */ | ||
23 | extern struct timespec wall_to_monotonic; | ||
24 | |||
25 | static 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 | |||
35 | void enable_timer(void) | ||
36 | { | ||
37 | set_interval(ITIMER_VIRTUAL); | ||
38 | } | ||
39 | |||
40 | void 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 | |||
52 | void 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 | ||
4 | unsigned long long os_usecs(void) | 74 | void 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 | |||
84 | extern void ktime_get_ts(struct timespec *ts); | ||
85 | #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) | ||
86 | |||
87 | void 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 | |||
100 | unsigned 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 | /* | 108 | void 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 | |||
119 | void 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 | ||
14 | void usr2_handler(int sig, union uml_pt_regs *regs) | 15 | void 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 | ||
65 | void stop(void) | ||
66 | { | ||
67 | while(1) sleep(1000000); | ||
68 | } | ||
69 | |||
70 | int 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 | ||
10 | unsigned long __do_user_copy(void *to, const void *from, int n, | 11 | unsigned 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" | |
33 | void stop(void) | 33 | #include "longjmp.h" |
34 | { | ||
35 | while(1) sleep(1000000); | ||
36 | } | ||
37 | 34 | ||
38 | void stack_protections(unsigned long address) | 35 | void 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 | ||
62 | int 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 | |||
105 | int raw(int fd) | 59 | int 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 | ||
150 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 104 | int 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 | ||
20 | extern int modify_ldt(int func, void *ptr, unsigned long bytecount); | 22 | extern 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, ©, 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 |
647 | CONFIG_E1000=y | 647 | CONFIG_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 | ||
675 | ia32_syscall_end: | 688 | ia32_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 | ||
149 | char boot_exception_stacks[(N_EXCEPTION_STACKS - 2) * EXCEPTION_STKSZ + DEBUG_STKSZ] | 149 | char 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 */ |