| 3501 | } |
| 3502 | |
| 3503 | static int |
| 3504 | vmx_setcap(void *arg, int vcpu, int type, int val) |
| 3505 | { |
| 3506 | struct vmx *vmx = arg; |
| 3507 | struct vmcs *vmcs = &vmx->vmcs[vcpu]; |
| 3508 | uint32_t baseval; |
| 3509 | uint32_t *pptr; |
| 3510 | int error; |
| 3511 | int flag; |
| 3512 | int reg; |
| 3513 | int retval; |
| 3514 | |
| 3515 | retval = ENOENT; |
| 3516 | pptr = NULL; |
| 3517 | |
| 3518 | switch (type) { |
| 3519 | case VM_CAP_HALT_EXIT: |
| 3520 | if (cap_halt_exit) { |
| 3521 | retval = 0; |
| 3522 | pptr = &vmx->cap[vcpu].proc_ctls; |
| 3523 | baseval = *pptr; |
| 3524 | flag = PROCBASED_HLT_EXITING; |
| 3525 | reg = VMCS_PRI_PROC_BASED_CTLS; |
| 3526 | } |
| 3527 | break; |
| 3528 | case VM_CAP_MTRAP_EXIT: |
| 3529 | if (cap_monitor_trap) { |
| 3530 | retval = 0; |
| 3531 | pptr = &vmx->cap[vcpu].proc_ctls; |
| 3532 | baseval = *pptr; |
| 3533 | flag = PROCBASED_MTF; |
| 3534 | reg = VMCS_PRI_PROC_BASED_CTLS; |
| 3535 | } |
| 3536 | break; |
| 3537 | case VM_CAP_PAUSE_EXIT: |
| 3538 | if (cap_pause_exit) { |
| 3539 | retval = 0; |
| 3540 | pptr = &vmx->cap[vcpu].proc_ctls; |
| 3541 | baseval = *pptr; |
| 3542 | flag = PROCBASED_PAUSE_EXITING; |
| 3543 | reg = VMCS_PRI_PROC_BASED_CTLS; |
| 3544 | } |
| 3545 | break; |
| 3546 | case VM_CAP_RDPID: |
| 3547 | case VM_CAP_RDTSCP: |
| 3548 | if (cap_rdpid || cap_rdtscp) |
| 3549 | /* |
| 3550 | * Choose not to support enabling/disabling |
| 3551 | * RDPID/RDTSCP via libvmmapi since, as per the |
| 3552 | * discussion in vmx_modinit(), RDPID/RDTSCP are |
| 3553 | * either always enabled or always disabled. |
| 3554 | */ |
| 3555 | error = EOPNOTSUPP; |
| 3556 | break; |
| 3557 | case VM_CAP_UNRESTRICTED_GUEST: |
| 3558 | if (cap_unrestricted_guest) { |
| 3559 | retval = 0; |
| 3560 | pptr = &vmx->cap[vcpu].proc_ctls2; |