Added function to iret from exit() syscall
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
target remote localhost:1234
|
||||
layout regs
|
||||
symbol-file build/sys/amd64/kernel.elf
|
||||
+27
-39
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user