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::backtrace::{self, PrintFormat}; | ||||
| use std::panic; | ||||
| 
 | ||||
| use sgx_types::*; | ||||
| use sgx_trts::libc; | ||||
| 
 | ||||
| @ -32,27 +31,28 @@ mod fs; | ||||
| mod process; | ||||
| mod syscall; | ||||
| mod vm; | ||||
| mod util; | ||||
| 
 | ||||
| use prelude::*; | ||||
| 
 | ||||
| /// Export system calls
 | ||||
| pub use syscall::*; | ||||
| 
 | ||||
| // TODO: return meaningful exit code
 | ||||
| #[no_mangle] | ||||
| pub extern "C" fn libos_boot(path_buf: *const i8) -> i32 { | ||||
|     let path_str = unsafe { | ||||
|         CStr::from_ptr(path_buf).to_string_lossy().into_owned() | ||||
|     }; | ||||
|     println!("LibOS boots: {}", path_str); | ||||
| 
 | ||||
|     let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short); | ||||
|     panic::catch_unwind(||{ | ||||
|         backtrace::__rust_begin_short_backtrace(||{ | ||||
|             let argv = std::vec::Vec::new(); | ||||
|             let envp = std::vec::Vec::new(); | ||||
|             process::do_spawn(&path_str, &argv, &envp); | ||||
|             match do_boot(&path_str) { | ||||
|                 Ok(()) => 0, | ||||
|                 Err(err) => err.errno.as_retval() /* Normal error */, | ||||
|             } | ||||
|         }) | ||||
|     }).ok(); | ||||
| 
 | ||||
|     0 | ||||
|     }).unwrap_or(-1 /* Fatal error */) | ||||
| } | ||||
| 
 | ||||
| #[no_mangle] | ||||
| @ -60,10 +60,28 @@ pub extern "C" fn libos_run() -> i32 { | ||||
|     let _ = backtrace::enable_backtrace("libocclum.signed.so", PrintFormat::Short); | ||||
|     panic::catch_unwind(||{ | ||||
|         backtrace::__rust_begin_short_backtrace(||{ | ||||
|             let _ = process::run_task(); | ||||
|             match do_run() { | ||||
|                 Ok(()) => 0, | ||||
|                 Err(err) => err.errno.as_retval() /* Normal error */, | ||||
|             } | ||||
|         }) | ||||
|     }).ok(); | ||||
| 
 | ||||
|     0 | ||||
|     }).unwrap_or(-1 /* Fatal error */) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // 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