aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-08 15:29:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-08 15:29:46 -0400
commitd9dc089583ebf28d6f02b995e2d71c85965660f9 (patch)
tree8e2beb1719d8891d6eec2bbdc809fc0997ba29f6
parent70ef8f0d37573079e093305214d0cc9eb71100f7 (diff)
parent2a4e669dd611855d89d938063c10f44cb67ce65d (diff)
Merge tag 'xtensa-20170507' of git://github.com/jcmvbkbc/linux-xtensa
Pull Xtensa updates from Max Filippov: - clearly mark references to spilled register locations with SPILL_SLOT macros - clean up xtensa ptrace: use generic tracehooks, move internal kernel definitions from uapi/asm to asm, make locally-used functions static, fix code style and alignment - use command line parameters passed to ISS as kernel command line. * tag 'xtensa-20170507' of git://github.com/jcmvbkbc/linux-xtensa: xtensa: clean up access to spilled registers locations xtensa: use generic tracehooks xtensa: move internal ptrace definitions from uapi/asm to asm xtensa: clean up xtensa/kernel/ptrace.c xtensa: drop unused fast_io_protect function xtensa: use ITLB_HIT_BIT instead of hardcoded number xtensa: ISS: update kernel command line in platform_setup xtensa: ISS: add argc/argv simcall definitions xtensa: ISS: cleanup setup.c
-rw-r--r--arch/xtensa/include/asm/processor.h15
-rw-r--r--arch/xtensa/include/asm/ptrace.h39
-rw-r--r--arch/xtensa/include/uapi/asm/ptrace.h40
-rw-r--r--arch/xtensa/kernel/coprocessor.S24
-rw-r--r--arch/xtensa/kernel/entry.S3
-rw-r--r--arch/xtensa/kernel/process.c8
-rw-r--r--arch/xtensa/kernel/ptrace.c170
-rw-r--r--arch/xtensa/kernel/setup.c9
-rw-r--r--arch/xtensa/kernel/signal.c10
-rw-r--r--arch/xtensa/kernel/stacktrace.c35
-rw-r--r--arch/xtensa/platforms/iss/include/platform/simcall.h20
-rw-r--r--arch/xtensa/platforms/iss/setup.c43
12 files changed, 197 insertions, 219 deletions
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 86ffcd68e496..003eeee3fbc6 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -113,6 +113,21 @@
113 */ 113 */
114#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) 114#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
115 115
116/* Spill slot location for the register reg in the spill area under the stack
117 * pointer sp. reg must be in the range [0..4).
118 */
119#define SPILL_SLOT(sp, reg) (*(((unsigned long *)(sp)) - 4 + (reg)))
120
121/* Spill slot location for the register reg in the spill area under the stack
122 * pointer sp for the call8. reg must be in the range [4..8).
123 */
124#define SPILL_SLOT_CALL8(sp, reg) (*(((unsigned long *)(sp)) - 12 + (reg)))
125
126/* Spill slot location for the register reg in the spill area under the stack
127 * pointer sp for the call12. reg must be in the range [4..12).
128 */
129#define SPILL_SLOT_CALL12(sp, reg) (*(((unsigned long *)(sp)) - 16 + (reg)))
130
116typedef struct { 131typedef struct {
117 unsigned long seg; 132 unsigned long seg;
118} mm_segment_t; 133} mm_segment_t;
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h
index 598e752dcbcd..e2d9c5eb10bd 100644
--- a/arch/xtensa/include/asm/ptrace.h
+++ b/arch/xtensa/include/asm/ptrace.h
@@ -12,6 +12,45 @@
12 12
13#include <uapi/asm/ptrace.h> 13#include <uapi/asm/ptrace.h>
14 14
15/*
16 * Kernel stack
17 *
18 * +-----------------------+ -------- STACK_SIZE
19 * | register file | |
20 * +-----------------------+ |
21 * | struct pt_regs | |
22 * +-----------------------+ | ------ PT_REGS_OFFSET
23 * double : 16 bytes spill area : | ^
24 * excetion :- - - - - - - - - - - -: | |
25 * frame : struct pt_regs : | |
26 * :- - - - - - - - - - - -: | |
27 * | | | |
28 * | memory stack | | |
29 * | | | |
30 * ~ ~ ~ ~
31 * ~ ~ ~ ~
32 * | | | |
33 * | | | |
34 * +-----------------------+ | | --- STACK_BIAS
35 * | struct task_struct | | | ^
36 * current --> +-----------------------+ | | |
37 * | struct thread_info | | | |
38 * +-----------------------+ --------
39 */
40
41#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)
42
43/* Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */
44
45#define EXC_TABLE_KSTK 0x004 /* Kernel Stack */
46#define EXC_TABLE_DOUBLE_SAVE 0x008 /* Double exception save area for a0 */
47#define EXC_TABLE_FIXUP 0x00c /* Fixup handler */
48#define EXC_TABLE_PARAM 0x010 /* For passing a parameter to fixup */
49#define EXC_TABLE_SYSCALL_SAVE 0x014 /* For fast syscall handler */
50#define EXC_TABLE_FAST_USER 0x100 /* Fast user exception handler */
51#define EXC_TABLE_FAST_KERNEL 0x200 /* Fast kernel exception handler */
52#define EXC_TABLE_DEFAULT 0x300 /* Default C-Handler */
53#define EXC_TABLE_SIZE 0x400
15 54
16#ifndef __ASSEMBLY__ 55#ifndef __ASSEMBLY__
17 56
diff --git a/arch/xtensa/include/uapi/asm/ptrace.h b/arch/xtensa/include/uapi/asm/ptrace.h
index 6ccbd9e38e35..8853a0d544c8 100644
--- a/arch/xtensa/include/uapi/asm/ptrace.h
+++ b/arch/xtensa/include/uapi/asm/ptrace.h
@@ -11,46 +11,6 @@
11#ifndef _UAPI_XTENSA_PTRACE_H 11#ifndef _UAPI_XTENSA_PTRACE_H
12#define _UAPI_XTENSA_PTRACE_H 12#define _UAPI_XTENSA_PTRACE_H
13 13
14/*
15 * Kernel stack
16 *
17 * +-----------------------+ -------- STACK_SIZE
18 * | register file | |
19 * +-----------------------+ |
20 * | struct pt_regs | |
21 * +-----------------------+ | ------ PT_REGS_OFFSET
22 * double : 16 bytes spill area : | ^
23 * excetion :- - - - - - - - - - - -: | |
24 * frame : struct pt_regs : | |
25 * :- - - - - - - - - - - -: | |
26 * | | | |
27 * | memory stack | | |
28 * | | | |
29 * ~ ~ ~ ~
30 * ~ ~ ~ ~
31 * | | | |
32 * | | | |
33 * +-----------------------+ | | --- STACK_BIAS
34 * | struct task_struct | | | ^
35 * current --> +-----------------------+ | | |
36 * | struct thread_info | | | |
37 * +-----------------------+ --------
38 */
39
40#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)
41
42/* Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */
43
44#define EXC_TABLE_KSTK 0x004 /* Kernel Stack */
45#define EXC_TABLE_DOUBLE_SAVE 0x008 /* Double exception save area for a0 */
46#define EXC_TABLE_FIXUP 0x00c /* Fixup handler */
47#define EXC_TABLE_PARAM 0x010 /* For passing a parameter to fixup */
48#define EXC_TABLE_SYSCALL_SAVE 0x014 /* For fast syscall handler */
49#define EXC_TABLE_FAST_USER 0x100 /* Fast user exception handler */
50#define EXC_TABLE_FAST_KERNEL 0x200 /* Fast kernel exception handler */
51#define EXC_TABLE_DEFAULT 0x300 /* Default C-Handler */
52#define EXC_TABLE_SIZE 0x400
53
54/* Registers used by strace */ 14/* Registers used by strace */
55 15
56#define REG_A_BASE 0x0000 16#define REG_A_BASE 0x0000
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
index 6911e384f608..3a98503ad11a 100644
--- a/arch/xtensa/kernel/coprocessor.S
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -26,30 +26,6 @@
26#include <asm/signal.h> 26#include <asm/signal.h>
27#include <asm/tlbflush.h> 27#include <asm/tlbflush.h>
28 28
29/*
30 * Entry condition:
31 *
32 * a0: trashed, original value saved on stack (PT_AREG0)
33 * a1: a1
34 * a2: new stack pointer, original in DEPC
35 * a3: a3
36 * depc: a2, original value saved on stack (PT_DEPC)
37 * excsave_1: dispatch table
38 *
39 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
40 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
41 */
42
43/* IO protection is currently unsupported. */
44
45ENTRY(fast_io_protect)
46
47 wsr a0, excsave1
48 movi a0, unrecoverable_exception
49 callx0 a0
50
51ENDPROC(fast_io_protect)
52
53#if XTENSA_HAVE_COPROCESSORS 29#if XTENSA_HAVE_COPROCESSORS
54 30
55/* 31/*
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index f5ef3cc0497c..37a239556889 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1899,10 +1899,11 @@ ENTRY(system_call)
1899 movi a4, do_syscall_trace_enter 1899 movi a4, do_syscall_trace_enter
1900 s32i a3, a2, PT_SYSCALL 1900 s32i a3, a2, PT_SYSCALL
1901 callx4 a4 1901 callx4 a4
1902 mov a3, a6
1902 1903
1903 /* syscall = sys_call_table[syscall_nr] */ 1904 /* syscall = sys_call_table[syscall_nr] */
1904 1905
1905 movi a4, sys_call_table; 1906 movi a4, sys_call_table
1906 movi a5, __NR_syscall_count 1907 movi a5, __NR_syscall_count
1907 movi a6, -ENOSYS 1908 movi a6, -ENOSYS
1908 bgeu a3, a5, 1f 1909 bgeu a3, a5, 1f
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 58f96d1230d4..ff4f0ecb03dd 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -204,8 +204,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
204#endif 204#endif
205 205
206 /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ 206 /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */
207 *((int*)childregs - 3) = (unsigned long)childregs; 207 SPILL_SLOT(childregs, 1) = (unsigned long)childregs;
208 *((int*)childregs - 4) = 0; 208 SPILL_SLOT(childregs, 0) = 0;
209 209
210 p->thread.sp = (unsigned long)childregs; 210 p->thread.sp = (unsigned long)childregs;
211 211
@@ -266,8 +266,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
266 /* pass parameters to ret_from_kernel_thread: 266 /* pass parameters to ret_from_kernel_thread:
267 * a2 = thread_fn, a3 = thread_fn arg 267 * a2 = thread_fn, a3 = thread_fn arg
268 */ 268 */
269 *((int *)childregs - 1) = thread_fn_arg; 269 SPILL_SLOT(childregs, 3) = thread_fn_arg;
270 *((int *)childregs - 2) = usp_thread_fn; 270 SPILL_SLOT(childregs, 2) = usp_thread_fn;
271 271
272 /* Childregs are only used when we're going to userspace 272 /* Childregs are only used when we're going to userspace
273 * in which case start_thread will set them up. 273 * in which case start_thread will set them up.
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index e0f583fed06a..e2461968efb2 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -1,4 +1,3 @@
1// TODO some minor issues
2/* 1/*
3 * This file is subject to the terms and conditions of the GNU General Public 2 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
@@ -24,13 +23,14 @@
24#include <linux/security.h> 23#include <linux/security.h>
25#include <linux/signal.h> 24#include <linux/signal.h>
26#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/tracehook.h>
27#include <linux/uaccess.h>
27 28
28#include <asm/coprocessor.h> 29#include <asm/coprocessor.h>
29#include <asm/elf.h> 30#include <asm/elf.h>
30#include <asm/page.h> 31#include <asm/page.h>
31#include <asm/pgtable.h> 32#include <asm/pgtable.h>
32#include <asm/ptrace.h> 33#include <asm/ptrace.h>
33#include <linux/uaccess.h>
34 34
35 35
36void user_enable_single_step(struct task_struct *child) 36void user_enable_single_step(struct task_struct *child)
@@ -52,7 +52,7 @@ void ptrace_disable(struct task_struct *child)
52 /* Nothing to do.. */ 52 /* Nothing to do.. */
53} 53}
54 54
55int ptrace_getregs(struct task_struct *child, void __user *uregs) 55static int ptrace_getregs(struct task_struct *child, void __user *uregs)
56{ 56{
57 struct pt_regs *regs = task_pt_regs(child); 57 struct pt_regs *regs = task_pt_regs(child);
58 xtensa_gregset_t __user *gregset = uregs; 58 xtensa_gregset_t __user *gregset = uregs;
@@ -73,12 +73,12 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs)
73 73
74 for (i = 0; i < XCHAL_NUM_AREGS; i++) 74 for (i = 0; i < XCHAL_NUM_AREGS; i++)
75 __put_user(regs->areg[i], 75 __put_user(regs->areg[i],
76 gregset->a + ((wb * 4 + i) % XCHAL_NUM_AREGS)); 76 gregset->a + ((wb * 4 + i) % XCHAL_NUM_AREGS));
77 77
78 return 0; 78 return 0;
79} 79}
80 80
81int ptrace_setregs(struct task_struct *child, void __user *uregs) 81static int ptrace_setregs(struct task_struct *child, void __user *uregs)
82{ 82{
83 struct pt_regs *regs = task_pt_regs(child); 83 struct pt_regs *regs = task_pt_regs(child);
84 xtensa_gregset_t *gregset = uregs; 84 xtensa_gregset_t *gregset = uregs;
@@ -107,7 +107,7 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs)
107 unsigned long rotws, wmask; 107 unsigned long rotws, wmask;
108 108
109 rotws = (((ws | (ws << WSBITS)) >> wb) & 109 rotws = (((ws | (ws << WSBITS)) >> wb) &
110 ((1 << WSBITS) - 1)) & ~1; 110 ((1 << WSBITS) - 1)) & ~1;
111 wmask = ((rotws ? WSBITS + 1 - ffs(rotws) : 0) << 4) | 111 wmask = ((rotws ? WSBITS + 1 - ffs(rotws) : 0) << 4) |
112 (rotws & 0xF) | 1; 112 (rotws & 0xF) | 1;
113 regs->windowbase = wb; 113 regs->windowbase = wb;
@@ -115,19 +115,19 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs)
115 regs->wmask = wmask; 115 regs->wmask = wmask;
116 } 116 }
117 117
118 if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, 118 if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4,
119 gregset->a, wb * 16)) 119 gregset->a, wb * 16))
120 return -EFAULT; 120 return -EFAULT;
121 121
122 if (__copy_from_user(regs->areg, gregset->a + wb * 4, 122 if (__copy_from_user(regs->areg, gregset->a + wb * 4,
123 (WSBITS - wb) * 16)) 123 (WSBITS - wb) * 16))
124 return -EFAULT; 124 return -EFAULT;
125 125
126 return 0; 126 return 0;
127} 127}
128 128
129 129
130int ptrace_getxregs(struct task_struct *child, void __user *uregs) 130static int ptrace_getxregs(struct task_struct *child, void __user *uregs)
131{ 131{
132 struct pt_regs *regs = task_pt_regs(child); 132 struct pt_regs *regs = task_pt_regs(child);
133 struct thread_info *ti = task_thread_info(child); 133 struct thread_info *ti = task_thread_info(child);
@@ -151,7 +151,7 @@ int ptrace_getxregs(struct task_struct *child, void __user *uregs)
151 return ret ? -EFAULT : 0; 151 return ret ? -EFAULT : 0;
152} 152}
153 153
154int ptrace_setxregs(struct task_struct *child, void __user *uregs) 154static int ptrace_setxregs(struct task_struct *child, void __user *uregs)
155{ 155{
156 struct thread_info *ti = task_thread_info(child); 156 struct thread_info *ti = task_thread_info(child);
157 struct pt_regs *regs = task_pt_regs(child); 157 struct pt_regs *regs = task_pt_regs(child);
@@ -177,7 +177,8 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs)
177 return ret ? -EFAULT : 0; 177 return ret ? -EFAULT : 0;
178} 178}
179 179
180int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret) 180static int ptrace_peekusr(struct task_struct *child, long regno,
181 long __user *ret)
181{ 182{
182 struct pt_regs *regs; 183 struct pt_regs *regs;
183 unsigned long tmp; 184 unsigned long tmp;
@@ -186,86 +187,87 @@ int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret)
186 tmp = 0; /* Default return value. */ 187 tmp = 0; /* Default return value. */
187 188
188 switch(regno) { 189 switch(regno) {
190 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
191 tmp = regs->areg[regno - REG_AR_BASE];
192 break;
189 193
190 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 194 case REG_A_BASE ... REG_A_BASE + 15:
191 tmp = regs->areg[regno - REG_AR_BASE]; 195 tmp = regs->areg[regno - REG_A_BASE];
192 break; 196 break;
193
194 case REG_A_BASE ... REG_A_BASE + 15:
195 tmp = regs->areg[regno - REG_A_BASE];
196 break;
197 197
198 case REG_PC: 198 case REG_PC:
199 tmp = regs->pc; 199 tmp = regs->pc;
200 break; 200 break;
201 201
202 case REG_PS: 202 case REG_PS:
203 /* Note: PS.EXCM is not set while user task is running; 203 /* Note: PS.EXCM is not set while user task is running;
204 * its being set in regs is for exception handling 204 * its being set in regs is for exception handling
205 * convenience. */ 205 * convenience.
206 tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); 206 */
207 break; 207 tmp = (regs->ps & ~(1 << PS_EXCM_BIT));
208 break;
208 209
209 case REG_WB: 210 case REG_WB:
210 break; /* tmp = 0 */ 211 break; /* tmp = 0 */
211 212
212 case REG_WS: 213 case REG_WS:
213 { 214 {
214 unsigned long wb = regs->windowbase; 215 unsigned long wb = regs->windowbase;
215 unsigned long ws = regs->windowstart; 216 unsigned long ws = regs->windowstart;
216 tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1); 217 tmp = ((ws >> wb) | (ws << (WSBITS - wb))) &
218 ((1 << WSBITS) - 1);
217 break; 219 break;
218 } 220 }
219 case REG_LBEG: 221 case REG_LBEG:
220 tmp = regs->lbeg; 222 tmp = regs->lbeg;
221 break; 223 break;
222 224
223 case REG_LEND: 225 case REG_LEND:
224 tmp = regs->lend; 226 tmp = regs->lend;
225 break; 227 break;
226 228
227 case REG_LCOUNT: 229 case REG_LCOUNT:
228 tmp = regs->lcount; 230 tmp = regs->lcount;
229 break; 231 break;
230 232
231 case REG_SAR: 233 case REG_SAR:
232 tmp = regs->sar; 234 tmp = regs->sar;
233 break; 235 break;
234 236
235 case SYSCALL_NR: 237 case SYSCALL_NR:
236 tmp = regs->syscall; 238 tmp = regs->syscall;
237 break; 239 break;
238 240
239 default: 241 default:
240 return -EIO; 242 return -EIO;
241 } 243 }
242 return put_user(tmp, ret); 244 return put_user(tmp, ret);
243} 245}
244 246
245int ptrace_pokeusr(struct task_struct *child, long regno, long val) 247static int ptrace_pokeusr(struct task_struct *child, long regno, long val)
246{ 248{
247 struct pt_regs *regs; 249 struct pt_regs *regs;
248 regs = task_pt_regs(child); 250 regs = task_pt_regs(child);
249 251
250 switch (regno) { 252 switch (regno) {
251 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 253 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
252 regs->areg[regno - REG_AR_BASE] = val; 254 regs->areg[regno - REG_AR_BASE] = val;
253 break; 255 break;
254 256
255 case REG_A_BASE ... REG_A_BASE + 15: 257 case REG_A_BASE ... REG_A_BASE + 15:
256 regs->areg[regno - REG_A_BASE] = val; 258 regs->areg[regno - REG_A_BASE] = val;
257 break; 259 break;
258 260
259 case REG_PC: 261 case REG_PC:
260 regs->pc = val; 262 regs->pc = val;
261 break; 263 break;
262 264
263 case SYSCALL_NR: 265 case SYSCALL_NR:
264 regs->syscall = val; 266 regs->syscall = val;
265 break; 267 break;
266 268
267 default: 269 default:
268 return -EIO; 270 return -EIO;
269 } 271 }
270 return 0; 272 return 0;
271} 273}
@@ -467,39 +469,21 @@ long arch_ptrace(struct task_struct *child, long request,
467 return ret; 469 return ret;
468} 470}
469 471
470void do_syscall_trace(void) 472unsigned long do_syscall_trace_enter(struct pt_regs *regs)
471{
472 /*
473 * The 0x80 provides a way for the tracing parent to distinguish
474 * between a syscall stop and SIGTRAP delivery
475 */
476 ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
477
478 /*
479 * this isn't the same as continuing with a signal, but it will do
480 * for normal use. strace only continues with a signal if the
481 * stopping signal is not SIGTRAP. -brl
482 */
483 if (current->exit_code) {
484 send_sig(current->exit_code, current, 1);
485 current->exit_code = 0;
486 }
487}
488
489void do_syscall_trace_enter(struct pt_regs *regs)
490{ 473{
491 if (test_thread_flag(TIF_SYSCALL_TRACE) 474 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
492 && (current->ptrace & PT_PTRACED)) 475 tracehook_report_syscall_entry(regs))
493 do_syscall_trace(); 476 return -1;
494 477
495#if 0 478 return regs->areg[2];
496 audit_syscall_entry(...);
497#endif
498} 479}
499 480
500void do_syscall_trace_leave(struct pt_regs *regs) 481void do_syscall_trace_leave(struct pt_regs *regs)
501{ 482{
502 if ((test_thread_flag(TIF_SYSCALL_TRACE)) 483 int step;
503 && (current->ptrace & PT_PTRACED)) 484
504 do_syscall_trace(); 485 step = test_thread_flag(TIF_SINGLESTEP);
486
487 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
488 tracehook_report_syscall_exit(regs, step);
505} 489}
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 197e75b400b1..394ef08300b6 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -317,8 +317,9 @@ static inline int mem_reserve(unsigned long start, unsigned long end)
317 317
318void __init setup_arch(char **cmdline_p) 318void __init setup_arch(char **cmdline_p)
319{ 319{
320 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
321 *cmdline_p = command_line; 320 *cmdline_p = command_line;
321 platform_setup(cmdline_p);
322 strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
322 323
323 /* Reserve some memory regions */ 324 /* Reserve some memory regions */
324 325
@@ -382,8 +383,6 @@ void __init setup_arch(char **cmdline_p)
382 383
383 unflatten_and_copy_device_tree(); 384 unflatten_and_copy_device_tree();
384 385
385 platform_setup(cmdline_p);
386
387#ifdef CONFIG_SMP 386#ifdef CONFIG_SMP
388 smp_init_cpus(); 387 smp_init_cpus();
389#endif 388#endif
@@ -453,9 +452,9 @@ void cpu_reset(void)
453 tmpaddr += SZ_512M; 452 tmpaddr += SZ_512M;
454 453
455 /* Invalidate mapping in the selected temporary area */ 454 /* Invalidate mapping in the selected temporary area */
456 if (itlb_probe(tmpaddr) & 0x8) 455 if (itlb_probe(tmpaddr) & BIT(ITLB_HIT_BIT))
457 invalidate_itlb_entry(itlb_probe(tmpaddr)); 456 invalidate_itlb_entry(itlb_probe(tmpaddr));
458 if (itlb_probe(tmpaddr + PAGE_SIZE) & 0x8) 457 if (itlb_probe(tmpaddr + PAGE_SIZE) & BIT(ITLB_HIT_BIT))
459 invalidate_itlb_entry(itlb_probe(tmpaddr + PAGE_SIZE)); 458 invalidate_itlb_entry(itlb_probe(tmpaddr + PAGE_SIZE));
460 459
461 /* 460 /*
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index 70a131945443..d427e784ab44 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -91,14 +91,14 @@ flush_window_regs_user(struct pt_regs *regs)
91 inc = 1; 91 inc = 1;
92 92
93 } else if (m & 4) { /* call8 */ 93 } else if (m & 4) { /* call8 */
94 if (copy_to_user((void*)(sp - 32), 94 if (copy_to_user(&SPILL_SLOT_CALL8(sp, 4),
95 &regs->areg[(base + 1) * 4], 16)) 95 &regs->areg[(base + 1) * 4], 16))
96 goto errout; 96 goto errout;
97 inc = 2; 97 inc = 2;
98 98
99 } else if (m & 8) { /* call12 */ 99 } else if (m & 8) { /* call12 */
100 if (copy_to_user((void*)(sp - 48), 100 if (copy_to_user(&SPILL_SLOT_CALL12(sp, 4),
101 &regs->areg[(base + 1) * 4], 32)) 101 &regs->areg[(base + 1) * 4], 32))
102 goto errout; 102 goto errout;
103 inc = 3; 103 inc = 3;
104 } 104 }
@@ -106,7 +106,7 @@ flush_window_regs_user(struct pt_regs *regs)
106 /* Save current frame a0..a3 under next SP */ 106 /* Save current frame a0..a3 under next SP */
107 107
108 sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS]; 108 sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS];
109 if (copy_to_user((void*)(sp - 16), &regs->areg[base * 4], 16)) 109 if (copy_to_user(&SPILL_SLOT(sp, 0), &regs->areg[base * 4], 16))
110 goto errout; 110 goto errout;
111 111
112 /* Get current stack pointer for next loop iteration. */ 112 /* Get current stack pointer for next loop iteration. */
diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c
index e7d30ee0fd48..0df4080fa20f 100644
--- a/arch/xtensa/kernel/stacktrace.c
+++ b/arch/xtensa/kernel/stacktrace.c
@@ -23,14 +23,6 @@
23 */ 23 */
24extern int common_exception_return; 24extern int common_exception_return;
25 25
26/* A struct that maps to the part of the frame containing the a0 and
27 * a1 registers.
28 */
29struct frame_start {
30 unsigned long a0;
31 unsigned long a1;
32};
33
34void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth, 26void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth,
35 int (*ufn)(struct stackframe *frame, void *data), 27 int (*ufn)(struct stackframe *frame, void *data),
36 void *data) 28 void *data)
@@ -96,26 +88,16 @@ void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth,
96 /* Start from the a1 register. */ 88 /* Start from the a1 register. */
97 /* a1 = regs->areg[1]; */ 89 /* a1 = regs->areg[1]; */
98 while (a0 != 0 && depth--) { 90 while (a0 != 0 && depth--) {
99 struct frame_start frame_start; 91 pc = MAKE_PC_FROM_RA(a0, pc);
100 /* Get the location for a1, a0 for the
101 * previous frame from the current a1.
102 */
103 unsigned long *psp = (unsigned long *)a1;
104
105 psp -= 4;
106 92
107 /* Check if the region is OK to access. */ 93 /* Check if the region is OK to access. */
108 if (!access_ok(VERIFY_READ, psp, sizeof(frame_start))) 94 if (!access_ok(VERIFY_READ, &SPILL_SLOT(a1, 0), 8))
109 return; 95 return;
110 /* Copy a1, a0 from user space stack frame. */ 96 /* Copy a1, a0 from user space stack frame. */
111 if (__copy_from_user_inatomic(&frame_start, psp, 97 if (__get_user(a0, &SPILL_SLOT(a1, 0)) ||
112 sizeof(frame_start))) 98 __get_user(a1, &SPILL_SLOT(a1, 1)))
113 return; 99 return;
114 100
115 pc = MAKE_PC_FROM_RA(a0, pc);
116 a0 = frame_start.a0;
117 a1 = frame_start.a1;
118
119 frame.pc = pc; 101 frame.pc = pc;
120 frame.sp = a1; 102 frame.sp = a1;
121 103
@@ -147,7 +129,6 @@ void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth,
147 */ 129 */
148 while (a1 > sp_start && a1 < sp_end && depth--) { 130 while (a1 > sp_start && a1 < sp_end && depth--) {
149 struct stackframe frame; 131 struct stackframe frame;
150 unsigned long *psp = (unsigned long *)a1;
151 132
152 frame.pc = pc; 133 frame.pc = pc;
153 frame.sp = a1; 134 frame.sp = a1;
@@ -171,8 +152,8 @@ void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth,
171 sp_start = a1; 152 sp_start = a1;
172 153
173 pc = MAKE_PC_FROM_RA(a0, pc); 154 pc = MAKE_PC_FROM_RA(a0, pc);
174 a0 = *(psp - 4); 155 a0 = SPILL_SLOT(a1, 0);
175 a1 = *(psp - 3); 156 a1 = SPILL_SLOT(a1, 1);
176 } 157 }
177} 158}
178EXPORT_SYMBOL(xtensa_backtrace_kernel); 159EXPORT_SYMBOL(xtensa_backtrace_kernel);
@@ -196,8 +177,8 @@ void walk_stackframe(unsigned long *sp,
196 177
197 sp = (unsigned long *)a1; 178 sp = (unsigned long *)a1;
198 179
199 a0 = *(sp - 4); 180 a0 = SPILL_SLOT(a1, 0);
200 a1 = *(sp - 3); 181 a1 = SPILL_SLOT(a1, 1);
201 182
202 if (a1 <= (unsigned long)sp) 183 if (a1 <= (unsigned long)sp)
203 break; 184 break;
diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h
index 27d7a528b41a..2ba45858e50a 100644
--- a/arch/xtensa/platforms/iss/include/platform/simcall.h
+++ b/arch/xtensa/platforms/iss/include/platform/simcall.h
@@ -6,6 +6,7 @@
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2001 Tensilica Inc. 8 * Copyright (C) 2001 Tensilica Inc.
9 * Copyright (C) 2017 Cadence Design Systems Inc.
9 */ 10 */
10 11
11#ifndef _XTENSA_PLATFORM_ISS_SIMCALL_H 12#ifndef _XTENSA_PLATFORM_ISS_SIMCALL_H
@@ -49,6 +50,10 @@
49#define SYS_bind 30 50#define SYS_bind 30
50#define SYS_ioctl 31 51#define SYS_ioctl 31
51 52
53#define SYS_iss_argc 1000 /* returns value of argc */
54#define SYS_iss_argv_size 1001 /* bytes needed for argv & arg strings */
55#define SYS_iss_set_argv 1002 /* saves argv & arg strings at given addr */
56
52/* 57/*
53 * SYS_select_one specifiers 58 * SYS_select_one specifiers
54 */ 59 */
@@ -118,5 +123,20 @@ static inline int simc_lseek(int fd, uint32_t off, int whence)
118 return __simc(SYS_lseek, fd, off, whence); 123 return __simc(SYS_lseek, fd, off, whence);
119} 124}
120 125
126static inline int simc_argc(void)
127{
128 return __simc(SYS_iss_argc, 0, 0, 0);
129}
130
131static inline int simc_argv_size(void)
132{
133 return __simc(SYS_iss_argv_size, 0, 0, 0);
134}
135
136static inline void simc_argv(void *buf)
137{
138 __simc(SYS_iss_set_argv, (int)buf, 0, 0);
139}
140
121#endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */ 141#endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */
122 142
diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index 379aeddcc638..f4bbb28026f8 100644
--- a/arch/xtensa/platforms/iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
@@ -8,6 +8,7 @@
8 * Joe Taylor <joe@tensilica.com> 8 * Joe Taylor <joe@tensilica.com>
9 * 9 *
10 * Copyright 2001 - 2005 Tensilica Inc. 10 * Copyright 2001 - 2005 Tensilica Inc.
11 * Copyright 2017 Cadence Design Systems Inc.
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the 14 * under the terms of the GNU General Public License as published by the
@@ -15,6 +16,7 @@
15 * option) any later version. 16 * option) any later version.
16 * 17 *
17 */ 18 */
19#include <linux/bootmem.h>
18#include <linux/stddef.h> 20#include <linux/stddef.h>
19#include <linux/kernel.h> 21#include <linux/kernel.h>
20#include <linux/init.h> 22#include <linux/init.h>
@@ -31,13 +33,13 @@
31 33
32#include <asm/platform.h> 34#include <asm/platform.h>
33#include <asm/bootparam.h> 35#include <asm/bootparam.h>
36#include <asm/setup.h>
34 37
35#include <platform/simcall.h> 38#include <platform/simcall.h>
36 39
37 40
38void __init platform_init(bp_tag_t* bootparam) 41void __init platform_init(bp_tag_t* bootparam)
39{ 42{
40
41} 43}
42 44
43void platform_halt(void) 45void platform_halt(void)
@@ -59,26 +61,10 @@ void platform_restart(void)
59 /* control never gets here */ 61 /* control never gets here */
60} 62}
61 63
62extern void iss_net_poll(void);
63
64const char twirl[]="|/-\\|/-\\";
65
66void platform_heartbeat(void) 64void platform_heartbeat(void)
67{ 65{
68#if 0
69 static int i = 0, j = 0;
70
71 if (--i < 0) {
72 i = 99;
73 printk("\r%c\r", twirl[j++]);
74 if (j == 8)
75 j = 0;
76 }
77#endif
78} 66}
79 67
80
81
82static int 68static int
83iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr) 69iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
84{ 70{
@@ -87,12 +73,29 @@ iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
87} 73}
88 74
89static struct notifier_block iss_panic_block = { 75static struct notifier_block iss_panic_block = {
90 iss_panic_event, 76 .notifier_call = iss_panic_event,
91 NULL,
92 0
93}; 77};
94 78
95void __init platform_setup(char **p_cmdline) 79void __init platform_setup(char **p_cmdline)
96{ 80{
81 int argc = simc_argc();
82 int argv_size = simc_argv_size();
83
84 if (argc > 1) {
85 void **argv = alloc_bootmem(argv_size);
86 char *cmdline = alloc_bootmem(argv_size);
87 int i;
88
89 cmdline[0] = 0;
90 simc_argv((void *)argv);
91
92 for (i = 1; i < argc; ++i) {
93 if (i > 1)
94 strcat(cmdline, " ");
95 strcat(cmdline, argv[i]);
96 }
97 *p_cmdline = cmdline;
98 }
99
97 atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block); 100 atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
98} 101}