Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Jun 2019 00:43:38 +0000 (UTC)
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r349485 - in stable/12/sys: conf riscv/include riscv/riscv
Message-ID:  <201906280043.x5S0hcnU077014@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mhorne
Date: Fri Jun 28 00:43:38 2019
New Revision: 349485
URL: https://svnweb.freebsd.org/changeset/base/349485

Log:
  MFC 348835-348836:
  Fix global pointer relaxations in the RISC-V kernel
  
  The gp register is intended to used by the linker as another means of
  performing relaxations, and should point to the small data section (.sdata).
  
  Currently gp is being used as the pcpu pointer within the kernel, but the more
  appropriate choice for this is the tp register, which is unused.
  
  Swap existing usage of gp with tp within the kernel, and set up gp properly
  at boot with the value of __global_pointer$ for all harts.
  
  Approved by:	markj (mentor, implicit)

Modified:
  stable/12/sys/conf/ldscript.riscv
  stable/12/sys/riscv/include/asm.h
  stable/12/sys/riscv/include/pcpu.h
  stable/12/sys/riscv/riscv/exception.S
  stable/12/sys/riscv/riscv/locore.S
  stable/12/sys/riscv/riscv/machdep.c
  stable/12/sys/riscv/riscv/mp_machdep.c
  stable/12/sys/riscv/riscv/swtch.S
  stable/12/sys/riscv/riscv/vm_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/conf/ldscript.riscv
==============================================================================
--- stable/12/sys/conf/ldscript.riscv	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/conf/ldscript.riscv	Fri Jun 28 00:43:38 2019	(r349485)
@@ -84,7 +84,11 @@ SECTIONS
      can access them all, and initialized data all before uninitialized, so
      we can shorten the on-disk segment size.  */
   . = ALIGN(8);
-  .sdata     : { *(.sdata) }
+  .sdata     :
+  {
+    __global_pointer$ = . + 0x800;
+    *(.sdata)
+  }
   _edata  =  .;
   PROVIDE (edata = .);
   /* Ensure __bss_start is associated with the next section in case orphan

Modified: stable/12/sys/riscv/include/asm.h
==============================================================================
--- stable/12/sys/riscv/include/asm.h	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/include/asm.h	Fri Jun 28 00:43:38 2019	(r349485)
@@ -59,7 +59,7 @@
 	.set alias,sym
 
 #define	SET_FAULT_HANDLER(handler, tmp)					\
-	ld	tmp, PC_CURTHREAD(gp);					\
+	ld	tmp, PC_CURTHREAD(tp);					\
 	ld	tmp, TD_PCB(tmp);		/* Load the pcb */	\
 	sd	handler, PCB_ONFAULT(tmp)	/* Set the handler */
 

Modified: stable/12/sys/riscv/include/pcpu.h
==============================================================================
--- stable/12/sys/riscv/include/pcpu.h	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/include/pcpu.h	Fri Jun 28 00:43:38 2019	(r349485)
@@ -60,7 +60,7 @@ get_pcpu(void)
 {
 	struct pcpu *pcpu;
 
-	__asm __volatile("mv %0, gp" : "=&r"(pcpu));
+	__asm __volatile("mv %0, tp" : "=&r"(pcpu));
 
 	return (pcpu);
 }
@@ -70,7 +70,7 @@ get_curthread(void)
 {
 	struct thread *td;
 
-	__asm __volatile("ld %0, 0(gp)" : "=&r"(td));
+	__asm __volatile("ld %0, 0(tp)" : "=&r"(td));
 
 	return (td);
 }

Modified: stable/12/sys/riscv/riscv/exception.S
==============================================================================
--- stable/12/sys/riscv/riscv/exception.S	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/riscv/exception.S	Fri Jun 28 00:43:38 2019	(r349485)
@@ -44,11 +44,18 @@ __FBSDID("$FreeBSD$");
 	addi	sp, sp, -(TF_SIZE)
 
 	sd	ra, (TF_RA)(sp)
-	sd	tp, (TF_TP)(sp)
 
-.if \el == 0	/* We came from userspace. Load our pcpu */
+.if \el == 0	/* We came from userspace. */
 	sd	gp, (TF_GP)(sp)
-	ld	gp, (TF_SIZE)(sp)
+.option push
+.option norelax
+	/* Load the kernel's global pointer */
+	la	gp, __global_pointer$
+.option pop
+
+	/* Load our pcpu */
+	sd	tp, (TF_TP)(sp)
+	ld	tp, (TF_SIZE)(sp)
 .endif
 
 	sd	t0, (TF_T + 0 * 8)(sp)
@@ -81,16 +88,6 @@ __FBSDID("$FreeBSD$");
 	sd	a6, (TF_A + 6 * 8)(sp)
 	sd	a7, (TF_A + 7 * 8)(sp)
 
-#if 0
-	/* XXX: temporary test: spin if stack is not kernel one */
-.if \el == 1	/* kernel */
-	mv	t0, sp
-	srli	t0, t0, 63
-1:
-	beqz	t0, 1b
-.endif
-#endif
-
 .if \el == 1
 	/* Store kernel sp */
 	li	t1, TF_SIZE
@@ -138,13 +135,15 @@ __FBSDID("$FreeBSD$");
 	ld	t0, (TF_SP)(sp)
 	csrw	sscratch, t0
 
-	/* And store our pcpu */
-	sd	gp, (TF_SIZE)(sp)
+	/* Store our pcpu */
+	sd	tp, (TF_SIZE)(sp)
+	ld	tp, (TF_TP)(sp)
+
+	/* And restore the user's global pointer */
 	ld	gp, (TF_GP)(sp)
 .endif
 
 	ld	ra, (TF_RA)(sp)
-	ld	tp, (TF_TP)(sp)
 
 	ld	t0, (TF_T + 0 * 8)(sp)
 	ld	t1, (TF_T + 1 * 8)(sp)
@@ -185,7 +184,7 @@ __FBSDID("$FreeBSD$");
 1:
 	csrci	sstatus, (SSTATUS_SIE)
 
-	ld	a1, PC_CURTHREAD(gp)
+	ld	a1, PC_CURTHREAD(tp)
 	lw	a2, TD_FLAGS(a1)
 
 	li	a3, (TDF_ASTPENDING|TDF_NEEDRESCHED)

Modified: stable/12/sys/riscv/riscv/locore.S
==============================================================================
--- stable/12/sys/riscv/riscv/locore.S	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/riscv/locore.S	Fri Jun 28 00:43:38 2019	(r349485)
@@ -171,12 +171,18 @@ va:
 	li	t0, 0
 	csrw	sscratch, t0
 
+	/* Set the global pointer */
+.option push
+.option norelax
+	la	gp, __global_pointer$
+.option pop
+
 	/* Initialize stack pointer */
 	la	s3, initstack_end
 	mv	sp, s3
 	addi	sp, sp, -PCB_SIZE
 
-	/* Clear BSS  */
+	/* Clear BSS */
 	la	s0, _C_LABEL(__bss_start)
 	la	s1, _C_LABEL(_end)
 1:
@@ -251,12 +257,6 @@ virt_map:
 hart_lottery:
 	.space	4
 
-	/* Not in use, but required for linking. */
-	.align 3
-	.globl __global_pointer$
-__global_pointer$:
-	.space	8
-
 	.globl init_pt_va
 init_pt_va:
 	.quad pagetable_l2	/* XXX: Keep page tables VA */
@@ -323,6 +323,12 @@ mpva:
 	/* Ensure sscratch is zero */
 	li	t0, 0
 	csrw	sscratch, t0
+
+	/* Set the global pointer */
+.option push
+.option norelax
+	la	gp, __global_pointer$
+.option pop
 
 	call	init_secondary
 END(mpentry)

Modified: stable/12/sys/riscv/riscv/machdep.c
==============================================================================
--- stable/12/sys/riscv/riscv/machdep.c	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/riscv/machdep.c	Fri Jun 28 00:43:38 2019	(r349485)
@@ -821,7 +821,7 @@ initriscv(struct riscv_bootparams *rvbp)
 	pcpup->pc_hart = boot_hart;
 
 	/* Set the pcpu pointer */
-	__asm __volatile("mv gp, %0" :: "r"(pcpup));
+	__asm __volatile("mv tp, %0" :: "r"(pcpup));
 
 	PCPU_SET(curthread, &thread0);
 

Modified: stable/12/sys/riscv/riscv/mp_machdep.c
==============================================================================
--- stable/12/sys/riscv/riscv/mp_machdep.c	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/riscv/mp_machdep.c	Fri Jun 28 00:43:38 2019	(r349485)
@@ -233,7 +233,7 @@ init_secondary(uint64_t hart)
 
 	/* Setup the pcpu pointer */
 	pcpup = &__pcpu[cpuid];
-	__asm __volatile("mv gp, %0" :: "r"(pcpup));
+	__asm __volatile("mv tp, %0" :: "r"(pcpup));
 
 	/* Workaround: make sure wfi doesn't halt the hart */
 	csr_set(sie, SIE_SSIE);

Modified: stable/12/sys/riscv/riscv/swtch.S
==============================================================================
--- stable/12/sys/riscv/riscv/swtch.S	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/riscv/swtch.S	Fri Jun 28 00:43:38 2019	(r349485)
@@ -217,15 +217,14 @@ ENTRY(cpu_throw)
 	mv	a0, s0
 
 	/* Store the new curthread */
-	sd	a0, PC_CURTHREAD(gp)
+	sd	a0, PC_CURTHREAD(tp)
 	/* And the new pcb */
 	ld	x13, TD_PCB(a0)
-	sd	x13, PC_CURPCB(gp)
+	sd	x13, PC_CURPCB(tp)
 
 	/* Load registers */
 	ld	ra, (PCB_RA)(x13)
 	ld	sp, (PCB_SP)(x13)
-	ld	tp, (PCB_TP)(x13)
 
 	/* s[0-11] */
 	ld	s0, (PCB_S + 0 * 8)(x13)
@@ -267,10 +266,10 @@ END(cpu_throw)
  */
 ENTRY(cpu_switch)
 	/* Store the new curthread */
-	sd	a1, PC_CURTHREAD(gp)
+	sd	a1, PC_CURTHREAD(tp)
 	/* And the new pcb */
 	ld	x13, TD_PCB(a1)
-	sd	x13, PC_CURPCB(gp)
+	sd	x13, PC_CURPCB(tp)
 
 	/* Save the old context. */
 	ld	x13, TD_PCB(a0)
@@ -278,7 +277,6 @@ ENTRY(cpu_switch)
 	/* Store ra, sp and the callee-saved registers */
 	sd	ra, (PCB_RA)(x13)
 	sd	sp, (PCB_SP)(x13)
-	sd	tp, (PCB_TP)(x13)
 
 	/* s[0-11] */
 	sd	s0, (PCB_S + 0 * 8)(x13)
@@ -340,7 +338,6 @@ ENTRY(cpu_switch)
 	ld	x13, TD_PCB(a1)
 
 	/* Restore the registers */
-	ld	tp, (PCB_TP)(x13)
 	ld	ra, (PCB_RA)(x13)
 	ld	sp, (PCB_SP)(x13)
 
@@ -429,15 +426,16 @@ ENTRY(fork_trampoline)
 	ld	a6, (TF_A + 6 * 8)(sp)
 	ld	a7, (TF_A + 7 * 8)(sp)
 
-	/* Load user ra and sp */
+	/* Load user ra and gp */
 	ld	ra, (TF_RA)(sp)
+	ld	gp, (TF_GP)(sp)
 
 	/*
 	 * Store our pcpup on stack, we will load it back
 	 * on kernel mode trap.
 	 */
-	sd	gp, (TF_SIZE)(sp)
-	ld	gp, (TF_GP)(sp)
+	sd	tp, (TF_SIZE)(sp)
+	ld	tp, (TF_TP)(sp)
 
 	/* Save kernel stack so we can use it doing a user trap */
 	addi	sp, sp, TF_SIZE
@@ -454,6 +452,7 @@ ENTRY(savectx)
 	sd	ra, (PCB_RA)(a0)
 	sd	sp, (PCB_SP)(a0)
 	sd	tp, (PCB_TP)(a0)
+	sd	gp, (PCB_GP)(a0)
 
 	/* s[0-11] */
 	sd	s0, (PCB_S + 0 * 8)(a0)

Modified: stable/12/sys/riscv/riscv/vm_machdep.c
==============================================================================
--- stable/12/sys/riscv/riscv/vm_machdep.c	Fri Jun 28 00:36:26 2019	(r349484)
+++ stable/12/sys/riscv/riscv/vm_machdep.c	Fri Jun 28 00:43:38 2019	(r349485)
@@ -69,23 +69,12 @@ cpu_fork(struct thread *td1, struct proc *p2, struct t
 {
 	struct pcb *pcb2;
 	struct trapframe *tf;
-	register_t val;
 
 	if ((flags & RFPROC) == 0)
 		return;
 
-	if (td1 == curthread) {
-		/*
-		 * Save the tp. These normally happen in cpu_switch,
-		 * but if userland changes this then forks this may
-		 * not have happened.
-		 */
-		__asm __volatile("mv %0, tp" : "=&r"(val));
-		td1->td_pcb->pcb_tp = val;
+	/* RISCVTODO: save the FPU state here */
 
-		/* RISCVTODO: save the FPU state here */
-	}
-
 	pcb2 = (struct pcb *)(td2->td_kstack +
 	    td2->td_kstack_pages * PAGE_SIZE) - 1;
 
@@ -205,15 +194,15 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *
 int
 cpu_set_user_tls(struct thread *td, void *tls_base)
 {
-	struct pcb *pcb;
 
 	if ((uintptr_t)tls_base >= VM_MAXUSER_ADDRESS)
 		return (EINVAL);
 
-	pcb = td->td_pcb;
-	pcb->pcb_tp = (register_t)tls_base + TP_OFFSET;
-	if (td == curthread)
-		__asm __volatile("mv tp, %0" :: "r"(pcb->pcb_tp));
+	/*
+	 * The user TLS is set by modifying the trapframe's tp value, which
+	 * will be restored when returning to userspace.
+	 */
+	td->td_frame->tf_tp = (register_t)tls_base + TP_OFFSET;
 
 	return (0);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201906280043.x5S0hcnU077014>