3.13.11-ckt29 -stable review patch.  If anyone has any objections, please let 
me know.

------------------

From: Ard Biesheuvel <ard.biesheu...@linaro.org>

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 <n...@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
Signed-off-by: Russell King <rmk+ker...@arm.linux.org.uk>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriq...@canonical.com>

Signed-off-by: Kamal Mostafa <ka...@canonical.com>
---
 arch/arm/Makefile | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c99b108..749e88f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -56,6 +56,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
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to