Enable MPX
This commit is contained in:
parent
9389b702ba
commit
e5d3ab3cf9
@ -21,7 +21,6 @@ extern crate lazy_static;
|
|||||||
use std::ffi::CStr; // a borrowed C string
|
use std::ffi::CStr; // a borrowed C string
|
||||||
use std::backtrace::{self, PrintFormat};
|
use std::backtrace::{self, PrintFormat};
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
|
||||||
use sgx_types::*;
|
use sgx_types::*;
|
||||||
use sgx_trts::libc;
|
use sgx_trts::libc;
|
||||||
|
|
||||||
@ -32,27 +31,28 @@ mod fs;
|
|||||||
mod process;
|
mod process;
|
||||||
mod syscall;
|
mod syscall;
|
||||||
mod vm;
|
mod vm;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
use prelude::*;
|
||||||
|
|
||||||
/// Export system calls
|
/// Export system calls
|
||||||
pub use syscall::*;
|
pub use syscall::*;
|
||||||
|
|
||||||
|
// TODO: return meaningful exit code
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn libos_boot(path_buf: *const i8) -> i32 {
|
pub extern "C" fn libos_boot(path_buf: *const i8) -> i32 {
|
||||||
let path_str = unsafe {
|
let path_str = unsafe {
|
||||||
CStr::from_ptr(path_buf).to_string_lossy().into_owned()
|
CStr::from_ptr(path_buf).to_string_lossy().into_owned()
|
||||||
};
|
};
|
||||||
println!("LibOS boots: {}", path_str);
|
|
||||||
|
|
||||||
let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short);
|
let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short);
|
||||||
panic::catch_unwind(||{
|
panic::catch_unwind(||{
|
||||||
backtrace::__rust_begin_short_backtrace(||{
|
backtrace::__rust_begin_short_backtrace(||{
|
||||||
let argv = std::vec::Vec::new();
|
match do_boot(&path_str) {
|
||||||
let envp = std::vec::Vec::new();
|
Ok(()) => 0,
|
||||||
process::do_spawn(&path_str, &argv, &envp);
|
Err(err) => err.errno.as_retval() /* Normal error */,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}).ok();
|
}).unwrap_or(-1 /* Fatal error */)
|
||||||
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -60,10 +60,28 @@ pub extern "C" fn libos_run() -> i32 {
|
|||||||
let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short);
|
let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short);
|
||||||
panic::catch_unwind(||{
|
panic::catch_unwind(||{
|
||||||
backtrace::__rust_begin_short_backtrace(||{
|
backtrace::__rust_begin_short_backtrace(||{
|
||||||
let _ = process::run_task();
|
match do_run() {
|
||||||
|
Ok(()) => 0,
|
||||||
|
Err(err) => err.errno.as_retval() /* Normal error */,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}).ok();
|
}).unwrap_or(-1 /* Fatal error */)
|
||||||
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: make sure do_boot can only be called once
|
||||||
|
fn do_boot(path_str: &str) -> Result<(), Error> {
|
||||||
|
util::mpx_enable()?;
|
||||||
|
|
||||||
|
let argv = std::vec::Vec::new();
|
||||||
|
let envp = std::vec::Vec::new();
|
||||||
|
process::do_spawn(&path_str, &argv, &envp)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make sure do_run() cannot be called before do_boot()
|
||||||
|
fn do_run() -> Result<(), Error> {
|
||||||
|
process::run_task()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
5
src/libos/src/util/mod.rs
Normal file
5
src/libos/src/util/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
use prelude::*;
|
||||||
|
|
||||||
|
pub use self::mpx_util::{*};
|
||||||
|
|
||||||
|
mod mpx_util;
|
100
src/libos/src/util/mpx_util.c
Normal file
100
src/libos/src/util/mpx_util.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include "mpx_util.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define data structures for the part of XSAVE area that are relevant
|
||||||
|
* to enabling MPX
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t xstate_bv;
|
||||||
|
uint64_t __irrelevant[2];
|
||||||
|
uint64_t __reserved[5];
|
||||||
|
} __attribute__ ((packed)) xsave_header_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t __irrelevant[8];
|
||||||
|
} __attribute__ ((packed)) bndreg_t ;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t enable: 1;
|
||||||
|
uint64_t bndpreserve: 1;
|
||||||
|
uint64_t __reserved: 10;
|
||||||
|
uint64_t __irrelevant: 52;
|
||||||
|
} __attribute__ ((packed)) bndcfgu_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bndcfgu_t bndcfgu;
|
||||||
|
uint64_t __irrelevant;
|
||||||
|
} __attribute__((packed)) bndcsr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t __irrelevant0[512];
|
||||||
|
xsave_header_t header;
|
||||||
|
uint8_t __irrelevant1[256];
|
||||||
|
uint8_t __irrelevant2[128];
|
||||||
|
bndreg_t bndreg;
|
||||||
|
bndcsr_t bndcsr;
|
||||||
|
} __attribute__ ((packed, __aligned__(64))) xsave_area_t ;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore the state components of CPU specified in rfbm from xsave_area.
|
||||||
|
*
|
||||||
|
* rfbm is the requested-feature bitmap, whose bits specifies which state
|
||||||
|
* components are to restored by this instruction.
|
||||||
|
*/
|
||||||
|
static void xrstor(xsave_area_t* xsave_area, uint64_t rfbm) {
|
||||||
|
uint32_t rfbm_l= rfbm;
|
||||||
|
uint32_t rfbm_h = rfbm >> 32;
|
||||||
|
|
||||||
|
#define REX_PREFIX "0x48, "
|
||||||
|
#define XRSTOR64 REX_PREFIX "0x0f,0xae,0x2f "
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".byte " XRSTOR64 "\n\t"
|
||||||
|
:
|
||||||
|
: "D" (xsave_area), "m" (*xsave_area), "a" (rfbm), "d" (rfbm)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The state component bitmaps for MPX
|
||||||
|
*
|
||||||
|
* The state component 3 (i.e., bit 3) is BNDREG state, which consists of the
|
||||||
|
* four MPX bound registers BND0-BND3.
|
||||||
|
*
|
||||||
|
* The state component 4 (i.e., bit 4) is BNDCSR state, which consists of the
|
||||||
|
* one MPX configuration register BNDCFGU and one MPX status register
|
||||||
|
* BNDSTATUS.
|
||||||
|
* */
|
||||||
|
#define MPX_BNDREG_COMPONENT_MASK (0x08UL)
|
||||||
|
#define MPX_BNDCSR_COMPONENT_MASK (0x10UL)
|
||||||
|
#define MPX_ALL_COMPONENT_MASK (MPX_BNDCSR_COMPONENT_MASK | \
|
||||||
|
MPX_BNDREG_COMPONENT_MASK)
|
||||||
|
|
||||||
|
int __mpx_enable(void) {
|
||||||
|
xsave_area_t xsave_area;
|
||||||
|
memset(&xsave_area, 0, sizeof(xsave_area));
|
||||||
|
|
||||||
|
/* Initialize MPX states
|
||||||
|
*
|
||||||
|
* xrestor initializes state component i if rfbm[i] = 1 and
|
||||||
|
* xsave_area.header.xstate_bv[i] = 0 */
|
||||||
|
uint64_t rfbm = MPX_ALL_COMPONENT_MASK;
|
||||||
|
xrstor(&xsave_area, rfbm);
|
||||||
|
|
||||||
|
/* xrestor updates state component i if rfbm[i] = 1 and
|
||||||
|
* xsave_area.header.xstate_bv[i] = 1 */
|
||||||
|
xsave_area.header.xstate_bv = MPX_BNDCSR_COMPONENT_MASK;
|
||||||
|
/* Set enable bit to 1 to enable MPX */
|
||||||
|
xsave_area.bndcsr.bndcfgu.enable = 1;
|
||||||
|
/* Set bndpreserve bit to 1 so that BND0-BND3 remain unchanged upon
|
||||||
|
* control flow transfer instructions (e.g., call, jmp, etc.). */
|
||||||
|
xsave_area.bndcsr.bndcfgu.bndpreserve = 1;
|
||||||
|
/* Set BNDCSR state component so that MPX is enabled. */
|
||||||
|
rfbm = MPX_BNDCSR_COMPONENT_MASK;
|
||||||
|
xrstor(&xsave_area, rfbm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
34
src/libos/src/util/mpx_util.h
Normal file
34
src/libos/src/util/mpx_util.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __MPX_UTIL__
|
||||||
|
#define __MPX_UTIL__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable the use of MPX bound registers bnd0-bnd3 and bound instructions
|
||||||
|
* bndmk, bndcl and bndcu. */
|
||||||
|
int __mpx_enable(void);
|
||||||
|
|
||||||
|
/* Make a new bound in bnd<i>*/
|
||||||
|
void __mpx_bndmk0(unsigned long base, unsigned long size);
|
||||||
|
void __mpx_bndmk1(unsigned long base, unsigned long size);
|
||||||
|
void __mpx_bndmk2(unsigned long base, unsigned long size);
|
||||||
|
void __mpx_bndmk3(unsigned long base, unsigned long size);
|
||||||
|
|
||||||
|
/* Check x against the lower bound of bnd<i>*/
|
||||||
|
void __mpx_bndcl0(unsigned long x);
|
||||||
|
void __mpx_bndcl1(unsigned long x);
|
||||||
|
void __mpx_bndcl2(unsigned long x);
|
||||||
|
void __mpx_bndcl3(unsigned long x);
|
||||||
|
|
||||||
|
/* Check x against the upper bound of bnd<i> */
|
||||||
|
void __mpx_bndcu0(unsigned long x);
|
||||||
|
void __mpx_bndcu1(unsigned long x);
|
||||||
|
void __mpx_bndcu2(unsigned long x);
|
||||||
|
void __mpx_bndcu3(unsigned long x);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MPX_UTIL__ */
|
66
src/libos/src/util/mpx_util.rs
Normal file
66
src/libos/src/util/mpx_util.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn mpx_enable() -> Result<(), Error> {
|
||||||
|
match unsafe { __mpx_enable () } {
|
||||||
|
0 => { Ok(()) }
|
||||||
|
_ => { errno!(EPERM, "MPX cannot be enabled") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MpxReg {
|
||||||
|
BND0,
|
||||||
|
BND1,
|
||||||
|
BND2,
|
||||||
|
BND3,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mpx_bndmk(bndreg: MpxReg, base: usize, size: usize) -> Result<(), Error> {
|
||||||
|
/* Check whether the upper bound overflows the max of 64-bit */
|
||||||
|
if base.checked_add(size).is_none() {
|
||||||
|
return errno!(ERANGE, "Upper bound overflows");
|
||||||
|
}
|
||||||
|
|
||||||
|
match bndreg {
|
||||||
|
MpxReg::BND0 => unsafe { __mpx_bndmk0(base, size) },
|
||||||
|
MpxReg::BND1 => unsafe { __mpx_bndmk1(base, size) },
|
||||||
|
MpxReg::BND2 => unsafe { __mpx_bndmk2(base, size) },
|
||||||
|
MpxReg::BND3 => unsafe { __mpx_bndmk3(base, size) },
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mpx_bndcl(bndreg: MpxReg, addr: usize) {
|
||||||
|
match bndreg {
|
||||||
|
MpxReg::BND0 => unsafe { __mpx_bndcl0(addr) },
|
||||||
|
MpxReg::BND1 => unsafe { __mpx_bndcl1(addr) },
|
||||||
|
MpxReg::BND2 => unsafe { __mpx_bndcl2(addr) },
|
||||||
|
MpxReg::BND3 => unsafe { __mpx_bndcl3(addr) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mpx_bndcu(bndreg: MpxReg, addr: usize) {
|
||||||
|
match bndreg {
|
||||||
|
MpxReg::BND0 => unsafe { __mpx_bndcu0(addr) },
|
||||||
|
MpxReg::BND1 => unsafe { __mpx_bndcu1(addr) },
|
||||||
|
MpxReg::BND2 => unsafe { __mpx_bndcu2(addr) },
|
||||||
|
MpxReg::BND3 => unsafe { __mpx_bndcu3(addr) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern {
|
||||||
|
// See mpx_util.h
|
||||||
|
fn __mpx_enable() -> i32;
|
||||||
|
fn __mpx_bndmk0(base: usize, size: usize);
|
||||||
|
fn __mpx_bndmk1(base: usize, size: usize);
|
||||||
|
fn __mpx_bndmk2(base: usize, size: usize);
|
||||||
|
fn __mpx_bndmk3(base: usize, size: usize);
|
||||||
|
fn __mpx_bndcl0(x: usize);
|
||||||
|
fn __mpx_bndcl1(x: usize);
|
||||||
|
fn __mpx_bndcl2(x: usize);
|
||||||
|
fn __mpx_bndcl3(x: usize);
|
||||||
|
fn __mpx_bndcu0(x: usize);
|
||||||
|
fn __mpx_bndcu1(x: usize);
|
||||||
|
fn __mpx_bndcu2(x: usize);
|
||||||
|
fn __mpx_bndcu3(x: usize);
|
||||||
|
}
|
81
src/libos/src/util/mpx_util_x86-64.S
Normal file
81
src/libos/src/util/mpx_util_x86-64.S
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
.file "mpx_util_x86-64.S"
|
||||||
|
|
||||||
|
/* For bnd0 */
|
||||||
|
|
||||||
|
.global __mpx_bndmk0
|
||||||
|
.type __mpx_bndmk0, @function
|
||||||
|
__mpx_bndmk0:
|
||||||
|
bndmk (%rdi, %rsi, 1), %bnd0
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcl0
|
||||||
|
.type __mpx_bndcl0, @function
|
||||||
|
__mpx_bndcl0:
|
||||||
|
bndcl %rdi, %bnd0
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcu0
|
||||||
|
.type __mpx_bndcu0, @function
|
||||||
|
__mpx_bndcu0:
|
||||||
|
bndcu %rdi, %bnd0
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* For bnd1 */
|
||||||
|
|
||||||
|
.global __mpx_bndmk1
|
||||||
|
.type __mpx_bndmk1, @function
|
||||||
|
__mpx_bndmk1:
|
||||||
|
bndmk (%rdi, %rsi, 1), %bnd1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcl1
|
||||||
|
.type __mpx_bndcl1, @function
|
||||||
|
__mpx_bndcl1:
|
||||||
|
bndcl %rdi, %bnd1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcu1
|
||||||
|
.type __mpx_bndcu1, @function
|
||||||
|
__mpx_bndcu1:
|
||||||
|
bndcu %rdi, %bnd1
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* For bnd2 */
|
||||||
|
|
||||||
|
.global __mpx_bndmk2
|
||||||
|
.type __mpx_bndmk2, @function
|
||||||
|
__mpx_bndmk2:
|
||||||
|
bndmk (%rdi, %rsi, 1), %bnd2
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcl2
|
||||||
|
.type __mpx_bndcl2, @function
|
||||||
|
__mpx_bndcl2:
|
||||||
|
bndcl %rdi, %bnd2
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcu2
|
||||||
|
.type __mpx_bndcu2, @function
|
||||||
|
__mpx_bndcu2:
|
||||||
|
bndcu %rdi, %bnd2
|
||||||
|
ret
|
||||||
|
|
||||||
|
/* For bnd3 */
|
||||||
|
|
||||||
|
.global __mpx_bndmk3
|
||||||
|
.type __mpx_bndmk3, @function
|
||||||
|
__mpx_bndmk3:
|
||||||
|
bndmk (%rdi, %rsi, 1), %bnd3
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcl3
|
||||||
|
.type __mpx_bndcl3, @function
|
||||||
|
__mpx_bndcl3:
|
||||||
|
bndcl %rdi, %bnd3
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __mpx_bndcu3
|
||||||
|
.type __mpx_bndcu3, @function
|
||||||
|
__mpx_bndcu3:
|
||||||
|
bndcu %rdi, %bnd3
|
||||||
|
ret
|
Loading…
Reference in New Issue
Block a user