diff mbox

[v2,0/5] support loading initrd below 4G for recent kernel

Message ID 1542765966-20244-1-git-send-email-lizhijian@cn.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

Li Zhijian Nov. 21, 2018, 2:06 a.m. UTC
Long long ago, linux kernel have supported up to 4G initrd, but it's header
still hard code to allow loading initrd below 2G only.
 cutting from arch/x86/head.S:
 # (Header version 0x0203 or later) the highest safe address for the contents
 # of an initrd. The current kernel allows up to 4 GB, but leave it at 2 GB to
 # avoid possible bootloader bugs.

In order to supporting more than 2G initrd, qemu must allow loading initrd
above 2G address. Luckly, recent kernel introduced a new field to linux header
named xloadflags:XLF_CAN_BE_LOADED_ABOVE_4G which tells bootload an optional
and safe address to load initrd.

Current QEMU always load initrd below below_4g_mem_size which always
less than 4G, so here limit initrd_max to 4G - 1 simply is enough if
this bit is set.

Default roms(Seabios + optionrom(linuxboot_dma)) works as expected with those
patch set.

Patch 1/5 make a huge changes to address/memory APIs, but if it's not a good
idea, below is an specfic patch to avoid dma overflow


changes:
V2: add 2 patches(3/5, 4/5) to fix potential loading issue.

Li Zhijian (5):
  unify len and addr type for memory/address APIs
  change load_image() reture type to ssize_t
  refactor load_image/load_image_size
  x86: exit qemu if load_image fails
  x86: allow load initrd below 4G for recent linux

 exec.c                    | 49 ++++++++++++++++++++++++-----------------------
 hw/core/loader.c          | 27 +++++++++++++++-----------
 hw/i386/pc.c              | 17 +++++++++++++++-
 include/exec/cpu-all.h    |  2 +-
 include/exec/cpu-common.h | 10 +++++-----
 include/exec/memory.h     | 20 +++++++++----------
 include/hw/loader.h       |  2 +-
 7 files changed, 74 insertions(+), 53 deletions(-)
diff mbox

Patch

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 946f765..5c9607c 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -338,7 +338,7 @@  static void fw_cfg_dma_transfer(FWCfgState *s)
     while (dma.length > 0 && !(dma.control & FW_CFG_DMA_CTL_ERROR)) {
         if (s->cur_entry == FW_CFG_INVALID || !e->data ||
                                 s->cur_offset >= e->len) {
-            len = dma.length;
+            len = dma.length > INT32_MAX ? INT32_MAX : dma.length;
 
             /* If the access is not a read access, it will be a skip access,
              * tested before.
@@ -358,6 +358,8 @@  static void fw_cfg_dma_transfer(FWCfgState *s)
                 len = (e->len - s->cur_offset);
             }
 
+            len = len > INT32_MAX ? INT32_MAX : len;
+
             /* If the access is not a read access, it will be a skip access,
              * tested before.
              */