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]
|
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "android"))'.dependencies]
|
||||||
libc = "0.2.42"
|
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(())
|
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::*;
|
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.
|
// We should call some implementation of `clear_cache` here.
|
||||||
//
|
//
|
||||||
// See: https://github.com/bytecodealliance/wasmtime/issues/3310
|
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user