On 09/21/15 17:50, Dr. David Alan Gilbert wrote: > * Peter Maydell (peter.mayd...@linaro.org) wrote: >> On 21 September 2015 at 08:12, Laszlo Ersek <ler...@redhat.com> wrote: >>> Where does the division by zero come from then? Well grub fetches and >>> stashes the TSC, then programs the PIT to sleep for some time, then >>> re-fetches the TSC, and uses the TSC difference as denominator when >>> calculating the "TSC rate". (It has a solid idea of the real time >>> passed, due to the PIT frequency being a given.) >> >> I was wondering rereading the bug report whether this was down >> to our lousy RDTSC implementation...thanks for digging in and >> confirming what's going on. >> >>> Now, the cpu_get_real_ticks() implementation is *host* specific. You can >>> find it implemented for a bunch of host architectures in >>> "include/qemu/timer.h". >> >>> I applied the following extremely sophisticated patch (with the motto >>> "it cannot get more wronger"): >>> >>>> diff --git a/include/qemu/timer.h b/include/qemu/timer.h >>>> index 9939246..def22de 100644 >>>> --- a/include/qemu/timer.h >>>> +++ b/include/qemu/timer.h >>>> @@ -1003,8 +1003,7 @@ static inline int64_t cpu_get_real_ticks(void) >>>> totally wrong, but hopefully better than nothing. */ >>>> static inline int64_t cpu_get_real_ticks (void) >>>> { >>>> - static int64_t ticks = 0; >>>> - return ticks++; >>>> + return get_clock(); >>>> } >>>> #endif >>>> >>> >>> get_clock() is CLOCK_MONOTONIC based, has (theoretical) nanosecond >>> resolution, and a nice flat int64_t encoding that should suffice for >>> approx. 329 years. This should provide grub with a larger denominator. >>> >>> This "fix" allowed me to boot the i386 Debian image on the AARCH64 host. >>> >>> For a real fix... I think on AARCH64 hosts at least, a "real" cycle >>> counter should be available, and someone who knows AARCH64 could write a >>> function that fetches it. >>> >>> For 32-bit ARM, I presume the Raspberry Pi 2 and the Odroid C1 are >>> advanced enough for a similar cycle counter reading function. >> >> There isn't a user-space readable cycle counter on ARM. >> (There is a counter which might be accessible to userspace >> depending on kernel config, but the kernel doesn't guarantee >> its availability as an ABI thing.) >> >> Probably we should figure out a sane way to emulate guest >> cycle counters that isn't dependent on the host CPU architecture. >> I think having QEMU's behaviour as seen by the guest vary like >> this is a recipe for confusion. > > Time is always hard though; what are the requirements for that > particular view of time: > > 1) It must be monotonic - which get_clock() is iff the host > supports it (which I guess most do?) > 2) It's got to be within a few orders of magnitude of sane > with respect to wall clock, so that if someone measures > it over a second or a 1/100th of a second or whatever then > it's still seen to go up. > > get_clock() isn't that bad if it's monotonic; if not I'd suggest > for TCG a multiple of the number of TBs executed (if that's > already stored somewhere), or something similar.
I think that's quite what -icount does; I had even tested -icount before posting my email, and it works too. (See -icount in qemu-options.hx.) I hadn't known about -icount, but I saw the connection in the cpu_get_ticks() function (mentioned earlier in the call tree): /* return the host CPU cycle counter and handle stop/restart */ /* Caller must hold the BQL */ int64_t cpu_get_ticks(void) { int64_t ticks; if (use_icount) { return cpu_get_icount(); } ... I didn't recommend it because the documentation in "qemu-options.hx" confused me, and I thought the emulation should work without obscure switches. Thanks Laszlo > > Dave > >> thanks >> -- PMM > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK >