[time] Adapt vdso module to SGX1 platform

This commit is contained in:
ClawSeven 2024-02-29 17:28:23 +08:00 committed by volcano
parent 501abda5ca
commit d3e84d2269
6 changed files with 74 additions and 17 deletions

@ -408,13 +408,7 @@ unsafe impl Sync for Vdso {}
unsafe impl Send for Vdso {} unsafe impl Send for Vdso {}
lazy_static! { lazy_static! {
static ref VDSO: Option<Vdso> = Vdso::new().map_or_else( static ref VDSO: Option<Vdso> = Vdso::new().ok();
|e| {
trace!("{}", e);
None
},
|v| Some(v)
);
} }
/// Try to get time according to ClockId. /// 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 { let mut ts = libc::timespec {
tv_sec: 0, tv_sec: 0,
tv_nsec: 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 { let mut res = libc::timespec {
tv_sec: 0, tv_sec: 0,
tv_nsec: 0, tv_nsec: 0,

@ -10,7 +10,7 @@ use crate::interrupt;
use crate::process::idle_reap_zombie_children; use crate::process::idle_reap_zombie_children;
use crate::process::{ProcessFilter, SpawnAttr}; use crate::process::{ProcessFilter, SpawnAttr};
use crate::signal::SigNum; 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::host_file_util::{host_file_buffer, parse_host_file, write_host_file, HostFile};
use crate::util::log::LevelFilter; use crate::util::log::LevelFilter;
use crate::util::mem_util::from_untrusted::*; use crate::util::mem_util::from_untrusted::*;
@ -96,8 +96,8 @@ pub extern "C" fn occlum_ecall_init(
interrupt::init(); interrupt::init();
// Init boot up time stamp here. // Init vdso and boot up time stamp here.
time::up_time::init(); time::init();
vm::init_user_space(); vm::init_user_space();

@ -18,7 +18,7 @@ struct CpuIdInput {
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] #[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)]
struct CpuIdResult { pub struct CpuIdResult {
eax: u32, eax: u32,
ebx: u32, ebx: u32,
ecx: u32, ecx: u32,
@ -218,6 +218,15 @@ impl CpuId {
}; };
cpuid_result 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! { lazy_static! {
@ -247,6 +256,14 @@ fn get_cpuid_info_via_ocall(cpuid_input: CpuIdInput) -> CpuIdResult {
cpuid_result 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() { pub fn setup_cpuid_info() {
// Make lazy_static to be executed at runtime in order to be initialized // Make lazy_static to be executed at runtime in order to be initialized
let max_basic_leaf = CPUID.get_max_basic_leaf(); 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::*;
use sgx_types::{sgx_exception_type_t, sgx_exception_vector_t}; 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 ENCLU: u32 = 0xd7010f;
const EACCEPT: u32 = 0x5; const EACCEPT: u32 = 0x5;
const EACCEPTCOPY: u32 = 0x7; const EACCEPTCOPY: u32 = 0x7;

@ -1,9 +1,12 @@
use self::timer_slack::*; use self::timer_slack::*;
use super::*; use super::*;
use crate::exception::is_cpu_support_sgx2;
use core::convert::TryFrom; use core::convert::TryFrom;
use process::pid_t; use process::pid_t;
use rcore_fs::dev::TimeProvider; use rcore_fs::dev::TimeProvider;
use rcore_fs::vfs::Timespec; use rcore_fs::vfs::Timespec;
use sgx_trts::enclave::{rsgx_get_enclave_mode, EnclaveMode};
use spin::Once;
use std::time::Duration; use std::time::Duration;
use std::{fmt, u64}; use std::{fmt, u64};
use syscall::SyscallNum; use syscall::SyscallNum;
@ -28,6 +31,26 @@ pub type clock_t = i64;
/// Clock ticks per second /// Clock ticks per second
pub const SC_CLK_TCK: u64 = 100; 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)] #[repr(C)]
#[derive(Debug, Default, Copy, Clone)] #[derive(Debug, Default, Copy, Clone)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
@ -75,7 +98,14 @@ impl From<Duration> for timeval_t {
} }
pub fn do_gettimeofday() -> 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() tv.validate()
.expect("gettimeofday returned invalid timeval_t"); .expect("gettimeofday returned invalid timeval_t");
tv tv
@ -145,14 +175,28 @@ impl timespec_t {
pub type clockid_t = i32; pub type clockid_t = i32;
pub fn do_clock_gettime(clockid: ClockId) -> Result<timespec_t> { 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() tv.validate()
.expect("clock_gettime returned invalid timespec"); .expect("clock_gettime returned invalid timespec");
Ok(tv) Ok(tv)
} }
pub fn do_clock_getres(clockid: ClockId) -> Result<timespec_t> { 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<()> { let validate_resolution = |res: &timespec_t| -> Result<()> {
// The resolution can be ranged from 1 nanosecond to a few milliseconds // 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 { if res.sec == 0 && res.nsec > 0 && res.nsec < 1_000_000_000 {

@ -10,7 +10,7 @@ lazy_static! {
.as_duration(); .as_duration();
} }
pub fn init() { pub(super) fn init() {
*BOOT_TIME_STAMP; *BOOT_TIME_STAMP;
*BOOT_TIME_STAMP_SINCE_EPOCH; *BOOT_TIME_STAMP_SINCE_EPOCH;
} }