qemu/hw-loongarch-boot-Adjust-the-loading-position-of-the.patch
Jiabo Feng b60d6a584c QEMU update to version 8.2.0-32:
- target/i386: csv: Release CSV3 shared pages after unmapping DMA
- target/i386: Add new CPU model ClearwaterForest
- target/i386: add sha512, sm3, sm4 feature bits
- docs: Add GNR, SRF and CWF CPU models
- target/i386: Export BHI_NO bit to guests
- target/i386: Introduce SierraForest-v2 model
- vdpa/iommufd:Implement DMA mapping through the iommufd interface
- vdpa/iommufd:Introduce vdpa-iommufd module
- vdpa/iommufd:support associating iommufd backend for vDPA devices
- Kconfig/iommufd/VDPA: Update IOMMUFD module configuration dependencies The vDPA module can also use IOMMUFD like the VFIO module.
- backends/iommufd: Get rid of qemu_open_old()
- backends/iommufd: Make iommufd_backend_*() return bool
- backends/iommufd: Fix missing ERRP_GUARD() for error_prepend()
- backends/iommufd: Remove mutex
- backends/iommufd: Remove check on number of backend users
- hw/intc: Add extioi ability of 256 vcpu interrupt routing
- hw/rtc: Fixed loongson rtc emulation errors
- hw/loongarch/boot: Adjust the loading position of the initrd
- target/loongarch: Fix the cpu unplug resource leak
- target/loongarch: fix vcpu reset command word issue
- vdpa:Fix dirty page bitmap synchronization not done after suspend for vdpa devices

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit a5212066e7516ff2a316e1b2feaa75dd5ee4d17a)
2025-05-15 17:01:38 +08:00

96 lines
3.4 KiB
Diff

From 16670675cbf7fc4db147a698ba7787d2e2fa675b Mon Sep 17 00:00:00 2001
From: Xianglai Li <lixianglai@loongson.cn>
Date: Wed, 26 Mar 2025 17:02:37 +0800
Subject: [PATCH] hw/loongarch/boot: Adjust the loading position of the initrd
When only the -kernel parameter is used to load the elf kernel,
the initrd is loaded in the ram. If the initrd size is too large,
the loading fails, resulting in a VM startup failure.
This patch first loads initrd near the kernel.
When the nearby memory space of the kernel is insufficient,
it tries to load it to the starting position of high memory.
If there is still not enough, qemu will report an error
and ask the user to increase the memory space for the
virtual machine to boot.
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
---
hw/loongarch/boot.c | 53 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 44 insertions(+), 9 deletions(-)
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 53dcefbb55..39c4a6d8c6 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -171,6 +171,48 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
}
+static void find_initrd_loadoffset(struct loongarch_boot_info *info,
+ uint64_t kernel_high, ssize_t kernel_size)
+{
+ hwaddr base, size, gap, low_end;
+ ram_addr_t initrd_end, initrd_start;
+
+ base = VIRT_LOWMEM_BASE;
+ gap = VIRT_LOWMEM_SIZE;
+ initrd_start = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB);
+ initrd_end = initrd_start + initrd_size;
+
+ size = info->ram_size;
+ low_end = base + MIN(size, gap);
+ if (initrd_end <= low_end) {
+ initrd_offset = initrd_start;
+ return;
+ }
+
+ if (size <= gap) {
+ error_report("The low memory too small for initial ram disk '%s',"
+ "You need to expand the memory space",
+ info->initrd_filename);
+ exit(1);
+ }
+
+ /*
+ * Try to load initrd in the high memory
+ */
+ size -= gap;
+ base = VIRT_HIGHMEM_BASE;
+ initrd_start = ROUND_UP(base, 64 * KiB);
+ if (initrd_size <= size) {
+ initrd_offset = initrd_start;
+ return;
+ }
+
+ error_report("The high memory too small for initial ram disk '%s',"
+ "You need to expand the memory space",
+ info->initrd_filename);
+ exit(1);
+}
+
static int64_t load_kernel_info(struct loongarch_boot_info *info)
{
uint64_t kernel_entry, kernel_low, kernel_high;
@@ -192,16 +234,9 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
if (info->initrd_filename) {
initrd_size = get_image_size(info->initrd_filename);
if (initrd_size > 0) {
- initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB);
-
- if (initrd_offset + initrd_size > info->ram_size) {
- error_report("memory too small for initial ram disk '%s'",
- info->initrd_filename);
- exit(1);
- }
-
+ find_initrd_loadoffset(info, kernel_high, kernel_size);
initrd_size = load_image_targphys(info->initrd_filename, initrd_offset,
- info->ram_size - initrd_offset);
+ initrd_size);
}
if (initrd_size == (target_ulong)-1) {
--
2.41.0.windows.1