mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
x86/HVM: XSETBV intercept needs to check CPL on SVM only
VMX doesn't need a software CPL check on the XSETBV intercept, and SVM can do that check without resorting to hvm_get_segment_register(). Clean up what is left of hvm_handle_xsetbv(), namely make it return a proper error code. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Acked-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
1 parent
484c14b725
commit
e513d8f7bc
2 files changed
+11
-17
No files matched your search
+6
-13
@@ -3153,22 +3153,15 @@ out:
|
||||
|
||||
int hvm_handle_xsetbv(u32 index, u64 new_bv)
|
||||
{
|
||||
struct segment_register sreg;
|
||||
struct vcpu *curr = current;
|
||||
int rc;
|
||||
|
||||
hvm_get_segment_register(curr, x86_seg_ss, &sreg);
|
||||
if ( sreg.attr.fields.dpl != 0 )
|
||||
goto err;
|
||||
hvm_event_crX(XCR0, new_bv, current->arch.xcr0);
|
||||
|
||||
hvm_event_crX(XCR0, new_bv, curr->arch.xcr0);
|
||||
rc = handle_xsetbv(index, new_bv);
|
||||
if ( rc )
|
||||
hvm_inject_hw_exception(TRAP_gp_fault, 0);
|
||||
|
||||
if ( handle_xsetbv(index, new_bv) )
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
hvm_inject_hw_exception(TRAP_gp_fault, 0);
|
||||
return -1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hvm_set_efer(uint64_t value)
|
||||
|
||||
@@ -2612,10 +2612,11 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
|
||||
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;
|
||||
|
||||
|
||||