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 a2def98..545af0c 100755 --- a/driver.sh +++ b/driver.sh @@ -85,8 +85,15 @@ setup_variables() { image_name=Image.gz qemu="qemu-system-aarch64" qemu_cmdline=( -cpu cortex-a57 - -drive "file=images/arm64/rootfs.ext4,format=raw" - -append "console=ttyAMA0 root=/dev/vda" ) + -drive "file=images/arm64/rootfs.ext4,format=raw,id=rootfs,if=none" + -device "virtio-blk-device,drive=rootfs" + -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") @@ -144,9 +151,15 @@ 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 + 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 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 +