From nobody Thu Jan 8 21:58:07 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4dnJgN0Pyxz6MpHL for ; Thu, 08 Jan 2026 21:58:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dnJgM757Mz3FsP for ; Thu, 08 Jan 2026 21:58:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1767909488; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bhdnuJABl5skitvYxlLK/aIlgsOehwzuK6BLUgMcBnk=; b=HQW14xyrvL4bTkMcsZ7ssyDCj3FF08XsztIHIcWUqIoY2h8Z3egXid716DcwllmCNM33Rn SrMrd01kKTvzPm2o1ySmQfaoD8aWP3Mp8p3xuXkoaz+4u17YSs4T4gE4TO7pPksYom7h8I bVAeg3SqHczd6i5c8gX3v1HgU6s4Mni2zYQl2XwDHq6rPv4Rkg+TpD2f+ZR3gIJMaKNN2P YnLPC1o59ce7yR6KxZiYT/f/Oo4Y7qU3YrmMN5nBoTgMNNWjbgnsAJk1UYYLbTxHldNuPc 8NoF0WDK3+ZmIsr2Cs6NFLJJ47hzQCosa+Y/qGLVwao58YXKfMTFD25v3KVGiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1767909488; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bhdnuJABl5skitvYxlLK/aIlgsOehwzuK6BLUgMcBnk=; b=IOYx3HNNGeOx5UyMic5orDsJ1h3WgwnP6Am8Yrje0Uz4vxtQau76dhMRDN9DtGwgo4bwAN 6cSmMH4aokIABYvr0bR7h07GngeK0R+ANJSW9Fv9X8J1sHuR+m8Gnu5bFbNGUfcvtH4omT U6hokln7TnvvgZRISVoKfy1+8lo/qKlM11oiyopzJir8ksrt6bhCp9R29UBhW/cF8/OWYm frTtxClqidA8qXxqKX7rVMtS3Y+V88Gt4sN6po66UV5krVWf3SHKLnSwsSB0i0Ob8GBK5R qSzDzcOH0ZeewtcUZBjMIsBKNhugnela47OqN8av1FFvRgqchUO6BWu0TCQjsg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1767909488; a=rsa-sha256; cv=none; b=pjqHiIexrvJEafLgMGSSGjQgoOuWIKxN1s2sKPRkuFvyHeVZe3xVkXim36iYOYWBqWAKkt CWYX4jwiopA0Mg7zXnmbbpK+/5fCDloSjObnWaehGD7lDBUsq+3QhpZmp5SxsrGh3KydfX zBIo/7NXQz3JEQ7hNQOYf30SeIwAW6r7laqc2EMjC3JR1EsdUroG4L0V6+CryppBQ4jU8v r3PlMg9KPqPFyWTdbuIsTYYOFpqR1ImswB7W5l6hej2GtY1v4PHK12KyBUOXnIDgxsTwFL uunqjvcGgaFWONlndef8WoA4RldNBQ+h+DimGN3lnBLboh6epfNbAdWZtd+83g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dnJgM6Nmwzx2p for ; Thu, 08 Jan 2026 21:58:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 23c48 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 08 Jan 2026 21:58:07 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: a6411f6b7df4 - main - vmm: Consolidate vm and vcpu definitions List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a6411f6b7df46edc7167a7844ed443db7a91a031 Auto-Submitted: auto-generated Date: Thu, 08 Jan 2026 21:58:07 +0000 Message-Id: <6960286f.23c48.6b4e6cc@gitrepo.freebsd.org> The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=a6411f6b7df46edc7167a7844ed443db7a91a031 commit a6411f6b7df46edc7167a7844ed443db7a91a031 Author: Mark Johnston AuthorDate: 2026-01-08 21:53:31 +0000 Commit: Mark Johnston 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 #include #include -#include #include #include #include #include +#include #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 #include -#include #include #include #include #include #include +#include #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 #include -#include #include #include + +#include #include #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 #include #include +#include #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 + +#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 + +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 #include #include -#include #include #include @@ -69,6 +68,8 @@ #include #include +#include + #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 #include + #include #include #include #include +#include #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 #include #include -#include #include #include #include #include +#include #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 #include #include +#include #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 #include +#include 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 #include +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 + +#include +#include + +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 + +#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 #include #include +#include #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 #include -#include + +#include 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 #include +#include + +#include + #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 #include #include -#include #include #include #include @@ -67,6 +66,7 @@ #include #include +#include #include "riscv.h" #include "vmm_aplic.h"