From: Matthias Kruk Date: Wed, 25 Sep 2019 13:46:09 +0000 (+0900) Subject: Add privilege level information to processes and tasks X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=79cd88869e61f72179aa2e24512fc919abab56cd;p=corax Add privilege level information to processes and tasks --- diff --git a/kernel/arch/process.c b/kernel/arch/process.c index 552abbc..f3716a1 100644 --- a/kernel/arch/process.c +++ b/kernel/arch/process.c @@ -8,7 +8,8 @@ struct process { struct pagedir *p_pgdir; - struct task *p_tasks; + struct task *p_tasks; + u32_t p_privl; }; void foo(void) @@ -20,7 +21,7 @@ void foo(void) extern int _pg_dir_vpxlate(pg_dir_t*, u32_t, u32_t*); -int process_create(process_t **dst) +int process_create(process_t **dst, u32_t ppl) { int ret_val; process_t *proc; @@ -50,8 +51,10 @@ int process_create(process_t **dst) goto cleanup; } + proc->p_privl = ppl; + task_prepare(proc->p_tasks, (u32_t)pdbr, (u32_t)foo, - (u32_t)kstack, (u32_t)ustack + PAGE_SIZE, 3); + (u32_t)kstack, (u32_t)ustack + PAGE_SIZE, ppl); proc->p_tasks->t_sp = (u32_t)(CONFIG_KERNEL_STACK_BASE + ((u32_t)proc->p_tasks->t_sp - (u32_t)kstack)); diff --git a/kernel/arch/task.S b/kernel/arch/task.S index b78b2af..f69c1bf 100644 --- a/kernel/arch/task.S +++ b/kernel/arch/task.S @@ -27,6 +27,7 @@ #define OFFSET_ESP0 0 #define OFFSET_CR3 4 #define OFFSET_KSTACK 8 +#define OFFSET_PRIVL 12 .extern _cpu @@ -52,6 +53,10 @@ task_prepare: movl 8(%esp), %eax movl %eax, OFFSET_CR3(%edi) + /* store privilege level in task structure */ + movl 24(%esp), %eax + movl %eax, OFFSET_PRIVL(%edi) + /* calculate stack start (since it grows down) */ movl 16(%esp), %eax addl $CONFIG_KERNEL_STACK_SIZE, %eax @@ -168,18 +173,24 @@ task_switch: movl %ecx, CPU_ESP0(%eax) movl $KERNEL_DATA, CPU_SS0(%eax) + /* set CS according to the task's privilege level */ + movl OFFSET_PRIVL(%edi), %ecx + shll $4, %ecx + addl $8, %ecx + orl OFFSET_PRIVL(%edi), %ecx + movl %ecx, CPU_CS(%eax) + /* - * We need to figure out the task's privilege level and - * set the segment registers accordingly + * Set the data segment selectors (this assumes a privilege + * level's DS descriptor follows the CS descriptor) */ - /* - movl $USER_CODE, CPU_CS(%eax) - movl $USER_DATA, CPU_DS(%eax) - movl $USER_DATA, CPU_ES(%eax) - movl $USER_DATA, CPU_FS(%eax) - movl $USER_DATA, CPU_GS(%eax) - movl $USER_DATA, CPU_SS(%eax) - */ + addl $8, %ecx + movl %ecx, CPU_DS(%eax) + movl %ecx, CPU_ES(%eax) + movl %ecx, CPU_FS(%eax) + movl %ecx, CPU_GS(%eax) + movl %ecx, CPU_SS(%eax) + movl OFFSET_CR3(%edi), %ecx /* check if we can avoid writing to cr3, which would clear the TLB */ diff --git a/kernel/include/arch.h b/kernel/include/arch.h index 43064fd..7503a2b 100644 --- a/kernel/include/arch.h +++ b/kernel/include/arch.h @@ -27,6 +27,7 @@ struct task { u32_t t_sp; u32_t t_pgdir; void *t_kstack; + u32_t t_privl; } __attribute__((packed)); int cpu_get_id(void); @@ -35,7 +36,7 @@ u64_t cpu_timestamp(void); u32_t cpu_set_pstate(int pstate); -int process_create(process_t**); +int process_create(process_t**, u32_t); int task_prepare(struct task*, u32_t cr3, u32_t eip, u32_t esp0, u32_t esp, u32_t priv); int task_switch(struct task*);