diff -Nru grub2-2.04/debian/changelog grub2-2.04/debian/changelog --- grub2-2.04/debian/changelog 2022-12-02 15:20:54.000000000 +0000 +++ grub2-2.04/debian/changelog 2022-12-18 21:29:03.000000000 +0000 @@ -1,3 +1,11 @@ +grub2 (2.04-1ubuntu26.17) focal; urgency=medium + + * linux_xen: Properly handle multiple initrd files (LP: #1987567) + - d/p/linux_xen-Properly-load-multiple-initrd-files.patch + - d/p/linux_xen-Properly-order-multiple-initrd-files.patch + + -- Mauricio Faria de Oliveira Sun, 18 Dec 2022 18:29:03 -0300 + grub2 (2.04-1ubuntu26.16) focal; urgency=medium * grub-multi-install: Reset partition type between partitions (LP: #1997795) diff -Nru grub2-2.04/debian/patches/linux_xen-Properly-load-multiple-initrd-files.patch grub2-2.04/debian/patches/linux_xen-Properly-load-multiple-initrd-files.patch --- grub2-2.04/debian/patches/linux_xen-Properly-load-multiple-initrd-files.patch 1970-01-01 00:00:00.000000000 +0000 +++ grub2-2.04/debian/patches/linux_xen-Properly-load-multiple-initrd-files.patch 2022-12-18 21:28:12.000000000 +0000 @@ -0,0 +1,123 @@ +From: Mauricio Faria de Oliveira +Date: Sat, 6 Aug 2022 20:46:48 -0300 +Subject: templates/linux_xen: Properly load multiple initrd files +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +The linux_xen template can put multiple initrd files in the +same multiboot[2] module[2] command, which is against specs. + +This causes ONLY the _first_ initrd file to be loaded; other +files just have filenames in a "cmdline" string of the first +initrd file and are NOT loaded. + +Fix this by inserting a module[2] command per initrd file. + +Before: + + # touch /boot/xen /boot/microcode.cpio + # grub-mkconfig 2>/dev/null | grep -P '^\t(multiboot|module)' + multiboot /boot/xen ... + module /boot/vmlinuz-5.4.0-122-generic ... + module --nounzip /boot/microcode.cpio /boot/initrd.img-5.4.0-122-generic + +After: + + # touch /boot/xen /boot/microcode.cpio + # grub-mkconfig 2>/dev/null | grep -P '^\t(multiboot|module)' + multiboot /boot/xen ... + module /boot/vmlinuz-5.4.0-122-generic ... + module --nounzip /boot/microcode.cpio + module --nounzip /boot/initrd.img-5.4.0-122-generic + +Cause: + +The code was copied from the linux template, which is *apparently* +equivalent.. but its backing command grub_cmd_initrd() *supports* +multiple files (see grub_initrd_init()), while grub_cmd_module() +*does not* (see grub_multiboot[2]_add_module()). + +See commit e86f6aafb8de ("grub-mkconfig/20_linux_xen: Support multiple early initrd images"): + 'This is basically a copy of a698240d "grub-mkconfig/10_linux: + Support multiple early initrd images" ...' + +Specs: + +Both multiboot and multiboot2 specifications mention support for +'multiple boot modules' (struct/tag used for kernel/initrd files): + + "Boot loaders don’t have to support multiple boot modules, + but they are strongly encouraged to" [1,2] + +However, there is a 1:1 relationship between boot modules and files, +more or less clearly; note the usage of singular/plural "module(s)". +(Multiboot2, clearly: "One tag appears per module".) + + Multiboot [1]: + + "the ‘mods’ fields indicate ... what boot modules + were loaded ..., and where they can be found. + ‘mods_count’ contains the number of modules loaded" + + "The first two fields contain the start and end addresses + of the boot module itself." + + Multiboot2 [2]: + + "This tag indicates ... what boot module was loaded ..., + and where it can be found." + + "The ‘mod_start’ and ‘mod_end’ contain the start and end + physical addresses of the boot module itself." + + "One tag appears per module. + This tag type may appear multiple times." + +And both clearly mention the 'string' field of a boot module, +which is to be used by the operating system, not boot loader: + + "The ‘string’ field provides an arbitrary string to be + associated with that particular boot module ... + its exact use is specific to the operating system." + +Links: + +[1] https://www.gnu.org/software/grub/manual/multiboot/multiboot.html + 3.3 Boot information format + +[2] https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html + 3.6.6 Modules + +Fixes: e86f6aafb8de ("grub-mkconfig/20_linux_xen: Support multiple early initrd images") + +Signed-off-by: Mauricio Faria de Oliveira + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1987567 +Origin: backport, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=b4b4acaf4ec7af1a78d122c10baed4e85187e2a5 +[mfo: backport: refresh lower context lines.] +LP: #1987567 +--- + util/grub.d/20_linux_xen.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index a12780e..6f38c5d 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -166,12 +166,12 @@ EOF + message="$(gettext_printf "Loading initial ramdisk ...")" + initrd_path= + for i in ${initrd}; do +- initrd_path="${initrd_path} ${rel_dirname}/${i}" +- done +- sed "s/^/$submenu_indentation/" << EOF ++ initrd_path="${rel_dirname}/${i}" ++ sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' + ${module_loader} --nounzip $(echo $initrd_path) + EOF ++ done + fi + sed "s/^/$submenu_indentation/" << EOF + } diff -Nru grub2-2.04/debian/patches/linux_xen-Properly-order-multiple-initrd-files.patch grub2-2.04/debian/patches/linux_xen-Properly-order-multiple-initrd-files.patch --- grub2-2.04/debian/patches/linux_xen-Properly-order-multiple-initrd-files.patch 1970-01-01 00:00:00.000000000 +0000 +++ grub2-2.04/debian/patches/linux_xen-Properly-order-multiple-initrd-files.patch 2022-12-18 21:28:12.000000000 +0000 @@ -0,0 +1,79 @@ +From: Mauricio Faria de Oliveira +Date: Sat, 6 Aug 2022 22:07:58 -0300 +Subject: templates/linux_xen: Properly order the multiple initrd files + +The linux_xen template orders the "early" initrd file(s) _first_ +(i.e., before the "real" initrd files) and that seems reasonable, +as microcode updates usually come first. + +However, this usually breaks Linux boot with initrd under Xen +because Xen assumes the real initrd is the first multiboot[2] +module after the kernel, passing its address over to Linux. + +So, if a microcode-only initrd (i.e., without init/userspace) +is found by grub-mkconfig, it ends up considered as a normal +initrd by the Linux kernel, which cannot do anything with it +(as it has no other files) and panic()s unable to mount root +if it depends on a initrd to do that (e.g., root=UUID=...). + +... + +Well, since Xen doesn't actually use the provided microcode +by default / unless the 'ucode=' option +is enabled, this isn't used in the general case (and breaks). + +Additionally, if an user enables the 'ucode=' option, that +either specifies which module is to be used for microcode, +or scans all modules (regardless of being first) for that. + +Thus, for Xen: +- it is *not required* to have microcode first, +- but it is *required* to have real initrd first + +So, fix it by ordering the real initrd before early initrd(s). + +... + +Corner case specific to Xen implementation details: + +It is actually _possible_ to have a microcode initrd first, +but that requires a non-default option (so can't rely on it), +and it turns out to be inconsistent with its counterpart +(really shouldn't rely on it, as it may get confusing; below). + +'ucode=1' does manually specify the first module is microcode +_AND_ clears its bit in the module bitmap. The next module is +now the 'new first', and gets passed to Linux as initrd. Good. + +'ucode=scan' checks all modules for microcode, but does _NOT_ +clear a bit if it finds one (reasonable, as it can find that +prepended in a "real" initrd anyway, which needs to be used). +The first module still gets passed to Linux as initrd. Bad. + +Fixes: e86f6aafb8de ("grub-mkconfig/20_linux_xen: Support multiple early initrd images") + +Signed-off-by: Mauricio Faria de Oliveira + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1987567 +Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=18d8eafdea2322dc80c37e826a75e4d62094fecc +LP: #1987567 +--- + util/grub.d/20_linux_xen.in | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index 6f38c5d..0629890 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -304,7 +304,10 @@ while [ "x${xen_list}" != "x" ] ; do + + initrd= + if test -n "${initrd_early}" || test -n "${initrd_real}"; then +- initrd="${initrd_early} ${initrd_real}" ++ # Xen assumes the real initrd is the first module after the kernel. ++ # Additional (later) initrds can also be used for microcode update, ++ # with Xen option 'ucode= (non-default anyway). ++ initrd="${initrd_real} ${initrd_early}" + + initrd_display= + for i in ${initrd}; do diff -Nru grub2-2.04/debian/patches/series grub2-2.04/debian/patches/series --- grub2-2.04/debian/patches/series 2022-12-02 15:20:54.000000000 +0000 +++ grub2-2.04/debian/patches/series 2022-12-18 21:28:12.000000000 +0000 @@ -116,3 +116,5 @@ cherry-fix-crash-on-http.patch ubuntu-add-initrd-less-boot-messages.patch 0241-Call-hwmatch-only-on-the-grub-pc-platform.patch +linux_xen-Properly-load-multiple-initrd-files.patch +linux_xen-Properly-order-multiple-initrd-files.patch