From f7e1bb53e4ea20869766206e348ad97351f94bb2 Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Thu, 25 Sep 2014 19:33:39 -0300 Subject: [PATCH 1/8] Disable VSX instruction VSX bit is enabled by default for Power7 and Power8 CPU models, so we need to disable them in order to avoid instruction exceptions. Kernel will activate it when necessary. * grub-core/kern/powerpc/ieee1275/startup.S: Disable VSX. Also-By: Adhemerval Zanella Also-By: Colin Watson Origin: other, https://lists.gnu.org/archive/html/grub-devel/2014-09/msg00078.html Last-Update: 2015-01-27 Patch-Name: ppc64el-disable-vsx.patch --- grub-core/kern/powerpc/ieee1275/startup.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S index 21c884b43..de9a9601a 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/grub-core/kern/powerpc/ieee1275/startup.S @@ -20,6 +20,8 @@ #include #include +#define MSR_VSX 0x80 + .extern __bss_start .extern _end @@ -28,6 +30,16 @@ .globl start, _start start: _start: + _start: + + /* Disable VSX instruction */ + mfmsr 0 + oris 0,0,MSR_VSX + /* The "VSX Available" bit is in the lower half of the MSR, so we + don't need mtmsrd, which in any case won't work in 32-bit mode. */ + mtmsr 0 + isync + li 2, 0 li 13, 0 From 1f6d5327f7ae4d6b2cccb6a7c7bd19e86dffbc6e Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Sat, 6 Sep 2014 12:20:12 +0100 Subject: [PATCH 2/8] grub-install: Install PV Xen binaries into the upstream specified path Upstream have defined a specification for where guests ought to place their xenpv grub binaries in order to facilitate chainloading from a stage 1 grub loaded from dom0. http://xenbits.xen.org/docs/unstable-staging/misc/x86-xenpv-bootloader.html The spec calls for installation into /boot/xen/pvboot-i386.elf or /boot/xen/pvboot-x86_64.elf. Signed-off-by: Ian Campbell Bug-Debian: https://bugs.debian.org/762307 Forwarded: http://lists.gnu.org/archive/html/grub-devel/2014-10/msg00041.html Last-Update: 2014-10-24 Patch-Name: grub-install-pvxen-paths.patch --- v2: Respect bootdir, create /boot/xen as needed. --- util/grub-install.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/util/grub-install.c b/util/grub-install.c index 70f514c50..7a7734e4b 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -1979,6 +1979,28 @@ main (int argc, char *argv[]) } break; + case GRUB_INSTALL_PLATFORM_I386_XEN: + { + char *path = grub_util_path_concat (2, bootdir, "xen"); + char *dst = grub_util_path_concat (2, path, "pvboot-i386.elf"); + grub_install_mkdir_p (path); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + free (path); + } + break; + + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + { + char *path = grub_util_path_concat (2, bootdir, "xen"); + char *dst = grub_util_path_concat (2, path, "pvboot-x86_64.elf"); + grub_install_mkdir_p (path); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + free (path); + } + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: @@ -1987,8 +2009,6 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_QEMU: - case GRUB_INSTALL_PLATFORM_I386_XEN: - case GRUB_INSTALL_PLATFORM_X86_64_XEN: grub_util_warn ("%s", _("WARNING: no platform-specific install was performed")); break; From 34411ff593136ce78ab5c21706dfb7ae3655a16f Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 14 Aug 2014 21:02:31 +0400 Subject: [PATCH 3/8] Fix typo (gettext_print instead of gettext_printf) Bug-Ubuntu: https://bugs.launchpad.net/bugs/1390766 Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commitdiff;h=c291f47b2c003ef6daeafaedd458db838bad6fb8 Last-Update: 2014-11-18 Patch-Name: gettext-print-typo.patch --- util/grub-mkconfig.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index ccce9e5a9..4641563d4 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -131,7 +131,7 @@ set $grub_probe dummy if test -f "$1"; then : else - gettext_print "%s: Not found.\n" "$1" 1>&2 + gettext_printf "%s: Not found.\n" "$1" 1>&2 exit 1 fi From 117750671b90c8576dab576af524f29df9a0981c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Sun, 30 Nov 2014 12:12:52 +0000 Subject: [PATCH 4/8] Arrange to insmod xzio and lzopio when booting a kernel as a Xen guest This is needed in case the Linux kernel is compiled with CONFIG_KERNEL_XZ or CONFIG_KERNEL_LZO rather than CONFIG_KERNEL_GZ (gzio is already loaded by grub.cfg today). Signed-off-by: Ian Campbell Bug-Debian: https://bugs.debian.org/755256 Forwarded: http://lists.gnu.org/archive/html/grub-devel/2014-11/msg00091.html Last-Update: 2014-11-30 Patch-Name: insmod-xzio-and-lzopio-on-xen.patch --- util/grub.d/10_linux.in | 1 + 1 file changed, 1 insertion(+) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 79fa03a7d..86e35f21b 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -150,6 +150,7 @@ linux_entry () fi echo " insmod gzio" | sed "s/^/$submenu_indentation/" + echo " if [ x\$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi" | sed "s/^/$submenu_indentation/" if [ x$dirname = x/ ]; then if [ -z "${prepare_root_cache}" ]; then From 0c98fa2f582d686e2e9ebdc7065b4475d38e57cb Mon Sep 17 00:00:00 2001 From: Steve McIntyre <93sam@debian.org> Date: Wed, 3 Dec 2014 01:25:12 +0000 Subject: [PATCH 5/8] Add support for forcing EFI installation to the removable media path Add an extra option to grub-install "--force-extra-removable". On EFI platforms, this will cause an extra copy of the grub-efi image to be written to the appropriate removable media patch /boot/efi/EFI/BOOT/BOOT$ARCH.EFI as well. This will help with broken UEFI implementations where the firmware does not work when configured with new boot paths. Signed-off-by: Steve McIntyre <93sam@debian.org> Bug-Debian: https://bugs.debian.org/767037 https://bugs.debian.org/773092 Forwarded: Not yet Last-Update: 2014-12-20 Patch-Name: grub-install-extra-removable.patch --- util/grub-install.c | 110 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/util/grub-install.c b/util/grub-install.c index 7a7734e4b..54fbd3514 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -56,6 +56,7 @@ static char *target; static int removable = 0; +static int force_extra_removable = 0; static int recheck = 0; static int update_nvram = 1; static char *install_device = NULL; @@ -114,7 +115,8 @@ enum OPTION_LABEL_BGCOLOR, OPTION_PRODUCT_VERSION, OPTION_UEFI_SECURE_BOOT, - OPTION_NO_UEFI_SECURE_BOOT + OPTION_NO_UEFI_SECURE_BOOT, + OPTION_FORCE_EXTRA_REMOVABLE }; static int fs_probe = 1; @@ -217,6 +219,10 @@ argp_parser (int key, char *arg, struct argp_state *state) removable = 1; return 0; + case OPTION_FORCE_EXTRA_REMOVABLE: + force_extra_removable = 1; + return 0; + case OPTION_ALLOW_FLOPPY: allow_floppy = 1; return 0; @@ -323,6 +329,9 @@ static struct argp_option options[] = { N_("do not install an image usable with UEFI Secure Boot, even if the " "system was currently started using it. " "This option is only available on EFI."), 2}, + {"force-extra-removable", OPTION_FORCE_EXTRA_REMOVABLE, 0, 0, + N_("force installation to the removable media path also. " + "This option is only available on EFI."), 2}, {0, 0, 0, 0, 0, 0} }; @@ -829,6 +838,91 @@ fill_core_services (const char *core_services) free (sysv_plist); } +/* Helper routine for also_install_removable() below. Walk through the + specified dir, looking to see if there is a file/dir that matches + the search string exactly, but in a case-insensitive manner. If so, + return a copy of the exact file/dir that *does* exist. If not, + return NULL */ +static char * +check_component_exists(const char *dir, + const char *search) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + char *found = NULL; + + d = grub_util_fd_opendir (dir); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + dir, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + if (strcasecmp (de->d_name, search) == 0) + { + found = xstrdup (de->d_name); + break; + } + } + grub_util_fd_closedir (d); + return found; +} + +/* Some complex directory-handling stuff in here, to cope with + * case-insensitive FAT/VFAT filesystem semantics. Ugh. */ +static void +also_install_removable(const char *src, + const char *base_efidir, + const char *efi_suffix_upper) +{ + char *efi_file = NULL; + char *dst = NULL; + char *cur = NULL; + char *found = NULL; + + if (!efi_suffix_upper) + grub_util_error ("%s", _("efi_suffix_upper not set")); + efi_file = xasprintf ("BOOT%s.EFI", efi_suffix_upper); + + /* We need to install in $base_efidir/EFI/BOOT/$efi_file, but we + * need to cope with case-insensitive stuff here. Build the path one + * component at a time, checking for existing matches each time. */ + + /* Look for "EFI" in base_efidir. Make it if it does not exist in + * some form. */ + found = check_component_exists(base_efidir, "EFI"); + if (found == NULL) + found = xstrdup("EFI"); + dst = grub_util_path_concat (2, base_efidir, found); + cur = xstrdup (dst); + free (dst); + free (found); + grub_install_mkdir_p (cur); + + /* Now BOOT */ + found = check_component_exists(cur, "BOOT"); + if (found == NULL) + found = xstrdup("BOOT"); + dst = grub_util_path_concat (2, cur, found); + cur = xstrdup (dst); + free (dst); + free (found); + grub_install_mkdir_p (cur); + + /* Now $efi_file */ + found = check_component_exists(cur, efi_file); + if (found == NULL) + found = xstrdup(efi_file); + dst = grub_util_path_concat (2, cur, found); + cur = xstrdup (dst); + free (dst); + free (found); + grub_install_copy_file (src, cur, 1); + + free (cur); + free (efi_file); +} + int main (int argc, char *argv[]) { @@ -846,6 +940,7 @@ main (int argc, char *argv[]) char *relative_grubdir; char **efidir_device_names = NULL; grub_device_t efidir_grub_dev = NULL; + char *base_efidir = NULL; char *efidir_grub_devname; int efidir_is_mac = 0; int is_prep = 0; @@ -878,6 +973,9 @@ main (int argc, char *argv[]) bootloader_id = xstrdup ("grub"); } + if (removable && force_extra_removable) + grub_util_error (_("Invalid to use both --removable and --force_extra_removable")); + if (!grub_install_source_directory) { if (!target) @@ -1087,6 +1185,8 @@ main (int argc, char *argv[]) if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0) grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir); + base_efidir = xstrdup(efidir); + /* The EFI specification requires that an EFI System Partition must contain an "EFI" subdirectory, and that OS loaders are stored in subdirectories below EFI. Vendors are expected to pick names that do @@ -1949,9 +2049,15 @@ main (int argc, char *argv[]) fprintf (config_dst_f, "configfile $prefix/grub.cfg\n"); fclose (config_dst_f); free (config_dst); + if (force_extra_removable) + also_install_removable(efi_signed, base_efidir, efi_suffix_upper); } else - grub_install_copy_file (imgfile, dst, 1); + { + grub_install_copy_file (imgfile, dst, 1); + if (force_extra_removable) + also_install_removable(imgfile, base_efidir, efi_suffix_upper); + } free (dst); } if (!removable && update_nvram) From 810bd3508823c23b4fe05a4edcaf822932a9fffb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 3 Jan 2015 12:04:59 +0000 Subject: [PATCH 6/8] Generate alternative init entries in advanced menu Add fallback boot entries for alternative installed init systems. Based on patches from Michael Biebl and Didier Roche. Bug-Debian: https://bugs.debian.org/757298 Bug-Debian: https://bugs.debian.org/773173 Forwarded: no Last-Update: 2015-01-03 Patch-Name: mkconfig_other_inits.patch --- util/grub.d/10_linux.in | 10 ++++++++++ util/grub.d/20_linux_xen.in | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 86e35f21b..f201e7d07 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -32,6 +32,7 @@ export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR="@localedir@" CLASS="--class gnu-linux --class gnu --class os" +SUPPORTED_INITS="sysvinit:/lib/sysvinit/init systemd:/lib/systemd/systemd upstart:/sbin/upstart" if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux @@ -115,6 +116,8 @@ linux_entry () case $type in recovery) title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;; + init-*) + title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "${type#init-}")" ;; *) title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; esac @@ -340,6 +343,13 @@ while [ "x$list" != "x" ] ; do linux_entry "${OS}" "${version}" advanced \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" + for supported_init in ${SUPPORTED_INITS}; do + init_path="${supported_init#*:}" + if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "${init_path}" ]; then + linux_entry "${OS}" "${version}" "init-${supported_init%%:*}" \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}" + fi + done if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" recovery \ "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}" diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index a5e5e5092..11b7e0105 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -27,6 +27,7 @@ export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR="@localedir@" CLASS="--class gnu-linux --class gnu --class os --class xen" +SUPPORTED_INITS="sysvinit:/lib/sysvinit/init systemd:/lib/systemd/systemd upstart:/sbin/upstart" if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux @@ -94,6 +95,8 @@ linux_entry () if [ x$type != xsimple ] ; then if [ x$type = xrecovery ] ; then title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" + elif [ "${type#init-}" != "$type" ] ; then + title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "${type#init-}")" else title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")" fi @@ -255,6 +258,14 @@ while [ "x${xen_list}" != "x" ] ; do linux_entry "${OS}" "${version}" "${xen_version}" advanced \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" + for supported_init in ${SUPPORTED_INITS}; do + init_path="${supported_init#*:}" + if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "${init_path}" ]; then + linux_entry "${OS}" "${version}" "${xen_version}" "init-${supported_init%%:*}" \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" + + fi + done if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" "${xen_version}" recovery \ "single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" From 2a54e1b19aa1e080f9795a00d7381c0be85b2a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=BE=D0=BC=D0=B0=D0=BD=20=D0=9F=D0=B5=D1=85=D0=BE?= =?UTF-8?q?=D0=B2?= Date: Sun, 22 Jun 2014 03:51:50 +0400 Subject: [PATCH 7/8] * grub-core/commands/loadenv.c (check_blocklists): Fix overlap check. Bug: http://savannah.gnu.org/bugs/?42134 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1311247 Origin: upstream, http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1f6af2a9f8b02a71f213b4717d8e62c8a6b14fc5 Last-Update: 2015-01-23 Patch-Name: check_blocklists_overlap_fix.patch --- grub-core/commands/loadenv.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index 6af811207..acd93d123 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -263,7 +263,7 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, for (q = p->next; q; q = q->next) { grub_disk_addr_t s1, s2; - grub_disk_addr_t e1, e2, t; + grub_disk_addr_t e1, e2; s1 = p->sector; e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); @@ -271,16 +271,7 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, s2 = q->sector; e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - if (s2 > s1) - { - t = s2; - s2 = s1; - s1 = t; - t = e2; - e2 = e1; - e1 = t; - } - if (e1 > s2) + if (s1 < e2 && s2 < e1) { /* This might be actually valid, but it is unbelievable that any filesystem makes such a silly allocation. */ From 9d4f1601e187894da565f4573b5d174dcf586cd6 Mon Sep 17 00:00:00 2001 From: Steve McIntyre <93sam@debian.org> Date: Tue, 27 Jan 2015 20:08:53 +0000 Subject: [PATCH 8/8] Add support for running a 64-bit Linux kernel on a 32-bit EFI Some platforms might be capable of running a 64-bit Linux kernel but only use a 32-bit EFI. To support such systems, it is necessary to work out the size of the firmware rather than just the size of the kernel. To enable that, there is now an extra EFI sysfs file to describe the underlying firmware. Read that if possible, otherwise fall back to the kernel type as before. Signed-off-by: Steve McIntyre <93sam@debian.org> Bug-Debian: https://bugs.debian.org/775202 Forwarded: Not yet Last-Update: 2015-01-10 Patch-Name: mixed_size_efi.patch --- grub-core/osdep/linux/platform.c | 38 +++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c index 033afd822..3675b2362 100644 --- a/grub-core/osdep/linux/platform.c +++ b/grub-core/osdep/linux/platform.c @@ -63,6 +63,42 @@ is_64_kernel (void) return strcmp (un.machine, "x86_64") == 0; } +static int +read_platform_size (void) +{ + FILE *fp; + char *buf = NULL; + size_t len = 0; + int ret = 0; + + /* Newer kernels can tell us directly about the size of the + * underlying firmware - let's see if that interface is there. */ + fp = grub_util_fopen ("/sys/firmware/efi/fw_platform_size", "r"); + if (fp != NULL) + { + if (getline (&buf, &len, fp) > 0) + { + if (strncmp (buf, "32", 2) == 0) + ret = 32; + else if (strncmp (buf, "64", 2) == 0) + ret = 64; + } + free (buf); + fclose (fp); + } + + if (ret == 0) + /* Unrecognised - fall back to matching the kernel size instead */ + { + if (is_64_kernel ()) + ret = 64; + else + ret = 32; + } + + return ret; +} + const char * grub_install_get_default_x86_platform (void) { @@ -85,7 +121,7 @@ grub_install_get_default_x86_platform (void) int found; grub_util_info ("...found"); - if (is_64_kernel ()) + if (read_platform_size() == 64) platform = "x86_64-efi"; else platform = "i386-efi";