lkml.org 
[lkml]   [2022]   [Jan]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/5] KVM: x86: Do runtime CPUID update before updating vcpu->arch.cpuid_entries
    Date
    kvm_update_cpuid_runtime() mangles CPUID data coming from userspace
    VMM after updating 'vcpu->arch.cpuid_entries', this makes it
    impossible to compare an update with what was previously
    supplied. Introduce __kvm_update_cpuid_runtime() version which can be
    used to tweak the input before it goes to 'vcpu->arch.cpuid_entries'
    so the upcoming update check can compare tweaked data.

    No functional change intended.

    Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
    ---
    arch/x86/kvm/cpuid.c | 34 ++++++++++++++++++++++++----------
    1 file changed, 24 insertions(+), 10 deletions(-)

    diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
    index 89af3c7390d3..c4d4c350afbe 100644
    --- a/arch/x86/kvm/cpuid.c
    +++ b/arch/x86/kvm/cpuid.c
    @@ -125,14 +125,21 @@ static void kvm_update_kvm_cpuid_base(struct kvm_vcpu *vcpu)
    }
    }

    -static struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
    +static struct kvm_cpuid_entry2 *__kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu,
    + struct kvm_cpuid_entry2 *entries, int nent)
    {
    u32 base = vcpu->arch.kvm_cpuid_base;

    if (!base)
    return NULL;

    - return kvm_find_cpuid_entry(vcpu, base | KVM_CPUID_FEATURES, 0);
    + return cpuid_entry2_find(entries, nent, base | KVM_CPUID_FEATURES, 0);
    +}
    +
    +static struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
    +{
    + return __kvm_find_kvm_cpuid_features(vcpu, vcpu->arch.cpuid_entries,
    + vcpu->arch.cpuid_nent);
    }

    void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
    @@ -147,11 +154,12 @@ void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
    vcpu->arch.pv_cpuid.features = best->eax;
    }

    -void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
    +static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *entries,
    + int nent)
    {
    struct kvm_cpuid_entry2 *best;

    - best = kvm_find_cpuid_entry(vcpu, 1, 0);
    + best = cpuid_entry2_find(entries, nent, 1, 0);
    if (best) {
    /* Update OSXSAVE bit */
    if (boot_cpu_has(X86_FEATURE_XSAVE))
    @@ -162,33 +170,38 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
    vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE);
    }

    - best = kvm_find_cpuid_entry(vcpu, 7, 0);
    + best = cpuid_entry2_find(entries, nent, 7, 0);
    if (best && boot_cpu_has(X86_FEATURE_PKU) && best->function == 0x7)
    cpuid_entry_change(best, X86_FEATURE_OSPKE,
    kvm_read_cr4_bits(vcpu, X86_CR4_PKE));

    - best = kvm_find_cpuid_entry(vcpu, 0xD, 0);
    + best = cpuid_entry2_find(entries, nent, 0xD, 0);
    if (best)
    best->ebx = xstate_required_size(vcpu->arch.xcr0, false);

    - best = kvm_find_cpuid_entry(vcpu, 0xD, 1);
    + best = cpuid_entry2_find(entries, nent, 0xD, 1);
    if (best && (cpuid_entry_has(best, X86_FEATURE_XSAVES) ||
    cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
    best->ebx = xstate_required_size(vcpu->arch.xcr0, true);

    - best = kvm_find_kvm_cpuid_features(vcpu);
    + best = __kvm_find_kvm_cpuid_features(vcpu, entries, nent);
    if (kvm_hlt_in_guest(vcpu->kvm) && best &&
    (best->eax & (1 << KVM_FEATURE_PV_UNHALT)))
    best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT);

    if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT)) {
    - best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
    + best = cpuid_entry2_find(entries, nent, 0x1, 0);
    if (best)
    cpuid_entry_change(best, X86_FEATURE_MWAIT,
    vcpu->arch.ia32_misc_enable_msr &
    MSR_IA32_MISC_ENABLE_MWAIT);
    }
    }
    +
    +void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
    +{
    + __kvm_update_cpuid_runtime(vcpu, vcpu->arch.cpuid_entries, vcpu->arch.cpuid_nent);
    +}
    EXPORT_SYMBOL_GPL(kvm_update_cpuid_runtime);

    static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
    @@ -278,6 +291,8 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
    {
    int r;

    + __kvm_update_cpuid_runtime(vcpu, e2, nent);
    +
    r = kvm_check_cpuid(e2, nent);
    if (r)
    return r;
    @@ -287,7 +302,6 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2,
    vcpu->arch.cpuid_nent = nent;

    kvm_update_kvm_cpuid_base(vcpu);
    - kvm_update_cpuid_runtime(vcpu);
    kvm_vcpu_after_set_cpuid(vcpu);

    return 0;
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-01-13 14:39    [W:4.246 / U:1.584 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site