3.10-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>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 arch/arm/Makefile |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -55,6 +55,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


--
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