[time] Adapt vdso module to SGX1 platform
This commit is contained in:
		
							parent
							
								
									501abda5ca
								
							
						
					
					
						commit
						d3e84d2269
					
				| @ -408,13 +408,7 @@ unsafe impl Sync for Vdso {} | ||||
| unsafe impl Send for Vdso {} | ||||
| 
 | ||||
| lazy_static! { | ||||
|     static ref VDSO: Option<Vdso> = Vdso::new().map_or_else( | ||||
|         |e| { | ||||
|             trace!("{}", e); | ||||
|             None | ||||
|         }, | ||||
|         |v| Some(v) | ||||
|     ); | ||||
|     static ref VDSO: Option<Vdso> = Vdso::new().ok(); | ||||
| } | ||||
| 
 | ||||
| /// Try to get time according to ClockId.
 | ||||
| @ -455,7 +449,7 @@ pub fn clock_getres(clockid: ClockId) -> Result<Duration> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn clock_gettime_slow(clockid: ClockId) -> Result<Duration> { | ||||
| pub fn clock_gettime_slow(clockid: ClockId) -> Result<Duration> { | ||||
|     let mut ts = libc::timespec { | ||||
|         tv_sec: 0, | ||||
|         tv_nsec: 0, | ||||
| @ -486,7 +480,7 @@ fn clock_gettime_slow(clockid: ClockId) -> Result<Duration> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn clock_getres_slow(clockid: ClockId) -> Result<Duration> { | ||||
| pub fn clock_getres_slow(clockid: ClockId) -> Result<Duration> { | ||||
|     let mut res = libc::timespec { | ||||
|         tv_sec: 0, | ||||
|         tv_nsec: 0, | ||||
|  | ||||
| @ -10,7 +10,7 @@ use crate::interrupt; | ||||
| use crate::process::idle_reap_zombie_children; | ||||
| use crate::process::{ProcessFilter, SpawnAttr}; | ||||
| use crate::signal::SigNum; | ||||
| use crate::time::up_time::init; | ||||
| use crate::time::init; | ||||
| use crate::util::host_file_util::{host_file_buffer, parse_host_file, write_host_file, HostFile}; | ||||
| use crate::util::log::LevelFilter; | ||||
| use crate::util::mem_util::from_untrusted::*; | ||||
| @ -96,8 +96,8 @@ pub extern "C" fn occlum_ecall_init( | ||||
| 
 | ||||
|         interrupt::init(); | ||||
| 
 | ||||
|         // Init boot up time stamp here.
 | ||||
|         time::up_time::init(); | ||||
|         // Init vdso and boot up time stamp here.
 | ||||
|         time::init(); | ||||
| 
 | ||||
|         vm::init_user_space(); | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ struct CpuIdInput { | ||||
| 
 | ||||
| #[repr(C)] | ||||
| #[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] | ||||
| struct CpuIdResult { | ||||
| pub struct CpuIdResult { | ||||
|     eax: u32, | ||||
|     ebx: u32, | ||||
|     ecx: u32, | ||||
| @ -218,6 +218,15 @@ impl CpuId { | ||||
|         }; | ||||
|         cpuid_result | ||||
|     } | ||||
| 
 | ||||
|     pub fn support_sgx2(&self) -> bool { | ||||
|         const SGX_CPUID: u32 = 12; | ||||
|         let cpuid = self.get_cpuid_info(SGX_CPUID, 0); | ||||
| 
 | ||||
|         // The 0th bit set to 1 in `cpuid.eax` indicates that the SGX feature is enabled.
 | ||||
|         // The 1st bit set to 1 in `cpuid.eax` indicates that the SGX2 feature is enabled.
 | ||||
|         (cpuid.eax & 0b11) == 0b11 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| lazy_static! { | ||||
| @ -247,6 +256,14 @@ fn get_cpuid_info_via_ocall(cpuid_input: CpuIdInput) -> CpuIdResult { | ||||
|     cpuid_result | ||||
| } | ||||
| 
 | ||||
| pub fn is_cpu_support_sgx2() -> bool { | ||||
|     CPUID.support_sgx2() | ||||
| } | ||||
| 
 | ||||
| pub fn get_cpuid_info(leaf: u32, subleaf: u32) -> CpuIdResult { | ||||
|     CPUID.get_cpuid_info(leaf, subleaf) | ||||
| } | ||||
| 
 | ||||
| pub fn setup_cpuid_info() { | ||||
|     // Make lazy_static to be executed at runtime in order to be initialized
 | ||||
|     let max_basic_leaf = CPUID.get_max_basic_leaf(); | ||||
|  | ||||
| @ -11,6 +11,8 @@ use crate::vm::{enclave_page_fault_handler, is_page_committed, VMRange, USER_SPA | ||||
| use sgx_types::*; | ||||
| use sgx_types::{sgx_exception_type_t, sgx_exception_vector_t}; | ||||
| 
 | ||||
| pub use self::cpuid::{get_cpuid_info, is_cpu_support_sgx2}; | ||||
| 
 | ||||
| const ENCLU: u32 = 0xd7010f; | ||||
| const EACCEPT: u32 = 0x5; | ||||
| const EACCEPTCOPY: u32 = 0x7; | ||||
|  | ||||
| @ -1,9 +1,12 @@ | ||||
| use self::timer_slack::*; | ||||
| use super::*; | ||||
| use crate::exception::is_cpu_support_sgx2; | ||||
| use core::convert::TryFrom; | ||||
| use process::pid_t; | ||||
| use rcore_fs::dev::TimeProvider; | ||||
| use rcore_fs::vfs::Timespec; | ||||
| use sgx_trts::enclave::{rsgx_get_enclave_mode, EnclaveMode}; | ||||
| use spin::Once; | ||||
| use std::time::Duration; | ||||
| use std::{fmt, u64}; | ||||
| use syscall::SyscallNum; | ||||
| @ -28,6 +31,26 @@ pub type clock_t = i64; | ||||
| /// Clock ticks per second
 | ||||
| pub const SC_CLK_TCK: u64 = 100; | ||||
| 
 | ||||
| static IS_ENABLE_VDSO: Once<bool> = Once::new(); | ||||
| 
 | ||||
| pub fn init() { | ||||
|     init_vdso(); | ||||
|     up_time::init(); | ||||
| } | ||||
| 
 | ||||
| fn init_vdso() { | ||||
|     IS_ENABLE_VDSO.call_once(|| match rsgx_get_enclave_mode() { | ||||
|         EnclaveMode::Hw if is_cpu_support_sgx2() => true, | ||||
|         EnclaveMode::Sim => true, | ||||
|         _ => false, | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| #[inline(always)] | ||||
| fn is_enable_vdso() -> bool { | ||||
|     IS_ENABLE_VDSO.get().map_or(false, |is_enable| *is_enable) | ||||
| } | ||||
| 
 | ||||
| #[repr(C)] | ||||
| #[derive(Debug, Default, Copy, Clone)] | ||||
| #[allow(non_camel_case_types)] | ||||
| @ -75,7 +98,14 @@ impl From<Duration> for timeval_t { | ||||
| } | ||||
| 
 | ||||
| pub fn do_gettimeofday() -> timeval_t { | ||||
|     let tv = timeval_t::from(vdso_time::clock_gettime(ClockId::CLOCK_REALTIME).unwrap()); | ||||
|     let duration = if is_enable_vdso() { | ||||
|         vdso_time::clock_gettime(ClockId::CLOCK_REALTIME).unwrap() | ||||
|     } else { | ||||
|         // SGX1 Hardware doesn't support rdtsc instruction
 | ||||
|         vdso_time::clock_gettime_slow(ClockId::CLOCK_REALTIME).unwrap() | ||||
|     }; | ||||
| 
 | ||||
|     let tv = timeval_t::from(duration); | ||||
|     tv.validate() | ||||
|         .expect("gettimeofday returned invalid timeval_t"); | ||||
|     tv | ||||
| @ -145,14 +175,28 @@ impl timespec_t { | ||||
| pub type clockid_t = i32; | ||||
| 
 | ||||
| pub fn do_clock_gettime(clockid: ClockId) -> Result<timespec_t> { | ||||
|     let tv = timespec_t::from(vdso_time::clock_gettime(clockid).unwrap()); | ||||
|     let duration = if is_enable_vdso() { | ||||
|         vdso_time::clock_gettime(clockid).unwrap() | ||||
|     } else { | ||||
|         // SGX1 Hardware doesn't support rdtsc instruction
 | ||||
|         vdso_time::clock_gettime_slow(clockid).unwrap() | ||||
|     }; | ||||
| 
 | ||||
|     let tv = timespec_t::from(duration); | ||||
|     tv.validate() | ||||
|         .expect("clock_gettime returned invalid timespec"); | ||||
|     Ok(tv) | ||||
| } | ||||
| 
 | ||||
| pub fn do_clock_getres(clockid: ClockId) -> Result<timespec_t> { | ||||
|     let res = timespec_t::from(vdso_time::clock_getres(clockid).unwrap()); | ||||
|     let duration = if is_enable_vdso() { | ||||
|         vdso_time::clock_getres(clockid).unwrap() | ||||
|     } else { | ||||
|         // SGX1 Hardware doesn't support rdtsc instruction
 | ||||
|         vdso_time::clock_getres_slow(clockid).unwrap() | ||||
|     }; | ||||
| 
 | ||||
|     let res = timespec_t::from(duration); | ||||
|     let validate_resolution = |res: ×pec_t| -> Result<()> { | ||||
|         // The resolution can be ranged from 1 nanosecond to a few milliseconds
 | ||||
|         if res.sec == 0 && res.nsec > 0 && res.nsec < 1_000_000_000 { | ||||
|  | ||||
| @ -10,7 +10,7 @@ lazy_static! { | ||||
|         .as_duration(); | ||||
| } | ||||
| 
 | ||||
| pub fn init() { | ||||
| pub(super) fn init() { | ||||
|     *BOOT_TIME_STAMP; | ||||
|     *BOOT_TIME_STAMP_SINCE_EPOCH; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user