It turns out that we weren't actually hooking sys_riscv_flush_icache into the syscall table, which results in any flush_icache() call that escapes the vDSO to silently do nothing.
Changes since v1: * sys_riscv_flush_icache is now defined even when SMP=n, which allows this patch set to build against SMP=n and SMP=y.