aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/stack.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-09-03 17:42:35 -0400
committerRuss Cox <rsc@golang.org>2014-09-03 17:42:35 -0400
commit5ea69978fd07abdd4bb5ed63dfb38700389493c6 (patch)
treedef2af33e055771de9bb4ac3d1ffa39d0696cd25 /src/pkg/runtime/stack.c
parentf82097f5cf8a84b89fd8b9cc056f2854c1115c3c (diff)
downloadgo-5ea69978fd07abdd4bb5ed63dfb38700389493c6.tar.xz
runtime: make entersyscall/exitsyscall safe for stack splits
It is fundamentally unsafe to grow the stack once someone has made a call to syscall.Syscall. That function takes 6 uintptr arguments, but depending on the call some are pointers. In fact, some might be pointers to stack values, and we don't know which. That makes it impossible to copy the stack somewhere else. Since we want to delete all the stack splitting code, relying only on stack copying, make sure that Syscall never needs to split the stack. The only thing Syscall does is: call entersyscall make the system call call exitsyscall As long as we make sure that entersyscall and exitsyscall can live in the nosplit region, they won't ask for more stack. Do this by making entersyscall and exitsyscall set up the stack guard so that any call to a function with a split check will cause a crash. Then move non-essential slow-path work onto the m stack using onM and mark the rest of the work nosplit. The linker will verify that the chain of nosplits fits in the total nosplit budget. LGTM=iant R=golang-codereviews, iant CC=dvyukov, golang-codereviews, khr, r https://golang.org/cl/140950043
Diffstat (limited to 'src/pkg/runtime/stack.c')
-rw-r--r--src/pkg/runtime/stack.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c
index 6a57ab08cf..8456f79369 100644
--- a/src/pkg/runtime/stack.c
+++ b/src/pkg/runtime/stack.c
@@ -876,6 +876,8 @@ runtime·newstack(void)
g->m->morebuf.g, g->m, g->m->curg, g->m->g0, g->m->gsignal);
runtime·throw("runtime: wrong goroutine in newstack");
}
+ if(g->throwsplit)
+ runtime·throw("runtime: stack split at bad time");
// The goroutine must be executing in order to call newstack, so the possible states are
// Grunning and Gsyscall (and, due to GC, also Gscanrunning and Gscansyscall).