Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/riscv/kernel/entry.S
29266 views
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/alternative-macros.h>
11
#include <asm/asm.h>
12
#include <asm/csr.h>
13
#include <asm/scs.h>
14
#include <asm/unistd.h>
15
#include <asm/page.h>
16
#include <asm/thread_info.h>
17
#include <asm/asm-offsets.h>
18
#include <asm/errata_list.h>
19
#include <linux/sizes.h>
20
21
.section .irqentry.text, "ax"
22
23
.macro new_vmalloc_check
24
REG_S a0, TASK_TI_A0(tp)
25
csrr a0, CSR_CAUSE
26
/* Exclude IRQs */
27
blt a0, zero, .Lnew_vmalloc_restore_context_a0
28
29
REG_S a1, TASK_TI_A1(tp)
30
/* Only check new_vmalloc if we are in page/protection fault */
31
li a1, EXC_LOAD_PAGE_FAULT
32
beq a0, a1, .Lnew_vmalloc_kernel_address
33
li a1, EXC_STORE_PAGE_FAULT
34
beq a0, a1, .Lnew_vmalloc_kernel_address
35
li a1, EXC_INST_PAGE_FAULT
36
bne a0, a1, .Lnew_vmalloc_restore_context_a1
37
38
.Lnew_vmalloc_kernel_address:
39
/* Is it a kernel address? */
40
csrr a0, CSR_TVAL
41
bge a0, zero, .Lnew_vmalloc_restore_context_a1
42
43
/* Check if a new vmalloc mapping appeared that could explain the trap */
44
REG_S a2, TASK_TI_A2(tp)
45
/*
46
* Computes:
47
* a0 = &new_vmalloc[BIT_WORD(cpu)]
48
* a1 = BIT_MASK(cpu)
49
*/
50
lw a2, TASK_TI_CPU(tp)
51
/*
52
* Compute the new_vmalloc element position:
53
* (cpu / 64) * 8 = (cpu >> 6) << 3
54
*/
55
srli a1, a2, 6
56
slli a1, a1, 3
57
la a0, new_vmalloc
58
add a0, a0, a1
59
/*
60
* Compute the bit position in the new_vmalloc element:
61
* bit_pos = cpu % 64 = cpu - (cpu / 64) * 64 = cpu - (cpu >> 6) << 6
62
* = cpu - ((cpu >> 6) << 3) << 3
63
*/
64
slli a1, a1, 3
65
sub a1, a2, a1
66
/* Compute the "get mask": 1 << bit_pos */
67
li a2, 1
68
sll a1, a2, a1
69
70
/* Check the value of new_vmalloc for this cpu */
71
REG_L a2, 0(a0)
72
and a2, a2, a1
73
beq a2, zero, .Lnew_vmalloc_restore_context
74
75
/* Atomically reset the current cpu bit in new_vmalloc */
76
amoxor.d a0, a1, (a0)
77
78
/* Only emit a sfence.vma if the uarch caches invalid entries */
79
ALTERNATIVE("sfence.vma", "nop", 0, RISCV_ISA_EXT_SVVPTC, 1)
80
81
REG_L a0, TASK_TI_A0(tp)
82
REG_L a1, TASK_TI_A1(tp)
83
REG_L a2, TASK_TI_A2(tp)
84
csrw CSR_SCRATCH, x0
85
sret
86
87
.Lnew_vmalloc_restore_context:
88
REG_L a2, TASK_TI_A2(tp)
89
.Lnew_vmalloc_restore_context_a1:
90
REG_L a1, TASK_TI_A1(tp)
91
.Lnew_vmalloc_restore_context_a0:
92
REG_L a0, TASK_TI_A0(tp)
93
.endm
94
95
96
SYM_CODE_START(handle_exception)
97
/*
98
* If coming from userspace, preserve the user thread pointer and load
99
* the kernel thread pointer. If we came from the kernel, the scratch
100
* register will contain 0, and we should continue on the current TP.
101
*/
102
csrrw tp, CSR_SCRATCH, tp
103
bnez tp, .Lsave_context
104
105
.Lrestore_kernel_tpsp:
106
csrr tp, CSR_SCRATCH
107
108
#ifdef CONFIG_64BIT
109
/*
110
* The RISC-V kernel does not eagerly emit a sfence.vma after each
111
* new vmalloc mapping, which may result in exceptions:
112
* - if the uarch caches invalid entries, the new mapping would not be
113
* observed by the page table walker and an invalidation is needed.
114
* - if the uarch does not cache invalid entries, a reordered access
115
* could "miss" the new mapping and traps: in that case, we only need
116
* to retry the access, no sfence.vma is required.
117
*/
118
new_vmalloc_check
119
#endif
120
121
REG_S sp, TASK_TI_KERNEL_SP(tp)
122
123
#ifdef CONFIG_VMAP_STACK
124
addi sp, sp, -(PT_SIZE_ON_STACK)
125
srli sp, sp, THREAD_SHIFT
126
andi sp, sp, 0x1
127
bnez sp, handle_kernel_stack_overflow
128
REG_L sp, TASK_TI_KERNEL_SP(tp)
129
#endif
130
131
.Lsave_context:
132
REG_S sp, TASK_TI_USER_SP(tp)
133
REG_L sp, TASK_TI_KERNEL_SP(tp)
134
addi sp, sp, -(PT_SIZE_ON_STACK)
135
REG_S x1, PT_RA(sp)
136
REG_S x3, PT_GP(sp)
137
REG_S x5, PT_T0(sp)
138
save_from_x6_to_x31
139
140
/*
141
* Disable user-mode memory access as it should only be set in the
142
* actual user copy routines.
143
*
144
* Disable the FPU/Vector to detect illegal usage of floating point
145
* or vector in kernel space.
146
*/
147
li t0, SR_SUM | SR_FS_VS
148
149
REG_L s0, TASK_TI_USER_SP(tp)
150
csrrc s1, CSR_STATUS, t0
151
csrr s2, CSR_EPC
152
csrr s3, CSR_TVAL
153
csrr s4, CSR_CAUSE
154
csrr s5, CSR_SCRATCH
155
REG_S s0, PT_SP(sp)
156
REG_S s1, PT_STATUS(sp)
157
REG_S s2, PT_EPC(sp)
158
REG_S s3, PT_BADADDR(sp)
159
REG_S s4, PT_CAUSE(sp)
160
REG_S s5, PT_TP(sp)
161
162
/*
163
* Set the scratch register to 0, so that if a recursive exception
164
* occurs, the exception vector knows it came from the kernel
165
*/
166
csrw CSR_SCRATCH, x0
167
168
/* Load the global pointer */
169
load_global_pointer
170
171
/* Load the kernel shadow call stack pointer if coming from userspace */
172
scs_load_current_if_task_changed s5
173
174
#ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
175
move a0, sp
176
call riscv_v_context_nesting_start
177
#endif
178
move a0, sp /* pt_regs */
179
180
/*
181
* MSB of cause differentiates between
182
* interrupts and exceptions
183
*/
184
bge s4, zero, 1f
185
186
/* Handle interrupts */
187
call do_irq
188
j ret_from_exception
189
1:
190
/* Handle other exceptions */
191
slli t0, s4, RISCV_LGPTR
192
la t1, excp_vect_table
193
la t2, excp_vect_table_end
194
add t0, t1, t0
195
/* Check if exception code lies within bounds */
196
bgeu t0, t2, 3f
197
REG_L t1, 0(t0)
198
2: jalr t1
199
j ret_from_exception
200
3:
201
202
la t1, do_trap_unknown
203
j 2b
204
SYM_CODE_END(handle_exception)
205
ASM_NOKPROBE(handle_exception)
206
207
/*
208
* The ret_from_exception must be called with interrupt disabled. Here is the
209
* caller list:
210
* - handle_exception
211
* - ret_from_fork
212
*/
213
SYM_CODE_START_NOALIGN(ret_from_exception)
214
REG_L s0, PT_STATUS(sp)
215
#ifdef CONFIG_RISCV_M_MODE
216
/* the MPP value is too large to be used as an immediate arg for addi */
217
li t0, SR_MPP
218
and s0, s0, t0
219
#else
220
andi s0, s0, SR_SPP
221
#endif
222
bnez s0, 1f
223
224
#ifdef CONFIG_KSTACK_ERASE
225
call stackleak_erase_on_task_stack
226
#endif
227
228
/* Save unwound kernel stack pointer in thread_info */
229
addi s0, sp, PT_SIZE_ON_STACK
230
REG_S s0, TASK_TI_KERNEL_SP(tp)
231
232
/* Save the kernel shadow call stack pointer */
233
scs_save_current
234
235
/*
236
* Save TP into the scratch register , so we can find the kernel data
237
* structures again.
238
*/
239
csrw CSR_SCRATCH, tp
240
1:
241
#ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
242
move a0, sp
243
call riscv_v_context_nesting_end
244
#endif
245
REG_L a0, PT_STATUS(sp)
246
/*
247
* The current load reservation is effectively part of the processor's
248
* state, in the sense that load reservations cannot be shared between
249
* different hart contexts. We can't actually save and restore a load
250
* reservation, so instead here we clear any existing reservation --
251
* it's always legal for implementations to clear load reservations at
252
* any point (as long as the forward progress guarantee is kept, but
253
* we'll ignore that here).
254
*
255
* Dangling load reservations can be the result of taking a trap in the
256
* middle of an LR/SC sequence, but can also be the result of a taken
257
* forward branch around an SC -- which is how we implement CAS. As a
258
* result we need to clear reservations between the last CAS and the
259
* jump back to the new context. While it is unlikely the store
260
* completes, implementations are allowed to expand reservations to be
261
* arbitrarily large.
262
*/
263
REG_L a2, PT_EPC(sp)
264
REG_SC x0, a2, PT_EPC(sp)
265
266
csrw CSR_STATUS, a0
267
csrw CSR_EPC, a2
268
269
REG_L x1, PT_RA(sp)
270
REG_L x3, PT_GP(sp)
271
REG_L x4, PT_TP(sp)
272
REG_L x5, PT_T0(sp)
273
restore_from_x6_to_x31
274
275
REG_L x2, PT_SP(sp)
276
277
#ifdef CONFIG_RISCV_M_MODE
278
mret
279
#else
280
sret
281
#endif
282
SYM_INNER_LABEL(ret_from_exception_end, SYM_L_GLOBAL)
283
SYM_CODE_END(ret_from_exception)
284
ASM_NOKPROBE(ret_from_exception)
285
286
#ifdef CONFIG_VMAP_STACK
287
SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
288
/* we reach here from kernel context, sscratch must be 0 */
289
csrrw x31, CSR_SCRATCH, x31
290
asm_per_cpu sp, overflow_stack, x31
291
li x31, OVERFLOW_STACK_SIZE
292
add sp, sp, x31
293
/* zero out x31 again and restore x31 */
294
xor x31, x31, x31
295
csrrw x31, CSR_SCRATCH, x31
296
297
addi sp, sp, -(PT_SIZE_ON_STACK)
298
299
//save context to overflow stack
300
REG_S x1, PT_RA(sp)
301
REG_S x3, PT_GP(sp)
302
REG_S x5, PT_T0(sp)
303
save_from_x6_to_x31
304
305
REG_L s0, TASK_TI_KERNEL_SP(tp)
306
csrr s1, CSR_STATUS
307
csrr s2, CSR_EPC
308
csrr s3, CSR_TVAL
309
csrr s4, CSR_CAUSE
310
csrr s5, CSR_SCRATCH
311
REG_S s0, PT_SP(sp)
312
REG_S s1, PT_STATUS(sp)
313
REG_S s2, PT_EPC(sp)
314
REG_S s3, PT_BADADDR(sp)
315
REG_S s4, PT_CAUSE(sp)
316
REG_S s5, PT_TP(sp)
317
move a0, sp
318
tail handle_bad_stack
319
SYM_CODE_END(handle_kernel_stack_overflow)
320
ASM_NOKPROBE(handle_kernel_stack_overflow)
321
#endif
322
323
SYM_CODE_START(ret_from_fork_kernel_asm)
324
call schedule_tail
325
move a0, s1 /* fn_arg */
326
move a1, s0 /* fn */
327
move a2, sp /* pt_regs */
328
call ret_from_fork_kernel
329
j ret_from_exception
330
SYM_CODE_END(ret_from_fork_kernel_asm)
331
332
SYM_CODE_START(ret_from_fork_user_asm)
333
call schedule_tail
334
move a0, sp /* pt_regs */
335
call ret_from_fork_user
336
j ret_from_exception
337
SYM_CODE_END(ret_from_fork_user_asm)
338
339
#ifdef CONFIG_IRQ_STACKS
340
/*
341
* void call_on_irq_stack(struct pt_regs *regs,
342
* void (*func)(struct pt_regs *));
343
*
344
* Calls func(regs) using the per-CPU IRQ stack.
345
*/
346
SYM_FUNC_START(call_on_irq_stack)
347
/* Create a frame record to save ra and s0 (fp) */
348
addi sp, sp, -STACKFRAME_SIZE_ON_STACK
349
REG_S ra, STACKFRAME_RA(sp)
350
REG_S s0, STACKFRAME_FP(sp)
351
addi s0, sp, STACKFRAME_SIZE_ON_STACK
352
353
/* Switch to the per-CPU shadow call stack */
354
scs_save_current
355
scs_load_irq_stack t0
356
357
/* Switch to the per-CPU IRQ stack and call the handler */
358
load_per_cpu t0, irq_stack_ptr, t1
359
li t1, IRQ_STACK_SIZE
360
add sp, t0, t1
361
jalr a1
362
363
/* Switch back to the thread shadow call stack */
364
scs_load_current
365
366
/* Switch back to the thread stack and restore ra and s0 */
367
addi sp, s0, -STACKFRAME_SIZE_ON_STACK
368
REG_L ra, STACKFRAME_RA(sp)
369
REG_L s0, STACKFRAME_FP(sp)
370
addi sp, sp, STACKFRAME_SIZE_ON_STACK
371
372
ret
373
SYM_FUNC_END(call_on_irq_stack)
374
#endif /* CONFIG_IRQ_STACKS */
375
376
/*
377
* Integer register context switch
378
* The callee-saved registers must be saved and restored.
379
*
380
* a0: previous task_struct (must be preserved across the switch)
381
* a1: next task_struct
382
*
383
* The value of a0 and a1 must be preserved by this function, as that's how
384
* arguments are passed to schedule_tail.
385
*/
386
SYM_FUNC_START(__switch_to)
387
/* Save context into prev->thread */
388
li a4, TASK_THREAD_RA
389
add a3, a0, a4
390
add a4, a1, a4
391
REG_S ra, TASK_THREAD_RA_RA(a3)
392
REG_S sp, TASK_THREAD_SP_RA(a3)
393
REG_S s0, TASK_THREAD_S0_RA(a3)
394
REG_S s1, TASK_THREAD_S1_RA(a3)
395
REG_S s2, TASK_THREAD_S2_RA(a3)
396
REG_S s3, TASK_THREAD_S3_RA(a3)
397
REG_S s4, TASK_THREAD_S4_RA(a3)
398
REG_S s5, TASK_THREAD_S5_RA(a3)
399
REG_S s6, TASK_THREAD_S6_RA(a3)
400
REG_S s7, TASK_THREAD_S7_RA(a3)
401
REG_S s8, TASK_THREAD_S8_RA(a3)
402
REG_S s9, TASK_THREAD_S9_RA(a3)
403
REG_S s10, TASK_THREAD_S10_RA(a3)
404
REG_S s11, TASK_THREAD_S11_RA(a3)
405
406
/* save the user space access flag */
407
csrr s0, CSR_STATUS
408
REG_S s0, TASK_THREAD_SUM_RA(a3)
409
410
/* Save the kernel shadow call stack pointer */
411
scs_save_current
412
/* Restore context from next->thread */
413
REG_L s0, TASK_THREAD_SUM_RA(a4)
414
li s1, SR_SUM
415
and s0, s0, s1
416
csrs CSR_STATUS, s0
417
REG_L ra, TASK_THREAD_RA_RA(a4)
418
REG_L sp, TASK_THREAD_SP_RA(a4)
419
REG_L s0, TASK_THREAD_S0_RA(a4)
420
REG_L s1, TASK_THREAD_S1_RA(a4)
421
REG_L s2, TASK_THREAD_S2_RA(a4)
422
REG_L s3, TASK_THREAD_S3_RA(a4)
423
REG_L s4, TASK_THREAD_S4_RA(a4)
424
REG_L s5, TASK_THREAD_S5_RA(a4)
425
REG_L s6, TASK_THREAD_S6_RA(a4)
426
REG_L s7, TASK_THREAD_S7_RA(a4)
427
REG_L s8, TASK_THREAD_S8_RA(a4)
428
REG_L s9, TASK_THREAD_S9_RA(a4)
429
REG_L s10, TASK_THREAD_S10_RA(a4)
430
REG_L s11, TASK_THREAD_S11_RA(a4)
431
/* The offset of thread_info in task_struct is zero. */
432
move tp, a1
433
/* Switch to the next shadow call stack */
434
scs_load_current
435
ret
436
SYM_FUNC_END(__switch_to)
437
438
#ifndef CONFIG_MMU
439
#define do_page_fault do_trap_unknown
440
#endif
441
442
.section ".rodata"
443
.align LGREG
444
/* Exception vector table */
445
SYM_DATA_START_LOCAL(excp_vect_table)
446
RISCV_PTR do_trap_insn_misaligned
447
ALT_INSN_FAULT(RISCV_PTR do_trap_insn_fault)
448
RISCV_PTR do_trap_insn_illegal
449
RISCV_PTR do_trap_break
450
RISCV_PTR do_trap_load_misaligned
451
RISCV_PTR do_trap_load_fault
452
RISCV_PTR do_trap_store_misaligned
453
RISCV_PTR do_trap_store_fault
454
RISCV_PTR do_trap_ecall_u /* system call */
455
RISCV_PTR do_trap_ecall_s
456
RISCV_PTR do_trap_unknown
457
RISCV_PTR do_trap_ecall_m
458
/* instruciton page fault */
459
ALT_PAGE_FAULT(RISCV_PTR do_page_fault)
460
RISCV_PTR do_page_fault /* load page fault */
461
RISCV_PTR do_trap_unknown
462
RISCV_PTR do_page_fault /* store page fault */
463
SYM_DATA_END_LABEL(excp_vect_table, SYM_L_LOCAL, excp_vect_table_end)
464
465
#ifndef CONFIG_MMU
466
SYM_DATA_START(__user_rt_sigreturn)
467
li a7, __NR_rt_sigreturn
468
ecall
469
SYM_DATA_END(__user_rt_sigreturn)
470
#endif
471
472