Kazu wrote:

If you set /proc/sys/dev/rtc/max-user-freq to 1024 and disable cpuspeed
service that is related to SpeedStep/PowerNow! on a host OS, the clock in
guest OS works fine.

I checked it on i686/x86_64 Linux host.

Mind saying how you checked this? I'm on a pentium-III mobile processor and the only way I've seen so far to make qemu + rdtsc behave 100% is by disabling ACPI (boot with -noacpi). If I add a simple printf to cpu_calibrate_ticks it doesn't seem fixed to me:

[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 1126809000
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 17308857
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 103710852
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 15292604
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 96695295
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 1126761234
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 1126762522
[EMAIL PROTECTED] /prog/qemu-stuff $ qemu -localtime -hda winxp.img -no-acpi -kernel-kqemu -soundhw es1370
ticks_per_sec set as 49791263

The first entry is with the patch attached called 'ticks_from_proc.patch' applied (I've been using this for almost a year). It sets the value ticks_per_sec, which happens to be used by a lot of qemu's hardware emulation, using information in /proc/cpuinfo. This doesn't fix the time issue as rdtsc is still used every time a SIGALRM signal occurs for timing, but at least the guest's emulated hardware runs to speed.

[EMAIL PROTECTED] /prog/qemu-cvs/qemu-acpi/qemu $ find . -type f -exec fgrep -l 'ticks_per_sec' {} \;
./audio/audio.c
./audio/noaudio.c
./audio/wavaudio.c
./monitor.c
./vl.c
./vl.h
./hw/acpi.c
./hw/adlib.c
./hw/arm_timer.c
./hw/cuda.c
./hw/fdc.c
./hw/i8254.c
./hw/i8259.c
./hw/ide.c
./hw/mc146818rtc.c
./hw/mips_r4k.c
./hw/ppc.c
./hw/sb16.c
./hw/sh7750.c
./hw/slavio_timer.c
./hw/usb-uhci.c

The second patch adds the printf statement so you can see this for yourself.
--- a/vl.c      2006-05-16 06:42:11.000000000 -0500
+++ b/vl.c      2006-05-16 06:35:25.000000000 -0500
@@ -637,6 +637,7 @@
     usec = get_clock() - usec;
     ticks = cpu_get_real_ticks() - ticks;
     ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
+    printf("ticks_per_sec set as %lli\n", ticks_per_sec);
 }
 #endif /* !_WIN32 */
 
Index: qemu/vl.c
@@ -596,8 +596,43 @@
 #endif
 }
 
+uint64_t get_tps_from_proc()
+{
+    FILE *fp;
+    char buf[30];
+    double cpu_mhz;
+
+    if (!(fp = fopen("/proc/cpuinfo", "r")))
+        return 0;
+
+    /* find wanted line */
+    while (fgets(buf, 30, fp) != NULL)
+        if (!strncmp(buf, "cpu MHz", 7))
+            break;
+
+    /* line not found? */
+    if (feof(fp)) {
+        fclose(fp);
+        return 0;
+    }
+    fclose(fp);
+
+    /* put 'cpu MHz' value into cpu_mhz */
+    if (!sscanf(&buf[9], ": %lf", &cpu_mhz))
+        return 0;
+
+    /* return estimated ticks/sec value */
+    return (uint64_t)(cpu_mhz * 1000000.0);
+}
+
 void cpu_calibrate_ticks(void)
 {
+    if (!(ticks_per_sec = get_tps_from_proc()))
+        fprintf(stderr, "Could not obtain ticks/sec. from /proc/cpuinfo\n \
+                        resorting to regular method (tsc)\n");
+    else /* value obtained, skip below */
+        return;
+
     int64_t usec, ticks;
 
     usec = get_clock();
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to