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 */
 
