diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/frv/kernel | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/frv/kernel')
-rw-r--r-- | arch/frv/kernel/Makefile | 6 | ||||
-rw-r--r-- | arch/frv/kernel/debug-stub.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/entry.S | 60 | ||||
-rw-r--r-- | arch/frv/kernel/frv_ksyms.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/gdb-io.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/gdb-stub.c | 45 | ||||
-rw-r--r-- | arch/frv/kernel/irq-mb93091.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/irq-mb93093.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/irq-mb93493.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/irq.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/pm.c | 19 | ||||
-rw-r--r-- | arch/frv/kernel/process.c | 128 | ||||
-rw-r--r-- | arch/frv/kernel/ptrace.c | 1 | ||||
-rw-r--r-- | arch/frv/kernel/setup.c | 18 | ||||
-rw-r--r-- | arch/frv/kernel/signal.c | 111 | ||||
-rw-r--r-- | arch/frv/kernel/traps.c | 1 |
16 files changed, 284 insertions, 112 deletions
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile index 3cbb3294b9f..c36f70b6699 100644 --- a/arch/frv/kernel/Makefile +++ b/arch/frv/kernel/Makefile | |||
@@ -5,10 +5,10 @@ | |||
5 | heads-y := head-uc-fr401.o head-uc-fr451.o head-uc-fr555.o | 5 | heads-y := head-uc-fr401.o head-uc-fr451.o head-uc-fr555.o |
6 | heads-$(CONFIG_MMU) := head-mmu-fr451.o | 6 | heads-$(CONFIG_MMU) := head-mmu-fr451.o |
7 | 7 | ||
8 | extra-y:= head.o vmlinux.lds | 8 | extra-y:= head.o init_task.o vmlinux.lds |
9 | 9 | ||
10 | obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \ | 10 | obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ |
11 | process.o traps.o ptrace.o signal.o dma.o \ | 11 | kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ |
12 | sys_frv.o time.o setup.o frv_ksyms.o \ | 12 | sys_frv.o time.o setup.o frv_ksyms.o \ |
13 | debug-stub.o irq.o sleep.o uaccess.o | 13 | debug-stub.o irq.o sleep.o uaccess.o |
14 | 14 | ||
diff --git a/arch/frv/kernel/debug-stub.c b/arch/frv/kernel/debug-stub.c index a0228f717ef..2845139c807 100644 --- a/arch/frv/kernel/debug-stub.c +++ b/arch/frv/kernel/debug-stub.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/serial_reg.h> | 17 | #include <linux/serial_reg.h> |
18 | #include <linux/start_kernel.h> | 18 | #include <linux/start_kernel.h> |
19 | 19 | ||
20 | #include <asm/system.h> | ||
20 | #include <asm/serial-regs.h> | 21 | #include <asm/serial-regs.h> |
21 | #include <asm/timer-regs.h> | 22 | #include <asm/timer-regs.h> |
22 | #include <asm/irc-regs.h> | 23 | #include <asm/irc-regs.h> |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index dfcd263c051..5ba23f715ea 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -863,14 +863,6 @@ ret_from_fork: | |||
863 | setlos.p #0,gr8 | 863 | setlos.p #0,gr8 |
864 | bra __syscall_exit | 864 | bra __syscall_exit |
865 | 865 | ||
866 | .globl ret_from_kernel_thread | ||
867 | ret_from_kernel_thread: | ||
868 | lddi.p @(gr28,#REG_GR(8)),gr20 | ||
869 | call schedule_tail | ||
870 | calll.p @(gr21,gr0) | ||
871 | or gr20,gr20,gr8 | ||
872 | bra __syscall_exit | ||
873 | |||
874 | ################################################################################################### | 866 | ################################################################################################### |
875 | # | 867 | # |
876 | # Return to user mode is not as complex as all this looks, | 868 | # Return to user mode is not as complex as all this looks, |
@@ -913,19 +905,18 @@ __syscall_call: | |||
913 | __syscall_exit: | 905 | __syscall_exit: |
914 | LEDS 0x6300 | 906 | LEDS 0x6300 |
915 | 907 | ||
916 | # keep current PSR in GR23 | 908 | sti gr8,@(gr28,#REG_GR(8)) ; save return value |
917 | movsg psr,gr23 | ||
918 | |||
919 | ldi @(gr28,#REG_PSR),gr22 | ||
920 | |||
921 | sti.p gr8,@(gr28,#REG_GR(8)) ; save return value | ||
922 | 909 | ||
923 | # rebuild saved psr - execve will change it for init/main.c | 910 | # rebuild saved psr - execve will change it for init/main.c |
911 | ldi @(gr28,#REG_PSR),gr22 | ||
924 | srli gr22,#1,gr5 | 912 | srli gr22,#1,gr5 |
925 | andi.p gr22,#~PSR_PS,gr22 | 913 | andi.p gr22,#~PSR_PS,gr22 |
926 | andi gr5,#PSR_PS,gr5 | 914 | andi gr5,#PSR_PS,gr5 |
927 | or gr5,gr22,gr22 | 915 | or gr5,gr22,gr22 |
928 | ori.p gr22,#PSR_S,gr22 | 916 | ori gr22,#PSR_S,gr22 |
917 | |||
918 | # keep current PSR in GR23 | ||
919 | movsg psr,gr23 | ||
929 | 920 | ||
930 | # make sure we don't miss an interrupt setting need_resched or sigpending between | 921 | # make sure we don't miss an interrupt setting need_resched or sigpending between |
931 | # sampling and the RETT | 922 | # sampling and the RETT |
@@ -933,7 +924,9 @@ __syscall_exit: | |||
933 | movgs gr23,psr | 924 | movgs gr23,psr |
934 | 925 | ||
935 | ldi @(gr15,#TI_FLAGS),gr4 | 926 | ldi @(gr15,#TI_FLAGS),gr4 |
936 | andicc gr4,#_TIF_ALLWORK_MASK,gr0,icc0 | 927 | sethi.p %hi(_TIF_ALLWORK_MASK),gr5 |
928 | setlo %lo(_TIF_ALLWORK_MASK),gr5 | ||
929 | andcc gr4,gr5,gr0,icc0 | ||
937 | bne icc0,#0,__syscall_exit_work | 930 | bne icc0,#0,__syscall_exit_work |
938 | 931 | ||
939 | # restore all registers and return | 932 | # restore all registers and return |
@@ -1075,10 +1068,27 @@ __entry_return_from_kernel_interrupt: | |||
1075 | subicc gr5,#0,gr0,icc0 | 1068 | subicc gr5,#0,gr0,icc0 |
1076 | beq icc0,#0,__entry_return_direct | 1069 | beq icc0,#0,__entry_return_direct |
1077 | 1070 | ||
1078 | subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ | 1071 | __entry_preempt_need_resched: |
1079 | call preempt_schedule_irq | 1072 | ldi @(gr15,#TI_FLAGS),gr4 |
1080 | #endif | 1073 | andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 |
1074 | beq icc0,#1,__entry_return_direct | ||
1075 | |||
1076 | setlos #PREEMPT_ACTIVE,gr5 | ||
1077 | sti gr5,@(gr15,#TI_FLAGS) | ||
1078 | |||
1079 | andi gr23,#~PSR_PIL,gr23 | ||
1080 | movgs gr23,psr | ||
1081 | |||
1082 | call schedule | ||
1083 | sti gr0,@(gr15,#TI_PRE_COUNT) | ||
1084 | |||
1085 | movsg psr,gr23 | ||
1086 | ori gr23,#PSR_PIL_14,gr23 | ||
1087 | movgs gr23,psr | ||
1088 | bra __entry_preempt_need_resched | ||
1089 | #else | ||
1081 | bra __entry_return_direct | 1090 | bra __entry_return_direct |
1091 | #endif | ||
1082 | 1092 | ||
1083 | 1093 | ||
1084 | ############################################################################### | 1094 | ############################################################################### |
@@ -1101,7 +1111,9 @@ __entry_resume_userspace: | |||
1101 | __entry_return_from_user_interrupt: | 1111 | __entry_return_from_user_interrupt: |
1102 | LEDS 0x6402 | 1112 | LEDS 0x6402 |
1103 | ldi @(gr15,#TI_FLAGS),gr4 | 1113 | ldi @(gr15,#TI_FLAGS),gr4 |
1104 | andicc gr4,#_TIF_WORK_MASK,gr0,icc0 | 1114 | sethi.p %hi(_TIF_WORK_MASK),gr5 |
1115 | setlo %lo(_TIF_WORK_MASK),gr5 | ||
1116 | andcc gr4,gr5,gr0,icc0 | ||
1105 | beq icc0,#1,__entry_return_direct | 1117 | beq icc0,#1,__entry_return_direct |
1106 | 1118 | ||
1107 | __entry_work_pending: | 1119 | __entry_work_pending: |
@@ -1121,7 +1133,9 @@ __entry_work_resched: | |||
1121 | 1133 | ||
1122 | LEDS 0x6401 | 1134 | LEDS 0x6401 |
1123 | ldi @(gr15,#TI_FLAGS),gr4 | 1135 | ldi @(gr15,#TI_FLAGS),gr4 |
1124 | andicc gr4,#_TIF_WORK_MASK,gr0,icc0 | 1136 | sethi.p %hi(_TIF_WORK_MASK),gr5 |
1137 | setlo %lo(_TIF_WORK_MASK),gr5 | ||
1138 | andcc gr4,gr5,gr0,icc0 | ||
1125 | beq icc0,#1,__entry_return_direct | 1139 | beq icc0,#1,__entry_return_direct |
1126 | andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 | 1140 | andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 |
1127 | bne icc0,#1,__entry_work_resched | 1141 | bne icc0,#1,__entry_work_resched |
@@ -1149,9 +1163,7 @@ __syscall_trace_entry: | |||
1149 | # perform syscall exit tracing | 1163 | # perform syscall exit tracing |
1150 | __syscall_exit_work: | 1164 | __syscall_exit_work: |
1151 | LEDS 0x6340 | 1165 | LEDS 0x6340 |
1152 | andicc gr22,#PSR_PS,gr0,icc1 ; don't handle on return to kernel mode | 1166 | andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0 |
1153 | andicc.p gr4,#_TIF_SYSCALL_TRACE,gr0,icc0 | ||
1154 | bne icc1,#0,__entry_return_direct | ||
1155 | beq icc0,#1,__entry_work_pending | 1167 | beq icc0,#1,__entry_work_pending |
1156 | 1168 | ||
1157 | movsg psr,gr23 | 1169 | movsg psr,gr23 |
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index 86c516d96dc..a89803b58b9 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c | |||
@@ -30,6 +30,7 @@ EXPORT_SYMBOL(ip_fast_csum); | |||
30 | EXPORT_SYMBOL(local_irq_count); | 30 | EXPORT_SYMBOL(local_irq_count); |
31 | EXPORT_SYMBOL(local_bh_count); | 31 | EXPORT_SYMBOL(local_bh_count); |
32 | #endif | 32 | #endif |
33 | EXPORT_SYMBOL(kernel_thread); | ||
33 | 34 | ||
34 | EXPORT_SYMBOL(__res_bus_clock_speed_HZ); | 35 | EXPORT_SYMBOL(__res_bus_clock_speed_HZ); |
35 | EXPORT_SYMBOL(__page_offset); | 36 | EXPORT_SYMBOL(__page_offset); |
diff --git a/arch/frv/kernel/gdb-io.c b/arch/frv/kernel/gdb-io.c index 0707d35079b..2ca641d199f 100644 --- a/arch/frv/kernel/gdb-io.c +++ b/arch/frv/kernel/gdb-io.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/serial_reg.h> | 19 | #include <linux/serial_reg.h> |
20 | 20 | ||
21 | #include <asm/pgtable.h> | 21 | #include <asm/pgtable.h> |
22 | #include <asm/system.h> | ||
22 | #include <asm/irc-regs.h> | 23 | #include <asm/irc-regs.h> |
23 | #include <asm/timer-regs.h> | 24 | #include <asm/timer-regs.h> |
24 | #include <asm/gdb-stub.h> | 25 | #include <asm/gdb-stub.h> |
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c index bbe78b0bffe..a4dba6b20bd 100644 --- a/arch/frv/kernel/gdb-stub.c +++ b/arch/frv/kernel/gdb-stub.c | |||
@@ -126,6 +126,7 @@ | |||
126 | 126 | ||
127 | #include <asm/asm-offsets.h> | 127 | #include <asm/asm-offsets.h> |
128 | #include <asm/pgtable.h> | 128 | #include <asm/pgtable.h> |
129 | #include <asm/system.h> | ||
129 | #include <asm/gdb-stub.h> | 130 | #include <asm/gdb-stub.h> |
130 | 131 | ||
131 | #define LEDS(x) do { /* *(u32*)0xe1200004 = ~(x); mb(); */ } while(0) | 132 | #define LEDS(x) do { /* *(u32*)0xe1200004 = ~(x); mb(); */ } while(0) |
@@ -671,7 +672,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa | |||
671 | if ((uint32_t)mem&1 && count>=1) { | 672 | if ((uint32_t)mem&1 && count>=1) { |
672 | if (!gdbstub_read_byte(mem,ch)) | 673 | if (!gdbstub_read_byte(mem,ch)) |
673 | return NULL; | 674 | return NULL; |
674 | buf = hex_byte_pack(buf, ch[0]); | 675 | buf = pack_hex_byte(buf, ch[0]); |
675 | mem++; | 676 | mem++; |
676 | count--; | 677 | count--; |
677 | } | 678 | } |
@@ -679,8 +680,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa | |||
679 | if ((uint32_t)mem&3 && count>=2) { | 680 | if ((uint32_t)mem&3 && count>=2) { |
680 | if (!gdbstub_read_word(mem,(uint16_t *)ch)) | 681 | if (!gdbstub_read_word(mem,(uint16_t *)ch)) |
681 | return NULL; | 682 | return NULL; |
682 | buf = hex_byte_pack(buf, ch[0]); | 683 | buf = pack_hex_byte(buf, ch[0]); |
683 | buf = hex_byte_pack(buf, ch[1]); | 684 | buf = pack_hex_byte(buf, ch[1]); |
684 | mem += 2; | 685 | mem += 2; |
685 | count -= 2; | 686 | count -= 2; |
686 | } | 687 | } |
@@ -688,10 +689,10 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa | |||
688 | while (count>=4) { | 689 | while (count>=4) { |
689 | if (!gdbstub_read_dword(mem,(uint32_t *)ch)) | 690 | if (!gdbstub_read_dword(mem,(uint32_t *)ch)) |
690 | return NULL; | 691 | return NULL; |
691 | buf = hex_byte_pack(buf, ch[0]); | 692 | buf = pack_hex_byte(buf, ch[0]); |
692 | buf = hex_byte_pack(buf, ch[1]); | 693 | buf = pack_hex_byte(buf, ch[1]); |
693 | buf = hex_byte_pack(buf, ch[2]); | 694 | buf = pack_hex_byte(buf, ch[2]); |
694 | buf = hex_byte_pack(buf, ch[3]); | 695 | buf = pack_hex_byte(buf, ch[3]); |
695 | mem += 4; | 696 | mem += 4; |
696 | count -= 4; | 697 | count -= 4; |
697 | } | 698 | } |
@@ -699,8 +700,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa | |||
699 | if (count>=2) { | 700 | if (count>=2) { |
700 | if (!gdbstub_read_word(mem,(uint16_t *)ch)) | 701 | if (!gdbstub_read_word(mem,(uint16_t *)ch)) |
701 | return NULL; | 702 | return NULL; |
702 | buf = hex_byte_pack(buf, ch[0]); | 703 | buf = pack_hex_byte(buf, ch[0]); |
703 | buf = hex_byte_pack(buf, ch[1]); | 704 | buf = pack_hex_byte(buf, ch[1]); |
704 | mem += 2; | 705 | mem += 2; |
705 | count -= 2; | 706 | count -= 2; |
706 | } | 707 | } |
@@ -708,7 +709,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa | |||
708 | if (count>=1) { | 709 | if (count>=1) { |
709 | if (!gdbstub_read_byte(mem,ch)) | 710 | if (!gdbstub_read_byte(mem,ch)) |
710 | return NULL; | 711 | return NULL; |
711 | buf = hex_byte_pack(buf, ch[0]); | 712 | buf = pack_hex_byte(buf, ch[0]); |
712 | } | 713 | } |
713 | 714 | ||
714 | *buf = 0; | 715 | *buf = 0; |
@@ -1497,21 +1498,21 @@ void gdbstub(int sigval) | |||
1497 | ptr = mem2hex(title, ptr, sizeof(title) - 1,0); | 1498 | ptr = mem2hex(title, ptr, sizeof(title) - 1,0); |
1498 | 1499 | ||
1499 | hx = hex_asc_hi(brr >> 24); | 1500 | hx = hex_asc_hi(brr >> 24); |
1500 | ptr = hex_byte_pack(ptr, hx); | 1501 | ptr = pack_hex_byte(ptr, hx); |
1501 | hx = hex_asc_lo(brr >> 24); | 1502 | hx = hex_asc_lo(brr >> 24); |
1502 | ptr = hex_byte_pack(ptr, hx); | 1503 | ptr = pack_hex_byte(ptr, hx); |
1503 | hx = hex_asc_hi(brr >> 16); | 1504 | hx = hex_asc_hi(brr >> 16); |
1504 | ptr = hex_byte_pack(ptr, hx); | 1505 | ptr = pack_hex_byte(ptr, hx); |
1505 | hx = hex_asc_lo(brr >> 16); | 1506 | hx = hex_asc_lo(brr >> 16); |
1506 | ptr = hex_byte_pack(ptr, hx); | 1507 | ptr = pack_hex_byte(ptr, hx); |
1507 | hx = hex_asc_hi(brr >> 8); | 1508 | hx = hex_asc_hi(brr >> 8); |
1508 | ptr = hex_byte_pack(ptr, hx); | 1509 | ptr = pack_hex_byte(ptr, hx); |
1509 | hx = hex_asc_lo(brr >> 8); | 1510 | hx = hex_asc_lo(brr >> 8); |
1510 | ptr = hex_byte_pack(ptr, hx); | 1511 | ptr = pack_hex_byte(ptr, hx); |
1511 | hx = hex_asc_hi(brr); | 1512 | hx = hex_asc_hi(brr); |
1512 | ptr = hex_byte_pack(ptr, hx); | 1513 | ptr = pack_hex_byte(ptr, hx); |
1513 | hx = hex_asc_lo(brr); | 1514 | hx = hex_asc_lo(brr); |
1514 | ptr = hex_byte_pack(ptr, hx); | 1515 | ptr = pack_hex_byte(ptr, hx); |
1515 | 1516 | ||
1516 | ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); | 1517 | ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0); |
1517 | *ptr = 0; | 1518 | *ptr = 0; |
@@ -1525,10 +1526,10 @@ void gdbstub(int sigval) | |||
1525 | 1526 | ||
1526 | /* Send trap type (converted to signal) */ | 1527 | /* Send trap type (converted to signal) */ |
1527 | *ptr++ = 'T'; | 1528 | *ptr++ = 'T'; |
1528 | ptr = hex_byte_pack(ptr, sigval); | 1529 | ptr = pack_hex_byte(ptr, sigval); |
1529 | 1530 | ||
1530 | /* Send Error PC */ | 1531 | /* Send Error PC */ |
1531 | ptr = hex_byte_pack(ptr, GDB_REG_PC); | 1532 | ptr = pack_hex_byte(ptr, GDB_REG_PC); |
1532 | *ptr++ = ':'; | 1533 | *ptr++ = ':'; |
1533 | ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0); | 1534 | ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0); |
1534 | *ptr++ = ';'; | 1535 | *ptr++ = ';'; |
@@ -1536,7 +1537,7 @@ void gdbstub(int sigval) | |||
1536 | /* | 1537 | /* |
1537 | * Send frame pointer | 1538 | * Send frame pointer |
1538 | */ | 1539 | */ |
1539 | ptr = hex_byte_pack(ptr, GDB_REG_FP); | 1540 | ptr = pack_hex_byte(ptr, GDB_REG_FP); |
1540 | *ptr++ = ':'; | 1541 | *ptr++ = ':'; |
1541 | ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0); | 1542 | ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0); |
1542 | *ptr++ = ';'; | 1543 | *ptr++ = ';'; |
@@ -1544,7 +1545,7 @@ void gdbstub(int sigval) | |||
1544 | /* | 1545 | /* |
1545 | * Send stack pointer | 1546 | * Send stack pointer |
1546 | */ | 1547 | */ |
1547 | ptr = hex_byte_pack(ptr, GDB_REG_SP); | 1548 | ptr = pack_hex_byte(ptr, GDB_REG_SP); |
1548 | *ptr++ = ':'; | 1549 | *ptr++ = ':'; |
1549 | ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0); | 1550 | ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0); |
1550 | *ptr++ = ';'; | 1551 | *ptr++ = ';'; |
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c index 2cc327a1ca4..9afc2ea400d 100644 --- a/arch/frv/kernel/irq-mb93091.c +++ b/arch/frv/kernel/irq-mb93091.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | 21 | ||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/system.h> | ||
23 | #include <asm/delay.h> | 24 | #include <asm/delay.h> |
24 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
25 | #include <asm/irc-regs.h> | 26 | #include <asm/irc-regs.h> |
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c index 95e4eb4f1f3..4d4ad09d3c9 100644 --- a/arch/frv/kernel/irq-mb93093.c +++ b/arch/frv/kernel/irq-mb93093.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | 21 | ||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/system.h> | ||
23 | #include <asm/delay.h> | 24 | #include <asm/delay.h> |
24 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
25 | #include <asm/irc-regs.h> | 26 | #include <asm/irc-regs.h> |
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c index ba648da0932..4d034c7840c 100644 --- a/arch/frv/kernel/irq-mb93493.c +++ b/arch/frv/kernel/irq-mb93493.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | 21 | ||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/system.h> | ||
23 | #include <asm/delay.h> | 24 | #include <asm/delay.h> |
24 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
25 | #include <asm/irc-regs.h> | 26 | #include <asm/irc-regs.h> |
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c index 2239346fa3d..3facbc28cbb 100644 --- a/arch/frv/kernel/irq.c +++ b/arch/frv/kernel/irq.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/atomic.h> | 28 | #include <linux/atomic.h> |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | #include <asm/smp.h> | 30 | #include <asm/smp.h> |
31 | #include <asm/system.h> | ||
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include <asm/pgalloc.h> | 33 | #include <asm/pgalloc.h> |
33 | #include <asm/delay.h> | 34 | #include <asm/delay.h> |
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c index 0b579927439..5fa3889d858 100644 --- a/arch/frv/kernel/pm.c +++ b/arch/frv/kernel/pm.c | |||
@@ -153,22 +153,23 @@ static int user_atoi(char __user *ubuf, size_t len) | |||
153 | static int sysctl_pm_do_suspend(ctl_table *ctl, int write, | 153 | static int sysctl_pm_do_suspend(ctl_table *ctl, int write, |
154 | void __user *buffer, size_t *lenp, loff_t *fpos) | 154 | void __user *buffer, size_t *lenp, loff_t *fpos) |
155 | { | 155 | { |
156 | int mode; | 156 | int retval, mode; |
157 | 157 | ||
158 | if (*lenp <= 0) | 158 | if (*lenp <= 0) |
159 | return -EIO; | 159 | return -EIO; |
160 | 160 | ||
161 | mode = user_atoi(buffer, *lenp); | 161 | mode = user_atoi(buffer, *lenp); |
162 | switch (mode) { | 162 | if ((mode != 1) && (mode != 5)) |
163 | case 1: | 163 | return -EINVAL; |
164 | return pm_do_suspend(); | ||
165 | |||
166 | case 5: | ||
167 | return pm_do_bus_sleep(); | ||
168 | 164 | ||
169 | default: | 165 | if (retval == 0) { |
170 | return -EINVAL; | 166 | if (mode == 5) |
167 | retval = pm_do_bus_sleep(); | ||
168 | else | ||
169 | retval = pm_do_suspend(); | ||
171 | } | 170 | } |
171 | |||
172 | return retval; | ||
172 | } | 173 | } |
173 | 174 | ||
174 | static int try_set_cmode(int new_cmode) | 175 | static int try_set_cmode(int new_cmode) |
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 23916b2a12a..3901df1213c 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c | |||
@@ -25,10 +25,10 @@ | |||
25 | #include <linux/reboot.h> | 25 | #include <linux/reboot.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/pagemap.h> | 27 | #include <linux/pagemap.h> |
28 | #include <linux/rcupdate.h> | ||
29 | 28 | ||
30 | #include <asm/asm-offsets.h> | 29 | #include <asm/asm-offsets.h> |
31 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
31 | #include <asm/system.h> | ||
32 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
33 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
34 | #include <asm/tlb.h> | 34 | #include <asm/tlb.h> |
@@ -38,13 +38,27 @@ | |||
38 | #include "local.h" | 38 | #include "local.h" |
39 | 39 | ||
40 | asmlinkage void ret_from_fork(void); | 40 | asmlinkage void ret_from_fork(void); |
41 | asmlinkage void ret_from_kernel_thread(void); | ||
42 | 41 | ||
43 | #include <asm/pgalloc.h> | 42 | #include <asm/pgalloc.h> |
44 | 43 | ||
45 | void (*pm_power_off)(void); | 44 | void (*pm_power_off)(void); |
46 | EXPORT_SYMBOL(pm_power_off); | 45 | EXPORT_SYMBOL(pm_power_off); |
47 | 46 | ||
47 | struct task_struct *alloc_task_struct_node(int node) | ||
48 | { | ||
49 | struct task_struct *p = kmalloc_node(THREAD_SIZE, GFP_KERNEL, node); | ||
50 | |||
51 | if (p) | ||
52 | atomic_set((atomic_t *)(p+1), 1); | ||
53 | return p; | ||
54 | } | ||
55 | |||
56 | void free_task_struct(struct task_struct *p) | ||
57 | { | ||
58 | if (atomic_dec_and_test((atomic_t *)(p+1))) | ||
59 | kfree(p); | ||
60 | } | ||
61 | |||
48 | static void core_sleep_idle(void) | 62 | static void core_sleep_idle(void) |
49 | { | 63 | { |
50 | #ifdef LED_DEBUG_SLEEP | 64 | #ifdef LED_DEBUG_SLEEP |
@@ -71,16 +85,16 @@ void cpu_idle(void) | |||
71 | { | 85 | { |
72 | /* endless idle loop with no priority at all */ | 86 | /* endless idle loop with no priority at all */ |
73 | while (1) { | 87 | while (1) { |
74 | rcu_idle_enter(); | ||
75 | while (!need_resched()) { | 88 | while (!need_resched()) { |
76 | check_pgt_cache(); | 89 | check_pgt_cache(); |
77 | 90 | ||
78 | if (!frv_dma_inprogress && idle) | 91 | if (!frv_dma_inprogress && idle) |
79 | idle(); | 92 | idle(); |
80 | } | 93 | } |
81 | rcu_idle_exit(); | ||
82 | 94 | ||
83 | schedule_preempt_disabled(); | 95 | preempt_enable_no_resched(); |
96 | schedule(); | ||
97 | preempt_disable(); | ||
84 | } | 98 | } |
85 | } | 99 | } |
86 | 100 | ||
@@ -139,40 +153,87 @@ inline unsigned long user_stack(const struct pt_regs *regs) | |||
139 | return user_mode(regs) ? regs->sp : 0; | 153 | return user_mode(regs) ? regs->sp : 0; |
140 | } | 154 | } |
141 | 155 | ||
156 | asmlinkage int sys_fork(void) | ||
157 | { | ||
158 | #ifndef CONFIG_MMU | ||
159 | /* fork almost works, enough to trick you into looking elsewhere:-( */ | ||
160 | return -EINVAL; | ||
161 | #else | ||
162 | return do_fork(SIGCHLD, user_stack(__frame), __frame, 0, NULL, NULL); | ||
163 | #endif | ||
164 | } | ||
165 | |||
166 | asmlinkage int sys_vfork(void) | ||
167 | { | ||
168 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, user_stack(__frame), __frame, 0, | ||
169 | NULL, NULL); | ||
170 | } | ||
171 | |||
172 | /*****************************************************************************/ | ||
173 | /* | ||
174 | * clone a process | ||
175 | * - tlsptr is retrieved by copy_thread() | ||
176 | */ | ||
177 | asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
178 | int __user *parent_tidptr, int __user *child_tidptr, | ||
179 | int __user *tlsptr) | ||
180 | { | ||
181 | if (!newsp) | ||
182 | newsp = user_stack(__frame); | ||
183 | return do_fork(clone_flags, newsp, __frame, 0, parent_tidptr, child_tidptr); | ||
184 | } /* end sys_clone() */ | ||
185 | |||
186 | /*****************************************************************************/ | ||
187 | /* | ||
188 | * This gets called before we allocate a new thread and copy | ||
189 | * the current task into it. | ||
190 | */ | ||
191 | void prepare_to_copy(struct task_struct *tsk) | ||
192 | { | ||
193 | //unlazy_fpu(tsk); | ||
194 | } /* end prepare_to_copy() */ | ||
195 | |||
196 | /*****************************************************************************/ | ||
142 | /* | 197 | /* |
143 | * set up the kernel stack and exception frames for a new process | 198 | * set up the kernel stack and exception frames for a new process |
144 | */ | 199 | */ |
145 | int copy_thread(unsigned long clone_flags, | 200 | int copy_thread(unsigned long clone_flags, |
146 | unsigned long usp, unsigned long arg, | 201 | unsigned long usp, unsigned long topstk, |
147 | struct task_struct *p) | 202 | struct task_struct *p, struct pt_regs *regs) |
148 | { | 203 | { |
149 | struct pt_regs *childregs; | 204 | struct pt_regs *childregs0, *childregs, *regs0; |
150 | 205 | ||
151 | childregs = (struct pt_regs *) | 206 | regs0 = __kernel_frame0_ptr; |
207 | childregs0 = (struct pt_regs *) | ||
152 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); | 208 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); |
209 | childregs = childregs0; | ||
153 | 210 | ||
154 | /* set up the userspace frame (the only place that the USP is stored) */ | 211 | /* set up the userspace frame (the only place that the USP is stored) */ |
155 | *childregs = *current_pt_regs(); | 212 | *childregs0 = *regs0; |
213 | |||
214 | childregs0->gr8 = 0; | ||
215 | childregs0->sp = usp; | ||
216 | childregs0->next_frame = NULL; | ||
217 | |||
218 | /* set up the return kernel frame if called from kernel_thread() */ | ||
219 | if (regs != regs0) { | ||
220 | childregs--; | ||
221 | *childregs = *regs; | ||
222 | childregs->sp = (unsigned long) childregs0; | ||
223 | childregs->next_frame = childregs0; | ||
224 | childregs->gr15 = (unsigned long) task_thread_info(p); | ||
225 | childregs->gr29 = (unsigned long) p; | ||
226 | } | ||
227 | |||
228 | p->set_child_tid = p->clear_child_tid = NULL; | ||
156 | 229 | ||
157 | p->thread.frame = childregs; | 230 | p->thread.frame = childregs; |
158 | p->thread.curr = p; | 231 | p->thread.curr = p; |
159 | p->thread.sp = (unsigned long) childregs; | 232 | p->thread.sp = (unsigned long) childregs; |
160 | p->thread.fp = 0; | 233 | p->thread.fp = 0; |
161 | p->thread.lr = 0; | 234 | p->thread.lr = 0; |
162 | p->thread.frame0 = childregs; | 235 | p->thread.pc = (unsigned long) ret_from_fork; |
163 | 236 | p->thread.frame0 = childregs0; | |
164 | if (unlikely(p->flags & PF_KTHREAD)) { | ||
165 | childregs->gr9 = usp; /* function */ | ||
166 | childregs->gr8 = arg; | ||
167 | p->thread.pc = (unsigned long) ret_from_kernel_thread; | ||
168 | save_user_regs(p->thread.user); | ||
169 | return 0; | ||
170 | } | ||
171 | if (usp) | ||
172 | childregs->sp = usp; | ||
173 | childregs->next_frame = NULL; | ||
174 | |||
175 | p->thread.pc = (unsigned long) ret_from_fork; | ||
176 | 237 | ||
177 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ | 238 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ |
178 | if (clone_flags & CLONE_SETTLS) | 239 | if (clone_flags & CLONE_SETTLS) |
@@ -183,6 +244,25 @@ int copy_thread(unsigned long clone_flags, | |||
183 | return 0; | 244 | return 0; |
184 | } /* end copy_thread() */ | 245 | } /* end copy_thread() */ |
185 | 246 | ||
247 | /* | ||
248 | * sys_execve() executes a new program. | ||
249 | */ | ||
250 | asmlinkage int sys_execve(const char __user *name, | ||
251 | const char __user *const __user *argv, | ||
252 | const char __user *const __user *envp) | ||
253 | { | ||
254 | int error; | ||
255 | char * filename; | ||
256 | |||
257 | filename = getname(name); | ||
258 | error = PTR_ERR(filename); | ||
259 | if (IS_ERR(filename)) | ||
260 | return error; | ||
261 | error = do_execve(filename, argv, envp, __frame); | ||
262 | putname(filename); | ||
263 | return error; | ||
264 | } | ||
265 | |||
186 | unsigned long get_wchan(struct task_struct *p) | 266 | unsigned long get_wchan(struct task_struct *p) |
187 | { | 267 | { |
188 | struct pt_regs *regs0; | 268 | struct pt_regs *regs0; |
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c index 3987ff88dab..9d68f7fac73 100644 --- a/arch/frv/kernel/ptrace.c +++ b/arch/frv/kernel/ptrace.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/page.h> | 27 | #include <asm/page.h> |
28 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
29 | #include <asm/system.h> | ||
29 | #include <asm/processor.h> | 30 | #include <asm/processor.h> |
30 | #include <asm/unistd.h> | 31 | #include <asm/unistd.h> |
31 | 32 | ||
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index a5136474c6f..75cf7f4b2fa 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c | |||
@@ -112,11 +112,9 @@ char __initdata redboot_command_line[COMMAND_LINE_SIZE]; | |||
112 | #ifdef CONFIG_PM | 112 | #ifdef CONFIG_PM |
113 | #define __pminit | 113 | #define __pminit |
114 | #define __pminitdata | 114 | #define __pminitdata |
115 | #define __pminitconst | ||
116 | #else | 115 | #else |
117 | #define __pminit __init | 116 | #define __pminit __init |
118 | #define __pminitdata __initdata | 117 | #define __pminitdata __initdata |
119 | #define __pminitconst __initconst | ||
120 | #endif | 118 | #endif |
121 | 119 | ||
122 | struct clock_cmode { | 120 | struct clock_cmode { |
@@ -186,7 +184,7 @@ static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = { | |||
186 | [6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, | 184 | [6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, |
187 | }; | 185 | }; |
188 | 186 | ||
189 | static const struct clock_cmode __pminitconst *clock_cmodes; | 187 | static const struct clock_cmode __pminitdata *clock_cmodes; |
190 | static int __pminitdata clock_doubled; | 188 | static int __pminitdata clock_doubled; |
191 | 189 | ||
192 | static struct uart_port __pminitdata __frv_uart0 = { | 190 | static struct uart_port __pminitdata __frv_uart0 = { |
@@ -804,9 +802,9 @@ void __init setup_arch(char **cmdline_p) | |||
804 | 802 | ||
805 | BUG_ON(memory_start == memory_end); | 803 | BUG_ON(memory_start == memory_end); |
806 | 804 | ||
807 | init_mm.start_code = (unsigned long) _stext; | 805 | init_mm.start_code = (unsigned long) &_stext; |
808 | init_mm.end_code = (unsigned long) _etext; | 806 | init_mm.end_code = (unsigned long) &_etext; |
809 | init_mm.end_data = (unsigned long) _edata; | 807 | init_mm.end_data = (unsigned long) &_edata; |
810 | #if 0 /* DAVIDM - don't set brk just incase someone decides to use it */ | 808 | #if 0 /* DAVIDM - don't set brk just incase someone decides to use it */ |
811 | init_mm.brk = (unsigned long) &_end; | 809 | init_mm.brk = (unsigned long) &_end; |
812 | #else | 810 | #else |
@@ -814,8 +812,10 @@ void __init setup_arch(char **cmdline_p) | |||
814 | #endif | 812 | #endif |
815 | 813 | ||
816 | #ifdef DEBUG | 814 | #ifdef DEBUG |
817 | printk("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n", | 815 | printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n", |
818 | _stext, _etext, _sdata, _edata, __bss_start, __bss_stop); | 816 | (int) &_stext, (int) &_etext, |
817 | (int) &_sdata, (int) &_edata, | ||
818 | (int) &_sbss, (int) &_ebss); | ||
819 | #endif | 819 | #endif |
820 | 820 | ||
821 | #ifdef CONFIG_VT | 821 | #ifdef CONFIG_VT |
@@ -852,7 +852,7 @@ void __init setup_arch(char **cmdline_p) | |||
852 | /* | 852 | /* |
853 | * | 853 | * |
854 | */ | 854 | */ |
855 | static int setup_arch_serial(void) | 855 | static int __devinit setup_arch_serial(void) |
856 | { | 856 | { |
857 | /* register those serial ports that are available */ | 857 | /* register those serial ports that are available */ |
858 | #ifndef CONFIG_GDBSTUB_UART0 | 858 | #ifndef CONFIG_GDBSTUB_UART0 |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 535810a3217..bab01298b58 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
21 | #include <linux/unistd.h> | 21 | #include <linux/unistd.h> |
22 | #include <linux/personality.h> | 22 | #include <linux/personality.h> |
23 | #include <linux/freezer.h> | ||
23 | #include <linux/tracehook.h> | 24 | #include <linux/tracehook.h> |
24 | #include <asm/ucontext.h> | 25 | #include <asm/ucontext.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -27,6 +28,8 @@ | |||
27 | 28 | ||
28 | #define DEBUG_SIG 0 | 29 | #define DEBUG_SIG 0 |
29 | 30 | ||
31 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
32 | |||
30 | struct fdpic_func_descriptor { | 33 | struct fdpic_func_descriptor { |
31 | unsigned long text; | 34 | unsigned long text; |
32 | unsigned long GOT; | 35 | unsigned long GOT; |
@@ -37,9 +40,17 @@ struct fdpic_func_descriptor { | |||
37 | */ | 40 | */ |
38 | 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) |
39 | { | 42 | { |
40 | sigset_t blocked; | 43 | mask &= _BLOCKABLE; |
41 | siginitset(&blocked, mask); | 44 | spin_lock_irq(¤t->sighand->siglock); |
42 | return sigsuspend(&blocked); | 45 | current->saved_sigmask = current->blocked; |
46 | siginitset(¤t->blocked, mask); | ||
47 | recalc_sigpending(); | ||
48 | spin_unlock_irq(¤t->sighand->siglock); | ||
49 | |||
50 | current->state = TASK_INTERRUPTIBLE; | ||
51 | schedule(); | ||
52 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
53 | return -ERESTARTNOHAND; | ||
43 | } | 54 | } |
44 | 55 | ||
45 | asmlinkage int sys_sigaction(int sig, | 56 | asmlinkage int sys_sigaction(int sig, |
@@ -53,10 +64,10 @@ asmlinkage int sys_sigaction(int sig, | |||
53 | old_sigset_t mask; | 64 | old_sigset_t mask; |
54 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 65 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
55 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 66 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
56 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || | 67 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) |
57 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
58 | __get_user(mask, &act->sa_mask)) | ||
59 | return -EFAULT; | 68 | return -EFAULT; |
69 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
70 | __get_user(mask, &act->sa_mask); | ||
60 | siginitset(&new_ka.sa.sa_mask, mask); | 71 | siginitset(&new_ka.sa.sa_mask, mask); |
61 | } | 72 | } |
62 | 73 | ||
@@ -65,10 +76,10 @@ asmlinkage int sys_sigaction(int sig, | |||
65 | if (!ret && oact) { | 76 | if (!ret && oact) { |
66 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 77 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
67 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 78 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
68 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || | 79 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) |
69 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
70 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
71 | return -EFAULT; | 80 | return -EFAULT; |
81 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
82 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
72 | } | 83 | } |
73 | 84 | ||
74 | return ret; | 85 | return ret; |
@@ -146,7 +157,11 @@ asmlinkage int sys_sigreturn(void) | |||
146 | __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask))) | 157 | __copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask))) |
147 | goto badframe; | 158 | goto badframe; |
148 | 159 | ||
149 | set_current_blocked(&set); | 160 | sigdelsetmask(&set, ~_BLOCKABLE); |
161 | spin_lock_irq(¤t->sighand->siglock); | ||
162 | current->blocked = set; | ||
163 | recalc_sigpending(); | ||
164 | spin_unlock_irq(¤t->sighand->siglock); | ||
150 | 165 | ||
151 | if (restore_sigcontext(&frame->sc, &gr8)) | 166 | if (restore_sigcontext(&frame->sc, &gr8)) |
152 | goto badframe; | 167 | goto badframe; |
@@ -168,7 +183,11 @@ asmlinkage int sys_rt_sigreturn(void) | |||
168 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | 183 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) |
169 | goto badframe; | 184 | goto badframe; |
170 | 185 | ||
171 | set_current_blocked(&set); | 186 | sigdelsetmask(&set, ~_BLOCKABLE); |
187 | spin_lock_irq(¤t->sighand->siglock); | ||
188 | current->blocked = set; | ||
189 | recalc_sigpending(); | ||
190 | spin_unlock_irq(¤t->sighand->siglock); | ||
172 | 191 | ||
173 | if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8)) | 192 | if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8)) |
174 | goto badframe; | 193 | goto badframe; |
@@ -297,6 +316,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
297 | __frame->lr = (unsigned long) &frame->retcode; | 316 | __frame->lr = (unsigned long) &frame->retcode; |
298 | __frame->gr8 = sig; | 317 | __frame->gr8 = sig; |
299 | 318 | ||
319 | /* the tracer may want to single-step inside the handler */ | ||
320 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
321 | ptrace_notify(SIGTRAP); | ||
322 | |||
300 | #if DEBUG_SIG | 323 | #if DEBUG_SIG |
301 | printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", | 324 | printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", |
302 | sig, current->comm, current->pid, frame, __frame->pc, | 325 | sig, current->comm, current->pid, frame, __frame->pc, |
@@ -395,6 +418,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
395 | __frame->gr8 = sig; | 418 | __frame->gr8 = sig; |
396 | __frame->gr9 = (unsigned long) &frame->info; | 419 | __frame->gr9 = (unsigned long) &frame->info; |
397 | 420 | ||
421 | /* the tracer may want to single-step inside the handler */ | ||
422 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
423 | ptrace_notify(SIGTRAP); | ||
424 | |||
398 | #if DEBUG_SIG | 425 | #if DEBUG_SIG |
399 | printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", | 426 | printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", |
400 | sig, current->comm, current->pid, frame, __frame->pc, | 427 | sig, current->comm, current->pid, frame, __frame->pc, |
@@ -413,10 +440,9 @@ give_sigsegv: | |||
413 | /* | 440 | /* |
414 | * OK, we're invoking a handler | 441 | * OK, we're invoking a handler |
415 | */ | 442 | */ |
416 | static void handle_signal(unsigned long sig, siginfo_t *info, | 443 | static int handle_signal(unsigned long sig, siginfo_t *info, |
417 | struct k_sigaction *ka) | 444 | struct k_sigaction *ka, sigset_t *oldset) |
418 | { | 445 | { |
419 | sigset_t *oldset = sigmask_to_save(); | ||
420 | int ret; | 446 | int ret; |
421 | 447 | ||
422 | /* Are we from a system call? */ | 448 | /* Are we from a system call? */ |
@@ -448,11 +474,18 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
448 | else | 474 | else |
449 | ret = setup_frame(sig, ka, oldset); | 475 | ret = setup_frame(sig, ka, oldset); |
450 | 476 | ||
451 | if (ret) | 477 | if (ret == 0) { |
452 | return; | 478 | spin_lock_irq(¤t->sighand->siglock); |
479 | sigorsets(¤t->blocked, ¤t->blocked, | ||
480 | &ka->sa.sa_mask); | ||
481 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
482 | sigaddset(¤t->blocked, sig); | ||
483 | recalc_sigpending(); | ||
484 | spin_unlock_irq(¤t->sighand->siglock); | ||
485 | } | ||
486 | |||
487 | return ret; | ||
453 | 488 | ||
454 | signal_delivered(sig, info, ka, __frame, | ||
455 | test_thread_flag(TIF_SINGLESTEP)); | ||
456 | } /* end handle_signal() */ | 489 | } /* end handle_signal() */ |
457 | 490 | ||
458 | /*****************************************************************************/ | 491 | /*****************************************************************************/ |
@@ -465,14 +498,44 @@ static void do_signal(void) | |||
465 | { | 498 | { |
466 | struct k_sigaction ka; | 499 | struct k_sigaction ka; |
467 | siginfo_t info; | 500 | siginfo_t info; |
501 | sigset_t *oldset; | ||
468 | int signr; | 502 | int signr; |
469 | 503 | ||
504 | /* | ||
505 | * We want the common case to go fast, which | ||
506 | * is why we may in certain cases get here from | ||
507 | * kernel mode. Just return without doing anything | ||
508 | * if so. | ||
509 | */ | ||
510 | if (!user_mode(__frame)) | ||
511 | return; | ||
512 | |||
513 | if (try_to_freeze()) | ||
514 | goto no_signal; | ||
515 | |||
516 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
517 | oldset = ¤t->saved_sigmask; | ||
518 | else | ||
519 | oldset = ¤t->blocked; | ||
520 | |||
470 | signr = get_signal_to_deliver(&info, &ka, __frame, NULL); | 521 | signr = get_signal_to_deliver(&info, &ka, __frame, NULL); |
471 | if (signr > 0) { | 522 | if (signr > 0) { |
472 | handle_signal(signr, &info, &ka); | 523 | if (handle_signal(signr, &info, &ka, oldset) == 0) { |
524 | /* a signal was successfully delivered; the saved | ||
525 | * sigmask will have been stored in the signal frame, | ||
526 | * and will be restored by sigreturn, so we can simply | ||
527 | * clear the TIF_RESTORE_SIGMASK flag */ | ||
528 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
529 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
530 | |||
531 | tracehook_signal_handler(signr, &info, &ka, __frame, | ||
532 | test_thread_flag(TIF_SINGLESTEP)); | ||
533 | } | ||
534 | |||
473 | return; | 535 | return; |
474 | } | 536 | } |
475 | 537 | ||
538 | no_signal: | ||
476 | /* Did we come from a system call? */ | 539 | /* Did we come from a system call? */ |
477 | if (__frame->syscallno != -1) { | 540 | if (__frame->syscallno != -1) { |
478 | /* Restart the system call - no handlers present */ | 541 | /* Restart the system call - no handlers present */ |
@@ -494,7 +557,11 @@ static void do_signal(void) | |||
494 | 557 | ||
495 | /* if there's no signal to deliver, we just put the saved sigmask | 558 | /* if there's no signal to deliver, we just put the saved sigmask |
496 | * back */ | 559 | * back */ |
497 | restore_saved_sigmask(); | 560 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
561 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
562 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
563 | } | ||
564 | |||
498 | } /* end do_signal() */ | 565 | } /* end do_signal() */ |
499 | 566 | ||
500 | /*****************************************************************************/ | 567 | /*****************************************************************************/ |
@@ -509,13 +576,15 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags) | |||
509 | clear_thread_flag(TIF_SINGLESTEP); | 576 | clear_thread_flag(TIF_SINGLESTEP); |
510 | 577 | ||
511 | /* deal with pending signal delivery */ | 578 | /* deal with pending signal delivery */ |
512 | if (thread_info_flags & _TIF_SIGPENDING) | 579 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
513 | do_signal(); | 580 | do_signal(); |
514 | 581 | ||
515 | /* deal with notification on about to resume userspace execution */ | 582 | /* deal with notification on about to resume userspace execution */ |
516 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 583 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
517 | clear_thread_flag(TIF_NOTIFY_RESUME); | 584 | clear_thread_flag(TIF_NOTIFY_RESUME); |
518 | tracehook_notify_resume(__frame); | 585 | tracehook_notify_resume(__frame); |
586 | if (current->replacement_session_keyring) | ||
587 | key_replace_session_keyring(); | ||
519 | } | 588 | } |
520 | 589 | ||
521 | } /* end do_notify_resume() */ | 590 | } /* end do_notify_resume() */ |
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c index 5cfd1420b09..1d2dfe67d44 100644 --- a/arch/frv/kernel/traps.c +++ b/arch/frv/kernel/traps.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/asm-offsets.h> | 23 | #include <asm/asm-offsets.h> |
24 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
25 | #include <asm/fpu.h> | 25 | #include <asm/fpu.h> |
26 | #include <asm/system.h> | ||
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
27 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
28 | #include <asm/siginfo.h> | 29 | #include <asm/siginfo.h> |