On Sat, Sep 04 2021, Jeremie Courreges-Anglas <j...@wxcvbn.org> wrote: > The first problem I was able to diagnose using egdb on riscv was > lang/python/2.7 using libffi and aborting in libcompiler-rt (the > compilerrt_abort() call below). > > --8<-- > #elif defined(__riscv) && defined(__linux__) > #define __NR_riscv_flush_icache (244 + 15) > register void *start_reg __asm("a0") = start; > const register void *end_reg __asm("a1") = end; > const register long flags __asm("a2") = 0; > const register long syscall_nr __asm("a7") = __NR_riscv_flush_icache; > __asm __volatile("ecall" > : "=r"(start_reg) > : "r"(start_reg), "r"(end_reg), "r"(flags), > "r"(syscall_nr)); > assert(start_reg == 0 && "Cache flush syscall failed."); > #else > #if __APPLE__ > // On Darwin, sys_icache_invalidate() provides this functionality > sys_icache_invalidate(start, end - start); > #else > compilerrt_abort(); > #endif > #endif > } > -->8-- > > The ususal way we provide this functionality is through sysarch(2). > Since the RISC-V ISA only provides fence.i as an extension, and that > fence.i doesn't support parameters to only act on a specific range, > I figured I would reflect that in the API for the sake of clarity. > > If people expect the spec to evolve and new CPUs to ship with > support for finer-grained invalidation, a more forward-looking approach > would be to mimic ARM_SYNC_ICACHE and struct arm_sync_icache_args, and > let the kernel ignore the parameters if appropriate. > > In the diff below I'm moving the core of the code to cpu.c since it > doesn't look pmap-specific, but I don't feel strongly about it. > I haven't even built this since I'm still on the way back from k2k21 but > I figured I'd ask for feedback early. Input welcome.
Updated diff that builds (one #include was missing) and that appears to do the right thing. The diff also includes the compiler-rt change. Index: gnu/llvm/compiler-rt/lib/builtins/clear_cache.c =================================================================== RCS file: /cvs/src/gnu/llvm/compiler-rt/lib/builtins/clear_cache.c,v retrieving revision 1.3 diff -u -p -r1.3 clear_cache.c --- gnu/llvm/compiler-rt/lib/builtins/clear_cache.c 2 Jan 2021 17:14:13 -0000 1.3 +++ gnu/llvm/compiler-rt/lib/builtins/clear_cache.c 19 Aug 2021 17:28:40 -0000 @@ -33,7 +33,7 @@ uintptr_t GetCurrentProcess(void); #include <machine/sysarch.h> #endif -#if defined(__OpenBSD__) && (defined(__arm__) || defined(__mips__)) +#if defined(__OpenBSD__) && (defined(__arm__) || defined(__mips__) || defined(__riscv)) // clang-format off #include <sys/types.h> #include <machine/sysarch.h> @@ -157,6 +157,8 @@ void __clear_cache(void *start, void *en : "=r"(start_reg) : "r"(start_reg), "r"(end_reg), "r"(flags), "r"(syscall_nr)); assert(start_reg == 0 && "Cache flush syscall failed."); +#elif defined(__riscv) && defined(__OpenBSD__) + sysarch(RISCV_SYNC_ICACHE_ALL, NULL); #else #if __APPLE__ // On Darwin, sys_icache_invalidate() provides this functionality Index: sys/arch/riscv64/include/cpufunc.h =================================================================== RCS file: /cvs/src/sys/arch/riscv64/include/cpufunc.h,v retrieving revision 1.4 diff -u -p -r1.4 cpufunc.h --- sys/arch/riscv64/include/cpufunc.h 18 May 2021 09:14:49 -0000 1.4 +++ sys/arch/riscv64/include/cpufunc.h 18 Aug 2021 23:24:59 -0000 @@ -92,6 +92,7 @@ extern int64_t icache_line_size; extern void (*cpu_dcache_wbinv_range)(paddr_t, psize_t); extern void (*cpu_dcache_inv_range)(paddr_t, psize_t); extern void (*cpu_dcache_wb_range)(paddr_t, psize_t); +extern void icache_flush(void); static __inline void load_satp(uint64_t val) Index: sys/arch/riscv64/include/sysarch.h =================================================================== RCS file: sys/arch/riscv64/include/sysarch.h diff -N sys/arch/riscv64/include/sysarch.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/riscv64/include/sysarch.h 18 Aug 2021 23:24:59 -0000 @@ -0,0 +1,38 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2021 Jeremie Courreges-Anglas <j...@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _RISCV64_SYSARCH_H_ +#define _RISCV64_SYSARCH_H_ + +/* + * Architecture specific syscalls (riscv64) + */ + +#define RISCV_SYNC_ICACHE_ALL 0 + +#ifndef _KERNEL + +#include <sys/cdefs.h> + +__BEGIN_DECLS +int sysarch(int, void *); +__END_DECLS + +#endif /* _KERNEL */ + +#endif /* _RISCV64_SYSARCH_H_ */ Index: sys/arch/riscv64/riscv64/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v retrieving revision 1.11 diff -u -p -r1.11 cpu.c --- sys/arch/riscv64/riscv64/cpu.c 24 Jul 2021 18:15:13 -0000 1.11 +++ sys/arch/riscv64/riscv64/cpu.c 18 Aug 2021 23:24:59 -0000 @@ -26,6 +26,7 @@ #include <uvm/uvm.h> +#include <machine/cpufunc.h> #include <machine/fdt.h> #include <machine/sbi.h> @@ -300,6 +301,38 @@ cpu_cache_nop_range(paddr_t pa, psize_t void (*cpu_dcache_wbinv_range)(paddr_t, psize_t) = cpu_cache_nop_range; void (*cpu_dcache_inv_range)(paddr_t, psize_t) = cpu_cache_nop_range; void (*cpu_dcache_wb_range)(paddr_t, psize_t) = cpu_cache_nop_range; + +void +icache_flush(void) +{ +#ifdef MULTIPROCESSOR + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + unsigned long hart_mask = 0; +#endif + + fence_i(); + +#ifdef MULTIPROCESSOR + CPU_INFO_FOREACH(cii, ci) { + if (ci == curcpu()) + continue; + hart_mask |= (1UL << ci->ci_hartid); + } + + /* + * From the RISC-V ISA: + * + * To make a store to instruction memory visible to all RISC-V + * harts, the writing hart has to execute a data FENCE before + * requesting that all remote RISC-V harts execute a FENCE.I. + */ + if (hart_mask != 0) { + membar_sync(); + sbi_remote_fence_i(&hart_mask); + } +#endif +} #ifdef MULTIPROCESSOR Index: sys/arch/riscv64/riscv64/machdep.c =================================================================== RCS file: /cvs/src/sys/arch/riscv64/riscv64/machdep.c,v retrieving revision 1.25 diff -u -p -r1.25 machdep.c --- sys/arch/riscv64/riscv64/machdep.c 2 Jul 2021 14:50:18 -0000 1.25 +++ sys/arch/riscv64/riscv64/machdep.c 19 Aug 2021 23:29:41 -0000 @@ -42,8 +42,10 @@ #include <machine/param.h> #include <machine/bootconfig.h> #include <machine/bus.h> +#include <machine/cpufunc.h> #include <machine/riscv64var.h> #include <machine/sbi.h> +#include <machine/sysarch.h> #include <machine/db_machdep.h> #include <ddb/db_extern.h> @@ -517,6 +519,9 @@ sys_sysarch(struct proc *p, void *v, reg int error = 0; switch (SCARG(uap, op)) { + case RISCV_SYNC_ICACHE_ALL: + icache_flush(); + break; default: error = EINVAL; break; Index: sys/arch/riscv64/riscv64/pmap.c =================================================================== RCS file: /cvs/src/sys/arch/riscv64/riscv64/pmap.c,v retrieving revision 1.19 diff -u -p -r1.19 pmap.c --- sys/arch/riscv64/riscv64/pmap.c 2 Aug 2021 19:07:29 -0000 1.19 +++ sys/arch/riscv64/riscv64/pmap.c 19 Aug 2021 17:35:45 -0000 @@ -98,38 +98,6 @@ tlb_flush_page(pmap_t pm, vaddr_t va) do_tlb_flush_page(pm, va); } -static inline void -icache_flush(void) -{ -#ifdef MULTIPROCESSOR - CPU_INFO_ITERATOR cii; - struct cpu_info *ci; - unsigned long hart_mask = 0; -#endif - - fence_i(); - -#ifdef MULTIPROCESSOR - CPU_INFO_FOREACH(cii, ci) { - if (ci == curcpu()) - continue; - hart_mask |= (1UL << ci->ci_hartid); - } - - /* - * From the RISC-V ISA: - * - * To make a store to instruction memory visible to all RISC-V - * harts, the writing hart has to execute a data FENCE before - * requesting that all remote RISC-V harts execute a FENCE.I. - */ - if (hart_mask != 0) { - membar_sync(); - sbi_remote_fence_i(&hart_mask); - } -#endif -} - struct pmap kernel_pmap_; LIST_HEAD(pted_pv_head, pte_desc); -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE