Allocate the new stack early, so that error reporting need
not clean up other objects.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@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