From 27c9d154d6bf925383de0bb83ae76181f1dbe2fe Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 15 Aug 2019 13:28:11 -0700 Subject: [PATCH 1/4] driver: Fix arm64's qemu_cmdline to specify virtio-blk-device We need this to support booting up with EFI, otherwise arm64 on 4.4 panics because the block device cannot be found. This mirrors what is done for arm32. Suggested-by: Kees Cook Signed-off-by: Nathan Chancellor --- driver.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver.sh b/driver.sh index a2def98..6e24a08 100755 --- a/driver.sh +++ b/driver.sh @@ -85,7 +85,8 @@ setup_variables() { image_name=Image.gz qemu="qemu-system-aarch64" qemu_cmdline=( -cpu cortex-a57 - -drive "file=images/arm64/rootfs.ext4,format=raw" + -drive "file=images/arm64/rootfs.ext4,format=raw,id=rootfs,if=none" + -device "virtio-blk-device,drive=rootfs" -append "console=ttyAMA0 root=/dev/vda" ) export CROSS_COMPILE=aarch64-linux-gnu- ;; From 1a7e59ac3ead151a2629186396caac842c446a64 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 15 Aug 2019 13:57:47 -0700 Subject: [PATCH 2/4] driver: Move x86_64 from ide to virtio This allows booting up via EFI; without this, init panics because /dev/sda is not found. The IDE block driver is seldom used, virtio is better for our purposes. Suggested-by: Kees Cook Signed-off-by: Nathan Chancellor --- driver.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driver.sh b/driver.sh index 6e24a08..2f4784e 100755 --- a/driver.sh +++ b/driver.sh @@ -145,8 +145,8 @@ setup_variables() { -initrd "images/x86_64/rootfs.cpio" ) ;; *) config=defconfig - qemu_cmdline=( -drive "file=images/x86_64/rootfs.ext4,format=raw,if=ide" - -append "console=ttyS0 root=/dev/sda" ) ;; + qemu_cmdline=( -drive "file=images/x86_64/rootfs.ext4,format=raw,if=virtio" + -append "console=ttyS0 root=/dev/vda" ) ;; esac # Use KVM if the processor supports it (first part) and the KVM module is loaded (second part) [[ $(grep -c -E 'vmx|svm' /proc/cpuinfo) -gt 0 && $(lsmod 2>/dev/null | grep -c kvm) -gt 0 ]] && qemu_cmdline=( "${qemu_cmdline[@]}" -enable-kvm ) From 6ff45c2f44ece6426ce10d6470b795c503793012 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 14 Aug 2019 11:22:45 -0700 Subject: [PATCH 3/4] patches: Add Kees' arm64 EFI fix We need this to start booting via EFI. Signed-off-by: Nathan Chancellor --- ...-variable-assignments-after-SECTIONS.patch | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 patches/llvm-all/linux/arm64/0001-arm64-efi-Move-variable-assignments-after-SECTIONS.patch diff --git a/patches/llvm-all/linux/arm64/0001-arm64-efi-Move-variable-assignments-after-SECTIONS.patch b/patches/llvm-all/linux/arm64/0001-arm64-efi-Move-variable-assignments-after-SECTIONS.patch new file mode 100644 index 0000000..8d32f29 --- /dev/null +++ b/patches/llvm-all/linux/arm64/0001-arm64-efi-Move-variable-assignments-after-SECTIONS.patch @@ -0,0 +1,172 @@ +From f43cc4ed67f44f22754bef5bec98bf8aad3e6e8d Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Tue, 13 Aug 2019 16:04:50 -0700 +Subject: [PATCH] arm64/efi: Move variable assignments after SECTIONS + +It seems that LLVM's linker does not correctly handle variable assignments +involving section positions that are updated during the SECTIONS +parsing. Commit aa69fb62bea1 ("arm64/efi: Mark __efistub_stext_offset as +an absolute symbol explicitly") ran into this too, but found a different +workaround. + +However, this was not enough, as other variables were also miscalculated +which manifested as boot failures under UEFI where __efistub__end was +not taking the correct _end value (they should be the same): + +$ ld.lld -EL -maarch64elf --no-undefined -X -shared \ + -Bsymbolic -z notext -z norelro --no-apply-dynamic-relocs \ + -o vmlinux.lld -T poc.lds --whole-archive vmlinux.o && \ + readelf -Ws vmlinux.lld | egrep '\b(__efistub_|)_end\b' +368272: ffff000002218000 0 NOTYPE LOCAL HIDDEN 38 __efistub__end +368322: ffff000012318000 0 NOTYPE GLOBAL DEFAULT 38 _end + +$ aarch64-linux-gnu-ld.bfd -EL -maarch64elf --no-undefined -X -shared \ + -Bsymbolic -z notext -z norelro --no-apply-dynamic-relocs \ + -o vmlinux.bfd -T poc.lds --whole-archive vmlinux.o && \ + readelf -Ws vmlinux.bfd | egrep '\b(__efistub_|)_end\b' +338124: ffff000012318000 0 NOTYPE LOCAL DEFAULT ABS __efistub__end +383812: ffff000012318000 0 NOTYPE GLOBAL DEFAULT 15325 _end + +To work around this, all of the __efistub_-prefixed variable assignments +need to be moved after the linker script's SECTIONS entry. As it turns +out, this also solves the problem fixed in commit aa69fb62bea1, so those +changes are reverted here. + +Link: https://github.com/ClangBuiltLinux/linux/issues/634 +Link: https://bugs.llvm.org/show_bug.cgi?id=42990 +Acked-by: Ard Biesheuvel +Signed-off-by: Kees Cook +Signed-off-by: Will Deacon +(am from https://git.kernel.org/arm64/c/90776dd1c427cbb4d381aa4b13338f1fb1d20f5e) +Signed-off-by: Nathan Chancellor +--- + arch/arm64/kernel/image-vars.h | 51 +++++++++++++++++++++++++++++++++ + arch/arm64/kernel/image.h | 42 --------------------------- + arch/arm64/kernel/vmlinux.lds.S | 2 ++ + 3 files changed, 53 insertions(+), 42 deletions(-) + create mode 100644 arch/arm64/kernel/image-vars.h + +diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h +new file mode 100644 +index 000000000000..25a2a9b479c2 +--- /dev/null ++++ b/arch/arm64/kernel/image-vars.h +@@ -0,0 +1,51 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Linker script variables to be set after section resolution, as ++ * ld.lld does not like variables assigned before SECTIONS is processed. ++ */ ++#ifndef __ARM64_KERNEL_IMAGE_VARS_H ++#define __ARM64_KERNEL_IMAGE_VARS_H ++ ++#ifndef LINKER_SCRIPT ++#error This file should only be included in vmlinux.lds.S ++#endif ++ ++#ifdef CONFIG_EFI ++ ++__efistub_stext_offset = stext - _text; ++ ++/* ++ * The EFI stub has its own symbol namespace prefixed by __efistub_, to ++ * isolate it from the kernel proper. The following symbols are legally ++ * accessed by the stub, so provide some aliases to make them accessible. ++ * Only include data symbols here, or text symbols of functions that are ++ * guaranteed to be safe when executed at another offset than they were ++ * linked at. The routines below are all implemented in assembler in a ++ * position independent manner ++ */ ++__efistub_memcmp = __pi_memcmp; ++__efistub_memchr = __pi_memchr; ++__efistub_memcpy = __pi_memcpy; ++__efistub_memmove = __pi_memmove; ++__efistub_memset = __pi_memset; ++__efistub_strlen = __pi_strlen; ++__efistub_strnlen = __pi_strnlen; ++__efistub_strcmp = __pi_strcmp; ++__efistub_strncmp = __pi_strncmp; ++__efistub_strrchr = __pi_strrchr; ++__efistub___flush_dcache_area = __pi___flush_dcache_area; ++ ++#ifdef CONFIG_KASAN ++__efistub___memcpy = __pi_memcpy; ++__efistub___memmove = __pi_memmove; ++__efistub___memset = __pi_memset; ++#endif ++ ++__efistub__text = _text; ++__efistub__end = _end; ++__efistub__edata = _edata; ++__efistub_screen_info = screen_info; ++ ++#endif ++ ++#endif /* __ARM64_KERNEL_IMAGE_VARS_H */ +diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h +index 2b85c0d6fa3d..c7d38c660372 100644 +--- a/arch/arm64/kernel/image.h ++++ b/arch/arm64/kernel/image.h +@@ -65,46 +65,4 @@ + DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET); \ + DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS); + +-#ifdef CONFIG_EFI +- +-/* +- * Use ABSOLUTE() to avoid ld.lld treating this as a relative symbol: +- * https://github.com/ClangBuiltLinux/linux/issues/561 +- */ +-__efistub_stext_offset = ABSOLUTE(stext - _text); +- +-/* +- * The EFI stub has its own symbol namespace prefixed by __efistub_, to +- * isolate it from the kernel proper. The following symbols are legally +- * accessed by the stub, so provide some aliases to make them accessible. +- * Only include data symbols here, or text symbols of functions that are +- * guaranteed to be safe when executed at another offset than they were +- * linked at. The routines below are all implemented in assembler in a +- * position independent manner +- */ +-__efistub_memcmp = __pi_memcmp; +-__efistub_memchr = __pi_memchr; +-__efistub_memcpy = __pi_memcpy; +-__efistub_memmove = __pi_memmove; +-__efistub_memset = __pi_memset; +-__efistub_strlen = __pi_strlen; +-__efistub_strnlen = __pi_strnlen; +-__efistub_strcmp = __pi_strcmp; +-__efistub_strncmp = __pi_strncmp; +-__efistub_strrchr = __pi_strrchr; +-__efistub___flush_dcache_area = __pi___flush_dcache_area; +- +-#ifdef CONFIG_KASAN +-__efistub___memcpy = __pi_memcpy; +-__efistub___memmove = __pi_memmove; +-__efistub___memset = __pi_memset; +-#endif +- +-__efistub__text = _text; +-__efistub__end = _end; +-__efistub__edata = _edata; +-__efistub_screen_info = screen_info; +- +-#endif +- + #endif /* __ARM64_KERNEL_IMAGE_H */ +diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S +index 7fa008374907..803b24d2464a 100644 +--- a/arch/arm64/kernel/vmlinux.lds.S ++++ b/arch/arm64/kernel/vmlinux.lds.S +@@ -245,6 +245,8 @@ SECTIONS + HEAD_SYMBOLS + } + ++#include "image-vars.h" ++ + /* + * The HYP init code and ID map text can't be longer than a page each, + * and should not cross a page boundary. +-- +2.23.0.rc2 + From d3c7c5b3b76846fe82d96c606bec7150b0fe122d Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Thu, 15 Aug 2019 22:08:47 -0700 Subject: [PATCH 4/4] driver: Support booting via EFI on arm64 and x86_64 If the ovmf or qemu-efi-aarch64 packages are installed on Debian or Ubuntu, use those files to boot up via EFI. This will help prevent regressions like https://github.com/ClangBuiltLinux/linux/issues/634. This is disabled for kernel/common because the kernel does not shut down cleanly; I don't think this is worth exploring because Android does not care about EFI as far as I am aware. I considered checking in the fd files so that other distributions could take advantage of this but these files are over 50MB, which is too much of a burden to force on everyone. Presubmit: https://travis-ci.com/nathanchance/continuous-integration/builds/123450697 [skip ci] Suggested-by: Kees Cook Signed-off-by: Nathan Chancellor --- .gitignore | 1 + driver.sh | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d755b96..6eed8e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.fd *.swp *.tar.gz .ccache diff --git a/driver.sh b/driver.sh index 2f4784e..545af0c 100755 --- a/driver.sh +++ b/driver.sh @@ -87,7 +87,13 @@ setup_variables() { qemu_cmdline=( -cpu cortex-a57 -drive "file=images/arm64/rootfs.ext4,format=raw,id=rootfs,if=none" -device "virtio-blk-device,drive=rootfs" - -append "console=ttyAMA0 root=/dev/vda" ) + -append "console=ttyAMA0 earlycon root=/dev/vda" ) + aavmf=/usr/share/AAVMF + if [[ ${tree} != common && -f ${aavmf}/AAVMF_CODE.fd && -f ${aavmf}/AAVMF_VARS.fd ]]; then + cp ${aavmf}/AAVMF_VARS.fd images/arm64 + qemu_cmdline+=( -drive "if=pflash,format=raw,readonly,file=${aavmf}/AAVMF_CODE.fd" + -drive "if=pflash,format=raw,file=images/arm64/AAVMF_VARS.fd" ) + fi export CROSS_COMPILE=aarch64-linux-gnu- ;; "mipsel") @@ -148,6 +154,12 @@ setup_variables() { qemu_cmdline=( -drive "file=images/x86_64/rootfs.ext4,format=raw,if=virtio" -append "console=ttyS0 root=/dev/vda" ) ;; esac + ovmf=/usr/share/OVMF + if [[ ${tree} != common && -f ${ovmf}/OVMF_CODE.fd && -f ${ovmf}/OVMF_VARS.fd ]]; then + cp ${ovmf}/OVMF_VARS.fd images/x86_64 + qemu_cmdline+=( -drive "if=pflash,format=raw,readonly,file=${ovmf}/OVMF_CODE.fd" + -drive "if=pflash,format=raw,file=images/x86_64/OVMF_VARS.fd" ) + fi # Use KVM if the processor supports it (first part) and the KVM module is loaded (second part) [[ $(grep -c -E 'vmx|svm' /proc/cpuinfo) -gt 0 && $(lsmod 2>/dev/null | grep -c kvm) -gt 0 ]] && qemu_cmdline=( "${qemu_cmdline[@]}" -enable-kvm ) image_name=bzImage