* [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements
@ 2024-03-05 16:46 Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe Andrew Jones
` (18 more replies)
0 siblings, 19 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
This series collects one fix ("Update MAX_SMP probe") with a bunch of
improvements to the EFI setup code and run script. With the series
applied one can add --enable-efi-direct when configuring and then
run the EFI tests on QEMU much, much faster by using direct kernel
boot for them (and environment variables will work too). The non-
direct (original) way of running the EFI tests has also been sped up
a bit by not running the dummy test and not generating the dtb twice.
The cleanups in the setup code allow duplicated code to be removed
(by sharing with the non-EFI setup code) and eventually for riscv
to share some code too with the introduction of memregions_efi_init().
v3:
- Dropped fdt_valid
- Factored out qemu_args+=(-machine acpi=off) [Nikos]
- Ensure etext is page aligned
- Picked up Nikos's r-b's
v2:
- Add another improvement (patches 15-17), which is to stop mapping
EFI regions which we consider reserved (including
EFI_BOOT_SERVICES_DATA regions which requires moving the primary stack)
- Add EFI gitlab CI tests
- Fix one typo in configure help text
Andrew Jones (17):
runtime: Update MAX_SMP probe
runtime: Add yet another 'no kernel' error message
arm64: efi: Don't create dummy test
arm64: efi: Remove redundant dtb generation
arm64: efi: Move run code into a function
arm64: efi: Remove EFI_USE_DTB
arm64: efi: Improve device tree discovery
lib/efi: Add support for loading the initrd
arm64: efi: Allow running tests directly
arm/arm64: Factor out some initial setup
arm/arm64: Factor out allocator init from mem_init
arm64: Simplify efi_mem_init
arm64: Add memregions_efi_init
arm64: efi: Don't map reserved regions
arm64: efi: Fix _start returns from failed _relocate
arm64: efi: Switch to our own stack
arm64: efi: Add gitlab CI
Shaoqin Huang (1):
arm64: efi: Make running tests on EFI can be parallel
.gitlab-ci.yml | 32 ++++-
arm/efi/crt0-efi-aarch64.S | 37 ++++--
arm/efi/elf_aarch64_efi.lds | 1 +
arm/efi/run | 64 ++++++----
arm/run | 6 +-
configure | 17 +++
lib/arm/mmu.c | 6 +-
lib/arm/setup.c | 227 ++++++++++++++----------------------
lib/efi.c | 84 +++++++++++--
lib/linux/efi.h | 29 +++++
lib/memregions.c | 53 +++++++++
lib/memregions.h | 6 +
run_tests.sh | 5 +-
scripts/runtime.bash | 21 ++--
14 files changed, 389 insertions(+), 199 deletions(-)
--
2.44.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-07 2:29 ` Shaoqin Huang
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 02/18] runtime: Add yet another 'no kernel' error message Andrew Jones
` (17 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Arm's MAX_SMP probing must have stopped working at some point due to
QEMU's error message changing, but nobody noticed. Also, the probing
should work for at least x86 now too, so the comment isn't correct
anymore either. We could probably just delete this probe thing, but
in case it could still serve some purpose we can also keep it, but
updated for later QEMU, and only enabled when a new run_tests.sh
command line option is provided.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
run_tests.sh | 5 ++++-
scripts/runtime.bash | 19 ++++++++++---------
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/run_tests.sh b/run_tests.sh
index abb0ab773362..bb3024ff95b1 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -44,7 +44,7 @@ fi
only_tests=""
list_tests=""
-args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list -- $*)
+args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list,probe-maxsmp -- $*)
[ $? -ne 0 ] && exit 2;
set -- $args;
while [ $# -gt 0 ]; do
@@ -78,6 +78,9 @@ while [ $# -gt 0 ]; do
-l | --list)
list_tests="yes"
;;
+ --probe-maxsmp)
+ probe_maxsmp
+ ;;
--)
;;
*)
diff --git a/scripts/runtime.bash b/scripts/runtime.bash
index c73fb0240d12..f2e43bb1ed60 100644
--- a/scripts/runtime.bash
+++ b/scripts/runtime.bash
@@ -200,12 +200,13 @@ function run()
#
# Probe for MAX_SMP, in case it's less than the number of host cpus.
#
-# This probing currently only works for ARM, as x86 bails on another
-# error first, so this check is only run for ARM and ARM64. The
-# parameter expansion takes the last number from the QEMU error
-# message, which gives the allowable MAX_SMP.
-if [[ $ARCH == 'arm' || $ARCH == 'arm64' ]] &&
- smp=$($RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP |& grep 'exceeds max CPUs'); then
- smp=${smp##*(}
- MAX_SMP=${smp:0:-1}
-fi
+function probe_maxsmp()
+{
+ local smp
+
+ if smp=$($RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP |& grep 'Invalid SMP CPUs'); then
+ smp=${smp##* }
+ echo "Restricting MAX_SMP from ($MAX_SMP) to the max supported ($smp)" >&2
+ MAX_SMP=$smp
+ fi
+}
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 02/18] runtime: Add yet another 'no kernel' error message
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-07 2:39 ` Shaoqin Huang
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 03/18] arm64: efi: Don't create dummy test Andrew Jones
` (16 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
When booting an Arm machine with the -bios command line option we
get yet another error message from QEMU when using _NO_FILE_4Uhere_
to probe command line support. Add it to the check in
premature_failure()
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
scripts/runtime.bash | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/runtime.bash b/scripts/runtime.bash
index f2e43bb1ed60..255e756f2cb2 100644
--- a/scripts/runtime.bash
+++ b/scripts/runtime.bash
@@ -18,7 +18,7 @@ premature_failure()
local log="$(eval "$(get_cmdline _NO_FILE_4Uhere_)" 2>&1)"
echo "$log" | grep "_NO_FILE_4Uhere_" |
- grep -q -e "could not \(load\|open\) kernel" -e "error loading" &&
+ grep -q -e "could not \(load\|open\) kernel" -e "error loading" -e "failed to load" &&
return 1
RUNTIME_log_stderr <<< "$log"
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 03/18] arm64: efi: Don't create dummy test
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 02/18] runtime: Add yet another 'no kernel' error message Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-07 3:37 ` Shaoqin Huang
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 04/18] arm64: efi: Make running tests on EFI can be parallel Andrew Jones
` (15 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
The purpose of the _NO_FILE_4Uhere_ kernel is to check that all the
QEMU command line options that have been pulled together by the
scripts will work. Since booting with UEFI and the -kernel command
line is supported by QEMU, then we don't need to create a dummy
test for _NO_FILE_4Uhere_ and go all the way into UEFI's shell and
execute it to prove the command line is OK, since we would have
failed much before all that if it wasn't. Just run QEMU "normally",
i.e. no EFI_RUN=y, but add the UEFI -bios and its file system command
line options, in order to check the full command line.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/run | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arm/efi/run b/arm/efi/run
index 6872c337c945..e629abde5273 100755
--- a/arm/efi/run
+++ b/arm/efi/run
@@ -53,7 +53,14 @@ while (( "$#" )); do
done
if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
- EFI_CASE=dummy
+ EFI_CASE_DIR="$EFI_TEST/dummy"
+ mkdir -p "$EFI_CASE_DIR"
+ $TEST_DIR/run \
+ $EFI_CASE \
+ -bios "$EFI_UEFI" \
+ -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
+ "${qemu_args[@]}"
+ exit
fi
: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_CASE"}"
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 04/18] arm64: efi: Make running tests on EFI can be parallel
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (2 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 03/18] arm64: efi: Don't create dummy test Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 05/18] arm64: efi: Remove redundant dtb generation Andrew Jones
` (14 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
From: Shaoqin Huang <shahuang@redhat.com>
Currently running tests on EFI in parallel can cause part of tests to
fail, this is because arm/efi/run script use the EFI_CASE to create the
subdir under the efi-tests, and the EFI_CASE is the filename of the
test, when running tests in parallel, the multiple tests exist in the
same filename will execute at the same time, which will use the same
directory and write the test specific things into it, this cause
chaotic and make some tests fail.
For example, if we running the pmu-sw-incr and pmu-chained-counters
and other pmu tests on EFI at the same time, the EFI_CASE will be pmu.
So they will write their $cmd_args to the $EFI/TEST/pmu/startup.nsh
at the same time, which will corrupt the startup.nsh file.
And we can get the log which outputs:
* pmu-sw-incr.log:
- ABORT: pmu: Unknown sub-test 'pmu-mem-acce'
* pmu-chained-counters.log
- ABORT: pmu: Unknown sub-test 'pmu-mem-access-reliab'
And the efi-tests/pmu/startup.nsh:
@echo -off
setvar fdtfile -guid 97ef3e03-7329-4a6a-b9ba-6c1fdcc5f823 -rt =L"dtb"
pmu.efi pmu-mem-access-reliability
setvar fdtfile -guid 97ef3e03-7329-4a6a-b9ba-6c1fdcc5f823 -rt =L"dtb"
pmu.efi pmu-chained-sw-incr
As you can see, when multiple tests write to the same startup.nsh file,
it causes the issue.
To Fix this issue, use the testname instead of the filename to create
the subdir under the efi-tests. We use the EFI_TESTNAME to replace the
EFI_CASE in script. Since every testname is specific, now the tests
can be run parallel. It also considers when user directly use the
arm/efi/run to run test, in this case, still use the filename.
Besides, replace multiple $EFI_TEST/$EFI_CASE to the $EFI_CASE_DIR, this
makes the script looks more clean and we don'e need to replace many
EFI_CASE to EFI_TESTNAME.
Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
Signed-off-by: Shaoqin Huang <shahuang@redhat.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/run | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/arm/efi/run b/arm/efi/run
index e629abde5273..8b6512520026 100755
--- a/arm/efi/run
+++ b/arm/efi/run
@@ -25,6 +25,8 @@ fi
: "${EFI_UEFI:=$DEFAULT_UEFI}"
: "${EFI_TEST:=efi-tests}"
: "${EFI_CASE:=$(basename $1 .efi)}"
+: "${EFI_TESTNAME:=$TESTNAME}"
+: "${EFI_TESTNAME:=$EFI_CASE}"
: "${EFI_VAR_GUID:=97ef3e03-7329-4a6a-b9ba-6c1fdcc5f823}"
[ "$EFI_USE_ACPI" = "y" ] || EFI_USE_DTB=y
@@ -63,20 +65,20 @@ if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
exit
fi
-: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_CASE"}"
+: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_TESTNAME"}"
mkdir -p "$EFI_CASE_DIR"
-cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_TEST/$EFI_CASE/"
-echo "@echo -off" > "$EFI_TEST/$EFI_CASE/startup.nsh"
+cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_CASE_DIR/"
+echo "@echo -off" > "$EFI_CASE_DIR/startup.nsh"
if [ "$EFI_USE_DTB" = "y" ]; then
qemu_args+=(-machine acpi=off)
FDT_BASENAME="dtb"
- $(EFI_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_TEST/$EFI_CASE/$FDT_BASENAME" "${qemu_args[@]}")
- echo "setvar fdtfile -guid $EFI_VAR_GUID -rt =L\"$FDT_BASENAME\"" >> "$EFI_TEST/$EFI_CASE/startup.nsh"
+ $(EFI_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}")
+ echo "setvar fdtfile -guid $EFI_VAR_GUID -rt =L\"$FDT_BASENAME\"" >> "$EFI_CASE_DIR/startup.nsh"
fi
-echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_TEST/$EFI_CASE/startup.nsh"
+echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_CASE_DIR/startup.nsh"
EFI_RUN=y $TEST_DIR/run \
-bios "$EFI_UEFI" \
- -drive file.dir="$EFI_TEST/$EFI_CASE/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
+ -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
"${qemu_args[@]}"
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 05/18] arm64: efi: Remove redundant dtb generation
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (3 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 04/18] arm64: efi: Make running tests on EFI can be parallel Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 06/18] arm64: efi: Move run code into a function Andrew Jones
` (13 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
When a line in bash is written as
$(some-line)
Then 'some-line' will be evaluated and then whatever some-line outputs
will be evaluated. The dtb is getting generated twice since the line
that should generate it is within $() and the output of that is the
command itself (since arm/run outputs its command), so the command
gets executed again. Remove the $() to just execute dtb generation
once.
While mucking with arm/efi/run tidy it a bit by by removing the unused
sourcing of common.bash and the unnecessary 'set -e' (we check for and
propagate errors ourselves). Finally, make one reorganization change
and some whitespace fixes.
Fixes: 2607d2d6946a ("arm64: Add an efi/run script")
Fixes: 2e080dafec2a ("arm64: Use the provided fdt when booting through EFI")
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/run | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/arm/efi/run b/arm/efi/run
index 8b6512520026..e45cecfa3265 100755
--- a/arm/efi/run
+++ b/arm/efi/run
@@ -1,7 +1,5 @@
#!/bin/bash
-set -e
-
if [ $# -eq 0 ]; then
echo "Usage $0 TEST_CASE [QEMU_ARGS]"
exit 2
@@ -13,7 +11,6 @@ if [ ! -f config.mak ]; then
fi
source config.mak
source scripts/arch-run.bash
-source scripts/common.bash
if [ -f /usr/share/qemu-efi-aarch64/QEMU_EFI.fd ]; then
DEFAULT_UEFI=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd
@@ -27,6 +24,7 @@ fi
: "${EFI_CASE:=$(basename $1 .efi)}"
: "${EFI_TESTNAME:=$TESTNAME}"
: "${EFI_TESTNAME:=$EFI_CASE}"
+: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_TESTNAME"}"
: "${EFI_VAR_GUID:=97ef3e03-7329-4a6a-b9ba-6c1fdcc5f823}"
[ "$EFI_USE_ACPI" = "y" ] || EFI_USE_DTB=y
@@ -65,20 +63,18 @@ if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
exit
fi
-: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_TESTNAME"}"
mkdir -p "$EFI_CASE_DIR"
-
cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_CASE_DIR/"
echo "@echo -off" > "$EFI_CASE_DIR/startup.nsh"
if [ "$EFI_USE_DTB" = "y" ]; then
qemu_args+=(-machine acpi=off)
FDT_BASENAME="dtb"
- $(EFI_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}")
+ EFI_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}"
echo "setvar fdtfile -guid $EFI_VAR_GUID -rt =L\"$FDT_BASENAME\"" >> "$EFI_CASE_DIR/startup.nsh"
fi
echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_CASE_DIR/startup.nsh"
EFI_RUN=y $TEST_DIR/run \
- -bios "$EFI_UEFI" \
- -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
- "${qemu_args[@]}"
+ -bios "$EFI_UEFI" \
+ -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
+ "${qemu_args[@]}"
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 06/18] arm64: efi: Move run code into a function
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (4 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 05/18] arm64: efi: Remove redundant dtb generation Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 07/18] arm64: efi: Remove EFI_USE_DTB Andrew Jones
` (12 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Push the run code in arm/efi/run into a function named
uefi_shell_run() since it will create an EFI file system, copy
the test and possibly the DTB there, and create a startup.nsh
which executes the test from the UEFI shell. Pushing this
code into a function allows additional execution paths to be
created in the script. Also rename EFI_RUN to UEFI_SHELL_RUN
to pass the information on to arm/run that it's being called
from uefi_shell_run().
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/run | 33 +++++++++++++++++++--------------
arm/run | 4 ++--
2 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/arm/efi/run b/arm/efi/run
index e45cecfa3265..494ba9e7efe7 100755
--- a/arm/efi/run
+++ b/arm/efi/run
@@ -63,18 +63,23 @@ if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
exit
fi
-mkdir -p "$EFI_CASE_DIR"
-cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_CASE_DIR/"
-echo "@echo -off" > "$EFI_CASE_DIR/startup.nsh"
-if [ "$EFI_USE_DTB" = "y" ]; then
- qemu_args+=(-machine acpi=off)
- FDT_BASENAME="dtb"
- EFI_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}"
- echo "setvar fdtfile -guid $EFI_VAR_GUID -rt =L\"$FDT_BASENAME\"" >> "$EFI_CASE_DIR/startup.nsh"
-fi
-echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_CASE_DIR/startup.nsh"
+uefi_shell_run()
+{
+ mkdir -p "$EFI_CASE_DIR"
+ cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_CASE_DIR/"
+ echo "@echo -off" > "$EFI_CASE_DIR/startup.nsh"
+ if [ "$EFI_USE_DTB" = "y" ]; then
+ qemu_args+=(-machine acpi=off)
+ FDT_BASENAME="dtb"
+ UEFI_SHELL_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}"
+ echo "setvar fdtfile -guid $EFI_VAR_GUID -rt =L\"$FDT_BASENAME\"" >> "$EFI_CASE_DIR/startup.nsh"
+ fi
+ echo "$EFI_CASE.efi" "${cmd_args[@]}" >> "$EFI_CASE_DIR/startup.nsh"
+
+ UEFI_SHELL_RUN=y $TEST_DIR/run \
+ -bios "$EFI_UEFI" \
+ -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
+ "${qemu_args[@]}"
+}
-EFI_RUN=y $TEST_DIR/run \
- -bios "$EFI_UEFI" \
- -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
- "${qemu_args[@]}"
+uefi_shell_run
diff --git a/arm/run b/arm/run
index ac64b3b461a2..40c2ca66ba7e 100755
--- a/arm/run
+++ b/arm/run
@@ -60,7 +60,7 @@ if ! $qemu $M -chardev '?' | grep -q testdev; then
exit 2
fi
-if [ "$EFI_RUN" != "y" ]; then
+if [ "$UEFI_SHELL_RUN" != "y" ]; then
chr_testdev='-device virtio-serial-device'
chr_testdev+=' -device virtconsole,chardev=ctd -chardev testdev,id=ctd'
fi
@@ -75,7 +75,7 @@ command="$qemu -nodefaults $M $A -cpu $processor $chr_testdev $pci_testdev"
command+=" -display none -serial stdio"
command="$(migration_cmd) $(timeout_cmd) $command"
-if [ "$EFI_RUN" = "y" ]; then
+if [ "$UEFI_SHELL_RUN" = "y" ]; then
ENVIRON_DEFAULT=n run_qemu_status $command "$@"
else
run_qemu $command -kernel "$@"
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 07/18] arm64: efi: Remove EFI_USE_DTB
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (5 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 06/18] arm64: efi: Move run code into a function Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery Andrew Jones
` (11 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
We don't need two variables for one boolean property. Just use
!EFI_USE_ACPI to infer efi-use-dtb.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/run | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arm/efi/run b/arm/efi/run
index 494ba9e7efe7..b7a8418a07f8 100755
--- a/arm/efi/run
+++ b/arm/efi/run
@@ -27,8 +27,6 @@ fi
: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_TESTNAME"}"
: "${EFI_VAR_GUID:=97ef3e03-7329-4a6a-b9ba-6c1fdcc5f823}"
-[ "$EFI_USE_ACPI" = "y" ] || EFI_USE_DTB=y
-
if [ ! -f "$EFI_UEFI" ]; then
echo "UEFI firmware not found."
echo "Please specify the path with the env variable EFI_UEFI"
@@ -68,7 +66,7 @@ uefi_shell_run()
mkdir -p "$EFI_CASE_DIR"
cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_CASE_DIR/"
echo "@echo -off" > "$EFI_CASE_DIR/startup.nsh"
- if [ "$EFI_USE_DTB" = "y" ]; then
+ if [ "$EFI_USE_ACPI" != "y" ]; then
qemu_args+=(-machine acpi=off)
FDT_BASENAME="dtb"
UEFI_SHELL_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}"
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (6 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 07/18] arm64: efi: Remove EFI_USE_DTB Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-25 16:24 ` Paluri, PavanKumar
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 09/18] lib/efi: Add support for loading the initrd Andrew Jones
` (10 subsequent siblings)
18 siblings, 1 reply; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Check the device tree GUID when the environment variable is missing,
which allows directly loading the unit test with QEMU's '-kernel'
command line parameter, which is much faster than putting the test
in the EFI file system and then running it from the UEFI shell.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/efi.c | 19 ++++++++++++-------
lib/linux/efi.h | 2 ++
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/lib/efi.c b/lib/efi.c
index d94f0fa16fc0..4d1126b4a64e 100644
--- a/lib/efi.c
+++ b/lib/efi.c
@@ -6,13 +6,13 @@
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
-
-#include "efi.h"
+#include <libcflat.h>
#include <argv.h>
-#include <stdlib.h>
#include <ctype.h>
-#include <libcflat.h>
+#include <stdlib.h>
#include <asm/setup.h>
+#include "efi.h"
+#include "libfdt/libfdt.h"
/* From lib/argv.c */
extern int __argc, __envc;
@@ -288,13 +288,18 @@ static void *efi_get_fdt(efi_handle_t handle, struct efi_loaded_image_64 *image)
efi_char16_t var[] = ENV_VARNAME_DTBFILE;
efi_char16_t *val;
void *fdt = NULL;
- int fdtsize;
+ int fdtsize = 0;
val = efi_get_var(handle, image, var);
- if (val)
+ if (val) {
efi_load_image(handle, image, &fdt, &fdtsize, val);
+ if (fdtsize == 0)
+ return NULL;
+ } else if (efi_get_system_config_table(DEVICE_TREE_GUID, &fdt) != EFI_SUCCESS) {
+ return NULL;
+ }
- return fdt;
+ return fdt_check_header(fdt) == 0 ? fdt : NULL;
}
efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
diff --git a/lib/linux/efi.h b/lib/linux/efi.h
index 410f0b1a0da1..92d798f79767 100644
--- a/lib/linux/efi.h
+++ b/lib/linux/efi.h
@@ -66,6 +66,8 @@ typedef guid_t efi_guid_t;
#define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
+#define DEVICE_TREE_GUID EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
+
#define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
typedef struct {
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 09/18] lib/efi: Add support for loading the initrd
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (7 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 10/18] arm64: efi: Allow running tests directly Andrew Jones
` (9 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
When loading non-efi tests with QEMU's '-kernel' option we also load
an environ with the '-initrd' option. Now that efi tests can also be
loaded with the '-kernel' option also provide the '-initrd' environ.
For EFI, we use the EFI_LOAD_FILE2_PROTOCOL_GUID protocol to load
LINUX_EFI_INITRD_MEDIA_GUID. Each architecture which wants to use the
initrd for the environ will need to call setup_env() on the initrd
data. As usual, the new efi function is heavily influenced by Linux's
implementation.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/efi.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/linux/efi.h | 27 ++++++++++++++++++++
2 files changed, 92 insertions(+)
diff --git a/lib/efi.c b/lib/efi.c
index 4d1126b4a64e..12c66c6ffd1f 100644
--- a/lib/efi.c
+++ b/lib/efi.c
@@ -14,6 +14,10 @@
#include "efi.h"
#include "libfdt/libfdt.h"
+/* From each arch */
+extern char *initrd;
+extern u32 initrd_size;
+
/* From lib/argv.c */
extern int __argc, __envc;
extern char *__argv[100];
@@ -302,6 +306,65 @@ static void *efi_get_fdt(efi_handle_t handle, struct efi_loaded_image_64 *image)
return fdt_check_header(fdt) == 0 ? fdt : NULL;
}
+static const struct {
+ struct efi_vendor_dev_path vendor;
+ struct efi_generic_dev_path end;
+} __packed initrd_dev_path = {
+ {
+ {
+ EFI_DEV_MEDIA,
+ EFI_DEV_MEDIA_VENDOR,
+ sizeof(struct efi_vendor_dev_path),
+ },
+ LINUX_EFI_INITRD_MEDIA_GUID
+ }, {
+ EFI_DEV_END_PATH,
+ EFI_DEV_END_ENTIRE,
+ sizeof(struct efi_generic_dev_path)
+ }
+};
+
+static void efi_load_initrd(void)
+{
+ efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
+ efi_device_path_protocol_t *dp;
+ efi_load_file2_protocol_t *lf2;
+ efi_handle_t handle;
+ efi_status_t status;
+ unsigned long file_size = 0;
+
+ initrd = NULL;
+ initrd_size = 0;
+
+ dp = (efi_device_path_protocol_t *)&initrd_dev_path;
+ status = efi_bs_call(locate_device_path, &lf2_proto_guid, &dp, &handle);
+ if (status != EFI_SUCCESS)
+ return;
+
+ status = efi_bs_call(handle_protocol, handle, &lf2_proto_guid, (void **)&lf2);
+ assert(status == EFI_SUCCESS);
+
+ status = efi_call_proto(lf2, load_file, dp, false, &file_size, NULL);
+ assert(status == EFI_BUFFER_TOO_SMALL);
+
+ status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, file_size, (void **)&initrd);
+ assert(status == EFI_SUCCESS);
+
+ status = efi_call_proto(lf2, load_file, dp, false, &file_size, (void *)initrd);
+ assert(status == EFI_SUCCESS);
+
+ initrd_size = (u32)file_size;
+
+ /*
+ * UEFI appends initrd=initrd to the command line when an initrd is present.
+ * Remove it in order to avoid confusing unit tests.
+ */
+ if (!strcmp(__argv[__argc - 1], "initrd=initrd")) {
+ __argv[__argc - 1] = NULL;
+ __argc -= 1;
+ }
+}
+
efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
{
int ret;
@@ -340,6 +403,8 @@ efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
}
setup_args(cmdline_ptr);
+ efi_load_initrd();
+
efi_bootinfo.fdt = efi_get_fdt(handle, image);
/* Set up efi_bootinfo */
efi_bootinfo.mem_map.map = ↦
diff --git a/lib/linux/efi.h b/lib/linux/efi.h
index 92d798f79767..8fa23ad078ce 100644
--- a/lib/linux/efi.h
+++ b/lib/linux/efi.h
@@ -70,6 +70,9 @@ typedef guid_t efi_guid_t;
#define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_LOAD_FILE2_PROTOCOL_GUID EFI_GUID(0x4006c0c1, 0xfcb3, 0x403e, 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d)
+#define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
+
typedef struct {
efi_guid_t guid;
void *table;
@@ -248,6 +251,12 @@ struct efi_generic_dev_path {
u16 length;
} __packed;
+struct efi_vendor_dev_path {
+ struct efi_generic_dev_path header;
+ efi_guid_t vendorguid;
+ u8 vendordata[];
+} __packed;
+
typedef struct efi_generic_dev_path efi_device_path_protocol_t;
/*
@@ -449,6 +458,19 @@ typedef struct _efi_simple_file_system_protocol efi_simple_file_system_protocol_
typedef struct _efi_file_protocol efi_file_protocol_t;
typedef efi_simple_file_system_protocol_t efi_file_io_interface_t;
typedef efi_file_protocol_t efi_file_t;
+typedef union efi_load_file_protocol efi_load_file_protocol_t;
+typedef union efi_load_file_protocol efi_load_file2_protocol_t;
+
+union efi_load_file_protocol {
+ struct {
+ efi_status_t (__efiapi *load_file)(efi_load_file_protocol_t *,
+ efi_device_path_protocol_t *,
+ bool, unsigned long *, void *);
+ };
+ struct {
+ u32 load_file;
+ } mixed_mode;
+};
typedef efi_status_t efi_simple_file_system_protocol_open_volume(
efi_simple_file_system_protocol_t *this,
@@ -544,7 +566,12 @@ typedef struct {
efi_char16_t file_name[1];
} efi_file_info_t;
+#define efi_fn_call(inst, func, ...) (inst)->func(__VA_ARGS__)
#define efi_bs_call(func, ...) efi_system_table->boottime->func(__VA_ARGS__)
#define efi_rs_call(func, ...) efi_system_table->runtime->func(__VA_ARGS__)
+#define efi_call_proto(inst, func, ...) ({ \
+ __typeof__(inst) __inst = (inst); \
+ efi_fn_call(__inst, func, __inst, ##__VA_ARGS__); \
+})
#endif /* __LINUX_UEFI_H */
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 10/18] arm64: efi: Allow running tests directly
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (8 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 09/18] lib/efi: Add support for loading the initrd Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 11/18] arm/arm64: Factor out some initial setup Andrew Jones
` (8 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Since it's possible to run tests with UEFI and the QEMU -kernel
option (and now the DTB will be found and even the environ will
be set up from an initrd if given with the -initrd option), then
we can skip the loading of EFI tests into a file system and booting
to the shell to run them. Just run them directly. Running directly
is waaaaaay faster than booting the shell first. We keep the UEFI
shell as the default behavior, though, and provide a new configure
option to enable the direct running.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/run | 18 +++++++++++++++---
arm/run | 4 +++-
configure | 17 +++++++++++++++++
3 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/arm/efi/run b/arm/efi/run
index b7a8418a07f8..f07a6e55c381 100755
--- a/arm/efi/run
+++ b/arm/efi/run
@@ -18,10 +18,12 @@ elif [ -f /usr/share/edk2/aarch64/QEMU_EFI.silent.fd ]; then
DEFAULT_UEFI=/usr/share/edk2/aarch64/QEMU_EFI.silent.fd
fi
+KERNEL_NAME=$1
+
: "${EFI_SRC:=$TEST_DIR}"
: "${EFI_UEFI:=$DEFAULT_UEFI}"
: "${EFI_TEST:=efi-tests}"
-: "${EFI_CASE:=$(basename $1 .efi)}"
+: "${EFI_CASE:=$(basename $KERNEL_NAME .efi)}"
: "${EFI_TESTNAME:=$TESTNAME}"
: "${EFI_TESTNAME:=$EFI_CASE}"
: "${EFI_CASE_DIR:="$EFI_TEST/$EFI_TESTNAME"}"
@@ -49,6 +51,9 @@ while (( "$#" )); do
shift 1
fi
done
+if [ "$EFI_USE_ACPI" != "y" ]; then
+ qemu_args+=(-machine acpi=off)
+fi
if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
EFI_CASE_DIR="$EFI_TEST/dummy"
@@ -67,7 +72,6 @@ uefi_shell_run()
cp "$EFI_SRC/$EFI_CASE.efi" "$EFI_CASE_DIR/"
echo "@echo -off" > "$EFI_CASE_DIR/startup.nsh"
if [ "$EFI_USE_ACPI" != "y" ]; then
- qemu_args+=(-machine acpi=off)
FDT_BASENAME="dtb"
UEFI_SHELL_RUN=y $TEST_DIR/run -machine dumpdtb="$EFI_CASE_DIR/$FDT_BASENAME" "${qemu_args[@]}"
echo "setvar fdtfile -guid $EFI_VAR_GUID -rt =L\"$FDT_BASENAME\"" >> "$EFI_CASE_DIR/startup.nsh"
@@ -80,4 +84,12 @@ uefi_shell_run()
"${qemu_args[@]}"
}
-uefi_shell_run
+if [ "$EFI_DIRECT" = "y" ]; then
+ $TEST_DIR/run \
+ $KERNEL_NAME \
+ -append "$(basename $KERNEL_NAME) ${cmd_args[@]}" \
+ -bios "$EFI_UEFI" \
+ "${qemu_args[@]}"
+else
+ uefi_shell_run
+fi
diff --git a/arm/run b/arm/run
index 40c2ca66ba7e..efdd44ce86a7 100755
--- a/arm/run
+++ b/arm/run
@@ -60,7 +60,7 @@ if ! $qemu $M -chardev '?' | grep -q testdev; then
exit 2
fi
-if [ "$UEFI_SHELL_RUN" != "y" ]; then
+if [ "$UEFI_SHELL_RUN" != "y" ] && [ "$EFI_USE_ACPI" != "y" ]; then
chr_testdev='-device virtio-serial-device'
chr_testdev+=' -device virtconsole,chardev=ctd -chardev testdev,id=ctd'
fi
@@ -77,6 +77,8 @@ command="$(migration_cmd) $(timeout_cmd) $command"
if [ "$UEFI_SHELL_RUN" = "y" ]; then
ENVIRON_DEFAULT=n run_qemu_status $command "$@"
+elif [ "$EFI_USE_ACPI" = "y" ]; then
+ run_qemu_status $command -kernel "$@"
else
run_qemu $command -kernel "$@"
fi
diff --git a/configure b/configure
index 4a00bdfeb8fd..51edee8cd21b 100755
--- a/configure
+++ b/configure
@@ -32,6 +32,7 @@ enable_dump=no
page_size=
earlycon=
efi=
+efi_direct=
# Enable -Werror by default for git repositories only (i.e. developer builds)
if [ -e "$srcdir"/.git ]; then
@@ -90,6 +91,11 @@ usage() {
--[enable|disable]-efi Boot and run from UEFI (disabled by default, x86_64 and arm64 only)
--[enable|disable]-werror
Select whether to compile with the -Werror compiler flag
+ --[enable|disable]-efi-direct
+ Select whether to run EFI tests directly with QEMU's -kernel
+ option. When not enabled, tests will be placed in an EFI file
+ system and run from the UEFI shell. Ignored when efi isn't enabled.
+ (arm64 only)
EOF
exit 1
}
@@ -169,6 +175,12 @@ while [[ "$1" = -* ]]; do
--disable-efi)
efi=n
;;
+ --enable-efi-direct)
+ efi_direct=y
+ ;;
+ --disable-efi-direct)
+ efi_direct=n
+ ;;
--enable-werror)
werror=-Werror
;;
@@ -186,6 +198,10 @@ while [[ "$1" = -* ]]; do
esac
done
+if [ -z "$efi" ] || [ "$efi" = "n" ]; then
+ [ "$efi_direct" = "y" ] && efi_direct=
+fi
+
if [ -n "$host_key_document" ] && [ ! -f "$host_key_document" ]; then
echo "Host key document doesn't exist at the specified location."
exit 1
@@ -428,6 +444,7 @@ GENPROTIMG=${GENPROTIMG-genprotimg}
HOST_KEY_DOCUMENT=$host_key_document
CONFIG_DUMP=$enable_dump
CONFIG_EFI=$efi
+EFI_DIRECT=$efi_direct
CONFIG_WERROR=$werror
GEN_SE_HEADER=$gen_se_header
EOF
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 11/18] arm/arm64: Factor out some initial setup
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (9 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 10/18] arm64: efi: Allow running tests directly Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 12/18] arm/arm64: Factor out allocator init from mem_init Andrew Jones
` (7 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Factor out some initial setup code into separate functions in order
to share more code between setup() and setup_efi().
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/arm/setup.c | 82 +++++++++++++++++++++++++++++--------------------
1 file changed, 48 insertions(+), 34 deletions(-)
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 0382cbdaf5a1..80f952377cf9 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -182,32 +182,57 @@ static void mem_init(phys_addr_t freemem_start)
page_alloc_ops_enable();
}
-void setup(const void *fdt, phys_addr_t freemem_start)
+static void freemem_push_fdt(void **freemem, const void *fdt)
{
- void *freemem;
- const char *bootargs, *tmp;
u32 fdt_size;
int ret;
- assert(sizeof(long) == 8 || freemem_start < (3ul << 30));
- freemem = (void *)(unsigned long)freemem_start;
-
- /* Move the FDT to the base of free memory */
fdt_size = fdt_totalsize(fdt);
- ret = fdt_move(fdt, freemem, fdt_size);
+ ret = fdt_move(fdt, *freemem, fdt_size);
assert(ret == 0);
- ret = dt_init(freemem);
+ ret = dt_init(*freemem);
assert(ret == 0);
- freemem += fdt_size;
+ *freemem += fdt_size;
+}
+
+static void freemem_push_dt_initrd(void **freemem)
+{
+ const char *tmp;
+ int ret;
- /* Move the initrd to the top of the FDT */
ret = dt_get_initrd(&tmp, &initrd_size);
assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
if (ret == 0) {
- initrd = freemem;
+ initrd = *freemem;
memmove(initrd, tmp, initrd_size);
- freemem += initrd_size;
+ *freemem += initrd_size;
}
+}
+
+static void initrd_setup(void)
+{
+ char *env;
+
+ if (!initrd)
+ return;
+
+ /* environ is currently the only file in the initrd */
+ env = malloc(initrd_size);
+ memcpy(env, initrd, initrd_size);
+ setup_env(env, initrd_size);
+}
+
+void setup(const void *fdt, phys_addr_t freemem_start)
+{
+ void *freemem;
+ const char *bootargs;
+ int ret;
+
+ assert(sizeof(long) == 8 || freemem_start < (3ul << 30));
+ freemem = (void *)(unsigned long)freemem_start;
+
+ freemem_push_fdt(&freemem, fdt);
+ freemem_push_dt_initrd(&freemem);
memregions_init(arm_mem_regions, NR_MEM_REGIONS);
memregions_add_dt_regions(MAX_DT_MEM_REGIONS);
@@ -229,12 +254,7 @@ void setup(const void *fdt, phys_addr_t freemem_start)
assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
setup_args_progname(bootargs);
- if (initrd) {
- /* environ is currently the only file in the initrd */
- char *env = malloc(initrd_size);
- memcpy(env, initrd, initrd_size);
- setup_env(env, initrd_size);
- }
+ initrd_setup();
if (!(auxinfo.flags & AUXINFO_MMU_OFF))
setup_vm();
@@ -277,7 +297,6 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
uintptr_t text = (uintptr_t)&_text, etext = ALIGN((uintptr_t)&_etext, 4096);
uintptr_t data = (uintptr_t)&_data, edata = ALIGN((uintptr_t)&_edata, 4096);
const void *fdt = efi_bootinfo->fdt;
- int fdt_size, ret;
/*
* Record the largest free EFI_CONVENTIONAL_MEMORY region
@@ -342,15 +361,15 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
}
memregions_add(&r);
}
+
if (fdt) {
- /* Move the FDT to the base of free memory */
- fdt_size = fdt_totalsize(fdt);
- ret = fdt_move(fdt, (void *)free_mem_start, fdt_size);
- assert(ret == 0);
- ret = dt_init((void *)free_mem_start);
- assert(ret == 0);
- free_mem_start += ALIGN(fdt_size, EFI_PAGE_SIZE);
- free_mem_pages -= ALIGN(fdt_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
+ unsigned long old_start = free_mem_start;
+ void *freemem = (void *)free_mem_start;
+
+ freemem_push_fdt(&freemem, fdt);
+
+ free_mem_start = ALIGN((unsigned long)freemem, EFI_PAGE_SIZE);
+ free_mem_pages = (free_mem_start - old_start) >> EFI_PAGE_SHIFT;
}
__phys_end &= PHYS_MASK;
@@ -418,13 +437,8 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
io_init();
timer_save_state();
- if (initrd) {
- /* environ is currently the only file in the initrd */
- char *env = malloc(initrd_size);
- memcpy(env, initrd, initrd_size);
- setup_env(env, initrd_size);
- }
+ initrd_setup();
if (!(auxinfo.flags & AUXINFO_MMU_OFF))
setup_vm();
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 12/18] arm/arm64: Factor out allocator init from mem_init
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (10 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 11/18] arm/arm64: Factor out some initial setup Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 13/18] arm64: Simplify efi_mem_init Andrew Jones
` (6 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
The allocator init is identical for mem_init() and efi_mem_init().
Share it.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/arm/setup.c | 46 ++++++++++++++++++++++------------------------
1 file changed, 22 insertions(+), 24 deletions(-)
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 80f952377cf9..7f2043907634 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -136,9 +136,28 @@ static void arm_memregions_add_assumed(void)
#endif
}
-static void mem_init(phys_addr_t freemem_start)
+static void mem_allocator_init(phys_addr_t freemem_start, phys_addr_t freemem_end)
{
phys_addr_t base, top;
+
+ freemem_start = PAGE_ALIGN(freemem_start);
+ freemem_end &= PAGE_MASK;
+
+ phys_alloc_init(freemem_start, freemem_end - freemem_start);
+ phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
+
+ phys_alloc_get_unused(&base, &top);
+ base = PAGE_ALIGN(base);
+ top &= PAGE_MASK;
+ assert(sizeof(long) == 8 || !(base >> 32));
+ if (sizeof(long) != 8 && (top >> 32) != 0)
+ top = ((uint64_t)1 << 32);
+ page_alloc_init_area(0, base >> PAGE_SHIFT, top >> PAGE_SHIFT);
+ page_alloc_ops_enable();
+}
+
+static void mem_init(phys_addr_t freemem_start)
+{
struct mem_region *freemem, *r, mem = {
.start = (phys_addr_t)-1,
};
@@ -169,17 +188,7 @@ static void mem_init(phys_addr_t freemem_start)
__phys_offset = mem.start; /* PHYS_OFFSET */
__phys_end = mem.end; /* PHYS_END */
- phys_alloc_init(freemem_start, freemem->end - freemem_start);
- phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
-
- phys_alloc_get_unused(&base, &top);
- base = PAGE_ALIGN(base);
- top = top & PAGE_MASK;
- assert(sizeof(long) == 8 || !(base >> 32));
- if (sizeof(long) != 8 && (top >> 32) != 0)
- top = ((uint64_t)1 << 32);
- page_alloc_init_area(0, base >> PAGE_SHIFT, top >> PAGE_SHIFT);
- page_alloc_ops_enable();
+ mem_allocator_init(freemem_start, freemem->end);
}
static void freemem_push_fdt(void **freemem, const void *fdt)
@@ -292,7 +301,6 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
struct efi_boot_memmap *map = &(efi_bootinfo->mem_map);
efi_memory_desc_t *buffer = *map->map;
efi_memory_desc_t *d = NULL;
- phys_addr_t base, top;
struct mem_region r;
uintptr_t text = (uintptr_t)&_text, etext = ALIGN((uintptr_t)&_etext, 4096);
uintptr_t data = (uintptr_t)&_data, edata = ALIGN((uintptr_t)&_edata, 4096);
@@ -380,17 +388,7 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
assert(sizeof(long) == 8 || free_mem_start < (3ul << 30));
- phys_alloc_init(free_mem_start, free_mem_pages << EFI_PAGE_SHIFT);
- phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
-
- phys_alloc_get_unused(&base, &top);
- base = PAGE_ALIGN(base);
- top = top & PAGE_MASK;
- assert(sizeof(long) == 8 || !(base >> 32));
- if (sizeof(long) != 8 && (top >> 32) != 0)
- top = ((uint64_t)1 << 32);
- page_alloc_init_area(0, base >> PAGE_SHIFT, top >> PAGE_SHIFT);
- page_alloc_ops_enable();
+ mem_allocator_init(free_mem_start, free_mem_start + (free_mem_pages << EFI_PAGE_SHIFT));
return EFI_SUCCESS;
}
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 13/18] arm64: Simplify efi_mem_init
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (11 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 12/18] arm/arm64: Factor out allocator init from mem_init Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 14/18] arm64: Add memregions_efi_init Andrew Jones
` (5 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Reduce the EFI mem_map loop to only setting flags and finding the
largest free memory region. Then, apply memregions_split() for
the code/data region split (which requires ensuring _etext is
page aligned). Finally, do the rest of the things that used to be
done in the EFI mem_map loop in a separate mem_region loop.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/elf_aarch64_efi.lds | 1 +
lib/arm/setup.c | 45 +++++++++++++++++--------------------
2 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/arm/efi/elf_aarch64_efi.lds b/arm/efi/elf_aarch64_efi.lds
index 836d98255d88..7a4192b77900 100644
--- a/arm/efi/elf_aarch64_efi.lds
+++ b/arm/efi/elf_aarch64_efi.lds
@@ -13,6 +13,7 @@ SECTIONS
*(.rodata*)
. = ALIGN(16);
}
+ . = ALIGN(4096);
_etext = .;
_text_size = . - _text;
.dynamic : { *(.dynamic) }
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 7f2043907634..b8c88b5bf011 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -301,9 +301,7 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
struct efi_boot_memmap *map = &(efi_bootinfo->mem_map);
efi_memory_desc_t *buffer = *map->map;
efi_memory_desc_t *d = NULL;
- struct mem_region r;
- uintptr_t text = (uintptr_t)&_text, etext = ALIGN((uintptr_t)&_etext, 4096);
- uintptr_t data = (uintptr_t)&_data, edata = ALIGN((uintptr_t)&_edata, 4096);
+ struct mem_region r, *code, *data;
const void *fdt = efi_bootinfo->fdt;
/*
@@ -337,21 +335,7 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
r.flags = MR_F_IO;
break;
case EFI_LOADER_CODE:
- if (r.start <= text && r.end > text) {
- /* This is the unit test region. Flag the code separately. */
- phys_addr_t tmp = r.end;
-
- assert(etext <= data);
- assert(edata <= r.end);
- r.flags = MR_F_CODE;
- r.end = data;
- memregions_add(&r);
- r.start = data;
- r.end = tmp;
- r.flags = 0;
- } else {
- r.flags = MR_F_RESERVED;
- }
+ r.flags = MR_F_CODE;
break;
case EFI_CONVENTIONAL_MEMORY:
if (free_mem_pages < d->num_pages) {
@@ -361,15 +345,27 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
break;
}
- if (!(r.flags & MR_F_IO)) {
- if (r.start < __phys_offset)
- __phys_offset = r.start;
- if (r.end > __phys_end)
- __phys_end = r.end;
- }
memregions_add(&r);
}
+ memregions_split((unsigned long)&_etext, &code, &data);
+ assert(code && (code->flags & MR_F_CODE));
+ if (data)
+ data->flags &= ~MR_F_CODE;
+
+ for (struct mem_region *m = mem_regions; m->end; ++m) {
+ if (m != code && (m->flags & MR_F_CODE))
+ m->flags = MR_F_RESERVED;
+
+ if (!(m->flags & MR_F_IO)) {
+ if (m->start < __phys_offset)
+ __phys_offset = m->start;
+ if (m->end > __phys_end)
+ __phys_end = m->end;
+ }
+ }
+ __phys_end &= PHYS_MASK;
+
if (fdt) {
unsigned long old_start = free_mem_start;
void *freemem = (void *)free_mem_start;
@@ -380,7 +376,6 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
free_mem_pages = (free_mem_start - old_start) >> EFI_PAGE_SHIFT;
}
- __phys_end &= PHYS_MASK;
asm_mmu_disable();
if (free_mem_pages == 0)
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 14/18] arm64: Add memregions_efi_init
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (12 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 13/18] arm64: Simplify efi_mem_init Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 15/18] arm64: efi: Don't map reserved regions Andrew Jones
` (4 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Provide a memregions function which initialized memregions from an
EFI memory map. Add a new memregions flag (MR_F_PERSISTENT) for
EFI_PERSISTENT_MEMORY since that type should not be reserved, but it
should also be distinct from conventional memory. The function also
points out the largest conventional memory region by returning a
pointer to it in the freemem parameter. Immediately apply this
function to arm64's efi_mem_init(). riscv will make use of it as well.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/arm/setup.c | 76 ++++++++----------------------------------------
lib/memregions.c | 51 ++++++++++++++++++++++++++++++++
lib/memregions.h | 6 ++++
3 files changed, 69 insertions(+), 64 deletions(-)
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index b8c88b5bf011..f5dbb48e721a 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -295,58 +295,13 @@ static efi_status_t setup_rsdp(efi_bootinfo_t *efi_bootinfo)
static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
{
- int i;
- unsigned long free_mem_pages = 0;
- unsigned long free_mem_start = 0;
- struct efi_boot_memmap *map = &(efi_bootinfo->mem_map);
- efi_memory_desc_t *buffer = *map->map;
- efi_memory_desc_t *d = NULL;
- struct mem_region r, *code, *data;
- const void *fdt = efi_bootinfo->fdt;
-
- /*
- * Record the largest free EFI_CONVENTIONAL_MEMORY region
- * which will be used to set up the memory allocator, so that
- * the memory allocator can work in the largest free
- * continuous memory region.
- */
- for (i = 0; i < *(map->map_size); i += *(map->desc_size)) {
- d = (efi_memory_desc_t *)(&((u8 *)buffer)[i]);
-
- r.start = d->phys_addr;
- r.end = d->phys_addr + d->num_pages * EFI_PAGE_SIZE;
- r.flags = 0;
-
- switch (d->type) {
- case EFI_RESERVED_TYPE:
- case EFI_LOADER_DATA:
- case EFI_BOOT_SERVICES_CODE:
- case EFI_BOOT_SERVICES_DATA:
- case EFI_RUNTIME_SERVICES_CODE:
- case EFI_RUNTIME_SERVICES_DATA:
- case EFI_UNUSABLE_MEMORY:
- case EFI_ACPI_RECLAIM_MEMORY:
- case EFI_ACPI_MEMORY_NVS:
- case EFI_PAL_CODE:
- r.flags = MR_F_RESERVED;
- break;
- case EFI_MEMORY_MAPPED_IO:
- case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
- r.flags = MR_F_IO;
- break;
- case EFI_LOADER_CODE:
- r.flags = MR_F_CODE;
- break;
- case EFI_CONVENTIONAL_MEMORY:
- if (free_mem_pages < d->num_pages) {
- free_mem_pages = d->num_pages;
- free_mem_start = d->phys_addr;
- }
- break;
- }
+ struct mem_region *freemem_mr = NULL, *code, *data;
+ phys_addr_t freemem_start;
+ void *freemem;
- memregions_add(&r);
- }
+ memregions_efi_init(&efi_bootinfo->mem_map, &freemem_mr);
+ if (!freemem_mr)
+ return EFI_OUT_OF_RESOURCES;
memregions_split((unsigned long)&_etext, &code, &data);
assert(code && (code->flags & MR_F_CODE));
@@ -366,24 +321,17 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
}
__phys_end &= PHYS_MASK;
- if (fdt) {
- unsigned long old_start = free_mem_start;
- void *freemem = (void *)free_mem_start;
+ freemem = (void *)PAGE_ALIGN(freemem_mr->start);
- freemem_push_fdt(&freemem, fdt);
+ if (efi_bootinfo->fdt)
+ freemem_push_fdt(&freemem, efi_bootinfo->fdt);
- free_mem_start = ALIGN((unsigned long)freemem, EFI_PAGE_SIZE);
- free_mem_pages = (free_mem_start - old_start) >> EFI_PAGE_SHIFT;
- }
+ freemem_start = PAGE_ALIGN((unsigned long)freemem);
+ assert(sizeof(long) == 8 || freemem_start < (3ul << 30));
asm_mmu_disable();
- if (free_mem_pages == 0)
- return EFI_OUT_OF_RESOURCES;
-
- assert(sizeof(long) == 8 || free_mem_start < (3ul << 30));
-
- mem_allocator_init(free_mem_start, free_mem_start + (free_mem_pages << EFI_PAGE_SHIFT));
+ mem_allocator_init(freemem_start, freemem_mr->end);
return EFI_SUCCESS;
}
diff --git a/lib/memregions.c b/lib/memregions.c
index 96de86b27333..9cdbb639ab62 100644
--- a/lib/memregions.c
+++ b/lib/memregions.c
@@ -80,3 +80,54 @@ void memregions_add_dt_regions(size_t max_nr)
});
}
}
+
+#ifdef CONFIG_EFI
+/*
+ * Add memory regions based on the EFI memory map. Also set a pointer to the
+ * memory region which corresponds to the largest EFI_CONVENTIONAL_MEMORY
+ * region, as that region is the largest free, continuous region, making it
+ * a good choice for the memory allocator.
+ */
+void memregions_efi_init(struct efi_boot_memmap *mem_map,
+ struct mem_region **freemem)
+{
+ u8 *buffer = (u8 *)*mem_map->map;
+ u64 freemem_pages = 0;
+
+ *freemem = NULL;
+
+ for (int i = 0; i < *mem_map->map_size; i += *mem_map->desc_size) {
+ efi_memory_desc_t *d = (efi_memory_desc_t *)&buffer[i];
+ struct mem_region r = {
+ .start = d->phys_addr,
+ .end = d->phys_addr + d->num_pages * EFI_PAGE_SIZE,
+ .flags = 0,
+ };
+
+ switch (d->type) {
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ r.flags = MR_F_IO;
+ break;
+ case EFI_LOADER_CODE:
+ r.flags = MR_F_CODE;
+ break;
+ case EFI_PERSISTENT_MEMORY:
+ r.flags = MR_F_PERSISTENT;
+ break;
+ case EFI_CONVENTIONAL_MEMORY:
+ if (freemem_pages < d->num_pages) {
+ freemem_pages = d->num_pages;
+ *freemem = memregions_add(&r);
+ continue;
+ }
+ break;
+ default:
+ r.flags = MR_F_RESERVED;
+ break;
+ }
+
+ memregions_add(&r);
+ }
+}
+#endif /* CONFIG_EFI */
diff --git a/lib/memregions.h b/lib/memregions.h
index 9a8e33182fe5..1600530ad7bf 100644
--- a/lib/memregions.h
+++ b/lib/memregions.h
@@ -9,6 +9,7 @@
#define MR_F_IO BIT(0)
#define MR_F_CODE BIT(1)
#define MR_F_RESERVED BIT(2)
+#define MR_F_PERSISTENT BIT(3)
#define MR_F_UNKNOWN BIT(31)
struct mem_region {
@@ -26,4 +27,9 @@ uint32_t memregions_get_flags(phys_addr_t paddr);
void memregions_split(phys_addr_t addr, struct mem_region **r1, struct mem_region **r2);
void memregions_add_dt_regions(size_t max_nr);
+#ifdef CONFIG_EFI
+#include <efi.h>
+void memregions_efi_init(struct efi_boot_memmap *mem_map, struct mem_region **freemem);
+#endif
+
#endif /* _MEMREGIONS_H_ */
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 15/18] arm64: efi: Don't map reserved regions
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (13 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 14/18] arm64: Add memregions_efi_init Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 16/18] arm64: efi: Fix _start returns from failed _relocate Andrew Jones
` (3 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
We shouldn't need to map all the regions that the EFI memory map
contains. Just map EFI_LOADER_CODE and EFI_LOADER_DATA, since
those are for the loaded unit test, and any region types which
could be used by the unit test for its own memory allocations. We
still map EFI_BOOT_SERVICES_DATA since the primary stack is on a
region of that type. In a later patch we'll switch to a stack we
allocate ourselves to drop that one too.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/arm/mmu.c | 6 +-----
lib/arm/setup.c | 4 ++--
lib/memregions.c | 8 ++++++++
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c
index eb5e82a95f06..9dce7da85709 100644
--- a/lib/arm/mmu.c
+++ b/lib/arm/mmu.c
@@ -221,12 +221,8 @@ void *setup_mmu(phys_addr_t phys_end, void *unused)
mmu_idmap = alloc_page();
for (r = mem_regions; r->end; ++r) {
- if (r->flags & MR_F_IO) {
+ if (r->flags & (MR_F_IO | MR_F_RESERVED)) {
continue;
- } else if (r->flags & MR_F_RESERVED) {
- /* Reserved pages need to be writable for whatever reserved them */
- mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end,
- __pgprot(PTE_WBWA));
} else if (r->flags & MR_F_CODE) {
/* armv8 requires code shared between EL1 and EL0 to be read-only */
mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end,
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index f5dbb48e721a..50a3bb65d865 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -309,8 +309,8 @@ static efi_status_t efi_mem_init(efi_bootinfo_t *efi_bootinfo)
data->flags &= ~MR_F_CODE;
for (struct mem_region *m = mem_regions; m->end; ++m) {
- if (m != code && (m->flags & MR_F_CODE))
- m->flags = MR_F_RESERVED;
+ if (m != code)
+ assert(!(m->flags & MR_F_CODE));
if (!(m->flags & MR_F_IO)) {
if (m->start < __phys_offset)
diff --git a/lib/memregions.c b/lib/memregions.c
index 9cdbb639ab62..3c6f751eb4f2 100644
--- a/lib/memregions.c
+++ b/lib/memregions.c
@@ -112,6 +112,14 @@ void memregions_efi_init(struct efi_boot_memmap *mem_map,
case EFI_LOADER_CODE:
r.flags = MR_F_CODE;
break;
+ case EFI_LOADER_DATA:
+ break;
+ case EFI_BOOT_SERVICES_DATA:
+ /*
+ * FIXME: This would ideally be MR_F_RESERVED, but the
+ * primary stack is in a region of this EFI type.
+ */
+ break;
case EFI_PERSISTENT_MEMORY:
r.flags = MR_F_PERSISTENT;
break;
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 16/18] arm64: efi: Fix _start returns from failed _relocate
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (14 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 15/18] arm64: efi: Don't map reserved regions Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 17/18] arm64: efi: Switch to our own stack Andrew Jones
` (2 subsequent siblings)
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
If _relocate fails we need to restore the frame pointer and the link
register and return from _start. But we've pushed x0 and x1 on below
the fp and lr, so, as the code was, we'd restore the wrong values.
Revert parts of the code back to the way they are in gnu-efi and move
the stack alignment below the loading of x0 and x1, after we've
confirmed _relocate didn't fail.
Fixes: d231b539a41f ("arm64: Use code from the gnu-efi when booting with EFI")
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/crt0-efi-aarch64.S | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/arm/efi/crt0-efi-aarch64.S b/arm/efi/crt0-efi-aarch64.S
index 5d0dc04af54a..5fd3dc94dae8 100644
--- a/arm/efi/crt0-efi-aarch64.S
+++ b/arm/efi/crt0-efi-aarch64.S
@@ -111,17 +111,10 @@ section_table:
.align 12
_start:
- stp x29, x30, [sp, #-16]!
-
- /* Align sp; this is necessary due to way we store cpu0's thread_info */
+ stp x29, x30, [sp, #-32]!
mov x29, sp
- mov x30, sp
- and x30, x30, #THREAD_MASK
- mov sp, x30
- str x29, [sp, #-16]!
-
- stp x0, x1, [sp, #-16]!
+ stp x0, x1, [sp, #16]
mov x2, x0
mov x3, x1
adr x0, ImageBase
@@ -130,12 +123,20 @@ _start:
bl _relocate
cbnz x0, 0f
- ldp x0, x1, [sp], #16
+ ldp x0, x1, [sp, #16]
+
+ /* Align sp; this is necessary due to way we store cpu0's thread_info */
+ mov x29, sp
+ mov x30, sp
+ and x30, x30, #THREAD_MASK
+ mov sp, x30
+ str x29, [sp, #-16]!
+
bl efi_main
/* Restore sp */
ldr x30, [sp], #16
- mov sp, x30
+ mov sp, x30
-0: ldp x29, x30, [sp], #16
+0: ldp x29, x30, [sp], #32
ret
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 17/18] arm64: efi: Switch to our own stack
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (15 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 16/18] arm64: efi: Fix _start returns from failed _relocate Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 18/18] arm64: efi: Add gitlab CI Andrew Jones
2024-03-18 16:47 ` [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
We don't want to map EFI_BOOT_SERVICES_DATA regions, so move the
stack from its EFI_BOOT_SERVICES_DATA region to EFI_LOADER_CODE,
which we always map. We'll still map the stack as R/W instead of
R/X because we split EFI_LOADER_CODE regions on the _etext boundary
and map addresses before _etext as R/X and the rest as R/W.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
arm/efi/crt0-efi-aarch64.S | 22 +++++++++++++++++-----
lib/arm/setup.c | 4 ----
lib/memregions.c | 6 ------
3 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/arm/efi/crt0-efi-aarch64.S b/arm/efi/crt0-efi-aarch64.S
index 5fd3dc94dae8..71ce2794f059 100644
--- a/arm/efi/crt0-efi-aarch64.S
+++ b/arm/efi/crt0-efi-aarch64.S
@@ -125,12 +125,18 @@ _start:
ldp x0, x1, [sp, #16]
- /* Align sp; this is necessary due to way we store cpu0's thread_info */
+ /*
+ * Switch to our own stack and align sp; this is necessary due
+ * to way we store cpu0's thread_info
+ */
+ adrp x2, stacktop
+ add x2, x2, :lo12:stacktop
+ and x2, x2, #THREAD_MASK
+ mov x3, sp
+ mov sp, x2
+ stp xzr, xzr, [sp, #-16]!
mov x29, sp
- mov x30, sp
- and x30, x30, #THREAD_MASK
- mov sp, x30
- str x29, [sp, #-16]!
+ str x3, [sp, #-16]!
bl efi_main
@@ -140,3 +146,9 @@ _start:
0: ldp x29, x30, [sp], #32
ret
+
+ .section .data
+
+.balign 65536
+.space 65536
+stacktop:
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 50a3bb65d865..2f649aff5551 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -340,10 +340,6 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
{
efi_status_t status;
- struct thread_info *ti = current_thread_info();
-
- memset(ti, 0, sizeof(*ti));
-
exceptions_init();
memregions_init(arm_mem_regions, NR_MEM_REGIONS);
diff --git a/lib/memregions.c b/lib/memregions.c
index 3c6f751eb4f2..53fc0c7cfc58 100644
--- a/lib/memregions.c
+++ b/lib/memregions.c
@@ -114,12 +114,6 @@ void memregions_efi_init(struct efi_boot_memmap *mem_map,
break;
case EFI_LOADER_DATA:
break;
- case EFI_BOOT_SERVICES_DATA:
- /*
- * FIXME: This would ideally be MR_F_RESERVED, but the
- * primary stack is in a region of this EFI type.
- */
- break;
case EFI_PERSISTENT_MEMORY:
r.flags = MR_F_PERSISTENT;
break;
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [kvm-unit-tests PATCH v3 18/18] arm64: efi: Add gitlab CI
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (16 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 17/18] arm64: efi: Switch to our own stack Andrew Jones
@ 2024-03-05 16:46 ` Andrew Jones
2024-03-18 16:47 ` [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-05 16:46 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
Now that we have efi-direct and tests run much faster, add a few
(just selftests) to the CI. Test with both DT and ACPI. While
touching the file update arm and arm64's pass/fail criteria to
the new style that ensures they're not all skips.
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
.gitlab-ci.yml | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 71d986e9884e..ff34b1f5062e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -44,7 +44,35 @@ build-aarch64:
selftest-vectors-user
timer
| tee results.txt
- - if grep -q FAIL results.txt ; then exit 1 ; fi
+ - grep -q PASS results.txt && ! grep -q FAIL results.txt
+
+build-aarch64-efi:
+ extends: .intree_template
+ script:
+ - dnf install -y qemu-system-aarch64 gcc-aarch64-linux-gnu edk2-aarch64
+ - ./configure --arch=aarch64 --cross-prefix=aarch64-linux-gnu- --enable-efi --enable-efi-direct
+ - make -j2
+ - ACCEL=tcg MAX_SMP=8 ./run_tests.sh
+ selftest-setup
+ selftest-smp
+ selftest-vectors-kernel
+ selftest-vectors-user
+ | tee results.txt
+ - grep -q PASS results.txt && ! grep -q FAIL results.txt
+
+build-aarch64-efi-acpi:
+ extends: .intree_template
+ script:
+ - dnf install -y qemu-system-aarch64 gcc-aarch64-linux-gnu edk2-aarch64
+ - ./configure --arch=aarch64 --cross-prefix=aarch64-linux-gnu- --enable-efi --enable-efi-direct
+ - make -j2
+ - EFI_USE_ACPI=y ACCEL=tcg MAX_SMP=8 ./run_tests.sh
+ selftest-setup
+ selftest-smp
+ selftest-vectors-kernel
+ selftest-vectors-user
+ | tee results.txt
+ - grep -q PASS results.txt && ! grep -q FAIL results.txt
build-arm:
extends: .outoftree_template
@@ -59,7 +87,7 @@ build-arm:
pci-test pmu-cycle-counter gicv2-ipi gicv2-mmio gicv3-ipi gicv2-active
gicv3-active
| tee results.txt
- - if grep -q FAIL results.txt ; then exit 1 ; fi
+ - grep -q PASS results.txt && ! grep -q FAIL results.txt
build-ppc64be:
extends: .outoftree_template
--
2.44.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe Andrew Jones
@ 2024-03-07 2:29 ` Shaoqin Huang
0 siblings, 0 replies; 26+ messages in thread
From: Shaoqin Huang @ 2024-03-07 2:29 UTC (permalink / raw)
To: Andrew Jones, kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, pbonzini, thuth
On 3/6/24 00:46, Andrew Jones wrote:
> Arm's MAX_SMP probing must have stopped working at some point due to
> QEMU's error message changing, but nobody noticed. Also, the probing
> should work for at least x86 now too, so the comment isn't correct
> anymore either. We could probably just delete this probe thing, but
> in case it could still serve some purpose we can also keep it, but
> updated for later QEMU, and only enabled when a new run_tests.sh
> command line option is provided.
> > Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> run_tests.sh | 5 ++++-
> scripts/runtime.bash | 19 ++++++++++---------
> 2 files changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/run_tests.sh b/run_tests.sh
> index abb0ab773362..bb3024ff95b1 100755
> --- a/run_tests.sh
> +++ b/run_tests.sh
> @@ -44,7 +44,7 @@ fi
>
> only_tests=""
> list_tests=""
> -args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list -- $*)
> +args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list,probe-maxsmp -- $*)
> [ $? -ne 0 ] && exit 2;
> set -- $args;
> while [ $# -gt 0 ]; do
> @@ -78,6 +78,9 @@ while [ $# -gt 0 ]; do
> -l | --list)
> list_tests="yes"
> ;;
> + --probe-maxsmp)
> + probe_maxsmp
> + ;;
> --)
> ;;
> *)
> diff --git a/scripts/runtime.bash b/scripts/runtime.bash
> index c73fb0240d12..f2e43bb1ed60 100644
> --- a/scripts/runtime.bash
> +++ b/scripts/runtime.bash
> @@ -200,12 +200,13 @@ function run()
> #
> # Probe for MAX_SMP, in case it's less than the number of host cpus.
> #
> -# This probing currently only works for ARM, as x86 bails on another
> -# error first, so this check is only run for ARM and ARM64. The
> -# parameter expansion takes the last number from the QEMU error
> -# message, which gives the allowable MAX_SMP.
> -if [[ $ARCH == 'arm' || $ARCH == 'arm64' ]] &&
> - smp=$($RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP |& grep 'exceeds max CPUs'); then
> - smp=${smp##*(}
> - MAX_SMP=${smp:0:-1}
> -fi
> +function probe_maxsmp()
> +{
> + local smp
> +
> + if smp=$($RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP |& grep 'Invalid SMP CPUs'); then
> + smp=${smp##* }
> + echo "Restricting MAX_SMP from ($MAX_SMP) to the max supported ($smp)" >&2
> + MAX_SMP=$smp
> + fi
> +}
--
Shaoqin
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 02/18] runtime: Add yet another 'no kernel' error message
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 02/18] runtime: Add yet another 'no kernel' error message Andrew Jones
@ 2024-03-07 2:39 ` Shaoqin Huang
0 siblings, 0 replies; 26+ messages in thread
From: Shaoqin Huang @ 2024-03-07 2:39 UTC (permalink / raw)
To: Andrew Jones, kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, pbonzini, thuth
On 3/6/24 00:46, Andrew Jones wrote:
> When booting an Arm machine with the -bios command line option we
> get yet another error message from QEMU when using _NO_FILE_4Uhere_
> to probe command line support. Add it to the check in
> premature_failure()
>
> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> scripts/runtime.bash | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/runtime.bash b/scripts/runtime.bash
> index f2e43bb1ed60..255e756f2cb2 100644
> --- a/scripts/runtime.bash
> +++ b/scripts/runtime.bash
> @@ -18,7 +18,7 @@ premature_failure()
> local log="$(eval "$(get_cmdline _NO_FILE_4Uhere_)" 2>&1)"
>
> echo "$log" | grep "_NO_FILE_4Uhere_" |
> - grep -q -e "could not \(load\|open\) kernel" -e "error loading" &&
> + grep -q -e "could not \(load\|open\) kernel" -e "error loading" -e "failed to load" &&
> return 1
>
> RUNTIME_log_stderr <<< "$log"
--
Shaoqin
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 03/18] arm64: efi: Don't create dummy test
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 03/18] arm64: efi: Don't create dummy test Andrew Jones
@ 2024-03-07 3:37 ` Shaoqin Huang
0 siblings, 0 replies; 26+ messages in thread
From: Shaoqin Huang @ 2024-03-07 3:37 UTC (permalink / raw)
To: Andrew Jones, kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, pbonzini, thuth
On 3/6/24 00:46, Andrew Jones wrote:
> The purpose of the _NO_FILE_4Uhere_ kernel is to check that all the
> QEMU command line options that have been pulled together by the
> scripts will work. Since booting with UEFI and the -kernel command
> line is supported by QEMU, then we don't need to create a dummy
> test for _NO_FILE_4Uhere_ and go all the way into UEFI's shell and
> execute it to prove the command line is OK, since we would have
> failed much before all that if it wasn't. Just run QEMU "normally",
> i.e. no EFI_RUN=y, but add the UEFI -bios and its file system command
> line options, in order to check the full command line.
It should absolutely accelerate the speed of efi tests.
>
> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
> ---
> arm/efi/run | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arm/efi/run b/arm/efi/run
> index 6872c337c945..e629abde5273 100755
> --- a/arm/efi/run
> +++ b/arm/efi/run
> @@ -53,7 +53,14 @@ while (( "$#" )); do
> done
>
> if [ "$EFI_CASE" = "_NO_FILE_4Uhere_" ]; then
> - EFI_CASE=dummy
> + EFI_CASE_DIR="$EFI_TEST/dummy"
> + mkdir -p "$EFI_CASE_DIR"
> + $TEST_DIR/run \
> + $EFI_CASE \
> + -bios "$EFI_UEFI" \
> + -drive file.dir="$EFI_CASE_DIR/",file.driver=vvfat,file.rw=on,format=raw,if=virtio \
> + "${qemu_args[@]}"
> + exit
> fi
>
> : "${EFI_CASE_DIR:="$EFI_TEST/$EFI_CASE"}"
--
Shaoqin
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
` (17 preceding siblings ...)
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 18/18] arm64: efi: Add gitlab CI Andrew Jones
@ 2024-03-18 16:47 ` Andrew Jones
18 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-18 16:47 UTC (permalink / raw)
To: kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth
On Tue, Mar 05, 2024 at 05:46:24PM +0100, Andrew Jones wrote:
> This series collects one fix ("Update MAX_SMP probe") with a bunch of
> improvements to the EFI setup code and run script. With the series
> applied one can add --enable-efi-direct when configuring and then
> run the EFI tests on QEMU much, much faster by using direct kernel
> boot for them (and environment variables will work too). The non-
> direct (original) way of running the EFI tests has also been sped up
> a bit by not running the dummy test and not generating the dtb twice.
> The cleanups in the setup code allow duplicated code to be removed
> (by sharing with the non-EFI setup code) and eventually for riscv
> to share some code too with the introduction of memregions_efi_init().
>
> v3:
> - Dropped fdt_valid
> - Factored out qemu_args+=(-machine acpi=off) [Nikos]
> - Ensure etext is page aligned
> - Picked up Nikos's r-b's
>
> v2:
> - Add another improvement (patches 15-17), which is to stop mapping
> EFI regions which we consider reserved (including
> EFI_BOOT_SERVICES_DATA regions which requires moving the primary stack)
> - Add EFI gitlab CI tests
> - Fix one typo in configure help text
>
>
> Andrew Jones (17):
> runtime: Update MAX_SMP probe
> runtime: Add yet another 'no kernel' error message
> arm64: efi: Don't create dummy test
> arm64: efi: Remove redundant dtb generation
> arm64: efi: Move run code into a function
> arm64: efi: Remove EFI_USE_DTB
> arm64: efi: Improve device tree discovery
> lib/efi: Add support for loading the initrd
> arm64: efi: Allow running tests directly
> arm/arm64: Factor out some initial setup
> arm/arm64: Factor out allocator init from mem_init
> arm64: Simplify efi_mem_init
> arm64: Add memregions_efi_init
> arm64: efi: Don't map reserved regions
> arm64: efi: Fix _start returns from failed _relocate
> arm64: efi: Switch to our own stack
> arm64: efi: Add gitlab CI
>
> Shaoqin Huang (1):
> arm64: efi: Make running tests on EFI can be parallel
>
> .gitlab-ci.yml | 32 ++++-
> arm/efi/crt0-efi-aarch64.S | 37 ++++--
> arm/efi/elf_aarch64_efi.lds | 1 +
> arm/efi/run | 64 ++++++----
> arm/run | 6 +-
> configure | 17 +++
> lib/arm/mmu.c | 6 +-
> lib/arm/setup.c | 227 ++++++++++++++----------------------
> lib/efi.c | 84 +++++++++++--
> lib/linux/efi.h | 29 +++++
> lib/memregions.c | 53 +++++++++
> lib/memregions.h | 6 +
> run_tests.sh | 5 +-
> scripts/runtime.bash | 21 ++--
> 14 files changed, 389 insertions(+), 199 deletions(-)
>
> --
> 2.44.0
>
Merged.
Thanks,
drew
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery Andrew Jones
@ 2024-03-25 16:24 ` Paluri, PavanKumar
2024-03-25 21:59 ` Nikos Nikoleris
0 siblings, 1 reply; 26+ messages in thread
From: Paluri, PavanKumar @ 2024-03-25 16:24 UTC (permalink / raw)
To: Andrew Jones, kvm, kvmarm
Cc: alexandru.elisei, eric.auger, nikos.nikoleris, shahuang, pbonzini,
thuth, Pavan Kumar Paluri
Hi,
On 3/5/2024 10:46 AM, Andrew Jones wrote:
> Check the device tree GUID when the environment variable is missing,
> which allows directly loading the unit test with QEMU's '-kernel'
> command line parameter, which is much faster than putting the test
> in the EFI file system and then running it from the UEFI shell.
>
> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
> ---
> lib/efi.c | 19 ++++++++++++-------
> lib/linux/efi.h | 2 ++
> 2 files changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/lib/efi.c b/lib/efi.c
> index d94f0fa16fc0..4d1126b4a64e 100644
> --- a/lib/efi.c
> +++ b/lib/efi.c
> @@ -6,13 +6,13 @@
> *
> * SPDX-License-Identifier: LGPL-2.0-or-later
> */
> -
> -#include "efi.h"
> +#include <libcflat.h>
> #include <argv.h>
> -#include <stdlib.h>
> #include <ctype.h>
> -#include <libcflat.h>
> +#include <stdlib.h>
> #include <asm/setup.h>
> +#include "efi.h"
> +#include "libfdt/libfdt.h"
>
> /* From lib/argv.c */
> extern int __argc, __envc;
> @@ -288,13 +288,18 @@ static void *efi_get_fdt(efi_handle_t handle, struct efi_loaded_image_64 *image)
> efi_char16_t var[] = ENV_VARNAME_DTBFILE;
> efi_char16_t *val;
> void *fdt = NULL;
> - int fdtsize;
> + int fdtsize = 0;
>
> val = efi_get_var(handle, image, var);
> - if (val)
> + if (val) {
> efi_load_image(handle, image, &fdt, &fdtsize, val);
> + if (fdtsize == 0)
> + return NULL;
> + } else if (efi_get_system_config_table(DEVICE_TREE_GUID, &fdt) != EFI_SUCCESS) {
> + return NULL;
> + }
>
> - return fdt;
> + return fdt_check_header(fdt) == 0 ? fdt : NULL;
The call to fdt_check_header() seems to be breaking x86 based UEFI
tests. I have tested it with .x86/efi/run ./x86/smptest.efi
Thanks,
Pavan
> }
>
> efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
> diff --git a/lib/linux/efi.h b/lib/linux/efi.h
> index 410f0b1a0da1..92d798f79767 100644
> --- a/lib/linux/efi.h
> +++ b/lib/linux/efi.h
> @@ -66,6 +66,8 @@ typedef guid_t efi_guid_t;
> #define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
> #define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
>
> +#define DEVICE_TREE_GUID EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
> +
> #define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
>
> typedef struct {
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery
2024-03-25 16:24 ` Paluri, PavanKumar
@ 2024-03-25 21:59 ` Nikos Nikoleris
2024-03-26 9:03 ` Andrew Jones
0 siblings, 1 reply; 26+ messages in thread
From: Nikos Nikoleris @ 2024-03-25 21:59 UTC (permalink / raw)
To: Paluri, PavanKumar, Andrew Jones, kvm, kvmarm
Cc: alexandru.elisei, eric.auger, shahuang, pbonzini, thuth
On 25/03/2024 16:24, Paluri, PavanKumar wrote:
> Hi,
>
> On 3/5/2024 10:46 AM, Andrew Jones wrote:
>> Check the device tree GUID when the environment variable is missing,
>> which allows directly loading the unit test with QEMU's '-kernel'
>> command line parameter, which is much faster than putting the test
>> in the EFI file system and then running it from the UEFI shell.
>>
>> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
>> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
>> ---
>> lib/efi.c | 19 ++++++++++++-------
>> lib/linux/efi.h | 2 ++
>> 2 files changed, 14 insertions(+), 7 deletions(-)
>>
>> diff --git a/lib/efi.c b/lib/efi.c
>> index d94f0fa16fc0..4d1126b4a64e 100644
>> --- a/lib/efi.c
>> +++ b/lib/efi.c
>> @@ -6,13 +6,13 @@
>> *
>> * SPDX-License-Identifier: LGPL-2.0-or-later
>> */
>> -
>> -#include "efi.h"
>> +#include <libcflat.h>
>> #include <argv.h>
>> -#include <stdlib.h>
>> #include <ctype.h>
>> -#include <libcflat.h>
>> +#include <stdlib.h>
>> #include <asm/setup.h>
>> +#include "efi.h"
>> +#include "libfdt/libfdt.h"
>>
>> /* From lib/argv.c */
>> extern int __argc, __envc;
>> @@ -288,13 +288,18 @@ static void *efi_get_fdt(efi_handle_t handle, struct efi_loaded_image_64 *image)
>> efi_char16_t var[] = ENV_VARNAME_DTBFILE;
>> efi_char16_t *val;
>> void *fdt = NULL;
>> - int fdtsize;
>> + int fdtsize = 0;
>>
>> val = efi_get_var(handle, image, var);
>> - if (val)
>> + if (val) {
>> efi_load_image(handle, image, &fdt, &fdtsize, val);
>> + if (fdtsize == 0)
>> + return NULL;
>> + } else if (efi_get_system_config_table(DEVICE_TREE_GUID, &fdt) != EFI_SUCCESS) {
>> + return NULL;
>> + }
>>
>> - return fdt;
>> + return fdt_check_header(fdt) == 0 ? fdt : NULL;
>
> The call to fdt_check_header() seems to be breaking x86 based UEFI
> tests. I have tested it with .x86/efi/run ./x86/smptest.efi
I am not familiar with the x86 boot process but I would have thought
that the efi shell variable "fdtfile" is not set and as a result val
would be NULL. Then efi_get_system_config_table(DEVICE_TREE_GUID, &fdt)
would return EFI_NOT_FOUND and efi_get_fdt would return NULL without
executing the line fdt_check_header(fdt).
Thanks,
Nikos
>
> Thanks,
> Pavan
>> }
>>
>> efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
>> diff --git a/lib/linux/efi.h b/lib/linux/efi.h
>> index 410f0b1a0da1..92d798f79767 100644
>> --- a/lib/linux/efi.h
>> +++ b/lib/linux/efi.h
>> @@ -66,6 +66,8 @@ typedef guid_t efi_guid_t;
>> #define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
>> #define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
>>
>> +#define DEVICE_TREE_GUID EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
>> +
>> #define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
>>
>> typedef struct {
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery
2024-03-25 21:59 ` Nikos Nikoleris
@ 2024-03-26 9:03 ` Andrew Jones
0 siblings, 0 replies; 26+ messages in thread
From: Andrew Jones @ 2024-03-26 9:03 UTC (permalink / raw)
To: Nikos Nikoleris
Cc: Paluri, PavanKumar, kvm, kvmarm, alexandru.elisei, eric.auger,
shahuang, pbonzini, thuth
On Mon, Mar 25, 2024 at 09:59:00PM +0000, Nikos Nikoleris wrote:
> On 25/03/2024 16:24, Paluri, PavanKumar wrote:
> > Hi,
> >
> > On 3/5/2024 10:46 AM, Andrew Jones wrote:
> > > Check the device tree GUID when the environment variable is missing,
> > > which allows directly loading the unit test with QEMU's '-kernel'
> > > command line parameter, which is much faster than putting the test
> > > in the EFI file system and then running it from the UEFI shell.
> > >
> > > Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
> > > Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
> > > ---
> > > lib/efi.c | 19 ++++++++++++-------
> > > lib/linux/efi.h | 2 ++
> > > 2 files changed, 14 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/lib/efi.c b/lib/efi.c
> > > index d94f0fa16fc0..4d1126b4a64e 100644
> > > --- a/lib/efi.c
> > > +++ b/lib/efi.c
> > > @@ -6,13 +6,13 @@
> > > *
> > > * SPDX-License-Identifier: LGPL-2.0-or-later
> > > */
> > > -
> > > -#include "efi.h"
> > > +#include <libcflat.h>
> > > #include <argv.h>
> > > -#include <stdlib.h>
> > > #include <ctype.h>
> > > -#include <libcflat.h>
> > > +#include <stdlib.h>
> > > #include <asm/setup.h>
> > > +#include "efi.h"
> > > +#include "libfdt/libfdt.h"
> > > /* From lib/argv.c */
> > > extern int __argc, __envc;
> > > @@ -288,13 +288,18 @@ static void *efi_get_fdt(efi_handle_t handle, struct efi_loaded_image_64 *image)
> > > efi_char16_t var[] = ENV_VARNAME_DTBFILE;
> > > efi_char16_t *val;
> > > void *fdt = NULL;
> > > - int fdtsize;
> > > + int fdtsize = 0;
> > > val = efi_get_var(handle, image, var);
> > > - if (val)
> > > + if (val) {
> > > efi_load_image(handle, image, &fdt, &fdtsize, val);
> > > + if (fdtsize == 0)
> > > + return NULL;
> > > + } else if (efi_get_system_config_table(DEVICE_TREE_GUID, &fdt) != EFI_SUCCESS) {
> > > + return NULL;
> > > + }
> > > - return fdt;
> > > + return fdt_check_header(fdt) == 0 ? fdt : NULL;
> >
> > The call to fdt_check_header() seems to be breaking x86 based UEFI
> > tests. I have tested it with .x86/efi/run ./x86/smptest.efi
>
> I am not familiar with the x86 boot process but I would have thought that
> the efi shell variable "fdtfile" is not set and as a result val would be
> NULL. Then efi_get_system_config_table(DEVICE_TREE_GUID, &fdt) would return
> EFI_NOT_FOUND and efi_get_fdt would return NULL without executing the line
> fdt_check_header(fdt).
I suppose there could be a table (maybe empty?) with the DEVICE_TREE_GUID
guid? Anyway, we should probably just #ifdef out the function since x86
kvm-unit-tests doesn't link with libfdt and the only reason it can compile
with an undefined reference to fdt_check_header() is because we create
.efi files through shared libraries.
Thanks,
drew
>
> Thanks,
>
> Nikos
>
> >
> > Thanks,
> > Pavan
> > > }
> > > efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab)
> > > diff --git a/lib/linux/efi.h b/lib/linux/efi.h
> > > index 410f0b1a0da1..92d798f79767 100644
> > > --- a/lib/linux/efi.h
> > > +++ b/lib/linux/efi.h
> > > @@ -66,6 +66,8 @@ typedef guid_t efi_guid_t;
> > > #define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
> > > #define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
> > > +#define DEVICE_TREE_GUID EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
> > > +
> > > #define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
> > > typedef struct {
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2024-03-26 9:04 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-05 16:46 [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 01/18] runtime: Update MAX_SMP probe Andrew Jones
2024-03-07 2:29 ` Shaoqin Huang
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 02/18] runtime: Add yet another 'no kernel' error message Andrew Jones
2024-03-07 2:39 ` Shaoqin Huang
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 03/18] arm64: efi: Don't create dummy test Andrew Jones
2024-03-07 3:37 ` Shaoqin Huang
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 04/18] arm64: efi: Make running tests on EFI can be parallel Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 05/18] arm64: efi: Remove redundant dtb generation Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 06/18] arm64: efi: Move run code into a function Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 07/18] arm64: efi: Remove EFI_USE_DTB Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 08/18] arm64: efi: Improve device tree discovery Andrew Jones
2024-03-25 16:24 ` Paluri, PavanKumar
2024-03-25 21:59 ` Nikos Nikoleris
2024-03-26 9:03 ` Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 09/18] lib/efi: Add support for loading the initrd Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 10/18] arm64: efi: Allow running tests directly Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 11/18] arm/arm64: Factor out some initial setup Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 12/18] arm/arm64: Factor out allocator init from mem_init Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 13/18] arm64: Simplify efi_mem_init Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 14/18] arm64: Add memregions_efi_init Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 15/18] arm64: efi: Don't map reserved regions Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 16/18] arm64: efi: Fix _start returns from failed _relocate Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 17/18] arm64: efi: Switch to our own stack Andrew Jones
2024-03-05 16:46 ` [kvm-unit-tests PATCH v3 18/18] arm64: efi: Add gitlab CI Andrew Jones
2024-03-18 16:47 ` [kvm-unit-tests PATCH v3 00/18] arm64: EFI improvements Andrew Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox