From 3cc2ba9f9c1510ddbfc8952d6bc87d0749a501ab Mon Sep 17 00:00:00 2001 From: Benjamin Walsh Date: Tue, 8 Nov 2016 15:44:05 -0500 Subject: [PATCH] kernel: add __ASSERT() for thread priorities Verify the thread priorities are within the bounds when starting a new thread and when changing the priority of a thread. Change-Id: I007b3b249e4b80235b6439cbee44cad2f31973bb Signed-off-by: Benjamin Walsh --- arch/arc/core/thread.c | 2 ++ arch/arm/core/thread.c | 2 ++ arch/nios2/core/thread.c | 2 ++ arch/x86/core/thread.c | 2 ++ kernel/unified/include/ksched.h | 18 ++++++++++++++++++ kernel/unified/sched.c | 5 +++++ 6 files changed, 31 insertions(+) diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index 418dbc7a119..fb95ddbf207 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -91,6 +91,8 @@ void _new_thread(char *pStackMem, unsigned stackSize, void *parameter1, void *parameter2, void *parameter3, int priority, unsigned options) { + _ASSERT_VALID_PRIO(priority, pEntry); + char *stackEnd = pStackMem + stackSize; struct init_stack_frame *pInitCtx; diff --git a/arch/arm/core/thread.c b/arch/arm/core/thread.c index bb5957ad837..cf0eec347fc 100644 --- a/arch/arm/core/thread.c +++ b/arch/arm/core/thread.c @@ -87,6 +87,8 @@ void _new_thread(char *pStackMem, unsigned stackSize, void *parameter1, void *parameter2, void *parameter3, int priority, unsigned options) { + _ASSERT_VALID_PRIO(priority, pEntry); + __ASSERT(!((uint32_t)pStackMem & (STACK_ALIGN - 1)), "stack is not aligned properly\n" "%d-byte alignment required\n", STACK_ALIGN); diff --git a/arch/nios2/core/thread.c b/arch/nios2/core/thread.c index 8b99bbb3495..40a2f247697 100644 --- a/arch/nios2/core/thread.c +++ b/arch/nios2/core/thread.c @@ -68,6 +68,8 @@ void _new_thread(char *stack_memory, unsigned stack_size, void *arg1, void *arg2, void *arg3, int priority, unsigned options) { + _ASSERT_VALID_PRIO(priority, thread_func); + struct tcs *tcs; struct init_stack_frame *iframe; diff --git a/arch/x86/core/thread.c b/arch/x86/core/thread.c index 94ea69c5d5f..e8c15d14872 100644 --- a/arch/x86/core/thread.c +++ b/arch/x86/core/thread.c @@ -259,6 +259,8 @@ void _new_thread(char *pStackMem, unsigned stackSize, void *parameter1, void *parameter2, void *parameter3, int priority, unsigned options) { + _ASSERT_VALID_PRIO(priority, pEntry); + unsigned long *pInitialThread; #ifdef CONFIG_INIT_STACKS diff --git a/kernel/unified/include/ksched.h b/kernel/unified/include/ksched.h index e629a739d82..6fadbbee233 100644 --- a/kernel/unified/include/ksched.h +++ b/kernel/unified/include/ksched.h @@ -36,6 +36,24 @@ extern void _move_thread_to_end_of_prio_q(struct k_thread *thread); extern struct k_thread *_get_next_ready_thread(void); extern int __must_switch_threads(void); extern int32_t _ms_to_ticks(int32_t ms); +extern void idle(void *, void *, void *); + +static inline int _is_idle_thread(void *entry_point) +{ + return entry_point == idle; +} + +#define _ASSERT_VALID_PRIO(prio, entry_point) do { \ + __ASSERT(((prio) == K_IDLE_PRIO && _is_idle_thread(entry_point)) || \ + (_is_prio_higher_or_equal((prio), \ + K_LOWEST_APPLICATION_THREAD_PRIO) && \ + _is_prio_lower_or_equal((prio), \ + K_HIGHEST_APPLICATION_THREAD_PRIO)), \ + "invalid priority (%d); allowed range: %d to %d", \ + (prio), \ + K_LOWEST_APPLICATION_THREAD_PRIO, \ + K_HIGHEST_APPLICATION_THREAD_PRIO); \ + } while ((0)) /* * The _is_prio_higher family: I created this because higher priorities are diff --git a/kernel/unified/sched.c b/kernel/unified/sched.c index bad4a9b3908..47c2199df14 100644 --- a/kernel/unified/sched.c +++ b/kernel/unified/sched.c @@ -222,6 +222,11 @@ int k_thread_priority_get(k_tid_t thread) void k_thread_priority_set(k_tid_t tid, int prio) { + /* + * Use NULL, since we cannot know what the entry point is (we do not + * keep track of it) and idle cannot change its priority. + */ + _ASSERT_VALID_PRIO(prio, NULL); __ASSERT(!_is_in_isr(), ""); struct k_thread *thread = (struct k_thread *)tid;