diff -r -u nvmm-official/src/driver/nvmm.c dfbsd/nvmm-dfbsd/src/driver/nvmm.c
--- nvmm-official/src/driver/nvmm.c	2021-01-17 11:20:49.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/nvmm.c	2021-01-27 16:22:08.566328000 +0100
@@ -1028,6 +1028,142 @@
 
 /* -------------------------------------------------------------------------- */
 
+#if defined(__DragonFly__)
+#include <sys/devfs.h>
+
+MALLOC_DEFINE(M_NVMM, "NVMM-related data", "NVMM-related data");
+DEVFS_DEFINE_CLONE_BITMAP(nvmm);
+
+/*
+ * This gets called unconditionally by the kernel, right after
+ * nvmm_close_devop().
+ */
+static void
+dfbsd_nvmm_cdevpriv_dtor(void *cd)
+{
+	struct nvmm_owner *owner = cd;
+
+	if (owner != &root_owner) {
+		os_mem_free(owner, sizeof(*owner));
+		kprintf("%s: freed\n", __func__);
+	}
+}
+
+static int
+dfbsd_nvmm_open(struct dev_open_args *ap)
+{
+	int flags = ap->a_oflags;
+	struct file *fp = ap->a_fp;
+	struct nvmm_owner *owner;
+
+	kprintf("%s: called\n", __func__);
+
+	if (__predict_false(nvmm_impl == NULL))
+		return ENXIO;
+	if (!(flags & O_CLOEXEC))
+		return EINVAL;
+
+	if (OFLAGS(flags) & O_WRONLY) {
+		owner = &root_owner;
+	} else {
+		owner = os_mem_alloc(sizeof(*owner));
+		owner->pid = curthread->td_proc->p_pid;
+	}
+
+	devfs_set_cdevpriv(fp, owner, dfbsd_nvmm_cdevpriv_dtor);
+
+	return 0;
+}
+
+static int
+dfbsd_nvmm_ioctl(struct dev_ioctl_args *ap)
+{
+	struct nvmm_owner *owner = NULL;
+
+	devfs_get_cdevpriv(ap->a_fp, (void **)&owner);
+
+	OS_ASSERT(owner != NULL);
+
+	return nvmm_ioctl(owner, ap->a_cmd, ap->a_data);
+}
+
+static int
+dfbsd_nvmm_close(struct dev_close_args *ap)
+{
+	int uminor_no = minor(ap->a_head.a_dev);
+	struct nvmm_owner *owner = NULL;
+
+	devfs_get_cdevpriv(ap->a_fp, (void **)&owner);
+
+	kprintf("%s: called, owner=%p\n", __func__, owner);
+
+	OS_ASSERT(owner != NULL);
+	nvmm_kill_machines(owner);
+
+	destroy_dev(ap->a_head.a_dev);
+	devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(nvmm), uminor_no);
+
+	return 0;
+}
+
+static int
+dfbsd_nvmm_mmap(struct dev_mmap_args *ap)
+{
+	return ENODEV;
+}
+
+static int
+dfbsd_nvmm_mmap_single(struct dev_mmap_single_args *ap)
+{
+	return ENODEV;
+}
+
+static struct dev_ops dfbsd_nvmm_ops = {
+	{ "nvmm", 0, D_MPSAFE },
+	.d_open = dfbsd_nvmm_open,
+	.d_ioctl = dfbsd_nvmm_ioctl,
+	.d_close = dfbsd_nvmm_close,
+	.d_mmap = dfbsd_nvmm_mmap,
+	.d_mmap_single = dfbsd_nvmm_mmap_single,
+};
+
+static int
+dfbsd_nvmm_clone(struct dev_clone_args *ap)
+{
+	int unit;
+
+	unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(nvmm),
+	    NVMM_MAX_MACHINES);
+	if (unit < 0) {
+		ap->a_dev = NULL;
+		return 1;
+	}
+
+	/*
+	 * The cloning bitmap should guarantee isolation during
+	 * initialization. No need to create a devfs node.
+	 */
+	ap->a_dev = make_only_dev(&dfbsd_nvmm_ops, unit,
+	    ap->a_cred->cr_ruid, 0, 0600, "nvmm%d", unit);
+
+	return 0;
+}
+
+static void
+dfbsd_nvmm_init(void)
+{
+	make_autoclone_dev(&dfbsd_nvmm_ops, &DEVFS_CLONE_BITMAP(nvmm),
+	    dfbsd_nvmm_clone, 0, 0, 0640, "nvmm");
+	(void)nvmm_init();
+}
+
+SYSINIT(nvmmdev, SI_SUB_DRIVERS, SI_ORDER_LATER, dfbsd_nvmm_init, NULL);
+SYSUNINIT(nvmmdev, SI_SUB_DRIVERS, SI_ORDER_LATER, nvmm_fini, NULL);
+
+#endif /* __DragonFly__ */
+
+/* -------------------------------------------------------------------------- */
+
 #if defined(__NetBSD__)
 static dev_type_open(nbsd_nvmm_open);
 static int nbsd_nvmm_ioctl(file_t *, u_long, void *);
diff -r -u nvmm-official/src/driver/nvmm.h dfbsd/nvmm-dfbsd/src/driver/nvmm.h
--- nvmm-official/src/driver/nvmm.h	2021-01-03 10:43:03.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/nvmm.h	2021-01-03 10:58:40.301067000 +0100
@@ -50,6 +50,8 @@
 #if defined(__x86_64__)
 #if defined(__NetBSD__)
 #include <dev/nvmm/x86/nvmm_x86.h>
+#elif defined(__DragonFly__)
+#include <dev/virtual/nvmm/x86/nvmm_x86.h>
 #endif
 #endif /* __x86_64__ */
 
diff -r -u nvmm-official/src/driver/nvmm_internal.h dfbsd/nvmm-dfbsd/src/driver/nvmm_internal.h
--- nvmm-official/src/driver/nvmm_internal.h	2021-01-03 10:43:03.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/nvmm_internal.h	2021-01-03 10:58:49.436880000 +0100
@@ -31,6 +31,8 @@
 
 #if defined(__NetBSD__)
 #include <dev/nvmm/nvmm_os.h>
+#elif defined(__DragonFly__)
+#include <dev/virtual/nvmm/nvmm_os.h>
 #endif
 
 #define NVMM_MAX_MACHINES	128
diff -r -u nvmm-official/src/driver/nvmm_ioctl.h dfbsd/nvmm-dfbsd/src/driver/nvmm_ioctl.h
--- nvmm-official/src/driver/nvmm_ioctl.h	2021-01-03 10:43:03.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/nvmm_ioctl.h	2021-01-03 10:58:58.014705000 +0100
@@ -33,6 +33,8 @@
 
 #if defined(__NetBSD__)
 #include <dev/nvmm/nvmm.h>
+#elif defined(__DragonFly__)
+#include <dev/virtual/nvmm/nvmm.h>
 #endif
 
 struct nvmm_ioc_capability {
diff -r -u nvmm-official/src/driver/nvmm_os.c dfbsd/nvmm-dfbsd/src/driver/nvmm_os.c
--- nvmm-official/src/driver/nvmm_os.c	2021-01-03 11:06:27.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/nvmm_os.c	2021-01-28 08:43:46.905582000 +0100
@@ -35,6 +35,8 @@
 
 #if defined(__NetBSD__)
 #include <dev/nvmm/nvmm_os.h>
+#elif defined(__DragonFly__)
+#include <dev/virtual/nvmm/nvmm_os.h>
 #endif
 
 os_vmspace_t *
@@ -42,6 +44,8 @@
 {
 #if defined(__NetBSD__)
 	return uvmspace_alloc(vmin, vmax, false);
+#elif defined(__DragonFly__)
+	return vmspace_alloc(vmin, vmax);
 #endif
 }
 
@@ -50,6 +54,8 @@
 {
 #if defined(__NetBSD__)
 	uvmspace_free(vm);
+#elif defined(__DragonFly__)
+	vmspace_rel(vm);
 #endif
 }
 
@@ -58,6 +64,8 @@
 {
 #if defined(__NetBSD__)
 	return uvm_fault(&vm->vm_map, va, prot);
+#elif defined(__DragonFly__)
+	return vm_fault(&vm->vm_map, va, prot, 0);
 #endif
 }
 
@@ -66,6 +74,8 @@
 {
 #if defined(__NetBSD__)
 	return uao_create(size, 0);
+#elif defined(__DragonFly__)
+	return vm_object_allocate(OBJT_DEFAULT, size / PAGE_SIZE);
 #endif
 }
 
@@ -74,6 +84,10 @@
 {
 #if defined(__NetBSD__)
 	uao_reference(vmobj);
+#elif defined(__DragonFly__)
+	VM_OBJECT_LOCK(vmobj);
+	vm_object_reference_locked(vmobj);
+	VM_OBJECT_UNLOCK(vmobj);
 #endif
 }
 
@@ -82,6 +96,8 @@
 {
 #if defined(__NetBSD__)
 	uao_detach(vmobj);
+#elif defined(__DragonFly__)
+	vm_object_deallocate(vmobj);
 #endif
 }
 
@@ -149,6 +165,44 @@
 	}
 
 	return 0;
+#elif defined(__DragonFly__)
+	int rv;
+
+	/* Get a reference to the object. */
+	os_vmobj_ref(vmobj);
+
+	/*
+	 * Map the object. This consumes the reference on success only. On
+	 * failure we must drop the reference manually.
+	 */
+	rv = vm_map_find(map, vmobj, NULL, uoffset, addr, size,
+	    PAGE_SIZE, !fixed, VM_MAPTYPE_NORMAL, VM_SUBSYS_UNKNOWN /* XXX */,
+	    prot, maxprot, 0);
+	if (rv != KERN_SUCCESS) {
+		/* Drop the ref. */
+		os_vmobj_rel(vmobj);
+		return EINVAL;
+	}
+
+	if (shared) {
+		rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE);
+		if (rv != KERN_SUCCESS) {
+			/* Unmap. */
+			vm_map_remove(map, *addr, *addr + size);
+			return EINVAL;
+		}
+	}
+
+	if (wired) {
+		rv = vm_map_unwire(map, *addr, *addr + size, false);
+		if (rv != KERN_SUCCESS) {
+			/* Unmap. */
+			vm_map_remove(map, *addr, *addr + size);
+			return EINVAL;
+		}
+	}
+
+	return 0;
 #endif
 }
 
@@ -157,6 +211,8 @@
 {
 #if defined(__NetBSD__)
 	uvm_unmap(map, start, end);
+#elif defined(__DragonFly__)
+	vm_map_remove(map, start, end);
 #endif
 }
 
@@ -168,6 +224,9 @@
 #if defined(__NetBSD__)
 	ret = (void *)uvm_km_alloc(kernel_map, roundup(size, PAGE_SIZE), 0,
 	    UVM_KMF_WIRED | UVM_KMF_ZERO);
+#elif defined(__DragonFly__)
+	ret = (void *)kmalloc(roundup(size, PAGE_SIZE), M_NVMM,
+	    M_WAITOK | M_ZERO);
 #endif
 
 	OS_ASSERT((uintptr_t)ret % PAGE_SIZE == 0);
@@ -181,6 +240,8 @@
 #if defined(__NetBSD__)
 	uvm_km_free(kernel_map, (vaddr_t)ptr, roundup(size, PAGE_SIZE),
 	    UVM_KMF_WIRED);
+#elif defined(__DragonFly__)
+	kfree(ptr, M_NVMM);
 #endif
 }
 
@@ -192,6 +253,11 @@
 
 	pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
 	return VM_PAGE_TO_PHYS(pg);
+#elif defined(__DragonFly__)
+	vm_page_t pg;
+
+	pg = vm_page_alloc(NULL, 0, VM_ALLOC_FORCE_ZERO | VM_ALLOC_NORMAL);
+	return VM_PAGE_TO_PHYS(pg);
 #endif
 }
 
@@ -200,6 +266,8 @@
 {
 #if defined(__NetBSD__)
 	uvm_pagefree(PHYS_TO_VM_PAGE(pa));
+#elif defined(__DragonFly__)
+	vm_page_free_toq(PHYS_TO_VM_PAGE(pa));
 #endif
 }
 
@@ -240,6 +308,11 @@
 		uvm_pagefree(PHYS_TO_VM_PAGE(_pa + i * PAGE_SIZE));
 	}
 	return ENOMEM;
+#elif defined(__DragonFly__)
+	*va = (vaddr_t)contigmalloc(npages * PAGE_SIZE, M_NVMM,
+	    M_WAITOK | M_ZERO, 0, 0xFFFFFFFFFFFFFFFFULL, npages * PAGE_SIZE, 0);
+	*pa = vtophys(*va);
+	return 0;
 #endif
 }
 
@@ -255,5 +328,7 @@
 	for (i = 0; i < npages; i++) {
 		uvm_pagefree(PHYS_TO_VM_PAGE(pa + i * PAGE_SIZE));
 	}
+#elif defined(__DragonFly__)
+	contigfree((void *)va, npages * PAGE_SIZE, M_TEMP);
 #endif
 }
diff -r -u nvmm-official/src/driver/nvmm_os.h dfbsd/nvmm-dfbsd/src/driver/nvmm_os.h
--- nvmm-official/src/driver/nvmm_os.h	2021-01-03 11:09:39.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/nvmm_os.h	2021-01-03 11:13:03.726447000 +0100
@@ -35,23 +35,60 @@
 #include <uvm/uvm_page.h>
 #endif
 
+#if defined(__DragonFly__)
+#include <sys/mutex2.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_param.h>
+#endif
+
 /* Types. */
 #if defined(__NetBSD__)
 typedef struct vmspace		os_vmspace_t;
 typedef struct uvm_object	os_vmobj_t;
 typedef krwlock_t		os_rwl_t;
 typedef kmutex_t		os_mtx_t;
+#elif defined(__DragonFly__)
+typedef struct vmspace		os_vmspace_t;
+typedef struct vm_object	os_vmobj_t;
+typedef struct mtx		os_rwl_t;
+typedef struct mtx		os_mtx_t;
+/* A few standard types. */
+typedef vm_offset_t		vaddr_t;
+typedef vm_offset_t		voff_t;
+typedef vm_size_t		vsize_t;
+typedef vm_paddr_t		paddr_t;
+#endif
+
+/* Attributes. */
+#if defined(__DragonFly__)
+#define __cacheline_aligned	__cachealign
+#define __diagused		__unused
+#endif
+
+/* Macros. */
+#if defined(__DragonFly__)
+#define __arraycount(__x)	(sizeof(__x) / sizeof(__x[0]))
+#define __insn_barrier()	__asm __volatile("":::"memory")
 #endif
 
 /* Bitops. */
 #if defined(__NetBSD__)
 #include <sys/bitops.h>
+#elif defined(__DragonFly__)
+#include <sys/bitops.h>
+/* DragonFly bitops have separate 32-bit __BIT() and a 64-bit __BIT64() */
+#undef __BIT
+#define __BIT(__x)		__BIT64(__x)
 #endif
 
 /* Maps. */
 #if defined(__NetBSD__)
 #define os_kernel_map		kernel_map
 #define os_curproc_map		&curproc->p_vmspace->vm_map
+#elif defined(__DragonFly__)
+#define os_kernel_map		&kernel_map
+#define os_curproc_map		&curproc->p_vmspace->vm_map
 #endif
 
 /* R/W locks. */
@@ -62,6 +99,13 @@
 #define os_rwl_wlock(lock)	rw_enter(lock, RW_WRITER);
 #define os_rwl_unlock(lock)	rw_exit(lock)
 #define os_rwl_wheld(lock)	rw_write_held(lock)
+#elif defined(__DragonFly__)
+#define os_rwl_init(lock)	mtx_init(lock, "nvmmrw")
+#define os_rwl_destroy(lock)	mtx_uninit(lock);
+#define os_rwl_rlock(lock)	mtx_lock_sh(lock, 0, 0);
+#define os_rwl_wlock(lock)	mtx_lock_ex(lock, 0, 0);
+#define os_rwl_unlock(lock)	mtx_unlock(lock)
+#define os_rwl_wheld(lock)	mtx_islocked_ex(lock)
 #endif
 
 /* Mutexes. */
@@ -71,6 +115,12 @@
 #define os_mtx_lock(lock)	mutex_enter(lock)
 #define os_mtx_unlock(lock)	mutex_exit(lock)
 #define os_mtx_owned(lock)	mutex_owned(lock)
+#elif defined(__DragonFly__)
+#define os_mtx_init(lock)	mtx_init(lock, "nvmmmtx")
+#define os_mtx_destroy(lock)	mtx_uninit(lock);
+#define os_mtx_lock(lock)	mtx_lock(lock)
+#define os_mtx_unlock(lock)	mtx_unlock(lock)
+#define os_mtx_owned(lock)	mtx_owned(lock)
 #endif
 
 /* Malloc. */
@@ -79,11 +129,19 @@
 #define os_mem_alloc(size)	kmem_alloc(size, KM_SLEEP)
 #define os_mem_zalloc(size)	kmem_zalloc(size, KM_SLEEP)
 #define os_mem_free(ptr, size)	kmem_free(ptr, size)
+#elif defined(__DragonFly__)
+#include <sys/malloc.h>
+MALLOC_DECLARE(M_NVMM);
+#define os_mem_alloc(size)	kmalloc(size, M_NVMM, M_WAITOK);
+#define os_mem_zalloc(size)	kmalloc(size, M_NVMM, M_WAITOK | M_ZERO);
+#define os_mem_free(ptr, size)	kfree(ptr, M_NVMM)
 #endif
 
 /* Printf. */
 #if defined(__NetBSD__)
 #define os_printf		printf
+#elif defined(__DragonFly__)
+#define os_printf		kprintf
 #endif
 
 /* Atomics. */
@@ -93,12 +151,19 @@
 #define os_atomic_dec_uint(x)	atomic_dec_uint(x)
 #define os_atomic_load_uint(x)	atomic_load_relaxed(x)
 #define os_atomic_inc_64(x)	atomic_inc_64(x)
+#elif defined(__DragonFly__)
+#define os_atomic_inc_uint(x)	atomic_add_int(x, 1)
+#define os_atomic_dec_uint(x)	atomic_subtract_int(x, 1)
+#define os_atomic_load_uint(x)	*(x) /* XXX XXX XXX */
+#define os_atomic_inc_64(x)	atomic_add_64(x, 1)
 #endif
 
 /* Pmap. */
 #if defined(__NetBSD__)
 #define os_vmspace_pdirpa(vm)	((vm)->vm_map.pmap->pm_pdirpa[0])
 #define os_pmap_mach(pm)	((pm)->pm_data)
+#elif defined(__DragonFly__)
+#define os_vmspace_pdirpa(vm)	vtophys((vm)->vm_map.pmap->pm_pml4)
 #endif
 
 /* CPU. */
@@ -114,6 +179,14 @@
 #define os_curcpu_tss()		curcpu()->ci_tss
 #define os_curcpu_gdt()		curcpu()->ci_gdt
 #define os_curcpu_idt()		curcpu()->ci_idtvec.iv_idt
+#elif defined(__DragonFly__)
+typedef struct globaldata	os_cpu_t;
+#define OS_MAXCPUS		SMP_MAXCPU
+#define OS_CPU_FOREACH(cpu)	\
+	for (int idx = 0; idx < ncpus && (cpu = globaldata_find(idx)); idx++)
+#define os_cpu_number(cpu)	(cpu)->gd_cpuid
+#define os_curcpu()		mycpu
+#define os_curcpu_number()	os_cpu_number(os_curcpu())
 #endif
 
 /* Cpusets. */
@@ -131,11 +204,22 @@
 #define os_preempt_disable()	kpreempt_disable()
 #define os_preempt_enable()	kpreempt_enable()
 #define os_preempt_disabled()	kpreempt_disabled()
+#elif defined(__DragonFly__)
+#define os_preempt_disable()	crit_enter()
+#define os_preempt_enable()	crit_exit()
+#define os_preempt_disabled()	crit_test(curthread)
 #endif
 
 /* Asserts. */
 #if defined(__NetBSD__)
 #define OS_ASSERT		KASSERT
+#elif defined(__DragonFly__)
+#define OS_ASSERT		KKASSERT
+#endif
+
+/* Misc. */
+#if defined(__DragonFly__)
+#define uimin(a, b)		((u_int)a < (u_int)b ? (u_int)a : (u_int)b)
 #endif
 
 os_vmspace_t *	os_vmspace_create(vaddr_t, vaddr_t);
@@ -170,6 +254,9 @@
 		return true;
 	}
 	return false;
+#elif defined(__DragonFly__)
+	/* XXX XXX XXX */
+	return true;
 #endif
 }
 
@@ -196,6 +283,18 @@
 	 */
 	pmap_tlb_shootdown(pmap_kernel(), -1, PTE_G, TLBSHOOT_NVMM);
 }
+#elif defined(__DragonFly__)
+#define OS_IPI_FUNC(func)	void func(void *arg)
+static inline void
+os_ipi_unicast(os_cpu_t *cpu, void (*func)(void *, void *), void *arg)
+{
+	/* TODO */
+}
+static inline void
+os_ipi_broadcast(void (*func)(void *), void *arg)
+{
+	lwkt_cpusync_simple(smp_active_mask, func, arg);
+}
 #endif
 
 #endif /* _NVMM_IOCTL_H_ */
diff -r -u nvmm-official/src/driver/x86/nvmm_x86.h dfbsd/nvmm-dfbsd/src/driver/x86/nvmm_x86.h
--- nvmm-official/src/driver/x86/nvmm_x86.h	2021-01-17 11:22:37.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/driver/x86/nvmm_x86.h	2021-01-30 16:10:55.104444000 +0100
@@ -642,6 +642,85 @@
 
 /* -------------------------------------------------------------------------- */
 
+/*
+ * Register defines. We mainly rely on the already-existing OS definitions.
+ */
+
+/* CR0. */
+#if defined(__DragonFly__)
+#define CR0_ET			0x00000010
+#endif
+
+/* CR4. */
+#if defined(__DragonFly__)
+#define CR4_OSFXSR		CR4_FXSR
+#define CR4_OSXMMEXCPT		CR4_XMM
+#define CR4_UMIP		0x00000800
+#define CR4_FSGSBASE		0x00010000
+#define CR4_PCIDE		0x00020000
+#define CR4_OSXSAVE		CR4_XSAVE
+#endif
+
+/* XCR0. */
+#if defined(__DragonFly__)
+#define XCR0_X87		0x00000001
+#define XCR0_SSE		0x00000002
+#endif
+
+/* EFER. */
+#if defined(__DragonFly__)
+#define 	EFER_FFXSR	0x00004000
+#define 	EFER_TCE	0x00008000
+#endif
+
+/* Misc MSRs. */
+#if defined(__DragonFly__)
+#define MSR_NB_CFG	0xc001001f
+#define 	NB_CFG_DISIOREQLOCK	0x0000000000000008ULL
+#define 	NB_CFG_DISDATMSK	0x0000001000000000ULL
+#define 	NB_CFG_INITAPICCPUIDLO	(1ULL << 54)
+#define MSR_IC_CFG	0xc0011021
+#define 	IC_CFG_DIS_SEQ_PREFETCH	0x00000800
+#define 	IC_CFG_DIS_IND		0x00004000
+#define 	IC_CFG_ERRATA_776	__BIT(26)
+#define MSR_DE_CFG	0xc0011029
+#define 	DE_CFG_ERRATA_721	0x00000001
+#define 	DE_CFG_LFENCE_SERIALIZE	__BIT(1)
+#define 	DE_CFG_ERRATA_1021	__BIT(13)
+#define MSR_UCODE_AMD_PATCHLEVEL	0x0000008b
+#define MSR_MISC_ENABLE		MSR_IA32_MISC_ENABLE
+#define 	IA32_MISC_FAST_STR_EN	__BIT(0)
+#define 	IA32_MISC_ATCC_EN	__BIT(3)
+#define 	IA32_MISC_PERFMON_EN	__BIT(7)
+#define 	IA32_MISC_BTS_UNAVAIL	__BIT(11)
+#define 	IA32_MISC_PEBS_UNAVAIL	__BIT(12)
+#define 	IA32_MISC_EISST_EN	__BIT(16)
+#define 	IA32_MISC_MWAIT_EN	__BIT(18)
+#define 	IA32_MISC_LIMIT_CPUID	__BIT(22)
+#define 	IA32_MISC_XTPR_DIS	__BIT(23)
+#define 	IA32_MISC_XD_DIS	__BIT(34)
+#define MSR_IA32_FLUSH_CMD	0x10b
+#define 	IA32_FLUSH_CMD_L1D_FLUSH 0x01
+#define MSR_IA32_ARCH_CAPABILITIES 0x10a
+#define 	IA32_ARCH_RDCL_NO	0x01
+#define 	IA32_ARCH_IBRS_ALL	0x02
+#define 	IA32_ARCH_RSBA		0x04
+#define 	IA32_ARCH_SKIP_L1DFL_VMENTRY 0x08
+#define 	IA32_ARCH_SSB_NO	0x10
+#define 	IA32_ARCH_MDS_NO	0x20
+#define 	IA32_ARCH_IF_PSCHANGE_MC_NO 0x40
+#define 	IA32_ARCH_TSX_CTRL	0x80
+#define 	IA32_ARCH_TAA_NO	0x100
+#define MSR_CR_PAT		MSR_PAT
+#define MSR_SFMASK		MSR_SF_MASK
+#define MSR_KERNELGSBASE	MSR_KGSBASE
+#define MSR_SYSENTER_CS		MSR_SYSENTER_CS_MSR
+#define MSR_SYSENTER_ESP	MSR_SYSENTER_ESP_MSR
+#define MSR_SYSENTER_EIP	MSR_SYSENTER_EIP_MSR
+#endif
+
+/* -------------------------------------------------------------------------- */
+
 #ifdef _KERNEL
 #define NVMM_X86_MACH_NCONF	0
 #define NVMM_X86_VCPU_NCONF	2
@@ -684,6 +763,9 @@
 #if defined(__NetBSD__)
 #define x86_get_cpuid(l, d)	x86_cpuid(l, (uint32_t *)d)
 #define x86_get_cpuid2(l, c, d)	x86_cpuid2(l, c, (uint32_t *)d)
+#elif defined(__DragonFly__)
+#define x86_get_cpuid(l, d)	cpuid_count(l, 0, (uint32_t *)d)
+#define x86_get_cpuid2(l, c, d)	cpuid_count(l, c, (uint32_t *)d)
 #endif
 
 /* Control registers. */
@@ -695,6 +777,18 @@
 #define x86_set_cr0(v)		lcr0(v)
 #define x86_set_cr2(v)		lcr2(v)
 #define x86_set_cr4(v)		lcr4(v)
+#elif defined(__DragonFly__)
+static __inline void
+load_cr2(u_long val)
+{
+	__asm __volatile("movq %0,%%cr2" : : "r" (val) : "memory");
+}
+#define x86_get_cr0()		rcr0()
+#define x86_get_cr2()		rcr2()
+#define x86_get_cr4()		rcr4()
+#define x86_set_cr0(v)		load_cr0(v)
+#define x86_set_cr2(v)		load_cr2(v)
+#define x86_set_cr4(v)		load_cr4(v)
 #endif
 
 /* Debug registers. */
@@ -714,6 +808,55 @@
 #define x86_set_dr3(v)		ldr3(v)
 #define x86_set_dr6(v)		ldr6(v)
 #define x86_set_dr7(v)		ldr7(v)
+#elif defined(__DragonFly__)
+static inline void
+x86_curthread_save_dbregs(void)
+{
+	/*
+	 * Nothing to do: the kernel maintains the dbregs values in the pcb, so
+	 * no point saving them, they are already there.
+	 */
+#if 0
+	struct pcb *pcb = curthread->td_lwp->lwp_thread->td_pcb;
+
+	if (__predict_true(!(pcb->pcb_flags & PCB_DBREGS)))
+		return;
+
+	pcb->pcb_dr0 = rdr0();
+	pcb->pcb_dr1 = rdr1();
+	pcb->pcb_dr2 = rdr2();
+	pcb->pcb_dr3 = rdr3();
+	pcb->pcb_dr6 = rdr6();
+	pcb->pcb_dr7 = rdr7();
+#endif
+}
+static inline void
+x86_curthread_restore_dbregs(void)
+{
+	struct pcb *pcb = curthread->td_lwp->lwp_thread->td_pcb;
+
+	if (__predict_true(!(pcb->pcb_flags & PCB_DBREGS)))
+		return;
+
+	load_dr0(pcb->pcb_dr0);
+	load_dr1(pcb->pcb_dr1);
+	load_dr2(pcb->pcb_dr2);
+	load_dr3(pcb->pcb_dr3);
+	load_dr6(pcb->pcb_dr6);
+	load_dr7(pcb->pcb_dr7);
+}
+#define x86_get_dr0()		rdr0()
+#define x86_get_dr1()		rdr1()
+#define x86_get_dr2()		rdr2()
+#define x86_get_dr3()		rdr3()
+#define x86_get_dr6()		rdr6()
+#define x86_get_dr7()		rdr7()
+#define x86_set_dr0(v)		load_dr0(v)
+#define x86_set_dr1(v)		load_dr1(v)
+#define x86_set_dr2(v)		load_dr2(v)
+#define x86_set_dr3(v)		load_dr3(v)
+#define x86_set_dr6(v)		load_dr6(v)
+#define x86_set_dr7(v)		load_dr7(v)
 #endif
 
 /* FPU. */
@@ -722,6 +865,19 @@
 #define x86_curthread_restore_fpu()	fpu_kern_leave()
 #define x86_save_fpu(a, m)		fpu_area_save(a, m, true)
 #define x86_restore_fpu(a, m)		fpu_area_restore(a, m, true)
+#elif defined(__DragonFly__)
+static inline void
+x86_curthread_save_fpu(void)
+{
+	fpusave(curthread->td_savefpu);
+}
+static inline void
+x86_curthread_restore_fpu(void)
+{
+	fpurstor(curthread->td_savefpu);
+}
+#define x86_save_fpu(a, m)		fpusave_mask(a, m)
+#define x86_restore_fpu(a, m)		fpurstor_mask(a, m)
 #endif
 
 /* XCRs. */
@@ -753,6 +909,11 @@
 	);
 }
 
+#if defined(__DragonFly__)
+#define x86_fpu_mxcsr_mask	npx_mxcsr_mask
+#define x86_xsave_features	npx_xcr0_mask
+#endif
+
 #endif /* _KERNEL */
 
 #endif /* ASM_NVMM */
diff -r -u nvmm-official/src/libnvmm/libnvmm.c dfbsd/nvmm-dfbsd/src/libnvmm/libnvmm.c
--- nvmm-official/src/libnvmm/libnvmm.c	2021-01-03 10:43:03.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/libnvmm/libnvmm.c	2021-01-03 11:13:31.035890000 +0100
@@ -124,7 +124,11 @@
 	area_list_t *areas = mach->areas;
 	area_t *ent, *nxt;
 
+#if defined(__NetBSD__)
 	LIST_FOREACH_SAFE(ent, areas, list, nxt) {
+#elif defined(__DragonFly__)
+	LIST_FOREACH_MUTABLE(ent, areas, list, nxt) {
+#endif
 		if (hva == ent->hva && gpa == ent->gpa && size == ent->size) {
 			LIST_REMOVE(ent, list);
 			free(ent);
diff -r -u nvmm-official/src/libnvmm/nvmm.h dfbsd/nvmm-dfbsd/src/libnvmm/nvmm.h
--- nvmm-official/src/libnvmm/nvmm.h	2021-01-03 10:43:03.000000000 +0100
+++ dfbsd/nvmm-dfbsd/src/libnvmm/nvmm.h	2021-01-03 11:14:39.873484000 +0100
@@ -35,6 +35,9 @@
 #if defined(__NetBSD__)
 #include <dev/nvmm/nvmm.h>
 #include <dev/nvmm/nvmm_ioctl.h>
+#elif defined(__DragonFly__)
+#include <dev/virtual/nvmm/nvmm.h>
+#include <dev/virtual/nvmm/nvmm_ioctl.h>
 #endif
 
 #define NVMM_USER_VERSION	1
