Received: by 10.223.164.202 with SMTP id h10csp4168254wrb; Mon, 20 Nov 2017 10:59:22 -0800 (PST) X-Google-Smtp-Source: AGs4zMaVWq2Au99mf/HlQJOD1a/PhCeNtuuyExwaZ6IVNcVICrrB4OE8DThIG1Fhfv3IuY86QGE4 X-Received: by 10.99.96.216 with SMTP id u207mr14449166pgb.406.1511204362135; Mon, 20 Nov 2017 10:59:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511204362; cv=none; d=google.com; s=arc-20160816; b=ZIvNxs8xyhEqs/OlkEu5bQzg9R9QyVVPInpW/XHucvxwnwmdPRkd1QnSMqMEqoaUqy ZXlXVAUNnZyuzMAhWUjH6FKkcB7KVCMmCm5YjqgqHn+M+Oyf8CPTooC1qF2DDaRoGlHr NNncSGwZLAc6IJ26Gg3jw3cdpplRmo4Z2GtbcJc5G40kPS/lk3Ua44rbpNBqDEjUUOoS aCvKIFy7c8pu1P1Ap5he/d5bXU5dX8L9AUyNI3jDSLr/IjM6Zm9OcGfec7XIBee+loQK 0vcMhhrKTpxQcS5y0vJi59nf+uwlFs4oGwGRwk1nvEBWlR9++Ipl6VUC4KA2JSADWMzE KMgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:from:cc:references:in-reply-to :message-id:date:subject:arc-authentication-results; bh=U4eR8vjpdNiZ7gS9rcKOiaRV8YymwATxDS8E479UDYs=; b=hGREUNSK5DfgNoGyWTM5TbZclP23KAXGzkruR7WtYayILELFHL1RmvRXd7W3nBVXf+ sHurzeqRRDEvX211Xl/hdK0gCCLb7XQYv8C454djz7ZdOXH5fs9L/q2vj/ub/Sp1mT7b QsDaHKLPFtv7991RYS0ZldKGYI5TJvHNeoBK5V6d64KX7D5Bb9NHjJoMgezczPRpEvfe S/lC02UQDPfQcrPTezhLYr5p5RqEp0by3iSJaaPU+TA3j+ggQehRe5AwdLzMhp+clLGd 7KzCUD6w3w+soa+g+ckR7VZ7yi2kGgHyRycpg+lQc732BydDwPGoyInRpCmPjMSJVXzg B3Gg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q9si5496026pgf.732.2017.11.20.10.59.12; Mon, 20 Nov 2017 10:59:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752343AbdKTS6G (ORCPT + 67 others); Mon, 20 Nov 2017 13:58:06 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:39641 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752298AbdKTS6D (ORCPT ); Mon, 20 Nov 2017 13:58:03 -0500 Received: by mail-pf0-f194.google.com with SMTP id l24so7942432pfj.6 for ; Mon, 20 Nov 2017 10:58:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:date:message-id:in-reply-to:references :cc:from:to; bh=U4eR8vjpdNiZ7gS9rcKOiaRV8YymwATxDS8E479UDYs=; b=HyiGO0ZGOxIZVs9TIfHoOF2SB9k2gR/EcLKwifLXesaWkOJYdg/FoLuQ3dLwfotRqm 3YOME9+GriZCmGWeLYbzkMoemziHF4w3L5qHFEarrI+NO87cuukhZ7kuWnEfg78+IXxb /7hYMxdSgf9QAfcAnVGf27hT5V8CZiAJEUx0A9BCjUqQwEmctqB9AbWrdJgcRPm0gDKB 53tR9NHwICjWOeQSZla1+3cvn652EcXBTPTeFBDJfFTJ4Qi/jw/HdFk+28MHB+tIn8pE A1vciU5Y2xCLm/1xeDqbn9ZAZx6eQpzw6f95z388jWnhHlLYaJL1zfUd0juSgbOuoPMx 6itA== X-Gm-Message-State: AJaThX4kRXj5v2BvL3wWtLMsceh0h7GBS99+LUMasfFW0MYUYy9QRsKb e7pCYp94+X/gUHDsu05RYOTUWQ== X-Received: by 10.84.212.8 with SMTP id d8mr14446213pli.75.1511204282474; Mon, 20 Nov 2017 10:58:02 -0800 (PST) Received: from localhost ([12.206.222.5]) by smtp.gmail.com with ESMTPSA id a23sm11610592pfa.177.2017.11.20.10.58.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Nov 2017 10:58:01 -0800 (PST) Subject: [PATCH 4/4] RISC-V: Allow userspace to flush the instruction cache Date: Mon, 20 Nov 2017 10:57:45 -0800 Message-Id: <20171120185745.30795-5-palmer@sifive.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171120185745.30795-1-palmer@sifive.com> References: <20171120185745.30795-1-palmer@sifive.com> Cc: patches@groups.riscv.org, Andrew Waterman , Palmer Dabbelt From: Palmer Dabbelt To: linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andrew Waterman Despite RISC-V having a direct 'fence.i' instruction available to userspace (which we can't trap!), that's not actually viable when running on Linux because the kernel might schedule a process on another hart. There is no way for userspace to handle this without invoking the kernel (as it doesn't know the thread->hart mappings), so we've defined a RISC-V specific system call to flush the instruction cache. This patch adds both a system call and a VDSO entry. If possible, we'd like to avoid having the system call be considered part of the user-facing ABI and instead restrict that to the VDSO entry -- both just in general to avoid having additional user-visible ABI to maintain, and because we'd prefer that users just call the VDSO entry because there might be a better way to do this in the future (ie, one that doesn't require entering the kernel). Signed-off-by: Andrew Waterman Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/cacheflush.h | 6 ++++++ arch/riscv/include/asm/vdso-syscalls.h | 28 ++++++++++++++++++++++++++++ arch/riscv/include/asm/vdso.h | 4 ++++ arch/riscv/kernel/sys_riscv.c | 32 ++++++++++++++++++++++++++++++++ arch/riscv/kernel/syscall_table.c | 2 ++ arch/riscv/kernel/vdso/Makefile | 1 + arch/riscv/kernel/vdso/flush_icache.S | 31 +++++++++++++++++++++++++++++++ arch/riscv/kernel/vdso/vdso.lds.S | 1 + 8 files changed, 105 insertions(+) create mode 100644 arch/riscv/include/asm/vdso-syscalls.h create mode 100644 arch/riscv/kernel/vdso/flush_icache.S diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h index 5c9ed39ee2a2..efd89a88d2d0 100644 --- a/arch/riscv/include/asm/cacheflush.h +++ b/arch/riscv/include/asm/cacheflush.h @@ -52,4 +52,10 @@ void flush_icache_mm(struct mm_struct *mm, bool local); #endif /* CONFIG_SMP */ +/* + * Bits in sys_riscv_flush_icache()'s flags argument. + */ +#define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL +#define SYS_RISCV_FLUSH_ICACHE_ALL (SYS_RISCV_FLUSH_ICACHE_LOCAL) + #endif /* _ASM_RISCV_CACHEFLUSH_H */ diff --git a/arch/riscv/include/asm/vdso-syscalls.h b/arch/riscv/include/asm/vdso-syscalls.h new file mode 100644 index 000000000000..a2ccf1894929 --- /dev/null +++ b/arch/riscv/include/asm/vdso-syscalls.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 SiFive + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _ASM_RISCV_VDSO_SYSCALLS_H +#define _ASM_RISCV_VDSO_SYSCALLS_H + +#ifdef CONFIG_SMP + +/* These syscalls are only used by the vDSO and are not in the uapi. */ +#define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15) +__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache) + +#endif + +#endif /* _ASM_RISCV_VDSO_H */ diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h index 602f61257553..541544d64c33 100644 --- a/arch/riscv/include/asm/vdso.h +++ b/arch/riscv/include/asm/vdso.h @@ -38,4 +38,8 @@ struct vdso_data { (void __user *)((unsigned long)(base) + __vdso_##name); \ }) +#ifdef CONFIG_SMP +asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t); +#endif + #endif /* _ASM_RISCV_VDSO_H */ diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c index 4351be7d0533..c6c037eabaf6 100644 --- a/arch/riscv/kernel/sys_riscv.c +++ b/arch/riscv/kernel/sys_riscv.c @@ -16,6 +16,7 @@ #include #include #include +#include static long riscv_sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, @@ -47,3 +48,34 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 12); } #endif /* !CONFIG_64BIT */ + +#ifdef CONFIG_SMP +/* + * Allows the instruction cache to be flushed from userspace. Despite RISC-V + * having a direct 'fence.i' instruction available to userspace (which we + * can't trap!), that's not actually viable when running on Linux because the + * kernel might schedule a process on another hart. There is no way for + * userspace to handle this without invoking the kernel (as it doesn't know the + * thread->hart mappings), so we've defined a RISC-V specific system call to + * flush the instruction cache. + * + * sys_riscv_flush_icache() is defined to flush the instruction cache over an + * address range, with the flush applying to either all threads or just the + * caller. We don't currently do anything with the address range, that's just + * in there for forwards compatibility. + */ +SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end, + uintptr_t, flags) +{ + struct mm_struct *mm = current->mm; + bool local = (flags & SYS_RISCV_FLUSH_ICACHE_LOCAL) != 0; + + /* Check the reserved flags. */ + if (unlikely(flags & !SYS_RISCV_FLUSH_ICACHE_ALL)) + return -EINVAL; + + flush_icache_mm(mm, local); + + return 0; +} +#endif diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c index 4e30dc5fb593..a5bd6401f95e 100644 --- a/arch/riscv/kernel/syscall_table.c +++ b/arch/riscv/kernel/syscall_table.c @@ -15,6 +15,7 @@ #include #include #include +#include #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), @@ -22,4 +23,5 @@ void *sys_call_table[__NR_syscalls] = { [0 ... __NR_syscalls - 1] = sys_ni_syscall, #include +#include }; diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile index 2dcc4f3070bc..324568d33921 100644 --- a/arch/riscv/kernel/vdso/Makefile +++ b/arch/riscv/kernel/vdso/Makefile @@ -6,6 +6,7 @@ vdso-syms += gettimeofday vdso-syms += clock_gettime vdso-syms += clock_getres vdso-syms += getcpu +vdso-syms += flush_icache # Files to link into the vdso obj-vdso = $(patsubst %, %.o, $(vdso-syms)) diff --git a/arch/riscv/kernel/vdso/flush_icache.S b/arch/riscv/kernel/vdso/flush_icache.S new file mode 100644 index 000000000000..b0fbad74e873 --- /dev/null +++ b/arch/riscv/kernel/vdso/flush_icache.S @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 SiFive + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + + .text +/* int __vdso_flush_icache(void *start, void *end, unsigned long flags); */ +ENTRY(__vdso_flush_icache) + .cfi_startproc +#ifdef CONFIG_SMP + li a7, __NR_riscv_flush_icache + ecall +#else + fence.i + li a0, 0 +#endif + ret + .cfi_endproc +ENDPROC(__vdso_flush_icache) diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S index c7543c6a00f9..cd1d47e0724b 100644 --- a/arch/riscv/kernel/vdso/vdso.lds.S +++ b/arch/riscv/kernel/vdso/vdso.lds.S @@ -74,6 +74,7 @@ VERSION __vdso_clock_gettime; __vdso_clock_getres; __vdso_getcpu; + __vdso_flush_icache; local: *; }; } -- 2.13.6 From 1584531174828335859@xxx Sun Nov 19 21:24:44 +0000 2017 X-GM-THRID: 1584531174828335859 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread