Re: svn commit: r306162 - in head/sys/arm: arm include

2016-09-22 Thread Ed Schouten
Hi Kostik,

2016-09-22 11:28 GMT+02:00 Konstantin Belousov :
> What do you mean about 'possibility to switch between TLS areas in
> usermode' ? On x86, kernel switches %fs/%gs bases on the context
> switches. There is, indeed, a way to turn off this functionality, but it
> is somewhat unobvious, I have to admit.

On x86 I've solved this by not letting apps have ownership over
%fs/%gs. Instead, they simply assume that they point to some valid
piece of memory. They can only use %fs:0. That way we now effectively
have the ability to adjust TLS from userspace on all architectures
freely.

This feature is already used extensively by the userspace emulator,
where you can run CloudABI executables on unmodified operating
systems. You can even run an emulator inside of an emulator inside of
an emulator. Not useful, but a good demonstration/test.

Another thing this could be useful for is that it allows us to
implement something like a simple truss(1) that doesn't depend on
kernel-level tracing facilities, but merely captures system call
invocations inside the process itself.

-- 
Ed Schouten 
Nuxi, 's-Hertogenbosch, the Netherlands
KvK-nr.: 62051717
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


Re: svn commit: r306162 - in head/sys/arm: arm include

2016-09-22 Thread Konstantin Belousov
On Thu, Sep 22, 2016 at 08:15:00AM +, Ed Schouten wrote:
> Author: ed
> Date: Thu Sep 22 08:14:59 2016
> New Revision: 306162
> URL: https://svnweb.freebsd.org/changeset/base/306162
> 
> Log:
>   Make it possible to safely use TPIDRURW from userspace.
>   
>   On amd64, arm64 and i386, we have the possibility to switch between TLS
>   areas in userspace. The nice thing about this is that it makes it easier
>   to do light-weight threading, if we ever feel like doing that. On armv6,
>   let's go into the same direction by making it possible to safely use the
>   TPIDRURW register, which is intended for this purpose.

What do you mean about 'possibility to switch between TLS areas in
usermode' ? On x86, kernel switches %fs/%gs bases on the context
switches. There is, indeed, a way to turn off this functionality, but it
is somewhat unobvious, I have to admit.

E.g. on Ivy+, RDFSBASE/RDGSBASE work.  WRFSBASE/WRGSBASE are enabled,
but they are de-facto not functional, since next context switch overrides
the base, in default setup.
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


svn commit: r306162 - in head/sys/arm: arm include

2016-09-22 Thread Ed Schouten
Author: ed
Date: Thu Sep 22 08:14:59 2016
New Revision: 306162
URL: https://svnweb.freebsd.org/changeset/base/306162

Log:
  Make it possible to safely use TPIDRURW from userspace.
  
  On amd64, arm64 and i386, we have the possibility to switch between TLS
  areas in userspace. The nice thing about this is that it makes it easier
  to do light-weight threading, if we ever feel like doing that. On armv6,
  let's go into the same direction by making it possible to safely use the
  TPIDRURW register, which is intended for this purpose.
  
  Clean up the ARMv6 code to remove md_tp entirely. Simply add a dedicated
  field to the PCB to hold the value of TPIDRURW across context switches,
  like we do for any other register. As userspace currently uses the
  read-only TPIDRURO register, simply ensure that we keep both values in
  sync where possible. The system calls for modifying the read-only
  register will simply write the intended value into both registers, so
  that it lazily ends up in the PCB during the next context switch.
  
  Reviewed by:  https://reviews.freebsd.org/D7951
  Approved by:  andrew
  Reviewed by:  imp
  Differential Revision:https://reviews.freebsd.org/D7951

Modified:
  head/sys/arm/arm/genassym.c
  head/sys/arm/arm/swtch-v6.S
  head/sys/arm/arm/sys_machdep.c
  head/sys/arm/arm/vm_machdep.c
  head/sys/arm/include/frame.h
  head/sys/arm/include/pcpu.h
  head/sys/arm/include/proc.h

Modified: head/sys/arm/arm/genassym.c
==
--- head/sys/arm/arm/genassym.c Thu Sep 22 07:55:07 2016(r306161)
+++ head/sys/arm/arm/genassym.c Thu Sep 22 08:14:59 2016(r306162)
@@ -81,6 +81,9 @@ ASSYM(PCB_R12, offsetof(struct pcb, pcb_
 ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp));
 ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr));
 ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc));
+#if __ARM_ARCH >= 6
+ASSYM(PCB_TPIDRURW, offsetof(struct pcb, pcb_regs.sf_tpidrurw));
+#endif
 
 ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
 ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
@@ -100,8 +103,8 @@ ASSYM(TD_FLAGS, offsetof(struct thread, 
 ASSYM(TD_PROC, offsetof(struct thread, td_proc));
 ASSYM(TD_MD, offsetof(struct thread, td_md));
 ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
-ASSYM(MD_TP, offsetof(struct mdthread, md_tp));
 #if __ARM_ARCH < 6
+ASSYM(MD_TP, offsetof(struct mdthread, md_tp));
 ASSYM(MD_RAS_START, offsetof(struct mdthread, md_ras_start));
 ASSYM(MD_RAS_END, offsetof(struct mdthread, md_ras_end));
 #endif

Modified: head/sys/arm/arm/swtch-v6.S
==
--- head/sys/arm/arm/swtch-v6.S Thu Sep 22 07:55:07 2016(r306161)
+++ head/sys/arm/arm/swtch-v6.S Thu Sep 22 08:14:59 2016(r306162)
@@ -291,6 +291,8 @@ ENTRY(cpu_switch)
ldr r3, [r0, #(TD_PCB)]
add r3, #(PCB_R4)
stmia   r3, {r4-r12, sp, lr, pc}
+   mrc CP15_TPIDRURW(r4)
+   str r4, [r3, #(PCB_TPIDRURW - PCB_R4)]
 
 #ifdef INVARIANTS
cmp r1, #0  /* new thread? */
@@ -437,9 +439,6 @@ sw1:
cmp r3, r6
beq 1b
 #endif
-   /* Set the new tls */
-   ldr r0, [r11, #(TD_MD + MD_TP)]
-   mcr CP15_TPIDRURO(r0)   /* write tls thread reg 2 */
 
/* We have a new curthread now so make a note it */
str r11, [r8, #PC_CURTHREAD]
@@ -452,7 +451,14 @@ sw1:
 * Restore all saved registers and return. Note that some saved
 * registers can be changed when either cpu_fork(), cpu_copy_thread(),
 * cpu_fork_kthread_handler(), or makectx() was called.
-*/
+*
+* The value of TPIDRURW is also written into TPIDRURO, as
+* userspace still uses TPIDRURO, modifying it through
+* sysarch(ARM_SET_TP, addr).
+*/
+   ldr r3, [r7, #PCB_TPIDRURW]
+   mcr CP15_TPIDRURW(r3)   /* write tls thread reg 2 */
+   mcr CP15_TPIDRURO(r3)   /* write tls thread reg 3 */
add r3, r7, #PCB_R4
ldmia   r3, {r4-r12, sp, pc}
 

Modified: head/sys/arm/arm/sys_machdep.c
==
--- head/sys/arm/arm/sys_machdep.c  Thu Sep 22 07:55:07 2016
(r306161)
+++ head/sys/arm/arm/sys_machdep.c  Thu Sep 22 08:14:59 2016
(r306162)
@@ -166,10 +166,10 @@ static int
 arm32_set_tp(struct thread *td, void *args)
 {
 
-   td->td_md.md_tp = (register_t)args;
 #if __ARM_ARCH >= 6
set_tls(args);
 #else
+   td->td_md.md_tp = (register_t)args;
*(register_t *)ARM_TP_ADDRESS = (register_t)args;
 #endif
return (0);
@@ -180,7 +180,7 @@ arm32_get_tp(struct thread *td, void *ar
 {
 
 #if __ARM_ARCH >= 6
-   td->td_retval[0] = td->td_md.md_tp;
+   td->td_retval[0] = (register_t)get_tls();
 #else
td->td_retval[0] = *(register_t