Skip to content

Commit

Permalink
[time] Adapt vdso module to SGX1 platform
Browse files Browse the repository at this point in the history
  • Loading branch information
ClawSeven authored and volcano0dr committed Mar 14, 2024
1 parent b2f721d commit e48cc13
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 17 deletions.
12 changes: 3 additions & 9 deletions src/libos/crates/vdso-time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions src/libos/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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();

Expand Down
19 changes: 18 additions & 1 deletion src/libos/src/exception/cpuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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! {
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions src/libos/src/exception/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
50 changes: 47 additions & 3 deletions src/libos/src/time/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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: &timespec_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 {
Expand Down
2 changes: 1 addition & 1 deletion src/libos/src/time/up_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ lazy_static! {
.as_duration();
}

pub fn init() {
pub(super) fn init() {
*BOOT_TIME_STAMP;
*BOOT_TIME_STAMP_SINCE_EPOCH;
}
Expand Down

0 comments on commit e48cc13

Please sign in to comment.