Skip to content

Commit 2e61792

Browse files
Keep kernel GS active on userland exit fast-path
1 parent e0cd7e5 commit 2e61792

5 files changed

Lines changed: 61 additions & 12 deletions

File tree

source/includes/tty.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
void tty_init(void);
1111
void tty_input_char(char c);
1212
int tty_read(char* buf, uint64_t count);
13+
void tty_flush_input(void);
1314

1415
#endif

source/kernel/C/interrupts/syscalls-x86_64.asm

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
global syscall_entry
22
extern syscall_handler
33
extern kernel_stack_top
4+
extern userland_should_return_kernel
5+
extern userland_resume_rsp
6+
extern userland_resume_rip
7+
extern userland_resume_rbx
8+
extern userland_resume_rbp
9+
extern userland_resume_r12
10+
extern userland_resume_r13
11+
extern userland_resume_r14
12+
extern userland_resume_r15
413

514
section .bss
615
align 8
@@ -54,6 +63,21 @@ syscall_entry:
5463
; Restore userland RBX prior to iretq.
5564
mov rbx, [rel saved_user_rbx]
5665

66+
cmp byte [rel userland_should_return_kernel], 0
67+
je .return_to_user
68+
69+
mov rbx, [rel userland_resume_rbx]
70+
mov rbp, [rel userland_resume_rbp]
71+
mov r12, [rel userland_resume_r12]
72+
mov r13, [rel userland_resume_r13]
73+
mov r14, [rel userland_resume_r14]
74+
mov r15, [rel userland_resume_r15]
75+
mov rsp, [rel userland_resume_rsp]
76+
mov rax, [rel userland_resume_rip]
77+
jmp rax
78+
79+
.return_to_user:
80+
5781
; Return to user
5882
swapgs
5983
iretq

source/kernel/C/shell/commands/exec.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <executables/elf.h>
1414
#include <userland.h>
1515
#include <graphics.h>
16+
#include <tty.h>
1617

1718
int cmd_exec(int argc, char** argv)
1819
{
@@ -37,10 +38,12 @@ int cmd_exec(int argc, char** argv)
3738

3839
user_argv[user_argc] = NULL;
3940

41+
tty_flush_input();
42+
4043
if (userland_exec(path, user_argc, user_argv, NULL) != 0) {
4144
eprintf("exec: failed to load ELF");
4245
return -1;
4346
}
4447

4548
return 0;
46-
}
49+
}

source/kernel/C/user-input/tty.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,8 @@ int tty_read(char* buf, uint64_t count) {
8686

8787
return (int)read;
8888
}
89+
90+
void tty_flush_input(void) {
91+
rb_clear(&cooked_rb);
92+
line_len = 0;
93+
}

source/kernel/C/userland.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@ static uint64_t user_heap_mapped_end = USER_HEAP_VADDR;
1313
static uint64_t user_mmap_cursor = USER_MMAP_VADDR;
1414
static uint64_t user_mmap_end = USER_MMAP_VADDR;
1515
static volatile bool userland_running = false;
16-
static volatile uint64_t userland_resume_rip = 0;
17-
static volatile uint64_t userland_resume_rsp = 0;
16+
volatile bool userland_should_return_kernel = false;
17+
volatile uint64_t userland_resume_rip = 0;
18+
volatile uint64_t userland_resume_rsp = 0;
19+
volatile uint64_t userland_resume_rbx = 0;
20+
volatile uint64_t userland_resume_rbp = 0;
21+
volatile uint64_t userland_resume_r12 = 0;
22+
volatile uint64_t userland_resume_r13 = 0;
23+
volatile uint64_t userland_resume_r14 = 0;
24+
volatile uint64_t userland_resume_r15 = 0;
1825
static volatile int userland_last_exit_code = 0;
1926

2027
static void debug_dump_initial_stack(uint64_t stack_top) {
@@ -329,17 +336,13 @@ uint64_t userland_mmap_anon(uint64_t length) {
329336
}
330337

331338
bool userland_prepare_exit(syscall_frame_t* frame, uint64_t exit_code) {
332-
if (!frame || !userland_running || !userland_resume_rip || !userland_resume_rsp)
339+
(void)frame;
340+
341+
if (!userland_running || !userland_resume_rip || !userland_resume_rsp)
333342
return false;
334343

335344
userland_last_exit_code = (int)exit_code;
336-
337-
frame->rip = userland_resume_rip;
338-
frame->cs = 0x08;
339-
frame->rflags = 0x202;
340-
frame->rsp = userland_resume_rsp;
341-
frame->ss = 0x10;
342-
frame->rax = exit_code;
345+
userland_should_return_kernel = true;
343346
return true;
344347
}
345348

@@ -413,8 +416,15 @@ int userland_exec(const char* path, int argc, const char* const* argv, const cha
413416

414417
uint64_t kernel_rsp = 0;
415418
asm volatile("mov %%rsp, %0" : "=r"(kernel_rsp));
419+
asm volatile("mov %%rbx, %0" : "=r"(userland_resume_rbx));
420+
asm volatile("mov %%rbp, %0" : "=r"(userland_resume_rbp));
421+
asm volatile("mov %%r12, %0" : "=r"(userland_resume_r12));
422+
asm volatile("mov %%r13, %0" : "=r"(userland_resume_r13));
423+
asm volatile("mov %%r14, %0" : "=r"(userland_resume_r14));
424+
asm volatile("mov %%r15, %0" : "=r"(userland_resume_r15));
416425
userland_resume_rsp = kernel_rsp;
417426
userland_resume_rip = (uint64_t)&&userland_return_label;
427+
userland_should_return_kernel = false;
418428
userland_last_exit_code = 0;
419429
userland_running = true;
420430

@@ -443,12 +453,18 @@ int userland_exec(const char* path, int argc, const char* const* argv, const cha
443453

444454
userland_return_label:
445455
userland_running = false;
456+
userland_should_return_kernel = false;
446457
userland_resume_rip = 0;
447458
userland_resume_rsp = 0;
459+
userland_resume_rbx = 0;
460+
userland_resume_rbp = 0;
461+
userland_resume_r12 = 0;
462+
userland_resume_r13 = 0;
463+
userland_resume_r14 = 0;
464+
userland_resume_r15 = 0;
448465
wrmsr64_local(IA32_FS_BASE_MSR, 0);
449466
userland_unmap_all();
450467
userland_heap_init();
451468
printf(blue_color "\n[process exited with code %d]" reset_color, userland_last_exit_code);
452-
hcf2();
453469
return 0;
454470
}

0 commit comments

Comments
 (0)