Perform I-Cache Maintenance on RISC-V (#5698)
* re modify this. * fix compile failure. * fix unused warning.
This commit is contained in:
@@ -21,3 +21,11 @@ features = [
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "android"))'.dependencies]
|
||||
libc = "0.2.42"
|
||||
|
||||
[features]
|
||||
# Most modern CPUs are SMP (multicore). However, when only one core is present,
|
||||
# some aspects of coherence are much cheaper. For example, RISC-V can use
|
||||
# one instruction `fence.i` rather than a syscall that invokes all other cores.
|
||||
# This feature enables such optimizations, but the resulting program will *only*
|
||||
# be safe to run on one-core systems.
|
||||
one-core = []
|
||||
@@ -91,6 +91,46 @@ mod details {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[cfg(all(target_arch = "riscv64", target_os = "linux"))]
|
||||
fn riscv_flush_icache(start: u64, end: u64) -> Result<()> {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "one-core")] {
|
||||
use std::arch::asm;
|
||||
unsafe {
|
||||
asm!("fence.i");
|
||||
};
|
||||
Ok(())
|
||||
} else {
|
||||
match unsafe {
|
||||
libc::syscall(
|
||||
{
|
||||
// The syscall isn't defined in `libc`, so we definfe the syscall number here.
|
||||
// https://github.com/torvalds/linux/search?q=__NR_arch_specific_syscall
|
||||
#[allow(non_upper_case_globals)]
|
||||
const __NR_arch_specific_syscall :i64 = 244;
|
||||
// https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/tools/arch/riscv/include/uapi/asm/unistd.h#L40
|
||||
#[allow(non_upper_case_globals)]
|
||||
const sys_riscv_flush_icache :i64 = __NR_arch_specific_syscall + 15;
|
||||
sys_riscv_flush_icache
|
||||
},
|
||||
// Currently these parameters are not used, but they are still defined.
|
||||
start, // start
|
||||
end, // end
|
||||
{
|
||||
#[allow(non_snake_case)]
|
||||
const SYS_RISCV_FLUSH_ICACHE_LOCAL :i64 = 1;
|
||||
#[allow(non_snake_case)]
|
||||
const SYS_RISCV_FLUSH_ICACHE_ALL :i64 = SYS_RISCV_FLUSH_ICACHE_LOCAL;
|
||||
SYS_RISCV_FLUSH_ICACHE_ALL
|
||||
}, // flags
|
||||
)
|
||||
} {
|
||||
0 => { Ok(()) }
|
||||
_ => Err(std::io::Error::last_os_error()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use details::*;
|
||||
|
||||
@@ -103,6 +143,7 @@ pub(crate) fn clear_cache(_ptr: *const c_void, _len: usize) -> Result<()> {
|
||||
// We should call some implementation of `clear_cache` here.
|
||||
//
|
||||
// See: https://github.com/bytecodealliance/wasmtime/issues/3310
|
||||
|
||||
#[cfg(all(target_arch = "riscv64", target_os = "linux"))]
|
||||
riscv_flush_icache(_ptr as u64, (_ptr as u64) + (_len as u64))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user