|
@@ -24,6 +24,7 @@
|
|
|
#include <linux/dmi.h>
|
|
|
#include <asm/div64.h>
|
|
|
#include <asm/vmware.h>
|
|
|
+#include <asm/x86_init.h>
|
|
|
|
|
|
#define CPUID_VMWARE_INFO_LEAF 0x40000000
|
|
|
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
|
|
@@ -47,21 +48,29 @@ static inline int __vmware_platform(void)
|
|
|
return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
|
|
|
}
|
|
|
|
|
|
-static unsigned long __vmware_get_tsc_khz(void)
|
|
|
+static unsigned long vmware_get_tsc_khz(void)
|
|
|
{
|
|
|
uint64_t tsc_hz;
|
|
|
uint32_t eax, ebx, ecx, edx;
|
|
|
|
|
|
VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
|
|
|
|
|
|
- if (ebx == UINT_MAX)
|
|
|
- return 0;
|
|
|
tsc_hz = eax | (((uint64_t)ebx) << 32);
|
|
|
do_div(tsc_hz, 1000);
|
|
|
BUG_ON(tsc_hz >> 32);
|
|
|
return tsc_hz;
|
|
|
}
|
|
|
|
|
|
+void __init vmware_platform_setup(void)
|
|
|
+{
|
|
|
+ uint32_t eax, ebx, ecx, edx;
|
|
|
+
|
|
|
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
|
|
|
+
|
|
|
+ if (ebx != UINT_MAX)
|
|
|
+ x86_platform.calibrate_tsc = vmware_get_tsc_khz;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* While checking the dmi string infomation, just checking the product
|
|
|
* serial key should be enough, as this will always have a VMware
|
|
@@ -87,12 +96,6 @@ int vmware_platform(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-unsigned long vmware_get_tsc_khz(void)
|
|
|
-{
|
|
|
- BUG_ON(!vmware_platform());
|
|
|
- return __vmware_get_tsc_khz();
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
|
|
|
* Still, due to timing difference when running on virtual cpus, the TSC can
|