Allocate the new stack early, so that error reporting need not clean up other objects.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- linux-user/syscall.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 2f1e881046..91210775ed 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6652,6 +6652,21 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, ts = g_new0(TaskState, 1); init_task_state(ts); +#ifdef TARGET_AARCH64 + /* + * If GCS is enabled in the parent thread, it is also enabled + * in the child thread, but with a newly allocated stack. + */ + abi_long new_gcspr = 0; + if (env->cp15.gcscr_el[0] & GCSCR_PCRSEL) { + new_gcspr = gcs_new_stack(ts); + if (new_gcspr == -1) { + g_free(ts); + return -TARGET_ENOMEM; + } + } +#endif + /* Grab a mutex so that thread setup appears atomic. */ pthread_mutex_lock(&clone_lock); @@ -6676,6 +6691,11 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, ts->info = parent_ts->info; ts->signal_mask = parent_ts->signal_mask; +#ifdef TARGET_AARCH64 + ts->gcs_el0_locked = parent_ts->gcs_el0_locked; + new_env->cp15.gcspr_el[0] = new_gcspr; +#endif + if (flags & CLONE_CHILD_CLEARTID) { ts->child_tidptr = child_tidptr; } -- 2.43.0