aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2012-02-08 08:34:40 -0500
committerAvi Kivity <avi@redhat.com>2012-03-08 07:10:28 -0500
commitea5e97e8bf1d56a4d9461c39e082b9c31a7be4ff (patch)
tree155889085c85412d1dcfddc1af904417cf0e996c /arch/x86
parent66b0ab8fac1031ffc70eb77491048339f2717a54 (diff)
KVM: SVM: Fix CPL updates
Keep CPL at 0 in real mode and at 3 in VM86. In protected/long mode, use RPL rather than DPL of the code segment. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/svm.c19
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
1335static 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
1335static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) 1350static 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}