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();
|
|
||||||
switch_td_to_kernel(task);
|
|
||||||
let (low, high) = {
|
let (low, high) = {
|
||||||
let mut low = 0;
|
let mut low = 0;
|
||||||
let mut high = 0;
|
let mut high = 0;
|
||||||
let sgx_status = occlum_ocall_rdtsc(&mut low, &mut high);
|
let ret = unsafe { __occlum_syscall(SyscallNum::Rdtsc as u32, &mut low, &mut high) };
|
||||||
assert!(sgx_status == sgx_status_t::SGX_SUCCESS);
|
assert!(ret == 0);
|
||||||
(low, high)
|
(low, high)
|
||||||
};
|
};
|
||||||
info.cpu_context.rax = low as u64;
|
info.cpu_context.rax = low as u64;
|
||||||
info.cpu_context.rdx = high 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