|
From: Kirill B. <bat...@is...> - 2010-02-01 17:17:18
Attachments:
vg-arm-set-tls.patch
|
Hi all, while trying to make Valgrind runnable on v5 and v6 ARM processors I've encountered bug in set_tls handling which I do not know how to fix properly. TLS value may be stored in CP15's register or at address 0xffff0ff0. The second case is handled incorrectly by Valgrind since revision r10973 in branches/ARM lately merged into trunk ( http://sourceforge.net/mailarchive/message.php?msg_name=20091229170034.6CD73108845%40jail0086.vps.exonetric.net ). Here is this syscall's code from 2.6 kernel. arch/arm/kernel/traps.c: case NR(set_tls): thread->tp_value = regs->ARM_r0; #if defined(CONFIG_HAS_TLS_REG) asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); #elif !defined(CONFIG_TLS_REG_EMUL) /* * User space must never try to access this directly. * Expect your app to break eventually if you do so. * The user helper at 0xffff0fe0 must be used instead. * (see entry-armv.S for details) */ *((unsigned int *)0xffff0ff0) = regs->ARM_r0; #endif return 0; And in arch/arm/kernel/entry-armv.S: __kuser_get_tls: @ 0xffff0fe0 #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 #else mrc p15, 0, r0, c13, c0, 3 @ read TLS register #endif usr_ret lr The reason of incorrect behavior is that set_tls syscall is never passed to the kernel. It is handled by Valgrind internally. As a result memory at address 0xffff0ff0 is not being written, ldr r0, [pc, #(16 - 8)] reads incorrect value and program crashes when it tries to dereference obtained pointer. Since writing blindly to 0xffff0ff0 does not seem to be a good idea this bug can be fixed by passing set_tls syscall to kernel. I created a small patch doing this but I'm not sure about two things: 1. Should Valrgind be told about possible memory write in PRE wrapper for set_tls? 2. TLS can be also set in clone syscall. It is not passed to kernel either as I understood. Should set_tls syscall be passed to kernel from do_clone function in this case? Or is there a better way of setting TLS in this case? Currently none of these 2 things are done. As a result, pth_cancel1 and pth_cancel2 from Nullgrind's regression tests hung. Can anybody help me to deal with these two problems? Thanks, Kirill. |