From 498eaee461adefd5e578e62c134382ece94198da Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Wed, 13 Nov 2019 15:05:17 -0500 Subject: [PATCH] cmd/internal/obj/x86: mark 2-instruction TLS access nonpreemptible The 2-instruction TLS access sequence MOVQ TLS, BX MOVQ 0(BX)(TLS*1), BX is not async preemptible, as if it is preempted and resumed on a different thread, the TLS address may become invalid. May fix #35349. (This is a rare failure and I haven't been able to reproduce it.) Change-Id: Ie1a366fd0d7d73627dc62ee2de01c0aa09365f2b Reviewed-on: https://go-review.googlesource.com/c/go/+/206903 Run-TryBot: Cherry Zhang Reviewed-by: Austin Clements --- src/cmd/internal/obj/x86/asm6.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index 3a33bc3c3cc83..cfeb179a86399 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -1984,6 +1984,22 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) { fmt.Printf(" rel %#.4x/%d %s%+d\n", uint32(r.Off), r.Siz, r.Sym.Name, r.Add) } } + + // Mark nonpreemptible instruction sequences. + // The 2-instruction TLS access sequence + // MOVQ TLS, BX + // MOVQ 0(BX)(TLS*1), BX + // is not async preemptible, as if it is preempted and resumed on + // a different thread, the TLS address may become invalid. + if !CanUse1InsnTLS(ctxt) { + useTLS := func(p *obj.Prog) bool { + // Only need to mark the second instruction, which has + // REG_TLS as Index. (It is okay to interrupt and restart + // the first instruction.) + return p.From.Index == REG_TLS + } + obj.MarkUnsafePoints(ctxt, s.Func.Text, newprog, useTLS) + } } func instinit(ctxt *obj.Link) {