* [PATCH 0/2] KVM: CPUID: CPUID emulation flow adjustment and one minor refinement when updating maxphyaddr @ 2019-09-10 8:24 Xiaoyao Li 2019-09-10 8:24 ` [PATCH 1/2] KVM: CPUID: Check limit first when emulating CPUID instruction Xiaoyao Li 2019-09-10 8:24 ` [PATCH 2/2] KVM: CPUID: Put maxphyaddr updating together with virtual address width checking Xiaoyao Li 0 siblings, 2 replies; 4+ messages in thread From: Xiaoyao Li @ 2019-09-10 8:24 UTC (permalink / raw) To: Paolo Bonzini, Radim Krčmář Cc: Xiaoyao Li, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson, Joerg Roedel, kvm Patch 1 adjusts the execution flow of CPUID instruction emulation, which checks the leaf number first per CPUID specification. Patch 2 moves physical address width updating to where we check the virtual address width in function kvm_update_cpuid() since they two use the same cpuid leaf, which makes it more reasonable and no functional change. Xiaoyao Li (2): KVM: CPUID: Check limit first when emulating CPUID instruction KVM: CPUID: Put maxphyaddr updating together with virtual address width checking arch/x86/kvm/cpuid.c | 56 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 24 deletions(-) -- 2.19.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] KVM: CPUID: Check limit first when emulating CPUID instruction 2019-09-10 8:24 [PATCH 0/2] KVM: CPUID: CPUID emulation flow adjustment and one minor refinement when updating maxphyaddr Xiaoyao Li @ 2019-09-10 8:24 ` Xiaoyao Li 2019-09-10 9:52 ` Xiaoyao Li 2019-09-10 8:24 ` [PATCH 2/2] KVM: CPUID: Put maxphyaddr updating together with virtual address width checking Xiaoyao Li 1 sibling, 1 reply; 4+ messages in thread From: Xiaoyao Li @ 2019-09-10 8:24 UTC (permalink / raw) To: Paolo Bonzini, Radim Krčmář Cc: Xiaoyao Li, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson, Joerg Roedel, kvm When limit checking is required, it should be executed first, which is consistent with the CPUID specification. Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com> --- arch/x86/kvm/cpuid.c | 50 +++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 22c2720cd948..866546b4d834 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -952,23 +952,33 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry); /* - * If no match is found, check whether we exceed the vCPU's limit - * and return the content of the highest valid _standard_ leaf instead. - * This is to satisfy the CPUID specification. + * Based on CPUID specification, if leaf number exceeds the vCPU's limit, + * it should return the content of the highest valid _standard_ leaf instead. + * Note: *found is set true only means the queried leaf number doesn't exceed + * the maximum leaf number of basic or extented leaf. */ -static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu, - u32 function, u32 index) +static struct kvm_cpuid_entry2* cpuid_check_limit(struct kvm_vcpu *vcpu, + u32 function, u32 index, + bool *found) { struct kvm_cpuid_entry2 *maxlevel; maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0); - if (!maxlevel || maxlevel->eax >= function) + if (!maxlevel) return NULL; - if (function & 0x80000000) { - maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0); - if (!maxlevel) - return NULL; + + if (maxlevel->eax >= function) { + if (found) + *found = true; + return kvm_find_cpuid_entry(vcpu, function, index); } + + if (function & 0x80000000) + maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0); + + if (!maxlevel) + return NULL; + return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index); } @@ -977,26 +987,22 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, { u32 function = *eax, index = *ecx; struct kvm_cpuid_entry2 *best; - bool entry_found = true; + bool entry_found = false; - best = kvm_find_cpuid_entry(vcpu, function, index); + if (check_limit) + best = cpuid_check_limit(vcpu, function, index, &entry_found); + else + best = kvm_find_cpuid_entry(vcpu, function, index); - if (!best) { - entry_found = false; - if (!check_limit) - goto out; - - best = check_cpuid_limit(vcpu, function, index); - } - -out: if (best) { *eax = best->eax; *ebx = best->ebx; *ecx = best->ecx; *edx = best->edx; - } else + } else { + entry_found = false; *eax = *ebx = *ecx = *edx = 0; + } trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, entry_found); return entry_found; } -- 2.19.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] KVM: CPUID: Check limit first when emulating CPUID instruction 2019-09-10 8:24 ` [PATCH 1/2] KVM: CPUID: Check limit first when emulating CPUID instruction Xiaoyao Li @ 2019-09-10 9:52 ` Xiaoyao Li 0 siblings, 0 replies; 4+ messages in thread From: Xiaoyao Li @ 2019-09-10 9:52 UTC (permalink / raw) To: Paolo Bonzini, Radim Krčmář Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson, Joerg Roedel, kvm On Tue, 2019-09-10 at 16:24 +0800, Xiaoyao Li wrote: > When limit checking is required, it should be executed first, which is > consistent with the CPUID specification. > > Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com> > --- > arch/x86/kvm/cpuid.c | 50 +++++++++++++++++++++++++------------------- > 1 file changed, 28 insertions(+), 22 deletions(-) > > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > index 22c2720cd948..866546b4d834 100644 > --- a/arch/x86/kvm/cpuid.c > +++ b/arch/x86/kvm/cpuid.c > @@ -952,23 +952,33 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct > kvm_vcpu *vcpu, > EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry); > > /* > - * If no match is found, check whether we exceed the vCPU's limit > - * and return the content of the highest valid _standard_ leaf instead. > - * This is to satisfy the CPUID specification. > + * Based on CPUID specification, if leaf number exceeds the vCPU's limit, > + * it should return the content of the highest valid _standard_ leaf instead. > + * Note: *found is set true only means the queried leaf number doesn't exceed > + * the maximum leaf number of basic or extented leaf. > */ > -static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu, > - u32 function, u32 index) > +static struct kvm_cpuid_entry2* cpuid_check_limit(struct kvm_vcpu *vcpu, > + u32 function, u32 index, > + bool *found) > { > struct kvm_cpuid_entry2 *maxlevel; > > maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0); > - if (!maxlevel || maxlevel->eax >= function) > + if (!maxlevel) > return NULL; > - if (function & 0x80000000) { > - maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0); > - if (!maxlevel) > - return NULL; > + > + if (maxlevel->eax >= function) { > + if (found) > + *found = true; > + return kvm_find_cpuid_entry(vcpu, function, index); > } > + > + if (function & 0x80000000) > + maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0); > + > + if (!maxlevel) > + return NULL; > + > return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index); > } > > @@ -977,26 +987,22 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 > *ebx, > { > u32 function = *eax, index = *ecx; > struct kvm_cpuid_entry2 *best; > - bool entry_found = true; > + bool entry_found = false; > > - best = kvm_find_cpuid_entry(vcpu, function, index); > + if (check_limit) > + best = cpuid_check_limit(vcpu, function, index, &entry_found); > + else > + best = kvm_find_cpuid_entry(vcpu, function, index); > > - if (!best) { > - entry_found = false; > - if (!check_limit) > - goto out; > - > - best = check_cpuid_limit(vcpu, function, index); > - } > - > -out: > if (best) { > *eax = best->eax; > *ebx = best->ebx; > *ecx = best->ecx; > *edx = best->edx; > - } else > + } else { > + entry_found = false; > *eax = *ebx = *ecx = *edx = 0; > + } > trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, entry_found); > return entry_found; > } Just realise the entry_found is not set true if found in no limit checking case. Will send v2. ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] KVM: CPUID: Put maxphyaddr updating together with virtual address width checking 2019-09-10 8:24 [PATCH 0/2] KVM: CPUID: CPUID emulation flow adjustment and one minor refinement when updating maxphyaddr Xiaoyao Li 2019-09-10 8:24 ` [PATCH 1/2] KVM: CPUID: Check limit first when emulating CPUID instruction Xiaoyao Li @ 2019-09-10 8:24 ` Xiaoyao Li 1 sibling, 0 replies; 4+ messages in thread From: Xiaoyao Li @ 2019-09-10 8:24 UTC (permalink / raw) To: Paolo Bonzini, Radim Krčmář Cc: Xiaoyao Li, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson, Joerg Roedel, kvm Since both of maxphyaddr updating and virtual address width checking need to query the cpuid leaf 0x80000008. We can put them together. Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com> --- arch/x86/kvm/cpuid.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 866546b4d834..5e7039d421ac 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -118,6 +118,7 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) best->ebx = xstate_required_size(vcpu->arch.xcr0, true); /* + * Update physical address width and check virtual address width. * The existing code assumes virtual address is 48-bit or 57-bit in the * canonical address checks; exit if it is ever changed. */ @@ -127,7 +128,10 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0) return -EINVAL; + + vcpu->arch.maxphyaddr = best->eax & 0xff; } + vcpu->arch.maxphyaddr = 36; best = kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0); if (kvm_hlt_in_guest(vcpu->kvm) && best && @@ -144,8 +148,6 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) } } - /* Update physical-address width */ - vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); kvm_mmu_reset_context(vcpu); kvm_pmu_refresh(vcpu); -- 2.19.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-09-10 9:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-09-10 8:24 [PATCH 0/2] KVM: CPUID: CPUID emulation flow adjustment and one minor refinement when updating maxphyaddr Xiaoyao Li 2019-09-10 8:24 ` [PATCH 1/2] KVM: CPUID: Check limit first when emulating CPUID instruction Xiaoyao Li 2019-09-10 9:52 ` Xiaoyao Li 2019-09-10 8:24 ` [PATCH 2/2] KVM: CPUID: Put maxphyaddr updating together with virtual address width checking Xiaoyao Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).