From patchwork Fri Dec 20 01:36:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 11304639 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F2E5414B7 for ; Fri, 20 Dec 2019 01:37:26 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id B363624676 for ; Fri, 20 Dec 2019 01:37:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="J143fqLZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B363624676 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id C88D68E0186; Thu, 19 Dec 2019 20:37:25 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id C397C8E0184; Thu, 19 Dec 2019 20:37:25 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B50668E0186; Thu, 19 Dec 2019 20:37:25 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0254.hostedemail.com [216.40.44.254]) by kanga.kvack.org (Postfix) with ESMTP id 9C7878E0184 for ; Thu, 19 Dec 2019 20:37:25 -0500 (EST) Received: from smtpin12.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id 3A3234DCA for ; Fri, 20 Dec 2019 01:37:25 +0000 (UTC) X-FDA: 76283807250.12.car09_7aeb31af09552 X-Spam-Summary: 2,0,0,3e9d41b0cf39a2be,d41d8cd98f00b204,30yx8xqmkcayviimuumrk.iusrot03-ssq1giq.uxm@flex--pcc.bounces.google.com,:catalin.marinas@arm.com:pcc@google.com:eugenis@google.com:kcc@google.com:linux-arm-kernel@lists.infradead.org:linux-arch@vger.kernel.org:richard.earnshaw@arm.com:szabolcs.nagy@arm.com:maz@kernel.org:kevin.brodsky@arm.com::andreyknvl@google.com:vincenzo.frascino@arm.com:will@kernel.org,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1311:1313:1314:1345:1359:1437:1513:1515:1516:1518:1521:1535:1544:1593:1594:1605:1711:1730:1747:1777:1792:2198:2199:2393:2553:2559:2562:2693:2731:2899:2900:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3873:3874:4031:4119:4250:4321:5007:6119:6261:6653:6742:7903:9592:9969:10004:11026:11232:11473:11658:11783:11914:12043:12295:12296:12297:12438:12555:12740:12895:12986:14181:14394:14659:14721:21080:21212:21444:21627:21740:21795:21939:21990:30051:30054:30070:30090:30091,0,RBL:209.85.215.202:@flex-- pcc.boun X-HE-Tag: car09_7aeb31af09552 X-Filterd-Recvd-Size: 8196 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) by imf13.hostedemail.com (Postfix) with ESMTP for ; Fri, 20 Dec 2019 01:37:24 +0000 (UTC) Received: by mail-pg1-f202.google.com with SMTP id d9so1996548pgd.10 for ; Thu, 19 Dec 2019 17:37:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=ZRY76nUi493+xuL7Tm0FlcOAyz0Ji1nFyA0Xlgk3AOY=; b=J143fqLZK4/lFzYrCfOIl3+2NbBbgVzLDSm4kEMxZktRis7lgreOCdxYJMeKPplkMr hSvPqstpn+bS83eJywSg4D1b1NnNaZKth1RGcbxQlbJXzymKqYCrpDhspOdmjZMZJAIa EVq6a8wp2BjjNPZhfifKOfE32LIe7ZDb7s537MMfK6RKt8WDX/8AlrlzRPwiyiVL+gdM o+H4bB45aiSA0r6k6yUMWDXVt6zN/mn+OF9zD5qopCyG4wLAKpciAbuN1IyLqfDzPqaR sK9p/dlPN2mXF3aCcHsGnVmUdCw2leQQMuwTxhXwL7/tkka64TwMlx9H42rQnN2jcNOi fntQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=ZRY76nUi493+xuL7Tm0FlcOAyz0Ji1nFyA0Xlgk3AOY=; b=dZl62t4VxEBJ8WnJj4FCE+fihLa1moIi/7IV40miHaMGkE0vQNxFK8Wg1yL22ZsD5B UNPOoqMETr0uaPea4SIBPq13HgyaQlDctkxnpgmGboHEmaUDV+dwKqnRHoYfglz54sse whyf+vz22L5MVk7tab5NqyDFkiFLnEa+rmWC+IrXu2Lqve/q/Vh5M2SjfYYGBWjpeTYo l71Y+9FGNfmZTZ414DBr7FwpXHlAX8U+tefklBEYDvTcD907rxvN3JgEKs58Tf1PMelJ C/5aOOAlPdZ7B0SSW/OPIi1KzHnuFsjht5w0O9qYWFhvwpQFWFB3HzS4UF8hmHY7WQD6 gguQ== X-Gm-Message-State: APjAAAXVtoVRkGxLaAQCxFy7po9Kd4tiKVq6VK/zkspmbaMTXJSSmqpp /U+3DbVaz6Zn5lrRwfgAr61bgyQ= X-Google-Smtp-Source: APXvYqxaNmZqoXs4tYB6snO5BmWk18re5etHg7lWZji+j3yxRsEA601c51JheS86Ob+7tZu24lPAgpI= X-Received: by 2002:a63:f107:: with SMTP id f7mr12336875pgi.76.1576805843222; Thu, 19 Dec 2019 17:37:23 -0800 (PST) Date: Thu, 19 Dec 2019 17:36:39 -0800 In-Reply-To: <20191217180152.GO5624@arrakis.emea.arm.com> Message-Id: <20191220013639.212396-1-pcc@google.com> Mime-Version: 1.0 References: <20191217180152.GO5624@arrakis.emea.arm.com> X-Mailer: git-send-email 2.24.1.735.g03f4e72817-goog Subject: [PATCH] arm64: mte: Do not service syscalls after async tag fault From: Peter Collingbourne To: Catalin Marinas Cc: Peter Collingbourne , Evgenii Stepanov , Kostya Serebryany , Linux ARM , linux-arch@vger.kernel.org, Richard Earnshaw , Szabolcs Nagy , Marc Zyngier , Kevin Brodsky , linux-mm@kvack.org, Andrey Konovalov , Vincenzo Frascino , Will Deacon X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: When entering the kernel after an async tag fault due to a syscall, rather than for another reason (e.g. preemption), we don't want to service the syscall as it may mask the tag fault. Rewind the PC to the svc instruction in order to give a userspace signal handler an opportunity to handle the fault and resume, and skip all other syscall processing. Signed-off-by: Peter Collingbourne Tested-by: Peter Collingbourne --- On Tue, Dec 17, 2019 at 10:01 AM Catalin Marinas wrote: > > On Fri, Dec 13, 2019 at 05:43:15PM -0800, Peter Collingbourne wrote: > > On Wed, Dec 11, 2019 at 10:44 AM Catalin Marinas > > wrote: > > > diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c > > > index dd2cdc0d5be2..41fae64af82a 100644 > > > --- a/arch/arm64/kernel/signal.c > > > +++ b/arch/arm64/kernel/signal.c > > > @@ -730,6 +730,9 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, > > >         regs->regs[29] = (unsigned long)&user->next_frame->fp; > > >         regs->pc = (unsigned long)ka->sa.sa_handler; > > > > > > +       /* TCO (Tag Check Override) always cleared for signal handlers */ > > > +       regs->pstate &= ~PSR_TCO_BIT; > > > + > > >         if (ka->sa.sa_flags & SA_RESTORER) > > >                 sigtramp = ka->sa.sa_restorer; > > >         else > > > @@ -921,6 +924,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, > > >                         if (thread_flags & _TIF_UPROBE) > > >                                 uprobe_notify_resume(regs); > > > > > > +                       if (thread_flags & _TIF_MTE_ASYNC_FAULT) { > > > +                               clear_thread_flag(TIF_MTE_ASYNC_FAULT); > > > +                               force_signal_inject(SIGSEGV, SEGV_MTEAERR, 0); > > > > In the case where the kernel is entered due to a syscall, this will > > inject a signal, but only after servicing the syscall. This means > > that, for example, if the syscall is exit(), the async tag check > > failure will be silently ignored. I can reproduce the problem with the > > program below: > [...] > > This patch fixes the problem for me: > > > > diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c > > index 9a9d98a443fc..d0c8918dee00 100644 > > --- a/arch/arm64/kernel/syscall.c > > +++ b/arch/arm64/kernel/syscall.c > > @@ -94,6 +94,8 @@ static void el0_svc_common(struct pt_regs *regs, int > > scno, int sc_nr, > >                            const syscall_fn_t syscall_table[]) > >  { > >         unsigned long flags = current_thread_info()->flags; > > +       if (flags & _TIF_MTE_ASYNC_FAULT) > > +               return; > > It needs a bit of thinking. This one wouldn't work if you want to handle > the signal and resume since it would skip the SVC instruction. We'd need > at least to do a regs->pc -= 4 and probably move it further down in this > function. Okay, how does this look? Peter arch/arm64/kernel/syscall.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 9a9d98a443fc..49ea9bb47190 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -95,13 +95,29 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, { unsigned long flags = current_thread_info()->flags; - regs->orig_x0 = regs->regs[0]; - regs->syscallno = scno; - cortex_a76_erratum_1463225_svc_handler(); local_daif_restore(DAIF_PROCCTX); user_exit(); +#ifdef CONFIG_ARM64_MTE + if (flags & _TIF_MTE_ASYNC_FAULT) { + /* + * We entered the kernel after an async tag fault due to a + * syscall, rather than for another reason (e.g. preemption). + * In this case, we don't want to service the syscall as it may + * mask the tag fault. Rewind the PC to the svc instruction in + * order to give a userspace signal handler an opportunity to + * handle the fault and resume, and skip all other syscall + * processing. + */ + regs->pc -= 4; + return; + } +#endif + + regs->orig_x0 = regs->regs[0]; + regs->syscallno = scno; + if (has_syscall_work(flags)) { /* set default errno for user-issued syscall(-1) */ if (scno == NO_SYSCALL)