summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Zhang <yu.c.zhang@linux.intel.com>2017-08-24 08:27:52 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2017-08-24 12:09:15 -0400
commite911eb3b3414e62cbd9853e0a91c124f4a545c0f (patch)
treee8ac1e3c35b9d452ef099cd3b04f2c1f40fe5c25
parent3db134805c69aae16ba6193946aa8deccd393ead (diff)
KVM: x86: Add return value to kvm_cpuid().
Return false in kvm_cpuid() when it fails to find the cpuid entry. Also, this routine(and its caller) is optimized with a new argument - check_limit, so that the check_cpuid_limit() fall back can be avoided. Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_emulate.h4
-rw-r--r--arch/x86/kvm/cpuid.c17
-rw-r--r--arch/x86/kvm/cpuid.h3
-rw-r--r--arch/x86/kvm/emulate.c12
-rw-r--r--arch/x86/kvm/svm.c2
-rw-r--r--arch/x86/kvm/trace.h11
-rw-r--r--arch/x86/kvm/x86.c6
7 files changed, 34 insertions, 21 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index fde36f189836..fa2558e12024 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -219,8 +219,8 @@ struct x86_emulate_ops {
219 struct x86_instruction_info *info, 219 struct x86_instruction_info *info,
220 enum x86_intercept_stage stage); 220 enum x86_intercept_stage stage);
221 221
222 void (*get_cpuid)(struct x86_emulate_ctxt *ctxt, 222 bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx,
223 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); 223 u32 *ecx, u32 *edx, bool check_limit);
224 void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked); 224 void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
225 225
226 unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt); 226 unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 59ca2eea522c..14505473fb21 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -853,16 +853,24 @@ static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
853 return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index); 853 return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
854} 854}
855 855
856void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) 856bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
857 u32 *ecx, u32 *edx, bool check_limit)
857{ 858{
858 u32 function = *eax, index = *ecx; 859 u32 function = *eax, index = *ecx;
859 struct kvm_cpuid_entry2 *best; 860 struct kvm_cpuid_entry2 *best;
861 bool entry_found = true;
860 862
861 best = kvm_find_cpuid_entry(vcpu, function, index); 863 best = kvm_find_cpuid_entry(vcpu, function, index);
862 864
863 if (!best) 865 if (!best) {
866 entry_found = false;
867 if (!check_limit)
868 goto out;
869
864 best = check_cpuid_limit(vcpu, function, index); 870 best = check_cpuid_limit(vcpu, function, index);
871 }
865 872
873out:
866 if (best) { 874 if (best) {
867 *eax = best->eax; 875 *eax = best->eax;
868 *ebx = best->ebx; 876 *ebx = best->ebx;
@@ -870,7 +878,8 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
870 *edx = best->edx; 878 *edx = best->edx;
871 } else 879 } else
872 *eax = *ebx = *ecx = *edx = 0; 880 *eax = *ebx = *ecx = *edx = 0;
873 trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx); 881 trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, entry_found);
882 return entry_found;
874} 883}
875EXPORT_SYMBOL_GPL(kvm_cpuid); 884EXPORT_SYMBOL_GPL(kvm_cpuid);
876 885
@@ -883,7 +892,7 @@ int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
883 892
884 eax = kvm_register_read(vcpu, VCPU_REGS_RAX); 893 eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
885 ecx = kvm_register_read(vcpu, VCPU_REGS_RCX); 894 ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
886 kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx); 895 kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, true);
887 kvm_register_write(vcpu, VCPU_REGS_RAX, eax); 896 kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
888 kvm_register_write(vcpu, VCPU_REGS_RBX, ebx); 897 kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
889 kvm_register_write(vcpu, VCPU_REGS_RCX, ecx); 898 kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index ac15193e5e52..1ea3c0e1e3a9 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -21,7 +21,8 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
21int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu, 21int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
22 struct kvm_cpuid2 *cpuid, 22 struct kvm_cpuid2 *cpuid,
23 struct kvm_cpuid_entry2 __user *entries); 23 struct kvm_cpuid_entry2 __user *entries);
24void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); 24bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
25 u32 *ecx, u32 *edx, bool check_limit);
25 26
26int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu); 27int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
27 28
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index fb0055953fbc..319d91f6f3c4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2333,7 +2333,7 @@ static int emulator_has_longmode(struct x86_emulate_ctxt *ctxt)
2333 2333
2334 eax = 0x80000001; 2334 eax = 0x80000001;
2335 ecx = 0; 2335 ecx = 0;
2336 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); 2336 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
2337 return edx & bit(X86_FEATURE_LM); 2337 return edx & bit(X86_FEATURE_LM);
2338} 2338}
2339 2339
@@ -2636,7 +2636,7 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
2636 u32 eax, ebx, ecx, edx; 2636 u32 eax, ebx, ecx, edx;
2637 2637
2638 eax = ecx = 0; 2638 eax = ecx = 0;
2639 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); 2639 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
2640 return ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 2640 return ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx
2641 && ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 2641 && ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx
2642 && edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx; 2642 && edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx;
@@ -2656,7 +2656,7 @@ static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
2656 2656
2657 eax = 0x00000000; 2657 eax = 0x00000000;
2658 ecx = 0x00000000; 2658 ecx = 0x00000000;
2659 ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); 2659 ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
2660 /* 2660 /*
2661 * Intel ("GenuineIntel") 2661 * Intel ("GenuineIntel")
2662 * remark: Intel CPUs only support "syscall" in 64bit 2662 * remark: Intel CPUs only support "syscall" in 64bit
@@ -3551,7 +3551,7 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
3551 /* 3551 /*
3552 * Check MOVBE is set in the guest-visible CPUID leaf. 3552 * Check MOVBE is set in the guest-visible CPUID leaf.
3553 */ 3553 */
3554 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); 3554 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
3555 if (!(ecx & FFL(MOVBE))) 3555 if (!(ecx & FFL(MOVBE)))
3556 return emulate_ud(ctxt); 3556 return emulate_ud(ctxt);
3557 3557
@@ -3865,7 +3865,7 @@ static int em_cpuid(struct x86_emulate_ctxt *ctxt)
3865 3865
3866 eax = reg_read(ctxt, VCPU_REGS_RAX); 3866 eax = reg_read(ctxt, VCPU_REGS_RAX);
3867 ecx = reg_read(ctxt, VCPU_REGS_RCX); 3867 ecx = reg_read(ctxt, VCPU_REGS_RCX);
3868 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); 3868 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, true);
3869 *reg_write(ctxt, VCPU_REGS_RAX) = eax; 3869 *reg_write(ctxt, VCPU_REGS_RAX) = eax;
3870 *reg_write(ctxt, VCPU_REGS_RBX) = ebx; 3870 *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
3871 *reg_write(ctxt, VCPU_REGS_RCX) = ecx; 3871 *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
@@ -3924,7 +3924,7 @@ static int check_fxsr(struct x86_emulate_ctxt *ctxt)
3924{ 3924{
3925 u32 eax = 1, ebx, ecx = 0, edx; 3925 u32 eax = 1, ebx, ecx = 0, edx;
3926 3926
3927 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx); 3927 ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
3928 if (!(edx & FFL(FXSR))) 3928 if (!(edx & FFL(FXSR)))
3929 return emulate_ud(ctxt); 3929 return emulate_ud(ctxt);
3930 3930
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 7e190b21a30b..c5b9705186d6 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1593,7 +1593,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
1593 } 1593 }
1594 init_vmcb(svm); 1594 init_vmcb(svm);
1595 1595
1596 kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy); 1596 kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true);
1597 kvm_register_write(vcpu, VCPU_REGS_RDX, eax); 1597 kvm_register_write(vcpu, VCPU_REGS_RDX, eax);
1598 1598
1599 if (kvm_vcpu_apicv_active(vcpu) && !init_event) 1599 if (kvm_vcpu_apicv_active(vcpu) && !init_event)
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 0a6cc6754ec5..8a202c49e2a0 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -151,8 +151,8 @@ TRACE_EVENT(kvm_fast_mmio,
151 */ 151 */
152TRACE_EVENT(kvm_cpuid, 152TRACE_EVENT(kvm_cpuid,
153 TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx, 153 TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx,
154 unsigned long rcx, unsigned long rdx), 154 unsigned long rcx, unsigned long rdx, bool found),
155 TP_ARGS(function, rax, rbx, rcx, rdx), 155 TP_ARGS(function, rax, rbx, rcx, rdx, found),
156 156
157 TP_STRUCT__entry( 157 TP_STRUCT__entry(
158 __field( unsigned int, function ) 158 __field( unsigned int, function )
@@ -160,6 +160,7 @@ TRACE_EVENT(kvm_cpuid,
160 __field( unsigned long, rbx ) 160 __field( unsigned long, rbx )
161 __field( unsigned long, rcx ) 161 __field( unsigned long, rcx )
162 __field( unsigned long, rdx ) 162 __field( unsigned long, rdx )
163 __field( bool, found )
163 ), 164 ),
164 165
165 TP_fast_assign( 166 TP_fast_assign(
@@ -168,11 +169,13 @@ TRACE_EVENT(kvm_cpuid,
168 __entry->rbx = rbx; 169 __entry->rbx = rbx;
169 __entry->rcx = rcx; 170 __entry->rcx = rcx;
170 __entry->rdx = rdx; 171 __entry->rdx = rdx;
172 __entry->found = found;
171 ), 173 ),
172 174
173 TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx", 175 TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx, cpuid entry %s",
174 __entry->function, __entry->rax, 176 __entry->function, __entry->rax,
175 __entry->rbx, __entry->rcx, __entry->rdx) 177 __entry->rbx, __entry->rcx, __entry->rdx,
178 __entry->found ? "found" : "not found")
176); 179);
177 180
178#define AREG(x) { APIC_##x, "APIC_" #x } 181#define AREG(x) { APIC_##x, "APIC_" #x }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4e699238a113..cc2c7e413e9c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5206,10 +5206,10 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
5206 return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage); 5206 return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
5207} 5207}
5208 5208
5209static void emulator_get_cpuid(struct x86_emulate_ctxt *ctxt, 5209static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
5210 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) 5210 u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, bool check_limit)
5211{ 5211{
5212 kvm_cpuid(emul_to_vcpu(ctxt), eax, ebx, ecx, edx); 5212 return kvm_cpuid(emul_to_vcpu(ctxt), eax, ebx, ecx, edx, check_limit);
5213} 5213}
5214 5214
5215static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg) 5215static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)