From 3449b8c566e8ac173d882f0423cb66b579a2eb45 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 25 Apr 2019 17:14:57 -0700 Subject: [PATCH] Implement the fast syscall challenge. --- inc/x86.h | 19 +++++++++++++++++++ kern/init.c | 6 ++++++ kern/trapentry.S | 15 +++++++++++++++ lib/syscall.c | 17 ++++++++++++++++- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/inc/x86.h b/inc/x86.h index cc15ff4..bb6891d 100644 --- a/inc/x86.h +++ b/inc/x86.h @@ -3,6 +3,10 @@ #include +#define MSR_IA32_SYSENTER_CS 0x174 +#define MSR_IA32_SYSENTER_EIP 0x176 +#define MSR_IA32_SYSENTER_ESP 0x175 + static inline void breakpoint(void) { @@ -261,4 +265,19 @@ xchg(volatile uint32_t *addr, uint32_t newval) return result; } +static inline void +write_msr(uint32_t reg, uint32_t low, uint32_t high) { + asm volatile("wrmsr\n\t" + :: "c" (reg), "a" (low), "d" (high)); +} + +static inline void +read_msr(uint32_t reg, uint32_t* low, uint32_t* high) { + uint32_t eax, edx; + asm volatile("rdmsr\n\t" + : "=a" (eax), "=d" (edx) : "c" (reg)); + *low = eax; + *high = edx; +} + #endif /* !JOS_INC_X86_H */ diff --git a/kern/init.c b/kern/init.c index b524643..0bdc695 100644 --- a/kern/init.c +++ b/kern/init.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -11,6 +12,7 @@ #include #include +void sysenter_handler(); void i386_init(void) @@ -34,6 +36,10 @@ i386_init(void) "\33[34m" "r" "\33[0m" " Works!" "\n"); + write_msr(MSR_IA32_SYSENTER_EIP, (uint32_t) sysenter_handler, 0); + write_msr(MSR_IA32_SYSENTER_ESP, KSTACKTOP, 0); + write_msr(MSR_IA32_SYSENTER_CS, GD_KT, 0); + // Lab 2 memory management initialization functions mem_init(); diff --git a/kern/trapentry.S b/kern/trapentry.S index 31b211f..f1d236e 100644 --- a/kern/trapentry.S +++ b/kern/trapentry.S @@ -43,6 +43,21 @@ .text +.globl sysenter_handler +sysenter_handler: + push %ebp // holds env's stack pointer + push %esi // holds the env's return addr + push %edi + push %ebx + push %ecx + push %edx + push %eax + call syscall + add $0x14, %esp + pop %edx + pop %ecx + sysexit + /* * Lab 3: Your code here for generating entry points for the different traps. */ diff --git a/lib/syscall.c b/lib/syscall.c index 8d28dda..08d7654 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -2,6 +2,7 @@ #include #include +#include static inline int32_t syscall(int num, int check, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) @@ -37,10 +38,24 @@ syscall(int num, int check, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, return ret; } +int32_t +fast_syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4) { + asm volatile( + "push %%ebp\n\t" + "mov %%esp, %%ebp\n\t" + "lea syscall_ret_%=, %%esi\n\t" + "sysenter\n\t" + "syscall_ret_%=: pop %%ebp\n\t" + : "+a" (num) + : "d" (a1), "c" (a2), "b" (a3), "D" (a4) + : "esi"); + return num; +} + void sys_cputs(const char *s, size_t len) { - syscall(SYS_cputs, 0, (uint32_t)s, len, 0, 0, 0); + fast_syscall(SYS_cputs, (uint32_t)s, len, 0, 0); } int