From e1e46c99354e100dccf1d60ec34c56b3dceb1921 Mon Sep 17 00:00:00 2001 From: "Tate, Hongliang Tian" Date: Fri, 12 Jul 2019 12:10:33 +0000 Subject: [PATCH] Add clock_gettimeofday --- src/Enclave.edl | 3 +- src/libos/src/syscall/mod.rs | 14 ++++++++- src/libos/src/time/mod.rs | 59 ++++++++++++++++++++++++++++++++++++ src/pal/pal.c | 8 +++++ test/include/test.h | 40 ++++++++++++++++++++++++ test/mmap/main.c | 33 ++------------------ test/test_common.mk | 2 +- test/time/main.c | 42 ++++++++++++++++++++++--- 8 files changed, 163 insertions(+), 38 deletions(-) create mode 100644 test/include/test.h diff --git a/src/Enclave.edl b/src/Enclave.edl index 82e084fd..b9878859 100644 --- a/src/Enclave.edl +++ b/src/Enclave.edl @@ -17,7 +17,8 @@ enclave { untrusted { void ocall_print_string([in, string] const char* msg); int ocall_run_new_task(void); - void ocall_gettimeofday([out] long* seconds, [out] long* microseconds); + void ocall_gettimeofday([out] long* sec, [out] long* us); + void ocall_clock_gettime(int clockid, [out] long* sec, [out] long* ns); void ocall_sync(void); }; }; diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index c81ba73b..1ab3783d 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -13,7 +13,7 @@ use prelude::*; use process::{pid_t, ChildProcessFilter, CloneFlags, FileAction, FutexFlags, FutexOp}; use std::ffi::{CStr, CString}; use std::ptr; -use time::timeval_t; +use time::{timeval_t, clockid_t, timespec_t}; use util::mem_util::from_user::*; use vm::{VMPerms, MMapFlags}; use {fs, process, std, vm}; @@ -203,6 +203,7 @@ pub extern "C" fn dispatch_syscall( SYS_DUP3 => do_dup3(arg0 as FileDesc, arg1 as FileDesc, arg2 as u32), SYS_GETTIMEOFDAY => do_gettimeofday(arg0 as *mut timeval_t), + SYS_CLOCK_GETTIME => do_clock_gettime(arg0 as clockid_t, arg1 as *mut timespec_t), SYS_UNAME => do_uname(arg0 as *mut utsname_t), @@ -790,6 +791,17 @@ fn do_gettimeofday(tv_u: *mut timeval_t) -> Result { Ok(0) } +fn do_clock_gettime(clockid: clockid_t, ts_u: *mut timespec_t) -> Result { + check_mut_ptr(ts_u)?; + let clockid = time::ClockID::from_raw(clockid)?; + let ts = time::do_clock_gettime(clockid)?; + unsafe { + *ts_u = ts; + } + Ok(0) +} + + // FIXME: use this const MAP_FAILED: *const c_void = ((-1) as i64) as *const c_void; diff --git a/src/libos/src/time/mod.rs b/src/libos/src/time/mod.rs index d458a319..27b0b765 100644 --- a/src/libos/src/time/mod.rs +++ b/src/libos/src/time/mod.rs @@ -11,6 +11,7 @@ pub type suseconds_t = i64; #[repr(C)] #[derive(Debug, Default, Copy, Clone)] +#[allow(non_camel_case_types)] pub struct timeval_t { sec: time_t, usec: suseconds_t, @@ -34,6 +35,64 @@ extern "C" { fn ocall_gettimeofday(sec: *mut time_t, usec: *mut suseconds_t) -> sgx_status_t; } + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +#[allow(non_camel_case_types)] +pub struct timespec_t { + sec: time_t, + nsec: i64, +} + +#[allow(non_camel_case_types)] +pub type clockid_t = i32; + +#[derive(Debug, Copy, Clone)] +#[allow(non_camel_case_types)] +pub enum ClockID { + CLOCK_REALTIME = 0, + CLOCK_MONOTONIC = 1, + CLOCK_PROCESS_CPUTIME_ID = 2, + CLOCK_THREAD_CPUTIME_ID = 3, + CLOCK_MONOTONIC_RAW = 4, + CLOCK_REALTIME_COARSE = 5, + CLOCK_MONOTONIC_COARSE = 6, + CLOCK_BOOTTIME = 7, +} + +impl ClockID { + #[deny(unreachable_patterns)] + pub fn from_raw(clockid: clockid_t) -> Result { + Ok(match clockid as i32 { + 0 => ClockID::CLOCK_REALTIME, + 1 => ClockID::CLOCK_MONOTONIC, + 2 => ClockID::CLOCK_PROCESS_CPUTIME_ID, + 3 => ClockID::CLOCK_THREAD_CPUTIME_ID, + 4 => ClockID::CLOCK_MONOTONIC_RAW, + 5 => ClockID::CLOCK_REALTIME_COARSE, + 6 => ClockID::CLOCK_MONOTONIC_COARSE, + 7 => ClockID::CLOCK_BOOTTIME, + _ => return errno!(EINVAL, "invalid command"), + }) + } +} + +pub fn do_clock_gettime(clockid: ClockID) -> Result { + let mut sec = 0; + let mut nsec = 0; + unsafe { + ocall_clock_gettime(clockid as clockid_t, &mut sec as *mut time_t, &mut nsec as *mut i64); + } + Ok(timespec_t { sec, nsec }) +} + +extern "C" { + fn ocall_clock_gettime(clockid: clockid_t, sec: *mut time_t, ns: *mut i64) -> sgx_status_t; +} + + +// For SEFS + pub struct OcclumTimeProvider; impl TimeProvider for OcclumTimeProvider { diff --git a/src/pal/pal.c b/src/pal/pal.c index ad28c299..17b19c16 100644 --- a/src/pal/pal.c +++ b/src/pal/pal.c @@ -5,6 +5,7 @@ #include #include #include +#include #define MAX_PATH FILENAME_MAX @@ -205,6 +206,13 @@ void ocall_gettimeofday(long* seconds, long* microseconds) { *microseconds = tv.tv_usec; } +void ocall_clock_gettime(int clockid, time_t* sec, long* ns) { + struct timespec ts; + clock_gettime(clockid, &ts); + *sec = ts.tv_sec; + *ns = ts.tv_nsec; +} + void ocall_sync(void) { sync(); } diff --git a/test/include/test.h b/test/include/test.h new file mode 100644 index 00000000..7fe53187 --- /dev/null +++ b/test/include/test.h @@ -0,0 +1,40 @@ +#ifndef __TEST_H +#define __TEST_H + +#include + +#define _STR(x) #x +#define STR(x) _STR(x) +#define MIN(a, b) ((a) <= (b) ? (a) : (b)) +#define MAX(a, b) ((a) >= (b) ? (a) : (b)) +#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) + + +typedef int(*test_case_func_t)(void); + +typedef struct { + const char* name; + test_case_func_t func; +} test_case_t; + +#define TEST_CASE(name) { STR(name), name } + +#define throw_error(msg) while(1) { \ + printf("\t\tERROR: %s in func %s at line %d of file %s\n", \ + (msg), __func__, __LINE__, __FILE__); \ + return -1; \ +} + +int test_suite_run(test_case_t* test_cases, int num_test_cases) { + for (int ti = 0; ti < num_test_cases; ti++) { + test_case_t* tc = &test_cases[ti]; + if (tc->func() < 0) { + printf(" func %s - [ERR]\n", tc->name); + return -1; + } + printf(" func %s - [OK]\n", tc->name); + } + return 0; +} + +#endif /* __TEST_H */ diff --git a/test/mmap/main.c b/test/mmap/main.c index 83291757..2d67fa8b 100644 --- a/test/mmap/main.c +++ b/test/mmap/main.c @@ -7,6 +7,7 @@ #include #include #include +#include "test.h" // ============================================================================ // Helper macros @@ -16,23 +17,9 @@ #define MB (1024 * 1024UL) #define PAGE_SIZE (4 * KB) -#define _STR(x) #x -#define STR(x) _STR(x) - -#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) - #define ALIGN_DOWN(x, a) ((x) & ~(a-1)) // a must be a power of two #define ALIGN_UP(x, a) ALIGN_DOWN((x+(a-1)), (a)) -#define MIN(a, b) ((a) <= (b) ? (a) : (b)) -#define MAX(a, b) ((a) >= (b) ? (a) : (b)) - -#define throw_error(msg) while(1) { \ - printf("ERROR: %s in func %s at line %d of file %s\n", \ - (msg), __func__, __LINE__, __FILE__); \ - return -1; \ -} - #define MAX_MMAP_USED_MEMORY (4 * MB) // ============================================================================ @@ -632,14 +619,6 @@ int test_munmap_with_non_page_aligned_len() { // Test suite main // ============================================================================ -typedef int(*test_case_func_t)(void); - -typedef struct { - const char* name; - test_case_func_t func; -} test_case_t; - -#define TEST_CASE(name) { STR(name), name } static test_case_t test_cases[] = { TEST_CASE(test_anonymous_mmap), TEST_CASE(test_anonymous_mmap_randomly), @@ -669,13 +648,5 @@ int main() { throw_error("test_suite_init failed"); } - for (int ti = 0; ti < ARRAY_SIZE(test_cases); ti++) { - test_case_t* tc = &test_cases[ti]; - if (tc->func() < 0) { - printf(" func %s - [ERR]\n", tc->name); - return -1; - } - printf(" func %s - [OK]\n", tc->name); - } - return 0; + return test_suite_run(test_cases, ARRAY_SIZE(test_cases)); } diff --git a/test/test_common.mk b/test/test_common.mk index 5a10084d..3213d6f5 100644 --- a/test/test_common.mk +++ b/test/test_common.mk @@ -19,7 +19,7 @@ READELF_FILE := bin.readelf CLANG_BIN_PATH := $(shell clang -print-prog-name=clang) LLVM_PATH := $(abspath $(dir $(CLANG_BIN_PATH))../) -C_FLAGS = -Wall -O2 -fPIC $(EXTRA_C_FLAGS) +C_FLAGS = -Wall -I../include -O2 -fPIC $(EXTRA_C_FLAGS) C_FLAGS += -Xclang -load -Xclang $(LLVM_PATH)/lib/LLVMMDSFIIRInserter.so LINK_FLAGS = $(C_FLAGS) -pie -locclum_stub $(EXTRA_LINK_FLAGS) diff --git a/test/time/main.c b/test/time/main.c index aa7d253a..f21c8902 100644 --- a/test/time/main.c +++ b/test/time/main.c @@ -1,9 +1,43 @@ #include -#include +#include +#include "test.h" -int main(int argc, const char* argv[]) { +// ============================================================================ +// Test cases for gettimeofday +// ============================================================================ + +int test_gettimeofday() { struct timeval tv; - gettimeofday(&tv, NULL); - printf("sec = %lu, usec = %lu\n", tv.tv_sec, tv.tv_usec); + if (gettimeofday(&tv, NULL)) { + throw_error("gettimeofday failed"); + } return 0; } + +// ============================================================================ +// Test cases for clock_gettime +// ============================================================================ + +int test_clock_gettime() { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts)) { + throw_error("clock_gettime(CLOCK_REALTIME, ...) failed"); + } + if (clock_gettime(CLOCK_MONOTONIC, &ts)) { + throw_error("clock_gettime(CLOCK_MONOTONIC, ...) failed"); + } + return 0; +} + +// ============================================================================ +// Test suite +// ============================================================================ + +static test_case_t test_cases[] = { + TEST_CASE(test_gettimeofday), + TEST_CASE(test_clock_gettime), +}; + +int main() { + return test_suite_run(test_cases, ARRAY_SIZE(test_cases)); +}