From 607efa961f3ba6663def9aef20d80735ba479ea1 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 30 Apr 2026 19:08:02 +0100 Subject: [PATCH] sched: task: implement task_config_get and task_config_set --- include/kernel/task.h | 10 ++++++ sched/task.c | 34 ++++++++++++++++++ syscall/dispatch.c | 2 ++ syscall/task.c | 83 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) diff --git a/include/kernel/task.h b/include/kernel/task.h index 7d6283f..d1882b1 100644 --- a/include/kernel/task.h +++ b/include/kernel/task.h @@ -70,6 +70,16 @@ extern kern_status_t task_resolve_handle( kern_handle_t handle, struct object **out_obj, handle_flags_t *out_flags); +extern kern_status_t task_config_get( + struct task *task, + kern_config_key_t key, + void *out, + size_t max); +extern kern_status_t task_config_set( + struct task *task, + kern_config_key_t key, + const void *ptr, + size_t len); extern kern_status_t task_close_handle(struct task *task, kern_handle_t handle); extern struct thread *task_create_thread(struct task *parent); extern struct task *kernel_task(void); diff --git a/sched/task.c b/sched/task.c index 54064f2..a9f148f 100644 --- a/sched/task.c +++ b/sched/task.c @@ -297,6 +297,40 @@ struct task *task_from_tid(tid_t id) return t; } +kern_status_t task_config_get( + struct task *task, + kern_config_key_t key, + void *out, + size_t max) +{ + switch (key) { + case TASK_CFG_ID: { + if (max != sizeof(tid_t)) { + return KERN_INVALID_ARGUMENT; + } + + tid_t *value = out; + *value = task->t_id; + return KERN_OK; + } + + default: + return KERN_INVALID_ARGUMENT; + } +} + +kern_status_t task_config_set( + struct task *task, + kern_config_key_t key, + const void *ptr, + size_t len) +{ + switch (key) { + default: + return KERN_INVALID_ARGUMENT; + } +} + void task_exit(int status) { struct task *self = get_current_task(); diff --git a/syscall/dispatch.c b/syscall/dispatch.c index 6261c5e..9044400 100644 --- a/syscall/dispatch.c +++ b/syscall/dispatch.c @@ -11,6 +11,8 @@ static const virt_addr_t syscall_table[] = { SYSCALL_TABLE_ENTRY(TASK_CREATE_THREAD, task_create_thread), SYSCALL_TABLE_ENTRY(TASK_GET_ADDRESS_SPACE, task_get_address_space), SYSCALL_TABLE_ENTRY(TASK_DUPLICATE, task_duplicate), + SYSCALL_TABLE_ENTRY(TASK_CONFIG_GET, task_config_get), + SYSCALL_TABLE_ENTRY(TASK_CONFIG_SET, task_config_set), SYSCALL_TABLE_ENTRY(THREAD_SELF, thread_self), SYSCALL_TABLE_ENTRY(THREAD_START, thread_start), SYSCALL_TABLE_ENTRY(THREAD_EXIT, thread_exit), diff --git a/syscall/task.c b/syscall/task.c index 90fbc9d..c9ef091 100644 --- a/syscall/task.c +++ b/syscall/task.c @@ -292,6 +292,89 @@ kern_status_t sys_task_get_address_space( return KERN_OK; } +kern_status_t sys_task_config_get( + kern_handle_t task_handle, + kern_config_key_t key, + void *ptr, + size_t len) +{ + unsigned long flags; + struct task *self = get_current_task(); + + if (!validate_access_w(self, ptr, len)) { + put_current_task(self); + return KERN_MEMORY_FAULT; + } + + struct object *task_obj; + handle_flags_t task_flags; + task_lock_irqsave(self, &flags); + kern_status_t status = task_resolve_handle( + self, + task_handle, + &task_obj, + &task_flags); + put_current_task(self); + task_unlock_irqrestore(self, flags); + + if (status != KERN_OK) { + return status; + } + + struct task *task = task_cast(task_obj); + task_unlock_irqrestore(self, flags); + + if (task) { + status = task_config_get(task, key, ptr, len); + } else { + status = KERN_INVALID_ARGUMENT; + } + + object_unref(task_obj); + + return status; +} + +kern_status_t sys_task_config_set( + kern_handle_t task_handle, + kern_config_key_t key, + const void *ptr, + size_t len) +{ + unsigned long flags; + struct task *self = get_current_task(); + + if (!validate_access_w(self, ptr, len)) { + put_current_task(self); + return KERN_MEMORY_FAULT; + } + + struct object *task_obj; + handle_flags_t task_flags; + task_lock_irqsave(self, &flags); + kern_status_t status = task_resolve_handle( + self, + task_handle, + &task_obj, + &task_flags); + task_unlock_irqrestore(self, flags); + put_current_task(self); + if (status != KERN_OK) { + return status; + } + + struct task *task = task_cast(task_obj); + if (task) { + status = task_config_set(task, key, ptr, len); + } else { + status = KERN_INVALID_ARGUMENT; + } + + object_unref(task_obj); + + return status; +} + kern_status_t sys_thread_self(kern_handle_t *out) { struct task *self = get_current_task();