int hvm_handle_xsetbv(u32 index, u64 new_bv)
{
- struct segment_register sreg;
- struct vcpu *curr = current;
-
- hvm_get_segment_register(curr, x86_seg_ss, &sreg);
- if ( sreg.attr.fields.dpl != 0 )
- goto err;
+ int rc;
- hvm_event_crX(XCR0, new_bv, curr->arch.xcr0);
+ hvm_event_crX(XCR0, new_bv, current->arch.xcr0);
- if ( handle_xsetbv(index, new_bv) )
- goto err;
+ rc = handle_xsetbv(index, new_bv);
+ if ( rc )
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
- return 0;
-err:
- hvm_inject_hw_exception(TRAP_gp_fault, 0);
- return -1;
+ return rc;
}
int hvm_set_efer(uint64_t value)
break;
case VMEXIT_XSETBV:
- if ( (inst_len = __get_instruction_length(current, INSTR_XSETBV))==0 )
- break;
- if ( hvm_handle_xsetbv(regs->ecx,
- (regs->rdx << 32) | regs->_eax) == 0 )
+ if ( vmcb_get_cpl(vmcb) )
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
+ else if ( (inst_len = __get_instruction_length(v, INSTR_XSETBV)) &&
+ hvm_handle_xsetbv(regs->ecx,
+ (regs->rdx << 32) | regs->_eax) == 0 )
__update_guest_eip(regs, inst_len);
break;