| From a077224fd35b2f7fbc93f14cf67074fc792fbac2 Mon Sep 17 00:00:00 2001 |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Thu, 3 Sep 2015 13:24:40 +0100 |
| Subject: ARM: 8429/1: disable GCC SRA optimization |
| |
| commit a077224fd35b2f7fbc93f14cf67074fc792fbac2 upstream. |
| |
| While working on the 32-bit ARM port of UEFI, I noticed a strange |
| corruption in the kernel log. The following snprintf() statement |
| (in drivers/firmware/efi/efi.c:efi_md_typeattr_format()) |
| |
| snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", |
| |
| was producing the following output in the log: |
| |
| | | | | | |WB|WT|WC|UC] |
| | | | | | |WB|WT|WC|UC] |
| | | | | | |WB|WT|WC|UC] |
| |RUN| | | | |WB|WT|WC|UC]* |
| |RUN| | | | |WB|WT|WC|UC]* |
| | | | | | |WB|WT|WC|UC] |
| |RUN| | | | |WB|WT|WC|UC]* |
| | | | | | |WB|WT|WC|UC] |
| |RUN| | | | | | | |UC] |
| |RUN| | | | | | | |UC] |
| |
| As it turns out, this is caused by incorrect code being emitted for |
| the string() function in lib/vsprintf.c. The following code |
| |
| if (!(spec.flags & LEFT)) { |
| while (len < spec.field_width--) { |
| if (buf < end) |
| *buf = ' '; |
| ++buf; |
| } |
| } |
| for (i = 0; i < len; ++i) { |
| if (buf < end) |
| *buf = *s; |
| ++buf; ++s; |
| } |
| while (len < spec.field_width--) { |
| if (buf < end) |
| *buf = ' '; |
| ++buf; |
| } |
| |
| when called with len == 0, triggers an issue in the GCC SRA optimization |
| pass (Scalar Replacement of Aggregates), which handles promotion of signed |
| struct members incorrectly. This is a known but as yet unresolved issue. |
| (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932). In this particular |
| case, it is causing the second while loop to be executed erroneously a |
| single time, causing the additional space characters to be printed. |
| |
| So disable the optimization by passing -fno-ipa-sra. |
| |
| Acked-by: Nicolas Pitre <nico@linaro.org> |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> |
| Signed-off-by: Zefan Li <lizefan@huawei.com> |
| --- |
| arch/arm/Makefile | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/arch/arm/Makefile |
| +++ b/arch/arm/Makefile |
| @@ -53,6 +53,14 @@ endif |
| |
| comma = , |
| |
| +# |
| +# The Scalar Replacement of Aggregates (SRA) optimization pass in GCC 4.9 and |
| +# later may result in code being generated that handles signed short and signed |
| +# char struct members incorrectly. So disable it. |
| +# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932) |
| +# |
| +KBUILD_CFLAGS += $(call cc-option,-fno-ipa-sra) |
| + |
| # This selects which instruction set is used. |
| # Note that GCC does not numerically define an architecture version |
| # macro, but instead defines a whole series of macros which makes |