[mips*/octeon] Add support for byte swapped initramfs to handle u-boot and kernel running with a different endianness.

This commit is contained in:
Aurelien Jarno 2016-05-13 18:54:45 +02:00
parent 594eaf7125
commit 4a8b374466
3 changed files with 86 additions and 0 deletions

2
debian/changelog vendored
View File

@ -84,6 +84,8 @@ linux (4.5.4-1) UNRELEASED; urgency=medium
* [mips*] Fix PR_SET_FPMODE issues with multi-threaded programs.
* [i386] Stop recommending libc6-i686.
* [arm,x86] Fix memory corruption in KVM with THP enabled.
* [mips*/octeon] Add support for byte swapped initramfs to handle u-boot and
kernel running with a different endianness.
[ Roger Shimizu ]
* netfilter: Enable NF_DUP_NETDEV / NFT_DUP_NETDEV / NFT_FWD_NETDEV

View File

@ -0,0 +1,83 @@
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Wed, 11 May 2016 00:37:42 +0200
Subject: MIPS: Octeon: detect and fix byte swapped initramfs
Origin: https://patchwork.linux-mips.org/patch/13219/
Octeon machines support running in little endian mode. U-Boot usually
runs in big endian-mode. Therefore the initramfs is loaded in big endian
mode, and the kernel later tries to access it in little endian mode.
This patch fixes that by detecting byte swapped initramfs using either the
CPIO header or the header from standard compression methods, and
byte swaps it if needed. It first checks that the header doesn't match
in the native endianness to avoid false detections. It uses the kernel
decompress library so that we don't have to maintain the list of magics
if some decompression methods are added to the kernel.
Cc: Ralf Baechle <ralf@linux-mips.org>
Acked-by: David Daney <david.daney@cavium.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
arch/mips/kernel/setup.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 4f60734..8841d7982 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -26,6 +26,7 @@
#include <linux/sizes.h>
#include <linux/device.h>
#include <linux/dma-contiguous.h>
+#include <linux/decompress/generic.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
@@ -250,6 +251,35 @@ disable:
return 0;
}
+/* In some conditions (e.g. big endian bootloader with a little endian
+ kernel), the initrd might appear byte swapped. Try to detect this and
+ byte swap it if needed. */
+static void __init maybe_bswap_initrd(void)
+{
+#if defined(CONFIG_CPU_CAVIUM_OCTEON)
+ u64 buf;
+
+ /* Check for CPIO signature */
+ if (!memcmp((void *)initrd_start, "070701", 6))
+ return;
+
+ /* Check for compressed initrd */
+ if (decompress_method((unsigned char *)initrd_start, 8, NULL))
+ return;
+
+ /* Try again with a byte swapped header */
+ buf = swab64p((u64 *)initrd_start);
+ if (!memcmp(&buf, "070701", 6) ||
+ decompress_method((unsigned char *)(&buf), 8, NULL)) {
+ unsigned long i;
+
+ pr_info("Byteswapped initrd detected\n");
+ for (i = initrd_start; i < ALIGN(initrd_end, 8); i += 8)
+ swab64s((u64 *)i);
+ }
+#endif
+}
+
static void __init finalize_initrd(void)
{
unsigned long size = initrd_end - initrd_start;
@@ -263,6 +293,8 @@ static void __init finalize_initrd(void)
goto disable;
}
+ maybe_bswap_initrd();
+
reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
initrd_below_start_ok = 1;
--
2.8.1

View File

@ -61,6 +61,7 @@ features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch
features/mips/MIPS-octeon-Add-support-for-the-UBNT-E200-board.patch
features/mips/libata-support-AHCI-on-OCTEON-platform.patch
features/mips/MIPS-Octeon-Add-Octeon-III-CN7xxx-interface-detection.patch
features/mips/MIPS-Octeon-detect-and-fix-byte-swapped-initramfs.patch
features/x86/x86-memtest-WARN-if-bad-RAM-found.patch
features/x86/x86-make-x32-syscall-support-conditional.patch
features/sparc/hwrng-n2-attach-on-t5-m5-t7-m7-sparc-cpus.patch