x86: implement user mode on 64-bit
- In early boot, enable the syscall instruction and set up necessary MSRs - Add a hook to update page tables on context switch - Properly initialize thread based on whether it will start in user or supervisor mode - Add landing function for system calls to execute the desired handler - Implement arch_user_string_nlen() - Implement logic for dropping a thread down to user mode - Reserve per-CPU storage space for user and privilege elevation stack pointers, necessary for handling syscalls when no free registers are available - Proper handling of gs register considerations when transitioning privilege levels Kernel page table isolation (KPTI) is not yet implemented. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
07c278382a
commit
3d80208025
10 changed files with 406 additions and 15 deletions
|
@ -59,6 +59,19 @@ struct x86_esf {
|
|||
|
||||
typedef struct x86_esf z_arch_esf_t;
|
||||
|
||||
struct x86_ssf {
|
||||
unsigned long rip;
|
||||
unsigned long rflags;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
unsigned long r8;
|
||||
unsigned long rdx;
|
||||
unsigned long rsi;
|
||||
char fxsave[X86_FXSAVE_SIZE];
|
||||
unsigned long rdi;
|
||||
unsigned long rsp;
|
||||
};
|
||||
|
||||
#define ARCH_EXCEPT(reason_p) do { \
|
||||
__asm__ volatile( \
|
||||
"movq %[reason], %%rax\n\t" \
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#define X86_USER_DS 0x30 /* 64-bit user mode data */
|
||||
#define X86_USER_CS 0x38 /* 64-bit user mode code */
|
||||
|
||||
/* Value programmed into bits 63:32 of STAR MSR with proper segment
|
||||
* descriptors for implementing user mode with syscall/sysret
|
||||
*/
|
||||
#define X86_STAR_UPPER ((X86_USER_CS_32 << 16) | X86_KERNEL_CS)
|
||||
|
||||
#define X86_KERNEL_CPU0_TR 0x40 /* 64-bit task state segment */
|
||||
#define X86_KERNEL_CPU1_TR 0x50 /* 64-bit task state segment */
|
||||
#define X86_KERNEL_CPU2_TR 0x60 /* 64-bit task state segment */
|
||||
|
@ -73,6 +78,13 @@ struct x86_tss64 {
|
|||
*/
|
||||
|
||||
struct _cpu *cpu;
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* Privilege mode stack pointer value when doing a system call */
|
||||
char *psp;
|
||||
|
||||
/* Storage area for user mode stack pointer when doing a syscall */
|
||||
char *usp;
|
||||
#endif
|
||||
} __packed __aligned(8);
|
||||
|
||||
typedef struct x86_tss64 x86_tss64_t;
|
||||
|
@ -101,6 +113,23 @@ typedef struct _callee_saved _callee_saved_t;
|
|||
struct _thread_arch {
|
||||
u8_t flags;
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* Pointer to page tables used by this thread. Supervisor threads
|
||||
* always use the kernel's page table, user thread use per-thread
|
||||
* tables stored in the stack object
|
||||
*/
|
||||
struct x86_page_tables *ptables;
|
||||
|
||||
/* Initial privilege mode stack pointer when doing a system call.
|
||||
* Un-set for supervisor threads.
|
||||
*/
|
||||
char *psp;
|
||||
|
||||
/* SS and CS selectors for this thread when restoring context */
|
||||
u64_t ss;
|
||||
u64_t cs;
|
||||
#endif
|
||||
|
||||
u64_t rax;
|
||||
u64_t rcx;
|
||||
u64_t rdx;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue