Skip to content

Commit e911eb3

Browse files
Yu Zhangbonzini
authored andcommitted
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 <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 3db1348 commit e911eb3

File tree

7 files changed

+34
-21
lines changed

7 files changed

+34
-21
lines changed

arch/x86/include/asm/kvm_emulate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ struct x86_emulate_ops {
219219
struct x86_instruction_info *info,
220220
enum x86_intercept_stage stage);
221221

222-
void (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
223-
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
222+
bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx,
223+
u32 *ecx, u32 *edx, bool check_limit);
224224
void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
225225

226226
unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt);

arch/x86/kvm/cpuid.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -853,24 +853,33 @@ static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
853853
return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
854854
}
855855

856-
void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
856+
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
857+
u32 *ecx, u32 *edx, bool check_limit)
857858
{
858859
u32 function = *eax, index = *ecx;
859860
struct kvm_cpuid_entry2 *best;
861+
bool entry_found = true;
860862

861863
best = kvm_find_cpuid_entry(vcpu, function, index);
862864

863-
if (!best)
865+
if (!best) {
866+
entry_found = false;
867+
if (!check_limit)
868+
goto out;
869+
864870
best = check_cpuid_limit(vcpu, function, index);
871+
}
865872

873+
out:
866874
if (best) {
867875
*eax = best->eax;
868876
*ebx = best->ebx;
869877
*ecx = best->ecx;
870878
*edx = best->edx;
871879
} else
872880
*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;
874883
}
875884
EXPORT_SYMBOL_GPL(kvm_cpuid);
876885

@@ -883,7 +892,7 @@ int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
883892

884893
eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
885894
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);
887896
kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
888897
kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
889898
kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);

arch/x86/kvm/cpuid.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
2121
int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
2222
struct kvm_cpuid2 *cpuid,
2323
struct kvm_cpuid_entry2 __user *entries);
24-
void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
24+
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
25+
u32 *ecx, u32 *edx, bool check_limit);
2526

2627
int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
2728

arch/x86/kvm/emulate.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,7 @@ static int emulator_has_longmode(struct x86_emulate_ctxt *ctxt)
23332333

23342334
eax = 0x80000001;
23352335
ecx = 0;
2336-
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
2336+
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
23372337
return edx & bit(X86_FEATURE_LM);
23382338
}
23392339

@@ -2636,7 +2636,7 @@ static bool vendor_intel(struct x86_emulate_ctxt *ctxt)
26362636
u32 eax, ebx, ecx, edx;
26372637

26382638
eax = ecx = 0;
2639-
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
2639+
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
26402640
return ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx
26412641
&& ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx
26422642
&& edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx;
@@ -2656,7 +2656,7 @@ static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
26562656

26572657
eax = 0x00000000;
26582658
ecx = 0x00000000;
2659-
ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
2659+
ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
26602660
/*
26612661
* Intel ("GenuineIntel")
26622662
* remark: Intel CPUs only support "syscall" in 64bit
@@ -3551,7 +3551,7 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
35513551
/*
35523552
* Check MOVBE is set in the guest-visible CPUID leaf.
35533553
*/
3554-
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
3554+
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
35553555
if (!(ecx & FFL(MOVBE)))
35563556
return emulate_ud(ctxt);
35573557

@@ -3865,7 +3865,7 @@ static int em_cpuid(struct x86_emulate_ctxt *ctxt)
38653865

38663866
eax = reg_read(ctxt, VCPU_REGS_RAX);
38673867
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);
38693869
*reg_write(ctxt, VCPU_REGS_RAX) = eax;
38703870
*reg_write(ctxt, VCPU_REGS_RBX) = ebx;
38713871
*reg_write(ctxt, VCPU_REGS_RCX) = ecx;
@@ -3924,7 +3924,7 @@ static int check_fxsr(struct x86_emulate_ctxt *ctxt)
39243924
{
39253925
u32 eax = 1, ebx, ecx = 0, edx;
39263926

3927-
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
3927+
ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx, false);
39283928
if (!(edx & FFL(FXSR)))
39293929
return emulate_ud(ctxt);
39303930

arch/x86/kvm/svm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
15931593
}
15941594
init_vmcb(svm);
15951595

1596-
kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy);
1596+
kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true);
15971597
kvm_register_write(vcpu, VCPU_REGS_RDX, eax);
15981598

15991599
if (kvm_vcpu_apicv_active(vcpu) && !init_event)

arch/x86/kvm/trace.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,16 @@ TRACE_EVENT(kvm_fast_mmio,
151151
*/
152152
TRACE_EVENT(kvm_cpuid,
153153
TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx,
154-
unsigned long rcx, unsigned long rdx),
155-
TP_ARGS(function, rax, rbx, rcx, rdx),
154+
unsigned long rcx, unsigned long rdx, bool found),
155+
TP_ARGS(function, rax, rbx, rcx, rdx, found),
156156

157157
TP_STRUCT__entry(
158158
__field( unsigned int, function )
159159
__field( unsigned long, rax )
160160
__field( unsigned long, rbx )
161161
__field( unsigned long, rcx )
162162
__field( unsigned long, rdx )
163+
__field( bool, found )
163164
),
164165

165166
TP_fast_assign(
@@ -168,11 +169,13 @@ TRACE_EVENT(kvm_cpuid,
168169
__entry->rbx = rbx;
169170
__entry->rcx = rcx;
170171
__entry->rdx = rdx;
172+
__entry->found = found;
171173
),
172174

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",
174176
__entry->function, __entry->rax,
175-
__entry->rbx, __entry->rcx, __entry->rdx)
177+
__entry->rbx, __entry->rcx, __entry->rdx,
178+
__entry->found ? "found" : "not found")
176179
);
177180

178181
#define AREG(x) { APIC_##x, "APIC_" #x }

arch/x86/kvm/x86.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5206,10 +5206,10 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
52065206
return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
52075207
}
52085208

5209-
static void emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
5210-
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
5209+
static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
5210+
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, bool check_limit)
52115211
{
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);
52135213
}
52145214

52155215
static ulong emulator_read_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg)

0 commit comments

Comments
 (0)