]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2014 03:10:33 +0000 (20:10 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2014 03:10:33 +0000 (20:10 -0700)
added patches:
drivers-hv-vmbus-negotiate-version-3.0-when-running-on-ws2012r2-hosts.patch
efi-pass-correct-file-handle-to-efi_file_-read-close.patch
target-iblock-fix-double-bioset_integrity_free-bug.patch
target-rd-t10-dif-ram-disk-is-allocating-more-space-than-required.patch
target-sbc-initialize-compare_and_write-write_sg-scatterlist.patch
target-tcm_fc-fix-use-after-free-of-ft_tpg.patch
word-at-a-time-avoid-undefined-behaviour-in-zero_bytemask-macro.patch
x86-efi-correct-efi-boot-stub-use-of-code32_start.patch

queue-3.14/drivers-hv-vmbus-negotiate-version-3.0-when-running-on-ws2012r2-hosts.patch [new file with mode: 0644]
queue-3.14/efi-pass-correct-file-handle-to-efi_file_-read-close.patch [new file with mode: 0644]
queue-3.14/series
queue-3.14/target-iblock-fix-double-bioset_integrity_free-bug.patch [new file with mode: 0644]
queue-3.14/target-rd-t10-dif-ram-disk-is-allocating-more-space-than-required.patch [new file with mode: 0644]
queue-3.14/target-sbc-initialize-compare_and_write-write_sg-scatterlist.patch [new file with mode: 0644]
queue-3.14/target-tcm_fc-fix-use-after-free-of-ft_tpg.patch [new file with mode: 0644]
queue-3.14/word-at-a-time-avoid-undefined-behaviour-in-zero_bytemask-macro.patch [new file with mode: 0644]
queue-3.14/x86-efi-correct-efi-boot-stub-use-of-code32_start.patch [new file with mode: 0644]

diff --git a/queue-3.14/drivers-hv-vmbus-negotiate-version-3.0-when-running-on-ws2012r2-hosts.patch b/queue-3.14/drivers-hv-vmbus-negotiate-version-3.0-when-running-on-ws2012r2-hosts.patch
new file mode 100644 (file)
index 0000000..233b79b
--- /dev/null
@@ -0,0 +1,63 @@
+From 03367ef5ea811475187a0732aada068919e14d61 Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Thu, 3 Apr 2014 18:02:45 -0700
+Subject: Drivers: hv: vmbus: Negotiate version 3.0 when running on ws2012r2 hosts
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 03367ef5ea811475187a0732aada068919e14d61 upstream.
+
+Only ws2012r2 hosts support the ability to reconnect to the host on VMBUS. This functionality
+is needed by kexec in Linux. To use this functionality we need to negotiate version 3.0 of the
+VMBUS protocol.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/connection.c |    5 ++++-
+ include/linux/hyperv.h  |    4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -55,6 +55,9 @@ static __u32 vmbus_get_next_version(__u3
+       case (VERSION_WIN8):
+               return VERSION_WIN7;
++      case (VERSION_WIN8_1):
++              return VERSION_WIN8;
++
+       case (VERSION_WS2008):
+       default:
+               return VERSION_INVAL;
+@@ -77,7 +80,7 @@ static int vmbus_negotiate_version(struc
+       msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
+       msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
+       msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
+-      if (version == VERSION_WIN8)
++      if (version == VERSION_WIN8_1)
+               msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
+       /*
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -464,15 +464,17 @@ hv_get_ringbuffer_availbytes(struct hv_r
+  * 0 . 13 (Windows Server 2008)
+  * 1 . 1  (Windows 7)
+  * 2 . 4  (Windows 8)
++ * 3 . 0  (Windows 8 R2)
+  */
+ #define VERSION_WS2008  ((0 << 16) | (13))
+ #define VERSION_WIN7    ((1 << 16) | (1))
+ #define VERSION_WIN8    ((2 << 16) | (4))
++#define VERSION_WIN8_1    ((3 << 16) | (0))
+ #define VERSION_INVAL -1
+-#define VERSION_CURRENT VERSION_WIN8
++#define VERSION_CURRENT VERSION_WIN8_1
+ /* Make maximum size of pipe payload of 16K */
+ #define MAX_PIPE_DATA_PAYLOAD         (sizeof(u8) * 16384)
diff --git a/queue-3.14/efi-pass-correct-file-handle-to-efi_file_-read-close.patch b/queue-3.14/efi-pass-correct-file-handle-to-efi_file_-read-close.patch
new file mode 100644 (file)
index 0000000..efa6bf6
--- /dev/null
@@ -0,0 +1,66 @@
+From 47514c996fac5e6f13ef3a4c5e23f1c5cffabb7b Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Thu, 10 Apr 2014 14:11:45 +0100
+Subject: efi: Pass correct file handle to efi_file_{read,close}
+
+From: Matt Fleming <matt.fleming@intel.com>
+
+commit 47514c996fac5e6f13ef3a4c5e23f1c5cffabb7b upstream.
+
+We're currently passing the file handle for the root file system to
+efi_file_read() and efi_file_close(), instead of the file handle for the
+file we wish to read/close.
+
+While this has worked up until now, it seems that it has only been by
+pure luck. Olivier explains,
+
+ "The issue is the UEFI Fat driver might return the same function for
+  'fh->read()' and 'h->read()'. While in our case it does not work with
+  a different implementation of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. In our
+  case, we return a different pointer when reading a directory and
+  reading a file."
+
+Fixing this actually clears up the two functions because we can drop one
+of the arguments, and instead only pass a file 'handle' argument.
+
+Reported-by: Olivier Martin <olivier.martin@arm.com>
+Reviewed-by: Olivier Martin <olivier.martin@arm.com>
+Reviewed-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Leif Lindholm <leif.lindholm@linaro.org>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/firmware/efi/efi-stub-helper.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/firmware/efi/efi-stub-helper.c
++++ b/drivers/firmware/efi/efi-stub-helper.c
+@@ -468,7 +468,7 @@ grow:
+                                       chunksize = EFI_READ_CHUNK_SIZE;
+                               else
+                                       chunksize = size;
+-                              status = efi_call_phys3(fh->read,
++                              status = efi_call_phys3(files[j].handle->read,
+                                                       files[j].handle,
+                                                       &chunksize,
+                                                       (void *)addr);
+@@ -480,7 +480,7 @@ grow:
+                               size -= chunksize;
+                       }
+-                      efi_call_phys1(fh->close, files[j].handle);
++                      efi_call_phys1(files[j].handle->close, files[j].handle);
+               }
+       }
+@@ -497,7 +497,7 @@ free_file_total:
+ close_handles:
+       for (k = j; k < i; k++)
+-              efi_call_phys1(fh->close, files[k].handle);
++              efi_call_phys1(files[k].handle->close, files[k].handle);
+ free_files:
+       efi_call_phys1(sys_table_arg->boottime->free_pool, files);
+ fail:
index f33eeae1c9dbe57379bc379495f6e72c48fda10c..02dd4b90953e1b47af961ee0f4473da541a8bbe3 100644 (file)
@@ -89,3 +89,11 @@ ib_srpt-use-correct-ib_sg_dma-primitives.patch
 scsi-qla2xxx-fix-error-handling-of-qla2x00_mem_alloc.patch
 scsi-arcmsr-upper-32-of-dma-address-lost.patch
 iscsi-target-fix-erl-2-async_event-connection-pointer-bug.patch
+target-rd-t10-dif-ram-disk-is-allocating-more-space-than-required.patch
+target-sbc-initialize-compare_and_write-write_sg-scatterlist.patch
+target-iblock-fix-double-bioset_integrity_free-bug.patch
+target-tcm_fc-fix-use-after-free-of-ft_tpg.patch
+drivers-hv-vmbus-negotiate-version-3.0-when-running-on-ws2012r2-hosts.patch
+x86-efi-correct-efi-boot-stub-use-of-code32_start.patch
+efi-pass-correct-file-handle-to-efi_file_-read-close.patch
+word-at-a-time-avoid-undefined-behaviour-in-zero_bytemask-macro.patch
diff --git a/queue-3.14/target-iblock-fix-double-bioset_integrity_free-bug.patch b/queue-3.14/target-iblock-fix-double-bioset_integrity_free-bug.patch
new file mode 100644 (file)
index 0000000..38ba9a4
--- /dev/null
@@ -0,0 +1,43 @@
+From d84287bcfe624697cd4f3c1df746beb53b86d9c4 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Thu, 3 Apr 2014 03:35:02 +0000
+Subject: target/iblock: Fix double bioset_integrity_free bug
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit d84287bcfe624697cd4f3c1df746beb53b86d9c4 upstream.
+
+This patch fixes a double free bug during IBLOCK backend shutdown
+where bioset_integrity_free() was incorrectly called ahead of
+bioset_free(), who is already making the same call directly.
+
+This bug was introduced with commit ecebbf6cc, and will end up
+triggering a general protection fault in iblock_free_device()
+
+Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
+Cc: Martin K. Petersen <martin.petersen@oracle.com>
+Cc: Or Gerlitz <ogerlitz@mellanox.com>
+Cc: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_iblock.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/target/target_core_iblock.c
++++ b/drivers/target/target_core_iblock.c
+@@ -203,10 +203,9 @@ static void iblock_free_device(struct se
+       if (ib_dev->ibd_bd != NULL)
+               blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
+-      if (ib_dev->ibd_bio_set != NULL) {
+-              bioset_integrity_free(ib_dev->ibd_bio_set);
++      if (ib_dev->ibd_bio_set != NULL)
+               bioset_free(ib_dev->ibd_bio_set);
+-      }
++
+       kfree(ib_dev);
+ }
diff --git a/queue-3.14/target-rd-t10-dif-ram-disk-is-allocating-more-space-than-required.patch b/queue-3.14/target-rd-t10-dif-ram-disk-is-allocating-more-space-than-required.patch
new file mode 100644 (file)
index 0000000..d6d5e35
--- /dev/null
@@ -0,0 +1,61 @@
+From 9d2e59f2a778328a41771fe9a0098dadbc4314ba Mon Sep 17 00:00:00 2001
+From: Quinn Tran <quinn.tran@qlogic.com>
+Date: Fri, 28 Mar 2014 19:05:27 -0400
+Subject: target/rd: T10-Dif: RAM disk is allocating more space than required.
+
+From: Quinn Tran <quinn.tran@qlogic.com>
+
+commit 9d2e59f2a778328a41771fe9a0098dadbc4314ba upstream.
+
+Ram disk is allocating 8x more space than required for diff data.
+For large RAM disk test, there is small potential for memory
+starvation.
+
+(Use block_size when calculating total_sg_needed - sagi + nab)
+
+Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
+Signed-off-by: Quinn Tran <quinn.tran@qlogic.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_rd.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/target/target_core_rd.c
++++ b/drivers/target/target_core_rd.c
+@@ -242,7 +242,7 @@ static void rd_release_prot_space(struct
+       rd_dev->sg_prot_count = 0;
+ }
+-static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length)
++static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length, int block_size)
+ {
+       struct rd_dev_sg_table *sg_table;
+       u32 total_sg_needed, sg_tables;
+@@ -252,8 +252,13 @@ static int rd_build_prot_space(struct rd
+       if (rd_dev->rd_flags & RDF_NULLIO)
+               return 0;
+-
+-      total_sg_needed = rd_dev->rd_page_count / prot_length;
++      /*
++       * prot_length=8byte dif data
++       * tot sg needed = rd_page_count * (PGSZ/block_size) *
++       *                 (prot_length/block_size) + pad
++       * PGSZ canceled each other.
++       */
++      total_sg_needed = (rd_dev->rd_page_count * prot_length / block_size) + 1;
+       sg_tables = (total_sg_needed / max_sg_per_table) + 1;
+@@ -606,7 +611,8 @@ static int rd_init_prot(struct se_device
+         if (!dev->dev_attrib.pi_prot_type)
+               return 0;
+-      return rd_build_prot_space(rd_dev, dev->prot_length);
++      return rd_build_prot_space(rd_dev, dev->prot_length,
++                                 dev->dev_attrib.block_size);
+ }
+ static void rd_free_prot(struct se_device *dev)
diff --git a/queue-3.14/target-sbc-initialize-compare_and_write-write_sg-scatterlist.patch b/queue-3.14/target-sbc-initialize-compare_and_write-write_sg-scatterlist.patch
new file mode 100644 (file)
index 0000000..bea0eab
--- /dev/null
@@ -0,0 +1,38 @@
+From a1e1774c6dfa3a524dd8df51ca95185fe5ef3247 Mon Sep 17 00:00:00 2001
+From: Martin Svec <martin.svec@zoner.cz>
+Date: Tue, 1 Apr 2014 16:03:02 +0200
+Subject: Target/sbc: Initialize COMPARE_AND_WRITE write_sg scatterlist
+
+From: Martin Svec <martin.svec@zoner.cz>
+
+commit a1e1774c6dfa3a524dd8df51ca95185fe5ef3247 upstream.
+
+When compiled with CONFIG_DEBUG_SG set, uninitialized SGL leads
+to BUG() in compare_and_write_callback().
+
+Signed-off-by: Martin Svec <martin.svec@zoner.cz>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_sbc.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/target/target_core_sbc.c
++++ b/drivers/target/target_core_sbc.c
+@@ -425,13 +425,14 @@ static sense_reason_t compare_and_write_
+               goto out;
+       }
+-      write_sg = kzalloc(sizeof(struct scatterlist) * cmd->t_data_nents,
++      write_sg = kmalloc(sizeof(struct scatterlist) * cmd->t_data_nents,
+                          GFP_KERNEL);
+       if (!write_sg) {
+               pr_err("Unable to allocate compare_and_write sg\n");
+               ret = TCM_OUT_OF_RESOURCES;
+               goto out;
+       }
++      sg_init_table(write_sg, cmd->t_data_nents);
+       /*
+        * Setup verify and write data payloads from total NumberLBAs.
+        */
diff --git a/queue-3.14/target-tcm_fc-fix-use-after-free-of-ft_tpg.patch b/queue-3.14/target-tcm_fc-fix-use-after-free-of-ft_tpg.patch
new file mode 100644 (file)
index 0000000..528cfe9
--- /dev/null
@@ -0,0 +1,52 @@
+From 2c42be2dd4f6586728dba5c4e197afd5cfaded78 Mon Sep 17 00:00:00 2001
+From: Andy Grover <agrover@redhat.com>
+Date: Fri, 4 Apr 2014 16:44:37 -0700
+Subject: target/tcm_fc: Fix use-after-free of ft_tpg
+
+From: Andy Grover <agrover@redhat.com>
+
+commit 2c42be2dd4f6586728dba5c4e197afd5cfaded78 upstream.
+
+ft_del_tpg checks tpg->tport is set before unlinking the tpg from the
+tport when the tpg is being removed. Set this pointer in ft_tport_create,
+or the unlinking won't happen in ft_del_tpg and tport->tpg will reference
+a deleted object.
+
+This patch sets tpg->tport in ft_tport_create, because that's what
+ft_del_tpg checks, and is the only way to get back to the tport to
+clear tport->tpg.
+
+The bug was occuring when:
+
+- lport created, tport (our per-lport, per-provider context) is
+  allocated.
+  tport->tpg = NULL
+- tpg created
+- a PRLI is received. ft_tport_create is called, tpg is found and
+  tport->tpg is set
+- tpg removed. ft_tpg is freed in ft_del_tpg. Since tpg->tport was not
+  set, tport->tpg is not cleared and points at freed memory
+- Future calls to ft_tport_create return tport via first conditional,
+  instead of searching for new tpg by calling ft_lport_find_tpg.
+  tport->tpg is still invalid, and will access freed memory.
+
+see https://bugzilla.redhat.com/show_bug.cgi?id=1071340
+
+Signed-off-by: Andy Grover <agrover@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/tcm_fc/tfc_sess.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/target/tcm_fc/tfc_sess.c
++++ b/drivers/target/tcm_fc/tfc_sess.c
+@@ -68,6 +68,7 @@ static struct ft_tport *ft_tport_create(
+       if (tport) {
+               tport->tpg = tpg;
++              tpg->tport = tport;
+               return tport;
+       }
diff --git a/queue-3.14/word-at-a-time-avoid-undefined-behaviour-in-zero_bytemask-macro.patch b/queue-3.14/word-at-a-time-avoid-undefined-behaviour-in-zero_bytemask-macro.patch
new file mode 100644 (file)
index 0000000..ff2640e
--- /dev/null
@@ -0,0 +1,55 @@
+From ec6931b281797b69e6cf109f9cc94d5a2bf994e0 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Wed, 23 Apr 2014 17:52:52 +0100
+Subject: word-at-a-time: avoid undefined behaviour in zero_bytemask macro
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit ec6931b281797b69e6cf109f9cc94d5a2bf994e0 upstream.
+
+The asm-generic, big-endian version of zero_bytemask creates a mask of
+bytes preceding the first zero-byte by left shifting ~0ul based on the
+position of the first zero byte.
+
+Unfortunately, if the first (top) byte is zero, the output of
+prep_zero_mask has only the top bit set, resulting in undefined C
+behaviour as we shift left by an amount equal to the width of the type.
+As it happens, GCC doesn't manage to spot this through the call to fls(),
+but the issue remains if architectures choose to implement their shift
+instructions differently.
+
+An example would be arch/arm/ (AArch32), where LSL Rd, Rn, #32 results
+in Rd == 0x0, whilst on arch/arm64 (AArch64) LSL Xd, Xn, #64 results in
+Xd == Xn.
+
+Rather than check explicitly for the problematic shift, this patch adds
+an extra shift by 1, replacing fls with __fls. Since zero_bytemask is
+never called with a zero argument (has_zero() is used to check the data
+first), we don't need to worry about calling __fls(0), which is
+undefined.
+
+Cc: Victor Kamensky <victor.kamensky@linaro.org>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/asm-generic/word-at-a-time.h |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/include/asm-generic/word-at-a-time.h
++++ b/include/asm-generic/word-at-a-time.h
+@@ -50,11 +50,7 @@ static inline bool has_zero(unsigned lon
+ }
+ #ifndef zero_bytemask
+-#ifdef CONFIG_64BIT
+-#define zero_bytemask(mask)   (~0ul << fls64(mask))
+-#else
+-#define zero_bytemask(mask)   (~0ul << fls(mask))
+-#endif /* CONFIG_64BIT */
+-#endif /* zero_bytemask */
++#define zero_bytemask(mask) (~0ul << __fls(mask) << 1)
++#endif
+ #endif /* _ASM_WORD_AT_A_TIME_H */
diff --git a/queue-3.14/x86-efi-correct-efi-boot-stub-use-of-code32_start.patch b/queue-3.14/x86-efi-correct-efi-boot-stub-use-of-code32_start.patch
new file mode 100644 (file)
index 0000000..07ea278
--- /dev/null
@@ -0,0 +1,107 @@
+From 7e8213c1f3acc064aef37813a39f13cbfe7c3ce7 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt@console-pimps.org>
+Date: Tue, 8 Apr 2014 13:14:00 +0100
+Subject: x86/efi: Correct EFI boot stub use of code32_start
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matt Fleming <matt@console-pimps.org>
+
+commit 7e8213c1f3acc064aef37813a39f13cbfe7c3ce7 upstream.
+
+code32_start should point at the start of the protected mode code, and
+*not* at the beginning of the bzImage. This is much easier to do in
+assembly so document that callers of make_boot_params() need to fill out
+code32_start.
+
+The fallout from this bug is that we would end up relocating the image
+but copying the image at some offset, resulting in what appeared to be
+memory corruption.
+
+Reported-by: Thomas Bächler <thomas@archlinux.org>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/boot/compressed/eboot.c   |    5 +++--
+ arch/x86/boot/compressed/head_32.S |   14 ++++++++------
+ arch/x86/boot/compressed/head_64.S |    9 +++------
+ 3 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/arch/x86/boot/compressed/eboot.c
++++ b/arch/x86/boot/compressed/eboot.c
+@@ -425,6 +425,9 @@ void setup_graphics(struct boot_params *
+  * Because the x86 boot code expects to be passed a boot_params we
+  * need to create one ourselves (usually the bootloader would create
+  * one for us).
++ *
++ * The caller is responsible for filling out ->code32_start in the
++ * returned boot_params.
+  */
+ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
+ {
+@@ -483,8 +486,6 @@ struct boot_params *make_boot_params(voi
+       hdr->vid_mode = 0xffff;
+       hdr->boot_flag = 0xAA55;
+-      hdr->code32_start = (__u64)(unsigned long)image->image_base;
+-
+       hdr->type_of_loader = 0x21;
+       /* Convert unicode cmdline to ascii */
+--- a/arch/x86/boot/compressed/head_32.S
++++ b/arch/x86/boot/compressed/head_32.S
+@@ -50,6 +50,13 @@ ENTRY(efi_pe_entry)
+       pushl   %eax
+       pushl   %esi
+       pushl   %ecx
++
++      call    reloc
++reloc:
++      popl    %ecx
++      subl    reloc, %ecx
++      movl    %ecx, BP_code32_start(%eax)
++
+       sub     $0x4, %esp
+ ENTRY(efi_stub_entry)
+@@ -63,12 +70,7 @@ ENTRY(efi_stub_entry)
+       hlt
+       jmp     1b
+ 2:
+-      call    3f
+-3:
+-      popl    %eax
+-      subl    $3b, %eax
+-      subl    BP_pref_address(%esi), %eax
+-      add     BP_code32_start(%esi), %eax
++      movl    BP_code32_start(%esi), %eax
+       leal    preferred_addr(%eax), %eax
+       jmp     *%eax
+--- a/arch/x86/boot/compressed/head_64.S
++++ b/arch/x86/boot/compressed/head_64.S
+@@ -217,6 +217,8 @@ ENTRY(efi_pe_entry)
+       cmpq    $0,%rax
+       je      1f
+       mov     %rax, %rdx
++      leaq    startup_32(%rip), %rax
++      movl    %eax, BP_code32_start(%rdx)
+       popq    %rsi
+       popq    %rdi
+@@ -230,12 +232,7 @@ ENTRY(efi_stub_entry)
+       hlt
+       jmp     1b
+ 2:
+-      call    3f
+-3:
+-      popq    %rax
+-      subq    $3b, %rax
+-      subq    BP_pref_address(%rsi), %rax
+-      add     BP_code32_start(%esi), %eax
++      movl    BP_code32_start(%esi), %eax
+       leaq    preferred_addr(%rax), %rax
+       jmp     *%rax