diff options
Diffstat (limited to 'arch/frv')
-rw-r--r-- | arch/frv/Kconfig | 1 | ||||
-rw-r--r-- | arch/frv/include/asm/bitops.h | 29 | ||||
-rw-r--r-- | arch/frv/include/asm/elf.h | 1 | ||||
-rw-r--r-- | arch/frv/include/asm/pci.h | 7 | ||||
-rw-r--r-- | arch/frv/include/asm/ptrace.h | 11 | ||||
-rw-r--r-- | arch/frv/include/asm/syscall.h | 123 | ||||
-rw-r--r-- | arch/frv/include/asm/thread_info.h | 10 | ||||
-rw-r--r-- | arch/frv/kernel/entry.S | 13 | ||||
-rw-r--r-- | arch/frv/kernel/ptrace.c | 755 | ||||
-rw-r--r-- | arch/frv/kernel/signal.c | 10 | ||||
-rw-r--r-- | arch/frv/kernel/uaccess.c | 6 | ||||
-rw-r--r-- | arch/frv/mb93090-mb00/pci-dma-nommu.c | 6 | ||||
-rw-r--r-- | arch/frv/mb93090-mb00/pci-dma.c | 6 |
13 files changed, 399 insertions, 579 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 9d1552a9ee2c..8a5bd7a9c6f5 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig | |||
@@ -6,6 +6,7 @@ config FRV | |||
6 | bool | 6 | bool |
7 | default y | 7 | default y |
8 | select HAVE_IDE | 8 | select HAVE_IDE |
9 | select HAVE_ARCH_TRACEHOOK | ||
9 | 10 | ||
10 | config ZONE_DMA | 11 | config ZONE_DMA |
11 | bool | 12 | bool |
diff --git a/arch/frv/include/asm/bitops.h b/arch/frv/include/asm/bitops.h index 287f6f697ce2..50ae91b29674 100644 --- a/arch/frv/include/asm/bitops.h +++ b/arch/frv/include/asm/bitops.h | |||
@@ -112,7 +112,7 @@ extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsig | |||
112 | #define atomic_clear_mask(mask, v) atomic_test_and_ANDNOT_mask((mask), (v)) | 112 | #define atomic_clear_mask(mask, v) atomic_test_and_ANDNOT_mask((mask), (v)) |
113 | #define atomic_set_mask(mask, v) atomic_test_and_OR_mask((mask), (v)) | 113 | #define atomic_set_mask(mask, v) atomic_test_and_OR_mask((mask), (v)) |
114 | 114 | ||
115 | static inline int test_and_clear_bit(int nr, volatile void *addr) | 115 | static inline int test_and_clear_bit(unsigned long nr, volatile void *addr) |
116 | { | 116 | { |
117 | volatile unsigned long *ptr = addr; | 117 | volatile unsigned long *ptr = addr; |
118 | unsigned long mask = 1UL << (nr & 31); | 118 | unsigned long mask = 1UL << (nr & 31); |
@@ -120,7 +120,7 @@ static inline int test_and_clear_bit(int nr, volatile void *addr) | |||
120 | return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0; | 120 | return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static inline int test_and_set_bit(int nr, volatile void *addr) | 123 | static inline int test_and_set_bit(unsigned long nr, volatile void *addr) |
124 | { | 124 | { |
125 | volatile unsigned long *ptr = addr; | 125 | volatile unsigned long *ptr = addr; |
126 | unsigned long mask = 1UL << (nr & 31); | 126 | unsigned long mask = 1UL << (nr & 31); |
@@ -128,7 +128,7 @@ static inline int test_and_set_bit(int nr, volatile void *addr) | |||
128 | return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0; | 128 | return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0; |
129 | } | 129 | } |
130 | 130 | ||
131 | static inline int test_and_change_bit(int nr, volatile void *addr) | 131 | static inline int test_and_change_bit(unsigned long nr, volatile void *addr) |
132 | { | 132 | { |
133 | volatile unsigned long *ptr = addr; | 133 | volatile unsigned long *ptr = addr; |
134 | unsigned long mask = 1UL << (nr & 31); | 134 | unsigned long mask = 1UL << (nr & 31); |
@@ -136,22 +136,22 @@ static inline int test_and_change_bit(int nr, volatile void *addr) | |||
136 | return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0; | 136 | return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | static inline void clear_bit(int nr, volatile void *addr) | 139 | static inline void clear_bit(unsigned long nr, volatile void *addr) |
140 | { | 140 | { |
141 | test_and_clear_bit(nr, addr); | 141 | test_and_clear_bit(nr, addr); |
142 | } | 142 | } |
143 | 143 | ||
144 | static inline void set_bit(int nr, volatile void *addr) | 144 | static inline void set_bit(unsigned long nr, volatile void *addr) |
145 | { | 145 | { |
146 | test_and_set_bit(nr, addr); | 146 | test_and_set_bit(nr, addr); |
147 | } | 147 | } |
148 | 148 | ||
149 | static inline void change_bit(int nr, volatile void * addr) | 149 | static inline void change_bit(unsigned long nr, volatile void *addr) |
150 | { | 150 | { |
151 | test_and_change_bit(nr, addr); | 151 | test_and_change_bit(nr, addr); |
152 | } | 152 | } |
153 | 153 | ||
154 | static inline void __clear_bit(int nr, volatile void * addr) | 154 | static inline void __clear_bit(unsigned long nr, volatile void *addr) |
155 | { | 155 | { |
156 | volatile unsigned long *a = addr; | 156 | volatile unsigned long *a = addr; |
157 | int mask; | 157 | int mask; |
@@ -161,7 +161,7 @@ static inline void __clear_bit(int nr, volatile void * addr) | |||
161 | *a &= ~mask; | 161 | *a &= ~mask; |
162 | } | 162 | } |
163 | 163 | ||
164 | static inline void __set_bit(int nr, volatile void * addr) | 164 | static inline void __set_bit(unsigned long nr, volatile void *addr) |
165 | { | 165 | { |
166 | volatile unsigned long *a = addr; | 166 | volatile unsigned long *a = addr; |
167 | int mask; | 167 | int mask; |
@@ -171,7 +171,7 @@ static inline void __set_bit(int nr, volatile void * addr) | |||
171 | *a |= mask; | 171 | *a |= mask; |
172 | } | 172 | } |
173 | 173 | ||
174 | static inline void __change_bit(int nr, volatile void *addr) | 174 | static inline void __change_bit(unsigned long nr, volatile void *addr) |
175 | { | 175 | { |
176 | volatile unsigned long *a = addr; | 176 | volatile unsigned long *a = addr; |
177 | int mask; | 177 | int mask; |
@@ -181,7 +181,7 @@ static inline void __change_bit(int nr, volatile void *addr) | |||
181 | *a ^= mask; | 181 | *a ^= mask; |
182 | } | 182 | } |
183 | 183 | ||
184 | static inline int __test_and_clear_bit(int nr, volatile void * addr) | 184 | static inline int __test_and_clear_bit(unsigned long nr, volatile void *addr) |
185 | { | 185 | { |
186 | volatile unsigned long *a = addr; | 186 | volatile unsigned long *a = addr; |
187 | int mask, retval; | 187 | int mask, retval; |
@@ -193,7 +193,7 @@ static inline int __test_and_clear_bit(int nr, volatile void * addr) | |||
193 | return retval; | 193 | return retval; |
194 | } | 194 | } |
195 | 195 | ||
196 | static inline int __test_and_set_bit(int nr, volatile void * addr) | 196 | static inline int __test_and_set_bit(unsigned long nr, volatile void *addr) |
197 | { | 197 | { |
198 | volatile unsigned long *a = addr; | 198 | volatile unsigned long *a = addr; |
199 | int mask, retval; | 199 | int mask, retval; |
@@ -205,7 +205,7 @@ static inline int __test_and_set_bit(int nr, volatile void * addr) | |||
205 | return retval; | 205 | return retval; |
206 | } | 206 | } |
207 | 207 | ||
208 | static inline int __test_and_change_bit(int nr, volatile void * addr) | 208 | static inline int __test_and_change_bit(unsigned long nr, volatile void *addr) |
209 | { | 209 | { |
210 | volatile unsigned long *a = addr; | 210 | volatile unsigned long *a = addr; |
211 | int mask, retval; | 211 | int mask, retval; |
@@ -220,12 +220,13 @@ static inline int __test_and_change_bit(int nr, volatile void * addr) | |||
220 | /* | 220 | /* |
221 | * This routine doesn't need to be atomic. | 221 | * This routine doesn't need to be atomic. |
222 | */ | 222 | */ |
223 | static inline int __constant_test_bit(int nr, const volatile void * addr) | 223 | static inline int |
224 | __constant_test_bit(unsigned long nr, const volatile void *addr) | ||
224 | { | 225 | { |
225 | return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; | 226 | return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; |
226 | } | 227 | } |
227 | 228 | ||
228 | static inline int __test_bit(int nr, const volatile void * addr) | 229 | static inline int __test_bit(unsigned long nr, const volatile void *addr) |
229 | { | 230 | { |
230 | int * a = (int *) addr; | 231 | int * a = (int *) addr; |
231 | int mask; | 232 | int mask; |
diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h index 7279ec07d62e..7bbf6e47f8c8 100644 --- a/arch/frv/include/asm/elf.h +++ b/arch/frv/include/asm/elf.h | |||
@@ -116,6 +116,7 @@ do { \ | |||
116 | } while(0) | 116 | } while(0) |
117 | 117 | ||
118 | #define USE_ELF_CORE_DUMP | 118 | #define USE_ELF_CORE_DUMP |
119 | #define CORE_DUMP_USE_REGSET | ||
119 | #define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC | 120 | #define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC |
120 | #define ELF_EXEC_PAGESIZE 16384 | 121 | #define ELF_EXEC_PAGESIZE 16384 |
121 | 122 | ||
diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h index 3ce227ba7744..492b5c4dfed6 100644 --- a/arch/frv/include/asm/pci.h +++ b/arch/frv/include/asm/pci.h | |||
@@ -81,8 +81,7 @@ static inline void pci_dma_sync_single(struct pci_dev *hwdev, | |||
81 | dma_addr_t dma_handle, | 81 | dma_addr_t dma_handle, |
82 | size_t size, int direction) | 82 | size_t size, int direction) |
83 | { | 83 | { |
84 | if (direction == PCI_DMA_NONE) | 84 | BUG_ON(direction == PCI_DMA_NONE); |
85 | BUG(); | ||
86 | 85 | ||
87 | frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), | 86 | frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), |
88 | (unsigned long)bus_to_virt(dma_handle) + size); | 87 | (unsigned long)bus_to_virt(dma_handle) + size); |
@@ -99,9 +98,7 @@ static inline void pci_dma_sync_sg(struct pci_dev *hwdev, | |||
99 | int nelems, int direction) | 98 | int nelems, int direction) |
100 | { | 99 | { |
101 | int i; | 100 | int i; |
102 | 101 | BUG_ON(direction == PCI_DMA_NONE); | |
103 | if (direction == PCI_DMA_NONE) | ||
104 | BUG(); | ||
105 | 102 | ||
106 | for (i = 0; i < nelems; i++) | 103 | for (i = 0; i < nelems; i++) |
107 | frv_cache_wback_inv(sg_dma_address(&sg[i]), | 104 | frv_cache_wback_inv(sg_dma_address(&sg[i]), |
diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h index cf6934012b64..a54b535c9e49 100644 --- a/arch/frv/include/asm/ptrace.h +++ b/arch/frv/include/asm/ptrace.h | |||
@@ -65,6 +65,8 @@ | |||
65 | #ifdef __KERNEL__ | 65 | #ifdef __KERNEL__ |
66 | #ifndef __ASSEMBLY__ | 66 | #ifndef __ASSEMBLY__ |
67 | 67 | ||
68 | struct task_struct; | ||
69 | |||
68 | /* | 70 | /* |
69 | * we dedicate GR28 to keeping a pointer to the current exception frame | 71 | * we dedicate GR28 to keeping a pointer to the current exception frame |
70 | * - gr28 is destroyed on entry to the kernel from userspace | 72 | * - gr28 is destroyed on entry to the kernel from userspace |
@@ -73,11 +75,18 @@ register struct pt_regs *__frame asm("gr28"); | |||
73 | 75 | ||
74 | #define user_mode(regs) (!((regs)->psr & PSR_S)) | 76 | #define user_mode(regs) (!((regs)->psr & PSR_S)) |
75 | #define instruction_pointer(regs) ((regs)->pc) | 77 | #define instruction_pointer(regs) ((regs)->pc) |
78 | #define user_stack_pointer(regs) ((regs)->sp) | ||
76 | 79 | ||
77 | extern unsigned long user_stack(const struct pt_regs *); | 80 | extern unsigned long user_stack(const struct pt_regs *); |
78 | extern void show_regs(struct pt_regs *); | 81 | extern void show_regs(struct pt_regs *); |
79 | #define profile_pc(regs) ((regs)->pc) | 82 | #define profile_pc(regs) ((regs)->pc) |
80 | #endif | 83 | |
84 | #define task_pt_regs(task) ((task)->thread.frame0) | ||
85 | |||
86 | #define arch_has_single_step() (1) | ||
87 | extern void user_enable_single_step(struct task_struct *); | ||
88 | extern void user_disable_single_step(struct task_struct *); | ||
81 | 89 | ||
82 | #endif /* !__ASSEMBLY__ */ | 90 | #endif /* !__ASSEMBLY__ */ |
91 | #endif /* __KERNEL__ */ | ||
83 | #endif /* _ASM_PTRACE_H */ | 92 | #endif /* _ASM_PTRACE_H */ |
diff --git a/arch/frv/include/asm/syscall.h b/arch/frv/include/asm/syscall.h new file mode 100644 index 000000000000..70689eb29b98 --- /dev/null +++ b/arch/frv/include/asm/syscall.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* syscall parameter access functions | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef _ASM_SYSCALL_H | ||
13 | #define _ASM_SYSCALL_H | ||
14 | |||
15 | #include <linux/err.h> | ||
16 | #include <asm/ptrace.h> | ||
17 | |||
18 | /* | ||
19 | * Get the system call number or -1 | ||
20 | */ | ||
21 | static inline long syscall_get_nr(struct task_struct *task, | ||
22 | struct pt_regs *regs) | ||
23 | { | ||
24 | return regs->syscallno; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | * Restore the clobbered GR8 register | ||
29 | * (1st syscall arg was overwritten with syscall return or error) | ||
30 | */ | ||
31 | static inline void syscall_rollback(struct task_struct *task, | ||
32 | struct pt_regs *regs) | ||
33 | { | ||
34 | regs->gr8 = regs->orig_gr8; | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * See if the syscall return value is an error, returning it if it is and 0 if | ||
39 | * not | ||
40 | */ | ||
41 | static inline long syscall_get_error(struct task_struct *task, | ||
42 | struct pt_regs *regs) | ||
43 | { | ||
44 | return IS_ERR_VALUE(regs->gr8) ? regs->gr8 : 0; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Get the syscall return value | ||
49 | */ | ||
50 | static inline long syscall_get_return_value(struct task_struct *task, | ||
51 | struct pt_regs *regs) | ||
52 | { | ||
53 | return regs->gr8; | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Set the syscall return value | ||
58 | */ | ||
59 | static inline void syscall_set_return_value(struct task_struct *task, | ||
60 | struct pt_regs *regs, | ||
61 | int error, long val) | ||
62 | { | ||
63 | if (error) | ||
64 | regs->gr8 = -error; | ||
65 | else | ||
66 | regs->gr8 = val; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * Retrieve the system call arguments | ||
71 | */ | ||
72 | static inline void syscall_get_arguments(struct task_struct *task, | ||
73 | struct pt_regs *regs, | ||
74 | unsigned int i, unsigned int n, | ||
75 | unsigned long *args) | ||
76 | { | ||
77 | /* | ||
78 | * Do this simply for now. If we need to start supporting | ||
79 | * fetching arguments from arbitrary indices, this will need some | ||
80 | * extra logic. Presently there are no in-tree users that depend | ||
81 | * on this behaviour. | ||
82 | */ | ||
83 | BUG_ON(i); | ||
84 | |||
85 | /* Argument pattern is: GR8, GR9, GR10, GR11, GR12, GR13 */ | ||
86 | switch (n) { | ||
87 | case 6: args[5] = regs->gr13; | ||
88 | case 5: args[4] = regs->gr12; | ||
89 | case 4: args[3] = regs->gr11; | ||
90 | case 3: args[2] = regs->gr10; | ||
91 | case 2: args[1] = regs->gr9; | ||
92 | case 1: args[0] = regs->gr8; | ||
93 | break; | ||
94 | default: | ||
95 | BUG(); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Alter the system call arguments | ||
101 | */ | ||
102 | static inline void syscall_set_arguments(struct task_struct *task, | ||
103 | struct pt_regs *regs, | ||
104 | unsigned int i, unsigned int n, | ||
105 | const unsigned long *args) | ||
106 | { | ||
107 | /* Same note as above applies */ | ||
108 | BUG_ON(i); | ||
109 | |||
110 | switch (n) { | ||
111 | case 6: regs->gr13 = args[5]; | ||
112 | case 5: regs->gr12 = args[4]; | ||
113 | case 4: regs->gr11 = args[3]; | ||
114 | case 3: regs->gr10 = args[2]; | ||
115 | case 2: regs->gr9 = args[1]; | ||
116 | case 1: regs->gr8 = args[0]; | ||
117 | break; | ||
118 | default: | ||
119 | BUG(); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | #endif /* _ASM_SYSCALL_H */ | ||
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h index bb53ab753ffb..e8a5ed7be021 100644 --- a/arch/frv/include/asm/thread_info.h +++ b/arch/frv/include/asm/thread_info.h | |||
@@ -109,20 +109,20 @@ register struct thread_info *__current_thread_info asm("gr15"); | |||
109 | * - other flags in MSW | 109 | * - other flags in MSW |
110 | */ | 110 | */ |
111 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 111 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
112 | #define TIF_SIGPENDING 1 /* signal pending */ | 112 | #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ |
113 | #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ | 113 | #define TIF_SIGPENDING 2 /* signal pending */ |
114 | #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ | 114 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
115 | #define TIF_IRET 4 /* return with iret */ | 115 | #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ |
116 | #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ | 116 | #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ |
117 | #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ | 117 | #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ |
118 | #define TIF_MEMDIE 17 /* OOM killer killed process */ | 118 | #define TIF_MEMDIE 17 /* OOM killer killed process */ |
119 | #define TIF_FREEZE 18 /* freezing for suspend */ | 119 | #define TIF_FREEZE 18 /* freezing for suspend */ |
120 | 120 | ||
121 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 121 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
122 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | ||
122 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 123 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
123 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) | 124 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
124 | #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) | 125 | #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) |
125 | #define _TIF_IRET (1 << TIF_IRET) | ||
126 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) | 126 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) |
127 | #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) | 127 | #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) |
128 | #define _TIF_FREEZE (1 << TIF_FREEZE) | 128 | #define _TIF_FREEZE (1 << TIF_FREEZE) |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 1da523b3298e..356e0e327a89 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -886,7 +886,6 @@ system_call: | |||
886 | bnc icc0,#0,__syscall_badsys | 886 | bnc icc0,#0,__syscall_badsys |
887 | 887 | ||
888 | ldi @(gr15,#TI_FLAGS),gr4 | 888 | ldi @(gr15,#TI_FLAGS),gr4 |
889 | ori gr4,#_TIF_SYSCALL_TRACE,gr4 | ||
890 | andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0 | 889 | andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0 |
891 | bne icc0,#0,__syscall_trace_entry | 890 | bne icc0,#0,__syscall_trace_entry |
892 | 891 | ||
@@ -1150,11 +1149,10 @@ __entry_work_notifysig: | |||
1150 | # perform syscall entry tracing | 1149 | # perform syscall entry tracing |
1151 | __syscall_trace_entry: | 1150 | __syscall_trace_entry: |
1152 | LEDS 0x6320 | 1151 | LEDS 0x6320 |
1153 | setlos.p #0,gr8 | 1152 | call syscall_trace_entry |
1154 | call do_syscall_trace | ||
1155 | 1153 | ||
1156 | ldi @(gr28,#REG_SYSCALLNO),gr7 | 1154 | lddi.p @(gr28,#REG_GR(8)) ,gr8 |
1157 | lddi @(gr28,#REG_GR(8)) ,gr8 | 1155 | ori gr8,#0,gr7 ; syscall_trace_entry() returned new syscallno |
1158 | lddi @(gr28,#REG_GR(10)),gr10 | 1156 | lddi @(gr28,#REG_GR(10)),gr10 |
1159 | lddi.p @(gr28,#REG_GR(12)),gr12 | 1157 | lddi.p @(gr28,#REG_GR(12)),gr12 |
1160 | 1158 | ||
@@ -1169,11 +1167,10 @@ __syscall_exit_work: | |||
1169 | beq icc0,#1,__entry_work_pending | 1167 | beq icc0,#1,__entry_work_pending |
1170 | 1168 | ||
1171 | movsg psr,gr23 | 1169 | movsg psr,gr23 |
1172 | andi gr23,#~PSR_PIL,gr23 ; could let do_syscall_trace() call schedule() | 1170 | andi gr23,#~PSR_PIL,gr23 ; could let syscall_trace_exit() call schedule() |
1173 | movgs gr23,psr | 1171 | movgs gr23,psr |
1174 | 1172 | ||
1175 | setlos.p #1,gr8 | 1173 | call syscall_trace_exit |
1176 | call do_syscall_trace | ||
1177 | bra __entry_resume_userspace | 1174 | bra __entry_resume_userspace |
1178 | 1175 | ||
1179 | __syscall_badsys: | 1176 | __syscall_badsys: |
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c index 5e7d401d21e7..60eeed3694c0 100644 --- a/arch/frv/kernel/ptrace.c +++ b/arch/frv/kernel/ptrace.c | |||
@@ -19,6 +19,9 @@ | |||
19 | #include <linux/user.h> | 19 | #include <linux/user.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | #include <linux/signal.h> | 21 | #include <linux/signal.h> |
22 | #include <linux/regset.h> | ||
23 | #include <linux/elf.h> | ||
24 | #include <linux/tracehook.h> | ||
22 | 25 | ||
23 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
24 | #include <asm/page.h> | 27 | #include <asm/page.h> |
@@ -33,6 +36,169 @@ | |||
33 | */ | 36 | */ |
34 | 37 | ||
35 | /* | 38 | /* |
39 | * retrieve the contents of FRV userspace general registers | ||
40 | */ | ||
41 | static int genregs_get(struct task_struct *target, | ||
42 | const struct user_regset *regset, | ||
43 | unsigned int pos, unsigned int count, | ||
44 | void *kbuf, void __user *ubuf) | ||
45 | { | ||
46 | const struct user_int_regs *iregs = &target->thread.user->i; | ||
47 | int ret; | ||
48 | |||
49 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
50 | iregs, 0, sizeof(*iregs)); | ||
51 | if (ret < 0) | ||
52 | return ret; | ||
53 | |||
54 | return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, | ||
55 | sizeof(*iregs), -1); | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * update the contents of the FRV userspace general registers | ||
60 | */ | ||
61 | static int genregs_set(struct task_struct *target, | ||
62 | const struct user_regset *regset, | ||
63 | unsigned int pos, unsigned int count, | ||
64 | const void *kbuf, const void __user *ubuf) | ||
65 | { | ||
66 | struct user_int_regs *iregs = &target->thread.user->i; | ||
67 | unsigned int offs_gr0, offs_gr1; | ||
68 | int ret; | ||
69 | |||
70 | /* not allowed to set PSR or __status */ | ||
71 | if (pos < offsetof(struct user_int_regs, psr) + sizeof(long) && | ||
72 | pos + count > offsetof(struct user_int_regs, psr)) | ||
73 | return -EIO; | ||
74 | |||
75 | if (pos < offsetof(struct user_int_regs, __status) + sizeof(long) && | ||
76 | pos + count > offsetof(struct user_int_regs, __status)) | ||
77 | return -EIO; | ||
78 | |||
79 | /* set the control regs */ | ||
80 | offs_gr0 = offsetof(struct user_int_regs, gr[0]); | ||
81 | offs_gr1 = offsetof(struct user_int_regs, gr[1]); | ||
82 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
83 | iregs, 0, offs_gr0); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | |||
87 | /* skip GR0/TBR */ | ||
88 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
89 | offs_gr0, offs_gr1); | ||
90 | if (ret < 0) | ||
91 | return ret; | ||
92 | |||
93 | /* set the general regs */ | ||
94 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
95 | &iregs->gr[1], offs_gr1, sizeof(*iregs)); | ||
96 | if (ret < 0) | ||
97 | return ret; | ||
98 | |||
99 | return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
100 | sizeof(*iregs), -1); | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * retrieve the contents of FRV userspace FP/Media registers | ||
105 | */ | ||
106 | static int fpmregs_get(struct task_struct *target, | ||
107 | const struct user_regset *regset, | ||
108 | unsigned int pos, unsigned int count, | ||
109 | void *kbuf, void __user *ubuf) | ||
110 | { | ||
111 | const struct user_fpmedia_regs *fpregs = &target->thread.user->f; | ||
112 | int ret; | ||
113 | |||
114 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
115 | fpregs, 0, sizeof(*fpregs)); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | |||
119 | return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, | ||
120 | sizeof(*fpregs), -1); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * update the contents of the FRV userspace FP/Media registers | ||
125 | */ | ||
126 | static int fpmregs_set(struct task_struct *target, | ||
127 | const struct user_regset *regset, | ||
128 | unsigned int pos, unsigned int count, | ||
129 | const void *kbuf, const void __user *ubuf) | ||
130 | { | ||
131 | struct user_fpmedia_regs *fpregs = &target->thread.user->f; | ||
132 | int ret; | ||
133 | |||
134 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
135 | fpregs, 0, sizeof(*fpregs)); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
140 | sizeof(*fpregs), -1); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * determine if the FP/Media registers have actually been used | ||
145 | */ | ||
146 | static int fpmregs_active(struct task_struct *target, | ||
147 | const struct user_regset *regset) | ||
148 | { | ||
149 | return tsk_used_math(target) ? regset->n : 0; | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * Define the register sets available on the FRV under Linux | ||
154 | */ | ||
155 | enum frv_regset { | ||
156 | REGSET_GENERAL, | ||
157 | REGSET_FPMEDIA, | ||
158 | }; | ||
159 | |||
160 | static const struct user_regset frv_regsets[] = { | ||
161 | /* | ||
162 | * General register format is: | ||
163 | * PSR, ISR, CCR, CCCR, LR, LCR, PC, (STATUS), SYSCALLNO, ORIG_G8 | ||
164 | * GNER0-1, IACC0, TBR, GR1-63 | ||
165 | */ | ||
166 | [REGSET_GENERAL] = { | ||
167 | .core_note_type = NT_PRSTATUS, | ||
168 | .n = ELF_NGREG, | ||
169 | .size = sizeof(long), | ||
170 | .align = sizeof(long), | ||
171 | .get = genregs_get, | ||
172 | .set = genregs_set, | ||
173 | }, | ||
174 | /* | ||
175 | * FPU/Media register format is: | ||
176 | * FR0-63, FNER0-1, MSR0-1, ACC0-7, ACCG0-8, FSR | ||
177 | */ | ||
178 | [REGSET_FPMEDIA] = { | ||
179 | .core_note_type = NT_PRFPREG, | ||
180 | .n = sizeof(struct user_fpmedia_regs) / sizeof(long), | ||
181 | .size = sizeof(long), | ||
182 | .align = sizeof(long), | ||
183 | .get = fpmregs_get, | ||
184 | .set = fpmregs_set, | ||
185 | .active = fpmregs_active, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static const struct user_regset_view user_frv_native_view = { | ||
190 | .name = "frv", | ||
191 | .e_machine = EM_FRV, | ||
192 | .regsets = frv_regsets, | ||
193 | .n = ARRAY_SIZE(frv_regsets), | ||
194 | }; | ||
195 | |||
196 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) | ||
197 | { | ||
198 | return &user_frv_native_view; | ||
199 | } | ||
200 | |||
201 | /* | ||
36 | * Get contents of register REGNO in task TASK. | 202 | * Get contents of register REGNO in task TASK. |
37 | */ | 203 | */ |
38 | static inline long get_reg(struct task_struct *task, int regno) | 204 | static inline long get_reg(struct task_struct *task, int regno) |
@@ -69,40 +235,23 @@ static inline int put_reg(struct task_struct *task, int regno, | |||
69 | } | 235 | } |
70 | 236 | ||
71 | /* | 237 | /* |
72 | * check that an address falls within the bounds of the target process's memory | ||
73 | * mappings | ||
74 | */ | ||
75 | static inline int is_user_addr_valid(struct task_struct *child, | ||
76 | unsigned long start, unsigned long len) | ||
77 | { | ||
78 | #ifdef CONFIG_MMU | ||
79 | if (start >= PAGE_OFFSET || len > PAGE_OFFSET - start) | ||
80 | return -EIO; | ||
81 | return 0; | ||
82 | #else | ||
83 | struct vm_area_struct *vma; | ||
84 | |||
85 | vma = find_vma(child->mm, start); | ||
86 | if (vma && start >= vma->vm_start && start + len <= vma->vm_end) | ||
87 | return 0; | ||
88 | |||
89 | return -EIO; | ||
90 | #endif | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Called by kernel/ptrace.c when detaching.. | 238 | * Called by kernel/ptrace.c when detaching.. |
95 | * | 239 | * |
96 | * Control h/w single stepping | 240 | * Control h/w single stepping |
97 | */ | 241 | */ |
98 | void ptrace_disable(struct task_struct *child) | 242 | void user_enable_single_step(struct task_struct *child) |
243 | { | ||
244 | child->thread.frame0->__status |= REG__STATUS_STEP; | ||
245 | } | ||
246 | |||
247 | void user_disable_single_step(struct task_struct *child) | ||
99 | { | 248 | { |
100 | child->thread.frame0->__status &= ~REG__STATUS_STEP; | 249 | child->thread.frame0->__status &= ~REG__STATUS_STEP; |
101 | } | 250 | } |
102 | 251 | ||
103 | void ptrace_enable(struct task_struct *child) | 252 | void ptrace_disable(struct task_struct *child) |
104 | { | 253 | { |
105 | child->thread.frame0->__status |= REG__STATUS_STEP; | 254 | user_disable_single_step(child); |
106 | } | 255 | } |
107 | 256 | ||
108 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 257 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
@@ -111,15 +260,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
111 | int ret; | 260 | int ret; |
112 | 261 | ||
113 | switch (request) { | 262 | switch (request) { |
114 | /* when I and D space are separate, these will need to be fixed. */ | ||
115 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | ||
116 | case PTRACE_PEEKDATA: | ||
117 | ret = -EIO; | ||
118 | if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) | ||
119 | break; | ||
120 | ret = generic_ptrace_peekdata(child, addr, data); | ||
121 | break; | ||
122 | |||
123 | /* read the word at location addr in the USER area. */ | 263 | /* read the word at location addr in the USER area. */ |
124 | case PTRACE_PEEKUSR: { | 264 | case PTRACE_PEEKUSR: { |
125 | tmp = 0; | 265 | tmp = 0; |
@@ -163,15 +303,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
163 | break; | 303 | break; |
164 | } | 304 | } |
165 | 305 | ||
166 | /* when I and D space are separate, this will have to be fixed. */ | ||
167 | case PTRACE_POKETEXT: /* write the word at location addr. */ | ||
168 | case PTRACE_POKEDATA: | ||
169 | ret = -EIO; | ||
170 | if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) | ||
171 | break; | ||
172 | ret = generic_ptrace_pokedata(child, addr, data); | ||
173 | break; | ||
174 | |||
175 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 306 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
176 | ret = -EIO; | 307 | ret = -EIO; |
177 | if ((addr & 3) || addr < 0) | 308 | if ((addr & 3) || addr < 0) |
@@ -179,7 +310,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
179 | 310 | ||
180 | ret = 0; | 311 | ret = 0; |
181 | switch (addr >> 2) { | 312 | switch (addr >> 2) { |
182 | case 0 ... PT__END-1: | 313 | case 0 ... PT__END - 1: |
183 | ret = put_reg(child, addr >> 2, data); | 314 | ret = put_reg(child, addr >> 2, data); |
184 | break; | 315 | break; |
185 | 316 | ||
@@ -189,95 +320,29 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
189 | } | 320 | } |
190 | break; | 321 | break; |
191 | 322 | ||
192 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 323 | case PTRACE_GETREGS: /* Get all integer regs from the child. */ |
193 | case PTRACE_CONT: /* restart after signal. */ | 324 | return copy_regset_to_user(child, &user_frv_native_view, |
194 | ret = -EIO; | 325 | REGSET_GENERAL, |
195 | if (!valid_signal(data)) | 326 | 0, sizeof(child->thread.user->i), |
196 | break; | 327 | (void __user *)data); |
197 | if (request == PTRACE_SYSCALL) | 328 | |
198 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 329 | case PTRACE_SETREGS: /* Set all integer regs in the child. */ |
199 | else | 330 | return copy_regset_from_user(child, &user_frv_native_view, |
200 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 331 | REGSET_GENERAL, |
201 | child->exit_code = data; | 332 | 0, sizeof(child->thread.user->i), |
202 | ptrace_disable(child); | 333 | (const void __user *)data); |
203 | wake_up_process(child); | 334 | |
204 | ret = 0; | 335 | case PTRACE_GETFPREGS: /* Get the child FP/Media state. */ |
205 | break; | 336 | return copy_regset_to_user(child, &user_frv_native_view, |
206 | 337 | REGSET_FPMEDIA, | |
207 | /* make the child exit. Best I can do is send it a sigkill. | 338 | 0, sizeof(child->thread.user->f), |
208 | * perhaps it should be put in the status that it wants to | 339 | (void __user *)data); |
209 | * exit. | 340 | |
210 | */ | 341 | case PTRACE_SETFPREGS: /* Set the child FP/Media state. */ |
211 | case PTRACE_KILL: | 342 | return copy_regset_from_user(child, &user_frv_native_view, |
212 | ret = 0; | 343 | REGSET_FPMEDIA, |
213 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | 344 | 0, sizeof(child->thread.user->f), |
214 | break; | 345 | (const void __user *)data); |
215 | child->exit_code = SIGKILL; | ||
216 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
217 | ptrace_disable(child); | ||
218 | wake_up_process(child); | ||
219 | break; | ||
220 | |||
221 | case PTRACE_SINGLESTEP: /* set the trap flag. */ | ||
222 | ret = -EIO; | ||
223 | if (!valid_signal(data)) | ||
224 | break; | ||
225 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
226 | ptrace_enable(child); | ||
227 | child->exit_code = data; | ||
228 | wake_up_process(child); | ||
229 | ret = 0; | ||
230 | break; | ||
231 | |||
232 | case PTRACE_DETACH: /* detach a process that was attached. */ | ||
233 | ret = ptrace_detach(child, data); | ||
234 | break; | ||
235 | |||
236 | case PTRACE_GETREGS: { /* Get all integer regs from the child. */ | ||
237 | int i; | ||
238 | for (i = 0; i < PT__GPEND; i++) { | ||
239 | tmp = get_reg(child, i); | ||
240 | if (put_user(tmp, (unsigned long *) data)) { | ||
241 | ret = -EFAULT; | ||
242 | break; | ||
243 | } | ||
244 | data += sizeof(long); | ||
245 | } | ||
246 | ret = 0; | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | case PTRACE_SETREGS: { /* Set all integer regs in the child. */ | ||
251 | int i; | ||
252 | for (i = 0; i < PT__GPEND; i++) { | ||
253 | if (get_user(tmp, (unsigned long *) data)) { | ||
254 | ret = -EFAULT; | ||
255 | break; | ||
256 | } | ||
257 | put_reg(child, i, tmp); | ||
258 | data += sizeof(long); | ||
259 | } | ||
260 | ret = 0; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | case PTRACE_GETFPREGS: { /* Get the child FP/Media state. */ | ||
265 | ret = 0; | ||
266 | if (copy_to_user((void *) data, | ||
267 | &child->thread.user->f, | ||
268 | sizeof(child->thread.user->f))) | ||
269 | ret = -EFAULT; | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | case PTRACE_SETFPREGS: { /* Set the child FP/Media state. */ | ||
274 | ret = 0; | ||
275 | if (copy_from_user(&child->thread.user->f, | ||
276 | (void *) data, | ||
277 | sizeof(child->thread.user->f))) | ||
278 | ret = -EFAULT; | ||
279 | break; | ||
280 | } | ||
281 | 346 | ||
282 | case PTRACE_GETFDPIC: | 347 | case PTRACE_GETFDPIC: |
283 | tmp = 0; | 348 | tmp = 0; |
@@ -300,414 +365,36 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
300 | break; | 365 | break; |
301 | 366 | ||
302 | default: | 367 | default: |
303 | ret = -EIO; | 368 | ret = ptrace_request(child, request, addr, data); |
304 | break; | 369 | break; |
305 | } | 370 | } |
306 | return ret; | 371 | return ret; |
307 | } | 372 | } |
308 | 373 | ||
309 | int __nongprelbss kstrace; | 374 | /* |
310 | 375 | * handle tracing of system call entry | |
311 | static const struct { | 376 | * - return the revised system call number or ULONG_MAX to cause ENOSYS |
312 | const char *name; | 377 | */ |
313 | unsigned argmask; | 378 | asmlinkage unsigned long syscall_trace_entry(void) |
314 | } __syscall_name_table[NR_syscalls] = { | ||
315 | [0] = { "restart_syscall" }, | ||
316 | [1] = { "exit", 0x000001 }, | ||
317 | [2] = { "fork", 0xffffff }, | ||
318 | [3] = { "read", 0x000141 }, | ||
319 | [4] = { "write", 0x000141 }, | ||
320 | [5] = { "open", 0x000235 }, | ||
321 | [6] = { "close", 0x000001 }, | ||
322 | [7] = { "waitpid", 0x000141 }, | ||
323 | [8] = { "creat", 0x000025 }, | ||
324 | [9] = { "link", 0x000055 }, | ||
325 | [10] = { "unlink", 0x000005 }, | ||
326 | [11] = { "execve", 0x000445 }, | ||
327 | [12] = { "chdir", 0x000005 }, | ||
328 | [13] = { "time", 0x000004 }, | ||
329 | [14] = { "mknod", 0x000325 }, | ||
330 | [15] = { "chmod", 0x000025 }, | ||
331 | [16] = { "lchown", 0x000025 }, | ||
332 | [17] = { "break" }, | ||
333 | [18] = { "oldstat", 0x000045 }, | ||
334 | [19] = { "lseek", 0x000131 }, | ||
335 | [20] = { "getpid", 0xffffff }, | ||
336 | [21] = { "mount", 0x043555 }, | ||
337 | [22] = { "umount", 0x000005 }, | ||
338 | [23] = { "setuid", 0x000001 }, | ||
339 | [24] = { "getuid", 0xffffff }, | ||
340 | [25] = { "stime", 0x000004 }, | ||
341 | [26] = { "ptrace", 0x004413 }, | ||
342 | [27] = { "alarm", 0x000001 }, | ||
343 | [28] = { "oldfstat", 0x000041 }, | ||
344 | [29] = { "pause", 0xffffff }, | ||
345 | [30] = { "utime", 0x000045 }, | ||
346 | [31] = { "stty" }, | ||
347 | [32] = { "gtty" }, | ||
348 | [33] = { "access", 0x000025 }, | ||
349 | [34] = { "nice", 0x000001 }, | ||
350 | [35] = { "ftime" }, | ||
351 | [36] = { "sync", 0xffffff }, | ||
352 | [37] = { "kill", 0x000011 }, | ||
353 | [38] = { "rename", 0x000055 }, | ||
354 | [39] = { "mkdir", 0x000025 }, | ||
355 | [40] = { "rmdir", 0x000005 }, | ||
356 | [41] = { "dup", 0x000001 }, | ||
357 | [42] = { "pipe", 0x000004 }, | ||
358 | [43] = { "times", 0x000004 }, | ||
359 | [44] = { "prof" }, | ||
360 | [45] = { "brk", 0x000004 }, | ||
361 | [46] = { "setgid", 0x000001 }, | ||
362 | [47] = { "getgid", 0xffffff }, | ||
363 | [48] = { "signal", 0x000041 }, | ||
364 | [49] = { "geteuid", 0xffffff }, | ||
365 | [50] = { "getegid", 0xffffff }, | ||
366 | [51] = { "acct", 0x000005 }, | ||
367 | [52] = { "umount2", 0x000035 }, | ||
368 | [53] = { "lock" }, | ||
369 | [54] = { "ioctl", 0x000331 }, | ||
370 | [55] = { "fcntl", 0x000331 }, | ||
371 | [56] = { "mpx" }, | ||
372 | [57] = { "setpgid", 0x000011 }, | ||
373 | [58] = { "ulimit" }, | ||
374 | [60] = { "umask", 0x000002 }, | ||
375 | [61] = { "chroot", 0x000005 }, | ||
376 | [62] = { "ustat", 0x000043 }, | ||
377 | [63] = { "dup2", 0x000011 }, | ||
378 | [64] = { "getppid", 0xffffff }, | ||
379 | [65] = { "getpgrp", 0xffffff }, | ||
380 | [66] = { "setsid", 0xffffff }, | ||
381 | [67] = { "sigaction" }, | ||
382 | [68] = { "sgetmask" }, | ||
383 | [69] = { "ssetmask" }, | ||
384 | [70] = { "setreuid" }, | ||
385 | [71] = { "setregid" }, | ||
386 | [72] = { "sigsuspend" }, | ||
387 | [73] = { "sigpending" }, | ||
388 | [74] = { "sethostname" }, | ||
389 | [75] = { "setrlimit" }, | ||
390 | [76] = { "getrlimit" }, | ||
391 | [77] = { "getrusage" }, | ||
392 | [78] = { "gettimeofday" }, | ||
393 | [79] = { "settimeofday" }, | ||
394 | [80] = { "getgroups" }, | ||
395 | [81] = { "setgroups" }, | ||
396 | [82] = { "select" }, | ||
397 | [83] = { "symlink" }, | ||
398 | [84] = { "oldlstat" }, | ||
399 | [85] = { "readlink" }, | ||
400 | [86] = { "uselib" }, | ||
401 | [87] = { "swapon" }, | ||
402 | [88] = { "reboot" }, | ||
403 | [89] = { "readdir" }, | ||
404 | [91] = { "munmap", 0x000034 }, | ||
405 | [92] = { "truncate" }, | ||
406 | [93] = { "ftruncate" }, | ||
407 | [94] = { "fchmod" }, | ||
408 | [95] = { "fchown" }, | ||
409 | [96] = { "getpriority" }, | ||
410 | [97] = { "setpriority" }, | ||
411 | [99] = { "statfs" }, | ||
412 | [100] = { "fstatfs" }, | ||
413 | [102] = { "socketcall" }, | ||
414 | [103] = { "syslog" }, | ||
415 | [104] = { "setitimer" }, | ||
416 | [105] = { "getitimer" }, | ||
417 | [106] = { "stat" }, | ||
418 | [107] = { "lstat" }, | ||
419 | [108] = { "fstat" }, | ||
420 | [111] = { "vhangup" }, | ||
421 | [114] = { "wait4" }, | ||
422 | [115] = { "swapoff" }, | ||
423 | [116] = { "sysinfo" }, | ||
424 | [117] = { "ipc" }, | ||
425 | [118] = { "fsync" }, | ||
426 | [119] = { "sigreturn" }, | ||
427 | [120] = { "clone" }, | ||
428 | [121] = { "setdomainname" }, | ||
429 | [122] = { "uname" }, | ||
430 | [123] = { "modify_ldt" }, | ||
431 | [123] = { "cacheflush" }, | ||
432 | [124] = { "adjtimex" }, | ||
433 | [125] = { "mprotect" }, | ||
434 | [126] = { "sigprocmask" }, | ||
435 | [127] = { "create_module" }, | ||
436 | [128] = { "init_module" }, | ||
437 | [129] = { "delete_module" }, | ||
438 | [130] = { "get_kernel_syms" }, | ||
439 | [131] = { "quotactl" }, | ||
440 | [132] = { "getpgid" }, | ||
441 | [133] = { "fchdir" }, | ||
442 | [134] = { "bdflush" }, | ||
443 | [135] = { "sysfs" }, | ||
444 | [136] = { "personality" }, | ||
445 | [137] = { "afs_syscall" }, | ||
446 | [138] = { "setfsuid" }, | ||
447 | [139] = { "setfsgid" }, | ||
448 | [140] = { "_llseek", 0x014331 }, | ||
449 | [141] = { "getdents" }, | ||
450 | [142] = { "_newselect", 0x000141 }, | ||
451 | [143] = { "flock" }, | ||
452 | [144] = { "msync" }, | ||
453 | [145] = { "readv" }, | ||
454 | [146] = { "writev" }, | ||
455 | [147] = { "getsid", 0x000001 }, | ||
456 | [148] = { "fdatasync", 0x000001 }, | ||
457 | [149] = { "_sysctl", 0x000004 }, | ||
458 | [150] = { "mlock" }, | ||
459 | [151] = { "munlock" }, | ||
460 | [152] = { "mlockall" }, | ||
461 | [153] = { "munlockall" }, | ||
462 | [154] = { "sched_setparam" }, | ||
463 | [155] = { "sched_getparam" }, | ||
464 | [156] = { "sched_setscheduler" }, | ||
465 | [157] = { "sched_getscheduler" }, | ||
466 | [158] = { "sched_yield" }, | ||
467 | [159] = { "sched_get_priority_max" }, | ||
468 | [160] = { "sched_get_priority_min" }, | ||
469 | [161] = { "sched_rr_get_interval" }, | ||
470 | [162] = { "nanosleep", 0x000044 }, | ||
471 | [163] = { "mremap" }, | ||
472 | [164] = { "setresuid" }, | ||
473 | [165] = { "getresuid" }, | ||
474 | [166] = { "vm86" }, | ||
475 | [167] = { "query_module" }, | ||
476 | [168] = { "poll" }, | ||
477 | [169] = { "nfsservctl" }, | ||
478 | [170] = { "setresgid" }, | ||
479 | [171] = { "getresgid" }, | ||
480 | [172] = { "prctl", 0x333331 }, | ||
481 | [173] = { "rt_sigreturn", 0xffffff }, | ||
482 | [174] = { "rt_sigaction", 0x001441 }, | ||
483 | [175] = { "rt_sigprocmask", 0x001441 }, | ||
484 | [176] = { "rt_sigpending", 0x000014 }, | ||
485 | [177] = { "rt_sigtimedwait", 0x001444 }, | ||
486 | [178] = { "rt_sigqueueinfo", 0x000411 }, | ||
487 | [179] = { "rt_sigsuspend", 0x000014 }, | ||
488 | [180] = { "pread", 0x003341 }, | ||
489 | [181] = { "pwrite", 0x003341 }, | ||
490 | [182] = { "chown", 0x000115 }, | ||
491 | [183] = { "getcwd" }, | ||
492 | [184] = { "capget" }, | ||
493 | [185] = { "capset" }, | ||
494 | [186] = { "sigaltstack" }, | ||
495 | [187] = { "sendfile" }, | ||
496 | [188] = { "getpmsg" }, | ||
497 | [189] = { "putpmsg" }, | ||
498 | [190] = { "vfork", 0xffffff }, | ||
499 | [191] = { "ugetrlimit" }, | ||
500 | [192] = { "mmap2", 0x313314 }, | ||
501 | [193] = { "truncate64" }, | ||
502 | [194] = { "ftruncate64" }, | ||
503 | [195] = { "stat64", 0x000045 }, | ||
504 | [196] = { "lstat64", 0x000045 }, | ||
505 | [197] = { "fstat64", 0x000041 }, | ||
506 | [198] = { "lchown32" }, | ||
507 | [199] = { "getuid32", 0xffffff }, | ||
508 | [200] = { "getgid32", 0xffffff }, | ||
509 | [201] = { "geteuid32", 0xffffff }, | ||
510 | [202] = { "getegid32", 0xffffff }, | ||
511 | [203] = { "setreuid32" }, | ||
512 | [204] = { "setregid32" }, | ||
513 | [205] = { "getgroups32" }, | ||
514 | [206] = { "setgroups32" }, | ||
515 | [207] = { "fchown32" }, | ||
516 | [208] = { "setresuid32" }, | ||
517 | [209] = { "getresuid32" }, | ||
518 | [210] = { "setresgid32" }, | ||
519 | [211] = { "getresgid32" }, | ||
520 | [212] = { "chown32" }, | ||
521 | [213] = { "setuid32" }, | ||
522 | [214] = { "setgid32" }, | ||
523 | [215] = { "setfsuid32" }, | ||
524 | [216] = { "setfsgid32" }, | ||
525 | [217] = { "pivot_root" }, | ||
526 | [218] = { "mincore" }, | ||
527 | [219] = { "madvise" }, | ||
528 | [220] = { "getdents64" }, | ||
529 | [221] = { "fcntl64" }, | ||
530 | [223] = { "security" }, | ||
531 | [224] = { "gettid" }, | ||
532 | [225] = { "readahead" }, | ||
533 | [226] = { "setxattr" }, | ||
534 | [227] = { "lsetxattr" }, | ||
535 | [228] = { "fsetxattr" }, | ||
536 | [229] = { "getxattr" }, | ||
537 | [230] = { "lgetxattr" }, | ||
538 | [231] = { "fgetxattr" }, | ||
539 | [232] = { "listxattr" }, | ||
540 | [233] = { "llistxattr" }, | ||
541 | [234] = { "flistxattr" }, | ||
542 | [235] = { "removexattr" }, | ||
543 | [236] = { "lremovexattr" }, | ||
544 | [237] = { "fremovexattr" }, | ||
545 | [238] = { "tkill" }, | ||
546 | [239] = { "sendfile64" }, | ||
547 | [240] = { "futex" }, | ||
548 | [241] = { "sched_setaffinity" }, | ||
549 | [242] = { "sched_getaffinity" }, | ||
550 | [243] = { "set_thread_area" }, | ||
551 | [244] = { "get_thread_area" }, | ||
552 | [245] = { "io_setup" }, | ||
553 | [246] = { "io_destroy" }, | ||
554 | [247] = { "io_getevents" }, | ||
555 | [248] = { "io_submit" }, | ||
556 | [249] = { "io_cancel" }, | ||
557 | [250] = { "fadvise64" }, | ||
558 | [252] = { "exit_group", 0x000001 }, | ||
559 | [253] = { "lookup_dcookie" }, | ||
560 | [254] = { "epoll_create" }, | ||
561 | [255] = { "epoll_ctl" }, | ||
562 | [256] = { "epoll_wait" }, | ||
563 | [257] = { "remap_file_pages" }, | ||
564 | [258] = { "set_tid_address" }, | ||
565 | [259] = { "timer_create" }, | ||
566 | [260] = { "timer_settime" }, | ||
567 | [261] = { "timer_gettime" }, | ||
568 | [262] = { "timer_getoverrun" }, | ||
569 | [263] = { "timer_delete" }, | ||
570 | [264] = { "clock_settime" }, | ||
571 | [265] = { "clock_gettime" }, | ||
572 | [266] = { "clock_getres" }, | ||
573 | [267] = { "clock_nanosleep" }, | ||
574 | [268] = { "statfs64" }, | ||
575 | [269] = { "fstatfs64" }, | ||
576 | [270] = { "tgkill" }, | ||
577 | [271] = { "utimes" }, | ||
578 | [272] = { "fadvise64_64" }, | ||
579 | [273] = { "vserver" }, | ||
580 | [274] = { "mbind" }, | ||
581 | [275] = { "get_mempolicy" }, | ||
582 | [276] = { "set_mempolicy" }, | ||
583 | [277] = { "mq_open" }, | ||
584 | [278] = { "mq_unlink" }, | ||
585 | [279] = { "mq_timedsend" }, | ||
586 | [280] = { "mq_timedreceive" }, | ||
587 | [281] = { "mq_notify" }, | ||
588 | [282] = { "mq_getsetattr" }, | ||
589 | [283] = { "sys_kexec_load" }, | ||
590 | }; | ||
591 | |||
592 | asmlinkage void do_syscall_trace(int leaving) | ||
593 | { | 379 | { |
594 | #if 0 | 380 | __frame->__status |= REG__STATUS_SYSC_ENTRY; |
595 | unsigned long *argp; | 381 | if (tracehook_report_syscall_entry(__frame)) { |
596 | const char *name; | 382 | /* tracing decided this syscall should not happen, so |
597 | unsigned argmask; | 383 | * We'll return a bogus call number to get an ENOSYS |
598 | char buffer[16]; | 384 | * error, but leave the original number in |
599 | 385 | * __frame->syscallno | |
600 | if (!kstrace) | 386 | */ |
601 | return; | 387 | return ULONG_MAX; |
602 | |||
603 | if (!current->mm) | ||
604 | return; | ||
605 | |||
606 | if (__frame->gr7 == __NR_close) | ||
607 | return; | ||
608 | |||
609 | #if 0 | ||
610 | if (__frame->gr7 != __NR_mmap2 && | ||
611 | __frame->gr7 != __NR_vfork && | ||
612 | __frame->gr7 != __NR_execve && | ||
613 | __frame->gr7 != __NR_exit) | ||
614 | return; | ||
615 | #endif | ||
616 | |||
617 | argmask = 0; | ||
618 | name = NULL; | ||
619 | if (__frame->gr7 < NR_syscalls) { | ||
620 | name = __syscall_name_table[__frame->gr7].name; | ||
621 | argmask = __syscall_name_table[__frame->gr7].argmask; | ||
622 | } | ||
623 | if (!name) { | ||
624 | sprintf(buffer, "sys_%lx", __frame->gr7); | ||
625 | name = buffer; | ||
626 | } | ||
627 | |||
628 | if (!leaving) { | ||
629 | if (!argmask) { | ||
630 | printk(KERN_CRIT "[%d] %s(%lx,%lx,%lx,%lx,%lx,%lx)\n", | ||
631 | current->pid, | ||
632 | name, | ||
633 | __frame->gr8, | ||
634 | __frame->gr9, | ||
635 | __frame->gr10, | ||
636 | __frame->gr11, | ||
637 | __frame->gr12, | ||
638 | __frame->gr13); | ||
639 | } | ||
640 | else if (argmask == 0xffffff) { | ||
641 | printk(KERN_CRIT "[%d] %s()\n", | ||
642 | current->pid, | ||
643 | name); | ||
644 | } | ||
645 | else { | ||
646 | printk(KERN_CRIT "[%d] %s(", | ||
647 | current->pid, | ||
648 | name); | ||
649 | |||
650 | argp = &__frame->gr8; | ||
651 | |||
652 | do { | ||
653 | switch (argmask & 0xf) { | ||
654 | case 1: | ||
655 | printk("%ld", (long) *argp); | ||
656 | break; | ||
657 | case 2: | ||
658 | printk("%lo", *argp); | ||
659 | break; | ||
660 | case 3: | ||
661 | printk("%lx", *argp); | ||
662 | break; | ||
663 | case 4: | ||
664 | printk("%p", (void *) *argp); | ||
665 | break; | ||
666 | case 5: | ||
667 | printk("\"%s\"", (char *) *argp); | ||
668 | break; | ||
669 | } | ||
670 | |||
671 | argp++; | ||
672 | argmask >>= 4; | ||
673 | if (argmask) | ||
674 | printk(","); | ||
675 | |||
676 | } while (argmask); | ||
677 | |||
678 | printk(")\n"); | ||
679 | } | ||
680 | } | ||
681 | else { | ||
682 | if ((int)__frame->gr8 > -4096 && (int)__frame->gr8 < 4096) | ||
683 | printk(KERN_CRIT "[%d] %s() = %ld\n", current->pid, name, __frame->gr8); | ||
684 | else | ||
685 | printk(KERN_CRIT "[%d] %s() = %lx\n", current->pid, name, __frame->gr8); | ||
686 | } | 388 | } |
687 | return; | ||
688 | #endif | ||
689 | |||
690 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | ||
691 | return; | ||
692 | |||
693 | if (!(current->ptrace & PT_PTRACED)) | ||
694 | return; | ||
695 | 389 | ||
696 | /* we need to indicate entry or exit to strace */ | 390 | return __frame->syscallno; |
697 | if (leaving) | 391 | } |
698 | __frame->__status |= REG__STATUS_SYSC_EXIT; | ||
699 | else | ||
700 | __frame->__status |= REG__STATUS_SYSC_ENTRY; | ||
701 | |||
702 | ptrace_notify(SIGTRAP); | ||
703 | 392 | ||
704 | /* | 393 | /* |
705 | * this isn't the same as continuing with a signal, but it will do | 394 | * handle tracing of system call exit |
706 | * for normal use. strace only continues with a signal if the | 395 | */ |
707 | * stopping signal is not SIGTRAP. -brl | 396 | asmlinkage void syscall_trace_exit(void) |
708 | */ | 397 | { |
709 | if (current->exit_code) { | 398 | __frame->__status |= REG__STATUS_SYSC_EXIT; |
710 | send_sig(current->exit_code, current, 1); | 399 | tracehook_report_syscall_exit(__frame, 0); |
711 | current->exit_code = 0; | ||
712 | } | ||
713 | } | 400 | } |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 3bdb368292a8..4a7a62c6e783 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -21,6 +21,7 @@ | |||
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/freezer.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> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
@@ -516,6 +517,9 @@ static void do_signal(void) | |||
516 | * clear the TIF_RESTORE_SIGMASK flag */ | 517 | * clear the TIF_RESTORE_SIGMASK flag */ |
517 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 518 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
518 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 519 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
520 | |||
521 | tracehook_signal_handler(signr, &info, &ka, __frame, | ||
522 | test_thread_flag(TIF_SINGLESTEP)); | ||
519 | } | 523 | } |
520 | 524 | ||
521 | return; | 525 | return; |
@@ -564,4 +568,10 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags) | |||
564 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 568 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
565 | do_signal(); | 569 | do_signal(); |
566 | 570 | ||
571 | /* deal with notification on about to resume userspace execution */ | ||
572 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
573 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
574 | tracehook_notify_resume(__frame); | ||
575 | } | ||
576 | |||
567 | } /* end do_notify_resume() */ | 577 | } /* end do_notify_resume() */ |
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c index 9fb771a20df3..374f88d6cc00 100644 --- a/arch/frv/kernel/uaccess.c +++ b/arch/frv/kernel/uaccess.c | |||
@@ -23,8 +23,7 @@ long strncpy_from_user(char *dst, const char __user *src, long count) | |||
23 | char *p, ch; | 23 | char *p, ch; |
24 | long err = -EFAULT; | 24 | long err = -EFAULT; |
25 | 25 | ||
26 | if (count < 0) | 26 | BUG_ON(count < 0); |
27 | BUG(); | ||
28 | 27 | ||
29 | p = dst; | 28 | p = dst; |
30 | 29 | ||
@@ -76,8 +75,7 @@ long strnlen_user(const char __user *src, long count) | |||
76 | long err = 0; | 75 | long err = 0; |
77 | char ch; | 76 | char ch; |
78 | 77 | ||
79 | if (count < 0) | 78 | BUG_ON(count < 0); |
80 | BUG(); | ||
81 | 79 | ||
82 | #ifndef CONFIG_MMU | 80 | #ifndef CONFIG_MMU |
83 | if ((unsigned long) src < memory_start) | 81 | if ((unsigned long) src < memory_start) |
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c index 52ff9aec799d..4e1ba0b15443 100644 --- a/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c | |||
@@ -116,8 +116,7 @@ EXPORT_SYMBOL(dma_free_coherent); | |||
116 | dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, | 116 | dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, |
117 | enum dma_data_direction direction) | 117 | enum dma_data_direction direction) |
118 | { | 118 | { |
119 | if (direction == DMA_NONE) | 119 | BUG_ON(direction == DMA_NONE); |
120 | BUG(); | ||
121 | 120 | ||
122 | frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size); | 121 | frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size); |
123 | 122 | ||
@@ -151,8 +150,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
151 | frv_cache_wback_inv(sg_dma_address(&sg[i]), | 150 | frv_cache_wback_inv(sg_dma_address(&sg[i]), |
152 | sg_dma_address(&sg[i]) + sg_dma_len(&sg[i])); | 151 | sg_dma_address(&sg[i]) + sg_dma_len(&sg[i])); |
153 | 152 | ||
154 | if (direction == DMA_NONE) | 153 | BUG_ON(direction == DMA_NONE); |
155 | BUG(); | ||
156 | 154 | ||
157 | return nents; | 155 | return nents; |
158 | } | 156 | } |
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c index 3ddedebc4eb3..45954f0813dc 100644 --- a/arch/frv/mb93090-mb00/pci-dma.c +++ b/arch/frv/mb93090-mb00/pci-dma.c | |||
@@ -48,8 +48,7 @@ EXPORT_SYMBOL(dma_free_coherent); | |||
48 | dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, | 48 | dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, |
49 | enum dma_data_direction direction) | 49 | enum dma_data_direction direction) |
50 | { | 50 | { |
51 | if (direction == DMA_NONE) | 51 | BUG_ON(direction == DMA_NONE); |
52 | BUG(); | ||
53 | 52 | ||
54 | frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size); | 53 | frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size); |
55 | 54 | ||
@@ -81,8 +80,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
81 | void *vaddr; | 80 | void *vaddr; |
82 | int i; | 81 | int i; |
83 | 82 | ||
84 | if (direction == DMA_NONE) | 83 | BUG_ON(direction == DMA_NONE); |
85 | BUG(); | ||
86 | 84 | ||
87 | dampr2 = __get_DAMPR(2); | 85 | dampr2 = __get_DAMPR(2); |
88 | 86 | ||