KVM: x86: optimize check for valid PAT value
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 10 Apr 2019 09:41:40 +0000 (11:41 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 16 Apr 2019 13:39:02 +0000 (15:39 +0200)
This check will soon be done on every nested vmentry and vmexit,
"parallelize" it using bitwise operations.

Reviewed-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/mtrr.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.h

index e9ea2d45ae66baa65a2e3818e7120189bcd61e57..9f72cc427158e637b1852e9843c5eddfcf78c43a 100644 (file)
@@ -48,11 +48,6 @@ static bool msr_mtrr_valid(unsigned msr)
        return false;
 }
 
-static bool valid_pat_type(unsigned t)
-{
-       return t < 8 && (1 << t) & 0xf3; /* 0, 1, 4, 5, 6, 7 */
-}
-
 static bool valid_mtrr_type(unsigned t)
 {
        return t < 8 && (1 << t) & 0x73; /* 0, 1, 4, 5, 6 */
@@ -67,10 +62,7 @@ bool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                return false;
 
        if (msr == MSR_IA32_CR_PAT) {
-               for (i = 0; i < 8; i++)
-                       if (!valid_pat_type((data >> (i * 8)) & 0xff))
-                               return false;
-               return true;
+               return kvm_pat_valid(data);
        } else if (msr == MSR_MTRRdefType) {
                if (data & ~0xcff)
                        return false;
index a8a1e533d7fb28fc91a284b08831272ebfebeb2f..c40fb667002c712aaadd8700c015b67a550ed83f 100644 (file)
@@ -1891,7 +1891,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_IA32_CR_PAT:
                if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
-                       if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
+                       if (!kvm_pat_valid(data))
                                return 1;
                        vmcs_write64(GUEST_IA32_PAT, data);
                        vcpu->arch.pat = data;
index aedc5d0d4989b3fc7422c17e55fc6b65bfef06a3..eda9544412134b51a27aa6ceea03bdea46d243cf 100644 (file)
@@ -347,6 +347,16 @@ static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
        __this_cpu_write(current_vcpu, NULL);
 }
 
+
+static inline bool kvm_pat_valid(u64 data)
+{
+       if (data & 0xF8F8F8F8F8F8F8F8ull)
+               return false;
+       /* 0, 1, 4, 5, 6, 7 are valid values.  */
+       return (data | ((data & 0x0202020202020202ull) << 1)) == data;
+}
+
 void kvm_load_guest_xcr0(struct kvm_vcpu *vcpu);
 void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu);
+
 #endif