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:
parent
3114df93d7
commit
be9ed3064d
5 changed files with 29 additions and 15 deletions
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue