Merge branch 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Sep 2013 18:05:13 +0000 (11:05 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Sep 2013 18:05:13 +0000 (11:05 -0700)
Pull x86 paravirt changes from Ingo Molnar:
 "Hypervisor signature detection cleanup and fixes - the goal is to make
  KVM guests run better on MS/Hyperv and to generalize and factor out
  the code a bit"

* 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86: Correctly detect hypervisor
  x86, kvm: Switch to use hypervisor_cpuid_base()
  xen: Switch to use hypervisor_cpuid_base()
  x86: Introduce hypervisor_cpuid_base()

1  2 
arch/x86/include/asm/processor.h

@@@ -942,6 -942,50 +942,21 @@@ extern int set_tsc_mode(unsigned int va
  
  extern u16 amd_get_nb_id(int cpu);
  
 -struct aperfmperf {
 -      u64 aperf, mperf;
 -};
 -
 -static inline void get_aperfmperf(struct aperfmperf *am)
 -{
 -      WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF));
 -
 -      rdmsrl(MSR_IA32_APERF, am->aperf);
 -      rdmsrl(MSR_IA32_MPERF, am->mperf);
 -}
 -
 -#define APERFMPERF_SHIFT 10
 -
 -static inline
 -unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
 -                                  struct aperfmperf *new)
 -{
 -      u64 aperf = new->aperf - old->aperf;
 -      u64 mperf = new->mperf - old->mperf;
 -      unsigned long ratio = aperf;
 -
 -      mperf >>= APERFMPERF_SHIFT;
 -      if (mperf)
 -              ratio = div64_u64(aperf, mperf);
 -
 -      return ratio;
 -}
 -
+ static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
+ {
+       uint32_t base, eax, signature[3];
+       for (base = 0x40000000; base < 0x40010000; base += 0x100) {
+               cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
+               if (!memcmp(sig, signature, 12) &&
+                   (leaves == 0 || ((eax - base) >= leaves)))
+                       return base;
+       }
+       return 0;
+ }
  extern unsigned long arch_align_stack(unsigned long sp);
  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);