mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
Implement fast syscall/sysret for sytem calls
This commit is contained in:
@@ -8,17 +8,17 @@ _start:
|
|||||||
xor rbp, rbp ; Sentinel rbp
|
xor rbp, rbp ; Sentinel rbp
|
||||||
|
|
||||||
mov rax, 5 ; GETPID syscall
|
mov rax, 5 ; GETPID syscall
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
mov [mypid], rax
|
mov [mypid], rax
|
||||||
|
|
||||||
mov rax, 8 ; FORK syscall
|
mov rax, 8 ; FORK syscall
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
mov [mychild], rax
|
mov [mychild], rax
|
||||||
|
|
||||||
mov r12, [mypid]
|
mov r12, [mypid]
|
||||||
mov r13, [mychild]
|
mov r13, [mychild]
|
||||||
mov rax, 1 ; DEBUG syscall
|
mov rax, 1 ; DEBUG syscall
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
|
|
||||||
cmp r12, 1
|
cmp r12, 1
|
||||||
je .dosend
|
je .dosend
|
||||||
@@ -32,7 +32,7 @@ _start:
|
|||||||
mov rax, 1 ; MESSAGE syscall
|
mov rax, 1 ; MESSAGE syscall
|
||||||
;mov rax, 0 ; NOOP syscall
|
;mov rax, 0 ; NOOP syscall
|
||||||
;syscall
|
;syscall
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
|
|
||||||
inc r11
|
inc r11
|
||||||
cmp r11, 2
|
cmp r11, 2
|
||||||
@@ -41,7 +41,7 @@ _start:
|
|||||||
|
|
||||||
mov rax, 4 ; SLEEP syscall
|
mov rax, 4 ; SLEEP syscall
|
||||||
; syscall
|
; syscall
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
|
|
||||||
add rbx, 20
|
add rbx, 20
|
||||||
|
|
||||||
@@ -51,11 +51,11 @@ _start:
|
|||||||
.dosend:
|
.dosend:
|
||||||
mov rax, 6 ; SEND syscall
|
mov rax, 6 ; SEND syscall
|
||||||
mov rdi, 2 ; target is pid 2
|
mov rdi, 2 ; target is pid 2
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
jmp .preloop
|
jmp .preloop
|
||||||
|
|
||||||
.doreceive:
|
.doreceive:
|
||||||
mov rax, 7 ; RECEIVE syscall
|
mov rax, 7 ; RECEIVE syscall
|
||||||
mov rdi, 1 ; source is pid 2
|
mov rdi, 1 ; source is pid 2
|
||||||
int 0xee
|
syscall ; int 0xee
|
||||||
jmp .preloop
|
jmp .preloop
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#define print_reg(name, value) cons->printf(" %s: %016lx\n", name, (value));
|
#define print_reg(name, value) cons->printf(" %s: %016lx\n", name, (value));
|
||||||
|
|
||||||
|
size_t __counter_syscall_enter = 0;
|
||||||
|
size_t __counter_syscall_sysret = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
print_regs(const cpu_state ®s)
|
print_regs(const cpu_state ®s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ extern "C" {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern size_t __counter_syscall_enter;
|
||||||
|
extern size_t __counter_syscall_sysret;
|
||||||
|
|
||||||
void print_regs(const cpu_state ®s);
|
void print_regs(const cpu_state ®s);
|
||||||
void print_stack(const cpu_state ®s);
|
void print_stack(const cpu_state ®s);
|
||||||
void print_stacktrace(int skip = 0);
|
void print_stacktrace(int skip = 0);
|
||||||
|
|||||||
@@ -4,38 +4,37 @@ extern isr_handler
|
|||||||
global isr_handler_prelude
|
global isr_handler_prelude
|
||||||
isr_handler_prelude:
|
isr_handler_prelude:
|
||||||
push_all_and_segments
|
push_all_and_segments
|
||||||
|
check_swap_gs
|
||||||
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
mov rsi, rsp
|
mov rsi, rsp
|
||||||
call isr_handler
|
call isr_handler
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
|
jmp isr_handler_return
|
||||||
pop_all_and_segments
|
|
||||||
|
|
||||||
add rsp, 16 ; because the ISRs added err/num
|
|
||||||
sti
|
|
||||||
iretq
|
|
||||||
|
|
||||||
extern irq_handler
|
extern irq_handler
|
||||||
global irq_handler_prelude
|
global irq_handler_prelude
|
||||||
irq_handler_prelude:
|
irq_handler_prelude:
|
||||||
push_all_and_segments
|
push_all_and_segments
|
||||||
|
check_swap_gs
|
||||||
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
mov rsi, rsp
|
mov rsi, rsp
|
||||||
call irq_handler
|
call irq_handler
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
|
; fall through to isr_handler_return
|
||||||
|
|
||||||
|
global isr_handler_return
|
||||||
|
isr_handler_return:
|
||||||
|
check_swap_gs
|
||||||
pop_all_and_segments
|
pop_all_and_segments
|
||||||
|
|
||||||
add rsp, 16 ; because the ISRs added err/num
|
add rsp, 16 ; because the ISRs added err/num
|
||||||
sti
|
|
||||||
iretq
|
iretq
|
||||||
|
|
||||||
%macro EMIT_ISR 2
|
%macro EMIT_ISR 2
|
||||||
global %1
|
global %1
|
||||||
%1:
|
%1:
|
||||||
cli
|
|
||||||
push 0
|
push 0
|
||||||
push %2
|
push %2
|
||||||
jmp isr_handler_prelude
|
jmp isr_handler_prelude
|
||||||
@@ -44,7 +43,6 @@ irq_handler_prelude:
|
|||||||
%macro EMIT_EISR 2
|
%macro EMIT_EISR 2
|
||||||
global %1
|
global %1
|
||||||
%1:
|
%1:
|
||||||
cli
|
|
||||||
push %2
|
push %2
|
||||||
jmp isr_handler_prelude
|
jmp isr_handler_prelude
|
||||||
%endmacro
|
%endmacro
|
||||||
@@ -52,7 +50,6 @@ irq_handler_prelude:
|
|||||||
%macro EMIT_IRQ 2
|
%macro EMIT_IRQ 2
|
||||||
global %1
|
global %1
|
||||||
%1:
|
%1:
|
||||||
cli
|
|
||||||
push 0
|
push 0
|
||||||
push %2
|
push %2
|
||||||
jmp irq_handler_prelude
|
jmp irq_handler_prelude
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ ramdisk_process_loader:
|
|||||||
mov rdx, rcx
|
mov rdx, rcx
|
||||||
call load_process
|
call load_process
|
||||||
|
|
||||||
|
swapgs
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
mov ax, ss
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
pop_all_and_segments
|
pop_all_and_segments
|
||||||
add rsp, 16 ; because the ISRs add err/num
|
add rsp, 16 ; because the ISRs add err/num
|
||||||
iretq
|
iretq
|
||||||
|
|||||||
@@ -44,4 +44,13 @@
|
|||||||
pop rax
|
pop rax
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
%macro check_swap_gs 0
|
||||||
|
mov rax, [rsp+0x90]
|
||||||
|
and rax, 0x03 ; mask out the RPL
|
||||||
|
cmp rax, 0x03
|
||||||
|
jne %%noswapgs
|
||||||
|
swapgs
|
||||||
|
%%noswapgs:
|
||||||
|
%endmacro
|
||||||
|
|
||||||
; vim: ft=asm
|
; vim: ft=asm
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
@@ -26,6 +27,14 @@ extern "C" {
|
|||||||
void load_process(const void *image_start, size_t bytes, process *proc, cpu_state state);
|
void load_process(const void *image_start, size_t bytes, process *proc, cpu_state state);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cpu_data
|
||||||
|
{
|
||||||
|
uintptr_t rsp0;
|
||||||
|
uintptr_t rsp3;
|
||||||
|
};
|
||||||
|
|
||||||
|
static cpu_data bsp_cpu_data;
|
||||||
|
|
||||||
scheduler::scheduler(lapic *apic) :
|
scheduler::scheduler(lapic *apic) :
|
||||||
m_apic(apic),
|
m_apic(apic),
|
||||||
m_next_pid(1)
|
m_next_pid(1)
|
||||||
@@ -181,6 +190,7 @@ void
|
|||||||
scheduler::start()
|
scheduler::start()
|
||||||
{
|
{
|
||||||
log::info(logs::task, "Starting scheduler.");
|
log::info(logs::task, "Starting scheduler.");
|
||||||
|
wrmsr(msr::ia32_gs_base, reinterpret_cast<uintptr_t>(&bsp_cpu_data));
|
||||||
m_tick_count = m_apic->enable_timer(isr::isrTimer, quantum_micros, false);
|
m_tick_count = m_apic->enable_timer(isr::isrTimer, quantum_micros, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +246,6 @@ void scheduler::prune(uint64_t now)
|
|||||||
uintptr_t
|
uintptr_t
|
||||||
scheduler::schedule(uintptr_t rsp0)
|
scheduler::schedule(uintptr_t rsp0)
|
||||||
{
|
{
|
||||||
|
|
||||||
// TODO: lol a real clock
|
// TODO: lol a real clock
|
||||||
static uint64_t now = 0;
|
static uint64_t now = 0;
|
||||||
|
|
||||||
@@ -262,7 +271,8 @@ scheduler::schedule(uintptr_t rsp0)
|
|||||||
|
|
||||||
// Set rsp0 to after the end of the about-to-be-popped cpu state
|
// Set rsp0 to after the end of the about-to-be-popped cpu state
|
||||||
tss_set_stack(0, rsp0 + sizeof(cpu_state));
|
tss_set_stack(0, rsp0 + sizeof(cpu_state));
|
||||||
wrmsr(msr::ia32_kernel_gs_base, rsp0);
|
bsp_cpu_data.rsp0 = rsp0;
|
||||||
|
|
||||||
|
|
||||||
// Swap page tables
|
// Swap page tables
|
||||||
page_table *pml4 = m_current->pml4;
|
page_table *pml4 = m_current->pml4;
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ syscall_dispatch(uintptr_t return_rsp, cpu_state ®s)
|
|||||||
cons->printf("\nProcess %u: Received DEBUG syscall\n", p->pid);
|
cons->printf("\nProcess %u: Received DEBUG syscall\n", p->pid);
|
||||||
cons->set_color();
|
cons->set_color();
|
||||||
print_regs(regs);
|
print_regs(regs);
|
||||||
|
cons->printf("\n Syscall enters: %8d\n", __counter_syscall_enter);
|
||||||
|
cons->printf(" Syscall sysret: %8d\n", __counter_syscall_sysret);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case syscall::message:
|
case syscall::message:
|
||||||
|
|||||||
@@ -1,21 +1,44 @@
|
|||||||
%include "push_all.inc"
|
%include "push_all.inc"
|
||||||
|
|
||||||
|
extern __counter_syscall_enter
|
||||||
|
extern __counter_syscall_sysret
|
||||||
|
|
||||||
extern syscall_handler
|
extern syscall_handler
|
||||||
|
extern isr_handler_return
|
||||||
global syscall_handler_prelude
|
global syscall_handler_prelude
|
||||||
syscall_handler_prelude:
|
syscall_handler_prelude:
|
||||||
push 0 ; ss, doesn't matter here
|
swapgs
|
||||||
|
mov [gs:0x08], rsp
|
||||||
|
mov rsp, [gs:0x00]
|
||||||
|
|
||||||
|
push 0x23 ; ss
|
||||||
push rsp
|
push rsp
|
||||||
pushf
|
pushf
|
||||||
push 0 ; cs, doesn't matter here
|
push 0x2b ; cs
|
||||||
push rcx ; user rip
|
push rcx ; user rip
|
||||||
push 0 ; bogus interrupt
|
push 0 ; bogus interrupt
|
||||||
push 0 ; bogus errorcode
|
push 0 ; bogus errorcode
|
||||||
push_all_and_segments
|
push_all_and_segments
|
||||||
|
|
||||||
|
inc qword [rel __counter_syscall_enter]
|
||||||
|
|
||||||
|
mov rax, [gs:0x08]
|
||||||
|
mov [rsp + 0x98], rax
|
||||||
|
mov rax, [rsp + 0x70]
|
||||||
|
|
||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
call syscall_handler
|
call syscall_handler
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
|
|
||||||
|
mov rax, [rsp + 0x90]
|
||||||
|
and rax, 0x3
|
||||||
|
cmp rax, 0x3
|
||||||
|
jne isr_handler_return
|
||||||
|
|
||||||
|
inc qword [rel __counter_syscall_sysret]
|
||||||
|
|
||||||
|
swapgs
|
||||||
|
|
||||||
pop_all_and_segments
|
pop_all_and_segments
|
||||||
add rsp, 16 ; ignore bogus interrupt / error
|
add rsp, 16 ; ignore bogus interrupt / error
|
||||||
pop rcx ; user rip
|
pop rcx ; user rip
|
||||||
|
|||||||
Reference in New Issue
Block a user