Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109808548
D48799.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D48799.diff
View Options
diff --git a/sys/riscv/include/frame.h b/sys/riscv/include/frame.h
--- a/sys/riscv/include/frame.h
+++ b/sys/riscv/include/frame.h
@@ -57,6 +57,10 @@
uint64_t tf_scause;
};
+#ifdef _KERNEL
+#define TF_SIZE (roundup2(sizeof(struct trapframe), STACKALIGNBYTES + 1))
+#endif
+
/*
* Signal frame. Pushed onto user stack before calling sigcode.
*/
@@ -65,6 +69,16 @@
ucontext_t sf_uc; /* actual saved ucontext */
};
+#ifdef _KERNEL
+/*
+ * Kernel frame. Reserved near the top of kernel stacks for saving kernel
+ * state while in userspace.
+ */
+struct kernframe {
+ register_t kf_tp;
+};
+#endif
+
#endif /* !LOCORE */
/* Definitions for syscalls */
diff --git a/sys/riscv/riscv/exception.S b/sys/riscv/riscv/exception.S
--- a/sys/riscv/riscv/exception.S
+++ b/sys/riscv/riscv/exception.S
@@ -53,7 +53,7 @@
.option pop
/* Load our pcpu */
- ld tp, (TF_SIZE)(sp)
+ ld tp, (TF_SIZE + KF_TP)(sp)
.endif
sd t0, (TF_T + 0 * 8)(sp)
@@ -139,7 +139,7 @@
csrw sscratch, t0
/* Store our pcpu */
- sd tp, (TF_SIZE)(sp)
+ sd tp, (TF_SIZE + KF_TP)(sp)
ld tp, (TF_TP)(sp)
/* And restore the user's global pointer */
diff --git a/sys/riscv/riscv/genassym.c b/sys/riscv/riscv/genassym.c
--- a/sys/riscv/riscv/genassym.c
+++ b/sys/riscv/riscv/genassym.c
@@ -85,7 +85,7 @@
ASSYM(TD_MD, offsetof(struct thread, td_md));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
-ASSYM(TF_SIZE, roundup2(sizeof(struct trapframe), STACKALIGNBYTES + 1));
+ASSYM(TF_SIZE, TF_SIZE);
ASSYM(TF_RA, offsetof(struct trapframe, tf_ra));
ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
ASSYM(TF_GP, offsetof(struct trapframe, tf_gp));
@@ -98,6 +98,8 @@
ASSYM(TF_SCAUSE, offsetof(struct trapframe, tf_scause));
ASSYM(TF_SSTATUS, offsetof(struct trapframe, tf_sstatus));
+ASSYM(KF_TP, offsetof(struct kernframe, kf_tp));
+
ASSYM(HYP_H_RA, offsetof(struct hypctx, host_regs.hyp_ra));
ASSYM(HYP_H_SP, offsetof(struct hypctx, host_regs.hyp_sp));
ASSYM(HYP_H_GP, offsetof(struct hypctx, host_regs.hyp_gp));
diff --git a/sys/riscv/riscv/swtch.S b/sys/riscv/riscv/swtch.S
--- a/sys/riscv/riscv/swtch.S
+++ b/sys/riscv/riscv/swtch.S
@@ -419,7 +419,7 @@
* Store our pcpup on stack, we will load it back
* on kernel mode trap.
*/
- sd tp, (TF_SIZE)(sp)
+ sd tp, (TF_SIZE + KF_TP)(sp)
ld tp, (TF_TP)(sp)
/* Save kernel stack so we can use it doing a user trap */
diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c
--- a/sys/riscv/riscv/vm_machdep.c
+++ b/sys/riscv/riscv/vm_machdep.c
@@ -57,6 +57,26 @@
#define TP_OFFSET 16 /* sizeof(struct tcb) */
#endif
+static void
+cpu_set_pcb_frame(struct thread *td)
+{
+ td->td_pcb = (struct pcb *)((char *)td->td_kstack +
+ td->td_kstack_pages * PAGE_SIZE) - 1;
+
+ /*
+ * td->td_frame + TF_SIZE will be the saved kernel stack pointer whilst
+ * in userspace, so keep it aligned so it's also aligned when we
+ * subtract TF_SIZE in the trap handler (and here for the initial stack
+ * pointer). This also keeps the struct kernframe just afterwards
+ * aligned no matter what's in it or struct pcb.
+ *
+ * NB: TF_SIZE not sizeof(struct trapframe) as we need the rounded
+ * value to match the trap handler.
+ */
+ td->td_frame = (struct trapframe *)(STACKALIGN(
+ (char *)td->td_pcb - sizeof(struct kernframe)) - TF_SIZE);
+}
+
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb, set up the stack so that the child
@@ -73,13 +93,12 @@
/* RISCVTODO: save the FPU state here */
- pcb2 = (struct pcb *)(td2->td_kstack +
- td2->td_kstack_pages * PAGE_SIZE) - 1;
+ cpu_set_pcb_frame(td2);
- td2->td_pcb = pcb2;
+ pcb2 = td2->td_pcb;
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
- tf = (struct trapframe *)STACKALIGN((struct trapframe *)pcb2 - 1);
+ tf = td2->td_frame;
bcopy(td1->td_frame, tf, sizeof(*tf));
/* Clear syscall error flag */
@@ -91,8 +110,6 @@
tf->tf_sstatus |= (SSTATUS_SPIE); /* Enable interrupts. */
tf->tf_sstatus &= ~(SSTATUS_SPP); /* User mode. */
- td2->td_frame = tf;
-
/* Set the return value registers for fork() */
td2->td_pcb->pcb_s[0] = (uintptr_t)fork_return;
td2->td_pcb->pcb_s[1] = (uintptr_t)td2;
@@ -206,11 +223,7 @@
void
cpu_thread_alloc(struct thread *td)
{
-
- td->td_pcb = (struct pcb *)(td->td_kstack +
- td->td_kstack_pages * PAGE_SIZE) - 1;
- td->td_frame = (struct trapframe *)STACKALIGN(
- (caddr_t)td->td_pcb - 8 - sizeof(struct trapframe));
+ cpu_set_pcb_frame(td);
}
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 10, 7:41 PM (7 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16582606
Default Alt Text
D48799.diff (4 KB)
Attached To
Mode
D48799: riscv: Fix and generalise saving TP (PCPU pointer) whilst in userspace
Attached
Detach File
Event Timeline
Log In to Comment