From f5becf4233bd12506cbfcb9cbc04b5968ac11ae0 Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Mon, 3 Jun 2013 12:28:24 +0400 Subject: [PATCH] runtime: add stackguard0 to G This is part of preemptive scheduler. stackguard0 is checked in split stack checks and can be set to StackPreempt. stackguard is not set to StackPreempt (holds the original value). R=golang-dev, daniel.morsing, iant CC=golang-dev https://golang.org/cl/9875043 --- src/pkg/runtime/asm_386.s | 5 +++++ src/pkg/runtime/asm_amd64.s | 5 +++++ src/pkg/runtime/asm_arm.s | 4 ++++ src/pkg/runtime/panic.c | 1 + src/pkg/runtime/proc.c | 4 ++++ src/pkg/runtime/runtime.h | 4 +++- src/pkg/runtime/stack.c | 2 ++ 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index 58fa6d69ac..85b500807e 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s @@ -18,6 +18,7 @@ TEXT _rt0_386(SB),7,$0 MOVL $runtime·g0(SB), BP LEAL (-64*1024+104)(SP), BX MOVL BX, g_stackguard(BP) + MOVL BX, g_stackguard0(BP) MOVL SP, g_stackbase(BP) // find out information about the processor we're on @@ -41,6 +42,10 @@ nocpuinfo: MOVL BX, 4(SP) MOVL BP, 0(SP) CALL AX + // update stackguard after _cgo_init + MOVL $runtime·g0(SB), CX + MOVL g_stackguard0(CX), AX + MOVL AX, g_stackguard(CX) // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows CMPL runtime·iswindows(SB), $0 JEQ ok diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index f779b94517..af83c0393c 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.s @@ -18,6 +18,7 @@ TEXT _rt0_amd64(SB),7,$-8 MOVQ $runtime·g0(SB), DI LEAQ (-64*1024+104)(SP), BX MOVQ BX, g_stackguard(DI) + MOVQ BX, g_stackguard0(DI) MOVQ SP, g_stackbase(DI) // find out information about the processor we're on @@ -39,6 +40,10 @@ nocpuinfo: MOVQ DI, CX // Win64 uses CX for first parameter MOVQ $setmg_gcc<>(SB), SI CALL AX + // update stackguard after _cgo_init + MOVQ $runtime·g0(SB), CX + MOVQ g_stackguard0(CX), AX + MOVQ AX, g_stackguard(CX) CMPL runtime·iswindows(SB), $0 JEQ ok diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s index fed9b30215..d4bcbd5a91 100644 --- a/src/pkg/runtime/asm_arm.s +++ b/src/pkg/runtime/asm_arm.s @@ -28,6 +28,7 @@ TEXT _rt0_arm(SB),7,$-4 // create istack out of the OS stack MOVW $(-8192+104)(R13), R0 MOVW R0, g_stackguard(g) // (w 104b guard) + MOVW R0, g_stackguard0(g) MOVW R13, g_stackbase(g) BL runtime·emptyfunc(SB) // fault if stack check is wrong @@ -36,6 +37,9 @@ TEXT _rt0_arm(SB),7,$-4 CMP $0, R2 MOVW.NE g, R0 // first argument of _cgo_init is g BL.NE (R2) // will clobber R0-R3 + // update stackguard after _cgo_init + MOVW g_stackguard0(g), R0 + MOVW R0, g_stackguard(g) BL runtime·checkgoarm(SB) BL runtime·check(SB) diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c index ecce93ff16..18e4779540 100644 --- a/src/pkg/runtime/panic.c +++ b/src/pkg/runtime/panic.c @@ -298,6 +298,7 @@ runtime·unwindstack(G *gp, byte *sp) break; gp->stackbase = (uintptr)top->stackbase; gp->stackguard = (uintptr)top->stackguard; + gp->stackguard0 = gp->stackguard; if(top->free != 0) runtime·stackfree(stk, top->free); } diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index c7a8d24182..206a3cba19 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -468,6 +468,7 @@ runtime·mstart(void) // so other calls can reuse this stack space. runtime·gosave(&m->g0->sched); m->g0->sched.pc = (void*)-1; // make sure it is never used + m->g0->stackguard = m->g0->stackguard0; // cgo sets only stackguard0, copy it to stackguard m->seh = &seh; runtime·asminit(); runtime·minit(); @@ -615,6 +616,7 @@ runtime·needm(byte x) runtime·setmg(mp, mp->g0); g->stackbase = (uintptr)(&x + 1024); g->stackguard = (uintptr)(&x - 32*1024); + g->stackguard0 = g->stackguard; // On windows/386, we need to put an SEH frame (two words) // somewhere on the current stack. We are called @@ -979,6 +981,7 @@ execute(G *gp) runtime·throw("execute: bad g status"); } gp->status = Grunning; + gp->stackguard0 = gp->stackguard; m->p->tick++; m->curg = gp; gp->m = m; @@ -1465,6 +1468,7 @@ runtime·malg(int32 stacksize) } newg->stack0 = (uintptr)stk; newg->stackguard = (uintptr)stk + StackGuard; + newg->stackguard0 = newg->stackguard; newg->stackbase = (uintptr)stk + StackSystem + stacksize - sizeof(Stktop); runtime·memclr((byte*)newg->stackbase, sizeof(Stktop)); } diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 2d918f4cff..e616990ccf 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -226,7 +226,8 @@ struct GCStats }; struct G { - uintptr stackguard; // cannot move - also known to linker, libmach, runtime/cgo + // stackguard0 can be set to StackPreempt as opposed to stackguard + uintptr stackguard0; // cannot move - also known to linker, libmach, runtime/cgo uintptr stackbase; // cannot move - also known to libmach, runtime/cgo Defer* defer; Panic* panic; @@ -235,6 +236,7 @@ struct G uintptr gcsp; // if status==Gsyscall, gcsp = sched.sp to use during gc byte* gcpc; // if status==Gsyscall, gcpc = sched.pc to use during gc uintptr gcguard; // if status==Gsyscall, gcguard = stackguard to use during gc + uintptr stackguard; // same as stackguard0, but not set to StackPreempt uintptr stack0; FuncVal* fnstart; // initial function G* alllink; // on allg diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c index b6f64aa766..a033d6b012 100644 --- a/src/pkg/runtime/stack.c +++ b/src/pkg/runtime/stack.c @@ -157,6 +157,7 @@ runtime·oldstack(void) label = top->gobuf; gp->stackbase = (uintptr)top->stackbase; gp->stackguard = (uintptr)top->stackguard; + gp->stackguard0 = gp->stackguard; if(top->free != 0) runtime·stackfree(old, top->free); @@ -249,6 +250,7 @@ runtime·newstack(void) gp->stackbase = (uintptr)top; gp->stackguard = (uintptr)stk + StackGuard; + gp->stackguard0 = gp->stackguard; sp = (byte*)top; if(argsize > 0) { -- 2.48.1