Fix RDTSC emulation's changing app's TLS by mistake
This commit switches from user mode to kernel mode before handling the exception caused by RDTSC instruction.
This commit is contained in:
		
							parent
							
								
									52cb897436
								
							
						
					
					
						commit
						bbc3b8a467
					
				| @ -1,16 +1,9 @@ | ||||
| use super::*; | ||||
| use process::Task; | ||||
| use crate::syscall::SyscallNum; | ||||
| use sgx_types::*; | ||||
| 
 | ||||
| const RDTSC_OPCODE: u16 = 0x310F; | ||||
| 
 | ||||
| extern "C" { | ||||
|     fn occlum_ocall_rdtsc(low: *mut u32, high: *mut u32) -> sgx_status_t; | ||||
|     fn __get_current_task() -> *const Task; | ||||
|     fn switch_td_to_kernel(task: *const Task); | ||||
|     fn switch_td_to_user(task: *const Task); | ||||
| } | ||||
| 
 | ||||
| #[no_mangle] | ||||
| pub extern "C" fn handle_rdtsc_exception(info: *mut sgx_exception_info_t) -> u32 { | ||||
|     let info = unsafe { &mut *info }; | ||||
| @ -21,21 +14,21 @@ pub extern "C" fn handle_rdtsc_exception(info: *mut sgx_exception_info_t) -> u32 | ||||
|     { | ||||
|         return EXCEPTION_CONTINUE_SEARCH; | ||||
|     } | ||||
|     unsafe { | ||||
|         let task = __get_current_task(); | ||||
|         switch_td_to_kernel(task); | ||||
| 
 | ||||
|     let (low, high) = { | ||||
|         let mut low = 0; | ||||
|         let mut high = 0; | ||||
|             let sgx_status = occlum_ocall_rdtsc(&mut low, &mut high); | ||||
|             assert!(sgx_status == sgx_status_t::SGX_SUCCESS); | ||||
|         let ret = unsafe { __occlum_syscall(SyscallNum::Rdtsc as u32, &mut low, &mut high) }; | ||||
|         assert!(ret == 0); | ||||
|         (low, high) | ||||
|     }; | ||||
|     info.cpu_context.rax = low as u64; | ||||
|     info.cpu_context.rdx = high as u64; | ||||
|         switch_td_to_user(task); | ||||
|     } | ||||
|     info.cpu_context.rip += 2; | ||||
| 
 | ||||
|     EXCEPTION_CONTINUE_EXECUTION | ||||
| } | ||||
| 
 | ||||
| extern "C" { | ||||
|     fn __occlum_syscall(num: u32, arg0: *mut u32, arg1: *mut u32) -> i64; | ||||
| } | ||||
|  | ||||
| @ -67,7 +67,5 @@ mod untrusted; | ||||
| mod util; | ||||
| mod vm; | ||||
| 
 | ||||
| // Export system calls
 | ||||
| pub use syscall::*; | ||||
| // Export ECalls
 | ||||
| pub use entry::*; | ||||
|  | ||||
| @ -393,6 +393,8 @@ macro_rules! process_syscall_table_with_callback { | ||||
| 
 | ||||
|                 // Occlum-specific sytem calls
 | ||||
|                 (Spawn = 360) => do_spawn(child_pid_ptr: *mut u32, path: *const i8, argv: *const *const i8, envp: *const *const i8, fdop_list: *const FdOp), | ||||
|                 // Exception handling
 | ||||
|                 (Rdtsc = 361) => do_rdtsc(low_ptr: *mut u32, high_ptr: *mut u32), | ||||
|             } | ||||
|     }; | ||||
| } | ||||
| @ -932,6 +934,18 @@ fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result<isize> | ||||
|     Ok(0) | ||||
| } | ||||
| 
 | ||||
| fn do_rdtsc(low_ptr: *mut u32, high_ptr: *mut u32) -> Result<isize> { | ||||
|     check_mut_ptr(low_ptr)?; | ||||
|     check_mut_ptr(high_ptr)?; | ||||
|     let (low, high) = time::do_rdtsc()?; | ||||
|     debug!("do_rdtsc result {{ low: {:#x} high: {:#x}}}", low, high); | ||||
|     unsafe { | ||||
|         *low_ptr = low; | ||||
|         *high_ptr = high; | ||||
|     } | ||||
|     Ok(0) | ||||
| } | ||||
| 
 | ||||
| // TODO: handle remainder
 | ||||
| fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> { | ||||
|     check_ptr(req_u)?; | ||||
|  | ||||
| @ -160,6 +160,17 @@ pub fn do_thread_getcpuclock() -> Result<timespec_t> { | ||||
|     Ok(tv) | ||||
| } | ||||
| 
 | ||||
| pub fn do_rdtsc() -> Result<(u32, u32)> { | ||||
|     extern "C" { | ||||
|         fn occlum_ocall_rdtsc(low: *mut u32, high: *mut u32) -> sgx_status_t; | ||||
|     } | ||||
|     let mut low = 0; | ||||
|     let mut high = 0; | ||||
|     let sgx_status = unsafe { occlum_ocall_rdtsc(&mut low, &mut high) }; | ||||
|     assert!(sgx_status == sgx_status_t::SGX_SUCCESS); | ||||
|     Ok((low, high)) | ||||
| } | ||||
| 
 | ||||
| // For SEFS
 | ||||
| pub struct OcclumTimeProvider; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user