lkml.org 
[lkml]   [2011]   [Feb]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/6] KVM: SVM: Implement infrastructure for TSC_RATE_MSR
    Date
    This patch enhances the kvm_amd module with functions to
    support the TSC_RATE_MSR which can be used to set a given
    tsc frequency for the guest vcpu.

    Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
    ---
    arch/x86/include/asm/msr-index.h | 1 +
    arch/x86/kvm/svm.c | 37 ++++++++++++++++++++++++++++++++++++-
    2 files changed, 37 insertions(+), 1 deletions(-)

    diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
    index 5bfafb6..fdac548 100644
    --- a/arch/x86/include/asm/msr-index.h
    +++ b/arch/x86/include/asm/msr-index.h
    @@ -106,6 +106,7 @@
    complete list. */

    #define MSR_AMD64_PATCH_LEVEL 0x0000008b
    +#define MSR_AMD64_TSC_RATIO 0xc0000104
    #define MSR_AMD64_NB_CFG 0xc001001f
    #define MSR_AMD64_PATCH_LOADER 0xc0010020
    #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
    diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
    index bfb4948..c96c0a6 100644
    --- a/arch/x86/kvm/svm.c
    +++ b/arch/x86/kvm/svm.c
    @@ -63,6 +63,8 @@ MODULE_LICENSE("GPL");

    #define DEBUGCTL_RESERVED_BITS (~(0x3fULL))

    +#define TSC_RATIO_RSVD 0xffffff0000000000ULL
    +
    static bool erratum_383_found __read_mostly;

    static const u32 host_save_user_msrs[] = {
    @@ -142,6 +144,12 @@ struct vcpu_svm {
    unsigned int3_injected;
    unsigned long int3_rip;
    u32 apf_reason;
    +
    + struct {
    + bool enabled;
    + u64 ratio;
    + } tsc_scale;
    +
    };

    #define MSR_INVALID 0xffffffffU
    @@ -852,6 +860,25 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
    seg->base = 0;
    }

    +static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
    +{
    + struct vcpu_svm *svm = to_svm(vcpu);
    + u64 _tsc = tsc;
    +
    + if (svm->tsc_scale.enabled) {
    + u64 mult, frac;
    +
    + mult = svm->tsc_scale.ratio >> 32;
    + frac = svm->tsc_scale.ratio & ((1ULL << 32) - 1);
    +
    + _tsc *= mult;
    + _tsc += (tsc >> 32) * frac;
    + _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
    + }
    +
    + return _tsc;
    +}
    +
    static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
    {
    struct vcpu_svm *svm = to_svm(vcpu);
    @@ -2808,7 +2835,9 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
    case MSR_IA32_TSC: {
    struct vmcb *vmcb = get_host_vmcb(svm);

    - *data = vmcb->control.tsc_offset + native_read_tsc();
    + *data = vmcb->control.tsc_offset +
    + svm_scale_tsc(vcpu, native_read_tsc());
    +
    break;
    }
    case MSR_STAR:
    @@ -3564,6 +3593,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)

    clgi();

    + if (static_cpu_has(X86_FEATURE_TSCRATEMSR) && svm->tsc_scale.enabled)
    + wrmsrl(MSR_AMD64_TSC_RATIO, svm->tsc_scale.ratio);
    +
    local_irq_enable();

    asm volatile (
    @@ -3647,6 +3679,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)

    local_irq_disable();

    + if (static_cpu_has(X86_FEATURE_TSCRATEMSR) && svm->tsc_scale.enabled)
    + wrmsr(MSR_AMD64_TSC_RATIO, 0, 1);
    +
    vcpu->arch.cr2 = svm->vmcb->save.cr2;
    vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
    vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
    --
    1.7.1



    \
     
     \ /
      Last update: 2011-02-09 18:33    [W:0.029 / U:0.204 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site