From patchwork Thu Aug 23 09:48:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw \(lists\)" X-Patchwork-Id: 144898 Delivered-To: patch@linaro.org Received: by 2002:a2e:164a:0:0:0:0:0 with SMTP id 10-v6csp873827ljw; Thu, 23 Aug 2018 02:49:13 -0700 (PDT) X-Google-Smtp-Source: ANB0VdY4d8/xlz+JIFhDO/TO9mzADTocVR72ljKj8s19UK0ynotFIzDAlca9SpTQSZ7ISjKSMW8f X-Received: by 2002:a63:8f48:: with SMTP id r8-v6mr4730674pgn.189.1535017753829; Thu, 23 Aug 2018 02:49:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535017753; cv=none; d=google.com; s=arc-20160816; b=LF4A3ARxb7B5GMrYsDIMmDFAv/0TQd9yWSPCO0JXBr74lKexlzSpd2SxBfvWamghxU gSk6J+nC5BkAClpUocoT0lQMGJhIkQQs5a1wtXZ26arEadcuZnnNDvdLjon2rcc4qAT9 gy3uu5GObVghE+sHubvDQMqJndDrZ8BoK38/FvnGXFtsaYGofDL794Ab351JGDz6UN55 pfQN5b3OtMIj37sUII6IlgSaKr+T8wljNAEWQuyoaikEUu/DPBYKVHR54+JKzkwOMp0k Uvcx3QfVBC6oEtGk5Teb08nEV1K8K8+QIAYWgTZ7gl1qYigpxSF0kzGh7dHvQNVLwCsA /aGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:date:message-id:openpgp:subject:from:to :delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=xDVh7l0NbZvNBa4LWSwIT30ez+lWbNinpnrljN3QCng=; b=uzxhvLS5Sp95gZczEpcOQQnEETvdDGfk+my7WnWC3WUZxMlvCZit/kQs3r+xip5tzN /1qVwWSr8yfGl5Uu5VP/ZKAQY/yltLNmnw8Ch8U//bY/d4oRy2ICCeG8N8o2lNm4vjZX 6hBHlUlUXjFV6VeUHcJbNJpr44ZA3/8QuZybzK7luMWWfuT+jGaIKFOWRxHdALShxQNy 4dmueA7lyFGNa5hugWYp00zjseBZ3LLgUcYJQwEuc/LvEHjqbSapWEaB//2g6zzjIgOf 3+XK0FePdt4/TNhGx8GsX97kGJDzEzsbfR+PsLnIXz2y1NJDGRXiQJygoOBAdrjhuqs7 RaaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=A+BXk1dk; spf=pass (google.com: domain of gcc-patches-return-484258-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-484258-patch=linaro.org@gcc.gnu.org" Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id n2-v6si3976060pgu.103.2018.08.23.02.49.13 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 23 Aug 2018 02:49:13 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-484258-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=A+BXk1dk; spf=pass (google.com: domain of gcc-patches-return-484258-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-484258-patch=linaro.org@gcc.gnu.org" DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=plUFgNF69Sbhln6myHlhhAUVZNdgKfsVmDzzqi14AySbwZuQvU /s/LA0krWf5KPkRPjtleEEIh9JomXnnvBlSOKu8SipjoVJZ6HJaEWgjshuw+KSeR 8/ldq73nntiubcU5bZWPPdIF8PqeDzzhxdsOu+9jSM4bPTqMd5gRjXGSk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=1VPyi6Xzx9clw7L9leaTNi+TXi8=; b=A+BXk1dkH29o9ipfkDXq 89M1eZvTiPR9lDA6uSYwKdRfG0wiP2sV1kWtPSreI2FkKhUKtFA4DFbDNerMR58k ZjcbRpleeAOPq+AdwG5yQ3uiaaM3bE9R+y17tABSDtYRBCJJc7DJyluGvRNgRZf/ I8lQ85qbHmgxkz/owt1Is2Q= Received: (qmail 59798 invoked by alias); 23 Aug 2018 09:49:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 59679 invoked by uid 89); 23 Aug 2018 09:48:59 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.2 spammy=label_ref, HX-Envelope-From:sk:Richard X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 23 Aug 2018 09:48:56 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CCD5F80D; Thu, 23 Aug 2018 02:48:54 -0700 (PDT) Received: from e120077-lin.cambridge.arm.com (e120077-lin.cambridge.arm.com [10.2.206.26]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4C6663F2EA; Thu, 23 Aug 2018 02:48:54 -0700 (PDT) To: gcc-patches From: "Richard Earnshaw (lists)" Subject: PR target/86951 arm - Handle speculation barriers on pre-armv7 CPUs Openpgp: preference=signencrypt Message-ID: <971c59f7-f545-2b5b-66e0-e6a8cce7cf81@arm.com> Date: Thu, 23 Aug 2018 10:48:52 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 The AArch32 instruction sets prior to Armv7 do not define the ISB and DSB instructions that are needed to form a speculation barrier. While I do not know of any instances of cores based on those instruction sets being vulnerable to speculative side channel attacks it is possible to run code built for those ISAs on more recent hardware where they would become vulnerable. This patch works around this by using a library call added to libgcc. That code can then take any platform-specific actions necessary to ensure safety. For the moment I've only handled two cases: the library code being built for armv7 or later anyway and running on Linux. On Linux we can handle this by calling the kernel function that will flush a small amount of cache. Such a sequence ends with a ISB+DSB sequence if running on an Armv7 or later CPU. gcc: PR target/86951 * config/arm/arm-protos.h (arm_emit_speculation_barrier): New prototype. * config/arm/arm.c (speculation_barrier_libfunc): New static variable. (arm_init_libfuncs): Initialize it. (arm_emit_speculation_barrier): New function. * config/arm/arm.md (speculation_barrier): Call arm_emit_speculation_barrier for architectures that do not have DSB or ISB. (speculation_barrier_insn): Only match on Armv7 or later. libgcc: PR target/86951 * config/arm/lib1funcs.asm (speculation_barrier): New function. * config/arm/t-arm (LIB1ASMFUNCS): Add it to list of functions to build. Bootstrapped and reg-tested and also tested by bootstrapping for ARMv5e (on an ARMv7-a board). Applied to trunk. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 8537262..0dfb3ac 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -56,6 +56,8 @@ extern void arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update extern rtx arm_simd_vect_par_cnst_half (machine_mode mode, bool high); extern bool arm_simd_check_vect_par_cnst_half_p (rtx op, machine_mode mode, bool high); +extern void arm_emit_speculation_barrier_function (void); + #ifdef RTX_CODE extern void arm_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode, rtx label_ref); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f5eece4..0efac9d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2466,8 +2466,9 @@ arm_set_fixed_conv_libfunc (convert_optab optable, machine_mode to, set_conv_libfunc (optable, to, from, buffer); } -/* Set up library functions unique to ARM. */ +static GTY(()) rtx speculation_barrier_libfunc; +/* Set up library functions unique to ARM. */ static void arm_init_libfuncs (void) { @@ -2753,6 +2754,8 @@ arm_init_libfuncs (void) if (TARGET_AAPCS_BASED) synchronize_libfunc = init_one_libfunc ("__sync_synchronize"); + + speculation_barrier_libfunc = init_one_libfunc ("__speculation_barrier"); } /* On AAPCS systems, this is the "struct __va_list". */ @@ -31528,6 +31531,16 @@ arm_constant_alignment (const_tree exp, HOST_WIDE_INT align) return align; } +/* Emit a speculation barrier on target architectures that do not have + DSB/ISB directly. Such systems probably don't need a barrier + themselves, but if the code is ever run on a later architecture, it + might become a problem. */ +void +arm_emit_speculation_barrier_function () +{ + emit_library_call (speculation_barrier_libfunc, LCT_NORMAL, VOIDmode); +} + #if CHECKING_P namespace selftest { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index ca2a2f5..270b8e4 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -12016,10 +12016,16 @@ (define_expand "speculation_barrier" [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)] "TARGET_EITHER" " - /* Don't emit anything for Thumb1 and suppress the warning from the - generic expansion. */ - if (!TARGET_32BIT) - DONE; + /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't + have a usable barrier (and probably don't need one in practice). + But to be safe if such code is run on later architectures, call a + helper function in libgcc that will do the thing for the active + system. */ + if (!(arm_arch7 || arm_arch8)) + { + arm_emit_speculation_barrier_function (); + DONE; + } " ) @@ -12027,7 +12033,7 @@ (define_expand "speculation_barrier" ;; tracking. (define_insn "*speculation_barrier_insn" [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)] - "TARGET_32BIT" + "arm_arch7 || arm_arch8" "isb\;dsb\\tsy" [(set_attr "type" "block") (set_attr "length" "8")] diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S index b9919aa..ff06d50 100644 --- a/libgcc/config/arm/lib1funcs.S +++ b/libgcc/config/arm/lib1funcs.S @@ -1533,6 +1533,50 @@ LSYM(Lover12): #error "This is only for ARM EABI GNU/Linux" #endif #endif /* L_clear_cache */ + +#ifdef L_speculation_barrier + FUNC_START speculation_barrier +#if __ARM_ARCH >= 7 + isb + dsb sy +#elif defined __ARM_EABI__ && defined __linux__ + /* We don't have a speculation barrier directly for this + platform/architecture variant. But we can use a kernel + clear_cache service routine which will emit such instructions + if run on a later version of the architecture. We don't + really want to flush the cache, but we must give it a valid + address, so just clear pc..pc+1. */ +#if defined __thumb__ && !defined __thumb2__ + push {r7} + mov r7, #0xf + lsl r7, #16 + add r7, #2 + adr r0, . + 4 + add r1, r0, #1 + mov r2, #0 + svc 0 + pop {r7} +#else + do_push {r7} +#ifdef __ARM_ARCH_6T2__ + movw r7, #2 + movt r7, #0xf +#else + mov r7, #0xf0000 + add r7, r7, #2 +#endif + add r0, pc, #0 /* ADR. */ + add r1, r0, #1 + mov r2, #0 + svc 0 + do_pop {r7} +#endif /* Thumb1 only */ +#else +#warning "No speculation barrier defined for this platform" +#endif + RET + FUNC_END speculation_barrier +#endif /* ------------------------------------------------------------------------ */ /* Dword shift operations. */ /* All the following Dword shift variants rely on the fact that diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm index 9e85ac0..274bf2a 100644 --- a/libgcc/config/arm/t-arm +++ b/libgcc/config/arm/t-arm @@ -1,6 +1,6 @@ LIB1ASMSRC = arm/lib1funcs.S LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \ - _thumb1_case_uhi _thumb1_case_si + _thumb1_case_uhi _thumb1_case_si _speculation_barrier HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - /dev/null),)