From 44195fd034ccf731f1d24addfb544732baed2b95 Mon Sep 17 00:00:00 2001 From: Ali Mashtizadeh Date: Sat, 29 Nov 2014 15:46:17 -0800 Subject: [PATCH] Fix TSS kernel stack pointer switching --- bin/shell/shell.c | 3 ++- include/syscall.h | 3 +++ lib/libc/syscall.c | 6 ++++++ sbin/init/init.c | 4 +--- sys/amd64/machine.c | 2 +- sys/amd64/thread.c | 7 +++++++ sys/kern/loader.c | 2 ++ sys/kern/syscall.c | 15 +++++++++++++-- sys/kern/thread.c | 16 ++++++++++++++-- 9 files changed, 49 insertions(+), 9 deletions(-) diff --git a/bin/shell/shell.c b/bin/shell/shell.c index 9475cef..f3a9014 100644 --- a/bin/shell/shell.c +++ b/bin/shell/shell.c @@ -4,12 +4,13 @@ int main(int argc, const char *argv[]) { + int i; char buf[256]; fputs("Shell\n", stdout); while (1) { fputs("> ", stdout); - fgets(buf, sizeof(buf), stdin); + //fgets(buf, sizeof(buf), stdin); } } diff --git a/include/syscall.h b/include/syscall.h index a2e636d..30c0e24 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -19,5 +19,8 @@ int SystemFlush(uint64_t fd); uint64_t SystemOpen(const char *path, uint64_t flags); int SystemClose(uint64_t fd); +// Threads +int SystemThreadSleep(uint64_t time); + #endif /* __SYSCALL_H__ */ diff --git a/lib/libc/syscall.c b/lib/libc/syscall.c index 09dce04..e99742d 100644 --- a/lib/libc/syscall.c +++ b/lib/libc/syscall.c @@ -79,3 +79,9 @@ SystemClose(uint64_t fd) return syscall(SYSCALL_CLOSE, fd); } +int +SystemThreadSleep(uint64_t time) +{ + return syscall(SYSCALL_THREADSLEEP, time); +} + diff --git a/sbin/init/init.c b/sbin/init/init.c index 7db436b..16bced4 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -8,10 +8,8 @@ main(int argc, const char *argv[]) SystemSpawn("/bin/shell"); - //while (1) { } - while (1) { - asm volatile("int3"); + SystemThreadSleep(0); } } diff --git a/sys/amd64/machine.c b/sys/amd64/machine.c index 2819918..de96092 100644 --- a/sys/amd64/machine.c +++ b/sys/amd64/machine.c @@ -34,7 +34,7 @@ extern void Loader_LoadInit(); static SegmentDescriptor GDT[MAX_CPUS][GDT_MAX]; static PseudoDescriptor GDTDescriptor[MAX_CPUS]; -static TaskStateSegment64 TSS[MAX_CPUS]; +TaskStateSegment64 TSS[MAX_CPUS]; static char df_stack[4096]; diff --git a/sys/amd64/thread.c b/sys/amd64/thread.c index 640fdaa..d1d1dd4 100644 --- a/sys/amd64/thread.c +++ b/sys/amd64/thread.c @@ -3,8 +3,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -48,6 +50,8 @@ Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg) tf->rflags = RFLAGS_IF; } +extern TaskStateSegment64 TSS[MAX_CPUS]; + void Thread_SwitchArch(Thread *oldthr, Thread *newthr) { @@ -63,5 +67,8 @@ Thread_SwitchArch(Thread *oldthr, Thread *newthr) // Jump to trapframe switchstack(&oldthr->arch.rsp, newthr->arch.rsp); + + // Set new RSP0 + TSS[CPU()].rsp0 = oldthr->kstack + 4096; } diff --git a/sys/kern/loader.c b/sys/kern/loader.c index 78c7c82..ffacbd9 100644 --- a/sys/kern/loader.c +++ b/sys/kern/loader.c @@ -147,6 +147,7 @@ void Loader_EnterUserLevel(void *arg) { TrapFrame tf; + memset(&tf, 0, sizeof(tf)); tf.ds = SEL_UDS | 3; tf.rip = (uint64_t)arg; @@ -154,6 +155,7 @@ Loader_EnterUserLevel(void *arg) tf.rsp = 0x70000000 + PGSIZE; tf.ss = SEL_UDS | 3; tf.rflags = RFLAGS_IF; + Trap_Pop(&tf); } diff --git a/sys/kern/syscall.c b/sys/kern/syscall.c index 92d1ae4..dc08bda 100644 --- a/sys/kern/syscall.c +++ b/sys/kern/syscall.c @@ -86,11 +86,11 @@ Syscall_Spawn(uint64_t user_path) handle = Console_OpenHandle(); Handle_Add(thr, handle); - //Loader_Load(thr, file, pg, 1024); + Loader_Load(thr, file, pg, 1024); VFS_Close(file); - //Thread_SetRunnable(thr); + Thread_SetRunnable(thr); return 0; } @@ -216,6 +216,15 @@ Syscall_Close(uint64_t fd) return (handle->close)(handle); } +uint64_t +Syscall_ThreadSleep(uint64_t time) +{ + // XXX: Support sleeping + Thread_Scheduler(); + + return 0; +} + uint64_t Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) @@ -249,6 +258,8 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2, return Syscall_Open(a1, a2); case SYSCALL_CLOSE: return Syscall_Close(a1); + case SYSCALL_THREADSLEEP: + return Syscall_ThreadSleep(a1); default: return (uint64_t)-1; } diff --git a/sys/kern/thread.c b/sys/kern/thread.c index 6fbc43d..841b1fe 100644 --- a/sys/kern/thread.c +++ b/sys/kern/thread.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -161,9 +162,13 @@ Thread_Scheduler() Spinlock_Unlock(&threadLock); } +extern TaskStateSegment64 TSS[MAX_CPUS]; + void ThreadKThreadEntry(TrapFrame *tf) { + TSS[CPU()].rsp0 = curProc->kstack + 4096; + Spinlock_Unlock(&threadLock); Trap_Pop(tf); @@ -174,7 +179,7 @@ Debug_Threads(int argc, const char *argv[]) { Thread *thr; - Spinlock_Lock(&threadLock); + //Spinlock_Lock(&threadLock); kprintf("Current: %016llx %d\n", curProc, curProc->ctxSwitches); TAILQ_FOREACH(thr, &threadQueue, schedQueue) @@ -182,8 +187,15 @@ Debug_Threads(int argc, const char *argv[]) kprintf("Thread: %016llx %d\n", thr, thr->ctxSwitches); } - Spinlock_Unlock(&threadLock); + //Spinlock_Unlock(&threadLock); } REGISTER_DBGCMD(threads, "Display list of threads", Debug_Threads); +void +Debug_ThreadInfo(int argc, const char *argv[]) +{ +} + +REGISTER_DBGCMD(threadinfo, "Display thread state", Debug_ThreadInfo); +