From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Kevin Pedretti <ktpedre-4OHPYypu0djtX7QSmKvirg@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: APIC_TMCCT register read bug
Date: Mon, 15 Oct 2007 11:29:48 +0200 [thread overview]
Message-ID: <4713330C.7050909@qumranet.com> (raw)
In-Reply-To: <1192252790.16540.4.camel@saix14899>
Kevin Pedretti wrote:
> Hi,
>
> While booting a non-Linux OS under kvm-46, I noticed that reading
> APIC_TMCCT before initializing APIC_TDCR to something other than its
> boot time value would lead to a host kernel divide by zero exception.
> It's due to apic->timer.divide_count being set to 0 at boot... it should
> be set to 2 since APIC_TDCR=0 means 'divide count by 2'. The last hunk
> of the attached patch results in apic->timer.divide_count being set to 2
> and eliminates the oops.
>
> The other changes to apic_get_tmcct() are intended to clean it up a bit,
> although completely untested other than to verify 0 is returned for a
> read of APIC_TMCCT at boot. 'apic' should not be used before the
> ASSERT() and using u32 for counter_passed makes it fairly easy to
> overflow.
>
Patch looks good, but I'm missing a signed-off-by: line.
Eddie, can you also take a look?
> --- kvm-46.orig/kernel/lapic.c 2007-10-10 02:06:36.000000000 -0600
> +++ kvm-46.fix/kernel/lapic.c 2007-10-12 22:50:01.000000000 -0600
> @@ -487,12 +487,19 @@
>
> static u32 apic_get_tmcct(struct kvm_lapic *apic)
> {
> - u32 counter_passed;
> - ktime_t passed, now = apic->timer.dev.base->get_time();
> - u32 tmcct = apic_get_reg(apic, APIC_TMICT);
> + u64 counter_passed;
> + ktime_t passed, now;
> + u32 tmcct;
>
> ASSERT(apic != NULL);
>
> + now = apic->timer.dev.base->get_time();
> + tmcct = apic_get_reg(apic, APIC_TMICT);
> +
> + /* if initial count is 0, current count should also be 0 */
> + if (tmcct == 0)
> + return 0;
> +
> if (unlikely(ktime_to_ns(now) <=
> ktime_to_ns(apic->timer.last_update))) {
> /* Wrap around */
> @@ -507,15 +514,24 @@
>
> counter_passed = div64_64(ktime_to_ns(passed),
> (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
> - tmcct -= counter_passed;
>
> - if (tmcct <= 0) {
> - if (unlikely(!apic_lvtt_period(apic)))
> + if (counter_passed > tmcct) {
> + if (unlikely(!apic_lvtt_period(apic))) {
> + /* one-shot timers stick at 0 until reset */
> tmcct = 0;
> - else
> - do {
> - tmcct += apic_get_reg(apic, APIC_TMICT);
> - } while (tmcct <= 0);
> + } else {
> + /*
> + * periodic timers reset to APIC_TMICT when they
> + * hit 0. The while loop simulates this happening N
> + * times. (counter_passed %= tmcct) would also work,
> + * but might be slower or not work on 32-bit??
> + */
> + while (counter_passed > tmcct)
> + counter_passed -= tmcct;
> + tmcct -= counter_passed;
> + }
> + } else {
> + tmcct -= counter_passed;
> }
>
> return tmcct;
> @@ -844,7 +860,7 @@
> apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
> apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
> }
> - apic->timer.divide_count = 0;
> + update_divide_count(apic);
> atomic_set(&apic->timer.pending, 0);
> if (vcpu->vcpu_id == 0)
> vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
--
error compiling committee.c: too many arguments to function
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
prev parent reply other threads:[~2007-10-15 9:29 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-13 5:19 APIC_TMCCT register read bug Kevin Pedretti
2007-10-15 9:29 ` Avi Kivity [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4713330C.7050909@qumranet.com \
--to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
--cc=ktpedre-4OHPYypu0djtX7QSmKvirg@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox