Page MenuHomeFreeBSD

D29851.1775114240.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D29851.1775114240.diff

diff --git a/sys/powerpc/include/reg.h b/sys/powerpc/include/reg.h
--- a/sys/powerpc/include/reg.h
+++ b/sys/powerpc/include/reg.h
@@ -68,6 +68,11 @@
int fill_dbregs(struct thread *, struct dbreg *);
int set_dbregs(struct thread *, struct dbreg *);
+/*
+ * MD interfaces.
+ */
+void cpu_save_thread_regs(struct thread *);
+
#ifdef COMPAT_FREEBSD32
struct image_params;
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -570,6 +570,74 @@
cleanup_fpscr();
}
+/*
+ * Ensure the PCB has been updated in preparation for copying a thread.
+ *
+ * This is needed because normally this only happens during switching tasks,
+ * but when we are cloning a thread, we need the updated state before doing
+ * the actual copy, so the new thread inherits the current state instead of
+ * the state at the last task switch.
+ *
+ * Keep this in sync with the assembly code in cpu_switch()!
+ */
+void
+cpu_save_thread_regs(struct thread *td)
+{
+ uint32_t pcb_flags;
+ struct pcb *pcb;
+
+ KASSERT(td == curthread,
+ ("cpu_save_thread_regs: td is not curthread"));
+
+ pcb = td->td_pcb;
+
+ pcb_flags = pcb->pcb_flags;
+
+#if defined(__powerpc64__)
+ /* Are *any* FSCR flags in use? */
+ if (pcb_flags & PCB_CFSCR) {
+ pcb->pcb_fscr = mfspr(SPR_FSCR);
+
+ if (pcb->pcb_fscr & FSCR_EBB) {
+ pcb->pcb_ebb.ebbhr = mfspr(SPR_EBBHR);
+ pcb->pcb_ebb.ebbrr = mfspr(SPR_EBBRR);
+ pcb->pcb_ebb.bescr = mfspr(SPR_BESCR);
+ }
+ if (pcb->pcb_fscr & FSCR_LM) {
+ pcb->pcb_lm.lmrr = mfspr(SPR_LMRR);
+ pcb->pcb_lm.lmser = mfspr(SPR_LMSER);
+ }
+ if (pcb->pcb_fscr & FSCR_TAR)
+ pcb->pcb_tar = mfspr(SPR_TAR);
+ }
+
+ /*
+ * This is outside of the PCB_CFSCR check because it can be set
+ * independently when running on POWER7/POWER8.
+ */
+ if (pcb_flags & PCB_CDSCR)
+ pcb->pcb_dscr = mfspr(SPR_DSCRP);
+#endif
+
+#if defined(__SPE__)
+ /*
+ * On E500v2, single-precision scalar instructions and access to
+ * SPEFSCR may be used without PSL_VEC turned on, as long as they
+ * limit themselves to the low word of the registers.
+ *
+ * As such, we need to unconditionally save SPEFSCR, even though
+ * it is also updated in save_vec_nodrop().
+ */
+ pcb->pcb_vec.vscr = mfspr(SPR_SPEFSCR);
+#endif
+
+ if (pcb_flags & PCB_FPU)
+ save_fpu_nodrop(td);
+
+ if (pcb_flags & PCB_VEC)
+ save_vec_nodrop(td);
+}
+
/*
* Set set up registers on exec.
*/
@@ -1028,6 +1096,10 @@
struct trapframe *tf;
struct callframe *cf;
+ /* Ensure td0 pcb is up to date. */
+ if (td == curthread)
+ cpu_save_thread_regs(td0);
+
pcb2 = td->td_pcb;
/* Copy the upcall pcb */
diff --git a/sys/powerpc/powerpc/swtch32.S b/sys/powerpc/powerpc/swtch32.S
--- a/sys/powerpc/powerpc/swtch32.S
+++ b/sys/powerpc/powerpc/swtch32.S
@@ -104,6 +104,8 @@
mr %r16,%r5 /* and the new lock */
mr %r17,%r6 /* and the PCB */
+ /* Keep this next section in sync with cpu_save_thread_regs()! */
+
lwz %r18,PCB_FLAGS(%r17)
/* Save FPU context if needed */
andi. %r7, %r18, PCB_FPU
diff --git a/sys/powerpc/powerpc/swtch64.S b/sys/powerpc/powerpc/swtch64.S
--- a/sys/powerpc/powerpc/swtch64.S
+++ b/sys/powerpc/powerpc/swtch64.S
@@ -131,6 +131,8 @@
stdu %r1,-48(%r1)
+ /* Keep this next section in sync with cpu_save_thread_regs()! */
+
lwz %r18, PCB_FLAGS(%r17)
andi. %r7, %r18, PCB_CFSCR
beq 1f
diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c
--- a/sys/powerpc/powerpc/vm_machdep.c
+++ b/sys/powerpc/powerpc/vm_machdep.c
@@ -91,6 +91,7 @@
#include <machine/frame.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
+#include <machine/reg.h>
#include <dev/ofw/openfirm.h>
@@ -121,6 +122,10 @@
if ((flags & RFPROC) == 0)
return;
+ /* Ensure td1 is up to date before copy. */
+ if (td1 == curthread)
+ cpu_save_thread_regs(td1);
+
pcb = (struct pcb *)((td2->td_kstack +
td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x2fUL);
td2->td_pcb = pcb;

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 7:17 AM (1 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28242915
Default Alt Text
D29851.1775114240.diff (3 KB)

Event Timeline