Message ID | 1302460123-25704-5-git-send-email-weil@mail.berlios.de |
---|---|
State | Superseded |
Headers | show |
On 04/10/2011 08:28 PM, Stefan Weil wrote: > Commit 68c23e5520e8286d79d96ab47c0ea722ceb75041 removed the > multimedia timer, but this timer is needed for certain > Linux kernels. Otherwise Linux boot stops with this error: > > MP-BIOS bug: 8254 timer not connected to IO-APIC > > So the multimedia timer is added again here. Which distribution and Windows version is that? Also, have they tried the non-dynticks timer (win32)? Paolo
Am 11.04.2011 09:36, schrieb Paolo Bonzini: > On 04/10/2011 08:28 PM, Stefan Weil wrote: >> Commit 68c23e5520e8286d79d96ab47c0ea722ceb75041 removed the >> multimedia timer, but this timer is needed for certain >> Linux kernels. Otherwise Linux boot stops with this error: >> >> MP-BIOS bug: 8254 timer not connected to IO-APIC >> >> So the multimedia timer is added again here. > > Which distribution and Windows version is that? Also, have they tried > the non-dynticks timer (win32)? > > Paolo The bug was reported for a tinycore 3.5.1 guest (linux kernel 3.6.33-3). The iso image is available from http://distro.ibiblio.org/tinycorelinux/3.x/release/. QEMU was running on XP SP3. Other Linux live CD-ROMs (e.g. FC14) were reported to show the same bug when run as guest. APIC can be disabled (kernel parameter), without APIC there is no problem. I see the same bug here with two XP hosts and also tried both timer variants of current QEMU (without a difference). I don't get the bug when running on a Linux host using wine. Regards, Stefan
On 2011-04-11 19:21, Stefan Weil wrote: > Am 11.04.2011 09:36, schrieb Paolo Bonzini: >> On 04/10/2011 08:28 PM, Stefan Weil wrote: >>> Commit 68c23e5520e8286d79d96ab47c0ea722ceb75041 removed the >>> multimedia timer, but this timer is needed for certain >>> Linux kernels. Otherwise Linux boot stops with this error: >>> >>> MP-BIOS bug: 8254 timer not connected to IO-APIC >>> >>> So the multimedia timer is added again here. >> >> Which distribution and Windows version is that? Also, have they tried >> the non-dynticks timer (win32)? >> >> Paolo > > The bug was reported for a tinycore 3.5.1 guest (linux kernel 3.6.33-3). > The iso image is available from > http://distro.ibiblio.org/tinycorelinux/3.x/release/. > QEMU was running on XP SP3. > > Other Linux live CD-ROMs (e.g. FC14) were reported to show the same bug > when run as guest. > > APIC can be disabled (kernel parameter), without APIC there is no problem. > > I see the same bug here with two XP hosts and also tried both timer > variants > of current QEMU (without a difference). > > I don't get the bug when running on a Linux host using wine. Passing no_timer_check to the Linux guest should work around the issue as well. But this feature is only available since 2.6.20 (excluding popular legacy 2.6.16 kernels). Jan
On 04/12/2011 02:36 PM, Jan Kiszka wrote: >> I see the same bug here with two XP hosts and also tried both timer >> variants >> of current QEMU (without a difference). >> >> I don't get the bug when running on a Linux host using wine. > > Passing no_timer_check to the Linux guest should work around the issue > as well. But this feature is only available since 2.6.20 (excluding > popular legacy 2.6.16 kernels). I think adding back MM timers is fine, especially since a bug that only happens under native Windows is a bug I'm unlikely to look at... Paolo
On 2011-04-12 14:40, Paolo Bonzini wrote: > On 04/12/2011 02:36 PM, Jan Kiszka wrote: >>> I see the same bug here with two XP hosts and also tried both timer >>> variants >>> of current QEMU (without a difference). >>> >>> I don't get the bug when running on a Linux host using wine. >> >> Passing no_timer_check to the Linux guest should work around the issue >> as well. But this feature is only available since 2.6.20 (excluding >> popular legacy 2.6.16 kernels). > > I think adding back MM timers is fine, especially since a bug that only > happens under native Windows is a bug I'm unlikely to look at... That wasn't meant as a vote against changing the Windows code paths, just as a further hint how to work-around virtualization related effects. Even with high-res timers, you may hit that issue once in a while, also on Linux hosts. When using KVM, latest Linux guest will notice that they are running on a hypervisor and should skip the test automatically IIRC. Jan
diff --git a/qemu-timer.c b/qemu-timer.c index 26e5ea3..a57197b 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -209,6 +209,10 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) #ifdef _WIN32 +static int mm_start_timer(struct qemu_alarm_timer *t); +static void mm_stop_timer(struct qemu_alarm_timer *t); +static void mm_rearm_timer(struct qemu_alarm_timer *t); + static int win32_start_timer(struct qemu_alarm_timer *t); static void win32_stop_timer(struct qemu_alarm_timer *t); static void win32_rearm_timer(struct qemu_alarm_timer *t); @@ -301,6 +305,8 @@ static struct qemu_alarm_timer alarm_timers[] = { #endif {"unix", unix_start_timer, unix_stop_timer, NULL}, #else + {"mmtimer", mm_start_timer, mm_stop_timer, NULL}, + {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer}, {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer}, {"win32", win32_start_timer, win32_stop_timer, NULL}, #endif @@ -949,6 +955,96 @@ static void unix_stop_timer(struct qemu_alarm_timer *t) #ifdef _WIN32 +static MMRESULT mm_timer; +static unsigned mm_period; + +static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, + DWORD_PTR dwUser, DWORD_PTR dw1, + DWORD_PTR dw2) +{ + struct qemu_alarm_timer *t = alarm_timer; + if (!t) { + return; + } + if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) { + t->expired = alarm_has_dynticks(t); + t->pending = 1; + qemu_notify_event(); + } +} + +static int mm_start_timer(struct qemu_alarm_timer *t) +{ + TIMECAPS tc; + UINT flags; + + memset(&tc, 0, sizeof(tc)); + timeGetDevCaps(&tc, sizeof(tc)); + + mm_period = tc.wPeriodMin; + timeBeginPeriod(mm_period); + + flags = TIME_CALLBACK_FUNCTION; + if (alarm_has_dynticks(t)) { + flags |= TIME_ONESHOT; + } else { + flags |= TIME_PERIODIC; + } + + mm_timer = timeSetEvent(1, /* interval (ms) */ + mm_period, /* resolution */ + mm_alarm_handler, /* function */ + (DWORD)t, /* parameter */ + flags); + + if (!mm_timer) { + fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", + GetLastError()); + timeEndPeriod(mm_period); + return -1; + } + + return 0; +} + +static void mm_stop_timer(struct qemu_alarm_timer *t) +{ + timeKillEvent(mm_timer); + timeEndPeriod(mm_period); +} + +static void mm_rearm_timer(struct qemu_alarm_timer *t) +{ + int nearest_delta_ms; + + assert(alarm_has_dynticks(t)); + if (!active_timers[QEMU_CLOCK_REALTIME] && + !active_timers[QEMU_CLOCK_VIRTUAL] && + !active_timers[QEMU_CLOCK_HOST]) { + return; + } + + timeKillEvent(mm_timer); + + nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000; + if (nearest_delta_ms < 1) { + nearest_delta_ms = 1; + } + mm_timer = timeSetEvent(nearest_delta_ms, + mm_period, + mm_alarm_handler, + (DWORD)t, + TIME_ONESHOT | TIME_CALLBACK_FUNCTION); + + if (!mm_timer) { + fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", + GetLastError()); + + timeEndPeriod(mm_period); + exit(1); + } +} + static int win32_start_timer(struct qemu_alarm_timer *t) { HANDLE hTimer;
Commit 68c23e5520e8286d79d96ab47c0ea722ceb75041 removed the multimedia timer, but this timer is needed for certain Linux kernels. Otherwise Linux boot stops with this error: MP-BIOS bug: 8254 timer not connected to IO-APIC So the multimedia timer is added again here. Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Stefan Weil <weil@mail.berlios.de> --- qemu-timer.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 96 insertions(+), 0 deletions(-)