- 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)
96 lines
3.4 KiB
Diff
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
|
|
|