Perform I-Cache Maintenance on RISC-V (#5698)

* re modify this.

* fix compile failure.

* fix unused warning.
This commit is contained in:
yuyang
2023-02-03 08:11:24 +08:00
committed by GitHub
parent 426c49b8e3
commit fd67ccf9cd
2 changed files with 50 additions and 1 deletions

View File

@@ -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 = []

View File

@@ -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(())
}