diff --git a/0001-efinet-Check-for-immediate-completition.patch b/0001-efinet-Check-for-immediate-completition.patch new file mode 100644 index 0000000..988f2a2 --- /dev/null +++ b/0001-efinet-Check-for-immediate-completition.patch @@ -0,0 +1,51 @@ +From cf2b4a36c408084852c44dea045331f039b895d2 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 27 Mar 2015 14:27:56 +0100 +Subject: [PATCH] efinet: Check for immediate completition. + +This both speeds GRUB up and workarounds unexpected EFI behaviour. +--- + grub-core/net/drivers/efi/efinet.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 2b344d6..f171f20 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -37,11 +37,12 @@ send_card_buffer (struct grub_net_card *dev, + grub_efi_status_t st; + grub_efi_simple_network_t *net = dev->efi_net; + grub_uint64_t limit_time = grub_get_time_ms () + 4000; ++ void *txbuf; + + if (dev->txbusy) + while (1) + { +- void *txbuf = NULL; ++ txbuf = NULL; + st = efi_call_3 (net->get_status, net, 0, &txbuf); + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, +@@ -74,7 +75,18 @@ send_card_buffer (struct grub_net_card *dev, + dev->txbuf, NULL, NULL, NULL); + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); +- dev->txbusy = 1; ++ ++ /* ++ The card may have sent out the packet immediately - set txbusy ++ to 0 in this case. ++ Cases were observed where checking txbuf at the next call ++ of send_card_buffer() is too late: 0 is returned in txbuf and ++ we run in the GRUB_ERR_TIMEOUT case above. ++ Perhaps a timeout in the FW has discarded the recycle buffer. ++ */ ++ st = efi_call_3 (net->get_status, net, 0, &txbuf); ++ dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf); ++ + return GRUB_ERR_NONE; + } + +-- +2.5.1 + diff --git a/0001-efinet-enable-hardware-filters-when-opening-interfac.patch b/0001-efinet-enable-hardware-filters-when-opening-interfac.patch new file mode 100644 index 0000000..ba0377a --- /dev/null +++ b/0001-efinet-enable-hardware-filters-when-opening-interfac.patch @@ -0,0 +1,107 @@ +From f348aee7b33dd85e7da62b497a96a7319a0bf9dd Mon Sep 17 00:00:00 2001 +From: Andrei Borzenkov +Date: Tue, 16 Jun 2015 19:52:45 +0300 +Subject: [PATCH] efinet: enable hardware filters when opening interface + +Exclusive open on SNP will close all existing protocol instances which +may disable all receive filters on interface. Reinstall them after we +opened protocol exclusively. + +Also follow UEFI specification recommendation and stop interfaces when +closing them: + +Unexpected system errors, reboots and hangs can occur if an OS is loaded +and the network devices are not Shutdown() and Stopped(). + +Also by: Mark Salter +Closes: 45204 +--- + grub-core/net/drivers/efi/efinet.c | 25 +++++++++++++++++++++++++ + include/grub/efi/api.h | 20 +++++++++++++++++--- + 2 files changed, 42 insertions(+), 3 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 5533515..70b26af 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -168,6 +168,29 @@ open_card (struct grub_net_card *dev) + return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed", + dev->name); + ++ /* Enable hardware receive filters if driver declares support for it. ++ We need unicast and broadcast and additionaly all nodes and ++ solicited multicast for IPv6. Solicited multicast is per-IPv6 ++ address and we currently do not have API to do it so simply ++ try to enable receive of all multicast packets or evertyhing in ++ the worst case (i386 PXE driver always enables promiscuous too). ++ ++ This does trust firmware to do what it claims to do. ++ */ ++ if (net->mode->receive_filter_mask) ++ { ++ grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST | ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; ++ ++ filters &= net->mode->receive_filter_mask; ++ if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST)) ++ filters |= (net->mode->receive_filter_mask & ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS); ++ ++ efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL); ++ } ++ + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, + dev->efi_net, &net_io_guid, + grub_efi_image_handle, dev->efi_handle); +@@ -181,6 +204,8 @@ open_card (struct grub_net_card *dev) + static void + close_card (struct grub_net_card *dev) + { ++ efi_call_1 (dev->efi_net->shutdown, dev->efi_net); ++ efi_call_1 (dev->efi_net->stop, dev->efi_net); + efi_call_4 (grub_efi_system_table->boot_services->close_protocol, + dev->efi_net, &net_io_guid, + grub_efi_image_handle, dev->efi_handle); +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index e5dd543..1a5e38c 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -1501,17 +1501,31 @@ enum + GRUB_EFI_NETWORK_INITIALIZED, + }; + ++enum ++ { ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08, ++ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10, ++ }; ++ + struct grub_efi_simple_network + { + grub_uint64_t revision; + grub_efi_status_t (*start) (struct grub_efi_simple_network *this); +- void (*stop) (void); ++ grub_efi_status_t (*stop) (struct grub_efi_simple_network *this); + grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, + grub_efi_uintn_t extra_rx, + grub_efi_uintn_t extra_tx); + void (*reset) (void); +- void (*shutdown) (void); +- void (*receive_filters) (void); ++ grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this); ++ grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this, ++ grub_uint32_t enable, ++ grub_uint32_t disable, ++ grub_efi_boolean_t reset_mcast_filter, ++ grub_efi_uintn_t mcast_filter_count, ++ grub_efi_mac_address_t *mcast_filter); + void (*station_address) (void); + void (*statistics) (void); + void (*mcastiptomac) (void); +-- +2.5.1 + diff --git a/grub.default b/grub.default index 835eb80..f5108f7 100644 --- a/grub.default +++ b/grub.default @@ -1,6 +1,9 @@ # If you change this file, run 'grub2-mkconfig -o /boot/grub2/grub.cfg' afterwards to update # /boot/grub2/grub.cfg. -GRUB_DISTRIBUTOR="openSUSE" + +# Uncomment to set your own custom distributor. If you leave it unset or empty, the default +# policy is to determine the value from /etc/os-release +# GRUB_DISTRIBUTOR="" GRUB_DEFAULT=0 GRUB_HIDDEN_TIMEOUT=0 diff --git a/grub2-arm64-efinet-handle-get_status-on-buggy-firmware-properly.patch b/grub2-arm64-efinet-handle-get_status-on-buggy-firmware-properly.patch new file mode 100644 index 0000000..be8ad0b --- /dev/null +++ b/grub2-arm64-efinet-handle-get_status-on-buggy-firmware-properly.patch @@ -0,0 +1,66 @@ +From 4fe8e6d4a1279b1840171d8e797d911cd8443333 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Thu, 6 Aug 2015 10:49:46 -0700 +Subject: [PATCH] efinet: handle get_status() on buggy firmware properly + +The EFI spec indicates that get_status() should return the address of the buffer +we passed into transmit to indicate the the buffer was transmitted. However we +have boxes where the firmware returns some arbitrary address instead, which +makes grub think that we've not sent anything. So since we have the SNP stuff +opened in exclusive mode just assume any non-NULL txbuf means that our transmit +occurred properly. This makes grub able to do its networking stuff properly on +our broken firmware. Thanks, + +cc: Peter Jones +Signed-off-by: Josef Bacik +--- + grub-core/net/drivers/efi/efinet.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 70b26af..5388f95 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -47,19 +47,19 @@ send_card_buffer (struct grub_net_card *dev, + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, + N_("couldn't send network packet")); +- if (txbuf == dev->txbuf) ++ /* ++ Some buggy firmware could return an arbitrary address instead of the ++ txbuf address we trasmitted, so just check that txbuf is non NULL ++ for success. This is ok because we open the SNP protocol in ++ exclusive mode so we know we're the only ones transmitting on this ++ box and since we only transmit one packet at a time we know our ++ transmit was successfull. ++ */ ++ if (txbuf) + { + dev->txbusy = 0; + break; + } +- if (txbuf) +- { +- st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, +- dev->txbuf, NULL, NULL, NULL); +- if (st != GRUB_EFI_SUCCESS) +- return grub_error (GRUB_ERR_IO, +- N_("couldn't send network packet")); +- } + if (limit_time < grub_get_time_ms ()) + return grub_error (GRUB_ERR_TIMEOUT, + N_("couldn't send network packet")); +@@ -84,8 +84,9 @@ send_card_buffer (struct grub_net_card *dev, + we run in the GRUB_ERR_TIMEOUT case above. + Perhaps a timeout in the FW has discarded the recycle buffer. + */ ++ txbuf = NULL; + st = efi_call_3 (net->get_status, net, 0, &txbuf); +- dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf); ++ dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf); + + return GRUB_ERR_NONE; + } +-- +2.5.1 + diff --git a/grub2-btrfs-04-grub2-install.patch b/grub2-btrfs-04-grub2-install.patch index 08e46d6..0006c02 100644 --- a/grub2-btrfs-04-grub2-install.patch +++ b/grub2-btrfs-04-grub2-install.patch @@ -2,7 +2,7 @@ Index: grub-2.02~beta2/grub-core/osdep/unix/config.c =================================================================== --- grub-2.02~beta2.orig/grub-core/osdep/unix/config.c +++ grub-2.02~beta2/grub-core/osdep/unix/config.c -@@ -82,6 +82,19 @@ grub_util_load_config (struct grub_util_ +@@ -200,6 +200,19 @@ grub_util_load_config (struct grub_util_ if (v) cfg->grub_distributor = xstrdup (v); @@ -22,7 +22,7 @@ Index: grub-2.02~beta2/grub-core/osdep/unix/config.c cfgfile = grub_util_get_config_filename (); if (!grub_util_is_regular (cfgfile)) return; -@@ -105,8 +118,8 @@ grub_util_load_config (struct grub_util_ +@@ -223,8 +236,8 @@ grub_util_load_config (struct grub_util_ *ptr++ = *iptr; } diff --git a/grub2-default-distributor.patch b/grub2-default-distributor.patch new file mode 100644 index 0000000..76170fd --- /dev/null +++ b/grub2-default-distributor.patch @@ -0,0 +1,177 @@ +Index: grub-2.02~beta2/grub-core/osdep/unix/config.c +=================================================================== +--- grub-2.02~beta2.orig/grub-core/osdep/unix/config.c ++++ grub-2.02~beta2/grub-core/osdep/unix/config.c +@@ -61,6 +61,124 @@ grub_util_get_localedir (void) + return LOCALEDIR; + } + ++#ifdef __linux__ ++ ++static char* ++grub_util_default_distributor (void) ++{ ++ pid_t pid; ++ const char *argv[4]; ++ char *script, *ptr; ++ char *cfgfile, *iptr; ++ FILE *f = NULL; ++ int fd; ++ char *def_dist = NULL; ++ ++ cfgfile = grub_util_path_concat (2, GRUB_SYSCONFDIR, "os-release"); ++ if (!grub_util_is_regular (cfgfile)) ++ { ++ grub_free (cfgfile); ++ return NULL; ++ } ++ ++ argv[0] = "sh"; ++ argv[1] = "-c"; ++ ++ script = xmalloc (4 * strlen (cfgfile) + 300); ++ ++ ptr = script; ++ memcpy (ptr, ". '", 3); ++ ptr += 3; ++ for (iptr = cfgfile; *iptr; iptr++) ++ { ++ if (*iptr == '\\') ++ { ++ memcpy (ptr, "'\\''", 4); ++ ptr += 4; ++ continue; ++ } ++ *ptr++ = *iptr; ++ } ++ ++ strcpy (ptr, "'; printf \"OS_RELEASE_NAME=%s\\nOS_RELEASE_VERSION=%s\\n\" " ++ "\"$NAME\" \"$VERSION\""); ++ ++ argv[2] = script; ++ argv[3] = '\0'; ++ ++ pid = grub_util_exec_pipe (argv, &fd); ++ ++ if (pid) ++ f = fdopen (fd, "r"); ++ ++ if (f) ++ { ++ char *buffer = NULL; ++ size_t sz = 0; ++ char *name, *ver; ++ ++ name = ver = NULL; ++ ++ while (getline (&buffer, &sz, f) >= 0) ++ { ++ for (ptr = buffer; *ptr && grub_isspace (*ptr); ptr++); ++ if (grub_strncmp (ptr, "OS_RELEASE_NAME=", ++ sizeof ("OS_RELEASE_NAME=") - 1) == 0) ++ { ++ char *ptr2; ++ ptr += sizeof ("OS_RELEASE_NAME=") - 1; ++ name = grub_strdup (ptr); ++ for (ptr2 = name + grub_strlen (name) - 1; ++ ptr2 >= name && (*ptr2 == '\r' || *ptr2 == '\n'); ptr2--); ++ ptr2[1] = '\0'; ++ continue; ++ } ++ if (grub_strncmp (ptr, "OS_RELEASE_VERSION=", ++ sizeof ("OS_RELEASE_VERSION=") - 1) == 0) ++ { ++ char *ptr2; ++ ptr += sizeof ("OS_RELEASE_VERSION=") - 1; ++ ver = grub_strdup (ptr); ++ for (ptr2 = ver + grub_strlen (ver) - 1; ++ ptr2 >= ver && (*ptr2 == '\r' || *ptr2 == '\n'); ptr2--); ++ ptr2[1] = '\0'; ++ continue; ++ } ++ } ++ ++ fclose (f); ++ ++ if (name && ver) ++ { ++ def_dist = xmalloc (grub_strlen(name) + grub_strlen(ver) + 2); ++ ++ ptr = def_dist; ++ grub_memcpy (ptr, name, grub_strlen (name)); ++ ptr += grub_strlen (name); ++ *ptr++ = ' '; ++ grub_strcpy (ptr, ver); ++ } ++ ++ if (name) ++ grub_free (name); ++ if (ver) ++ grub_free (ver); ++ } ++ ++ if (pid) ++ { ++ close (fd); ++ waitpid (pid, NULL, 0); ++ } ++ ++ grub_free (script); ++ grub_free (cfgfile); ++ ++ return def_dist; ++} ++ ++#endif ++ + void + grub_util_load_config (struct grub_util_config *cfg) + { +@@ -125,7 +243,17 @@ grub_util_load_config (struct grub_util_ + waitpid (pid, NULL, 0); + } + if (f) +- return; ++ { ++#ifdef __linux__ ++ if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0') ++ { ++ if (cfg->grub_distributor) ++ grub_free (cfg->grub_distributor); ++ cfg->grub_distributor = grub_util_default_distributor (); ++ } ++#endif ++ return; ++ } + + f = grub_util_fopen (cfgfile, "r"); + if (f) +@@ -136,4 +264,13 @@ grub_util_load_config (struct grub_util_ + else + grub_util_warn (_("cannot open configuration file `%s': %s"), + cfgfile, strerror (errno)); ++ ++#ifdef __linux__ ++ if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0') ++ { ++ if (cfg->grub_distributor) ++ grub_free (cfg->grub_distributor); ++ cfg->grub_distributor = grub_util_default_distributor (); ++ } ++#endif + } +Index: grub-2.02~beta2/util/grub-mkconfig.in +=================================================================== +--- grub-2.02~beta2.orig/util/grub-mkconfig.in ++++ grub-2.02~beta2/util/grub-mkconfig.in +@@ -203,6 +203,10 @@ GRUB_ACTUAL_DEFAULT="$GRUB_DEFAULT" + + if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub_editenv}" - list | sed -n '/^saved_entry=/ s,^saved_entry=,,p'`" ; fi + ++if [ x"${GRUB_DISTRIBUTOR}" = x ] && [ -f "${sysconfdir}/os-release" ] ; then ++ . "${sysconfdir}/os-release" ++ GRUB_DISTRIBUTOR="${NAME} ${VERSION}" ++fi + + # These are defined in this script, export them here so that user can + # override them. diff --git a/grub2.changes b/grub2.changes index 47c0e4d..087bbc8 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Wed Sep 23 20:02:47 UTC 2015 - dmueller@suse.com + +- add 0001-efinet-Check-for-immediate-completition.patch, + 0001-efinet-enable-hardware-filters-when-opening-interfac.patch, + grub2-arm64-efinet-handle-get_status-on-buggy-firmware-properly.patch + (bsc#947203) + +------------------------------------------------------------------- +Mon Sep 14 06:36:04 UTC 2015 - mchang@suse.com + +- Set default GRUB_DISTRIBUTOR from /etc/os-release if it is empty + or not set by user (bsc#942519) + * added grub2-default-distributor.patch + * modified grub.default + ------------------------------------------------------------------- Tue Aug 18 09:53:54 UTC 2015 - mchang@suse.com diff --git a/grub2.spec b/grub2.spec index 96fb7d0..5686788 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,7 +1,7 @@ # # spec file for package grub2 # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -182,6 +182,8 @@ Patch43: grub2-use-rpmsort-for-version-sorting.patch Patch44: 0001-efidisk-move-device-path-helpers-in-core-for-efinet.patch Patch45: 0002-efinet-skip-virtual-IPv4-and-IPv6-devices-when-enume.patch Patch46: 0003-efinet-open-Simple-Network-Protocol-exclusively.patch +Patch47: 0001-efinet-Check-for-immediate-completition.patch +Patch48: 0001-efinet-enable-hardware-filters-when-opening-interfac.patch Patch51: grub2-xen-legacy-config-device-name.patch Patch52: grub2-getroot-support-NVMe-device-names.patch Patch53: grub2-getroot-treat-mdadm-ddf-as-simple-device.patch @@ -202,6 +204,7 @@ Patch66: grub2-glibc-2.20.patch Patch67: grub2-Initialized-initrd_ctx-so-we-don-t-free-a-random-poi.patch Patch68: grub2-btrfs-fix-get_root-key-comparison-failures-due-to-en.patch Patch69: grub2-getroot-fix-get-btrfs-fs-prefix-big-endian.patch +Patch70: grub2-default-distributor.patch # Btrfs snapshot booting related patches Patch101: grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch Patch102: grub2-btrfs-02-export-subvolume-envvars.patch @@ -249,6 +252,7 @@ Patch237: grub2-ppc64le-fix-64bit-trampoline-in-dyn-linker.patch Patch238: grub2-arm64-Reduce-timer-event-frequency-by-10.patch Patch239: grub2-arm64-set-correct-length.patch Patch240: grub2-arm64-setjmp-Add-missing-license-macro.patch +Patch241: grub2-arm64-efinet-handle-get_status-on-buggy-firmware-properly.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 @@ -445,6 +449,8 @@ mv po/grub.pot po/%{name}.pot %patch44 -p1 %patch45 -p1 %patch46 -p1 +%patch47 -p1 +%patch48 -p1 %patch51 -p1 %patch52 -p1 %patch53 -p1 @@ -464,6 +470,7 @@ mv po/grub.pot po/%{name}.pot %patch67 -p1 %patch68 -p1 %patch69 -p1 +%patch70 -p1 %patch101 -p1 %patch102 -p1 %patch103 -p1 @@ -509,6 +516,7 @@ mv po/grub.pot po/%{name}.pot %patch238 -p1 %patch239 -p1 %patch240 -p1 +%patch241 -p1 # Generate po/LINGUAS for message catalogs ... ./linguas.sh