Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 08 Jan 2026 21:58:07 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: a6411f6b7df4 - main - vmm: Consolidate vm and vcpu definitions
Message-ID:  <6960286f.23c48.6b4e6cc@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=a6411f6b7df46edc7167a7844ed443db7a91a031

commit a6411f6b7df46edc7167a7844ed443db7a91a031
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-01-08 21:53:31 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-01-08 21:53:31 +0000

    vmm: Consolidate vm and vcpu definitions
    
    There is quite a lot of duplication of code between amd64, arm64 and
    riscv with respect to VM and vCPU state management.  This is a bit
    tricky to resolve since struct vm and struct vcpu are private to vmm.c
    and both structures contain a mix of machine-dependent and
    machine-independent fields.
    
    To allow deduplication without also introducing a lot of churn, follow
    the approach of struct pcpu and 1) lift the definitions of those
    structures into a new header, sys/dev/vmm/vmm_vm.h, and 2) define
    machine-dependent macros, VMM_VM_MD_FIELDS and VMM_VCPU_MD_FIELDS which
    lay out the machine-dependent fields.
    
    One disadvantage of this approach is that the two structures are no
    longer private to vmm.c, but I think this is acceptable.
    
    No functional change intended.  A follow-up change will move a good deal
    of machine/vmm/vmm.c into sys/dev/vmm/vmm_vm.c.
    
    MFC after:      2 months
    Sponsored by:   The FreeBSD Foundation
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D53584
---
 sys/amd64/include/vmm.h                  |  55 +++++++-------
 sys/amd64/vmm/amd/svm.c                  |   2 +-
 sys/amd64/vmm/intel/vmx.c                |   2 +-
 sys/amd64/vmm/io/vhpet.c                 |   3 +-
 sys/amd64/vmm/vmm.c                      |  83 +--------------------
 sys/arm64/include/vmm.h                  |  71 +++++++++---------
 sys/arm64/include/vmm_instruction_emul.h |   8 ++
 sys/arm64/vmm/io/vgic_v3.c               |   3 +-
 sys/arm64/vmm/vmm.c                      |  67 +----------------
 sys/arm64/vmm/vmm_arm64.c                |   2 +-
 sys/dev/vmm/vmm_dev.c                    |   1 +
 sys/dev/vmm/vmm_mem.c                    |   1 +
 sys/dev/vmm/vmm_mem.h                    |   3 +
 sys/dev/vmm/vmm_vm.h                     | 121 +++++++++++++++++++++++++++++++
 sys/riscv/include/vmm.h                  |  44 +++++------
 sys/riscv/include/vmm_instruction_emul.h |   6 ++
 sys/riscv/vmm/vmm.c                      |  56 +-------------
 sys/riscv/vmm/vmm_aplic.c                |   3 +-
 sys/riscv/vmm/vmm_fence.c                |   8 +-
 sys/riscv/vmm/vmm_riscv.c                |   2 +-
 20 files changed, 239 insertions(+), 302 deletions(-)

diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 5cf1ae2d769c..e1df85aa91b6 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -123,6 +123,33 @@ enum x2apic_state {
 #define	VM_INTINFO_SWINTR	(4 << 8)
 
 #ifdef _KERNEL
+#define	VMM_VCPU_MD_FIELDS						\
+	struct vlapic	*vlapic;	/* (i) APIC device model */	\
+	enum x2apic_state x2apic_state;	/* (i) APIC mode */		\
+	uint64_t	exitintinfo;	/* (i) events pending at VM exit */ \
+	int		nmi_pending;	/* (i) NMI pending */		\
+	int		extint_pending;	/* (i) INTR pending */		\
+	int		exception_pending; /* (i) exception pending */	\
+	int		exc_vector;	/* (x) exception collateral */	\
+	int		exc_errcode_valid;				\
+	uint32_t	exc_errcode;					\
+	struct savefpu	*guestfpu;	/* (a,i) guest fpu state */	\
+	uint64_t	guest_xcr0;	/* (i) guest %xcr0 register */	\
+	struct vm_exit	exitinfo;	/* (x) exit reason and collateral */ \
+	cpuset_t	exitinfo_cpuset; /* (x) storage for vmexit handlers */ \
+	uint64_t	nextrip;	/* (x) next instruction to execute */ \
+	uint64_t	tsc_offset	/* (o) TSC offsetting */
+
+#define	VMM_VM_MD_FIELDS						\
+	cpuset_t	startup_cpus;	/* (i) [r] waiting for startup */ \
+	void		*iommu;		/* (x) iommu-specific data */	\
+	struct vioapic	*vioapic;	/* (i) virtual ioapic */	\
+	struct vatpic	*vatpic;	/* (i) virtual atpic */		\
+	struct vatpit	*vatpit;	/* (i) virtual atpit */		\
+	struct vpmtmr	*vpmtmr;	/* (i) virtual ACPI PM timer */	\
+	struct vrtc	*vrtc;		/* (o) virtual RTC */		\
+	struct vhpet	*vhpet		/* (i) virtual HPET */
+
 struct vm;
 struct vm_exception;
 struct vm_mem;
@@ -326,34 +353,6 @@ bool vmm_is_pptdev(int bus, int slot, int func);
 
 void *vm_iommu_domain(struct vm *vm);
 
-enum vcpu_state {
-	VCPU_IDLE,
-	VCPU_FROZEN,
-	VCPU_RUNNING,
-	VCPU_SLEEPING,
-};
-
-int vcpu_set_state(struct vcpu *vcpu, enum vcpu_state state, bool from_idle);
-int vcpu_set_state_all(struct vm *vm, enum vcpu_state state);
-enum vcpu_state vcpu_get_state(struct vcpu *vcpu, int *hostcpu);
-
-static int __inline
-vcpu_is_running(struct vcpu *vcpu, int *hostcpu)
-{
-	return (vcpu_get_state(vcpu, hostcpu) == VCPU_RUNNING);
-}
-
-#ifdef _SYS_PROC_H_
-static int __inline
-vcpu_should_yield(struct vcpu *vcpu)
-{
-	struct thread *td;
-
-	td = curthread;
-	return (td->td_ast != 0 || td->td_owepreempt != 0);
-}
-#endif
-
 void *vcpu_stats(struct vcpu *vcpu);
 void vcpu_notify_event(struct vcpu *vcpu);
 void vcpu_notify_lapic(struct vcpu *vcpu);
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index 2fe6a5bc3584..37c950cfbc5f 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -50,12 +50,12 @@
 #include <machine/specialreg.h>
 #include <machine/smp.h>
 #include <machine/vmm.h>
-#include <machine/vmm_dev.h>
 #include <machine/vmm_instruction_emul.h>
 #include <machine/vmm_snapshot.h>
 
 #include <dev/vmm/vmm_ktr.h>
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "vmm_lapic.h"
 #include "vmm_stat.h"
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 4189c1214b40..7a2d0de6beff 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -53,13 +53,13 @@
 #include <machine/vmparam.h>
 
 #include <machine/vmm.h>
-#include <machine/vmm_dev.h>
 #include <machine/vmm_instruction_emul.h>
 #include <machine/vmm_snapshot.h>
 
 #include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_ktr.h>
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "vmm_lapic.h"
 #include "vmm_host.h"
diff --git a/sys/amd64/vmm/io/vhpet.c b/sys/amd64/vmm/io/vhpet.c
index 88063f2952e5..cdeb5e059128 100644
--- a/sys/amd64/vmm/io/vhpet.c
+++ b/sys/amd64/vmm/io/vhpet.c
@@ -38,10 +38,11 @@
 #include <sys/systm.h>
 
 #include <machine/vmm.h>
-#include <machine/vmm_dev.h>
 #include <machine/vmm_snapshot.h>
 
 #include <dev/acpica/acpi_hpet.h>
+
+#include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_ktr.h>
 
 #include "vmm_lapic.h"
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index f3f9717129c9..4b93e020f8dc 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -71,6 +71,7 @@
 #include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_ktr.h>
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "vmm_ioport.h"
 #include "vmm_host.h"
@@ -91,88 +92,6 @@
 
 struct vlapic;
 
-/*
- * Initialization:
- * (a) allocated when vcpu is created
- * (i) initialized when vcpu is created and when it is reinitialized
- * (o) initialized the first time the vcpu is created
- * (x) initialized before use
- */
-struct vcpu {
-	struct mtx 	mtx;		/* (o) protects 'state' and 'hostcpu' */
-	enum vcpu_state	state;		/* (o) vcpu state */
-	int		vcpuid;		/* (o) */
-	int		hostcpu;	/* (o) vcpu's host cpu */
-	int		reqidle;	/* (i) request vcpu to idle */
-	struct vm	*vm;		/* (o) */
-	void		*cookie;	/* (i) cpu-specific data */
-	struct vlapic	*vlapic;	/* (i) APIC device model */
-	enum x2apic_state x2apic_state;	/* (i) APIC mode */
-	uint64_t	exitintinfo;	/* (i) events pending at VM exit */
-	int		nmi_pending;	/* (i) NMI pending */
-	int		extint_pending;	/* (i) INTR pending */
-	int	exception_pending;	/* (i) exception pending */
-	int	exc_vector;		/* (x) exception collateral */
-	int	exc_errcode_valid;
-	uint32_t exc_errcode;
-	struct savefpu	*guestfpu;	/* (a,i) guest fpu state */
-	uint64_t	guest_xcr0;	/* (i) guest %xcr0 register */
-	void		*stats;		/* (a,i) statistics */
-	struct vm_exit	exitinfo;	/* (x) exit reason and collateral */
-	cpuset_t	exitinfo_cpuset; /* (x) storage for vmexit handlers */
-	uint64_t	nextrip;	/* (x) next instruction to execute */
-	uint64_t	tsc_offset;	/* (o) TSC offsetting */
-};
-
-#define	vcpu_lock_init(v)	mtx_init(&((v)->mtx), "vcpu lock", 0, MTX_SPIN)
-#define	vcpu_lock_destroy(v)	mtx_destroy(&((v)->mtx))
-#define	vcpu_lock(v)		mtx_lock_spin(&((v)->mtx))
-#define	vcpu_unlock(v)		mtx_unlock_spin(&((v)->mtx))
-#define	vcpu_assert_locked(v)	mtx_assert(&((v)->mtx), MA_OWNED)
-
-/*
- * Initialization:
- * (o) initialized the first time the VM is created
- * (i) initialized when VM is created and when it is reinitialized
- * (x) initialized before use
- *
- * Locking:
- * [m] mem_segs_lock
- * [r] rendezvous_mtx
- * [v] reads require one frozen vcpu, writes require freezing all vcpus
- */
-struct vm {
-	void		*cookie;		/* (i) cpu-specific data */
-	void		*iommu;			/* (x) iommu-specific data */
-	struct vhpet	*vhpet;			/* (i) virtual HPET */
-	struct vioapic	*vioapic;		/* (i) virtual ioapic */
-	struct vatpic	*vatpic;		/* (i) virtual atpic */
-	struct vatpit	*vatpit;		/* (i) virtual atpit */
-	struct vpmtmr	*vpmtmr;		/* (i) virtual ACPI PM timer */
-	struct vrtc	*vrtc;			/* (o) virtual RTC */
-	volatile cpuset_t active_cpus;		/* (i) active vcpus */
-	volatile cpuset_t debug_cpus;		/* (i) vcpus stopped for debug */
-	cpuset_t	startup_cpus;		/* (i) [r] waiting for startup */
-	int		suspend;		/* (i) stop VM execution */
-	bool		dying;			/* (o) is dying */
-	volatile cpuset_t suspended_cpus; 	/* (i) suspended vcpus */
-	volatile cpuset_t halted_cpus;		/* (x) cpus in a hard halt */
-	cpuset_t	rendezvous_req_cpus;	/* (x) [r] rendezvous requested */
-	cpuset_t	rendezvous_done_cpus;	/* (x) [r] rendezvous finished */
-	void		*rendezvous_arg;	/* (x) [r] rendezvous func/arg */
-	vm_rendezvous_func_t rendezvous_func;
-	struct mtx	rendezvous_mtx;		/* (o) rendezvous lock */
-	struct vm_mem	mem;			/* (i) [m+v] guest memory */
-	char		name[VM_MAX_NAMELEN+1];	/* (o) virtual machine name */
-	struct vcpu	**vcpu;			/* (o) guest vcpus */
-	/* The following describe the vm cpu topology */
-	uint16_t	sockets;		/* (o) num of sockets */
-	uint16_t	cores;			/* (o) num of cores/socket */
-	uint16_t	threads;		/* (o) num of threads/core */
-	uint16_t	maxcpus;		/* (o) max pluggable cpus */
-	struct sx	vcpus_init_lock;	/* (o) */
-};
-
 #define	VMM_CTR0(vcpu, format)						\
 	VCPU_CTR0((vcpu)->vm, (vcpu)->vcpuid, format)
 
diff --git a/sys/arm64/include/vmm.h b/sys/arm64/include/vmm.h
index e67540eac66d..16292dd42f28 100644
--- a/sys/arm64/include/vmm.h
+++ b/sys/arm64/include/vmm.h
@@ -107,14 +107,33 @@ enum vm_reg_name {
 #define VM_GUEST_BASE_IPA	0x80000000UL	/* Guest kernel start ipa */
 
 #ifdef _KERNEL
-struct vm;
-struct vm_exception;
-struct vm_exit;
-struct vm_run;
-struct vm_object;
-struct vm_guest_paging;
-struct vm_vgic_descr;
-struct pmap;
+#include <machine/vmm_instruction_emul.h>
+
+#define	VMM_VCPU_MD_FIELDS						\
+	struct vm_exit	exitinfo;					\
+	uint64_t	nextpc;		/* (x) next instruction to execute */ \
+	struct vfpstate	*guestfpu	/* (a,i) guest fpu state */
+
+#define	VMM_VM_MD_FIELDS						\
+	struct vmm_mmio_region mmio_region[VM_MAX_MMIO_REGIONS];	\
+	struct vmm_special_reg special_reg[VM_MAX_SPECIAL_REGS]
+
+struct vmm_mmio_region {
+	uint64_t start;
+	uint64_t end;
+	mem_region_read_t read;
+	mem_region_write_t write;
+};
+#define	VM_MAX_MMIO_REGIONS	4
+
+struct vmm_special_reg {
+	uint32_t	esr_iss;
+	uint32_t	esr_mask;
+	reg_read_t	reg_read;
+	reg_write_t	reg_write;
+	void		*arg;
+};
+#define	VM_MAX_SPECIAL_REGS	16
 
 struct vm_eventinfo {
 	void	*rptr;		/* rendezvous cookie */
@@ -125,6 +144,15 @@ struct vm_eventinfo {
 #define	DECLARE_VMMOPS_FUNC(ret_type, opname, args)			\
 	ret_type vmmops_##opname args
 
+struct vm;
+struct vm_exception;
+struct vm_exit;
+struct vm_run;
+struct vm_object;
+struct vm_guest_paging;
+struct vm_vgic_descr;
+struct pmap;
+
 DECLARE_VMMOPS_FUNC(int, modinit, (int ipinum));
 DECLARE_VMMOPS_FUNC(int, modcleanup, (void));
 DECLARE_VMMOPS_FUNC(void *, init, (struct vm *vm, struct pmap *pmap));
@@ -213,33 +241,6 @@ vcpu_suspended(struct vm_eventinfo *info)
 
 int vcpu_debugged(struct vcpu *vcpu);
 
-enum vcpu_state {
-	VCPU_IDLE,
-	VCPU_FROZEN,
-	VCPU_RUNNING,
-	VCPU_SLEEPING,
-};
-
-int vcpu_set_state(struct vcpu *vcpu, enum vcpu_state state, bool from_idle);
-enum vcpu_state vcpu_get_state(struct vcpu *vcpu, int *hostcpu);
-
-static int __inline
-vcpu_is_running(struct vcpu *vcpu, int *hostcpu)
-{
-	return (vcpu_get_state(vcpu, hostcpu) == VCPU_RUNNING);
-}
-
-#ifdef _SYS_PROC_H_
-static int __inline
-vcpu_should_yield(struct vcpu *vcpu)
-{
-	struct thread *td;
-
-	td = curthread;
-	return (td->td_ast != 0 || td->td_owepreempt != 0);
-}
-#endif
-
 void *vcpu_stats(struct vcpu *vcpu);
 void vcpu_notify_event(struct vcpu *vcpu);
 struct vm_mem *vm_mem(struct vm *vm);
diff --git a/sys/arm64/include/vmm_instruction_emul.h b/sys/arm64/include/vmm_instruction_emul.h
index a295f7cce127..dc281f442543 100644
--- a/sys/arm64/include/vmm_instruction_emul.h
+++ b/sys/arm64/include/vmm_instruction_emul.h
@@ -27,6 +27,14 @@
 #ifndef	_VMM_INSTRUCTION_EMUL_H_
 #define	_VMM_INSTRUCTION_EMUL_H_
 
+#include <sys/types.h>
+
+struct vcpu;
+struct vm;
+struct vie;
+struct vre;
+struct vm_guest_paging;
+
 /*
  * Callback functions to read and write memory regions.
  */
diff --git a/sys/arm64/vmm/io/vgic_v3.c b/sys/arm64/vmm/io/vgic_v3.c
index 023406c64182..e4f7bb2af3ee 100644
--- a/sys/arm64/vmm/io/vgic_v3.c
+++ b/sys/arm64/vmm/io/vgic_v3.c
@@ -57,7 +57,6 @@
 #include <machine/vmparam.h>
 #include <machine/intr.h>
 #include <machine/vmm.h>
-#include <machine/vmm_dev.h>
 #include <machine/vmm_instruction_emul.h>
 
 #include <arm/arm/gic_common.h>
@@ -69,6 +68,8 @@
 #include <arm64/vmm/arm64.h>
 #include <arm64/vmm/vmm_handlers.h>
 
+#include <dev/vmm/vmm_dev.h>
+
 #include "vgic.h"
 #include "vgic_v3.h"
 #include "vgic_v3_reg.h"
diff --git a/sys/arm64/vmm/vmm.c b/sys/arm64/vmm/vmm.c
index 31d2fb3f516b..75f7f2fcaaf7 100644
--- a/sys/arm64/vmm/vmm.c
+++ b/sys/arm64/vmm/vmm.c
@@ -61,10 +61,12 @@
 #include <machine/vmm_instruction_emul.h>
 
 #include <dev/pci/pcireg.h>
+
 #include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_ktr.h>
 #include <dev/vmm/vmm_mem.h>
 #include <dev/vmm/vmm_stat.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "arm64.h"
 #include "mmu.h"
@@ -72,71 +74,6 @@
 #include "io/vgic.h"
 #include "io/vtimer.h"
 
-struct vcpu {
-	int		flags;
-	enum vcpu_state	state;
-	struct mtx	mtx;
-	int		hostcpu;	/* host cpuid this vcpu last ran on */
-	int		vcpuid;
-	void		*stats;
-	struct vm_exit	exitinfo;
-	uint64_t	nextpc;		/* (x) next instruction to execute */
-	struct vm	*vm;		/* (o) */
-	void		*cookie;	/* (i) cpu-specific data */
-	struct vfpstate	*guestfpu;	/* (a,i) guest fpu state */
-};
-
-#define	vcpu_lock_init(v)	mtx_init(&((v)->mtx), "vcpu lock", 0, MTX_SPIN)
-#define	vcpu_lock_destroy(v)	mtx_destroy(&((v)->mtx))
-#define	vcpu_lock(v)		mtx_lock_spin(&((v)->mtx))
-#define	vcpu_unlock(v)		mtx_unlock_spin(&((v)->mtx))
-#define	vcpu_assert_locked(v)	mtx_assert(&((v)->mtx), MA_OWNED)
-
-struct vmm_mmio_region {
-	uint64_t start;
-	uint64_t end;
-	mem_region_read_t read;
-	mem_region_write_t write;
-};
-#define	VM_MAX_MMIO_REGIONS	4
-
-struct vmm_special_reg {
-	uint32_t	esr_iss;
-	uint32_t	esr_mask;
-	reg_read_t	reg_read;
-	reg_write_t	reg_write;
-	void		*arg;
-};
-#define	VM_MAX_SPECIAL_REGS	16
-
-/*
- * Initialization:
- * (o) initialized the first time the VM is created
- * (i) initialized when VM is created and when it is reinitialized
- * (x) initialized before use
- */
-struct vm {
-	void		*cookie;		/* (i) cpu-specific data */
-	volatile cpuset_t active_cpus;		/* (i) active vcpus */
-	volatile cpuset_t debug_cpus;		/* (i) vcpus stopped for debug */
-	int		suspend;		/* (i) stop VM execution */
-	bool		dying;			/* (o) is dying */
-	volatile cpuset_t suspended_cpus; 	/* (i) suspended vcpus */
-	volatile cpuset_t halted_cpus;		/* (x) cpus in a hard halt */
-	struct vm_mem	mem;			/* (i) guest memory */
-	char		name[VM_MAX_NAMELEN + 1];	/* (o) virtual machine name */
-	struct vcpu	**vcpu;			/* (i) guest vcpus */
-	struct vmm_mmio_region mmio_region[VM_MAX_MMIO_REGIONS];
-						/* (o) guest MMIO regions */
-	struct vmm_special_reg special_reg[VM_MAX_SPECIAL_REGS];
-	/* The following describe the vm cpu topology */
-	uint16_t	sockets;		/* (o) num of sockets */
-	uint16_t	cores;			/* (o) num of cores/socket */
-	uint16_t	threads;		/* (o) num of threads/core */
-	uint16_t	maxcpus;		/* (o) max pluggable cpus */
-	struct sx	vcpus_init_lock;	/* (o) */
-};
-
 static int vm_handle_wfi(struct vcpu *vcpu,
 			 struct vm_exit *vme, bool *retu);
 
diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c
index aa1361049f49..d529f000b828 100644
--- a/sys/arm64/vmm/vmm_arm64.c
+++ b/sys/arm64/vmm/vmm_arm64.c
@@ -52,12 +52,12 @@
 #include <machine/cpu.h>
 #include <machine/machdep.h>
 #include <machine/vmm.h>
-#include <machine/vmm_dev.h>
 #include <machine/atomic.h>
 #include <machine/hypervisor.h>
 #include <machine/pmap.h>
 
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "mmu.h"
 #include "arm64.h"
diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
index 840e810a39fb..eda15cc88b28 100644
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -33,6 +33,7 @@
 #include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_mem.h>
 #include <dev/vmm/vmm_stat.h>
+#include <dev/vmm/vmm_vm.h>
 
 #ifdef __amd64__
 #ifdef COMPAT_FREEBSD12
diff --git a/sys/dev/vmm/vmm_mem.c b/sys/dev/vmm/vmm_mem.c
index 5ae944713c81..5a73cbf7fc5b 100644
--- a/sys/dev/vmm/vmm_mem.c
+++ b/sys/dev/vmm/vmm_mem.c
@@ -23,6 +23,7 @@
 
 #include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 static void vm_free_memmap(struct vm *vm, int ident);
 
diff --git a/sys/dev/vmm/vmm_mem.h b/sys/dev/vmm/vmm_mem.h
index f3d22058c7b8..64bb29352a55 100644
--- a/sys/dev/vmm/vmm_mem.h
+++ b/sys/dev/vmm/vmm_mem.h
@@ -34,7 +34,10 @@ enum {
 #include <sys/types.h>
 #include <sys/_sx.h>
 
+struct domainset;
+struct vcpu;
 struct vm;
+struct vm_guest_paging;
 struct vm_object;
 struct vmspace;
 
diff --git a/sys/dev/vmm/vmm_vm.h b/sys/dev/vmm/vmm_vm.h
new file mode 100644
index 000000000000..23f40e079da4
--- /dev/null
+++ b/sys/dev/vmm/vmm_vm.h
@@ -0,0 +1,121 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2011 NetApp, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _DEV_VMM_VM_H_
+#define	_DEV_VMM_VM_H_
+
+#ifdef _KERNEL
+
+#include <machine/vmm.h>
+
+#include <dev/vmm/vmm_param.h>
+#include <dev/vmm/vmm_mem.h>
+
+struct vcpu;
+
+enum vcpu_state {
+	VCPU_IDLE,
+	VCPU_FROZEN,
+	VCPU_RUNNING,
+	VCPU_SLEEPING,
+};
+
+/*
+ * Initialization:
+ * (a) allocated when vcpu is created
+ * (i) initialized when vcpu is created and when it is reinitialized
+ * (o) initialized the first time the vcpu is created
+ * (x) initialized before use
+ */
+struct vcpu {
+	struct mtx 	mtx;		/* (o) protects 'state' and 'hostcpu' */
+	enum vcpu_state	state;		/* (o) vcpu state */
+	int		vcpuid;		/* (o) */
+	int		hostcpu;	/* (o) vcpu's host cpu */
+	int		reqidle;	/* (i) request vcpu to idle */
+	struct vm	*vm;		/* (o) */
+	void		*cookie;	/* (i) cpu-specific data */
+	void		*stats;		/* (a,i) statistics */
+
+	VMM_VCPU_MD_FIELDS;
+};
+
+#define	vcpu_lock_init(v)	mtx_init(&((v)->mtx), "vcpu lock", 0, MTX_SPIN)
+#define	vcpu_lock_destroy(v)	mtx_destroy(&((v)->mtx))
+#define	vcpu_lock(v)		mtx_lock_spin(&((v)->mtx))
+#define	vcpu_unlock(v)		mtx_unlock_spin(&((v)->mtx))
+#define	vcpu_assert_locked(v)	mtx_assert(&((v)->mtx), MA_OWNED)
+
+int vcpu_set_state(struct vcpu *vcpu, enum vcpu_state state, bool from_idle);
+#ifdef __amd64__
+int vcpu_set_state_all(struct vm *vm, enum vcpu_state state);
+#endif
+enum vcpu_state vcpu_get_state(struct vcpu *vcpu, int *hostcpu);
+
+static int __inline
+vcpu_is_running(struct vcpu *vcpu, int *hostcpu)
+{
+	return (vcpu_get_state(vcpu, hostcpu) == VCPU_RUNNING);
+}
+
+#ifdef _SYS_PROC_H_
+static int __inline
+vcpu_should_yield(struct vcpu *vcpu)
+{
+	struct thread *td;
+
+	td = curthread;
+	return (td->td_ast != 0 || td->td_owepreempt != 0);
+}
+#endif
+
+typedef void (*vm_rendezvous_func_t)(struct vcpu *vcpu, void *arg);
+
+/*
+ * Initialization:
+ * (o) initialized the first time the VM is created
+ * (i) initialized when VM is created and when it is reinitialized
+ * (x) initialized before use
+ *
+ * Locking:
+ * [m] mem_segs_lock
+ * [r] rendezvous_mtx
+ * [v] reads require one frozen vcpu, writes require freezing all vcpus
+ */
+struct vm {
+	void		*cookie;		/* (i) cpu-specific data */
+	struct vcpu	**vcpu;			/* (o) guest vcpus */
+	struct vm_mem	mem;			/* (i) [m+v] guest memory */
+
+	char		name[VM_MAX_NAMELEN + 1]; /* (o) virtual machine name */
+	struct sx	vcpus_init_lock;	/* (o) */
+
+	bool		dying;			/* (o) is dying */
+	int		suspend;		/* (i) stop VM execution */
+
+	volatile cpuset_t active_cpus;		/* (i) active vcpus */
+	volatile cpuset_t debug_cpus;		/* (i) vcpus stopped for debug */
+	volatile cpuset_t suspended_cpus; 	/* (i) suspended vcpus */
+	volatile cpuset_t halted_cpus;		/* (x) cpus in a hard halt */
+
+	cpuset_t	rendezvous_req_cpus;	/* (x) [r] rendezvous requested */
+	cpuset_t	rendezvous_done_cpus;	/* (x) [r] rendezvous finished */
+	void		*rendezvous_arg;	/* (x) [r] rendezvous func/arg */
+	vm_rendezvous_func_t rendezvous_func;
+	struct mtx	rendezvous_mtx;		/* (o) rendezvous lock */
+
+	uint16_t	sockets;		/* (o) num of sockets */
+	uint16_t	cores;			/* (o) num of cores/socket */
+	uint16_t	threads;		/* (o) num of threads/core */
+	uint16_t	maxcpus;		/* (o) max pluggable cpus */
+
+	VMM_VM_MD_FIELDS;
+};
+
+#endif /* _KERNEL */
+
+#endif /* !_DEV_VMM_VM_H_ */
diff --git a/sys/riscv/include/vmm.h b/sys/riscv/include/vmm.h
index 361140834805..a7318294464c 100644
--- a/sys/riscv/include/vmm.h
+++ b/sys/riscv/include/vmm.h
@@ -104,6 +104,15 @@ enum vm_reg_name {
 #define	VM_INTINFO_SWINTR	(4 << 8)
 
 #ifdef _KERNEL
+#include <machine/vmm_instruction_emul.h>
+
+#define	VMM_VCPU_MD_FIELDS						\
+	struct vm_exit	exitinfo;					\
+	uint64_t	nextpc;		/* (x) next instruction to execute */ \
+	struct fpreg	*guestfpu	/* (a,i) guest fpu state */
+
+#define	VMM_VM_MD_FIELDS						\
+	struct vmm_mmio_region mmio_region[VM_MAX_MMIO_REGIONS]
 
 struct vm;
 struct vm_exception;
@@ -114,6 +123,14 @@ struct vm_guest_paging;
 struct vm_aplic_descr;
 struct pmap;
 
+struct vmm_mmio_region {
+	uint64_t start;
+	uint64_t end;
+	mem_region_read_t read;
+	mem_region_write_t write;
+};
+#define	VM_MAX_MMIO_REGIONS	4
+
 struct vm_eventinfo {
 	void	*rptr;		/* rendezvous cookie */
 	int	*sptr;		/* suspend cookie */
@@ -203,33 +220,6 @@ vcpu_suspended(struct vm_eventinfo *info)
 
 int vcpu_debugged(struct vcpu *vcpu);
 
-enum vcpu_state {
-	VCPU_IDLE,
-	VCPU_FROZEN,
-	VCPU_RUNNING,
-	VCPU_SLEEPING,
-};
-
-int vcpu_set_state(struct vcpu *vcpu, enum vcpu_state state, bool from_idle);
-enum vcpu_state vcpu_get_state(struct vcpu *vcpu, int *hostcpu);
-
-static int __inline
-vcpu_is_running(struct vcpu *vcpu, int *hostcpu)
-{
-	return (vcpu_get_state(vcpu, hostcpu) == VCPU_RUNNING);
-}
-
-#ifdef _SYS_PROC_H_
-static int __inline
-vcpu_should_yield(struct vcpu *vcpu)
-{
-	struct thread *td;
-
-	td = curthread;
-	return (td->td_ast != 0 || td->td_owepreempt != 0);
-}
-#endif
-
 void *vcpu_stats(struct vcpu *vcpu);
 void vcpu_notify_event(struct vcpu *vcpu);
 struct vm_mem *vm_mem(struct vm *vm);
diff --git a/sys/riscv/include/vmm_instruction_emul.h b/sys/riscv/include/vmm_instruction_emul.h
index bee63d2f86ba..5041b10569f5 100644
--- a/sys/riscv/include/vmm_instruction_emul.h
+++ b/sys/riscv/include/vmm_instruction_emul.h
@@ -29,6 +29,12 @@
 #ifndef	_VMM_INSTRUCTION_EMUL_H_
 #define	_VMM_INSTRUCTION_EMUL_H_
 
+struct vcpu;
+struct vie;
+struct vre;
+struct vm;
+struct vm_guest_paging;
+
 /*
  * Callback functions to read and write memory regions.
  */
diff --git a/sys/riscv/vmm/vmm.c b/sys/riscv/vmm/vmm.c
index 23b57ad3b7aa..fea6421962dc 100644
--- a/sys/riscv/vmm/vmm.c
+++ b/sys/riscv/vmm/vmm.c
@@ -71,67 +71,13 @@
 #include <dev/vmm/vmm_dev.h>
 #include <dev/vmm/vmm_ktr.h>
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "vmm_stat.h"
 #include "riscv.h"
 
 #include "vmm_aplic.h"
 
-struct vcpu {
-	int		flags;
-	enum vcpu_state	state;
-	struct mtx	mtx;
-	int		hostcpu;	/* host cpuid this vcpu last ran on */
-	int		vcpuid;
-	void		*stats;
-	struct vm_exit	exitinfo;
-	uint64_t	nextpc;		/* (x) next instruction to execute */
-	struct vm	*vm;		/* (o) */
-	void		*cookie;	/* (i) cpu-specific data */
-	struct fpreg	*guestfpu;	/* (a,i) guest fpu state */
-};
-
-#define	vcpu_lock_init(v)	mtx_init(&((v)->mtx), "vcpu lock", 0, MTX_SPIN)
-#define	vcpu_lock_destroy(v)	mtx_destroy(&((v)->mtx))
-#define	vcpu_lock(v)		mtx_lock_spin(&((v)->mtx))
-#define	vcpu_unlock(v)		mtx_unlock_spin(&((v)->mtx))
-#define	vcpu_assert_locked(v)	mtx_assert(&((v)->mtx), MA_OWNED)
-
-struct vmm_mmio_region {
-	uint64_t start;
-	uint64_t end;
-	mem_region_read_t read;
-	mem_region_write_t write;
-};
-#define	VM_MAX_MMIO_REGIONS	4
-
-/*
- * Initialization:
- * (o) initialized the first time the VM is created
- * (i) initialized when VM is created and when it is reinitialized
- * (x) initialized before use
- */
-struct vm {
-	void		*cookie;		/* (i) cpu-specific data */
-	volatile cpuset_t active_cpus;		/* (i) active vcpus */
-	volatile cpuset_t debug_cpus;		/* (i) vcpus stopped for debug*/
-	int		suspend;		/* (i) stop VM execution */
-	bool		dying;			/* (o) is dying */
-	volatile cpuset_t suspended_cpus; 	/* (i) suspended vcpus */
-	volatile cpuset_t halted_cpus;		/* (x) cpus in a hard halt */
-	struct vm_mem	mem;			/* (i) [m+v] guest memory */
-	char		name[VM_MAX_NAMELEN + 1]; /* (o) virtual machine name */
-	struct vcpu	**vcpu;			/* (i) guest vcpus */
-	struct vmm_mmio_region mmio_region[VM_MAX_MMIO_REGIONS];
-						/* (o) guest MMIO regions */
-	/* The following describe the vm cpu topology */
-	uint16_t	sockets;		/* (o) num of sockets */
-	uint16_t	cores;			/* (o) num of cores/socket */
-	uint16_t	threads;		/* (o) num of threads/core */
-	uint16_t	maxcpus;		/* (o) max pluggable cpus */
-	struct sx	vcpus_init_lock;	/* (o) */
-};
-
 static MALLOC_DEFINE(M_VMM, "vmm", "vmm");
 
 /* statistics */
diff --git a/sys/riscv/vmm/vmm_aplic.c b/sys/riscv/vmm/vmm_aplic.c
index 74cb4fef4273..eaf2caa4d313 100644
--- a/sys/riscv/vmm/vmm_aplic.c
+++ b/sys/riscv/vmm/vmm_aplic.c
@@ -46,7 +46,8 @@
 #include <riscv/vmm/vmm_aplic.h>
 
 #include <machine/vmm_instruction_emul.h>
-#include <machine/vmm_dev.h>
+
+#include <dev/vmm/vmm_dev.h>
 
 MALLOC_DEFINE(M_APLIC, "RISC-V VMM APLIC", "RISC-V AIA APLIC");
 
diff --git a/sys/riscv/vmm/vmm_fence.c b/sys/riscv/vmm/vmm_fence.c
index f8b69aac77a9..ff7eabdb3d50 100644
--- a/sys/riscv/vmm/vmm_fence.c
+++ b/sys/riscv/vmm/vmm_fence.c
@@ -39,6 +39,10 @@
 #include <sys/mutex.h>
 #include <sys/bus.h>
 
+#include <machine/vmm.h>
+
+#include <dev/vmm/vmm_vm.h>
+
 #include "riscv.h"
 #include "vmm_fence.h"
 
@@ -145,7 +149,6 @@ vmm_fence_add(struct vm *vm, cpuset_t *cpus, struct vmm_fence *fence)
 	struct vcpu *vcpu;
 	uint16_t maxcpus;
 	int hostcpu;
-	int state;
 	bool enq;
 	int i;
 
@@ -193,8 +196,7 @@ vmm_fence_add(struct vm *vm, cpuset_t *cpus, struct vmm_fence *fence)
 
 		mb();
 
-		state = vcpu_get_state(vcpu, &hostcpu);
-		if (state == VCPU_RUNNING)
+		if (vcpu_is_running(vcpu, &hostcpu))
 			CPU_SET(hostcpu, &running_cpus);
 	}
 
diff --git a/sys/riscv/vmm/vmm_riscv.c b/sys/riscv/vmm/vmm_riscv.c
index 0e46aca60fdf..cfd3decd8cfa 100644
--- a/sys/riscv/vmm/vmm_riscv.c
+++ b/sys/riscv/vmm/vmm_riscv.c
@@ -59,7 +59,6 @@
 #include <machine/cpu.h>
 #include <machine/machdep.h>
 #include <machine/vmm.h>
-#include <machine/vmm_dev.h>
 #include <machine/atomic.h>
 #include <machine/pmap.h>
 #include <machine/intr.h>
@@ -67,6 +66,7 @@
 #include <machine/db_machdep.h>
 
 #include <dev/vmm/vmm_mem.h>
+#include <dev/vmm/vmm_vm.h>
 
 #include "riscv.h"
 #include "vmm_aplic.h"


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6960286f.23c48.6b4e6cc>