1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

preliminary works to use the gs register in user space

This commit is contained in:
Stefan Lankes 2015-09-13 14:51:25 +02:00
parent 3114df93d7
commit be9ed3064d
5 changed files with 29 additions and 15 deletions

View file

@ -55,11 +55,12 @@ void switch_context(size_t** stack);
* @param task Pointer to the task structure
* @param ep The entry point for code execution
* @param arg Arguments list pointer for the task's stack
* @param core_id Id of the core, which is firstly used by the task
* @return
* - 0 on success
* - -EINVAL (-22) on failure
*/
int create_default_frame(task_t* task, entry_point_t ep, void* arg);
int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t core_id);
/** @brief Jump to user code
*

View file

@ -38,6 +38,7 @@ extern kernel_end
MSR_FS_BASE equ 0xc0000100
MSR_GS_BASE equ 0xc0000101
MSR_KERNEL_GS_BASE equ 0xc0000102
; We use a special name to map this section at the begin of our kernel
; => Multiboot expects its magic number at the beginning of the kernel.
@ -350,8 +351,10 @@ align 16
isrsyscall:
; IF flag is already cleared
; cli
; only called from user space => get kernel-level selector
swapgs
; get kernel stack
xchg rsp, [gs:kernel_stack]
@ -391,8 +394,10 @@ isrsyscall:
cli
; restore registers
; restore return value
pop rax
; restore registers
pop rsi
pop rdi
pop rcx
@ -407,6 +412,7 @@ isrsyscall:
; set user-level selector
swapgs
; EFLAGS (and IF flag) will be restored by sysret
; sti
o64 sysret
@ -536,12 +542,16 @@ common_switch:
call finish_task_switch
no_context_switch:
; do we interrupt user-level code?
cmp QWORD [rsp+24+18*8], 0x08
je short kernel_space2
swapgs ; set GS to the user-level selector
kernel_space2:
; restore fs / gs register
global Lpatch2
Lpatch2:
jmp short Lwrfsgs ; we patch later this jump to enable wrfsbase/wrgsbase
add rsp, 8
;pop r15
pop r15
;wrgsbase r15 ; currently, we don't use the gs register
pop r15
wrfsbase r15
@ -575,11 +585,6 @@ Lgo3:
pop rcx
pop rax
; do we interrupt user-level code?
cmp QWORD [rsp+24], 0x08
je short kernel_space2
swapgs ; set GS to the user-level selector
kernel_space2:
add rsp, 16
iretq

View file

@ -33,9 +33,9 @@
#include <hermit/tasks.h>
/*
* * Note that linker symbols are not variables, they have no memory allocated for
* * maintaining a value, rather their address is their value.
* */
* Note that linker symbols are not variables, they have no memory allocated for
* maintaining a value, rather their address is their value.
*/
extern const void percore_start;
extern const void percore_end0;
extern const void percore_end;

View file

@ -40,6 +40,13 @@
#define START_ADDRESS 0x40200000
/*
* Note that linker symbols are not variables, they have no memory allocated for
* maintaining a value, rather their address is their value.
*/
extern const void percore_start;
extern const void percore_end0;
extern uint64_t base;
static inline void enter_user_task(size_t ep, size_t stack)
@ -128,7 +135,7 @@ size_t* get_current_stack(void)
return curr_task->last_stack_pointer;
}
int create_default_frame(task_t* task, entry_point_t ep, void* arg)
int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t core_id)
{
size_t *stack;
struct state *stptr;
@ -179,6 +186,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg)
}
stptr->cs = 0x08;
stptr->ss = 0x10;
stptr->gs = core_id * ((size_t) &percore_end0 - (size_t) &percore_start);
stptr->rflags = 0x1202;
stptr->userrsp = stptr->rsp;

View file

@ -325,7 +325,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
if (id)
*id = i;
ret = create_default_frame(task_table+i, ep, arg);
ret = create_default_frame(task_table+i, ep, arg, core_id);
if (ret)
goto out;
@ -418,7 +418,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c
*id = i;
//kprintf("Create task %d with pml4 at 0x%llx\n", i, task_table[i].page_map);
ret = create_default_frame(task_table+i, ep, arg);
ret = create_default_frame(task_table+i, ep, arg, core_id);
if (ret)
goto out;