[time] Adapt vdso module to SGX1 platform
This commit is contained in:
parent
b2f721d1bb
commit
e48cc13f79
@ -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