From 40325d2d28f4b255f93c85e2952bae71486fafd0 Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Wed, 9 Nov 2016 07:30:14 -0600 Subject: [PATCH] kernel: Fix bug in spawning of legacy tasks using floating point A thread defined via a legacy MDEF that belongs to the FPU or SSE task group must set the thread option bits for FP or SSE register use prior to being spawned. If this is not done, and the kernel is configured for SSE support, the kernel will auto-enable the thread's use of floating point so that the thread saves SSE register context info even if it belongs to just the FPU task group, which could cause the thread to overflow its stack. Note that this change only increases footprint for x86-based applications that enable floating point register sharing. Change-Id: Idfe4d20bcd7bc42b4cee6ac40ad7987e2a45ccf6 Signed-off-by: Allan Stephens --- kernel/unified/thread.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kernel/unified/thread.c b/kernel/unified/thread.c index d805772db21..15349614f29 100644 --- a/kernel/unified/thread.c +++ b/kernel/unified/thread.c @@ -42,6 +42,25 @@ extern struct _static_thread_data _static_thread_data_list_end[]; thread_data < _static_thread_data_list_end; \ thread_data++) +#ifdef CONFIG_FP_SHARING +static inline void _task_group_adjust(struct _static_thread_data *thread_data) +{ + /* + * set thread options corresponding to legacy FPU and SSE task groups + * so thread spawns properly; EXE and SYS task groups need no adjustment + */ + if (thread_data->init_groups & K_TASK_GROUP_FPU) { + thread_data->init_options |= K_FP_REGS; + } +#ifdef CONFIG_SSE + if (thread_data->init_groups & K_TASK_GROUP_SSE) { + thread_data->init_options |= K_SSE_REGS; + } +#endif /* CONFIG_SSE */ +} +#else +#define _task_group_adjust(thread_data) do { } while (0) +#endif /* CONFIG_FP_SHARING */ /* Legacy API */ @@ -359,6 +378,7 @@ void _init_static_threads(void) unsigned int key; _FOREACH_STATIC_THREAD(thread_data) { + _task_group_adjust(thread_data); _new_thread( thread_data->init_stack, thread_data->init_stack_size,