Added function to iret from exit() syscall

This commit is contained in:
Mark
2019-10-30 11:03:46 +02:00
parent 1a334aaafb
commit d6e0451abf
4 changed files with 73 additions and 48 deletions
+3
View File
@@ -0,0 +1,3 @@
target remote localhost:1234
layout regs
symbol-file build/sys/amd64/kernel.elf
+27 -39
View File
@@ -201,51 +201,39 @@ void sched_init(void) {
sched_add_to(0, &t_init);
}
void sched_remove_from(int cpu, struct thread *thr) {
struct thread *prev = thr->prev;
struct thread *next = thr->next;
kdebug("cpu%d: removing thread %d\n", cpu, thr->pid);
_assert(prev);
prev->next = next;
if (next) {
next->prev = prev;
} else {
sched_queue_tails[cpu] = prev;
}
--sched_queue_sizes[cpu];
thr->next = NULL;
thr->prev = NULL;
// TODO: make other cpus schedule a new thread if they're running a stopped one
}
void sched_remove(struct thread *thr) {
kdebug("Remove %p\n", thr);
sched_remove_from(thr->cpu, thr);
}
int sched(void) {
struct thread *from = get_cpu()->thread;
struct thread *to;
int cpu = get_cpu()->processor_id;
uintptr_t flags;
// Cleanup stopped tasks
// TODO: this won't be needed if I call sched_remove directly
to = sched_queue_heads[cpu];
while (to) {
if (to->flags & THREAD_STOPPED) {
// So we don't remove [idle]
_assert(to != sched_queue_heads[cpu]);
kdebug("(cpu%d) Removing %u from queue\n", cpu, to->pid);
if (to->pid == 1) {
panic("init process was killed\n");
}
struct thread *prev, *next;
prev = to->prev;
next = to->next;
_assert(prev);
prev->next = next;
if (next) {
next->prev = prev;
} else {
sched_queue_tails[cpu] = prev;
}
// TODO: free the task?
if (to == from) {
// Removing current thread
from = NULL;
}
if (!next) {
break;
}
}
to = to->next;
}
if (from && from->next) {
to = from->next;
} else {
+3 -7
View File
@@ -14,7 +14,7 @@ static void sys_close(int fd);
static int sys_stat(const char *filename, struct stat *st);
static void sys_exit(int status);
uint8_t irq1_key = 0;
__attribute__((noreturn)) void amd64_syscall_yield_stopped(void);
intptr_t amd64_syscall(uintptr_t rdi, uintptr_t rsi, uintptr_t rdx, uintptr_t rcx, uintptr_t r10, uintptr_t rax) {
switch (rax) {
@@ -32,12 +32,8 @@ intptr_t amd64_syscall(uintptr_t rdi, uintptr_t rsi, uintptr_t rdx, uintptr_t rc
case SYSCALL_NR_EXIT:
sys_exit((int) rdi);
// TODO: call sched_remove and reschedule a new task so that
// this one does not return
asm volatile ("sti; hlt");
panic("This should not happen\n");
// WTF?
return -1;
amd64_syscall_yield_stopped();
default:
kdebug("unknown syscall: %u\n", rax);
return -1;
+40 -2
View File
@@ -1,7 +1,9 @@
#include "sys/amd64/asm/asm_cpu.h"
#include "sys/amd64/asm/asm_irq.h"
.section .text
.global amd64_syscall_init
.global amd64_syscall_yield_stopped
#define MSR_STAR 0xC0000081
#define MSR_LSTAR 0xC0000082
@@ -104,5 +106,41 @@ amd64_syscall_entry:
swapgs
sysretq
_fmt0:
.string "rsp = %p\n"
// Schedule control to a new task instead of stopped one
amd64_syscall_yield_stopped:
cli
// No stack frame - the kernel stack is going to be discarded anyways
movq get_cpu(0x08), %rbx
call sched
test %rax, %rax
jz 1f
// sched() failed
leaq _yield_failed(%rip), %rdi
xorq %rax, %rax
call panicf
1:
// Remove old thread from queues
movq %rbx, %rdi
call sched_remove
// Load a new context
// rsi = thread structure pointer
movq get_cpu(0x08), %rsi
movq 0(%rsi), %rsp
// Write TSS entry
movq get_cpu(0x18), %rdi
movq %rsp, %rax
addq $(25 * 8), %rax
movq %rax, 4(%rdi)
1:
// Assume we're now on TASK2's stack
irq_pop_ctx
iretq
_yield_failed:
.string "sched() returned -1 on amd64_syscall_yield\n"