diff options
author | Alok Kataria <akataria@vmware.com> | 2008-11-03 14:31:28 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-11-03 14:35:57 -0500 |
commit | 6bdbfe99916398dbb28d83833cc04757110f2738 (patch) | |
tree | 7783c666ff16ce70022946c070dd058ae2a74989 | |
parent | 395628ef4ea12ff0748099f145363b5e33c69acb (diff) |
x86: VMware: Fix vmware_get_tsc code
Impact: Fix possible failure to calibrate the TSC on Vmware near 4 GHz
The current version of the code to get the tsc frequency from
the VMware hypervisor, will be broken on processor with frequency
(4G-1) HZ, because on such processors eax will have UINT_MAX
and that would be legitimate.
We instead check that EBX did change to decide if we were able to
read the frequency from the hypervisor.
Signed-off-by: Alok N Kataria <akataria@vmware.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | arch/x86/kernel/cpu/vmware.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 2ac4394fcb90..a0905ecfe7d2 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -36,7 +36,7 @@ | |||
36 | "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ | 36 | "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ |
37 | "0"(VMWARE_HYPERVISOR_MAGIC), \ | 37 | "0"(VMWARE_HYPERVISOR_MAGIC), \ |
38 | "1"(VMWARE_PORT_CMD_##cmd), \ | 38 | "1"(VMWARE_PORT_CMD_##cmd), \ |
39 | "2"(VMWARE_HYPERVISOR_PORT), "3"(0) : \ | 39 | "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ |
40 | "memory"); | 40 | "memory"); |
41 | 41 | ||
42 | static inline int __vmware_platform(void) | 42 | static inline int __vmware_platform(void) |
@@ -53,7 +53,7 @@ static unsigned long __vmware_get_tsc_khz(void) | |||
53 | 53 | ||
54 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); | 54 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
55 | 55 | ||
56 | if (eax == (uint32_t)-1) | 56 | if (ebx == UINT_MAX) |
57 | return 0; | 57 | return 0; |
58 | tsc_hz = eax | (((uint64_t)ebx) << 32); | 58 | tsc_hz = eax | (((uint64_t)ebx) << 32); |
59 | do_div(tsc_hz, 1000); | 59 | do_div(tsc_hz, 1000); |