Support for ramdisks when booting in PVH mode

Pierre Pronchery <[email protected]>
Newsgroups gmane.os.netbsd.devel.kernel
Message-ID <[email protected]>
		Hi tech-kern@,

TL;DR this adds support for booting NetBSD/amd64 with QEMU’s
-kernel/-initrd combination.

I did not exactly do a good job at pushing for reviews or setting a
deadline for my patch adding support for ramdisks when booting NetBSD/amd64
in PVH mode, and it no longer applied on -current for a while now.
(See https://mail-index.netbsd.org/tech-kern/2025/03/31/msg030298.html)

Thankfully I managed to make it work again last week-end, and I am
attaching the updated patch to this message.

Important note when testing: it works with plain filesystem images, but not
with modules yet. I suppose supporting any combination of filesystem,
modules or splash screen images could be done.

Please review; with no objections I intend to commit it around this time
next week. Thanks!

Would have been great to have this in -11, but my bad for waiting/taking
too long. Sorry!



Cheers & HTH,
-- 
khorben
patch-amd64-add-support-for-initrd-with-VM_GUEST_GENPVH.patch (application/octet-stream, 6.4 KB)
diff --git a/sys/arch/amd64/amd64/genassym.cf b/sys/arch/amd64/amd64/genassym.cf
index 92291334bc8d..9031dda6a234 100644
--- a/sys/arch/amd64/amd64/genassym.cf
+++ b/sys/arch/amd64/amd64/genassym.cf
@@ -383,6 +383,12 @@ define SIR_XENIPL_HIGH		SIR_XENIPL_HIGH
 define EVTCHN_UPCALL_MASK	offsetof(struct vcpu_info, evtchn_upcall_mask)
 define HVM_START_INFO_SIZE	sizeof(struct hvm_start_info)
 define START_INFO_VERSION	offsetof(struct hvm_start_info, version)
+define START_INFO_MODLIST_PADDR	offsetof(struct hvm_start_info, modlist_paddr)
+define START_INFO_NR_MODULES	offsetof(struct hvm_start_info, nr_modules)
+define HVM_MODLIST_ENTRY_SIZE	sizeof(struct hvm_modlist_entry)
+define MODLIST_ENTRY_CMDLINE	offsetof(struct hvm_modlist_entry, cmdline_paddr)
+define MODLIST_ENTRY_PADDR	offsetof(struct hvm_modlist_entry, paddr)
+define MODLIST_ENTRY_SIZE	offsetof(struct hvm_modlist_entry, size)
 define MMAP_PADDR		offsetof(struct hvm_start_info, memmap_paddr)
 define MMAP_ENTRIES		offsetof(struct hvm_start_info, memmap_entries)
 define MMAP_ENTRY_SIZE		sizeof(struct hvm_memmap_table_entry)
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S
index daf189b02019..24e2e5ce7c51 100644
--- a/sys/arch/amd64/amd64/locore.S
+++ b/sys/arch/amd64/amd64/locore.S
@@ -1187,7 +1187,69 @@ ENTRY(start_pvh)
 	shrl $2, %ecx
 	rep movsl
 
-	/* Copy cmdline_paddr after hvm_start_info */
+	/* Copy hvm_modlist_entry[] after hvm_start_info */
+	xor %ecx, %ecx
+	mov %ecx, START_INFO_MODLIST_PADDR(%eax)
+	movl START_INFO_NR_MODULES(%eax), %ecx	/* Get nr_modules */
+	testl %ecx, %ecx			/* if(nr_modules == 0) */
+	jz .modlist_copy_done			/*   goto modlist_copy_done */
+	movl %edi, START_INFO_MODLIST_PADDR(%eax) /* Set new modlist_paddr in hvm_start_info */
+	movl START_INFO_MODLIST_PADDR(%ebx), %esi
+	pushl %eax
+	movl $HVM_MODLIST_ENTRY_SIZE, %eax	/* eax = sizeof(hvm_modlist_entry) */
+	mull %ecx				/* eax * ecx => edx:eax */
+	movl %eax, %ecx
+	shrl $2, %ecx
+	rep movsl
+	popl %eax
+
+	/* Copy the modules after the hvm_modlist_entry[] */
+	xorl %ecx, %ecx				/* ecx = i = 0 */
+.module_copy:
+	/* eax points to our hvm_start_info */
+	/* ecx is our counter (i) */
+	/* Copy the module */
+	movl START_INFO_MODLIST_PADDR(%eax), %edx /* edx = &hvm_modlist_entry[0] */
+	pushl %eax
+	movl $HVM_MODLIST_ENTRY_SIZE, %eax	/* eax = sizeof(hvm_modlist_entry) */
+	pushl %ecx
+	pushl %edx
+	mull %ecx				/* eax * ecx => edx:eax */
+	popl %edx
+	addl %eax, %edx				/* edx = &hvm_modlist_entry[i] */
+	popl %ecx
+	/* Copy the module's cmdline */
+	movl MODLIST_ENTRY_CMDLINE(%edx), %esi
+	xorl %eax, %eax
+	movl %eax, MODLIST_ENTRY_CMDLINE(%edx)	/* hvm_modlist_entry[i].cmdline = NULL */
+	cmpl %eax, %esi
+	popl %eax
+	je .module_cmdline_copy_done
+	movl %edi, MODLIST_ENTRY_CMDLINE(%edx)	/* Set new cmdline_paddr in hvm_modlist_entry */
+	pushl %eax
+.module_cmdline_copy:
+	movb (%esi), %al
+	movsb
+	cmp $0, %al
+	jne .module_cmdline_copy
+	popl %eax
+.module_cmdline_copy_done:
+	/* Copy the module's content */
+	movl MODLIST_ENTRY_PADDR(%edx), %esi	/* esi = hvm_modlist_entry[i].paddr */
+	movl %edi, MODLIST_ENTRY_PADDR(%edx)	/* Set new paddr in hvm_modlist_entry */
+	pushl %ecx
+	movl MODLIST_ENTRY_SIZE(%edx), %ecx	/* ecx = hvm_modlist_entry[i].size */
+	rep movsb
+	popl %ecx
+	inc %ecx				/* i++ */
+	pushl %eax
+	movl START_INFO_NR_MODULES(%ebx), %eax	/* eax = nr_modules */
+	cmpl %eax, %ecx				/* if (ecx != nr_modules) */
+	popl %eax
+	jne .module_copy			/*   goto module_copy */
+.modlist_copy_done:
+
+	/* Copy cmdline_paddr after the modules */
 	movl CMDLINE_PADDR(%ebx), %esi
 	movl %edi, CMDLINE_PADDR(%eax)	/* Set new cmdline_paddr in hvm_start_info */
 .cmdline_copy:
diff --git a/sys/arch/amd64/conf/MICROVM b/sys/arch/amd64/conf/MICROVM
index 37724ecafde6..242a06848527 100644
--- a/sys/arch/amd64/conf/MICROVM
+++ b/sys/arch/amd64/conf/MICROVM
@@ -23,3 +23,7 @@ machine amd64 x86 xen
 include         "arch/x86/conf/MICROVM.common"
 
 options         EXEC_ELF64      # exec ELF binaries
+options 	MODULAR		# new style module(7) framework
+
+options 	MEMORY_DISK_HOOKS	# enable md specific hooks
+options 	MEMORY_DISK_DYNAMIC	# enable dynamic resizing
diff --git a/sys/arch/x86/x86/x86_machdep.c b/sys/arch/x86/x86/x86_machdep.c
index bb82cdd451cf..5621fa543d1f 100644
--- a/sys/arch/x86/x86/x86_machdep.c
+++ b/sys/arch/x86/x86/x86_machdep.c
@@ -215,6 +215,62 @@ mm_md_physacc(paddr_t pa, vm_prot_t prot)
 }
 
 #ifdef MODULAR
+#ifdef XEN
+void x86_add_xen_modules(void);
+void
+x86_add_xen_modules(void)
+{
+#if defined(XENPVHVM) || defined(XENPVH)
+	uint32_t i;
+	struct hvm_modlist_entry *modlist;
+
+	if (hvm_start_info->nr_modules == 0) {
+		aprint_verbose("No Xen module info at boot\n");
+		return;
+	}
+	aprint_debug("%d Xen module(s) at boot\n", hvm_start_info->nr_modules);
+	modlist = (void *)((uintptr_t)hvm_start_info->modlist_paddr + KERNBASE);
+	for (i = 0; i < hvm_start_info->nr_modules; i++) {
+		if (memcmp(
+			    (char *)((uintptr_t)modlist[i].paddr + KERNBASE),
+			    "\177ELF", 4) == 0) {
+			aprint_debug("Prep module path=%s len=%"PRIu64" pa=%p\n",
+			    "pvh-module",
+			    modlist[i].size,
+			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE));
+			module_prime(
+			    "pvh-module",
+			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE),
+			    modlist[i].size);
+#ifdef SPLASHSCREEN
+		} else if (memcmp(
+			    (char *)((uintptr_t)modlist[i].paddr + KERNBASE),
+			    "\211PNG\r\n\032\n", 8) == 0 ||
+			   memcmp(
+			    (char *)((uintptr_t)modlist[i].paddr + KERNBASE),
+			    "\377\330\377", 3) == 0) {
+			aprint_debug("Splash image path=%s len=%"PRIu64" pa=%p\n",
+			    "pvh-image", modlist[i].size,
+			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE));
+			splash_setimage(
+			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE),
+			    modlist[i].size);
+#endif
+#if defined(MEMORY_DISK_HOOKS) && defined(MEMORY_DISK_DYNAMIC)
+		} else {
+			aprint_debug("File-system image path=%s len=%"PRIu64" pa=%p\n",
+			    "pvh-filesystem",
+			    modlist[i].size,
+			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE));
+			md_root_setconf(
+			    (void *)((uintptr_t)modlist[i].paddr + KERNBASE),
+			    modlist[i].size);
+#endif
+		}
+	}
+#endif
+}
+#endif	/* XEN */
 /*
  * Push any modules loaded by the boot loader.
  */
@@ -922,6 +978,9 @@ init_x86_clusters(void)
 #ifdef XEN
 	if (pvh_boot) {
 		x86_add_xen_clusters();
+#ifdef MODULAR
+		x86_add_xen_modules();
+#endif
 	}
 #endif /* XEN */
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEjPEp1wC4bxBrX8svMDjL25iGlwMFAmknKHUACgkQMDjL25iG
lwPE8g/9GCJqAwYZNVA4sPMEymVTmWPA9SAlwIWEGDAx9Bq8jYScSln+q+9djVQg
sOmYjkuI1h/PDYXwEnljBotqW6MYWzV7kb9SEb6exEFoIzVVfFImqhZF1STs2Wll
Ncfa2K3HEB5e/7luCK3DI5G9Dh07SxumQjRnWg8Wgyhak0aLNsTrlnm44lGnt0nn
0lAjf14K1FVLtIXqgmW0ipw2Ry0w6nXIdoeMXXkU+QP71Fktyt5TUIoInZUgoDXi
G9L6swwSpkLgM1WMKTZXurs97BdEPVSIrCSmIKXZbknt+hIotuvQQy+mRqoPG/xa
gwtPsYlETnJ7y3FgYoL/YYrTapn6U5H5ikvQbNZSRe5c+OwC3K/5xMQTcadP4y3j
eheUThiYevpuAnYEdj0Cbj1QzDueq7Q9K7DTaKOwv+hRX+ZtwQlNG2HoArZXyF90
1z1zT9eEitvHJw6Sp7PMRC28PiWobIPnTHDyM27OF5GOij7sgqLauGCzmcQEZpIo
XPCOr8XFSAtZ4/EnKXRGyp2j2KhF9Bvn22gbTG3SFy7efMPLZ2XxnjgCkGEwA+oJ
ZCVbRwWEfhiGbdrrts5zGiWBsBMEaMuGrjVxdDunEwj3b7thAZbfSjqjnlTqioBu
xlz/TGeUjwhsNQpLklIKaIF4bmnc3xAlJyiU2xj2gXDsw5RPDcY=
=1CjS
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.