diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/svm.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 95cdeaf9c718..ab39d84dee00 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1332,6 +1332,21 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) | |||
1332 | wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); | 1332 | wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]); |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | static void svm_update_cpl(struct kvm_vcpu *vcpu) | ||
1336 | { | ||
1337 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1338 | int cpl; | ||
1339 | |||
1340 | if (!is_protmode(vcpu)) | ||
1341 | cpl = 0; | ||
1342 | else if (svm->vmcb->save.rflags & X86_EFLAGS_VM) | ||
1343 | cpl = 3; | ||
1344 | else | ||
1345 | cpl = svm->vmcb->save.cs.selector & 0x3; | ||
1346 | |||
1347 | svm->vmcb->save.cpl = cpl; | ||
1348 | } | ||
1349 | |||
1335 | static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) | 1350 | static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) |
1336 | { | 1351 | { |
1337 | return to_svm(vcpu)->vmcb->save.rflags; | 1352 | return to_svm(vcpu)->vmcb->save.rflags; |
@@ -1607,9 +1622,7 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, | |||
1607 | s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT; | 1622 | s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT; |
1608 | } | 1623 | } |
1609 | if (seg == VCPU_SREG_CS) | 1624 | if (seg == VCPU_SREG_CS) |
1610 | svm->vmcb->save.cpl | 1625 | svm_update_cpl(vcpu); |
1611 | = (svm->vmcb->save.cs.attrib | ||
1612 | >> SVM_SELECTOR_DPL_SHIFT) & 3; | ||
1613 | 1626 | ||
1614 | mark_dirty(svm->vmcb, VMCB_SEG); | 1627 | mark_dirty(svm->vmcb, VMCB_SEG); |
1615 | } | 1628 | } |