Just for info. We might someday want to make use of that at boot to run better in VMs... François. ------ Forwarded Message: ------ To: qemu-devel@xxxxxxxxxx From: Alexander Graf <agraf@xxxxxxx> 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 <agraf@xxxxxxx> --- 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