ArmPkg/CompilerIntrinsicsLib: provide atomics intrinsics

Gary reports the GCC 10 will emit calls to atomics intrinsics routines
unless -mno-outline-atomics is specified. This means GCC-10 introduces
new intrinsics, and even though it would be possible to work around this
by specifying the command line option, this would require a new GCC10
toolchain profile to be created, which we prefer to avoid.

So instead, add the new intrinsics to our library so they are provided
when necessary.
This commit is contained in:
eillon 2021-07-30 09:59:30 +08:00
parent b5c1394a2c
commit 85be15144b
2 changed files with 195 additions and 1 deletions

View File

@ -0,0 +1,190 @@
From ca407c7246bf405da6d9b1b9d93e5e7f17b4b1f9 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ard.biesheuvel@arm.com>
Date: Wed, 20 May 2020 13:44:48 +0200
Subject: [PATCH] ArmPkg/CompilerIntrinsicsLib: provide atomics intrinsics
Gary reports the GCC 10 will emit calls to atomics intrinsics routines
unless -mno-outline-atomics is specified. This means GCC-10 introduces
new intrinsics, and even though it would be possible to work around this
by specifying the command line option, this would require a new GCC10
toolchain profile to be created, which we prefer to avoid.
So instead, add the new intrinsics to our library so they are provided
when necessary.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Tested-by: Gary Lin <glin@suse.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
---
.../CompilerIntrinsicsLib/AArch64/Atomics.S | 142 ++++++++++++++++++
.../CompilerIntrinsicsLib.inf | 3 +
2 files changed, 145 insertions(+)
create mode 100644 ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
new file mode 100644
index 0000000000..3792020ab8
--- /dev/null
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
@@ -0,0 +1,142 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2020, Arm, Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+ /*
+ * Provide the GCC intrinsics that are required when using GCC 9 or
+ * later with the -moutline-atomics options (which became the default
+ * in GCC 10)
+ */
+ .arch armv8-a
+
+ .macro reg_alias, pfx, sz
+ r0_\sz .req \pfx\()0
+ r1_\sz .req \pfx\()1
+ tmp0_\sz .req \pfx\()16
+ tmp1_\sz .req \pfx\()17
+ .endm
+
+ /*
+ * Define register aliases of the right type for each size
+ * (xN for 8 bytes, wN for everything smaller)
+ */
+ reg_alias w, 1
+ reg_alias w, 2
+ reg_alias w, 4
+ reg_alias x, 8
+
+ .macro fn_start, name:req
+ .section .text.\name
+ .globl \name
+ .type \name, %function
+\name\():
+ .endm
+
+ .macro fn_end, name:req
+ .size \name, . - \name
+ .endm
+
+ /*
+ * Emit an atomic helper for \model with operands of size \sz, using
+ * the operation specified by \insn (which is the LSE name), and which
+ * can be implemented using the generic load-locked/store-conditional
+ * (LL/SC) sequence below, using the arithmetic operation given by
+ * \opc.
+ */
+ .macro emit_ld_sz, sz:req, insn:req, opc:req, model:req, s, a, l
+ fn_start __aarch64_\insn\()\sz\()\model
+ mov tmp0_\sz, r0_\sz
+0: ld\a\()xr\s r0_\sz, [x1]
+ .ifnc \insn, swp
+ \opc tmp1_\sz, r0_\sz, tmp0_\sz
+ st\l\()xr\s w15, tmp1_\sz, [x1]
+ .else
+ st\l\()xr\s w15, tmp0_\sz, [x1]
+ .endif
+ cbnz w15, 0b
+ ret
+ fn_end __aarch64_\insn\()\sz\()\model
+ .endm
+
+ /*
+ * Emit atomic helpers for \model for operand sizes in the
+ * set {1, 2, 4, 8}, for the instruction pattern given by
+ * \insn. (This is the LSE name, but this implementation uses
+ * the generic LL/SC sequence using \opc as the arithmetic
+ * operation on the target.)
+ */
+ .macro emit_ld, insn:req, opc:req, model:req, a, l
+ emit_ld_sz 1, \insn, \opc, \model, b, \a, \l
+ emit_ld_sz 2, \insn, \opc, \model, h, \a, \l
+ emit_ld_sz 4, \insn, \opc, \model, , \a, \l
+ emit_ld_sz 8, \insn, \opc, \model, , \a, \l
+ .endm
+
+ /*
+ * Emit the compare and swap helper for \model and size \sz
+ * using LL/SC instructions.
+ */
+ .macro emit_cas_sz, sz:req, model:req, uxt:req, s, a, l
+ fn_start __aarch64_cas\sz\()\model
+ \uxt tmp0_\sz, r0_\sz
+0: ld\a\()xr\s r0_\sz, [x2]
+ cmp r0_\sz, tmp0_\sz
+ bne 1f
+ st\l\()xr\s w15, r1_\sz, [x2]
+ cbnz w15, 0b
+1: ret
+ fn_end __aarch64_cas\sz\()\model
+ .endm
+
+ /*
+ * Emit compare-and-swap helpers for \model for operand sizes in the
+ * set {1, 2, 4, 8, 16}.
+ */
+ .macro emit_cas, model:req, a, l
+ emit_cas_sz 1, \model, uxtb, b, \a, \l
+ emit_cas_sz 2, \model, uxth, h, \a, \l
+ emit_cas_sz 4, \model, mov , , \a, \l
+ emit_cas_sz 8, \model, mov , , \a, \l
+
+ /*
+ * We cannot use the parameterized sequence for 16 byte CAS, so we
+ * need to define it explicitly.
+ */
+ fn_start __aarch64_cas16\model
+ mov x16, x0
+ mov x17, x1
+0: ld\a\()xp x0, x1, [x4]
+ cmp x0, x16
+ ccmp x1, x17, #0, eq
+ bne 1f
+ st\l\()xp w15, x16, x17, [x4]
+ cbnz w15, 0b
+1: ret
+ fn_end __aarch64_cas16\model
+ .endm
+
+ /*
+ * Emit the set of GCC outline atomic helper functions for
+ * the memory ordering model given by \model:
+ * - relax unordered loads and stores
+ * - acq load-acquire, unordered store
+ * - rel unordered load, store-release
+ * - acq_rel load-acquire, store-release
+ */
+ .macro emit_model, model:req, a, l
+ emit_ld ldadd, add, \model, \a, \l
+ emit_ld ldclr, bic, \model, \a, \l
+ emit_ld ldeor, eor, \model, \a, \l
+ emit_ld ldset, orr, \model, \a, \l
+ emit_ld swp, mov, \model, \a, \l
+ emit_cas \model, \a, \l
+ .endm
+
+ emit_model _relax
+ emit_model _acq, a
+ emit_model _rel,, l
+ emit_model _acq_rel, a, l
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
index d5bad94677..fcf48c6781 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -79,6 +79,9 @@
Arm/ldivmod.asm | MSFT
Arm/llsr.asm | MSFT
+[Sources.AARCH64]
+ AArch64/Atomics.S | GCC
+
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
--
2.27.0

View File

@ -5,7 +5,7 @@
Name: edk2
Version: %{stable_date}
Release: 6
Release: 7
Summary: EFI Development Kit II
License: BSD-2-Clause-Patent
URL: https://github.com/tianocore/edk2
@ -27,6 +27,7 @@ Patch0012: 0012-ArmVirtPkg-ArmVirtQemu-enable-the-TPM2-configuration.patch
Patch0013: 0013-ArmVirtPkg-ArmVirtQemu-enable-TPM2-based-measured-bo.patch
Patch0014: 0014-MdeModulePkg-Core-Dxe-assert-SectionInstance-invariant-in-FindChildNode.patch
Patch0015: 0015-MdeModulePkg-Core-Dxe-limit-FwVol-encapsulation-section-recursion.patch
Patch0016: 0016-ArmPkg-CompilerIntrinsicsLib-provide-atomics-intrins.patch
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command
@ -224,6 +225,9 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
%endif
%changelog
* Fri Jul 30 2021 Zhenyu Ye <yezhenyu2@huawei.com> - 202002-7
- ArmPkg/CompilerIntrinsicsLib: provide atomics intrinsics
* Mon Jun 28 2021 Jiajie Li <lijiajie11@huawei.com> - 202002-6
- Fix CVE-2021-28210