aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/include/vmm.h99
-rw-r--r--sys/amd64/vmm/vmm.c47
-rw-r--r--sys/amd64/vmm/vmm_dev_machdep.c1
-rw-r--r--sys/arm64/include/vmm.h32
-rw-r--r--sys/arm64/vmm/arm64.h31
-rw-r--r--sys/arm64/vmm/vmm.c37
-rw-r--r--sys/dev/ice/ice_common.c9
-rw-r--r--sys/dev/ice/ice_devids.h18
-rw-r--r--sys/dev/ice/ice_drv_info.h39
-rw-r--r--sys/dev/ixgbe/if_ix.c521
-rw-r--r--sys/dev/ixgbe/ixgbe.h52
-rw-r--r--sys/dev/ixgbe/ixgbe_features.h1
-rw-r--r--sys/dev/vmm/vmm_mem.c31
-rw-r--r--sys/dev/vmm/vmm_mem.h6
-rw-r--r--sys/netpfil/ipfw/ip_dn_io.c6
-rw-r--r--sys/riscv/include/vmm.h24
-rw-r--r--sys/riscv/vmm/riscv.h23
-rw-r--r--sys/riscv/vmm/vmm.c35
-rw-r--r--sys/sys/user.h3
-rw-r--r--sys/vm/vm_object.c12
20 files changed, 831 insertions, 196 deletions
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index e35119af8572..66d8991d36e8 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -170,55 +170,63 @@ struct vm_eventinfo {
int *iptr; /* reqidle cookie */
};
-typedef int (*vmm_init_func_t)(int ipinum);
-typedef int (*vmm_cleanup_func_t)(void);
-typedef void (*vmm_suspend_func_t)(void);
-typedef void (*vmm_resume_func_t)(void);
-typedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap);
-typedef int (*vmi_run_func_t)(void *vcpui, register_t rip,
- struct pmap *pmap, struct vm_eventinfo *info);
-typedef void (*vmi_cleanup_func_t)(void *vmi);
-typedef void * (*vmi_vcpu_init_func_t)(void *vmi, struct vcpu *vcpu,
- int vcpu_id);
-typedef void (*vmi_vcpu_cleanup_func_t)(void *vcpui);
-typedef int (*vmi_get_register_t)(void *vcpui, int num, uint64_t *retval);
-typedef int (*vmi_set_register_t)(void *vcpui, int num, uint64_t val);
-typedef int (*vmi_get_desc_t)(void *vcpui, int num, struct seg_desc *desc);
-typedef int (*vmi_set_desc_t)(void *vcpui, int num, struct seg_desc *desc);
-typedef int (*vmi_get_cap_t)(void *vcpui, int num, int *retval);
-typedef int (*vmi_set_cap_t)(void *vcpui, int num, int val);
-typedef struct vmspace * (*vmi_vmspace_alloc)(vm_offset_t min, vm_offset_t max);
-typedef void (*vmi_vmspace_free)(struct vmspace *vmspace);
-typedef struct vlapic * (*vmi_vlapic_init)(void *vcpui);
-typedef void (*vmi_vlapic_cleanup)(struct vlapic *vlapic);
-typedef int (*vmi_snapshot_vcpu_t)(void *vcpui, struct vm_snapshot_meta *meta);
-typedef int (*vmi_restore_tsc_t)(void *vcpui, uint64_t now);
+#define DECLARE_VMMOPS_FUNC(ret_type, opname, args) \
+ typedef ret_type (*vmmops_##opname##_t) args; \
+ ret_type vmmops_##opname args
+
+DECLARE_VMMOPS_FUNC(int, modinit, (int ipinum));
+DECLARE_VMMOPS_FUNC(int, modcleanup, (void));
+DECLARE_VMMOPS_FUNC(void, modresume, (void));
+DECLARE_VMMOPS_FUNC(void, modsuspend, (void));
+DECLARE_VMMOPS_FUNC(void *, init, (struct vm *vm, struct pmap *pmap));
+DECLARE_VMMOPS_FUNC(int, run, (void *vcpui, register_t pc,
+ struct pmap *pmap, struct vm_eventinfo *info));
+DECLARE_VMMOPS_FUNC(void, cleanup, (void *vmi));
+DECLARE_VMMOPS_FUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
+ int vcpu_id));
+DECLARE_VMMOPS_FUNC(void, vcpu_cleanup, (void *vcpui));
+DECLARE_VMMOPS_FUNC(int, getreg, (void *vcpui, int num, uint64_t *retval));
+DECLARE_VMMOPS_FUNC(int, setreg, (void *vcpui, int num, uint64_t val));
+DECLARE_VMMOPS_FUNC(int, getdesc, (void *vcpui, int num,
+ struct seg_desc *desc));
+DECLARE_VMMOPS_FUNC(int, setdesc, (void *vcpui, int num,
+ struct seg_desc *desc));
+DECLARE_VMMOPS_FUNC(int, getcap, (void *vcpui, int num, int *retval));
+DECLARE_VMMOPS_FUNC(int, setcap, (void *vcpui, int num, int val));
+DECLARE_VMMOPS_FUNC(struct vmspace *, vmspace_alloc,
+ (vm_offset_t min, vm_offset_t max));
+DECLARE_VMMOPS_FUNC(void, vmspace_free, (struct vmspace *vmspace));
+DECLARE_VMMOPS_FUNC(struct vlapic *, vlapic_init, (void *vcpui));
+DECLARE_VMMOPS_FUNC(void, vlapic_cleanup, (struct vlapic *vlapic));
+DECLARE_VMMOPS_FUNC(int, vcpu_snapshot, (void *vcpui,
+ struct vm_snapshot_meta *meta));
+DECLARE_VMMOPS_FUNC(int, restore_tsc, (void *vcpui, uint64_t now));
struct vmm_ops {
- vmm_init_func_t modinit; /* module wide initialization */
- vmm_cleanup_func_t modcleanup;
- vmm_resume_func_t modsuspend;
- vmm_resume_func_t modresume;
-
- vmi_init_func_t init; /* vm-specific initialization */
- vmi_run_func_t run;
- vmi_cleanup_func_t cleanup;
- vmi_vcpu_init_func_t vcpu_init;
- vmi_vcpu_cleanup_func_t vcpu_cleanup;
- vmi_get_register_t getreg;
- vmi_set_register_t setreg;
- vmi_get_desc_t getdesc;
- vmi_set_desc_t setdesc;
- vmi_get_cap_t getcap;
- vmi_set_cap_t setcap;
- vmi_vmspace_alloc vmspace_alloc;
- vmi_vmspace_free vmspace_free;
- vmi_vlapic_init vlapic_init;
- vmi_vlapic_cleanup vlapic_cleanup;
+ vmmops_modinit_t modinit; /* module wide initialization */
+ vmmops_modcleanup_t modcleanup;
+ vmmops_modresume_t modsuspend;
+ vmmops_modresume_t modresume;
+
+ vmmops_init_t init; /* vm-specific initialization */
+ vmmops_run_t run;
+ vmmops_cleanup_t cleanup;
+ vmmops_vcpu_init_t vcpu_init;
+ vmmops_vcpu_cleanup_t vcpu_cleanup;
+ vmmops_getreg_t getreg;
+ vmmops_setreg_t setreg;
+ vmmops_getdesc_t getdesc;
+ vmmops_setdesc_t setdesc;
+ vmmops_getcap_t getcap;
+ vmmops_setcap_t setcap;
+ vmmops_vmspace_alloc_t vmspace_alloc;
+ vmmops_vmspace_free_t vmspace_free;
+ vmmops_vlapic_init_t vlapic_init;
+ vmmops_vlapic_cleanup_t vlapic_cleanup;
/* checkpoint operations */
- vmi_snapshot_vcpu_t vcpu_snapshot;
- vmi_restore_tsc_t restore_tsc;
+ vmmops_vcpu_snapshot_t vcpu_snapshot;
+ vmmops_restore_tsc_t restore_tsc;
};
extern const struct vmm_ops vmm_ops_intel;
@@ -375,7 +383,6 @@ vcpu_should_yield(struct vcpu *vcpu)
void *vcpu_stats(struct vcpu *vcpu);
void vcpu_notify_event(struct vcpu *vcpu, bool lapic_intr);
-struct vmspace *vm_vmspace(struct vm *vm);
struct vm_mem *vm_mem(struct vm *vm);
struct vatpic *vm_atpic(struct vm *vm);
struct vatpit *vm_atpit(struct vm *vm);
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index c42da02d0bf6..2ac076551165 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -163,7 +163,6 @@ struct vm {
void *rendezvous_arg; /* (x) [r] rendezvous func/arg */
vm_rendezvous_func_t rendezvous_func;
struct mtx rendezvous_mtx; /* (o) rendezvous lock */
- struct vmspace *vmspace; /* (o) guest's address space */
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 */
@@ -201,7 +200,7 @@ vmmops_panic(void)
}
#define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \
- DEFINE_IFUNC(static, ret_type, vmmops_##opname, args) \
+ DEFINE_IFUNC(, ret_type, vmmops_##opname, args) \
{ \
if (vmm_is_intel()) \
return (vmm_ops_intel.opname); \
@@ -499,7 +498,7 @@ MODULE_VERSION(vmm, 1);
static void
vm_init(struct vm *vm, bool create)
{
- vm->cookie = vmmops_init(vm, vmspace_pmap(vm->vmspace));
+ vm->cookie = vmmops_init(vm, vmspace_pmap(vm_vmspace(vm)));
vm->iommu = NULL;
vm->vioapic = vioapic_init(vm);
vm->vhpet = vhpet_init(vm);
@@ -584,7 +583,7 @@ int
vm_create(const char *name, struct vm **retvm)
{
struct vm *vm;
- struct vmspace *vmspace;
+ int error;
/*
* If vmm.ko could not be successfully initialized then don't attempt
@@ -597,14 +596,13 @@ vm_create(const char *name, struct vm **retvm)
VM_MAX_NAMELEN + 1)
return (EINVAL);
- vmspace = vmmops_vmspace_alloc(0, VM_MAXUSER_ADDRESS_LA48);
- if (vmspace == NULL)
- return (ENOMEM);
-
vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO);
+ error = vm_mem_init(&vm->mem, 0, VM_MAXUSER_ADDRESS_LA48);
+ if (error != 0) {
+ free(vm, M_VM);
+ return (error);
+ }
strcpy(vm->name, name);
- vm->vmspace = vmspace;
- vm_mem_init(&vm->mem);
mtx_init(&vm->rendezvous_mtx, "vm rendezvous lock", 0, MTX_DEF);
sx_init(&vm->vcpus_init_lock, "vm vcpus");
vm->vcpu = malloc(sizeof(*vm->vcpu) * vm_maxcpu, M_VM, M_WAITOK |
@@ -685,9 +683,6 @@ vm_cleanup(struct vm *vm, bool destroy)
if (destroy) {
vm_mem_destroy(vm);
- vmmops_vmspace_free(vm->vmspace);
- vm->vmspace = NULL;
-
free(vm->vcpu, M_VM);
sx_destroy(&vm->vcpus_init_lock);
mtx_destroy(&vm->rendezvous_mtx);
@@ -731,7 +726,7 @@ vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa)
{
vm_object_t obj;
- if ((obj = vmm_mmio_alloc(vm->vmspace, gpa, len, hpa)) == NULL)
+ if ((obj = vmm_mmio_alloc(vm_vmspace(vm), gpa, len, hpa)) == NULL)
return (ENOMEM);
else
return (0);
@@ -741,19 +736,21 @@ int
vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len)
{
- vmm_mmio_free(vm->vmspace, gpa, len);
+ vmm_mmio_free(vm_vmspace(vm), gpa, len);
return (0);
}
static int
vm_iommu_map(struct vm *vm)
{
+ pmap_t pmap;
vm_paddr_t gpa, hpa;
struct vm_mem_map *mm;
int error, i;
sx_assert(&vm->mem.mem_segs_lock, SX_LOCKED);
+ pmap = vmspace_pmap(vm_vmspace(vm));
for (i = 0; i < VM_MAX_MEMMAPS; i++) {
if (!vm_memseg_sysmem(vm, i))
continue;
@@ -767,7 +764,7 @@ vm_iommu_map(struct vm *vm)
mm->flags |= VM_MEMMAP_F_IOMMU;
for (gpa = mm->gpa; gpa < mm->gpa + mm->len; gpa += PAGE_SIZE) {
- hpa = pmap_extract(vmspace_pmap(vm->vmspace), gpa);
+ hpa = pmap_extract(pmap, gpa);
/*
* All mappings in the vmm vmspace must be
@@ -816,7 +813,7 @@ vm_iommu_unmap(struct vm *vm)
for (gpa = mm->gpa; gpa < mm->gpa + mm->len; gpa += PAGE_SIZE) {
KASSERT(vm_page_wired(PHYS_TO_VM_PAGE(pmap_extract(
- vmspace_pmap(vm->vmspace), gpa))),
+ vmspace_pmap(vm_vmspace(vm)), gpa))),
("vm_iommu_unmap: vm %p gpa %jx not wired",
vm, (uintmax_t)gpa));
iommu_remove_mapping(vm->iommu, gpa, PAGE_SIZE);
@@ -1249,7 +1246,7 @@ vm_handle_paging(struct vcpu *vcpu, bool *retu)
("vm_handle_paging: invalid fault_type %d", ftype));
if (ftype == VM_PROT_READ || ftype == VM_PROT_WRITE) {
- rv = pmap_emulate_accessed_dirty(vmspace_pmap(vm->vmspace),
+ rv = pmap_emulate_accessed_dirty(vmspace_pmap(vm_vmspace(vm)),
vme->u.paging.gpa, ftype);
if (rv == 0) {
VMM_CTR2(vcpu, "%s bit emulation for gpa %#lx",
@@ -1259,7 +1256,7 @@ vm_handle_paging(struct vcpu *vcpu, bool *retu)
}
}
- map = &vm->vmspace->vm_map;
+ map = &vm_vmspace(vm)->vm_map;
rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL, NULL);
VMM_CTR3(vcpu, "vm_handle_paging rv = %d, gpa = %#lx, "
@@ -1560,7 +1557,7 @@ vm_run(struct vcpu *vcpu)
if (CPU_ISSET(vcpuid, &vm->suspended_cpus))
return (EINVAL);
- pmap = vmspace_pmap(vm->vmspace);
+ pmap = vmspace_pmap(vm_vmspace(vm));
vme = &vcpu->exitinfo;
evinfo.rptr = &vm->rendezvous_req_cpus;
evinfo.sptr = &vm->suspend;
@@ -2302,12 +2299,6 @@ vcpu_notify_event(struct vcpu *vcpu, bool lapic_intr)
vcpu_unlock(vcpu);
}
-struct vmspace *
-vm_vmspace(struct vm *vm)
-{
- return (vm->vmspace);
-}
-
struct vm_mem *
vm_mem(struct vm *vm)
{
@@ -2519,7 +2510,7 @@ vm_get_rescnt(struct vcpu *vcpu, struct vmm_stat_type *stat)
if (vcpu->vcpuid == 0) {
vmm_stat_set(vcpu, VMM_MEM_RESIDENT, PAGE_SIZE *
- vmspace_resident_count(vcpu->vm->vmspace));
+ vmspace_resident_count(vm_vmspace(vcpu->vm)));
}
}
@@ -2529,7 +2520,7 @@ vm_get_wiredcnt(struct vcpu *vcpu, struct vmm_stat_type *stat)
if (vcpu->vcpuid == 0) {
vmm_stat_set(vcpu, VMM_MEM_WIRED, PAGE_SIZE *
- pmap_wired_count(vmspace_pmap(vcpu->vm->vmspace)));
+ pmap_wired_count(vmspace_pmap(vm_vmspace(vcpu->vm))));
}
}
diff --git a/sys/amd64/vmm/vmm_dev_machdep.c b/sys/amd64/vmm/vmm_dev_machdep.c
index d8d2b460404c..dfebc9dcadbf 100644
--- a/sys/amd64/vmm/vmm_dev_machdep.c
+++ b/sys/amd64/vmm/vmm_dev_machdep.c
@@ -48,6 +48,7 @@
#include <x86/apicreg.h>
#include <dev/vmm/vmm_dev.h>
+#include <dev/vmm/vmm_mem.h>
#include <dev/vmm/vmm_stat.h>
#include "vmm_lapic.h"
diff --git a/sys/arm64/include/vmm.h b/sys/arm64/include/vmm.h
index e839b5dd92c9..84b286a60b38 100644
--- a/sys/arm64/include/vmm.h
+++ b/sys/arm64/include/vmm.h
@@ -143,6 +143,37 @@ struct vm_eventinfo {
int *iptr; /* reqidle cookie */
};
+#define DECLARE_VMMOPS_FUNC(ret_type, opname, args) \
+ ret_type vmmops_##opname args
+
+DECLARE_VMMOPS_FUNC(int, modinit, (int ipinum));
+DECLARE_VMMOPS_FUNC(int, modcleanup, (void));
+DECLARE_VMMOPS_FUNC(void *, init, (struct vm *vm, struct pmap *pmap));
+DECLARE_VMMOPS_FUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
+ uint64_t gla, int prot, uint64_t *gpa, int *is_fault));
+DECLARE_VMMOPS_FUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
+ struct vm_eventinfo *info));
+DECLARE_VMMOPS_FUNC(void, cleanup, (void *vmi));
+DECLARE_VMMOPS_FUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
+ int vcpu_id));
+DECLARE_VMMOPS_FUNC(void, vcpu_cleanup, (void *vcpui));
+DECLARE_VMMOPS_FUNC(int, exception, (void *vcpui, uint64_t esr, uint64_t far));
+DECLARE_VMMOPS_FUNC(int, getreg, (void *vcpui, int num, uint64_t *retval));
+DECLARE_VMMOPS_FUNC(int, setreg, (void *vcpui, int num, uint64_t val));
+DECLARE_VMMOPS_FUNC(int, getcap, (void *vcpui, int num, int *retval));
+DECLARE_VMMOPS_FUNC(int, setcap, (void *vcpui, int num, int val));
+DECLARE_VMMOPS_FUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
+ vm_offset_t max));
+DECLARE_VMMOPS_FUNC(void, vmspace_free, (struct vmspace *vmspace));
+#ifdef notyet
+#ifdef BHYVE_SNAPSHOT
+DECLARE_VMMOPS_FUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta *meta));
+DECLARE_VMMOPS_FUNC(int, vcpu_snapshot, (void *vcpui,
+ struct vm_snapshot_meta *meta));
+DECLARE_VMMOPS_FUNC(int, restore_tsc, (void *vcpui, uint64_t now));
+#endif
+#endif
+
int vm_create(const char *name, struct vm **retvm);
struct vcpu *vm_alloc_vcpu(struct vm *vm, int vcpuid);
void vm_disable_vcpu_creation(struct vm *vm);
@@ -232,7 +263,6 @@ vcpu_should_yield(struct vcpu *vcpu)
void *vcpu_stats(struct vcpu *vcpu);
void vcpu_notify_event(struct vcpu *vcpu);
-struct vmspace *vm_vmspace(struct vm *vm);
struct vm_mem *vm_mem(struct vm *vm);
enum vm_reg_name vm_segment_name(int seg_encoding);
diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h
index f9b74aef7188..f530dab05331 100644
--- a/sys/arm64/vmm/arm64.h
+++ b/sys/arm64/vmm/arm64.h
@@ -136,37 +136,6 @@ struct hyp {
struct hypctx *ctx[];
};
-#define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \
- ret_type vmmops_##opname args;
-
-DEFINE_VMMOPS_IFUNC(int, modinit, (int ipinum))
-DEFINE_VMMOPS_IFUNC(int, modcleanup, (void))
-DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap))
-DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
- uint64_t gla, int prot, uint64_t *gpa, int *is_fault))
-DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
- struct vm_eventinfo *info))
-DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi))
-DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
- int vcpu_id))
-DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui))
-DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t esr, uint64_t far))
-DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval))
-DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val))
-DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval))
-DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val))
-DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
- vm_offset_t max))
-DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace))
-#ifdef notyet
-#ifdef BHYVE_SNAPSHOT
-DEFINE_VMMOPS_IFUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta *meta))
-DEFINE_VMMOPS_IFUNC(int, vcpu_snapshot, (void *vcpui,
- struct vm_snapshot_meta *meta))
-DEFINE_VMMOPS_IFUNC(int, restore_tsc, (void *vcpui, uint64_t now))
-#endif
-#endif
-
uint64_t vmm_call_hyp(uint64_t, ...);
#if 0
diff --git a/sys/arm64/vmm/vmm.c b/sys/arm64/vmm/vmm.c
index a551a2807183..aeda689f3b1a 100644
--- a/sys/arm64/vmm/vmm.c
+++ b/sys/arm64/vmm/vmm.c
@@ -88,7 +88,6 @@ struct vcpu {
struct vfpstate *guestfpu; /* (a,i) guest fpu state */
};
-#define vcpu_lock_initialized(v) mtx_initialized(&((v)->mtx))
#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))
@@ -126,7 +125,6 @@ struct vm {
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 vmspace *vmspace; /* (o) guest's address space */
struct vm_mem mem; /* (i) guest memory */
char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
struct vcpu **vcpu; /* (i) guest vcpus */
@@ -274,6 +272,7 @@ vcpu_cleanup(struct vcpu *vcpu, bool destroy)
vmm_stat_free(vcpu->stats);
fpu_save_area_free(vcpu->guestfpu);
vcpu_lock_destroy(vcpu);
+ free(vcpu, M_VMM);
}
}
@@ -407,7 +406,7 @@ vm_init(struct vm *vm, bool create)
{
int i;
- vm->cookie = vmmops_init(vm, vmspace_pmap(vm->vmspace));
+ vm->cookie = vmmops_init(vm, vmspace_pmap(vm_vmspace(vm)));
MPASS(vm->cookie != NULL);
CPU_ZERO(&vm->active_cpus);
@@ -485,7 +484,7 @@ int
vm_create(const char *name, struct vm **retvm)
{
struct vm *vm;
- struct vmspace *vmspace;
+ int error;
/*
* If vmm.ko could not be successfully initialized then don't attempt
@@ -497,14 +496,13 @@ vm_create(const char *name, struct vm **retvm)
if (name == NULL || strlen(name) >= VM_MAX_NAMELEN)
return (EINVAL);
- vmspace = vmmops_vmspace_alloc(0, 1ul << 39);
- if (vmspace == NULL)
- return (ENOMEM);
-
vm = malloc(sizeof(struct vm), M_VMM, M_WAITOK | M_ZERO);
+ error = vm_mem_init(&vm->mem, 0, 1ul << 39);
+ if (error != 0) {
+ free(vm, M_VMM);
+ return (error);
+ }
strcpy(vm->name, name);
- vm->vmspace = vmspace;
- vm_mem_init(&vm->mem);
sx_init(&vm->vcpus_init_lock, "vm vcpus");
vm->sockets = 1;
@@ -558,7 +556,7 @@ vm_cleanup(struct vm *vm, bool destroy)
if (destroy) {
vm_xlock_memsegs(vm);
- pmap = vmspace_pmap(vm->vmspace);
+ pmap = vmspace_pmap(vm_vmspace(vm));
sched_pin();
PCPU_SET(curvmpmap, NULL);
sched_unpin();
@@ -582,11 +580,6 @@ vm_cleanup(struct vm *vm, bool destroy)
if (destroy) {
vm_mem_destroy(vm);
- vmmops_vmspace_free(vm->vmspace);
- vm->vmspace = NULL;
-
- for (i = 0; i < vm->maxcpus; i++)
- free(vm->vcpu[i], M_VMM);
free(vm->vcpu, M_VMM);
sx_destroy(&vm->vcpus_init_lock);
}
@@ -1090,12 +1083,6 @@ vcpu_notify_event(struct vcpu *vcpu)
vcpu_unlock(vcpu);
}
-struct vmspace *
-vm_vmspace(struct vm *vm)
-{
- return (vm->vmspace);
-}
-
struct vm_mem *
vm_mem(struct vm *vm)
{
@@ -1416,7 +1403,7 @@ vm_handle_paging(struct vcpu *vcpu, bool *retu)
vme = &vcpu->exitinfo;
- pmap = vmspace_pmap(vcpu->vm->vmspace);
+ pmap = vmspace_pmap(vm_vmspace(vcpu->vm));
addr = vme->u.paging.gpa;
esr = vme->u.paging.esr;
@@ -1433,7 +1420,7 @@ vm_handle_paging(struct vcpu *vcpu, bool *retu)
panic("%s: Invalid exception (esr = %lx)", __func__, esr);
}
- map = &vm->vmspace->vm_map;
+ map = &vm_vmspace(vm)->vm_map;
rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL, NULL);
if (rv != KERN_SUCCESS)
return (EFAULT);
@@ -1507,7 +1494,7 @@ vm_run(struct vcpu *vcpu)
if (CPU_ISSET(vcpuid, &vm->suspended_cpus))
return (EINVAL);
- pmap = vmspace_pmap(vm->vmspace);
+ pmap = vmspace_pmap(vm_vmspace(vm));
vme = &vcpu->exitinfo;
evinfo.rptr = NULL;
evinfo.sptr = &vm->suspend;
diff --git a/sys/dev/ice/ice_common.c b/sys/dev/ice/ice_common.c
index ad4ea4c8e7a1..b895f661bc46 100644
--- a/sys/dev/ice/ice_common.c
+++ b/sys/dev/ice/ice_common.c
@@ -213,6 +213,15 @@ int ice_set_mac_type(struct ice_hw *hw)
case ICE_DEV_ID_E830_L_QSFP:
case ICE_DEV_ID_E830C_SFP:
case ICE_DEV_ID_E830_L_SFP:
+ case ICE_DEV_ID_E835CC_BACKPLANE:
+ case ICE_DEV_ID_E835CC_QSFP56:
+ case ICE_DEV_ID_E835CC_SFP:
+ case ICE_DEV_ID_E835C_BACKPLANE:
+ case ICE_DEV_ID_E835C_QSFP:
+ case ICE_DEV_ID_E835C_SFP:
+ case ICE_DEV_ID_E835_L_BACKPLANE:
+ case ICE_DEV_ID_E835_L_QSFP:
+ case ICE_DEV_ID_E835_L_SFP:
hw->mac_type = ICE_MAC_E830;
break;
default:
diff --git a/sys/dev/ice/ice_devids.h b/sys/dev/ice/ice_devids.h
index 3f91e9dfbcaf..74712c61ae8e 100644
--- a/sys/dev/ice/ice_devids.h
+++ b/sys/dev/ice/ice_devids.h
@@ -62,6 +62,24 @@
#define ICE_DEV_ID_E830C_SFP 0x12DA
/* Intel(R) Ethernet Controller E830-L for SFP */
#define ICE_DEV_ID_E830_L_SFP 0x12DE
+/* Intel(R) Ethernet Controller E835-CC for backplane */
+#define ICE_DEV_ID_E835CC_BACKPLANE 0x1248
+/* Intel(R) Ethernet Controller E835-CC for QSFP */
+#define ICE_DEV_ID_E835CC_QSFP56 0x1249
+/* Intel(R) Ethernet Controller E835-CC for SFP */
+#define ICE_DEV_ID_E835CC_SFP 0x124A
+/* Intel(R) Ethernet Controller E835-C for backplane */
+#define ICE_DEV_ID_E835C_BACKPLANE 0x1261
+/* Intel(R) Ethernet Controller E835-C for QSFP */
+#define ICE_DEV_ID_E835C_QSFP 0x1262
+/* Intel(R) Ethernet Controller E835-C for SFP */
+#define ICE_DEV_ID_E835C_SFP 0x1263
+/* Intel(R) Ethernet Controller E835-L for backplane */
+#define ICE_DEV_ID_E835_L_BACKPLANE 0x1265
+/* Intel(R) Ethernet Controller E835-L for QSFP */
+#define ICE_DEV_ID_E835_L_QSFP 0x1266
+/* Intel(R) Ethernet Controller E835-L for SFP */
+#define ICE_DEV_ID_E835_L_SFP 0x1267
/* Intel(R) Ethernet Controller E810-C for backplane */
#define ICE_DEV_ID_E810C_BACKPLANE 0x1591
/* Intel(R) Ethernet Controller E810-C for QSFP */
diff --git a/sys/dev/ice/ice_drv_info.h b/sys/dev/ice/ice_drv_info.h
index 2a51a7394424..46965f4124bc 100644
--- a/sys/dev/ice/ice_drv_info.h
+++ b/sys/dev/ice/ice_drv_info.h
@@ -218,6 +218,45 @@ static const pci_vendor_info_t ice_vendor_info_array[] = {
"Intel(R) Ethernet Network Adapter E830-XXV-2"),
PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E830_L_SFP,
"Intel(R) Ethernet Connection E830-L for SFP"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_BACKPLANE,
+ "Intel(R) Ethernet Connection E835-CC for backplane"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_QSFP56,
+ ICE_INTEL_VENDOR_ID, 0x0001, 0,
+ "Intel(R) Ethernet Network Adapter E835-C-Q2"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_QSFP56,
+ ICE_INTEL_VENDOR_ID, 0x0002, 0,
+ "Intel(R) Ethernet Network Adapter E835-C-Q2 for OCP 3.0"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_QSFP56,
+ ICE_INTEL_VENDOR_ID, 0x0003, 0,
+ "Intel(R) Ethernet Network Adapter E835-CC-Q1"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_QSFP56,
+ ICE_INTEL_VENDOR_ID, 0x0004, 0,
+ "Intel(R) Ethernet Network Adapter E835-CC-Q1 for OCP 3.0"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_QSFP56,
+ "Intel(R) Ethernet Connection E835-CC for QSFP56"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP,
+ ICE_INTEL_VENDOR_ID, 0x0001, 0,
+ "Intel(R) Ethernet Network Adapter E835-XXV-2 for OCP 3.0"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP,
+ ICE_INTEL_VENDOR_ID, 0x0003, 0,
+ "Intel(R) Ethernet Network Adapter E835-XXV-2"),
+ PVIDV_OEM(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP,
+ ICE_INTEL_VENDOR_ID, 0x0004, 0,
+ "Intel(R) Ethernet Network Adapter E835-XXV-4 for OCP 3.0"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835CC_SFP,
+ "Intel(R) Ethernet Connection E835-CC for SFP"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835C_BACKPLANE,
+ "Intel(R) Ethernet Connection E835-C for backplane"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835C_QSFP,
+ "Intel(R) Ethernet Connection E835-C for QSFP"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835C_SFP,
+ "Intel(R) Ethernet Connection E835-C for SFP"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835_L_BACKPLANE,
+ "Intel(R) Ethernet Connection E835-L for backplane"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835_L_QSFP,
+ "Intel(R) Ethernet Connection E835-L for QSFP"),
+ PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E835_L_SFP,
+ "Intel(R) Ethernet Connection E835-L for SFP"),
PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825C_BACKPLANE,
"Intel(R) Ethernet Connection E825-C for backplane"),
PVIDV(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E825C_QSFP,
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index 6d08bd49bc04..1d36fd11f368 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -192,6 +192,8 @@ static int ixgbe_if_i2c_req(if_ctx_t, struct ifi2creq *);
static bool ixgbe_if_needs_restart(if_ctx_t, enum iflib_restart_event);
int ixgbe_intr(void *);
+static int ixgbe_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data);
+
/************************************************************************
* Function prototypes
************************************************************************/
@@ -239,6 +241,13 @@ static void ixgbe_setup_vlan_hw_support(if_ctx_t);
static void ixgbe_config_gpie(struct ixgbe_softc *);
static void ixgbe_config_delay_values(struct ixgbe_softc *);
+static void ixgbe_add_debug_sysctls(struct ixgbe_softc *sc);
+static void ixgbe_add_debug_dump_sysctls(struct ixgbe_softc *sc);
+static int ixgbe_debug_dump_ioctl(struct ixgbe_softc *sc, struct ifdrv *ifd);
+static u8 ixgbe_debug_dump_print_cluster(struct ixgbe_softc *sc,
+ struct sbuf *sbuf, u8 cluster_id);
+static int ixgbe_nvm_access_ioctl(struct ixgbe_softc *sc, struct ifdrv *ifd);
+
/* Sysctl handlers */
static int ixgbe_sysctl_flowcntl(SYSCTL_HANDLER_ARGS);
static int ixgbe_sysctl_advertise(SYSCTL_HANDLER_ARGS);
@@ -260,6 +269,9 @@ static int ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS);
static int ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS);
static int ixgbe_sysctl_tso_tcp_flags_mask(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_debug_dump_set_clusters(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_dump_debug_dump(SYSCTL_HANDLER_ARGS);
+
/* Deferred interrupt tasklets */
static void ixgbe_handle_msf(void *);
static void ixgbe_handle_mod(void *);
@@ -330,6 +342,7 @@ static device_method_t ixgbe_if_methods[] = {
DEVMETHOD(ifdi_get_counter, ixgbe_if_get_counter),
DEVMETHOD(ifdi_i2c_req, ixgbe_if_i2c_req),
DEVMETHOD(ifdi_needs_restart, ixgbe_if_needs_restart),
+ DEVMETHOD(ifdi_priv_ioctl, ixgbe_if_priv_ioctl),
#ifdef PCI_IOV
DEVMETHOD(ifdi_iov_init, ixgbe_if_iov_init),
DEVMETHOD(ifdi_iov_uninit, ixgbe_if_iov_uninit),
@@ -1015,6 +1028,8 @@ ixgbe_if_attach_pre(if_ctx_t ctx)
if (hw->mac.type == ixgbe_mac_E610)
ixgbe_init_aci(hw);
+ sc->do_debug_dump = false;
+
if (hw->mac.ops.fw_recovery_mode &&
hw->mac.ops.fw_recovery_mode(hw)) {
device_printf(dev,
@@ -1395,6 +1410,248 @@ ixgbe_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event)
}
/************************************************************************
+ * ixgbe_if_priv_ioctl - Ioctl handler for driver
+ *
+ * Handler for custom driver specific ioctls
+ *
+ * return 0 on success, positive on failure
+ ************************************************************************/
+static int
+ixgbe_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
+{
+ struct ixgbe_softc *sc = iflib_get_softc(ctx);
+ struct ifdrv *ifd;
+ device_t dev = sc->dev;
+
+ /* Make sure the command type is valid */
+ switch (command) {
+ case SIOCSDRVSPEC:
+ case SIOCGDRVSPEC:
+ /* Accepted commands */
+ break;
+ case SIOCGPRIVATE_0:
+ /*
+ * Although we do not support this ioctl command, it's expected
+ * that iflib will forward it to the IFDI_PRIV_IOCTL handler.
+ * Do not print a message in this case.
+ */
+ return (ENOTSUP);
+ default:
+ /*
+ * If we get a different command for this function, it's
+ * definitely unexpected, so log a message indicating what
+ * command we got for debugging purposes.
+ */
+ device_printf(dev,
+ "%s: unexpected ioctl command %08lx\n",
+ __func__, command);
+ return (EINVAL);
+ }
+
+ ifd = (struct ifdrv *)data;
+
+ switch (ifd->ifd_cmd) {
+ case IXGBE_NVM_ACCESS:
+ IOCTL_DEBUGOUT("ioctl: NVM ACCESS");
+ return (ixgbe_nvm_access_ioctl(sc, ifd));
+ case IXGBE_DEBUG_DUMP:
+ IOCTL_DEBUGOUT("ioctl: DEBUG DUMP");
+ return (ixgbe_debug_dump_ioctl(sc, ifd));
+ default:
+ IOCTL_DEBUGOUT1(
+ "ioctl: UNKNOWN SIOC(S|G)DRVSPEC (0x%X) command\n",
+ (int)ifd->ifd_cmd);
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+/************************************************************************
+ * ixgbe_nvm_access_ioctl
+ *
+ * Handles an NVM access ioctl request
+ ************************************************************************/
+static int
+ixgbe_nvm_access_ioctl(struct ixgbe_softc *sc, struct ifdrv *ifd)
+{
+ struct ixgbe_nvm_access_data *data;
+ struct ixgbe_nvm_access_cmd *cmd;
+ struct ixgbe_hw *hw = &sc->hw;
+ size_t ifd_len = ifd->ifd_len;
+ size_t malloc_len;
+ device_t dev = sc->dev;
+ u8 *nvm_buffer;
+ s32 error = 0;
+
+ /*
+ * ifioctl forwards SIOCxDRVSPEC to iflib without conducting
+ * a privilege check. Subsequently, iflib passes the ioctl to the driver
+ * without verifying privileges. To prevent non-privileged threads from
+ * accessing this interface, perform a privilege check at this point.
+ */
+ error = priv_check(curthread, PRIV_DRIVER);
+ if (error)
+ return (error);
+
+ if (ifd_len < sizeof(*cmd)) {
+ device_printf(dev,
+ "%s: ifdrv length is too small. Got %zu, "
+ "but expected %zu\n",
+ __func__, ifd_len, sizeof(*cmd));
+ return (EINVAL);
+ }
+
+ if (ifd->ifd_data == NULL) {
+ device_printf(dev, "%s: No ifd data buffer.\n",
+ __func__);
+ return (EINVAL);
+ }
+
+ malloc_len = max(ifd_len, sizeof(*data) + sizeof(*cmd));
+
+ nvm_buffer = (u8 *)malloc(malloc_len, M_IXGBE, M_ZERO | M_NOWAIT);
+ if (!nvm_buffer)
+ return (ENOMEM);
+
+ /* Copy the NVM access command and data in from user space */
+ error = copyin(ifd->ifd_data, nvm_buffer, ifd_len);
+ if (error) {
+ device_printf(dev, "%s: Failed to copy data in, error: %d\n",
+ __func__, error);
+ goto cleanup_free_nvm_buffer;
+ }
+
+ /*
+ * The NVM command structure is immediately followed by data which
+ * varies in size based on the command.
+ */
+ cmd = (struct ixgbe_nvm_access_cmd *)nvm_buffer;
+ data = (struct ixgbe_nvm_access_data *)
+ (nvm_buffer + sizeof(struct ixgbe_nvm_access_cmd));
+
+ /* Handle the NVM access request */
+ error = ixgbe_handle_nvm_access(hw, cmd, data);
+ if (error) {
+ device_printf(dev, "%s: NVM access request failed, error %d\n",
+ __func__, error);
+ }
+
+ /* Copy the possibly modified contents of the handled request out */
+ error = copyout(nvm_buffer, ifd->ifd_data, ifd_len);
+ if (error) {
+ device_printf(dev, "%s: Copying response back to "
+ "user space failed, error %d\n",
+ __func__, error);
+ goto cleanup_free_nvm_buffer;
+ }
+
+cleanup_free_nvm_buffer:
+ free(nvm_buffer, M_IXGBE);
+ return (error);
+}
+
+/************************************************************************
+ * ixgbe_debug_dump_ioctl
+ *
+ * Makes debug dump of internal FW/HW data.
+ ************************************************************************/
+static int
+ixgbe_debug_dump_ioctl(struct ixgbe_softc *sc, struct ifdrv *ifd)
+{
+ struct ixgbe_debug_dump_cmd *dd_cmd;
+ struct ixgbe_hw *hw = &sc->hw;
+ size_t ifd_len = ifd->ifd_len;
+ device_t dev = sc->dev;
+ s32 error = 0;
+
+ if (!(sc->feat_en & IXGBE_FEATURE_DBG_DUMP))
+ return (ENODEV);
+
+ /* Data returned from ACI command */
+ u16 ret_buf_size = 0;
+ u16 ret_next_cluster = 0;
+ u16 ret_next_table = 0;
+ u32 ret_next_index = 0;
+
+ /*
+ * ifioctl forwards SIOCxDRVSPEC to iflib without conducting
+ * a privilege check. Subsequently, iflib passes the ioctl to the driver
+ * without verifying privileges. To prevent non-privileged threads from
+ * accessing this interface, perform a privilege check at this point.
+ */
+ error = priv_check(curthread, PRIV_DRIVER);
+ if (error)
+ return (error);
+
+ if (ifd_len < sizeof(*dd_cmd)) {
+ device_printf(dev,
+ "%s: ifdrv length is too small. Got %zu, "
+ "but expected %zu\n",
+ __func__, ifd_len, sizeof(*dd_cmd));
+ return (EINVAL);
+ }
+
+ if (ifd->ifd_data == NULL) {
+ device_printf(dev, "%s: No ifd data buffer.\n",
+ __func__);
+ return (EINVAL);
+ }
+
+ dd_cmd = (struct ixgbe_debug_dump_cmd *)malloc(ifd_len, M_IXGBE,
+ M_NOWAIT | M_ZERO);
+ if (!dd_cmd) {
+ error = -ENOMEM;
+ goto out;
+ }
+ /* copy data from userspace */
+ error = copyin(ifd->ifd_data, dd_cmd, ifd_len);
+ if (error) {
+ device_printf(dev, "%s: Failed to copy data in, error: %d\n",
+ __func__, error);
+ goto out;
+ }
+
+ /* ACI command requires buf_size arg to be grater than 0 */
+ if (dd_cmd->data_size == 0) {
+ device_printf(dev, "%s: data_size must be greater than 0\n",
+ __func__);
+ error = EINVAL;
+ goto out;
+ }
+
+ /* Zero the data buffer memory space */
+ memset(dd_cmd->data, 0, ifd_len - sizeof(*dd_cmd));
+
+ error = ixgbe_aci_get_internal_data(hw, dd_cmd->cluster_id,
+ dd_cmd->table_id, dd_cmd->offset, dd_cmd->data, dd_cmd->data_size,
+ &ret_buf_size, &ret_next_cluster, &ret_next_table, &ret_next_index);
+ if (error) {
+ device_printf(dev,
+ "%s: Failed to get internal FW/HW data, error: %d\n",
+ __func__, error);
+ goto out;
+ }
+
+ dd_cmd->cluster_id = ret_next_cluster;
+ dd_cmd->table_id = ret_next_table;
+ dd_cmd->offset = ret_next_index;
+ dd_cmd->data_size = ret_buf_size;
+
+ error = copyout(dd_cmd, ifd->ifd_data, ifd->ifd_len);
+ if (error) {
+ device_printf(dev,
+ "%s: Failed to copy data out, error: %d\n",
+ __func__, error);
+ }
+
+out:
+ free(dd_cmd, M_IXGBE);
+
+ return (error);
+}
+
+/************************************************************************
* ixgbe_add_media_types
************************************************************************/
static void
@@ -2883,6 +3140,264 @@ ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS)
} /* ixgbe_sysctl_interrupt_rate_handler */
/************************************************************************
+ * ixgbe_debug_dump_print_cluster
+ ************************************************************************/
+static u8
+ixgbe_debug_dump_print_cluster(struct ixgbe_softc *sc, struct sbuf *sbuf,
+ u8 cluster_id)
+{
+ u16 data_buf_size = IXGBE_ACI_MAX_BUFFER_SIZE;
+ device_t dev = sc->dev;
+ struct ixgbe_hw *hw = &sc->hw;
+ const u8 reserved_buf[8] = {};
+ int max_aci_calls = 1000;
+ int error, counter = 0;
+ u8 *data_buf;
+
+ /* Input parameters / loop variables */
+ u16 table_id = 0;
+ u32 offset = 0;
+
+ /* Data returned from ACI command */
+ u16 ret_buf_size = 0;
+ u16 ret_next_cluster = 0;
+ u16 ret_next_table = 0;
+ u32 ret_next_index = 0;
+
+ data_buf = (u8 *)malloc(data_buf_size, M_IXGBE, M_NOWAIT | M_ZERO);
+ if (!data_buf)
+ return (0);
+
+ DEBUGOUT2("%s: dumping cluster id (relative) %d\n",
+ __func__, cluster_id);
+
+ do {
+ DEBUGOUT3("table_id 0x%04x offset 0x%08x buf_size %d\n",
+ table_id, offset, data_buf_size);
+
+ error = ixgbe_aci_get_internal_data(hw, cluster_id, table_id,
+ offset, data_buf, data_buf_size, &ret_buf_size,
+ &ret_next_cluster, &ret_next_table, &ret_next_index);
+ if (error) {
+ device_printf(dev,
+ "%s: Failed to get internal FW/HW data, error: %d, "
+ "last aci status: %d\n",
+ __func__, error, hw->aci.last_status);
+ break;
+ }
+
+ DEBUGOUT3("ret_table_id 0x%04x ret_offset 0x%08x "
+ "ret_buf_size %d\n",
+ ret_next_table, ret_next_index, ret_buf_size);
+
+ /* Print cluster id */
+ u32 print_cluster_id = (u32)cluster_id;
+ sbuf_bcat(sbuf, &print_cluster_id, sizeof(print_cluster_id));
+ /* Print table id */
+ u32 print_table_id = (u32)table_id;
+ sbuf_bcat(sbuf, &print_table_id, sizeof(print_table_id));
+ /* Print table length */
+ u32 print_table_length = (u32)ret_buf_size;
+ sbuf_bcat(sbuf, &print_table_length,
+ sizeof(print_table_length));
+ /* Print current offset */
+ u32 print_curr_offset = offset;
+ sbuf_bcat(sbuf, &print_curr_offset, sizeof(print_curr_offset));
+ /* Print reserved bytes */
+ sbuf_bcat(sbuf, reserved_buf, sizeof(reserved_buf));
+ /* Print data */
+ sbuf_bcat(sbuf, data_buf, ret_buf_size);
+
+ /* Prepare for the next loop spin */
+ memset(data_buf, 0, data_buf_size);
+
+ bool last_index = (ret_next_index == 0xffffffff);
+ bool last_table = ((ret_next_table == 0xff ||
+ ret_next_table == 0xffff) &&
+ last_index);
+
+ if (last_table) {
+ /* End of the cluster */
+ DEBUGOUT1("End of the cluster ID %d\n", cluster_id);
+ break;
+ } else if (last_index) {
+ /* End of the table */
+ table_id = ret_next_table;
+ offset = 0;
+ } else {
+ /* More data left in the table */
+ offset = ret_next_index;
+ }
+ } while (++counter < max_aci_calls);
+
+ if (counter >= max_aci_calls)
+ device_printf(dev, "Exceeded nr of ACI calls for cluster %d\n",
+ cluster_id);
+
+ free(data_buf, M_IXGBE);
+
+ return (++cluster_id);
+} /* ixgbe_print_debug_dump_cluster */
+
+/************************************************************************
+ * ixgbe_sysctl_debug_dump_set_clusters
+ *
+ * Sets the cluster to dump from FW when Debug Dump requested.
+ ************************************************************************/
+static int
+ixgbe_sysctl_debug_dump_set_clusters(SYSCTL_HANDLER_ARGS)
+{
+ struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
+ u32 clusters = sc->debug_dump_cluster_mask;
+ device_t dev = sc->dev;
+ int error;
+
+ error = sysctl_handle_32(oidp, &clusters, 0, req);
+ if ((error) || !req->newptr)
+ return (error);
+
+ if (clusters & ~(IXGBE_DBG_DUMP_VALID_CLUSTERS_MASK)) {
+ device_printf(dev,
+ "%s: Unrecognized parameter: %u\n",
+ __func__, clusters);
+ sc->debug_dump_cluster_mask =
+ IXGBE_ACI_DBG_DUMP_CLUSTER_ID_INVALID;
+ return (EINVAL);
+ }
+
+ sc->debug_dump_cluster_mask = clusters;
+
+ return (0);
+} /* ixgbe_sysctl_debug_dump_set_clusters */
+
+/************************************************************************
+ * ixgbe_sysctl_dump_debug_dump
+ ************************************************************************/
+static int
+ixgbe_sysctl_dump_debug_dump(SYSCTL_HANDLER_ARGS)
+{
+ struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
+ device_t dev = sc->dev;
+ struct sbuf *sbuf;
+ int error = 0;
+
+ UNREFERENCED_PARAMETER(arg2);
+
+ if (!sc->do_debug_dump) {
+ if (req->oldptr == NULL && req->newptr == NULL) {
+ error = SYSCTL_OUT(req, 0, 0);
+ return (error);
+ }
+
+ char input_buf[2] = "";
+ error = sysctl_handle_string(oidp, input_buf,
+ sizeof(input_buf), req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ if (input_buf[0] == '1') {
+ if (sc->debug_dump_cluster_mask ==
+ IXGBE_ACI_DBG_DUMP_CLUSTER_ID_INVALID) {
+ device_printf(dev,
+ "Debug Dump failed because an invalid "
+ "cluster was specified.\n");
+ return (EINVAL);
+ }
+
+ sc->do_debug_dump = true;
+ return (0);
+ }
+
+ return (EINVAL);
+ }
+
+ /* Caller just wants the upper bound for size */
+ if (req->oldptr == NULL && req->newptr == NULL) {
+ size_t est_output_len = IXGBE_DBG_DUMP_BASE_SIZE;
+ if (sc->debug_dump_cluster_mask & 0x2)
+ est_output_len += IXGBE_DBG_DUMP_BASE_SIZE;
+ error = SYSCTL_OUT(req, 0, est_output_len);
+ return (error);
+ }
+
+ sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+ sbuf_clear_flags(sbuf, SBUF_INCLUDENUL);
+
+ DEBUGOUT("FW Debug Dump running...\n");
+
+ if (sc->debug_dump_cluster_mask) {
+ for (u8 id = 0; id <= IXGBE_ACI_DBG_DUMP_CLUSTER_ID_MAX; id++) {
+ if (sc->debug_dump_cluster_mask & BIT(id)) {
+ DEBUGOUT1("Dumping cluster ID %u...\n", id);
+ ixgbe_debug_dump_print_cluster(sc, sbuf, id);
+ }
+ }
+ } else {
+ u8 next_cluster_id = 0;
+ do {
+ DEBUGOUT1("Dumping cluster ID %u...\n",
+ next_cluster_id);
+ next_cluster_id = ixgbe_debug_dump_print_cluster(sc,
+ sbuf, next_cluster_id);
+ } while (next_cluster_id != 0 &&
+ next_cluster_id <= IXGBE_ACI_DBG_DUMP_CLUSTER_ID_MAX);
+ }
+
+ sbuf_finish(sbuf);
+ sbuf_delete(sbuf);
+
+ sc->do_debug_dump = false;
+
+ return (error);
+} /* ixgbe_sysctl_dump_debug_dump */
+
+/************************************************************************
+ * ixgbe_add_debug_dump_sysctls
+ ************************************************************************/
+static void
+ixgbe_add_debug_dump_sysctls(struct ixgbe_softc *sc)
+{
+ struct sysctl_oid_list *debug_list, *dump_list;
+ struct sysctl_oid *dump_node;
+ struct sysctl_ctx_list *ctx;
+ device_t dev = sc->dev;
+
+ ctx = device_get_sysctl_ctx(dev);
+ debug_list = SYSCTL_CHILDREN(sc->debug_sysctls);
+
+ dump_node = SYSCTL_ADD_NODE(ctx, debug_list, OID_AUTO, "dump",
+ CTLFLAG_RD, NULL, "Internal FW/HW Dump");
+ dump_list = SYSCTL_CHILDREN(dump_node);
+
+ SYSCTL_ADD_PROC(ctx, dump_list, OID_AUTO, "clusters",
+ CTLTYPE_U32 | CTLFLAG_RW, sc, 0,
+ ixgbe_sysctl_debug_dump_set_clusters, "SU",
+ IXGBE_SYSCTL_DESC_DEBUG_DUMP_SET_CLUSTER);
+
+ SYSCTL_ADD_PROC(ctx, dump_list, OID_AUTO, "dump",
+ CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+ ixgbe_sysctl_dump_debug_dump, "",
+ IXGBE_SYSCTL_DESC_DUMP_DEBUG_DUMP);
+} /* ixgbe_add_debug_dump_sysctls */
+
+static void
+ixgbe_add_debug_sysctls(struct ixgbe_softc *sc)
+{
+ struct sysctl_oid_list *ctx_list;
+ struct sysctl_ctx_list *ctx;
+ device_t dev = sc->dev;
+
+ ctx = device_get_sysctl_ctx(dev);
+ ctx_list = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+
+ sc->debug_sysctls = SYSCTL_ADD_NODE(ctx, ctx_list, OID_AUTO, "debug",
+ CTLFLAG_RD, NULL, "Debug Sysctls");
+
+ if (sc->feat_en & IXGBE_FEATURE_DBG_DUMP)
+ ixgbe_add_debug_dump_sysctls(sc);
+} /* ixgbe_add_debug_sysctls */
+
+/************************************************************************
* ixgbe_add_device_sysctls
************************************************************************/
static void
@@ -2992,6 +3507,8 @@ ixgbe_add_device_sysctls(if_ctx_t ctx)
CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ixgbe_sysctl_eee_state, "I", "EEE Power Save State");
}
+
+ ixgbe_add_debug_sysctls(sc);
} /* ixgbe_add_device_sysctls */
/************************************************************************
@@ -5182,6 +5699,7 @@ ixgbe_init_device_features(struct ixgbe_softc *sc)
break;
case ixgbe_mac_E610:
sc->feat_cap |= IXGBE_FEATURE_RECOVERY_MODE;
+ sc->feat_cap |= IXGBE_FEATURE_DBG_DUMP;
break;
default:
break;
@@ -5203,6 +5721,9 @@ ixgbe_init_device_features(struct ixgbe_softc *sc)
/* Recovery mode */
if (sc->feat_cap & IXGBE_FEATURE_RECOVERY_MODE)
sc->feat_en |= IXGBE_FEATURE_RECOVERY_MODE;
+ /* FW Debug Dump */
+ if (sc->feat_cap & IXGBE_FEATURE_DBG_DUMP)
+ sc->feat_en |= IXGBE_FEATURE_DBG_DUMP;
/* Enabled via global sysctl... */
/* Flow Director */
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
index 844064bf8543..624b71acabea 100644
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -46,6 +46,7 @@
#include <sys/module.h>
#include <sys/sockio.h>
#include <sys/eventhandler.h>
+#include <sys/priv.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -475,6 +476,20 @@ struct ixgbe_softc {
u32 feat_cap;
u32 feat_en;
u16 lse_mask;
+
+ struct sysctl_oid *debug_sysctls;
+ u32 debug_dump_cluster_mask;
+ bool do_debug_dump;
+};
+
+struct ixgbe_debug_dump_cmd {
+ u32 offset; /* offset to read/write from table, in bytes */
+ u8 cluster_id; /* also used to get next cluster id */
+ u16 table_id;
+ u16 data_size; /* size of data field, in bytes */
+ u16 reserved1;
+ u32 reserved2;
+ u8 data[];
};
/* Precision Time Sync (IEEE 1588) defines */
@@ -499,6 +514,43 @@ struct ixgbe_softc {
#define IXGBE_PHY_CURRENT_TEMP 0xC820
#define IXGBE_PHY_OVERTEMP_STATUS 0xC830
+/**
+ * The ioctl command number used by NVM update for accessing the driver for
+ * NVM access commands.
+ */
+#define IXGBE_NVM_ACCESS \
+ (((((((('E' << 4) + '1') << 4) + 'K') << 4) + 'G') << 4) | 5)
+
+/*
+ * The ioctl command number used by a userspace tool for accessing the driver
+ * for getting debug dump data from the firmware.
+ */
+#define IXGBE_DEBUG_DUMP \
+ (((((((('E' << 4) + '1') << 4) + 'K') << 4) + 'G') << 4) | 6)
+
+/* Debug Dump related definitions */
+#define IXGBE_ACI_DBG_DUMP_CLUSTER_ID_INVALID 0xFFFFFF
+#define IXGBE_ACI_DBG_DUMP_CLUSTER_ID_BASE 50
+#define IXGBE_ACI_DBG_DUMP_CLUSTER_ID_MAX 1
+
+#define IXGBE_DBG_DUMP_VALID_CLUSTERS_MASK 0x3
+#define IXGBE_DBG_DUMP_BASE_SIZE (2 * 1024 * 1024)
+
+#define IXGBE_SYSCTL_DESC_DEBUG_DUMP_SET_CLUSTER \
+"\nSelect clusters to dump with \"dump\" sysctl" \
+"\nFlags:" \
+"\n\t 0x1 - Link" \
+"\n\t 0x2 - Full CSR Space, excluding RCW registers" \
+"\n\t" \
+"\nUse \"sysctl -x\" to view flags properly."
+
+#define IXGBE_SYSCTL_DESC_DUMP_DEBUG_DUMP \
+"\nWrite 1 to output a FW debug dump containing the clusters " \
+"specified by the \"clusters\" sysctl" \
+"\nThe \"-b\" flag must be used in order to dump this data " \
+"as binary data because" \
+"\nthis data is opaque and not a string."
+
/* Sysctl help messages; displayed with sysctl -d */
#define IXGBE_SYSCTL_DESC_ADV_SPEED \
"\nControl advertised link speed using these flags:\n" \
diff --git a/sys/dev/ixgbe/ixgbe_features.h b/sys/dev/ixgbe/ixgbe_features.h
index 0cef334a185f..bee9040319d8 100644
--- a/sys/dev/ixgbe/ixgbe_features.h
+++ b/sys/dev/ixgbe/ixgbe_features.h
@@ -57,6 +57,7 @@
#define IXGBE_FEATURE_LEGACY_IRQ (u32)(1 << 12)
#define IXGBE_FEATURE_NEEDS_CTXD (u32)(1 << 13)
#define IXGBE_FEATURE_RECOVERY_MODE (u32)(1 << 15)
+#define IXGBE_FEATURE_DBG_DUMP (u32)(1 << 16)
/* Check for OS support. Undefine features if not included in the OS */
#ifndef PCI_IOV
diff --git a/sys/dev/vmm/vmm_mem.c b/sys/dev/vmm/vmm_mem.c
index be59e37de33d..9df31c9ba133 100644
--- a/sys/dev/vmm/vmm_mem.c
+++ b/sys/dev/vmm/vmm_mem.c
@@ -26,10 +26,14 @@
static void vm_free_memmap(struct vm *vm, int ident);
-void
-vm_mem_init(struct vm_mem *mem)
+int
+vm_mem_init(struct vm_mem *mem, vm_offset_t lo, vm_offset_t hi)
{
+ mem->mem_vmspace = vmmops_vmspace_alloc(lo, hi);
+ if (mem->mem_vmspace == NULL)
+ return (ENOMEM);
sx_init(&mem->mem_segs_lock, "vm_mem_segs");
+ return (0);
}
static bool
@@ -93,10 +97,21 @@ vm_mem_destroy(struct vm *vm)
for (int i = 0; i < VM_MAX_MEMSEGS; i++)
vm_free_memseg(vm, i);
+ vmmops_vmspace_free(mem->mem_vmspace);
+
sx_xunlock(&mem->mem_segs_lock);
sx_destroy(&mem->mem_segs_lock);
}
+struct vmspace *
+vm_vmspace(struct vm *vm)
+{
+ struct vm_mem *mem;
+
+ mem = vm_mem(vm);
+ return (mem->mem_vmspace);
+}
+
void
vm_slock_memsegs(struct vm *vm)
{
@@ -246,7 +261,7 @@ vm_mmap_memseg(struct vm *vm, vm_paddr_t gpa, int segid, vm_ooffset_t first,
struct vm_mem *mem;
struct vm_mem_seg *seg;
struct vm_mem_map *m, *map;
- struct vmspace *vmspace;
+ struct vm_map *vmmap;
vm_ooffset_t last;
int i, error;
@@ -282,19 +297,19 @@ vm_mmap_memseg(struct vm *vm, vm_paddr_t gpa, int segid, vm_ooffset_t first,
if (map == NULL)
return (ENOSPC);
- vmspace = vm_vmspace(vm);
- error = vm_map_find(&vmspace->vm_map, seg->object, first, &gpa,
- len, 0, VMFS_NO_SPACE, prot, prot, 0);
+ vmmap = &mem->mem_vmspace->vm_map;
+ error = vm_map_find(vmmap, seg->object, first, &gpa, len, 0,
+ VMFS_NO_SPACE, prot, prot, 0);
if (error != KERN_SUCCESS)
return (EFAULT);
vm_object_reference(seg->object);
if (flags & VM_MEMMAP_F_WIRED) {
- error = vm_map_wire(&vmspace->vm_map, gpa, gpa + len,
+ error = vm_map_wire(vmmap, gpa, gpa + len,
VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
if (error != KERN_SUCCESS) {
- vm_map_remove(&vmspace->vm_map, gpa, gpa + len);
+ vm_map_remove(vmmap, gpa, gpa + len);
return (error == KERN_RESOURCE_SHORTAGE ? ENOMEM :
EFAULT);
}
diff --git a/sys/dev/vmm/vmm_mem.h b/sys/dev/vmm/vmm_mem.h
index 856470cf2590..f3d22058c7b8 100644
--- a/sys/dev/vmm/vmm_mem.h
+++ b/sys/dev/vmm/vmm_mem.h
@@ -36,6 +36,7 @@ enum {
struct vm;
struct vm_object;
+struct vmspace;
struct vm_mem_seg {
size_t len;
@@ -56,12 +57,15 @@ struct vm_mem {
struct vm_mem_map mem_maps[VM_MAX_MEMMAPS];
struct vm_mem_seg mem_segs[VM_MAX_MEMSEGS];
struct sx mem_segs_lock;
+ struct vmspace *mem_vmspace;
};
-void vm_mem_init(struct vm_mem *mem);
+int vm_mem_init(struct vm_mem *mem, vm_offset_t lo, vm_offset_t hi);
void vm_mem_cleanup(struct vm *vm);
void vm_mem_destroy(struct vm *vm);
+struct vmspace *vm_vmspace(struct vm *vm);
+
/*
* APIs that modify the guest memory map require all vcpus to be frozen.
*/
diff --git a/sys/netpfil/ipfw/ip_dn_io.c b/sys/netpfil/ipfw/ip_dn_io.c
index 03116cb0641c..3a8de2b2bfee 100644
--- a/sys/netpfil/ipfw/ip_dn_io.c
+++ b/sys/netpfil/ipfw/ip_dn_io.c
@@ -43,6 +43,7 @@
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
+#include <sys/sdt.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/sysctl.h>
@@ -70,6 +71,9 @@
#endif
#include <netpfil/ipfw/dn_sched.h>
+SDT_PROVIDER_DEFINE(dummynet);
+SDT_PROBE_DEFINE2(dummynet, , , drop, "struct mbuf *", "struct dn_queue *");
+
/*
* We keep a private variable for the simulation time, but we could
* probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
@@ -545,6 +549,7 @@ dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
drop:
V_dn_cfg.io_pkt_drop++;
+ SDT_PROBE2(dummynet, , , drop, m, q);
q->ni.drops++;
ni->drops++;
FREE_PKT(m);
@@ -1001,6 +1006,7 @@ done:
dropit:
V_dn_cfg.io_pkt_drop++;
+ SDT_PROBE2(dummynet, , , drop, m, q);
DN_BH_WUNLOCK();
if (m)
FREE_PKT(m);
diff --git a/sys/riscv/include/vmm.h b/sys/riscv/include/vmm.h
index de7119dd534a..bc00474ed0fd 100644
--- a/sys/riscv/include/vmm.h
+++ b/sys/riscv/include/vmm.h
@@ -123,6 +123,29 @@ struct vm_eventinfo {
int *iptr; /* reqidle cookie */
};
+#define DECLARE_VMMOPS_FUNC(ret_type, opname, args) \
+ ret_type vmmops_##opname args
+
+DECLARE_VMMOPS_FUNC(int, modinit, (void));
+DECLARE_VMMOPS_FUNC(int, modcleanup, (void));
+DECLARE_VMMOPS_FUNC(void *, init, (struct vm *vm, struct pmap *pmap));
+DECLARE_VMMOPS_FUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
+ uint64_t gla, int prot, uint64_t *gpa, int *is_fault));
+DECLARE_VMMOPS_FUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
+ struct vm_eventinfo *info));
+DECLARE_VMMOPS_FUNC(void, cleanup, (void *vmi));
+DECLARE_VMMOPS_FUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
+ int vcpu_id));
+DECLARE_VMMOPS_FUNC(void, vcpu_cleanup, (void *vcpui));
+DECLARE_VMMOPS_FUNC(int, exception, (void *vcpui, uint64_t scause));
+DECLARE_VMMOPS_FUNC(int, getreg, (void *vcpui, int num, uint64_t *retval));
+DECLARE_VMMOPS_FUNC(int, setreg, (void *vcpui, int num, uint64_t val));
+DECLARE_VMMOPS_FUNC(int, getcap, (void *vcpui, int num, int *retval));
+DECLARE_VMMOPS_FUNC(int, setcap, (void *vcpui, int num, int val));
+DECLARE_VMMOPS_FUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
+ vm_offset_t max));
+DECLARE_VMMOPS_FUNC(void, vmspace_free, (struct vmspace *vmspace));
+
int vm_create(const char *name, struct vm **retvm);
struct vcpu *vm_alloc_vcpu(struct vm *vm, int vcpuid);
void vm_disable_vcpu_creation(struct vm *vm);
@@ -212,7 +235,6 @@ vcpu_should_yield(struct vcpu *vcpu)
void *vcpu_stats(struct vcpu *vcpu);
void vcpu_notify_event(struct vcpu *vcpu);
-struct vmspace *vm_vmspace(struct vm *vm);
struct vm_mem *vm_mem(struct vm *vm);
enum vm_reg_name vm_segment_name(int seg_encoding);
diff --git a/sys/riscv/vmm/riscv.h b/sys/riscv/vmm/riscv.h
index 870d0d6c5cd1..917a333520ed 100644
--- a/sys/riscv/vmm/riscv.h
+++ b/sys/riscv/vmm/riscv.h
@@ -122,29 +122,6 @@ struct hyptrap {
uint64_t htinst;
};
-#define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \
- ret_type vmmops_##opname args;
-
-DEFINE_VMMOPS_IFUNC(int, modinit, (void))
-DEFINE_VMMOPS_IFUNC(int, modcleanup, (void))
-DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap))
-DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
- uint64_t gla, int prot, uint64_t *gpa, int *is_fault))
-DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
- struct vm_eventinfo *info))
-DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi))
-DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
- int vcpu_id))
-DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui))
-DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t scause))
-DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval))
-DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val))
-DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval))
-DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val))
-DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
- vm_offset_t max))
-DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace))
-
#define dprintf(fmt, ...)
struct hypctx *riscv_get_active_vcpu(void);
diff --git a/sys/riscv/vmm/vmm.c b/sys/riscv/vmm/vmm.c
index ec4514f70fa6..790dcc576507 100644
--- a/sys/riscv/vmm/vmm.c
+++ b/sys/riscv/vmm/vmm.c
@@ -92,7 +92,6 @@ struct vcpu {
struct fpreg *guestfpu; /* (a,i) guest fpu state */
};
-#define vcpu_lock_initialized(v) mtx_initialized(&((v)->mtx))
#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))
@@ -121,7 +120,6 @@ struct vm {
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 vmspace *vmspace; /* (o) guest's address space */
struct vm_mem mem; /* (i) [m+v] guest memory */
char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
struct vcpu **vcpu; /* (i) guest vcpus */
@@ -174,6 +172,7 @@ vcpu_cleanup(struct vcpu *vcpu, bool destroy)
vmm_stat_free(vcpu->stats);
fpu_save_area_free(vcpu->guestfpu);
vcpu_lock_destroy(vcpu);
+ free(vcpu, M_VMM);
}
}
@@ -285,7 +284,7 @@ vm_init(struct vm *vm, bool create)
{
int i;
- vm->cookie = vmmops_init(vm, vmspace_pmap(vm->vmspace));
+ vm->cookie = vmmops_init(vm, vmspace_pmap(vm_vmspace(vm)));
MPASS(vm->cookie != NULL);
CPU_ZERO(&vm->active_cpus);
@@ -362,7 +361,7 @@ int
vm_create(const char *name, struct vm **retvm)
{
struct vm *vm;
- struct vmspace *vmspace;
+ int error;
/*
* If vmm.ko could not be successfully initialized then don't attempt
@@ -374,14 +373,13 @@ vm_create(const char *name, struct vm **retvm)
if (name == NULL || strlen(name) >= VM_MAX_NAMELEN)
return (EINVAL);
- vmspace = vmmops_vmspace_alloc(0, 1ul << 39);
- if (vmspace == NULL)
- return (ENOMEM);
-
vm = malloc(sizeof(struct vm), M_VMM, M_WAITOK | M_ZERO);
+ error = vm_mem_init(&vm->mem, 0, 1ul << 39);
+ if (error != 0) {
+ free(vm, M_VMM);
+ return (error);
+ }
strcpy(vm->name, name);
- vm->vmspace = vmspace;
- vm_mem_init(&vm->mem);
sx_init(&vm->vcpus_init_lock, "vm vcpus");
vm->sockets = 1;
@@ -450,11 +448,6 @@ vm_cleanup(struct vm *vm, bool destroy)
if (destroy) {
vm_mem_destroy(vm);
- vmmops_vmspace_free(vm->vmspace);
- vm->vmspace = NULL;
-
- for (i = 0; i < vm->maxcpus; i++)
- free(vm->vcpu[i], M_VMM);
free(vm->vcpu, M_VMM);
sx_destroy(&vm->vcpus_init_lock);
}
@@ -760,12 +753,6 @@ vcpu_notify_event(struct vcpu *vcpu)
vcpu_unlock(vcpu);
}
-struct vmspace *
-vm_vmspace(struct vm *vm)
-{
- return (vm->vmspace);
-}
-
struct vm_mem *
vm_mem(struct vm *vm)
{
@@ -1084,7 +1071,7 @@ vm_handle_paging(struct vcpu *vcpu, bool *retu)
vm = vcpu->vm;
vme = &vcpu->exitinfo;
- pmap = vmspace_pmap(vm->vmspace);
+ pmap = vmspace_pmap(vm_vmspace(vm));
addr = (vme->htval << 2) & ~(PAGE_SIZE - 1);
dprintf("%s: %lx\n", __func__, addr);
@@ -1107,7 +1094,7 @@ vm_handle_paging(struct vcpu *vcpu, bool *retu)
if (pmap_fault(pmap, addr, ftype))
return (0);
- map = &vm->vmspace->vm_map;
+ map = &vm_vmspace(vm)->vm_map;
rv = vm_fault(map, addr, ftype, VM_FAULT_NORMAL, NULL);
if (rv != KERN_SUCCESS) {
printf("%s: vm_fault failed, addr %lx, ftype %d, err %d\n",
@@ -1189,7 +1176,7 @@ vm_run(struct vcpu *vcpu)
if (CPU_ISSET(vcpuid, &vm->suspended_cpus))
return (EINVAL);
- pmap = vmspace_pmap(vm->vmspace);
+ pmap = vmspace_pmap(vm_vmspace(vm));
vme = &vcpu->exitinfo;
evinfo.rptr = NULL;
evinfo.sptr = &vm->suspend;
diff --git a/sys/sys/user.h b/sys/sys/user.h
index 3183f0792256..1704bc089d85 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -617,7 +617,8 @@ struct kinfo_vmobject {
} kvo_type_spec; /* Type-specific union */
uint64_t kvo_me; /* Uniq handle for anon obj */
uint64_t kvo_laundry; /* Number of laundry pages. */
- uint64_t _kvo_qspare[5];
+ uint64_t kvo_wired; /* Number of wired pages. */
+ uint64_t _kvo_qspare[4];
uint32_t kvo_swapped; /* Number of swapped pages */
uint32_t kvo_flags;
uint32_t _kvo_ispare[6];
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 6d9ea8bf9d93..5b4517d2bf0c 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -2522,15 +2522,13 @@ vm_object_list_handler(struct sysctl_req *req, bool swap_only)
continue;
}
mtx_unlock(&vm_object_list_mtx);
+
+ memset(kvo, 0, sizeof(*kvo));
kvo->kvo_size = ptoa(obj->size);
kvo->kvo_resident = obj->resident_page_count;
kvo->kvo_ref_count = obj->ref_count;
kvo->kvo_shadow_count = atomic_load_int(&obj->shadow_count);
kvo->kvo_memattr = obj->memattr;
- kvo->kvo_active = 0;
- kvo->kvo_inactive = 0;
- kvo->kvo_laundry = 0;
- kvo->kvo_flags = 0;
if (!swap_only) {
vm_page_iter_init(&pages, obj);
VM_RADIX_FOREACH(m, &pages) {
@@ -2549,12 +2547,12 @@ vm_object_list_handler(struct sysctl_req *req, bool swap_only)
kvo->kvo_inactive++;
else if (vm_page_in_laundry(m))
kvo->kvo_laundry++;
+
+ if (vm_page_wired(m))
+ kvo->kvo_wired++;
}
}
- kvo->kvo_vn_fileid = 0;
- kvo->kvo_vn_fsid = 0;
- kvo->kvo_vn_fsid_freebsd11 = 0;
freepath = NULL;
fullpath = "";
vp = NULL;