GNU Linux-libre 6.8.7-gnu
[releases.git] / arch / riscv / kernel / entry.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2012 Regents of the University of California
4  * Copyright (C) 2017 SiFive
5  */
6
7 #include <linux/init.h>
8 #include <linux/linkage.h>
9
10 #include <asm/asm.h>
11 #include <asm/csr.h>
12 #include <asm/scs.h>
13 #include <asm/unistd.h>
14 #include <asm/page.h>
15 #include <asm/thread_info.h>
16 #include <asm/asm-offsets.h>
17 #include <asm/errata_list.h>
18 #include <linux/sizes.h>
19
20         .section .irqentry.text, "ax"
21
22 SYM_CODE_START(handle_exception)
23         /*
24          * If coming from userspace, preserve the user thread pointer and load
25          * the kernel thread pointer.  If we came from the kernel, the scratch
26          * register will contain 0, and we should continue on the current TP.
27          */
28         csrrw tp, CSR_SCRATCH, tp
29         bnez tp, .Lsave_context
30
31 .Lrestore_kernel_tpsp:
32         csrr tp, CSR_SCRATCH
33         REG_S sp, TASK_TI_KERNEL_SP(tp)
34
35 #ifdef CONFIG_VMAP_STACK
36         addi sp, sp, -(PT_SIZE_ON_STACK)
37         srli sp, sp, THREAD_SHIFT
38         andi sp, sp, 0x1
39         bnez sp, handle_kernel_stack_overflow
40         REG_L sp, TASK_TI_KERNEL_SP(tp)
41 #endif
42
43 .Lsave_context:
44         REG_S sp, TASK_TI_USER_SP(tp)
45         REG_L sp, TASK_TI_KERNEL_SP(tp)
46         addi sp, sp, -(PT_SIZE_ON_STACK)
47         REG_S x1,  PT_RA(sp)
48         REG_S x3,  PT_GP(sp)
49         REG_S x5,  PT_T0(sp)
50         save_from_x6_to_x31
51
52         /*
53          * Disable user-mode memory access as it should only be set in the
54          * actual user copy routines.
55          *
56          * Disable the FPU/Vector to detect illegal usage of floating point
57          * or vector in kernel space.
58          */
59         li t0, SR_SUM | SR_FS_VS
60
61         REG_L s0, TASK_TI_USER_SP(tp)
62         csrrc s1, CSR_STATUS, t0
63         csrr s2, CSR_EPC
64         csrr s3, CSR_TVAL
65         csrr s4, CSR_CAUSE
66         csrr s5, CSR_SCRATCH
67         REG_S s0, PT_SP(sp)
68         REG_S s1, PT_STATUS(sp)
69         REG_S s2, PT_EPC(sp)
70         REG_S s3, PT_BADADDR(sp)
71         REG_S s4, PT_CAUSE(sp)
72         REG_S s5, PT_TP(sp)
73
74         /*
75          * Set the scratch register to 0, so that if a recursive exception
76          * occurs, the exception vector knows it came from the kernel
77          */
78         csrw CSR_SCRATCH, x0
79
80         /* Load the global pointer */
81         load_global_pointer
82
83         /* Load the kernel shadow call stack pointer if coming from userspace */
84         scs_load_current_if_task_changed s5
85
86 #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
87         move a0, sp
88         call riscv_v_context_nesting_start
89 #endif
90         move a0, sp /* pt_regs */
91         la ra, ret_from_exception
92
93         /*
94          * MSB of cause differentiates between
95          * interrupts and exceptions
96          */
97         bge s4, zero, 1f
98
99         /* Handle interrupts */
100         tail do_irq
101 1:
102         /* Handle other exceptions */
103         slli t0, s4, RISCV_LGPTR
104         la t1, excp_vect_table
105         la t2, excp_vect_table_end
106         add t0, t1, t0
107         /* Check if exception code lies within bounds */
108         bgeu t0, t2, 1f
109         REG_L t0, 0(t0)
110         jr t0
111 1:
112         tail do_trap_unknown
113 SYM_CODE_END(handle_exception)
114
115 /*
116  * The ret_from_exception must be called with interrupt disabled. Here is the
117  * caller list:
118  *  - handle_exception
119  *  - ret_from_fork
120  */
121 SYM_CODE_START_NOALIGN(ret_from_exception)
122         REG_L s0, PT_STATUS(sp)
123 #ifdef CONFIG_RISCV_M_MODE
124         /* the MPP value is too large to be used as an immediate arg for addi */
125         li t0, SR_MPP
126         and s0, s0, t0
127 #else
128         andi s0, s0, SR_SPP
129 #endif
130         bnez s0, 1f
131
132         /* Save unwound kernel stack pointer in thread_info */
133         addi s0, sp, PT_SIZE_ON_STACK
134         REG_S s0, TASK_TI_KERNEL_SP(tp)
135
136         /* Save the kernel shadow call stack pointer */
137         scs_save_current
138
139         /*
140          * Save TP into the scratch register , so we can find the kernel data
141          * structures again.
142          */
143         csrw CSR_SCRATCH, tp
144 1:
145 #ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
146         move a0, sp
147         call riscv_v_context_nesting_end
148 #endif
149         REG_L a0, PT_STATUS(sp)
150         /*
151          * The current load reservation is effectively part of the processor's
152          * state, in the sense that load reservations cannot be shared between
153          * different hart contexts.  We can't actually save and restore a load
154          * reservation, so instead here we clear any existing reservation --
155          * it's always legal for implementations to clear load reservations at
156          * any point (as long as the forward progress guarantee is kept, but
157          * we'll ignore that here).
158          *
159          * Dangling load reservations can be the result of taking a trap in the
160          * middle of an LR/SC sequence, but can also be the result of a taken
161          * forward branch around an SC -- which is how we implement CAS.  As a
162          * result we need to clear reservations between the last CAS and the
163          * jump back to the new context.  While it is unlikely the store
164          * completes, implementations are allowed to expand reservations to be
165          * arbitrarily large.
166          */
167         REG_L  a2, PT_EPC(sp)
168         REG_SC x0, a2, PT_EPC(sp)
169
170         csrw CSR_STATUS, a0
171         csrw CSR_EPC, a2
172
173         REG_L x1,  PT_RA(sp)
174         REG_L x3,  PT_GP(sp)
175         REG_L x4,  PT_TP(sp)
176         REG_L x5,  PT_T0(sp)
177         restore_from_x6_to_x31
178
179         REG_L x2,  PT_SP(sp)
180
181 #ifdef CONFIG_RISCV_M_MODE
182         mret
183 #else
184         sret
185 #endif
186 SYM_CODE_END(ret_from_exception)
187
188 #ifdef CONFIG_VMAP_STACK
189 SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
190         /* we reach here from kernel context, sscratch must be 0 */
191         csrrw x31, CSR_SCRATCH, x31
192         asm_per_cpu sp, overflow_stack, x31
193         li x31, OVERFLOW_STACK_SIZE
194         add sp, sp, x31
195         /* zero out x31 again and restore x31 */
196         xor x31, x31, x31
197         csrrw x31, CSR_SCRATCH, x31
198
199         addi sp, sp, -(PT_SIZE_ON_STACK)
200
201         //save context to overflow stack
202         REG_S x1,  PT_RA(sp)
203         REG_S x3,  PT_GP(sp)
204         REG_S x5,  PT_T0(sp)
205         save_from_x6_to_x31
206
207         REG_L s0, TASK_TI_KERNEL_SP(tp)
208         csrr s1, CSR_STATUS
209         csrr s2, CSR_EPC
210         csrr s3, CSR_TVAL
211         csrr s4, CSR_CAUSE
212         csrr s5, CSR_SCRATCH
213         REG_S s0, PT_SP(sp)
214         REG_S s1, PT_STATUS(sp)
215         REG_S s2, PT_EPC(sp)
216         REG_S s3, PT_BADADDR(sp)
217         REG_S s4, PT_CAUSE(sp)
218         REG_S s5, PT_TP(sp)
219         move a0, sp
220         tail handle_bad_stack
221 SYM_CODE_END(handle_kernel_stack_overflow)
222 #endif
223
224 SYM_CODE_START(ret_from_fork)
225         call schedule_tail
226         beqz s0, 1f     /* not from kernel thread */
227         /* Call fn(arg) */
228         move a0, s1
229         jalr s0
230 1:
231         move a0, sp /* pt_regs */
232         la ra, ret_from_exception
233         tail syscall_exit_to_user_mode
234 SYM_CODE_END(ret_from_fork)
235
236 #ifdef CONFIG_IRQ_STACKS
237 /*
238  * void call_on_irq_stack(struct pt_regs *regs,
239  *                        void (*func)(struct pt_regs *));
240  *
241  * Calls func(regs) using the per-CPU IRQ stack.
242  */
243 SYM_FUNC_START(call_on_irq_stack)
244         /* Create a frame record to save ra and s0 (fp) */
245         addi    sp, sp, -STACKFRAME_SIZE_ON_STACK
246         REG_S   ra, STACKFRAME_RA(sp)
247         REG_S   s0, STACKFRAME_FP(sp)
248         addi    s0, sp, STACKFRAME_SIZE_ON_STACK
249
250         /* Switch to the per-CPU shadow call stack */
251         scs_save_current
252         scs_load_irq_stack t0
253
254         /* Switch to the per-CPU IRQ stack and call the handler */
255         load_per_cpu t0, irq_stack_ptr, t1
256         li      t1, IRQ_STACK_SIZE
257         add     sp, t0, t1
258         jalr    a1
259
260         /* Switch back to the thread shadow call stack */
261         scs_load_current
262
263         /* Switch back to the thread stack and restore ra and s0 */
264         addi    sp, s0, -STACKFRAME_SIZE_ON_STACK
265         REG_L   ra, STACKFRAME_RA(sp)
266         REG_L   s0, STACKFRAME_FP(sp)
267         addi    sp, sp, STACKFRAME_SIZE_ON_STACK
268
269         ret
270 SYM_FUNC_END(call_on_irq_stack)
271 #endif /* CONFIG_IRQ_STACKS */
272
273 /*
274  * Integer register context switch
275  * The callee-saved registers must be saved and restored.
276  *
277  *   a0: previous task_struct (must be preserved across the switch)
278  *   a1: next task_struct
279  *
280  * The value of a0 and a1 must be preserved by this function, as that's how
281  * arguments are passed to schedule_tail.
282  */
283 SYM_FUNC_START(__switch_to)
284         /* Save context into prev->thread */
285         li    a4,  TASK_THREAD_RA
286         add   a3, a0, a4
287         add   a4, a1, a4
288         REG_S ra,  TASK_THREAD_RA_RA(a3)
289         REG_S sp,  TASK_THREAD_SP_RA(a3)
290         REG_S s0,  TASK_THREAD_S0_RA(a3)
291         REG_S s1,  TASK_THREAD_S1_RA(a3)
292         REG_S s2,  TASK_THREAD_S2_RA(a3)
293         REG_S s3,  TASK_THREAD_S3_RA(a3)
294         REG_S s4,  TASK_THREAD_S4_RA(a3)
295         REG_S s5,  TASK_THREAD_S5_RA(a3)
296         REG_S s6,  TASK_THREAD_S6_RA(a3)
297         REG_S s7,  TASK_THREAD_S7_RA(a3)
298         REG_S s8,  TASK_THREAD_S8_RA(a3)
299         REG_S s9,  TASK_THREAD_S9_RA(a3)
300         REG_S s10, TASK_THREAD_S10_RA(a3)
301         REG_S s11, TASK_THREAD_S11_RA(a3)
302         /* Save the kernel shadow call stack pointer */
303         scs_save_current
304         /* Restore context from next->thread */
305         REG_L ra,  TASK_THREAD_RA_RA(a4)
306         REG_L sp,  TASK_THREAD_SP_RA(a4)
307         REG_L s0,  TASK_THREAD_S0_RA(a4)
308         REG_L s1,  TASK_THREAD_S1_RA(a4)
309         REG_L s2,  TASK_THREAD_S2_RA(a4)
310         REG_L s3,  TASK_THREAD_S3_RA(a4)
311         REG_L s4,  TASK_THREAD_S4_RA(a4)
312         REG_L s5,  TASK_THREAD_S5_RA(a4)
313         REG_L s6,  TASK_THREAD_S6_RA(a4)
314         REG_L s7,  TASK_THREAD_S7_RA(a4)
315         REG_L s8,  TASK_THREAD_S8_RA(a4)
316         REG_L s9,  TASK_THREAD_S9_RA(a4)
317         REG_L s10, TASK_THREAD_S10_RA(a4)
318         REG_L s11, TASK_THREAD_S11_RA(a4)
319         /* The offset of thread_info in task_struct is zero. */
320         move tp, a1
321         /* Switch to the next shadow call stack */
322         scs_load_current
323         ret
324 SYM_FUNC_END(__switch_to)
325
326 #ifndef CONFIG_MMU
327 #define do_page_fault do_trap_unknown
328 #endif
329
330         .section ".rodata"
331         .align LGREG
332         /* Exception vector table */
333 SYM_DATA_START_LOCAL(excp_vect_table)
334         RISCV_PTR do_trap_insn_misaligned
335         ALT_INSN_FAULT(RISCV_PTR do_trap_insn_fault)
336         RISCV_PTR do_trap_insn_illegal
337         RISCV_PTR do_trap_break
338         RISCV_PTR do_trap_load_misaligned
339         RISCV_PTR do_trap_load_fault
340         RISCV_PTR do_trap_store_misaligned
341         RISCV_PTR do_trap_store_fault
342         RISCV_PTR do_trap_ecall_u /* system call */
343         RISCV_PTR do_trap_ecall_s
344         RISCV_PTR do_trap_unknown
345         RISCV_PTR do_trap_ecall_m
346         /* instruciton page fault */
347         ALT_PAGE_FAULT(RISCV_PTR do_page_fault)
348         RISCV_PTR do_page_fault   /* load page fault */
349         RISCV_PTR do_trap_unknown
350         RISCV_PTR do_page_fault   /* store page fault */
351 SYM_DATA_END_LABEL(excp_vect_table, SYM_L_LOCAL, excp_vect_table_end)
352
353 #ifndef CONFIG_MMU
354 SYM_DATA_START(__user_rt_sigreturn)
355         li a7, __NR_rt_sigreturn
356         ecall
357 SYM_DATA_END(__user_rt_sigreturn)
358 #endif