summaryrefslogtreecommitdiff
path: root/sys/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'sys/riscv')
-rw-r--r--sys/riscv/include/pcpu.h2
-rw-r--r--sys/riscv/include/pcpu_aux.h3
-rw-r--r--sys/riscv/include/stack.h6
-rw-r--r--sys/riscv/riscv/db_trace.c18
-rw-r--r--sys/riscv/riscv/locore.S23
-rw-r--r--sys/riscv/riscv/stack_machdep.c19
-rw-r--r--sys/riscv/riscv/trap.c23
-rw-r--r--sys/riscv/riscv/unwind.c6
8 files changed, 61 insertions, 39 deletions
diff --git a/sys/riscv/include/pcpu.h b/sys/riscv/include/pcpu.h
index 46b258380a105..5068596462fc3 100644
--- a/sys/riscv/include/pcpu.h
+++ b/sys/riscv/include/pcpu.h
@@ -48,7 +48,7 @@
struct pmap *pc_curpmap; /* Currently active pmap */ \
uint32_t pc_pending_ipis; /* IPIs pending to this CPU */ \
uint32_t pc_hart; /* Hart ID */ \
- char __pad[49]
+ char __pad[56] /* Pad to factor of PAGE_SIZE */
#ifdef _KERNEL
diff --git a/sys/riscv/include/pcpu_aux.h b/sys/riscv/include/pcpu_aux.h
index 3d4c70c491d62..9fecd25c67cbc 100644
--- a/sys/riscv/include/pcpu_aux.h
+++ b/sys/riscv/include/pcpu_aux.h
@@ -46,6 +46,9 @@
* be a multiple of the size of struct pcpu.
*/
_Static_assert(PAGE_SIZE % sizeof(struct pcpu) == 0, "fix pcpu size");
+_Static_assert(offsetof(struct pcpu, __pad) +
+ sizeof(((struct pcpu *)0)->__pad) == sizeof(struct pcpu),
+ "fix pcpu padding");
extern struct pcpu __pcpu[];
diff --git a/sys/riscv/include/stack.h b/sys/riscv/include/stack.h
index 7f4be068ec273..40183afb9f4d6 100644
--- a/sys/riscv/include/stack.h
+++ b/sys/riscv/include/stack.h
@@ -41,9 +41,9 @@
(va) <= VM_MAX_KERNEL_ADDRESS)
struct unwind_state {
- uint64_t fp;
- uint64_t sp;
- uint64_t pc;
+ uintptr_t fp;
+ uintptr_t sp;
+ uintptr_t pc;
};
int unwind_frame(struct unwind_state *);
diff --git a/sys/riscv/riscv/db_trace.c b/sys/riscv/riscv/db_trace.c
index 2a783b2ed0f02..6d7b6b934d43e 100644
--- a/sys/riscv/riscv/db_trace.c
+++ b/sys/riscv/riscv/db_trace.c
@@ -108,9 +108,9 @@ db_stack_trace_cmd(struct unwind_state *frame)
db_printf("--- exception %ld, tval = %#lx\n",
tf->tf_scause & EXCP_MASK,
tf->tf_stval);
- frame->sp = (uint64_t)tf->tf_sp;
- frame->fp = (uint64_t)tf->tf_s[0];
- frame->pc = (uint64_t)tf->tf_sepc;
+ frame->sp = tf->tf_sp;
+ frame->fp = tf->tf_s[0];
+ frame->pc = tf->tf_sepc;
if (!INKERNEL(frame->fp))
break;
continue;
@@ -132,9 +132,9 @@ db_trace_thread(struct thread *thr, int count)
ctx = kdb_thr_ctx(thr);
- frame.sp = (uint64_t)ctx->pcb_sp;
- frame.fp = (uint64_t)ctx->pcb_s[0];
- frame.pc = (uint64_t)ctx->pcb_ra;
+ frame.sp = ctx->pcb_sp;
+ frame.fp = ctx->pcb_s[0];
+ frame.pc = ctx->pcb_ra;
db_stack_trace_cmd(&frame);
return (0);
}
@@ -143,12 +143,12 @@ void
db_trace_self(void)
{
struct unwind_state frame;
- uint64_t sp;
+ uintptr_t sp;
__asm __volatile("mv %0, sp" : "=&r" (sp));
frame.sp = sp;
- frame.fp = (uint64_t)__builtin_frame_address(0);
- frame.pc = (uint64_t)db_trace_self;
+ frame.fp = (uintptr_t)__builtin_frame_address(0);
+ frame.pc = (uintptr_t)db_trace_self;
db_stack_trace_cmd(&frame);
}
diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S
index 4a5b01df85b76..86eaab6d533b6 100644
--- a/sys/riscv/riscv/locore.S
+++ b/sys/riscv/riscv/locore.S
@@ -223,19 +223,21 @@ va:
csrw sscratch, t0
/* Initialize stack pointer */
- la s3, initstack_end
- mv sp, s3
+ la sp, initstack_end
+
+ /* Clear frame pointer */
+ mv s0, zero
/* Allocate space for thread0 PCB and riscv_bootparams */
addi sp, sp, -(PCB_SIZE + RISCV_BOOTPARAMS_SIZE) & ~STACKALIGNBYTES
/* Clear BSS */
- la s0, _C_LABEL(__bss_start)
- la s1, _C_LABEL(_end)
+ la t0, _C_LABEL(__bss_start)
+ la t1, _C_LABEL(_end)
1:
- sd zero, 0(s0)
- addi s0, s0, 8
- bltu s0, s1, 1b
+ sd zero, 0(t0)
+ addi t0, t0, 8
+ bltu t0, t1, 1b
/* Fill riscv_bootparams */
la t0, pagetable_l1
@@ -259,6 +261,11 @@ va:
call _C_LABEL(initriscv) /* Off we go */
call _C_LABEL(mi_startup)
+ /* We should never reach here, but if so just hang. */
+2:
+ wfi
+ j 2b
+
/*
* Get the physical address the kernel is loaded to. Returned in s9.
*/
@@ -350,7 +357,7 @@ ENTRY(mpentry)
ld sp, 0(t0)
/* Get the kernel's load address */
- jal get_physmem
+ jal get_physmem
/* Setup supervisor trap vector */
lla t0, mpva
diff --git a/sys/riscv/riscv/stack_machdep.c b/sys/riscv/riscv/stack_machdep.c
index 2e016f537f91c..d4939dbda0418 100644
--- a/sys/riscv/riscv/stack_machdep.c
+++ b/sys/riscv/riscv/stack_machdep.c
@@ -47,15 +47,18 @@ __FBSDID("$FreeBSD$");
#include <machine/stack.h>
static void
-stack_capture(struct stack *st, struct unwind_state *frame)
+stack_capture(struct thread *td, struct stack *st, struct unwind_state *frame)
{
stack_zero(st);
while (1) {
+ if ((vm_offset_t)frame->fp < td->td_kstack ||
+ (vm_offset_t)frame->fp >= td->td_kstack +
+ td->td_kstack_pages * PAGE_SIZE)
+ break;
unwind_frame(frame);
- if (!INKERNEL((vm_offset_t)frame->fp) ||
- !INKERNEL((vm_offset_t)frame->pc))
+ if (!INKERNEL((vm_offset_t)frame->pc))
break;
if (stack_put(st, frame->pc) == -1)
break;
@@ -78,7 +81,7 @@ stack_save_td(struct stack *st, struct thread *td)
frame.fp = td->td_pcb->pcb_s[0];
frame.pc = td->td_pcb->pcb_ra;
- stack_capture(st, &frame);
+ stack_capture(td, st, &frame);
return (0);
}
@@ -86,13 +89,13 @@ void
stack_save(struct stack *st)
{
struct unwind_state frame;
- uint64_t sp;
+ uintptr_t sp;
__asm __volatile("mv %0, sp" : "=&r" (sp));
frame.sp = sp;
- frame.fp = (uint64_t)__builtin_frame_address(0);
- frame.pc = (uint64_t)stack_save;
+ frame.fp = (uintptr_t)__builtin_frame_address(0);
+ frame.pc = (uintptr_t)stack_save;
- stack_capture(st, &frame);
+ stack_capture(curthread, st, &frame);
}
diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c
index aa9ec534669d3..dabd84e822e94 100644
--- a/sys/riscv/riscv/trap.c
+++ b/sys/riscv/riscv/trap.c
@@ -198,14 +198,22 @@ data_abort(struct trapframe *frame, int usermode)
"Kernel page fault") != 0)
goto fatal;
- if (usermode)
- map = &td->td_proc->p_vmspace->vm_map;
- else if (stval >= VM_MAX_USER_ADDRESS)
- map = kernel_map;
- else {
- if (pcb->pcb_onfault == 0)
- goto fatal;
+ if (usermode) {
map = &td->td_proc->p_vmspace->vm_map;
+ } else {
+ /*
+ * Enable interrupts for the duration of the page fault. For
+ * user faults this was done already in do_trap_user().
+ */
+ intr_enable();
+
+ if (stval >= VM_MAX_USER_ADDRESS) {
+ map = kernel_map;
+ } else {
+ if (pcb->pcb_onfault == 0)
+ goto fatal;
+ map = &td->td_proc->p_vmspace->vm_map;
+ }
}
va = trunc_page(stval);
@@ -324,6 +332,7 @@ do_trap_user(struct trapframe *frame)
riscv_cpu_intr(frame);
return;
}
+ intr_enable();
CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p",
curthread, frame->tf_sepc, frame);
diff --git a/sys/riscv/riscv/unwind.c b/sys/riscv/riscv/unwind.c
index 18fc1e250c9b5..8b0cdeca29034 100644
--- a/sys/riscv/riscv/unwind.c
+++ b/sys/riscv/riscv/unwind.c
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
int
unwind_frame(struct unwind_state *frame)
{
- uint64_t fp;
+ uintptr_t fp;
fp = frame->fp;
@@ -50,8 +50,8 @@ unwind_frame(struct unwind_state *frame)
return (-1);
frame->sp = fp;
- frame->fp = *(uint64_t *)(fp - 16);
- frame->pc = *(uint64_t *)(fp - 8) - 4;
+ frame->fp = ((uintptr_t *)fp)[-2];
+ frame->pc = ((uintptr_t *)fp)[-1] - 4;
return (0);
}