Merge pull request #30 from josephlr/uefi

Support x86_64-unknown-uefi
This commit is contained in:
Diggory Hardy 2019-06-17 09:17:35 +01:00 committed by GitHub
commit 0b87a0974b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 12 deletions

View File

@ -106,6 +106,9 @@ matrix:
- rustup target add x86_64-unknown-netbsd
- rustup target add x86_64-unknown-redox
- rustup target add x86_64-fortanix-unknown-sgx
# For no_std targets
- rustup component add rust-src
- cargo install cargo-xbuild || true
script:
- cargo build --target=x86_64-sun-solaris --all-features
- cargo build --target=x86_64-unknown-cloudabi --all-features
@ -114,6 +117,7 @@ matrix:
- cargo build --target=x86_64-unknown-netbsd --all-features
- cargo build --target=x86_64-unknown-redox --all-features
- cargo build --target=x86_64-fortanix-unknown-sgx --all-features
- cargo xbuild --target=x86_64-unknown-uefi
# also test minimum dependency versions are usable
- cargo generate-lockfile -Z minimal-versions
- cargo build --target=x86_64-sun-solaris --all-features
@ -123,6 +127,7 @@ matrix:
- cargo build --target=x86_64-unknown-netbsd --all-features
- cargo build --target=x86_64-unknown-redox --all-features
- cargo build --target=x86_64-fortanix-unknown-sgx --all-features
- cargo xbuild --target=x86_64-unknown-uefi
# Trust cross-built/emulated targets. We must repeat all non-default values.
- rust: stable

View File

@ -39,5 +39,8 @@ stdweb = { version = "0.4.9", optional = true }
[target.wasm32-wasi.dependencies]
libc = "0.2.54"
[target.'cfg(any(target_env = "sgx", target_os = "uefi"))'.dependencies]
lazy_static = { version = "1.3.0", features = ["spin_no_std"] }
[features]
std = []

View File

@ -190,6 +190,7 @@ mod_use!(cfg(target_os = "redox"), use_file);
mod_use!(cfg(target_os = "solaris"), solaris_illumos);
mod_use!(cfg(windows), windows);
mod_use!(cfg(target_env = "sgx"), rdrand);
mod_use!(cfg(all(target_arch = "x86_64", target_os = "uefi")), rdrand);
mod_use!(cfg(target_os = "wasi"), wasi);
mod_use!(
@ -231,6 +232,7 @@ mod_use!(
target_os = "openbsd",
target_os = "redox",
target_os = "solaris",
all(target_arch = "x86_64", target_os = "uefi"),
target_env = "sgx",
windows,
all(

View File

@ -9,11 +9,9 @@
//! Implementation for SGX using RDRAND instruction
use crate::Error;
use core::mem;
use core::arch::x86_64::_rdrand64_step;
use core::arch::x86_64::{__cpuid, _rdrand64_step};
use core::num::NonZeroU32;
#[cfg(not(target_feature = "rdrand"))]
compile_error!("enable rdrand target feature!");
use lazy_static::lazy_static;
// Recommendation from "Intel® Digital Random Number Generator (DRNG) Software
// Implementation Guide" - Section 5.2.1 and "Intel® 64 and IA-32 Architectures
@ -21,21 +19,51 @@ compile_error!("enable rdrand target feature!");
const RETRY_LIMIT: usize = 10;
const WORD_SIZE: usize = mem::size_of::<u64>();
fn rdrand() -> Result<[u8; WORD_SIZE], Error> {
#[target_feature(enable = "rdrand")]
unsafe fn rdrand() -> Result<[u8; WORD_SIZE], Error> {
for _ in 0..RETRY_LIMIT {
unsafe {
// SAFETY: we've checked RDRAND support, and u64 can have any value.
let mut el = mem::uninitialized();
if _rdrand64_step(&mut el) == 1 {
return Ok(el.to_ne_bytes());
}
};
let mut el = mem::uninitialized();
if _rdrand64_step(&mut el) == 1 {
return Ok(el.to_ne_bytes());
}
}
error!("RDRAND failed, CPU issue likely");
Err(Error::UNKNOWN)
}
// "rdrand" target feature requires "+rdrnd" flag, see https://github.com/rust-lang/rust/issues/49653.
#[cfg(all(target_env = "sgx", not(target_feature = "rdrand")))]
compile_error!(
"SGX targets require 'rdrand' target feature. Enable by using -C target-feature=+rdrnd."
);
// TODO use is_x86_feature_detected!("rdrand") when that works in core. See:
// https://github.com/rust-lang-nursery/stdsimd/issues/464
fn is_rdrand_supported() -> bool {
if cfg!(target_feature = "rdrand") {
true
} else {
// SAFETY: All x86_64 CPUs support CPUID leaf 1
const FLAG: u32 = 1 << 30;
lazy_static! {
static ref HAS_RDRAND: bool = unsafe { __cpuid(1).ecx & FLAG != 0 };
}
*HAS_RDRAND
}
}
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
if !is_rdrand_supported() {
return Err(Error::UNAVAILABLE);
}
// SAFETY: After this point, rdrand is supported, so calling the rdrand
// functions is not undefined behavior.
unsafe { rdrand_exact(dest) }
}
#[target_feature(enable = "rdrand")]
unsafe fn rdrand_exact(dest: &mut [u8]) -> Result<(), Error> {
// We use chunks_exact_mut instead of chunks_mut as it allows almost all
// calls to memcpy to be elided by the compiler.
let mut chunks = dest.chunks_exact_mut(WORD_SIZE);