qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 1/2] [RFC] Make vmport report the processor speed


From: Alexander Graf
Subject: [Qemu-devel] [PATCH 1/2] [RFC] Make vmport report the processor speed
Date: Mon, 5 Jan 2009 17:11:10 +0100

If VMware ESX finds itself virtualized (read: inside VMware), it reads the TSC 
speed
from its backdoor, because measuring the TSC inside a VM is not exact.

This patch implements a hacky way to detect the TSC speed and passes that 
through to
the VM. I am open to suggestions on how to improve the behavior.
It also adds a magic return value of 2 on the version return, which is required 
by
VMware ESX.

WARNING: This implementation breaks on non-x86 hosts!

Signed-off-by: Alexander Graf <address@hidden>
---
 hw/vmport.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/hw/vmport.c b/hw/vmport.c
index 884af3f..825fd92 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -28,6 +28,7 @@
 
 //#define VMPORT_DEBUG
 
+#define VMPORT_CMD_GETPROCSPEED 0x01
 #define VMPORT_CMD_GETVERSION 0x0a
 #define VMPORT_CMD_GETRAMSIZE 0x14
 
@@ -87,6 +88,7 @@ static uint32_t vmport_cmd_get_version(void *opaque, uint32_t 
addr)
 {
     CPUState *env = cpu_single_env;
     env->regs[R_EBX] = VMPORT_MAGIC;
+    env->regs[R_ECX] = 2;
     return 6;
 }
 
@@ -97,6 +99,25 @@ static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t 
addr)
     return ram_size;
 }
 
+
+static inline int64_t rdtsc(void)
+{
+    int64_t val;
+    asm volatile ("rdtsc" : "=A" (val));
+    return val;
+}
+
+static uint32_t vmport_cmd_proc_speed(void *opaque, uint32_t addr)
+{
+    static uint64_t tsc = 0;
+    if ( tsc == 0 ) {
+        tsc = rdtsc();
+        usleep(100000);
+        tsc = (rdtsc() - tsc) / 100000;
+    }
+    return (tsc / 66) * 66;
+}
+
 void vmport_init(void)
 {
     register_ioport_read(0x5658, 1, 4, vmport_ioport_read, &port_state);
@@ -105,4 +126,5 @@ void vmport_init(void)
     /* Register some generic port commands */
     vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL);
     vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, NULL);
+    vmport_register(VMPORT_CMD_GETPROCSPEED, vmport_cmd_proc_speed, NULL);
 }
-- 
1.5.6





reply via email to

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