qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v3 2/3] x86: kvm: Add MTRR support for kvm_get|p


From: Laszlo Ersek
Subject: Re: [Qemu-devel] [PATCH v3 2/3] x86: kvm: Add MTRR support for kvm_get|put_msrs()
Date: Fri, 15 Aug 2014 00:18:31 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0

On 08/14/14 23:39, Alex Williamson wrote:
> The MTRR state in KVM currently runs completely independent of the
> QEMU state in CPUX86State.mtrr_*.  This means that on migration, the
> target loses MTRR state from the source.  Generally that's ok though
> because KVM ignores it and maps everything as write-back anyway.  The
> exception to this rule is when we have an assigned device and an IOMMU
> that doesn't promote NoSnoop transactions from that device to be cache
> coherent.  In that case KVM trusts the guest mapping of memory as
> configured in the MTRR.
> 
> This patch updates kvm_get|put_msrs() so that we retrieve the actual
> vCPU MTRR settings and therefore keep CPUX86State synchronized for
> migration.  kvm_put_msrs() is also used on vCPU reset and therefore
> allows future modificaitons of MTRR state at reset to be realized.
> 
> Note that the entries array used by both functions was already
> slightly undersized for holding every possible MSR, so this patch
> increases it beyond the 28 new entries necessary for MTRR state.
> 
> Signed-off-by: Alex Williamson <address@hidden>
> Cc: Laszlo Ersek <address@hidden>
> Cc: address@hidden
> ---
> 
>  target-i386/cpu.h |    2 +
>  target-i386/kvm.c |  101 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 101 insertions(+), 2 deletions(-)
> 
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index d37d857..3460b12 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -337,6 +337,8 @@
>  #define MSR_MTRRphysBase(reg)           (0x200 + 2 * (reg))
>  #define MSR_MTRRphysMask(reg)           (0x200 + 2 * (reg) + 1)
>  
> +#define MSR_MTRRphysIndex(addr)         ((((addr) & ~1u) - 0x200) / 2)
> +
>  #define MSR_MTRRfix64K_00000            0x250
>  #define MSR_MTRRfix16K_80000            0x258
>  #define MSR_MTRRfix16K_A0000            0x259
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 097fe11..ddedc73 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -79,6 +79,7 @@ static int lm_capable_kernel;
>  static bool has_msr_hv_hypercall;
>  static bool has_msr_hv_vapic;
>  static bool has_msr_hv_tsc;
> +static bool has_msr_mtrr;
>  
>  static bool has_msr_architectural_pmu;
>  static uint32_t num_architectural_pmu_counters;
> @@ -739,6 +740,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
>          env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
>      }
>  
> +    if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
> +        has_msr_mtrr = true;
> +    }
> +
>      return 0;
>  }
>  
> @@ -1183,7 +1188,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
>      CPUX86State *env = &cpu->env;
>      struct {
>          struct kvm_msrs info;
> -        struct kvm_msr_entry entries[100];
> +        struct kvm_msr_entry entries[150];
>      } msr_data;
>      struct kvm_msr_entry *msrs = msr_data.entries;
>      int n = 0, i;
> @@ -1278,6 +1283,37 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
>              kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC,
>                                env->msr_hv_tsc);
>          }
> +        if (has_msr_mtrr) {
> +            kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, 
> env->mtrr_deftype);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix64K_00000, env->mtrr_fixed[0]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix16K_80000, env->mtrr_fixed[1]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]);
> +            kvm_msr_entry_set(&msrs[n++],
> +                              MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]);
> +            for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
> +                kvm_msr_entry_set(&msrs[n++],
> +                                  MSR_MTRRphysBase(i), 
> env->mtrr_var[i].base);
> +                kvm_msr_entry_set(&msrs[n++],
> +                                  MSR_MTRRphysMask(i), 
> env->mtrr_var[i].mask);
> +            }
> +        }
>  
>          /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
>           *       kvm_put_msr_feature_control. */
> @@ -1484,7 +1520,7 @@ static int kvm_get_msrs(X86CPU *cpu)
>      CPUX86State *env = &cpu->env;
>      struct {
>          struct kvm_msrs info;
> -        struct kvm_msr_entry entries[100];
> +        struct kvm_msr_entry entries[150];
>      } msr_data;
>      struct kvm_msr_entry *msrs = msr_data.entries;
>      int ret, i, n;
> @@ -1572,6 +1608,24 @@ static int kvm_get_msrs(X86CPU *cpu)
>      if (has_msr_hv_tsc) {
>          msrs[n++].index = HV_X64_MSR_REFERENCE_TSC;
>      }
> +    if (has_msr_mtrr) {
> +        msrs[n++].index = MSR_MTRRdefType;
> +        msrs[n++].index = MSR_MTRRfix64K_00000;
> +        msrs[n++].index = MSR_MTRRfix16K_80000;
> +        msrs[n++].index = MSR_MTRRfix16K_A0000;
> +        msrs[n++].index = MSR_MTRRfix4K_C0000;
> +        msrs[n++].index = MSR_MTRRfix4K_C8000;
> +        msrs[n++].index = MSR_MTRRfix4K_D0000;
> +        msrs[n++].index = MSR_MTRRfix4K_D8000;
> +        msrs[n++].index = MSR_MTRRfix4K_E0000;
> +        msrs[n++].index = MSR_MTRRfix4K_E8000;
> +        msrs[n++].index = MSR_MTRRfix4K_F0000;
> +        msrs[n++].index = MSR_MTRRfix4K_F8000;
> +        for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
> +            msrs[n++].index = MSR_MTRRphysBase(i);
> +            msrs[n++].index = MSR_MTRRphysMask(i);
> +        }
> +    }
>  
>      msr_data.info.nmsrs = n;
>      ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
> @@ -1692,6 +1746,49 @@ static int kvm_get_msrs(X86CPU *cpu)
>          case HV_X64_MSR_REFERENCE_TSC:
>              env->msr_hv_tsc = msrs[i].data;
>              break;
> +        case MSR_MTRRdefType:
> +            env->mtrr_deftype = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix64K_00000:
> +            env->mtrr_fixed[0] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix16K_80000:
> +            env->mtrr_fixed[1] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix16K_A0000:
> +            env->mtrr_fixed[2] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_C0000:
> +            env->mtrr_fixed[3] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_C8000:
> +            env->mtrr_fixed[4] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_D0000:
> +            env->mtrr_fixed[5] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_D8000:
> +            env->mtrr_fixed[6] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_E0000:
> +            env->mtrr_fixed[7] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_E8000:
> +            env->mtrr_fixed[8] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_F0000:
> +            env->mtrr_fixed[9] = msrs[i].data;
> +            break;
> +        case MSR_MTRRfix4K_F8000:
> +            env->mtrr_fixed[10] = msrs[i].data;
> +            break;
> +        case MSR_MTRRphysBase(0) ... MSR_MTRRphysMask(MSR_MTRRcap_VCNT - 1):
> +            if (index & 1) {
> +                env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data;
> +            } else {
> +                env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
> +            }
> +            break;
>          }
>      }
>  
> 

Compared it with v2 2/3.

Reviewed-by: Laszlo Ersek <address@hidden>

Thanks!
Laszlo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]