Print this page
13275 bhyve needs richer INIT/SIPI support
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>


 200 };
 201 
 202 struct vm_guest_paging {
 203         uint64_t        cr3;
 204         int             cpl;
 205         enum vm_cpu_mode cpu_mode;
 206         enum vm_paging_mode paging_mode;
 207 };
 208 
 209 enum vm_exitcode {
 210         VM_EXITCODE_INOUT,
 211         VM_EXITCODE_VMX,
 212         VM_EXITCODE_BOGUS,
 213         VM_EXITCODE_RDMSR,
 214         VM_EXITCODE_WRMSR,
 215         VM_EXITCODE_HLT,
 216         VM_EXITCODE_MTRAP,
 217         VM_EXITCODE_PAUSE,
 218         VM_EXITCODE_PAGING,
 219         VM_EXITCODE_INST_EMUL,
 220         VM_EXITCODE_SPINUP_AP,
 221         VM_EXITCODE_MMIO_EMUL,
 222         VM_EXITCODE_RUNBLOCK,
 223         VM_EXITCODE_IOAPIC_EOI,
 224         VM_EXITCODE_SUSPENDED,
 225         VM_EXITCODE_MMIO,
 226         VM_EXITCODE_TASK_SWITCH,
 227         VM_EXITCODE_MONITOR,
 228         VM_EXITCODE_MWAIT,
 229         VM_EXITCODE_SVM,
 230         VM_EXITCODE_REQIDLE,
 231         VM_EXITCODE_DEBUG,
 232         VM_EXITCODE_VMINSN,
 233         VM_EXITCODE_BPT,
 234 #ifndef __FreeBSD__
 235         VM_EXITCODE_HT,
 236 #endif
 237         VM_EXITCODE_MAX
 238 };
 239 
 240 enum inout_flags {
 241         INOUT_IN        = (1U << 0), /* direction: 'in' when set, else 'out' */
 242 


 270         uint64_t        gpa;
 271         uint64_t        data;
 272 };
 273 
 274 enum task_switch_reason {
 275         TSR_CALL,
 276         TSR_IRET,
 277         TSR_JMP,
 278         TSR_IDT_GATE,   /* task gate in IDT */
 279 };
 280 
 281 struct vm_task_switch {
 282         uint16_t        tsssel;         /* new TSS selector */
 283         int             ext;            /* task switch due to external event */
 284         uint32_t        errcode;
 285         int             errcode_valid;  /* push 'errcode' on the new stack */
 286         enum task_switch_reason reason;
 287         struct vm_guest_paging paging;
 288 };
 289 












 290 struct vm_exit {
 291         enum vm_exitcode        exitcode;
 292         int                     inst_length;    /* 0 means unknown */
 293         uint64_t                rip;
 294         union {
 295                 struct vm_inout inout;
 296                 struct vm_mmio  mmio;
 297                 struct {
 298                         uint64_t        gpa;
 299                         int             fault_type;
 300                 } paging;
 301                 /*
 302                  * Kernel-internal MMIO decoding and emulation.
 303                  * Userspace should not expect to see this, but rather a
 304                  * VM_EXITCODE_MMIO with the above 'mmio' context.
 305                  */
 306                 struct {
 307                         uint64_t        gpa;
 308                         uint64_t        gla;
 309                         uint64_t        cs_base;


 331                          */
 332                         int             inst_type;
 333                         int             inst_error;
 334                 } vmx;
 335                 /*
 336                  * SVM specific payload.
 337                  */
 338                 struct {
 339                         uint64_t        exitcode;
 340                         uint64_t        exitinfo1;
 341                         uint64_t        exitinfo2;
 342                 } svm;
 343                 struct {
 344                         int             inst_length;
 345                 } bpt;
 346                 struct {
 347                         uint32_t        code;           /* ecx value */
 348                         uint64_t        wval;
 349                 } msr;
 350                 struct {
 351                         int             vcpu;
 352                         uint64_t        rip;
 353                 } spinup_ap;
 354                 struct {
 355                         uint64_t        rflags;
 356                 } hlt;
 357                 struct {
 358                         int             vector;
 359                 } ioapic_eoi;
 360                 struct {
 361                         enum vm_suspend_how how;
 362                 } suspended;
 363                 struct vm_task_switch task_switch;
 364         } u;
 365 };
 366 
 367 enum vm_entry_cmds {
 368         VEC_DEFAULT = 0,
 369         VEC_DISCARD_INSTR,      /* discard inst emul state */
 370         VEC_COMPLETE_MMIO,      /* entry includes result for mmio emul */
 371         VEC_COMPLETE_INOUT,     /* entry includes result for inout emul */
 372 };
 373 
 374 struct vm_entry {
 375         int cpuid;
 376         uint_t cmd;             /* see: vm_entry_cmds */
 377         void *exit_data;
 378         union {
 379                 struct vm_inout inout;
 380                 struct vm_mmio mmio;
 381         } u;
 382 };
 383 
 384 int vm_restart_instruction(void *vm, int vcpuid);
 385 
 386 #endif  /* _VMM_H_ */


 200 };
 201 
 202 struct vm_guest_paging {
 203         uint64_t        cr3;
 204         int             cpl;
 205         enum vm_cpu_mode cpu_mode;
 206         enum vm_paging_mode paging_mode;
 207 };
 208 
 209 enum vm_exitcode {
 210         VM_EXITCODE_INOUT,
 211         VM_EXITCODE_VMX,
 212         VM_EXITCODE_BOGUS,
 213         VM_EXITCODE_RDMSR,
 214         VM_EXITCODE_WRMSR,
 215         VM_EXITCODE_HLT,
 216         VM_EXITCODE_MTRAP,
 217         VM_EXITCODE_PAUSE,
 218         VM_EXITCODE_PAGING,
 219         VM_EXITCODE_INST_EMUL,
 220         VM_EXITCODE_RUN_STATE,
 221         VM_EXITCODE_MMIO_EMUL,
 222         VM_EXITCODE_DEPRECATED, /* formerly RUNBLOCK */
 223         VM_EXITCODE_IOAPIC_EOI,
 224         VM_EXITCODE_SUSPENDED,
 225         VM_EXITCODE_MMIO,
 226         VM_EXITCODE_TASK_SWITCH,
 227         VM_EXITCODE_MONITOR,
 228         VM_EXITCODE_MWAIT,
 229         VM_EXITCODE_SVM,
 230         VM_EXITCODE_REQIDLE,
 231         VM_EXITCODE_DEBUG,
 232         VM_EXITCODE_VMINSN,
 233         VM_EXITCODE_BPT,
 234 #ifndef __FreeBSD__
 235         VM_EXITCODE_HT,
 236 #endif
 237         VM_EXITCODE_MAX
 238 };
 239 
 240 enum inout_flags {
 241         INOUT_IN        = (1U << 0), /* direction: 'in' when set, else 'out' */
 242 


 270         uint64_t        gpa;
 271         uint64_t        data;
 272 };
 273 
 274 enum task_switch_reason {
 275         TSR_CALL,
 276         TSR_IRET,
 277         TSR_JMP,
 278         TSR_IDT_GATE,   /* task gate in IDT */
 279 };
 280 
 281 struct vm_task_switch {
 282         uint16_t        tsssel;         /* new TSS selector */
 283         int             ext;            /* task switch due to external event */
 284         uint32_t        errcode;
 285         int             errcode_valid;  /* push 'errcode' on the new stack */
 286         enum task_switch_reason reason;
 287         struct vm_guest_paging paging;
 288 };
 289 
 290 enum vcpu_run_state {
 291         VRS_HALT                = 0,
 292         VRS_INIT                = (1 << 0),
 293         VRS_RUN                 = (1 << 1),
 294 
 295         VRS_PEND_INIT           = (1 << 14),
 296         VRS_PEND_SIPI           = (1 << 15),
 297 };
 298 #define VRS_MASK_VALID(v)       \
 299         ((v) & (VRS_INIT | VRS_RUN | VRS_PEND_SIPI | VRS_PEND_SIPI))
 300 #define VRS_IS_VALID(v)         ((v) == VRS_MASK_VALID(v))
 301 
 302 struct vm_exit {
 303         enum vm_exitcode        exitcode;
 304         int                     inst_length;    /* 0 means unknown */
 305         uint64_t                rip;
 306         union {
 307                 struct vm_inout inout;
 308                 struct vm_mmio  mmio;
 309                 struct {
 310                         uint64_t        gpa;
 311                         int             fault_type;
 312                 } paging;
 313                 /*
 314                  * Kernel-internal MMIO decoding and emulation.
 315                  * Userspace should not expect to see this, but rather a
 316                  * VM_EXITCODE_MMIO with the above 'mmio' context.
 317                  */
 318                 struct {
 319                         uint64_t        gpa;
 320                         uint64_t        gla;
 321                         uint64_t        cs_base;


 343                          */
 344                         int             inst_type;
 345                         int             inst_error;
 346                 } vmx;
 347                 /*
 348                  * SVM specific payload.
 349                  */
 350                 struct {
 351                         uint64_t        exitcode;
 352                         uint64_t        exitinfo1;
 353                         uint64_t        exitinfo2;
 354                 } svm;
 355                 struct {
 356                         int             inst_length;
 357                 } bpt;
 358                 struct {
 359                         uint32_t        code;           /* ecx value */
 360                         uint64_t        wval;
 361                 } msr;
 362                 struct {




 363                         uint64_t        rflags;
 364                 } hlt;
 365                 struct {
 366                         int             vector;
 367                 } ioapic_eoi;
 368                 struct {
 369                         enum vm_suspend_how how;
 370                 } suspended;
 371                 struct vm_task_switch task_switch;
 372         } u;
 373 };
 374 
 375 enum vm_entry_cmds {
 376         VEC_DEFAULT = 0,
 377         VEC_DISCARD_INSTR,      /* discard inst emul state */
 378         VEC_FULFILL_MMIO,       /* entry includes result for mmio emul */
 379         VEC_FULFILL_INOUT,      /* entry includes result for inout emul */
 380 };
 381 
 382 struct vm_entry {
 383         int cpuid;
 384         uint_t cmd;             /* see: vm_entry_cmds */
 385         void *exit_data;
 386         union {
 387                 struct vm_inout inout;
 388                 struct vm_mmio mmio;
 389         } u;
 390 };
 391 
 392 int vm_restart_instruction(void *vm, int vcpuid);
 393 
 394 #endif  /* _VMM_H_ */