Skip to contentSkip to conversation

KVM: x86: no need to check CPL for XSETBV on VMX

PATCH In review Yang Zhang 2 participants 7 messages Apr 15, 2016

Subsystems (3)
lore
Share & tools
lore

Yang Zhang

author
#0 lore raw

PATCH 1/1 KVM: x86: no need to check CPL for XSETBV on VMX

The CPL check for XSETBV instruction is done by hardware on VMX. It only needs by SVM.

---
 arch/x86/kvm/svm.c | 4 +++-
 arch/x86/kvm/x86.c | 3 +--
 2 files changed, 4 insertions(+), 3 deletions(-)
arch/x86/kvm/svm.c +3 -1
index 31346a3..14680f5 100644
@@ -2715,7 +2715,9 @@ static int xsetbv_interception(struct vcpu_svm *svm)
 	u64 new_bv = kvm_read_edx_eax(&svm->vcpu);
 	u32 index = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX);
 
-	if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
+	if (svm_get_cpl(&svm->vcpu) != 0)
+		kvm_inject_gp(&svm->vcpu, 0);
+	else if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
 		svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 		skip_emulated_instruction(&svm->vcpu);
 	}
arch/x86/kvm/x86.c +1 -2
index 8f57335..3cfc59f 100644
@@ -709,8 +709,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 
 int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 {
-	if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
-	    __kvm_set_xcr(vcpu, index, xcr)) {
+	if (__kvm_set_xcr(vcpu, index, xcr)) {
 		kvm_inject_gp(vcpu, 0);
 		return 1;
 	}
Signature · 1 line
1.8.3.1
maintainer
#1 lore raw
Quoted 2 lines · Yang Zhang

The CPL check for XSETBV instruction is done by hardware on VMX. It only needs by SVM.

I don't think this is performance-sensitive, hence it's simpler to keep the code as simple as possible. For example, if one added XSETBV support to the emulator, your patch would introduce a bug.

Paolo

Quoted 36 lines
---
 arch/x86/kvm/svm.c | 4 +++-
 arch/x86/kvm/x86.c | 3 +--
 2 files changed, 4 insertions(+), 3 deletions(-)
arch/x86/kvm/svm.c +3 -1
index 31346a3..14680f5 100644
@@ -2715,7 +2715,9 @@ static int xsetbv_interception(struct vcpu_svm *svm)
     u64 new_bv = kvm_read_edx_eax(&svm->vcpu);
     u32 index = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX);
 
-    if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
+    if (svm_get_cpl(&svm->vcpu) != 0)
+        kvm_inject_gp(&svm->vcpu, 0);
+    else if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
         svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
         skip_emulated_instruction(&svm->vcpu);
     }
arch/x86/kvm/x86.c +1 -2
index 8f57335..3cfc59f 100644
@@ -709,8 +709,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32
 index, u64 xcr)
 
 int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
 {
-    if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
-        __kvm_set_xcr(vcpu, index, xcr)) {
+    if (__kvm_set_xcr(vcpu, index, xcr)) {
         kvm_inject_gp(vcpu, 0);
         return 1;
     }
author
#2 lore raw
Quoted 9 lines · Paolo Bonzini
Quoted 2 lines · Yang Zhang

The CPL check for XSETBV instruction is done by hardware on VMX. It only needs by SVM.

I don't think this is performance-sensitive, hence it's simpler to keep the code as simple as possible. For example, if one added XSETBV support to the emulator, your patch would introduce a bug.

In what case we need to decode XSETBV?

Quoted 39 lines

Paolo

Quoted 36 lines
---
  arch/x86/kvm/svm.c | 4 +++-
  arch/x86/kvm/x86.c | 3 +--
  2 files changed, 4 insertions(+), 3 deletions(-)
arch/x86/kvm/svm.c +3 -1
index 31346a3..14680f5 100644
@@ -2715,7 +2715,9 @@ static int xsetbv_interception(struct vcpu_svm *svm)
      u64 new_bv = kvm_read_edx_eax(&svm->vcpu);
      u32 index = kvm_register_read(&svm->vcpu, VCPU_REGS_RCX);
 
-    if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
+    if (svm_get_cpl(&svm->vcpu) != 0)
+        kvm_inject_gp(&svm->vcpu, 0);
+    else if (kvm_set_xcr(&svm->vcpu, index, new_bv) == 0) {
          svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
          skip_emulated_instruction(&svm->vcpu);
      }
arch/x86/kvm/x86.c +1 -2
index 8f57335..3cfc59f 100644
@@ -709,8 +709,7 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32
 index, u64 xcr)
 
  int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
  {
-    if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
-        __kvm_set_xcr(vcpu, index, xcr)) {
+    if (__kvm_set_xcr(vcpu, index, xcr)) {
          kvm_inject_gp(vcpu, 0);
          return 1;
      }
Signature · 2 lines
best regards
yang
maintainer
#3 lore raw
Quoted 5 lines · Yang Zhang
Quoted 3 lines

I don't think this is performance-sensitive, hence it's simpler to keep the code as simple as possible. For example, if one added XSETBV support to the emulator, your patch would introduce a bug.

In what case we need to decode XSETBV?

The emulator can be a way to unify code between vmx and svm. It is an alternative to writing small wrapper functions such as kvm_set_xcr.

Thanks,

Paolo

author
#4 lore raw
Quoted 11 lines · Paolo Bonzini
Quoted 5 lines · Yang Zhang
Quoted 3 lines

I don't think this is performance-sensitive, hence it's simpler to keep the code as simple as possible. For example, if one added XSETBV support to the emulator, your patch would introduce a bug.

In what case we need to decode XSETBV?

The emulator can be a way to unify code between vmx and svm. It is an alternative to writing small wrapper functions such as kvm_set_xcr.

I still think the correctness is important. But it's ok to leave it there since it doesn't cause any real problem so far. :)

Signature · 2 lines
best regards
yang
maintainer
#5 lore raw
Quoted 11 lines · Yang Zhang
Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

I don't think this is performance-sensitive, hence it's simpler to keep the code as simple as possible. For example, if one added XSETBV support to the emulator, your patch would introduce a bug.

In what case we need to decode XSETBV?

The emulator can be a way to unify code between vmx and svm. It is an alternative to writing small wrapper functions such as kvm_set_xcr.

I still think the correctness is important.

What correctness? You said "the CPL check is done by hardware on VMX".
Doing the check twice is not incorrect.

Unifying code between VMX and SVM is exactly useful because it makes it easier to have correct code.

Paolo

author
#6 lore raw
Quoted 10 lines · Paolo Bonzini
Quoted 7 lines · Yang Zhang
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines

I don't think this is performance-sensitive, hence it's simpler to keep the code as simple as possible. For example, if one added XSETBV support to the emulator, your patch would introduce a bug.

In what case we need to decode XSETBV?

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

The emulator can be a way to unify code between vmx and svm. It is an alternative to writing small wrapper functions such as kvm_set_xcr.

I still think the correctness is important.

What correctness? You said "the CPL check is done by hardware on VMX".
Doing the check twice is not incorrect.

Yes, you are right. It cannot be considered as correctness issue.

Quoted 6 lines

Unifying code between VMX and SVM is exactly useful because it makes it easier to have correct code.

Paolo

Signature · 2 lines
best regards
yang