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 super::*; | ||||||
| use process::Task; | use crate::syscall::SyscallNum; | ||||||
| use sgx_types::*; | use sgx_types::*; | ||||||
| 
 | 
 | ||||||
| const RDTSC_OPCODE: u16 = 0x310F; | 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] | #[no_mangle] | ||||||
| pub extern "C" fn handle_rdtsc_exception(info: *mut sgx_exception_info_t) -> u32 { | pub extern "C" fn handle_rdtsc_exception(info: *mut sgx_exception_info_t) -> u32 { | ||||||
|     let info = unsafe { &mut *info }; |     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; |         return EXCEPTION_CONTINUE_SEARCH; | ||||||
|     } |     } | ||||||
|     unsafe { | 
 | ||||||
|         let task = __get_current_task(); |     let (low, high) = { | ||||||
|         switch_td_to_kernel(task); |         let mut low = 0; | ||||||
|         let (low, high) = { |         let mut high = 0; | ||||||
|             let mut low = 0; |         let ret = unsafe { __occlum_syscall(SyscallNum::Rdtsc as u32, &mut low, &mut high) }; | ||||||
|             let mut high = 0; |         assert!(ret == 0); | ||||||
|             let sgx_status = occlum_ocall_rdtsc(&mut low, &mut high); |         (low, high) | ||||||
|             assert!(sgx_status == sgx_status_t::SGX_SUCCESS); |     }; | ||||||
|             (low, high) |     info.cpu_context.rax = low as u64; | ||||||
|         }; |     info.cpu_context.rdx = high as u64; | ||||||
|         info.cpu_context.rax = low as u64; |  | ||||||
|         info.cpu_context.rdx = high as u64; |  | ||||||
|         switch_td_to_user(task); |  | ||||||
|     } |  | ||||||
|     info.cpu_context.rip += 2; |     info.cpu_context.rip += 2; | ||||||
| 
 | 
 | ||||||
|     EXCEPTION_CONTINUE_EXECUTION |     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 util; | ||||||
| mod vm; | mod vm; | ||||||
| 
 | 
 | ||||||
| // Export system calls
 |  | ||||||
| pub use syscall::*; |  | ||||||
| // Export ECalls
 | // Export ECalls
 | ||||||
| pub use entry::*; | pub use entry::*; | ||||||
|  | |||||||
| @ -393,6 +393,8 @@ macro_rules! process_syscall_table_with_callback { | |||||||
| 
 | 
 | ||||||
|                 // Occlum-specific sytem calls
 |                 // 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), |                 (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) |     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
 | // TODO: handle remainder
 | ||||||
| fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> { | fn do_nanosleep(req_u: *const timespec_t, rem_u: *mut timespec_t) -> Result<isize> { | ||||||
|     check_ptr(req_u)?; |     check_ptr(req_u)?; | ||||||
|  | |||||||
| @ -160,6 +160,17 @@ pub fn do_thread_getcpuclock() -> Result<timespec_t> { | |||||||
|     Ok(tv) |     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
 | // For SEFS
 | ||||||
| pub struct OcclumTimeProvider; | pub struct OcclumTimeProvider; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user