Switch user/kernel fsbase
This commit is contained in:
		
							parent
							
								
									05e5efdb57
								
							
						
					
					
						commit
						b717842113
					
				| @ -2,7 +2,7 @@ | ||||
| <EnclaveConfiguration> | ||||
|   <ProdID>0</ProdID> | ||||
|   <ISVSVN>0</ISVSVN> | ||||
|   <StackMaxSize>0x80000</StackMaxSize> | ||||
|   <StackMaxSize>0x100000</StackMaxSize> | ||||
|   <HeapMaxSize>0x1000000</HeapMaxSize> | ||||
|   <TCSNum>8</TCSNum> | ||||
|   <TCSPolicy>1</TCSPolicy> | ||||
|  | ||||
| @ -13,10 +13,11 @@ extern "C" { | ||||
| 
 | ||||
| // See Struct Task in process.rs
 | ||||
| struct Task { | ||||
|     uint64_t            syscall_stack_addr; | ||||
|     uint64_t            kernel_stack_addr; | ||||
|     uint64_t            kernel_fsbase_addr; | ||||
|     uint64_t            user_stack_addr; | ||||
|     uint64_t            user_fsbase_addr; | ||||
|     uint64_t            user_entry_addr; | ||||
|     uint64_t            fs_base_addr; | ||||
|     jmp_buf*            saved_state; | ||||
| }; | ||||
| 
 | ||||
| @ -37,7 +38,11 @@ void do_exit_task(void); | ||||
| /* Override the field for stack guard */ | ||||
| #define TD_TASK_OFFSET              TD_STACKGUARD_OFFSET | ||||
| 
 | ||||
| #define TASK_SYSCALL_STACK_OFFSET   (8 * 0) | ||||
| #define TASK_KERNEL_STACK_ADDR      (8 * 0) | ||||
| #define TASK_KERNEL_FSBASE_ADDR     (8 * 1) | ||||
| #define TASK_USER_STACK_ADDR        (8 * 2) | ||||
| #define TASK_USER_FSBASE_ADDR       (8 * 3) | ||||
| #define TASK_USER_ENTRY_ADDR        (8 * 4) | ||||
| 
 | ||||
| #endif /* __ASSEMBLY__ */ | ||||
| 
 | ||||
|  | ||||
| @ -85,7 +85,6 @@ fn init_task(user_entry: usize, stack_top: usize, | ||||
|     Ok(Task { | ||||
|         user_stack_addr: user_stack, | ||||
|         user_entry_addr: user_entry, | ||||
|         fs_base_addr: 0, | ||||
|         .. Default::default() | ||||
|     }) | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| #include "task.h" | ||||
| 
 | ||||
| extern void __run_task(uint64_t entry_point, uint64_t stack_top); | ||||
| extern void __run_task(struct Task* task); | ||||
| 
 | ||||
| extern uint64_t __get_stack_guard(void); | ||||
| extern void __set_stack_guard(uint64_t new_val); | ||||
| 
 | ||||
| static uint64_t get_syscall_stack(struct Task* this_task) { | ||||
| #define LARGE_ENOUGH_GAP        4096 | ||||
| #define LARGE_ENOUGH_GAP        (8192) | ||||
|     char libos_stack_var = 0; | ||||
|     uint64_t libos_stack = ((uint64_t) &libos_stack_var) - LARGE_ENOUGH_GAP; | ||||
|     libos_stack &= ~0x0FUL; // stack must be 16-byte aligned
 | ||||
| @ -20,17 +20,16 @@ static uint64_t get_syscall_stack(struct Task* this_task) { | ||||
| #define RESET_CURRENT_TASK()                    \ | ||||
|     __set_stack_guard(stack_guard); | ||||
| 
 | ||||
| 
 | ||||
| int do_run_task(struct Task* task) { | ||||
|     jmp_buf libos_state = {0}; | ||||
|     task->saved_state = &libos_state; | ||||
|     task->syscall_stack_addr = get_syscall_stack(task); | ||||
|     task->kernel_stack_addr = get_syscall_stack(task); | ||||
| 
 | ||||
|     SET_CURRENT_TASK(task); | ||||
| 
 | ||||
|     int second = setjmp(libos_state); | ||||
|     if (!second) { | ||||
|         __run_task(task->user_entry_addr, task->user_stack_addr); | ||||
|         __run_task(task); | ||||
|     } | ||||
| 
 | ||||
|     // From occlum_exit
 | ||||
| @ -39,6 +38,7 @@ int do_run_task(struct Task* task) { | ||||
| } | ||||
| 
 | ||||
| void do_exit_task(void) { | ||||
|     jmp_buf* jb = __get_current_task()->saved_state; | ||||
|     struct Task* task = __get_current_task(); | ||||
|     jmp_buf* jb = task->saved_state; | ||||
|     longjmp(*jb, 1); | ||||
| } | ||||
|  | ||||
| @ -5,10 +5,11 @@ use std::{mem}; | ||||
| #[derive(Clone, Debug, Default)] | ||||
| #[repr(C)] | ||||
| pub struct Task { | ||||
|     pub syscall_stack_addr: usize, | ||||
|     pub kernel_stack_addr: usize, | ||||
|     pub kernel_fsbase_addr: usize, | ||||
|     pub user_stack_addr: usize, | ||||
|     pub user_fsbase_addr: usize, | ||||
|     pub user_entry_addr: usize, | ||||
|     pub fs_base_addr: usize, | ||||
|     pub saved_state: usize, // struct jmpbuf*
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -30,5 +30,14 @@ __set_stack_guard: | ||||
|     .global __run_task
 | ||||
|     .type __run_task, @function
 | ||||
| __run_task: | ||||
|     mov %rsi, %rsp | ||||
|     jmp *%rdi | ||||
|     // Save kernel fsbase | ||||
|     rdfsbase %r10 | ||||
|     movq %r10, TASK_KERNEL_FSBASE_ADDR(%rdi) | ||||
|     // Use user fsbase | ||||
|     movq TASK_USER_FSBASE_ADDR(%rdi), %r10 | ||||
|     wrfsbase %r10 | ||||
|     // Use user stack | ||||
|     movq TASK_USER_STACK_ADDR(%rdi), %rsp | ||||
|     // Run user code | ||||
|     movq TASK_USER_ENTRY_ADDR(%rdi), %r11 | ||||
|     jmp *%r11 | ||||
|  | ||||
| @ -6,7 +6,6 @@ | ||||
| 
 | ||||
| long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) { | ||||
|     long ret = 0; | ||||
| 
 | ||||
|     switch (num) { | ||||
|     case SYS_exit: { | ||||
|         DECL_SYSCALL_ARG(int, status, arg0); | ||||
|  | ||||
| @ -5,13 +5,50 @@ | ||||
|     .global __occlum_syscall
 | ||||
|     .type __occlum_syscall, @function
 | ||||
| __occlum_syscall: | ||||
|     push %rbp | ||||
|     //      num  - %rdi | ||||
|     //      arg0 - %rsi | ||||
|     //      arg1 - %rdx | ||||
|     //      arg2 - %rcx | ||||
|     //      arg3 - %r8 | ||||
|     //      arg4 - %r9 | ||||
|     //      arg5 - *0x8(%rsp) | ||||
| 
 | ||||
|     // Given by the user, the user-space stack pointer %rsp cannot be trusted. | ||||
|     // So we need to check whether %rsp is within the read-write region of the | ||||
|     // current data domain | ||||
|     bndcl %rsp, %bnd0 | ||||
|     bndcu %rsp, %bnd0 | ||||
| 
 | ||||
|     // Save the user stack | ||||
|     pushq %rbp | ||||
|     movq %rsp, %rbp | ||||
| 
 | ||||
|     movq %gs:(TD_TASK_OFFSET), %rax | ||||
|     movq TASK_SYSCALL_STACK_OFFSET(%rax), %rsp | ||||
|     // Get current task | ||||
|     movq %gs:(TD_TASK_OFFSET), %r12 | ||||
|     // Switch to the kernel stack | ||||
|     movq TASK_KERNEL_STACK_ADDR(%r12), %rsp | ||||
|     // Use kernel fsbase | ||||
|     movq TASK_KERNEL_FSBASE_ADDR(%r12), %r11 | ||||
|     wrfsbase %r11 | ||||
| 
 | ||||
|     // TODO: Pass arg5 | ||||
|     // pushq 0x10(%rbp) | ||||
| 
 | ||||
|     call dispatch_syscall | ||||
| 
 | ||||
|     // addq 0x08, %rsp | ||||
| 
 | ||||
|     // Use user fsbase | ||||
|     movq TASK_KERNEL_FSBASE_ADDR(%r12), %r11 | ||||
|     wrfsbase %r11 | ||||
| 
 | ||||
|     // Restore the user stack | ||||
|     movq %rbp, %rsp | ||||
|     popq %rbp | ||||
|     ret | ||||
| 
 | ||||
|     // Check return target is a valid instruction (i.e., a cfi_label) | ||||
|     popq %r10 | ||||
|     movq (%r10), %r11 | ||||
|     bndcl %r11, %bnd2 | ||||
|     bndcu %r11, %bnd2 | ||||
|     jmpq *%r10 | ||||
|  | ||||
| @ -8,7 +8,6 @@ lazy_static! { | ||||
|             unsafe { vm_get_prealloced_data_space(&mut addr, &mut size) }; | ||||
|             (addr, size) | ||||
|         }; | ||||
|         println!("addr = {:X?}, size = {}", addr, size); | ||||
|         let vm_space = unsafe { | ||||
|             match VMSpace::new(addr, size, VMGuardAreaType::None) { | ||||
|                 Ok(vm_space) => vm_space, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user