User Tools

Site Tools


struct vm_stats {
        int             cpuid;                          /* in */
        int             num_entries;                    /* out */
        struct timeval  tv;
        uint64_t        statbuf[MAX_VM_STATS];
};
 
struct vm_stat_desc {
        int             index;                          /* in */
        char            desc[128];                      /* out */
};
 
struct vm_cpu_topology {
        uint16_t        sockets;
        uint16_t        cores;
        uint16_t        threads;
        uint16_t        maxcpus;
}
vmm_dev.c
static int
vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
             struct thread *td) { 
    	case VM_RUN:
	case VM_GET_REGISTER:
	case VM_SET_REGISTER:
	case VM_GET_SEGMENT_DESCRIPTOR:
	case VM_SET_SEGMENT_DESCRIPTOR:
	case VM_GET_REGISTER_SET:
	case VM_SET_REGISTER_SET:
	case VM_INJECT_EXCEPTION:
	case VM_GET_CAPABILITY:
	case VM_SET_CAPABILITY:
	case VM_PPTDEV_MSI:
	case VM_PPTDEV_MSIX:
	case VM_SET_X2APIC_STATE:
	case VM_GLA2GPA:
	case VM_GLA2GPA_NOFAULT:
	case VM_ACTIVATE_CPU:
	case VM_SET_INTINFO:
	case VM_GET_INTINFO:
	case VM_RESTART_INSTRUCTION:
	case VM_MAP_PPTDEV_MMIO:
	case VM_BIND_PPTDEV:
	case VM_UNBIND_PPTDEV:
	case VM_ALLOC_MEMSEG:
	case VM_MMAP_MEMSEG:
	case VM_REINIT:
	case VM_GET_MEMSEG:
	case VM_MMAP_GETNEXT:
	case VM_RUN:
	case VM_SUSPEND:
	case VM_REINIT:
	case VM_STAT_DESC: {
	case VM_STATS: {
	case VM_PPTDEV_MSI:
	case VM_PPTDEV_MSIX:
	case VM_PPTDEV_DISABLE_MSIX:
	case VM_MAP_PPTDEV_MMIO:
	case VM_BIND_PPTDEV:
	case VM_UNBIND_PPTDEV:
	case VM_INJECT_EXCEPTION:
	case VM_INJECT_NMI:
	case VM_LAPIC_IRQ:
	case VM_LAPIC_LOCAL_IRQ:
	case VM_LAPIC_MSI:
	case VM_IOAPIC_ASSERT_IRQ:
	case VM_IOAPIC_DEASSERT_IRQ:
	case VM_IOAPIC_PULSE_IRQ:
	case VM_IOAPIC_PINCOUNT:
	case VM_ISA_ASSERT_IRQ:
	case VM_ISA_DEASSERT_IRQ:
	case VM_ISA_PULSE_IRQ:
	case VM_ISA_SET_IRQ_TRIGGER:
	case VM_MMAP_GETNEXT:
	case VM_MMAP_MEMSEG:
	case VM_ALLOC_MEMSEG:
	case VM_GET_MEMSEG:
	case VM_GET_REGISTER:
	case VM_SET_REGISTER:
	case VM_SET_SEGMENT_DESCRIPTOR:
	case VM_GET_SEGMENT_DESCRIPTOR:
	case VM_GET_REGISTER_SET:
	case VM_SET_REGISTER_SET:
	case VM_GET_CAPABILITY:
	case VM_SET_CAPABILITY:
	case VM_SET_X2APIC_STATE:
	case VM_GET_X2APIC_STATE:
	case VM_GET_GPA_PMAP:
	case VM_GET_HPET_CAPABILITIES:
	case VM_GLA2GPA: {
	case VM_GLA2GPA_NOFAULT:
	case VM_ACTIVATE_CPU:
	case VM_GET_CPUS:
	case VM_SUSPEND_CPU:
	case VM_RESUME_CPU:
	case VM_SET_INTINFO:
	case VM_GET_INTINFO:
	case VM_RTC_WRITE:
	case VM_RTC_READ:
	case VM_RTC_SETTIME:
	case VM_RTC_GETTIME:
	case VM_RESTART_INSTRUCTION:
	case VM_SET_TOPOLOGY:
	case VM_GET_TOPOLOGY:
}
proc.h
/*-
 * Description of a process.
 *
 * This structure contains the information needed to manage a thread of
 * control, known in UN*X as a process; it has references to substructures
 * containing descriptions of things that the process uses, but may share
 * with related processes.  The process structure and the substructures
 * are always addressable except for those marked "(CPU)" below,
 * which might be addressable only on a processor on which the process
 * is running.
 *
 * Below is a key of locks used to protect each member of struct proc.  The
 * lock is indicated by a reference to a specific character in parens in the
 * associated comment.
 *      * - not yet protected
 *      a - only touched by curproc or parent during fork/wait
 *      b - created at fork, never changes
 *              (exception aiods switch vmspaces, but they are also
 *              marked 'P_SYSTEM' so hopefully it will be left alone)
 *      c - locked by proc mtx
 *      d - locked by allproc_lock lock
 *      e - locked by proctree_lock lock
 *      f - session mtx
 *      g - process group mtx
 *      h - callout_lock mtx
 *      i - by curproc or the master session mtx
 *      j - locked by proc slock
 *      k - only accessed by curthread
 *      k*- only accessed by curthread and from an interrupt
 *      kx- only accessed by curthread and by debugger
 *      l - the attaching proc or attaching proc parent
 *      m - Giant
 *      n - not locked, lazy
 *      o - ktrace lock
 *      q - td_contested lock
 *      r - p_peers lock
 *      s - see sleepq_switch(), sleeping_on_old_rtc(), and sleep(9)
 *      t - thread lock
 *      u - process stat lock
 *      w - process timer lock
 *      x - created at fork, only changes during single threading in exec
 *      y - created at first aio, doesn't change until exit or exec at which
 *          point we are single-threaded and only curthread changes it
 *      z - zombie threads lock
 *
 * If the locking key specifies two identifiers (for example, p_pptr) then
 * either lock is sufficient for read access, but both locks must be held
 * for write access.
 */
struct cpuset;
struct filecaps;
struct filemon;
struct kaioinfo;
struct kaudit_record;
struct kdtrace_proc;
struct kdtrace_thread;
struct mqueue_notifier;
struct nlminfo;
struct p_sched;
struct proc;
struct procdesc;
struct racct;
struct sbuf;
struct sleepqueue;
struct socket;
 
/*
 * Kernel runnable context (thread).
 * This is what is put to sleep and reactivated.
 * Thread context.  Processes may have multiple threads.
 */
struct thread {
        struct mtx      *volatile td_lock; /* replaces sched lock */
        struct proc     *td_proc;       /* (*) Associated process. */
        TAILQ_ENTRY(thread) td_plist;   /* (*) All threads in this proc. */
        TAILQ_ENTRY(thread) td_runq;    /* (t) Run queue. */
        TAILQ_ENTRY(thread) td_slpq;    /* (t) Sleep queue. */
        TAILQ_ENTRY(thread) td_lockq;   /* (t) Lock queue. */
        LIST_ENTRY(thread) td_hash;     /* (d) Hash chain. */
        struct cpuset   *td_cpuset;     /* (t) CPU affinity mask. */
        struct domainset_ref td_domain; /* (a) NUMA policy */
        struct seltd    *td_sel;        /* Select queue/channel. */
        struct sleepqueue *td_sleepqueue; /* (k) Associated sleep queue. */
        struct turnstile *td_turnstile; /* (k) Associated turnstile. */
        struct rl_q_entry *td_rlqe;     /* (k) Associated range lock entry. */
        struct umtx_q   *td_umtxq;      /* (c?) Link for when we're blocked. */
        lwpid_t         td_tid;         /* (b) Thread ID. */
        sigqueue_t      td_sigqueue;    /* (c) Sigs arrived, not delivered. */
#define td_siglist      td_sigqueue.sq_signals
        u_char          td_lend_user_pri; /* (t) Lend user pri. */
 
/* Cleared during fork1() */
#define td_startzero td_epochnest
        u_char          td_epochnest;   /* (k) Epoch nest counter. */
        int             td_flags;       /* (t) TDF_* flags. */
        int             td_inhibitors;  /* (t) Why can not run. */
        int             td_pflags;      /* (k) Private thread (TDP_*) flags. */
        int             td_dupfd;       /* (k) Ret value from fdopen. XXX */
        int             td_sqqueue;     /* (t) Sleepqueue queue blocked on. */
        void            *td_wchan;      /* (t) Sleep address. */
        const char      *td_wmesg;      /* (t) Reason for sleep. */
        volatile u_char td_owepreempt;  /* (k*) Preempt on last critical_exit */
        u_char          td_tsqueue;     /* (t) Turnstile queue blocked on. */
        short           td_locks;       /* (k) Debug: count of non-spin locks */
        short           td_rw_rlocks;   /* (k) Count of rwlock read locks. */
        short           td_sx_slocks;   /* (k) Count of sx shared locks. */
        short           td_lk_slocks;   /* (k) Count of lockmgr shared locks. */
        short           td_stopsched;   /* (k) Scheduler stopped. */
        struct turnstile *td_blocked;   /* (t) Lock thread is blocked on. */
        const char      *td_lockname;   /* (t) Name of lock blocked on. */
        LIST_HEAD(, turnstile) td_contested;    /* (q) Contested locks. */
        struct lock_list_entry *td_sleeplocks; /* (k) Held sleep locks. */
        int             td_intr_nesting_level; /* (k) Interrupt recursion. */
        int             td_pinned;      /* (k) Temporary cpu pin count. */
        struct ucred    *td_ucred;      /* (k) Reference to credentials. */
        struct plimit   *td_limit;      /* (k) Resource limits. */
        int             td_slptick;     /* (t) Time at sleep. */
        int             td_blktick;     /* (t) Time spent blocked. */
        int             td_swvoltick;   /* (t) Time at last SW_VOL switch. */
        int             td_swinvoltick; /* (t) Time at last SW_INVOL switch. */
        u_int           td_cow;         /* (*) Number of copy-on-write faults */
        struct rusage   td_ru;          /* (t) rusage information. */
        struct rusage_ext td_rux;       /* (t) Internal rusage information. */
        uint64_t        td_incruntime;  /* (t) Cpu ticks to transfer to proc. */
        uint64_t        td_runtime;     /* (t) How many cpu ticks we've run. */
        u_int           td_pticks;      /* (t) Statclock hits for profiling */
        u_int           td_sticks;      /* (t) Statclock hits in system mode. */
        u_int           td_iticks;      /* (t) Statclock hits in intr mode. */
        u_int           td_uticks;      /* (t) Statclock hits in user mode. */
        int             td_intrval;     /* (t) Return value for sleepq. */
        sigset_t        td_oldsigmask;  /* (k) Saved mask from pre sigpause. */
        volatile u_int  td_generation;  /* (k) For detection of preemption */
        volatile u_int  td_generation;  /* (k) For detection of preemption */
        stack_t         td_sigstk;      /* (k) Stack ptr and on-stack flag. */
        int             td_xsig;        /* (c) Signal for ptrace */
        u_long          td_profil_addr; /* (k) Temporary addr until AST. */
        u_int           td_profil_ticks; /* (k) Temporary ticks until AST. */
        char            td_name[MAXCOMLEN + 1]; /* (*) Thread name. */
        struct file     *td_fpop;       /* (k) file referencing cdev under op */
        int             td_dbgflags;    /* (c) Userland debugger flags */
        siginfo_t       td_si;          /* (c) For debugger or core file */
        int             td_ng_outbound; /* (k) Thread entered ng from above. */
        struct osd      td_osd;         /* (k) Object specific data. */
        struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */
        pid_t           td_dbg_forked;  /* (c) Child pid for debugger. */
        u_int           td_vp_reserv;   /* (k) Count of reserved vnodes. */
        int             td_no_sleeping; /* (k) Sleeping disabled count. */
        void            *td_su;         /* (k) FFS SU private */
        sbintime_t      td_sleeptimo;   /* (t) Sleep timeout. */
        int             td_rtcgen;      /* (s) rtc_generation of abs. sleep */
        size_t          td_vslock_sz;   /* (k) amount of vslock-ed space */
#define td_endzero td_sigmask
 
/* Copied during fork1() or create_thread(). */
#define td_startcopy td_endzero
        sigset_t        td_sigmask;     /* (c) Current signal mask. */
        u_char          td_rqindex;     /* (t) Run queue index. */
        u_char          td_base_pri;    /* (t) Thread base kernel priority. */
        u_char          td_priority;    /* (t) Thread active priority. */
        u_char          td_pri_class;   /* (t) Scheduling class. */
        u_char          td_user_pri;    /* (t) User pri from estcpu and nice. */
        u_char          td_base_user_pri; /* (t) Base user pri */
        u_char          td_pre_epoch_prio; /* (k) User pri on entry to epoch */
        uintptr_t       td_rb_list;     /* (k) Robust list head. */
        uintptr_t       td_rbp_list;    /* (k) Robust priv list head. */
        uintptr_t       td_rb_inact;    /* (k) Current in-action mutex loc. */
        struct syscall_args td_sa;      /* (kx) Syscall parameters. Copied on
                                           fork for child tracing. */
#define td_endcopy td_pcb
 
/*
 * Fields that must be manually set in fork1() or create_thread()
 * or already have been set in the allocator, constructor, etc.
 */
       struct pcb      *td_pcb;        /* (k) Kernel VA of pcb and kstack. */
        enum {
                TDS_INACTIVE = 0x0,
                TDS_INHIBITED,
                TDS_CAN_RUN,
                TDS_RUNQ,
                TDS_RUNNING
        } td_state;                     /* (t) thread state */
        union {
                register_t      tdu_retval[2];
                off_t           tdu_off;
        } td_uretoff;                   /* (k) Syscall aux returns. */
#define td_retval       td_uretoff.tdu_retval
        u_int           td_cowgen;      /* (k) Generation of COW pointers. */
        /* LP64 hole */
        struct callout  td_slpcallout;  /* (h) Callout for sleep. */
        struct trapframe *td_frame;     /* (k) */
        struct vm_object *td_kstack_obj;/* (a) Kstack object. */
        vm_offset_t     td_kstack;      /* (a) Kernel VA of kstack. */
        int             td_kstack_pages; /* (a) Size of the kstack. */
        volatile u_int  td_critnest;    /* (k*) Critical section nest level. */
#ifdef __amd64__
        uint32_t        td_md_pad0[16];
#else
        struct mdthread td_md;          /* (k) Any machine-dependent fields. */
#endif
        struct kaudit_record    *td_ar; /* (k) Active audit record, if any. */
        struct lpohead  td_lprof[2];    /* (a) lock profiling objects. */
        struct kdtrace_thread   *td_dtrace; /* (*) DTrace-specific data. */
        int             td_errno;       /* Error returned by last syscall. */
        /* LP64 hole */
        struct vnet     *td_vnet;       /* (k) Effective vnet. */
        const char      *td_vnet_lpush; /* (k) Debugging vnet push / pop. */
        struct trapframe *td_intr_frame;/* (k) Frame of the current irq */
        struct proc     *td_rfppwait_p; /* (k) The vforked child */
        struct vm_page  **td_ma;        /* (k) uio pages held */
        int             td_ma_cnt;      /* (k) size of *td_ma */
        /* LP64 hole */
        void            *td_emuldata;   /* Emulator state data */
        int             td_lastcpu;     /* (t) Last cpu we were on. */
        int             td_oncpu;       /* (t) Which cpu we are on. */
        void            *td_lkpi_task;  /* LinuxKPI task struct pointer */
        int             td_pmcpend;
#ifdef __amd64__
        struct mdthread td_md;          /* (k) Any machine-dependent fields. */
#endif
        int             td_pflags2;     /* (k) Private thread (TDP2_*) flags. */
};
 
 
/*
 * Process structure.
 */
struct proc {
        LIST_ENTRY(proc) p_list;        /* (d) List of all processes. */
        TAILQ_HEAD(, thread) p_threads; /* (c) all threads. */
        struct mtx      p_slock;        /* process spin lock */
        struct ucred    *p_ucred;       /* (c) Process owner's identity. */
        struct filedesc *p_fd;          /* (b) Open files. */
        struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
        struct pstats   *p_stats;       /* (b) Accounting/statistics (CPU). */
        struct plimit   *p_limit;       /* (c) Resource limits. */
        struct callout  p_limco;        /* (c) Limit callout handle */
        struct sigacts  *p_sigacts;     /* (x) Signal actions, state (CPU). */
 
        int             p_flag;         /* (c) P_* flags. */
        int             p_flag2;        /* (c) P2_* flags. */
        enum {
                PRS_NEW = 0,            /* In creation */
                PRS_NORMAL,             /* threads can be run. */
                PRS_ZOMBIE
        } p_state;                      /* (j/c) Process status. */
        pid_t           p_pid;          /* (b) Process identifier. */
        LIST_ENTRY(proc) p_hash;        /* (d) Hash chain. */
        LIST_ENTRY(proc) p_pglist;      /* (g + e) List of processes in pgrp. */
        struct proc     *p_pptr;        /* (c + e) Pointer to parent process. */
        LIST_ENTRY(proc) p_sibling;     /* (e) List of sibling processes. */
        LIST_HEAD(, proc) p_children;   /* (e) Pointer to list of children. */
        struct proc     *p_reaper;      /* (e) My reaper. */
        LIST_HEAD(, proc) p_reaplist;   /* (e) List of my descendants
                                               (if I am reaper). */
        LIST_ENTRY(proc) p_reapsibling; /* (e) List of siblings - descendants of
                                               the same reaper. */
        struct mtx      p_mtx;          /* (n) Lock for this struct. */
        struct mtx      p_statmtx;      /* Lock for the stats */
        struct mtx      p_itimmtx;      /* Lock for the virt/prof timers */
        struct mtx      p_profmtx;      /* Lock for the profiling */
        struct ksiginfo *p_ksi; /* Locked by parent proc lock */
        sigqueue_t      p_sigqueue;     /* (c) Sigs not delivered to a td. */
#define p_siglist       p_sigqueue.sq_signals
        pid_t           p_oppid;        /* (c + e) Real parent pid. */
 
/* The following fields are all zeroed upon creation in fork. */
#define p_startzero     p_vmspace
        struct vmspace  *p_vmspace;     /* (b) Address space. */
        u_int           p_swtick;       /* (c) Tick when swapped in or out. */
        u_int           p_cowgen;       /* (c) Generation of COW pointers. */
        struct itimerval p_realtimer;   /* (c) Alarm timer. */
        struct rusage   p_ru;           /* (a) Exit information. */
        struct rusage_ext p_rux;        /* (cu) Internal resource usage. */
        struct rusage_ext p_crux;       /* (c) Internal child resource usage. */
        int             p_profthreads;  /* (c) Num threads in addupc_task. */
        volatile int    p_exitthreads;  /* (j) Number of threads exiting */
        int             p_traceflag;    /* (o) Kernel trace points. */
        struct vnode    *p_tracevp;     /* (c + o) Trace to vnode. */
       struct vnode    *p_tracevp;     /* (c + o) Trace to vnode. */
        struct ucred    *p_tracecred;   /* (o) Credentials to trace with. */
        struct vnode    *p_textvp;      /* (b) Vnode of executable. */
        u_int           p_lock;         /* (c) Proclock (prevent swap) count. */
        struct sigiolst p_sigiolst;     /* (c) List of sigio sources. */
        int             p_sigparent;    /* (c) Signal to parent on exit. */
        int             p_sig;          /* (n) For core dump/debugger XXX. */
        u_long          p_code;         /* (n) For core dump/debugger XXX. */
        u_int           p_stops;        /* (c) Stop event bitmask. */
        u_int           p_stype;        /* (c) Stop event type. */
        char            p_step;         /* (c) Process is stopped. */
        u_char          p_pfsflags;     /* (c) Procfs flags. */
        u_int           p_ptevents;     /* (c + e) ptrace() event mask. */
        struct nlminfo  *p_nlminfo;     /* (?) Only used by/for lockd. */
        struct kaioinfo *p_aioinfo;     /* (y) ASYNC I/O info. */
        struct thread   *p_singlethread;/* (c + j) If single threading this is it */
        int             p_suspcount;    /* (j) Num threads in suspended mode. */
        struct thread   *p_xthread;     /* (c) Trap thread */
        int             p_boundary_count;/* (j) Num threads at user boundary */
        int             p_pendingcnt;   /* how many signals are pending */
        struct itimers  *p_itimers;     /* (c) POSIX interval timers. */
        struct procdesc *p_procdesc;    /* (e) Process descriptor, if any. */
        u_int           p_treeflag;     /* (e) P_TREE flags */
        int             p_pendingexits; /* (c) Count of pending thread exits. */
        struct filemon  *p_filemon;     /* (c) filemon-specific data. */
        int             p_pdeathsig;    /* (c) Signal from parent on exit. */
/* End area that is zeroed on creation. */
#define p_endzero       p_magic
 
/* The following fields are all copied upon creation in fork. */
#define p_startcopy     p_endzero
        u_int           p_magic;        /* (b) Magic number. */
        int             p_osrel;        /* (x) osreldate for the
                                               binary (from ELF note, if any) */
        char            p_comm[MAXCOMLEN + 1];  /* (x) Process name. */
        struct sysentvec *p_sysent;     /* (b) Syscall dispatch info. */
        struct pargs    *p_args;        /* (c) Process arguments. */
        rlim_t          p_cpulimit;     /* (c) Current CPU limit in seconds. */
        signed char     p_nice;         /* (c) Process "nice" value. */
        int             p_fibnum;       /* in this routing domain XXX MRT */
        pid_t           p_reapsubtree;  /* (e) Pid of the direct child of the
                                               reaper which spawned
                                               our subtree. */
        uint16_t        p_elf_machine;  /* (x) ELF machine type */
        uint64_t        p_elf_flags;    /* (x) ELF flags */
/* End area that is copied on creation. */
#define p_endcopy       p_xexit
 
        u_int           p_xexit;        /* (c) Exit code. */
        u_int           p_xsig;         /* (c) Stop/kill sig. */
        struct pgrp     *p_pgrp;        /* (c + e) Pointer to process group. */
        struct knlist   *p_klist;       /* (c) Knotes attached to this proc. */
        int             p_numthreads;   /* (c) Number of threads. */
        struct mdproc   p_md;           /* Any machine-dependent fields. */
        struct callout  p_itcallout;    /* (h + c) Interval timer callout. */
        u_short         p_acflag;       /* (c) Accounting flags. */
        struct proc     *p_peers;       /* (r) */
        struct proc     *p_leader;      /* (b) */
 
        void            *p_emuldata;    /* (c) Emulator state data. */
        struct label    *p_label;       /* (*) Proc (not subject) MAC label. */
        STAILQ_HEAD(, ktr_request)      p_ktr;  /* (o) KTR event queue. */
        LIST_HEAD(, mqueue_notifier)    p_mqnotifier; /* (c) mqueue notifiers.*/
        struct kdtrace_proc     *p_dtrace; /* (*) DTrace-specific data. */
        struct cv       p_pwait;        /* (*) wait cv for exit/exec. */
        uint64_t        p_prev_runtime; /* (c) Resource usage accounting. */
        struct racct    *p_racct;       /* (b) Resource accounting. */
        int             p_throttled;    /* (c) Flag for racct pcpu throttling */
        /*
         * An orphan is the child that has been re-parented to the
         * debugger as a result of attaching to it.  Need to keep
         * track of them for parent to be able to collect the exit
         * status of what used to be children.
         */
        LIST_ENTRY(proc) p_orphan;      /* (e) List of orphan processes. */
        LIST_HEAD(, proc) p_orphans;    /* (e) Pointer to list of orphans. */
        uint32_t        p_fctl0;        /* (x) ABI feature control, ELF note */
        u_int           p_amd64_md_flags; /* (c) md process flags P_MD */
};
svm.h
/*
 * Guest register state that is saved outside the VMCB.
 */
struct svm_regctx {
        register_t      sctx_rbp;
        register_t      sctx_rbx;
        register_t      sctx_rcx;
        register_t      sctx_rdx;
        register_t      sctx_rdi;
        register_t      sctx_rsi;
        register_t      sctx_r8;
        register_t      sctx_r9;
        register_t      sctx_r10;
        register_t      sctx_r11;
        register_t      sctx_r12;
        register_t      sctx_r13;
        register_t      sctx_r14;
        register_t      sctx_r15;
        register_t      sctx_dr0;
        register_t      sctx_dr1;
        register_t      sctx_dr2;
        register_t      sctx_dr3;
 
        register_t      host_dr0;
        register_t      host_dr1;
        register_t      host_dr2;
        register_t      host_dr3;
        register_t      host_dr6;
        register_t      host_dr7;
        uint64_t        host_debugctl;
};
vmm.c
/*
 * 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             hostcpu;        /* (o) vcpu's host cpu */
        int             reqidle;        /* (i) request vcpu to idle */
        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 */
        uint64_t        nextrip;        /* (x) next instruction to execute */
};
 
 
/*
 * 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 */
        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 */
        int             suspend;                /* (i) stop VM execution */
        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) rendezvous requested */
        cpuset_t        rendezvous_done_cpus;   /* (x) rendezvous finished */
        void            *rendezvous_arg;        /* (x) rendezvous func/arg */
        vm_rendezvous_func_t rendezvous_func;
        struct mtx      rendezvous_mtx;         /* (o) rendezvous lock */
        struct mem_map  mem_maps[VM_MAX_MEMMAPS]; /* (i) guest address space */
        struct mem_seg  mem_segs[VM_MAX_MEMSEGS]; /* (o) guest memory regions */
        struct vmspace  *vmspace;               /* (o) guest's address space */
        char            name[VM_MAX_NAMELEN+1]; /* (o) virtual machine name */
        struct vcpu     vcpu[VM_MAXCPU];        /* (i) 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 */
};
 
vm_init(struct vm *vm, bool create)
{
        int i;
 
        vm->cookie = VMINIT(vm, vmspace_pmap(vm->vmspace));
        vm->iommu = NULL;
        vm->vioapic = vioapic_init(vm);
        vm->vhpet = vhpet_init(vm);
        vm->vatpic = vatpic_init(vm);
        vm->vatpit = vatpit_init(vm);
        vm->vpmtmr = vpmtmr_init(vm);
        if (create)
                vm->vrtc = vrtc_init(vm);
 
        CPU_ZERO(&vm->active_cpus);
        CPU_ZERO(&vm->debug_cpus);
 
        vm->suspend = 0;
        CPU_ZERO(&vm->suspended_cpus);
 
        for (i = 0; i < vm->maxcpus; i++)
                vcpu_init(vm, i, create);
}
 
 
#ifdef KTR
static const char *
vcpu_state2str(enum vcpu_state state) {
        switch (state) {
        case VCPU_IDLE:
                return ("idle");
        case VCPU_FROZEN:
                return ("frozen");
        case VCPU_RUNNING:
                return ("running");
        case VCPU_SLEEPING:
                return ("sleeping");
        default:
                return ("unknown");
        }
}
#endif
#  bhyvectl --vm=b13 --get-stats
vcpu0 stats:
timer interrupts generated by vlapic    	2908
corrected machine check interrupts generated by vlapic	0
lvts triggered[0]                       	0
lvts triggered[1]                       	0
lvts triggered[2]                       	0
lvts triggered[3]                       	0
lvts triggered[4]                       	0
lvts triggered[5]                       	0
lvts triggered[6]                       	0
ipis sent to vcpu[0]                    	0
ipis sent to vcpu[1]                    	2540
ipis sent to vcpu[2]                    	2476
ipis sent to vcpu[3]                    	0
ipis sent to vcpu[4]                    	0
ipis sent to vcpu[5]                    	0
ipis sent to vcpu[6]                    	0
ipis sent to vcpu[7]                    	0
ipis sent to vcpu[8]                    	0
ipis sent to vcpu[9]                    	0
ipis sent to vcpu[10]                   	0
ipis sent to vcpu[11]                   	0
ipis sent to vcpu[12]                   	0
ipis sent to vcpu[13]                   	0
ipis sent to vcpu[14]                   	0
ipis sent to vcpu[15]                   	0
Resident memory                         	172515328
Wired memory                            	0
Number of vpid invalidations saved      	0
Number of vpid invalidations done       	1960
vcpu migration across host cpus         	1960
total number of vm exits                	519101
vm exits due to external interrupt      	3905
number of times hlt was intercepted     	5223
number of times %cr access was intercepted	2
number of times rdmsr was intercepted   	8
number of times wrmsr was intercepted   	2
number of monitor trap exits            	0
number of times pause was intercepted   	159543
vm exits due to interrupt window opening	419
vm exits due to nmi window opening      	0
number of times in/out was intercepted  	179947
number of times cpuid was intercepted   	3594
vm exits due to nested page fault       	24507
vm exits for instruction emulation      	141950
number of vm exits for unknown reason   	0
number of times astpending at exit      	631
number of times idle requested at exit  	0
number of vm exits handled in userspace 	511180
number of times rendezvous pending at exit	10
number of vm exits due to exceptions    	0
vcpu total runtime                      	8808050026
number of ticks vcpu was idle           	110341
number of NMIs delivered to vcpu        	0
number of ExtINTs delivered to vcpu     	0
EOI without any in-service interrupt    	0
error interrupts generated by vlapic    	0
vmm_stat.c
 
/* global statistics */
VMM_STAT(VCPU_MIGRATIONS, "vcpu migration across host cpus");
VMM_STAT(VMEXIT_COUNT, "total number of vm exits");
VMM_STAT(VMEXIT_EXTINT, "vm exits due to external interrupt");
VMM_STAT(VMEXIT_HLT, "number of times hlt was intercepted");
VMM_STAT(VMEXIT_CR_ACCESS, "number of times %cr access was intercepted");
VMM_STAT(VMEXIT_RDMSR, "number of times rdmsr was intercepted");
VMM_STAT(VMEXIT_WRMSR, "number of times wrmsr was intercepted");
VMM_STAT(VMEXIT_MTRAP, "number of monitor trap exits");
VMM_STAT(VMEXIT_PAUSE, "number of times pause was intercepted");
VMM_STAT(VMEXIT_INTR_WINDOW, "vm exits due to interrupt window opening");
VMM_STAT(VMEXIT_NMI_WINDOW, "vm exits due to nmi window opening");
VMM_STAT(VMEXIT_INOUT, "number of times in/out was intercepted");
VMM_STAT(VMEXIT_CPUID, "number of times cpuid was intercepted");
VMM_STAT(VMEXIT_NESTED_FAULT, "vm exits due to nested page fault");
VMM_STAT(VMEXIT_INST_EMUL, "vm exits for instruction emulation");
VMM_STAT(VMEXIT_UNKNOWN, "number of vm exits for unknown reason");
VMM_STAT(VMEXIT_ASTPENDING, "number of times astpending at exit");
VMM_STAT(VMEXIT_REQIDLE, "number of times idle requested at exit");
VMM_STAT(VMEXIT_USERSPACE, "number of vm exits handled in userspace");
VMM_STAT(VMEXIT_RENDEZVOUS, "number of times rendezvous pending at exit");
VMM_STAT(VMEXIT_EXCEPTION, "number of vm exits due to exceptions");
vmm_stat.h
VMM_STAT_DECLARE(VCPU_MIGRATIONS);                                                                                              
VMM_STAT_DECLARE(VMEXIT_COUNT);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_EXTINT);                                                                                                
VMM_STAT_DECLARE(VMEXIT_HLT);                                                                                                   
VMM_STAT_DECLARE(VMEXIT_CR_ACCESS);                                                                                             
VMM_STAT_DECLARE(VMEXIT_RDMSR);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_WRMSR);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_MTRAP);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_PAUSE);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_INTR_WINDOW);                                                                                           
VMM_STAT_DECLARE(VMEXIT_NMI_WINDOW);                                                                                            
VMM_STAT_DECLARE(VMEXIT_INOUT);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_CPUID);                                                                                                 
VMM_STAT_DECLARE(VMEXIT_NESTED_FAULT);                                                                                          
VMM_STAT_DECLARE(VMEXIT_INST_EMUL);                                                                                             
VMM_STAT_DECLARE(VMEXIT_UNKNOWN);                                                                                               
VMM_STAT_DECLARE(VMEXIT_ASTPENDING);                                                                                            
VMM_STAT_DECLARE(VMEXIT_USERSPACE);                                                                                             
VMM_STAT_DECLARE(VMEXIT_RENDEZVOUS);                                                                                            
VMM_STAT_DECLARE(VMEXIT_EXCEPTION);                                                                                             
VMM_STAT_DECLARE(VMEXIT_REQIDLE);      
vmm.c
static VMM_STAT(VCPU_TOTAL_RUNTIME, "vcpu total runtime");
static VMM_STAT(VCPU_IDLE_TICKS, "number of ticks vcpu was idle");
static VMM_STAT(VCPU_NMI_COUNT, "number of NMIs delivered to vcpu");
static VMM_STAT(VCPU_EXTINT_COUNT, "number of ExtINTs delivered to vcpu");

https://uni.dtln.ru/digest/analiz-proizvoditelnosti-vm-v-vmware-vsphere-chast-1-cpu

Если ядро ВМ (vCPU) находится в состоянии Ready, оно не выполняет полезную работу. Такое состояние возникает, когда гипервизор не находит свободное физическое ядро, на которое можно назначить процесс vCPU виртуальной машины.

Как анализировать? Обычно если ядра виртуальной машины находятся в состоянии Ready больше 10% времени, то вы заметите проблемы с производительностью. Проще говоря, больше 10% времени ВМ ждет доступности физических ресурсов.

В vCenter можно посмотреть 2 счетчика, связанных с CPU Ready:

  Readiness,
  Ready.

Значения обоих счетчиков можно посмотреть как по всей ВМ, так и по отдельным ядрам.

Readiness показывает значение сразу в процентах, но только в Real-time (данные за последний час, интервал измерений 20 секунд). Этот счетчик лучше использовать только для поиска проблем “по горячим следам”.

Значения счетчика Ready можно посмотреть также в исторической перспективе. Это полезно, если нужно установить закономерности и для более глубокого анализа проблемы. Например, если у виртуальной машины начинаются проблемы с производительностью в какое-то определенное время, можно сопоставить интервалы повешенного значения CPU Ready с общей нагрузкой на сервер, где данная ВМ работает, и принять меры по снижению нагрузки (если DRS не справился).

Ready в отличие от Readiness показывается не в процентах, а миллисекундах. Это счетчик типа Summation, то есть он показывает, сколько времени за период измерения ядро ВМ находилось в состоянии Ready. Перевести данное значение в проценты можно по несложной формуле:

(CPU ready summation value / (chart default update interval in seconds * 1000)) * 100 = CPU ready %

Источник: https://kb.vmware.com/kb/200218

Например, для ВМ на графике ниже пиковое значение Ready на всю виртуальную машину получится следующим: