* [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel
@ 2018-12-06 2:32 Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs Li Zhijian
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: Li Zhijian @ 2018-12-06 2:32 UTC (permalink / raw)
To: qemu-devel, mst, peter.maydell; +Cc: philip.li, zhijianx.li, philmd, Li Zhijian
Long long ago, linux kernel has 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 support 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/BIOS always loads initrd below below_4g_mem_size which always
less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
this bit is set.
Default roms(Seabios + optionrom(linuxboot_dma)) works as expected with this
patchset.
changes:
V4:
- add Reviwed-by tag to 1/4 and 2/4
- use scripts/update-linux-headers.sh to import bootparam.h
- minor fix at commit log
V3:
- rebase code basing on http://patchwork.ozlabs.org/cover/1005990 and
https://patchew.org/QEMU/20181122133507.30950-1-peter.maydell@linaro.org
- add new patch 3/4 to import header bootparam.h (Michael S. Tsirkin)
V2: add 2 patches(3/5, 4/5) to fix potential loading issue.
Li Zhijian (4):
unify len and addr type for memory/address APIs
refactor load_image_size
i386: import & use bootparam.h
i386: allow to load initrd below 4G for recent linux
exec.c | 47 ++++++++++++++--------------
hw/core/loader.c | 11 +++----
hw/i386/pc.c | 18 ++++++-----
include/exec/cpu-all.h | 2 +-
include/exec/cpu-common.h | 8 ++---
include/exec/memory.h | 22 ++++++-------
include/standard-headers/asm-x86/bootparam.h | 34 ++++++++++++++++++++
scripts/update-linux-headers.sh | 4 +++
8 files changed, 92 insertions(+), 54 deletions(-)
create mode 100644 include/standard-headers/asm-x86/bootparam.h
--
2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs
2018-12-06 2:32 [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
@ 2018-12-06 2:32 ` Li Zhijian
2019-01-07 10:04 ` Stefano Garzarella
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size Li Zhijian
` (3 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Li Zhijian @ 2018-12-06 2:32 UTC (permalink / raw)
To: qemu-devel, mst, peter.maydell
Cc: philip.li, zhijianx.li, philmd, Li Zhijian, Paolo Bonzini,
Peter Crosthwaite, Richard Henderson
Some address/memory APIs have different type between
'hwaddr/target_ulong addr' and 'int len'. It is very unsafe, espcially
some APIs will be passed a non-int len by caller which might cause
overflow quietly.
Below is an potential overflow case:
dma_memory_read(uint32_t len)
-> dma_memory_rw(uint32_t len)
-> dma_memory_rw_relaxed(uint32_t len)
-> address_space_rw(int len) # len overflow
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Peter Crosthwaite <crosthwaite.peter@gmail.com>
CC: Richard Henderson <rth@twiddle.net>
CC: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
V4: minor fix at commit message and add Reviewed-by tag
V3: use the same type between len and addr(Peter Maydell)
rebase code basing on https://patchew.org/QEMU/20181122133507.30950-1-peter.maydell@linaro.org/
---
exec.c | 47 +++++++++++++++++++++++------------------------
include/exec/cpu-all.h | 2 +-
include/exec/cpu-common.h | 8 ++++----
include/exec/memory.h | 22 +++++++++++-----------
4 files changed, 39 insertions(+), 40 deletions(-)
diff --git a/exec.c b/exec.c
index 6e875f0..f475974 100644
--- a/exec.c
+++ b/exec.c
@@ -2848,10 +2848,10 @@ static const MemoryRegionOps watch_mem_ops = {
};
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
- MemTxAttrs attrs, uint8_t *buf, int len);
+ MemTxAttrs attrs, uint8_t *buf, hwaddr len);
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
- const uint8_t *buf, int len);
-static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
+ const uint8_t *buf, hwaddr len);
+static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len,
bool is_write, MemTxAttrs attrs);
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
@@ -3099,10 +3099,10 @@ MemoryRegion *get_system_io(void)
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, int is_write)
+ uint8_t *buf, target_ulong len, int is_write)
{
- int l, flags;
- target_ulong page;
+ int flags;
+ target_ulong l, page;
void * p;
while (len > 0) {
@@ -3215,7 +3215,7 @@ static bool prepare_mmio_access(MemoryRegion *mr)
static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf,
- int len, hwaddr addr1,
+ hwaddr len, hwaddr addr1,
hwaddr l, MemoryRegion *mr)
{
uint8_t *ptr;
@@ -3260,7 +3260,7 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
/* Called from RCU critical section. */
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
- const uint8_t *buf, int len)
+ const uint8_t *buf, hwaddr len)
{
hwaddr l;
hwaddr addr1;
@@ -3278,7 +3278,7 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
/* Called within RCU critical section. */
MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
- int len, hwaddr addr1, hwaddr l,
+ hwaddr len, hwaddr addr1, hwaddr l,
MemoryRegion *mr)
{
uint8_t *ptr;
@@ -3321,7 +3321,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
/* Called from RCU critical section. */
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
- MemTxAttrs attrs, uint8_t *buf, int len)
+ MemTxAttrs attrs, uint8_t *buf, hwaddr len)
{
hwaddr l;
hwaddr addr1;
@@ -3334,7 +3334,7 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
}
MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
- MemTxAttrs attrs, uint8_t *buf, int len)
+ MemTxAttrs attrs, uint8_t *buf, hwaddr len)
{
MemTxResult result = MEMTX_OK;
FlatView *fv;
@@ -3351,7 +3351,7 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
- const uint8_t *buf, int len)
+ const uint8_t *buf, hwaddr len)
{
MemTxResult result = MEMTX_OK;
FlatView *fv;
@@ -3367,7 +3367,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
}
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- uint8_t *buf, int len, bool is_write)
+ uint8_t *buf, hwaddr len, bool is_write)
{
if (is_write) {
return address_space_write(as, addr, attrs, buf, len);
@@ -3377,7 +3377,7 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
}
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
- int len, int is_write)
+ hwaddr len, int is_write)
{
address_space_rw(&address_space_memory, addr, MEMTXATTRS_UNSPECIFIED,
buf, len, is_write);
@@ -3392,7 +3392,7 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf,
- int len,
+ hwaddr len,
enum write_rom_type type)
{
hwaddr l;
@@ -3432,13 +3432,13 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
/* used for ROM loading : can write in RAM and ROM */
MemTxResult address_space_write_rom(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
- const uint8_t *buf, int len)
+ const uint8_t *buf, hwaddr len)
{
return address_space_write_rom_internal(as, addr, attrs,
buf, len, WRITE_DATA);
}
-void cpu_flush_icache_range(hwaddr start, int len)
+void cpu_flush_icache_range(hwaddr start, hwaddr len)
{
/*
* This function should do the same thing as an icache flush that was
@@ -3541,7 +3541,7 @@ static void cpu_notify_map_clients(void)
qemu_mutex_unlock(&map_client_list_lock);
}
-static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
+static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len,
bool is_write, MemTxAttrs attrs)
{
MemoryRegion *mr;
@@ -3564,7 +3564,7 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
}
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
- int len, bool is_write,
+ hwaddr len, bool is_write,
MemTxAttrs attrs)
{
FlatView *fv;
@@ -3817,7 +3817,7 @@ static inline MemoryRegion *address_space_translate_cached(
*/
void
address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
- void *buf, int len)
+ void *buf, hwaddr len)
{
hwaddr addr1, l;
MemoryRegion *mr;
@@ -3835,7 +3835,7 @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
*/
void
address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
- const void *buf, int len)
+ const void *buf, hwaddr len)
{
hwaddr addr1, l;
MemoryRegion *mr;
@@ -3858,11 +3858,10 @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
/* virtual memory access for debug (includes writing to ROM) */
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, int is_write)
+ uint8_t *buf, target_ulong len, int is_write)
{
- int l;
hwaddr phys_addr;
- target_ulong page;
+ target_ulong l, page;
cpu_synchronize_state(cpu);
while (len > 0) {
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 117d2fb..b16c9ec 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -367,7 +367,7 @@ void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
#endif /* !CONFIG_USER_ONLY */
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, int is_write);
+ uint8_t *buf, target_ulong len, int is_write);
int cpu_exec(CPUState *cpu);
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 2ad2d6d..63ec1f9 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -83,14 +83,14 @@ size_t qemu_ram_pagesize(RAMBlock *block);
size_t qemu_ram_pagesize_largest(void);
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
- int len, int is_write);
+ hwaddr len, int is_write);
static inline void cpu_physical_memory_read(hwaddr addr,
- void *buf, int len)
+ void *buf, hwaddr len)
{
cpu_physical_memory_rw(addr, buf, len, 0);
}
static inline void cpu_physical_memory_write(hwaddr addr,
- const void *buf, int len)
+ const void *buf, hwaddr len)
{
cpu_physical_memory_rw(addr, (void *)buf, len, 1);
}
@@ -111,7 +111,7 @@ bool cpu_physical_memory_is_io(hwaddr phys_addr);
*/
void qemu_flush_coalesced_mmio_buffer(void);
-void cpu_flush_icache_range(hwaddr start, int len);
+void cpu_flush_icache_range(hwaddr start, hwaddr len);
extern struct MemoryRegion io_mem_rom;
extern struct MemoryRegion io_mem_notdirty;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index ffd23ed..6235f77 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1773,7 +1773,7 @@ void address_space_destroy(AddressSpace *as);
*/
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
- int len, bool is_write);
+ hwaddr len, bool is_write);
/**
* address_space_write: write to address space.
@@ -1790,7 +1790,7 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
*/
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
- const uint8_t *buf, int len);
+ const uint8_t *buf, hwaddr len);
/**
* address_space_write_rom: write to address space, including ROM.
@@ -1816,7 +1816,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
*/
MemTxResult address_space_write_rom(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
- const uint8_t *buf, int len);
+ const uint8_t *buf, hwaddr len);
/* address_space_ld*: load from an address space
* address_space_st*: store to an address space
@@ -2017,7 +2017,7 @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
* @is_write: indicates the transfer direction
* @attrs: memory attributes
*/
-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, hwaddr len,
bool is_write, MemTxAttrs attrs);
/* address_space_map: map a physical memory region into a host virtual address
@@ -2054,19 +2054,19 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
/* Internal functions, part of the implementation of address_space_read. */
MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
- MemTxAttrs attrs, uint8_t *buf, int len);
+ MemTxAttrs attrs, uint8_t *buf, hwaddr len);
MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
- int len, hwaddr addr1, hwaddr l,
+ hwaddr len, hwaddr addr1, hwaddr l,
MemoryRegion *mr);
void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
/* Internal functions, part of the implementation of address_space_read_cached
* and address_space_write_cached. */
void address_space_read_cached_slow(MemoryRegionCache *cache,
- hwaddr addr, void *buf, int len);
+ hwaddr addr, void *buf, hwaddr len);
void address_space_write_cached_slow(MemoryRegionCache *cache,
- hwaddr addr, const void *buf, int len);
+ hwaddr addr, const void *buf, hwaddr len);
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
@@ -2094,7 +2094,7 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
static inline __attribute__((__always_inline__))
MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
- int len)
+ hwaddr len)
{
MemTxResult result = MEMTX_OK;
hwaddr l, addr1;
@@ -2133,7 +2133,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
*/
static inline void
address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
- void *buf, int len)
+ void *buf, hwaddr len)
{
assert(addr < cache->len && len <= cache->len - addr);
if (likely(cache->ptr)) {
@@ -2153,7 +2153,7 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
*/
static inline void
address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
- void *buf, int len)
+ void *buf, hwaddr len)
{
assert(addr < cache->len && len <= cache->len - addr);
if (likely(cache->ptr)) {
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size
2018-12-06 2:32 [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs Li Zhijian
@ 2018-12-06 2:32 ` Li Zhijian
2018-12-21 16:12 ` Michael S. Tsirkin
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h Li Zhijian
` (2 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Li Zhijian @ 2018-12-06 2:32 UTC (permalink / raw)
To: qemu-devel, mst, peter.maydell; +Cc: philip.li, zhijianx.li, philmd, Li Zhijian
Don't expect read(2) can always read as many as it's told.
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
V4: add reviewed-by tag
---
hw/core/loader.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/hw/core/loader.c b/hw/core/loader.c
index fa41842..9cbceab 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -77,21 +77,20 @@ int64_t get_image_size(const char *filename)
ssize_t load_image_size(const char *filename, void *addr, size_t size)
{
int fd;
- ssize_t actsize;
+ ssize_t actsize, l = 0;
fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0) {
return -1;
}
- actsize = read(fd, addr, size);
- if (actsize < 0) {
- close(fd);
- return -1;
+ while ((actsize = read(fd, addr + l, size - l)) > 0) {
+ l += actsize;
}
+
close(fd);
- return actsize;
+ return actsize < 0 ? -1 : l;
}
/* read()-like version */
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h
2018-12-06 2:32 [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size Li Zhijian
@ 2018-12-06 2:32 ` Li Zhijian
2018-12-21 16:04 ` Michael S. Tsirkin
2019-01-04 16:41 ` Stefano Garzarella
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux Li Zhijian
2018-12-21 1:37 ` [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
4 siblings, 2 replies; 21+ messages in thread
From: Li Zhijian @ 2018-12-06 2:32 UTC (permalink / raw)
To: qemu-devel, mst, peter.maydell; +Cc: philip.li, zhijianx.li, philmd, Li Zhijian
it's from v4.20-rc5.
CC: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
V4: use scirpt to import bootparam.h (Michael S. Tsirkin)
V3: new patch
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
hw/i386/pc.c | 8 +------
include/standard-headers/asm-x86/bootparam.h | 34 ++++++++++++++++++++++++++++
| 4 ++++
3 files changed, 39 insertions(+), 7 deletions(-)
create mode 100644 include/standard-headers/asm-x86/bootparam.h
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 067d23a..3b10726 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -74,6 +74,7 @@
#include "hw/nmi.h"
#include "hw/i386/intel_iommu.h"
#include "hw/net/ne2000-isa.h"
+#include "standard-headers/asm-x86/bootparam.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
@@ -820,13 +821,6 @@ static long get_file_size(FILE *f)
return size;
}
-/* setup_data types */
-#define SETUP_NONE 0
-#define SETUP_E820_EXT 1
-#define SETUP_DTB 2
-#define SETUP_PCI 3
-#define SETUP_EFI 4
-
struct setup_data {
uint64_t next;
uint32_t type;
diff --git a/include/standard-headers/asm-x86/bootparam.h b/include/standard-headers/asm-x86/bootparam.h
new file mode 100644
index 0000000..67d4f01
--- /dev/null
+++ b/include/standard-headers/asm-x86/bootparam.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_X86_BOOTPARAM_H
+#define _ASM_X86_BOOTPARAM_H
+
+/* setup_data types */
+#define SETUP_NONE 0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
+#define SETUP_PCI 3
+#define SETUP_EFI 4
+#define SETUP_APPLE_PROPERTIES 5
+#define SETUP_JAILHOUSE 6
+
+/* ram_size flags */
+#define RAMDISK_IMAGE_START_MASK 0x07FF
+#define RAMDISK_PROMPT_FLAG 0x8000
+#define RAMDISK_LOAD_FLAG 0x4000
+
+/* loadflags */
+#define LOADED_HIGH (1<<0)
+#define KASLR_FLAG (1<<1)
+#define QUIET_FLAG (1<<5)
+#define KEEP_SEGMENTS (1<<6)
+#define CAN_USE_HEAP (1<<7)
+
+/* xloadflags */
+#define XLF_KERNEL_64 (1<<0)
+#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
+#define XLF_EFI_HANDOVER_32 (1<<2)
+#define XLF_EFI_HANDOVER_64 (1<<3)
+#define XLF_EFI_KEXEC (1<<4)
+
+
+#endif /* _ASM_X86_BOOTPARAM_H */
--git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 0a964fe..77ec108 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -120,6 +120,10 @@ for arch in $ARCHLIST; do
cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
cp_portable "$tmpdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch"
+ # Remove everything except the macros from bootparam.h avoiding the
+ # unnecessary import of several video/ist/etc headers
+ sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' $tmpdir/include/asm/bootparam.h > $tmpdir/bootparam.h
+ cp_portable $tmpdir/bootparam.h "$output/include/standard-headers/asm-$arch"
fi
done
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2018-12-06 2:32 [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
` (2 preceding siblings ...)
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h Li Zhijian
@ 2018-12-06 2:32 ` Li Zhijian
2018-12-21 16:10 ` Michael S. Tsirkin
2018-12-21 1:37 ` [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
4 siblings, 1 reply; 21+ messages in thread
From: Li Zhijian @ 2018-12-06 2:32 UTC (permalink / raw)
To: qemu-devel, mst, peter.maydell
Cc: philip.li, zhijianx.li, philmd, Li Zhijian, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Marcel Apfelbaum
a new field xloadflags was added to recent x86 linux, and BIT 1:
XLF_CAN_BE_LOADED_ABOVE_4G is used to tell bootload that where initrd can be
loaded safely.
Current QEMU/BIOS always loads initrd below below_4g_mem_size which is always
less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
this bit is set.
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Richard Henderson <rth@twiddle.net>
CC: Eduardo Habkost <ehabkost@redhat.com>
CC: "Michael S. Tsirkin" <mst@redhat.com>
CC: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
V3: correct grammar and check XLF_CAN_BE_LOADED_ABOVE_4G first (Michael S. Tsirkin)
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
---
hw/i386/pc.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3b10726..baa99c0 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -904,7 +904,15 @@ static void load_linux(PCMachineState *pcms,
#endif
/* highest address for loading the initrd */
- if (protocol >= 0x203) {
+ if (protocol >= 0x20c &&
+ lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) {
+ /*
+ * Although kernel allows initrd loading to above 4G,
+ * it just makes it as large as possible while still staying below 4G
+ * since current BIOS always loads initrd below pcms->below_4g_mem_size
+ */
+ initrd_max = UINT32_MAX;
+ } else if (protocol >= 0x203) {
initrd_max = ldl_p(header+0x22c);
} else {
initrd_max = 0x37ffffff;
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel
2018-12-06 2:32 [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
` (3 preceding siblings ...)
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux Li Zhijian
@ 2018-12-21 1:37 ` Li Zhijian
4 siblings, 0 replies; 21+ messages in thread
From: Li Zhijian @ 2018-12-21 1:37 UTC (permalink / raw)
To: qemu-devel, mst, peter.maydell; +Cc: philip.li, zhijianx.li, philmd
ping
On 12/6/18 10:32, Li Zhijian wrote:
> Long long ago, linux kernel has 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 support 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/BIOS always loads initrd below below_4g_mem_size which always
> less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
> this bit is set.
>
> Default roms(Seabios + optionrom(linuxboot_dma)) works as expected with this
> patchset.
>
> changes:
> V4:
> - add Reviwed-by tag to 1/4 and 2/4
> - use scripts/update-linux-headers.sh to import bootparam.h
> - minor fix at commit log
> V3:
> - rebase code basing on http://patchwork.ozlabs.org/cover/1005990 and
> https://patchew.org/QEMU/20181122133507.30950-1-peter.maydell@linaro.org
> - add new patch 3/4 to import header bootparam.h (Michael S. Tsirkin)
>
> V2: add 2 patches(3/5, 4/5) to fix potential loading issue.
>
> Li Zhijian (4):
> unify len and addr type for memory/address APIs
> refactor load_image_size
> i386: import & use bootparam.h
> i386: allow to load initrd below 4G for recent linux
>
> exec.c | 47 ++++++++++++++--------------
> hw/core/loader.c | 11 +++----
> hw/i386/pc.c | 18 ++++++-----
> include/exec/cpu-all.h | 2 +-
> include/exec/cpu-common.h | 8 ++---
> include/exec/memory.h | 22 ++++++-------
> include/standard-headers/asm-x86/bootparam.h | 34 ++++++++++++++++++++
> scripts/update-linux-headers.sh | 4 +++
> 8 files changed, 92 insertions(+), 54 deletions(-)
> create mode 100644 include/standard-headers/asm-x86/bootparam.h
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h Li Zhijian
@ 2018-12-21 16:04 ` Michael S. Tsirkin
2019-01-04 16:41 ` Stefano Garzarella
1 sibling, 0 replies; 21+ messages in thread
From: Michael S. Tsirkin @ 2018-12-21 16:04 UTC (permalink / raw)
To: Li Zhijian; +Cc: qemu-devel, peter.maydell, philip.li, zhijianx.li, philmd
On Thu, Dec 06, 2018 at 10:32:12AM +0800, Li Zhijian wrote:
> it's from v4.20-rc5.
>
> CC: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> V4: use scirpt to import bootparam.h (Michael S. Tsirkin)
> V3: new patch
>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> ---
> hw/i386/pc.c | 8 +------
> include/standard-headers/asm-x86/bootparam.h | 34 ++++++++++++++++++++++++++++
> scripts/update-linux-headers.sh | 4 ++++
> 3 files changed, 39 insertions(+), 7 deletions(-)
> create mode 100644 include/standard-headers/asm-x86/bootparam.h
>
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 067d23a..3b10726 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -74,6 +74,7 @@
> #include "hw/nmi.h"
> #include "hw/i386/intel_iommu.h"
> #include "hw/net/ne2000-isa.h"
> +#include "standard-headers/asm-x86/bootparam.h"
>
> /* debug PC/ISA interrupts */
> //#define DEBUG_IRQ
> @@ -820,13 +821,6 @@ static long get_file_size(FILE *f)
> return size;
> }
>
> -/* setup_data types */
> -#define SETUP_NONE 0
> -#define SETUP_E820_EXT 1
> -#define SETUP_DTB 2
> -#define SETUP_PCI 3
> -#define SETUP_EFI 4
> -
> struct setup_data {
> uint64_t next;
> uint32_t type;
> diff --git a/include/standard-headers/asm-x86/bootparam.h b/include/standard-headers/asm-x86/bootparam.h
> new file mode 100644
> index 0000000..67d4f01
> --- /dev/null
> +++ b/include/standard-headers/asm-x86/bootparam.h
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _ASM_X86_BOOTPARAM_H
> +#define _ASM_X86_BOOTPARAM_H
> +
> +/* setup_data types */
> +#define SETUP_NONE 0
> +#define SETUP_E820_EXT 1
> +#define SETUP_DTB 2
> +#define SETUP_PCI 3
> +#define SETUP_EFI 4
> +#define SETUP_APPLE_PROPERTIES 5
> +#define SETUP_JAILHOUSE 6
> +
> +/* ram_size flags */
> +#define RAMDISK_IMAGE_START_MASK 0x07FF
> +#define RAMDISK_PROMPT_FLAG 0x8000
> +#define RAMDISK_LOAD_FLAG 0x4000
> +
> +/* loadflags */
> +#define LOADED_HIGH (1<<0)
> +#define KASLR_FLAG (1<<1)
> +#define QUIET_FLAG (1<<5)
> +#define KEEP_SEGMENTS (1<<6)
> +#define CAN_USE_HEAP (1<<7)
> +
> +/* xloadflags */
> +#define XLF_KERNEL_64 (1<<0)
> +#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
> +#define XLF_EFI_HANDOVER_32 (1<<2)
> +#define XLF_EFI_HANDOVER_64 (1<<3)
> +#define XLF_EFI_KEXEC (1<<4)
> +
> +
> +#endif /* _ASM_X86_BOOTPARAM_H */
> diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
> index 0a964fe..77ec108 100755
> --- a/scripts/update-linux-headers.sh
> +++ b/scripts/update-linux-headers.sh
> @@ -120,6 +120,10 @@ for arch in $ARCHLIST; do
> cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
> cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
> cp_portable "$tmpdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch"
> + # Remove everything except the macros from bootparam.h avoiding the
> + # unnecessary import of several video/ist/etc headers
> + sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' $tmpdir/include/asm/bootparam.h > $tmpdir/bootparam.h
> + cp_portable $tmpdir/bootparam.h "$output/include/standard-headers/asm-$arch"
> fi
> done
>
> --
> 2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux Li Zhijian
@ 2018-12-21 16:10 ` Michael S. Tsirkin
2018-12-27 20:31 ` Eduardo Habkost
0 siblings, 1 reply; 21+ messages in thread
From: Michael S. Tsirkin @ 2018-12-21 16:10 UTC (permalink / raw)
To: Li Zhijian
Cc: qemu-devel, peter.maydell, philip.li, zhijianx.li, philmd,
Paolo Bonzini, Richard Henderson, Eduardo Habkost,
Marcel Apfelbaum
On Thu, Dec 06, 2018 at 10:32:13AM +0800, Li Zhijian wrote:
> a new field xloadflags was added to recent x86 linux, and BIT 1:
> XLF_CAN_BE_LOADED_ABOVE_4G is used to tell bootload that where initrd can be
> loaded safely.
>
> Current QEMU/BIOS always loads initrd below below_4g_mem_size which is always
> less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
> this bit is set.
>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Richard Henderson <rth@twiddle.net>
> CC: Eduardo Habkost <ehabkost@redhat.com>
> CC: "Michael S. Tsirkin" <mst@redhat.com>
> CC: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>
> ---
> V3: correct grammar and check XLF_CAN_BE_LOADED_ABOVE_4G first (Michael S. Tsirkin)
>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> ---
> hw/i386/pc.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 3b10726..baa99c0 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -904,7 +904,15 @@ static void load_linux(PCMachineState *pcms,
> #endif
>
> /* highest address for loading the initrd */
> - if (protocol >= 0x203) {
> + if (protocol >= 0x20c &&
> + lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) {
> + /*
> + * Although kernel allows initrd loading to above 4G,
> + * it just makes it as large as possible while still staying below 4G
> + * since current BIOS always loads initrd below pcms->below_4g_mem_size
> + */
> + initrd_max = UINT32_MAX;
> + } else if (protocol >= 0x203) {
> initrd_max = ldl_p(header+0x22c);
> } else {
> initrd_max = 0x37ffffff;
I still have trouble understanding the above.
Anyone else wants to comment / help rephrase the comment
and commit log so it's readable?
> --
> 2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size Li Zhijian
@ 2018-12-21 16:12 ` Michael S. Tsirkin
2018-12-24 2:14 ` Li Zhijian
0 siblings, 1 reply; 21+ messages in thread
From: Michael S. Tsirkin @ 2018-12-21 16:12 UTC (permalink / raw)
To: Li Zhijian; +Cc: qemu-devel, peter.maydell, philip.li, zhijianx.li, philmd
On Thu, Dec 06, 2018 at 10:32:11AM +0800, Li Zhijian wrote:
> Don't expect read(2) can always read as many as it's told.
>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This is more a theoretical bugfix than a refactoring right?
> ---
> V4: add reviewed-by tag
> ---
> hw/core/loader.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/hw/core/loader.c b/hw/core/loader.c
> index fa41842..9cbceab 100644
> --- a/hw/core/loader.c
> +++ b/hw/core/loader.c
> @@ -77,21 +77,20 @@ int64_t get_image_size(const char *filename)
> ssize_t load_image_size(const char *filename, void *addr, size_t size)
> {
> int fd;
> - ssize_t actsize;
> + ssize_t actsize, l = 0;
>
> fd = open(filename, O_RDONLY | O_BINARY);
> if (fd < 0) {
> return -1;
> }
>
> - actsize = read(fd, addr, size);
> - if (actsize < 0) {
> - close(fd);
> - return -1;
> + while ((actsize = read(fd, addr + l, size - l)) > 0) {
> + l += actsize;
> }
> +
> close(fd);
>
> - return actsize;
> + return actsize < 0 ? -1 : l;
> }
>
> /* read()-like version */
> --
> 2.7.4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size
2018-12-21 16:12 ` Michael S. Tsirkin
@ 2018-12-24 2:14 ` Li Zhijian
2019-01-07 10:33 ` Stefano Garzarella
0 siblings, 1 reply; 21+ messages in thread
From: Li Zhijian @ 2018-12-24 2:14 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: peter.maydell, zhijianx.li, philmd, qemu-devel, philip.li
On 12/22/18 00:12, Michael S. Tsirkin wrote:
> On Thu, Dec 06, 2018 at 10:32:11AM +0800, Li Zhijian wrote:
>> Don't expect read(2) can always read as many as it's told.
>>
>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> This is more a theoretical bugfix than a refactoring right?
Yes, it does.
how about change the title to : "enhance reading on load_image_size()" or such
Thanks
Zhijian
>
>> ---
>> V4: add reviewed-by tag
>> ---
>> hw/core/loader.c | 11 +++++------
>> 1 file changed, 5 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/core/loader.c b/hw/core/loader.c
>> index fa41842..9cbceab 100644
>> --- a/hw/core/loader.c
>> +++ b/hw/core/loader.c
>> @@ -77,21 +77,20 @@ int64_t get_image_size(const char *filename)
>> ssize_t load_image_size(const char *filename, void *addr, size_t size)
>> {
>> int fd;
>> - ssize_t actsize;
>> + ssize_t actsize, l = 0;
>>
>> fd = open(filename, O_RDONLY | O_BINARY);
>> if (fd < 0) {
>> return -1;
>> }
>>
>> - actsize = read(fd, addr, size);
>> - if (actsize < 0) {
>> - close(fd);
>> - return -1;
>> + while ((actsize = read(fd, addr + l, size - l)) > 0) {
>> + l += actsize;
>> }
>> +
>> close(fd);
>>
>> - return actsize;
>> + return actsize < 0 ? -1 : l;
>> }
>>
>> /* read()-like version */
>> --
>> 2.7.4
>
>
>
--
Best regards.
Li Zhijian (8528)
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2018-12-21 16:10 ` Michael S. Tsirkin
@ 2018-12-27 20:31 ` Eduardo Habkost
2018-12-28 7:20 ` Li Zhijian
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Eduardo Habkost @ 2018-12-27 20:31 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Li Zhijian, qemu-devel, peter.maydell, philip.li, zhijianx.li,
philmd, Paolo Bonzini, Richard Henderson, Marcel Apfelbaum
On Fri, Dec 21, 2018 at 11:10:30AM -0500, Michael S. Tsirkin wrote:
> On Thu, Dec 06, 2018 at 10:32:13AM +0800, Li Zhijian wrote:
> > a new field xloadflags was added to recent x86 linux, and BIT 1:
> > XLF_CAN_BE_LOADED_ABOVE_4G is used to tell bootload that where initrd can be
> > loaded safely.
> >
> > Current QEMU/BIOS always loads initrd below below_4g_mem_size which is always
> > less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
> > this bit is set.
> >
> > CC: Paolo Bonzini <pbonzini@redhat.com>
> > CC: Richard Henderson <rth@twiddle.net>
> > CC: Eduardo Habkost <ehabkost@redhat.com>
> > CC: "Michael S. Tsirkin" <mst@redhat.com>
> > CC: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
> > Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> >
> > ---
> > V3: correct grammar and check XLF_CAN_BE_LOADED_ABOVE_4G first (Michael S. Tsirkin)
> >
> > Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> > ---
> > hw/i386/pc.c | 10 +++++++++-
> > 1 file changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 3b10726..baa99c0 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -904,7 +904,15 @@ static void load_linux(PCMachineState *pcms,
> > #endif
> >
> > /* highest address for loading the initrd */
> > - if (protocol >= 0x203) {
> > + if (protocol >= 0x20c &&
> > + lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) {
> > + /*
> > + * Although kernel allows initrd loading to above 4G,
> > + * it just makes it as large as possible while still staying below 4G
> > + * since current BIOS always loads initrd below pcms->below_4g_mem_size
> > + */
> > + initrd_max = UINT32_MAX;
> > + } else if (protocol >= 0x203) {
> > initrd_max = ldl_p(header+0x22c);
> > } else {
> > initrd_max = 0x37ffffff;
>
>
> I still have trouble understanding the above.
> Anyone else wants to comment / help rephrase the comment
> and commit log so it's readable?
The comment seems to contradict what I see on the code:
| Although kernel allows initrd loading to above 4G,
Sounds correct.
| it just makes it as large as possible while still staying below 4G
I'm not a native English speaker, but I believe "it" here should
be interpreted as "the kernel", which would be incorrect. It's
this QEMU function that limits initrd_max to a uint32 value, not
the kernel.
| since current BIOS always loads initrd below pcms->below_4g_mem_size
I don't know why the BIOS is mentioned here. The
below_4g_mem_size limit comes from these 2 lines inside
load_linux():
if (initrd_max >= pcms->below_4g_mem_size - pcmc->acpi_data_size) {
initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1;
}
In addition to that, initrd_max is uint32_t simply because QEMU
doesn't support the 64-bit boot protocol (specifically the
ext_ramdisk_image field), so all talk about below_4g_mem_size
seems to be just a distraction.
All that said, I miss one piece of information here: is
XLF_CAN_BE_LOADED_ABOVE_4G really supposed to override
header+0x22c? linux/Documentation/x86/boot.txt isn't clear about
that. Is there any reference that can help us confirm this?
--
Eduardo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2018-12-27 20:31 ` Eduardo Habkost
@ 2018-12-28 7:20 ` Li Zhijian
2019-01-07 12:11 ` Stefano Garzarella
2019-01-07 23:35 ` Paolo Bonzini
2 siblings, 0 replies; 21+ messages in thread
From: Li Zhijian @ 2018-12-28 7:20 UTC (permalink / raw)
To: Eduardo Habkost, Michael S. Tsirkin
Cc: Li Zhijian, qemu-devel, peter.maydell, philip.li, philmd,
Paolo Bonzini, Richard Henderson, Marcel Apfelbaum
On 12/28/2018 4:31 AM, Eduardo Habkost wrote:
> On Fri, Dec 21, 2018 at 11:10:30AM -0500, Michael S. Tsirkin wrote:
>> On Thu, Dec 06, 2018 at 10:32:13AM +0800, Li Zhijian wrote:
>>>
>>> /* highest address for loading the initrd */
>>> - if (protocol >= 0x203) {
>>> + if (protocol >= 0x20c &&
>>> + lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) {
>>> + /*
>>> + * Although kernel allows initrd loading to above 4G,
>>> + * it just makes it as large as possible while still staying below 4G
>>> + * since current BIOS always loads initrd below pcms->below_4g_mem_size
>>> + */
>>> + initrd_max = UINT32_MAX;
>>> + } else if (protocol >= 0x203) {
>>> initrd_max = ldl_p(header+0x22c);
>>> } else {
>>> initrd_max = 0x37ffffff;
>>
>> I still have trouble understanding the above.
>> Anyone else wants to comment / help rephrase the comment
>> and commit log so it's readable?
>
> The comment seems to contradict what I see on the code:
>
> | Although kernel allows initrd loading to above 4G,
>
> Sounds correct.
>
>
> | it just makes it as large as possible while still staying below 4G
>
> I'm not a native English speaker, but I believe "it" here should
> be interpreted as "the kernel", which would be incorrect. It's
> this QEMU function that limits initrd_max to a uint32 value, not
> the kernel.
>
>
> | since current BIOS always loads initrd below pcms->below_4g_mem_size
>
> I don't know why the BIOS is mentioned here. The
> below_4g_mem_size limit comes from these 2 lines inside
> load_linux():
>
> if (initrd_max >= pcms->below_4g_mem_size - pcmc->acpi_data_size) {
> initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1;
> }
> In addition to that, initrd_max is uint32_t simply because QEMU
> doesn't support the 64-bit boot protocol (specifically the
> ext_ramdisk_image field),
Thanks for explaining this :), i'm not clear before.
> so all talk about below_4g_mem_size
> seems to be just a distraction.
>
> All that said, I miss one piece of information here: is
> XLF_CAN_BE_LOADED_ABOVE_4G really supposed to override
> header+0x22c? linux/Documentation/x86/boot.txt isn't clear about
> that. Is there any reference that can help us confirm this?
Good question.
Since i'm not familiar with boot protocol, at the beginning, i also CCed to LKML for helps
https://lkml.org/lkml/2018/11/10/82
Ingo said:
>> > If XLF_CAN_BE_LOADED_ABOVE_4G is not > set, then you most likely
>> are on a 32-bit kernel and there are more > fundamental limits (even
>> if you were to load it above the 2 GB mark, you > would be limited by
>> the size of kernel memory.) > > So, in case you are wondering: the
>> bootloader that broke when setting > the initrd_max field above 2 GB
>> was, of course, Grub. > > So just use XLF_CAN_BE_LOADED_ABOVE_4G.
>> There is no need for a new flag > or new field. That's nice, and
>> that's the best solution!
that make me to believe that if XLF_CAN_BE_LOADED_ABOVE_4G is set, BELOW_4G is allowed too.
if above is credible, might be we can update the comments like:
-------
QEMU doesn't support the 64-bit boot protocol (specifically the
ext_ramdisk_image field).
In addition, kernel allows to load initrd above 4G if XLF_CAN_BE_LOADED_ABOVE_4G is set,
so we believe that load initrd below 4G is allowed too.
For simplicity, so just set initrd_max to UINT32_MAX is enough and safe.
-------
Thanks
Zhijian
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h Li Zhijian
2018-12-21 16:04 ` Michael S. Tsirkin
@ 2019-01-04 16:41 ` Stefano Garzarella
2019-01-08 1:11 ` Li Zhijian
1 sibling, 1 reply; 21+ messages in thread
From: Stefano Garzarella @ 2019-01-04 16:41 UTC (permalink / raw)
To: Li Zhijian
Cc: qemu-devel, Michael Tsirkin, peter.maydell, philip.li,
zhijianx.li, Philippe Mathieu Daude
Hi Li,
On Thu, Dec 6, 2018 at 3:24 AM Li Zhijian <lizhijian@cn.fujitsu.com> wrote:
>
> it's from v4.20-rc5.
>
> CC: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>
> ---
> V4: use scirpt to import bootparam.h (Michael S. Tsirkin)
> V3: new patch
>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> ---
> hw/i386/pc.c | 8 +------
> include/standard-headers/asm-x86/bootparam.h | 34 ++++++++++++++++++++++++++++
> scripts/update-linux-headers.sh | 4 ++++
> 3 files changed, 39 insertions(+), 7 deletions(-)
> create mode 100644 include/standard-headers/asm-x86/bootparam.h
>
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 067d23a..3b10726 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -74,6 +74,7 @@
> #include "hw/nmi.h"
> #include "hw/i386/intel_iommu.h"
> #include "hw/net/ne2000-isa.h"
> +#include "standard-headers/asm-x86/bootparam.h"
>
> /* debug PC/ISA interrupts */
> //#define DEBUG_IRQ
> @@ -820,13 +821,6 @@ static long get_file_size(FILE *f)
> return size;
> }
>
> -/* setup_data types */
> -#define SETUP_NONE 0
> -#define SETUP_E820_EXT 1
> -#define SETUP_DTB 2
> -#define SETUP_PCI 3
> -#define SETUP_EFI 4
> -
> struct setup_data {
> uint64_t next;
> uint32_t type;
> diff --git a/include/standard-headers/asm-x86/bootparam.h b/include/standard-headers/asm-x86/bootparam.h
> new file mode 100644
> index 0000000..67d4f01
> --- /dev/null
> +++ b/include/standard-headers/asm-x86/bootparam.h
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _ASM_X86_BOOTPARAM_H
> +#define _ASM_X86_BOOTPARAM_H
> +
> +/* setup_data types */
> +#define SETUP_NONE 0
> +#define SETUP_E820_EXT 1
> +#define SETUP_DTB 2
> +#define SETUP_PCI 3
> +#define SETUP_EFI 4
> +#define SETUP_APPLE_PROPERTIES 5
> +#define SETUP_JAILHOUSE 6
> +
> +/* ram_size flags */
> +#define RAMDISK_IMAGE_START_MASK 0x07FF
> +#define RAMDISK_PROMPT_FLAG 0x8000
> +#define RAMDISK_LOAD_FLAG 0x4000
> +
> +/* loadflags */
> +#define LOADED_HIGH (1<<0)
> +#define KASLR_FLAG (1<<1)
> +#define QUIET_FLAG (1<<5)
> +#define KEEP_SEGMENTS (1<<6)
> +#define CAN_USE_HEAP (1<<7)
> +
> +/* xloadflags */
> +#define XLF_KERNEL_64 (1<<0)
> +#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
> +#define XLF_EFI_HANDOVER_32 (1<<2)
> +#define XLF_EFI_HANDOVER_64 (1<<3)
> +#define XLF_EFI_KEXEC (1<<4)
> +
> +
> +#endif /* _ASM_X86_BOOTPARAM_H */
> diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
> index 0a964fe..77ec108 100755
> --- a/scripts/update-linux-headers.sh
> +++ b/scripts/update-linux-headers.sh
> @@ -120,6 +120,10 @@ for arch in $ARCHLIST; do
> cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
> cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
> cp_portable "$tmpdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch"
> + # Remove everything except the macros from bootparam.h avoiding the
> + # unnecessary import of several video/ist/etc headers
> + sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' $tmpdir/include/asm/bootparam.h > $tmpdir/bootparam.h
> + cp_portable $tmpdir/bootparam.h "$output/include/standard-headers/asm-$arch"
Maybe is better to use the double quotes for all paths.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Thanks,
Stefano
> fi
> done
>
> --
> 2.7.4
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs Li Zhijian
@ 2019-01-07 10:04 ` Stefano Garzarella
2019-01-08 1:06 ` Li Zhijian
0 siblings, 1 reply; 21+ messages in thread
From: Stefano Garzarella @ 2019-01-07 10:04 UTC (permalink / raw)
To: Li Zhijian
Cc: qemu-devel, Michael Tsirkin, Peter Maydell, Peter Crosthwaite,
philip.li, zhijianx.li, Paolo Bonzini, Philippe Mathieu Daude,
Richard Henderson
Hi Li,
On Thu, Dec 6, 2018 at 3:26 AM Li Zhijian <lizhijian@cn.fujitsu.com> wrote:
>
> Some address/memory APIs have different type between
> 'hwaddr/target_ulong addr' and 'int len'. It is very unsafe, espcially
As Philippe already suggested,
s/espcially/especially
> some APIs will be passed a non-int len by caller which might cause
> overflow quietly.
> Below is an potential overflow case:
> dma_memory_read(uint32_t len)
> -> dma_memory_rw(uint32_t len)
> -> dma_memory_rw_relaxed(uint32_t len)
> -> address_space_rw(int len) # len overflow
>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> CC: Richard Henderson <rth@twiddle.net>
> CC: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
> ---
> V4: minor fix at commit message and add Reviewed-by tag
> V3: use the same type between len and addr(Peter Maydell)
> rebase code basing on https://patchew.org/QEMU/20181122133507.30950-1-peter.maydell@linaro.org/
> ---
> exec.c | 47 +++++++++++++++++++++++------------------------
> include/exec/cpu-all.h | 2 +-
> include/exec/cpu-common.h | 8 ++++----
> include/exec/memory.h | 22 +++++++++++-----------
> 4 files changed, 39 insertions(+), 40 deletions(-)
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size
2018-12-24 2:14 ` Li Zhijian
@ 2019-01-07 10:33 ` Stefano Garzarella
2019-01-08 1:09 ` Li Zhijian
0 siblings, 1 reply; 21+ messages in thread
From: Stefano Garzarella @ 2019-01-07 10:33 UTC (permalink / raw)
To: Li Zhijian
Cc: Michael S. Tsirkin, Peter Maydell, zhijianx.li,
Philippe Mathieu Daude, qemu-devel, philip.li
On Mon, Dec 24, 2018 at 3:16 AM Li Zhijian <lizhijian@cn.fujitsu.com> wrote:
>
>
> On 12/22/18 00:12, Michael S. Tsirkin wrote:
> > On Thu, Dec 06, 2018 at 10:32:11AM +0800, Li Zhijian wrote:
> >> Don't expect read(2) can always read as many as it's told.
> >>
> >> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> >> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> > This is more a theoretical bugfix than a refactoring right?
>
> Yes, it does.
>
> how about change the title to : "enhance reading on load_image_size()" or such
Maybe something like this: "hw/core/loader.c: Read as long as possible
in load_image_size()"
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
> Thanks
> Zhijian
>
>
> >
> >> ---
> >> V4: add reviewed-by tag
> >> ---
> >> hw/core/loader.c | 11 +++++------
> >> 1 file changed, 5 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/hw/core/loader.c b/hw/core/loader.c
> >> index fa41842..9cbceab 100644
> >> --- a/hw/core/loader.c
> >> +++ b/hw/core/loader.c
> >> @@ -77,21 +77,20 @@ int64_t get_image_size(const char *filename)
> >> ssize_t load_image_size(const char *filename, void *addr, size_t size)
> >> {
> >> int fd;
> >> - ssize_t actsize;
> >> + ssize_t actsize, l = 0;
> >>
> >> fd = open(filename, O_RDONLY | O_BINARY);
> >> if (fd < 0) {
> >> return -1;
> >> }
> >>
> >> - actsize = read(fd, addr, size);
> >> - if (actsize < 0) {
> >> - close(fd);
> >> - return -1;
> >> + while ((actsize = read(fd, addr + l, size - l)) > 0) {
> >> + l += actsize;
> >> }
> >> +
> >> close(fd);
> >>
> >> - return actsize;
> >> + return actsize < 0 ? -1 : l;
> >> }
> >>
> >> /* read()-like version */
> >> --
> >> 2.7.4
> >
> >
> >
> --
> Best regards.
> Li Zhijian (8528)
>
>
>
--
Stefano Garzarella
Red Hat
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2018-12-27 20:31 ` Eduardo Habkost
2018-12-28 7:20 ` Li Zhijian
@ 2019-01-07 12:11 ` Stefano Garzarella
2019-01-09 6:22 ` Li Zhijian
2019-01-07 23:35 ` Paolo Bonzini
2 siblings, 1 reply; 21+ messages in thread
From: Stefano Garzarella @ 2019-01-07 12:11 UTC (permalink / raw)
To: Eduardo Habkost
Cc: Michael S. Tsirkin, Peter Maydell, Li Zhijian, qemu-devel,
philip.li, zhijianx.li, Paolo Bonzini, Philippe Mathieu Daude,
Richard Henderson
Hi,
On Thu, Dec 27, 2018 at 9:32 PM Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> On Fri, Dec 21, 2018 at 11:10:30AM -0500, Michael S. Tsirkin wrote:
> > On Thu, Dec 06, 2018 at 10:32:13AM +0800, Li Zhijian wrote:
> > > a new field xloadflags was added to recent x86 linux, and BIT 1:
> > > XLF_CAN_BE_LOADED_ABOVE_4G is used to tell bootload that where initrd can be
> > > loaded safely.
> > >
> > > Current QEMU/BIOS always loads initrd below below_4g_mem_size which is always
> > > less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
> > > this bit is set.
> > >
> > > CC: Paolo Bonzini <pbonzini@redhat.com>
> > > CC: Richard Henderson <rth@twiddle.net>
> > > CC: Eduardo Habkost <ehabkost@redhat.com>
> > > CC: "Michael S. Tsirkin" <mst@redhat.com>
> > > CC: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
> > > Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> > >
> > > ---
> > > V3: correct grammar and check XLF_CAN_BE_LOADED_ABOVE_4G first (Michael S. Tsirkin)
> > >
> > > Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
> > > ---
> > > hw/i386/pc.c | 10 +++++++++-
> > > 1 file changed, 9 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 3b10726..baa99c0 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -904,7 +904,15 @@ static void load_linux(PCMachineState *pcms,
> > > #endif
> > >
> > > /* highest address for loading the initrd */
> > > - if (protocol >= 0x203) {
> > > + if (protocol >= 0x20c &&
> > > + lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) {
> > > + /*
> > > + * Although kernel allows initrd loading to above 4G,
> > > + * it just makes it as large as possible while still staying below 4G
> > > + * since current BIOS always loads initrd below pcms->below_4g_mem_size
> > > + */
> > > + initrd_max = UINT32_MAX;
> > > + } else if (protocol >= 0x203) {
> > > initrd_max = ldl_p(header+0x22c);
> > > } else {
> > > initrd_max = 0x37ffffff;
> >
> >
> > I still have trouble understanding the above.
> > Anyone else wants to comment / help rephrase the comment
> > and commit log so it's readable?
>
>
> The comment seems to contradict what I see on the code:
>
> | Although kernel allows initrd loading to above 4G,
>
> Sounds correct.
>
>
> | it just makes it as large as possible while still staying below 4G
>
> I'm not a native English speaker, but I believe "it" here should
> be interpreted as "the kernel", which would be incorrect. It's
> this QEMU function that limits initrd_max to a uint32 value, not
> the kernel.
>
>
> | since current BIOS always loads initrd below pcms->below_4g_mem_size
>
> I don't know why the BIOS is mentioned here. The
> below_4g_mem_size limit comes from these 2 lines inside
> load_linux():
>
> if (initrd_max >= pcms->below_4g_mem_size - pcmc->acpi_data_size) {
> initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1;
> }
> In addition to that, initrd_max is uint32_t simply because QEMU
> doesn't support the 64-bit boot protocol (specifically the
> ext_ramdisk_image field), so all talk about below_4g_mem_size
> seems to be just a distraction.
>
> All that said, I miss one piece of information here: is
> XLF_CAN_BE_LOADED_ABOVE_4G really supposed to override
> header+0x22c? linux/Documentation/x86/boot.txt isn't clear about
> that. Is there any reference that can help us confirm this?
Looking at the following patch seems that we can confirm the assumption:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4bf7111f50167133a71c23530ca852a41355e739
Note: the patch was reverted due to bugs in some firmwares, but IMHO
the assumption is correct.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=47226ad4f4cfd1e91ded7f2ec42f83ff1c624663
Cheers,
Stefano
>
> --
> Eduardo
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2018-12-27 20:31 ` Eduardo Habkost
2018-12-28 7:20 ` Li Zhijian
2019-01-07 12:11 ` Stefano Garzarella
@ 2019-01-07 23:35 ` Paolo Bonzini
2 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2019-01-07 23:35 UTC (permalink / raw)
To: Eduardo Habkost, Michael S. Tsirkin
Cc: Li Zhijian, qemu-devel, peter.maydell, philip.li, zhijianx.li,
philmd, Richard Henderson, Marcel Apfelbaum
On 27/12/18 21:31, Eduardo Habkost wrote:
> All that said, I miss one piece of information here: is
> XLF_CAN_BE_LOADED_ABOVE_4G really supposed to override
> header+0x22c? linux/Documentation/x86/boot.txt isn't clear about
> that. Is there any reference that can help us confirm this?
Linux has supported initrd up to 4 GB for a very long time (2007, long
before XLF_CAN_BE_LOADED_ABOVE_4G which was added in 2013), though it
only sets initrd_max to 2 GB to "work around bootloader bugs". So I
guess the flag can be taken as a hint that you can load at any address,
and perhaps could be renamed.
Paolo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs
2019-01-07 10:04 ` Stefano Garzarella
@ 2019-01-08 1:06 ` Li Zhijian
0 siblings, 0 replies; 21+ messages in thread
From: Li Zhijian @ 2019-01-08 1:06 UTC (permalink / raw)
To: Stefano Garzarella
Cc: qemu-devel, Michael Tsirkin, Peter Maydell, Peter Crosthwaite,
philip.li, zhijianx.li, Paolo Bonzini, Philippe Mathieu Daude,
Richard Henderson
On 1/7/19 18:04, Stefano Garzarella wrote:
> As Philippe already suggested,
> s/espcially/especially
Hi Stefano,
thanks a lot, will update it at next version.
Thanks
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size
2019-01-07 10:33 ` Stefano Garzarella
@ 2019-01-08 1:09 ` Li Zhijian
0 siblings, 0 replies; 21+ messages in thread
From: Li Zhijian @ 2019-01-08 1:09 UTC (permalink / raw)
To: Stefano Garzarella
Cc: Michael S. Tsirkin, Peter Maydell, zhijianx.li,
Philippe Mathieu Daude, qemu-devel, philip.li
On 1/7/19 18:33, Stefano Garzarella wrote:
> On Mon, Dec 24, 2018 at 3:16 AM Li Zhijian <lizhijian@cn.fujitsu.com> wrote:
>>
>> On 12/22/18 00:12, Michael S. Tsirkin wrote:
>>> On Thu, Dec 06, 2018 at 10:32:11AM +0800, Li Zhijian wrote:
>>>> Don't expect read(2) can always read as many as it's told.
>>>>
>>>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>>>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>>> This is more a theoretical bugfix than a refactoring right?
>> Yes, it does.
>>
>> how about change the title to : "enhance reading on load_image_size()" or such
> Maybe something like this: "hw/core/loader.c: Read as long as possible
> in load_image_size()"
It really helps, i will take your suggestion to the subject.
Thanks
Zhijian
>
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h
2019-01-04 16:41 ` Stefano Garzarella
@ 2019-01-08 1:11 ` Li Zhijian
0 siblings, 0 replies; 21+ messages in thread
From: Li Zhijian @ 2019-01-08 1:11 UTC (permalink / raw)
To: Stefano Garzarella
Cc: qemu-devel, Michael Tsirkin, peter.maydell, philip.li,
zhijianx.li, Philippe Mathieu Daude
Hi Stefano,
On 1/5/19 00:41, Stefano Garzarella wrote:
>> + # Remove everything except the macros from bootparam.h avoiding the
>> + # unnecessary import of several video/ist/etc headers
>> + sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' $tmpdir/include/asm/bootparam.h > $tmpdir/bootparam.h
>> + cp_portable $tmpdir/bootparam.h "$output/include/standard-headers/asm-$arch"
> Maybe is better to use the double quotes for all paths.
Sure, i will update it at next version.
Thanks
Zhijian
>
> Reviewed-by: Stefano Garzarella<sgarzare@redhat.com>
>
> Thanks,
> Stefano
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux
2019-01-07 12:11 ` Stefano Garzarella
@ 2019-01-09 6:22 ` Li Zhijian
0 siblings, 0 replies; 21+ messages in thread
From: Li Zhijian @ 2019-01-09 6:22 UTC (permalink / raw)
To: Stefano Garzarella, Eduardo Habkost
Cc: Michael S. Tsirkin, Peter Maydell, qemu-devel, philip.li,
zhijianx.li, Paolo Bonzini, Philippe Mathieu Daude,
Richard Henderson
On 1/7/19 20:11, Stefano Garzarella wrote:
> Hi,
>
> On Thu, Dec 27, 2018 at 9:32 PM Eduardo Habkost <ehabkost@redhat.com> wrote:
>> On Fri, Dec 21, 2018 at 11:10:30AM -0500, Michael S. Tsirkin wrote:
>>> On Thu, Dec 06, 2018 at 10:32:13AM +0800, Li Zhijian wrote:
>>>> a new field xloadflags was added to recent x86 linux, and BIT 1:
>>>> XLF_CAN_BE_LOADED_ABOVE_4G is used to tell bootload that where initrd can be
>>>> loaded safely.
>>>>
>>>> Current QEMU/BIOS always loads initrd below below_4g_mem_size which is always
>>>> less than 4G, so here limiting initrd_max to 4G - 1 simply is enough if
>>>> this bit is set.
>>>>
>>>> CC: Paolo Bonzini <pbonzini@redhat.com>
>>>> CC: Richard Henderson <rth@twiddle.net>
>>>> CC: Eduardo Habkost <ehabkost@redhat.com>
>>>> CC: "Michael S. Tsirkin" <mst@redhat.com>
>>>> CC: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
>>>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>>>>
>>>> ---
>>>> V3: correct grammar and check XLF_CAN_BE_LOADED_ABOVE_4G first (Michael S. Tsirkin)
>>>>
>>>> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
>>>> ---
>>>> hw/i386/pc.c | 10 +++++++++-
>>>> 1 file changed, 9 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>>>> index 3b10726..baa99c0 100644
>>>> --- a/hw/i386/pc.c
>>>> +++ b/hw/i386/pc.c
>>>> @@ -904,7 +904,15 @@ static void load_linux(PCMachineState *pcms,
>>>> #endif
>>>>
>>>> /* highest address for loading the initrd */
>>>> - if (protocol >= 0x203) {
>>>> + if (protocol >= 0x20c &&
>>>> + lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) {
>>>> + /*
>>>> + * Although kernel allows initrd loading to above 4G,
>>>> + * it just makes it as large as possible while still staying below 4G
>>>> + * since current BIOS always loads initrd below pcms->below_4g_mem_size
>>>> + */
>>>> + initrd_max = UINT32_MAX;
>>>> + } else if (protocol >= 0x203) {
>>>> initrd_max = ldl_p(header+0x22c);
>>>> } else {
>>>> initrd_max = 0x37ffffff;
>>>
>>> I still have trouble understanding the above.
>>> Anyone else wants to comment / help rephrase the comment
>>> and commit log so it's readable?
>>
>> The comment seems to contradict what I see on the code:
>>
>> | Although kernel allows initrd loading to above 4G,
>>
>> Sounds correct.
>>
>>
>> | it just makes it as large as possible while still staying below 4G
>>
>> I'm not a native English speaker, but I believe "it" here should
>> be interpreted as "the kernel", which would be incorrect. It's
>> this QEMU function that limits initrd_max to a uint32 value, not
>> the kernel.
>>
>>
>> | since current BIOS always loads initrd below pcms->below_4g_mem_size
>>
>> I don't know why the BIOS is mentioned here. The
>> below_4g_mem_size limit comes from these 2 lines inside
>> load_linux():
>>
>> if (initrd_max >= pcms->below_4g_mem_size - pcmc->acpi_data_size) {
>> initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1;
>> }
>> In addition to that, initrd_max is uint32_t simply because QEMU
>> doesn't support the 64-bit boot protocol (specifically the
>> ext_ramdisk_image field), so all talk about below_4g_mem_size
>> seems to be just a distraction.
>>
>> All that said, I miss one piece of information here: is
>> XLF_CAN_BE_LOADED_ABOVE_4G really supposed to override
>> header+0x22c? linux/Documentation/x86/boot.txt isn't clear about
>> that. Is there any reference that can help us confirm this?
> Looking at the following patch seems that we can confirm the assumption:
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4bf7111f50167133a71c23530ca852a41355e739
>
> Note: the patch was reverted due to bugs in some firmwares, but IMHO
> the assumption is correct.
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=47226ad4f4cfd1e91ded7f2ec42f83ff1c624663
thanks for you info.
When use '-kernel vmlinux -initrd initrd.cgz' to launch a VM,
the firmware(it could be linuxboot_dma.bin) helps to read initrd
contents into guest memory(below ramdisk_max) and jump to kernel.
that's similar with what bootloader does, like grub.
And firmware can work well with some fixes in this patchset.
Zhijian
>
> Cheers,
> Stefano
>
>> --
>> Eduardo
>>
>
> .
>
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2019-01-09 6:23 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-06 2:32 [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 1/4] unify len and addr type for memory/address APIs Li Zhijian
2019-01-07 10:04 ` Stefano Garzarella
2019-01-08 1:06 ` Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 2/4] refactor load_image_size Li Zhijian
2018-12-21 16:12 ` Michael S. Tsirkin
2018-12-24 2:14 ` Li Zhijian
2019-01-07 10:33 ` Stefano Garzarella
2019-01-08 1:09 ` Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 3/4] i386: import & use bootparam.h Li Zhijian
2018-12-21 16:04 ` Michael S. Tsirkin
2019-01-04 16:41 ` Stefano Garzarella
2019-01-08 1:11 ` Li Zhijian
2018-12-06 2:32 ` [Qemu-devel] [PATCH for-4.0 v4 4/4] i386: allow to load initrd below 4G for recent linux Li Zhijian
2018-12-21 16:10 ` Michael S. Tsirkin
2018-12-27 20:31 ` Eduardo Habkost
2018-12-28 7:20 ` Li Zhijian
2019-01-07 12:11 ` Stefano Garzarella
2019-01-09 6:22 ` Li Zhijian
2019-01-07 23:35 ` Paolo Bonzini
2018-12-21 1:37 ` [Qemu-devel] [PATCH for-4.0 v4 0/4] allow to load initrd below 4G for recent kernel Li Zhijian
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).