From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751706AbcFXQZt (ORCPT ); Fri, 24 Jun 2016 12:25:49 -0400 Received: from foss.arm.com ([217.140.101.70]:59436 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751121AbcFXQZs (ORCPT ); Fri, 24 Jun 2016 12:25:48 -0400 Date: Fri, 24 Jun 2016 17:25:44 +0100 From: Catalin Marinas To: Andre Przywara Cc: Will Deacon , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH 6/6] arm64: trap userspace "dc cvau" cache operation on errata-affected core Message-ID: <20160624162544.GG22608@e104818-lin.cambridge.arm.com> References: <1462812590-4494-1-git-send-email-andre.przywara@arm.com> <1462812590-4494-7-git-send-email-andre.przywara@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1462812590-4494-7-git-send-email-andre.przywara@arm.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, May 09, 2016 at 05:49:50PM +0100, Andre Przywara wrote: > +#define __user_cache_maint(insn, address, res) \ > + asm volatile ( \ > + "1: " insn ", %1\n" \ > + " mov %w0, #0\n" \ > + "2:\n" \ > + " .pushsection .fixup,\"ax\"\n" \ > + " .align 2\n" \ > + "3: mov %w0, %w2\n" \ > + " b 2b\n" \ > + " .popsection\n" \ > + _ASM_EXTABLE(1b, 3b) \ > + : "=r" (res) \ > + : "r" (address), "i" (-EFAULT) \ > + : "memory") I don't think we need the "memory" clobber here. It's not really accessing memory that the compiler controls. > +asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs) > +{ > + unsigned long address; > + int ret; > + > + /* if this is a write with: Op0=1, Op2=1, Op1=3, CRn=7 */ > + if ((esr & 0x01fffc01) == 0x0012dc00) { > + int rt = (esr >> 5) & 0x1f; > + int crm = (esr >> 1) & 0x0f; > + > + address = regs->regs[rt]; > + > + switch (crm) { > + case 11: /* DC CVAU, gets promoted */ > + __user_cache_maint("dc civac", address, ret); > + break; > + case 10: /* DC CVAC, gets promoted */ > + __user_cache_maint("dc civac", address, ret); > + break; > + case 14: /* DC CIVAC */ > + __user_cache_maint("dc civac", address, ret); > + break; > + case 5: /* IC IVAU */ > + __user_cache_maint("ic ivau", address, ret); > + break; > + default: > + force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); > + return; > + } > + } else { > + force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0); > + return; > + } > + > + if (ret) { > + int sig_code; > + > + down_read(¤t->mm->mmap_sem); > + if (find_vma(current->mm, address) == NULL) > + sig_code = SEGV_MAPERR; > + else > + sig_code = SEGV_ACCERR; > + up_read(¤t->mm->mmap_sem); > + > + force_signal_inject(SIGSEGV, sig_code, regs, address); BTW, there is some duplication with set_segfault() in armv8_deprecated.c, could you make this a common function in trap.c? -- Catalin