[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Clean up two small APIC TDCR issues.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 617c187322ab3bdd82de7512adbcba2213ad0bc4 # Parent 5a9b79981a3553fb29422beb937dc23e12b36596 [HVM] Clean up two small APIC TDCR issues. First, only save the bits that can be set, so that on a subsequent read can't see MBZ bits as set. Next, be sure to initialize the timer_divide_count, which is derived from the TDCR. This avoids a potential divide-by-zero elsewhere in the code. The original patch was provided by Ben Thomas <ben@xxxxxxxxxxxxxxx>. This modified version refactors the code slightly and renames timer_divide_count to timer_divisor. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/vlapic.c | 43 +++++++++++++++++++-------------------- xen/include/asm-x86/hvm/vlapic.h | 2 - 2 files changed, 23 insertions(+), 22 deletions(-) diff -r 5a9b79981a35 -r 617c187322ab xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Thu Nov 09 17:28:12 2006 +0000 +++ b/xen/arch/x86/hvm/vlapic.c Thu Nov 09 17:53:05 2006 +0000 @@ -495,8 +495,7 @@ static uint32_t vlapic_get_tmcct(struct else passed = now - vlapic->timer_last_update; - counter_passed = passed / - (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count); + counter_passed = passed / (APIC_BUS_CYCLE_NS * vlapic->timer_divisor); tmcct -= counter_passed; @@ -528,10 +527,21 @@ static uint32_t vlapic_get_tmcct(struct return tmcct; } +static void vlapic_set_tdcr(struct vlapic *vlapic, unsigned int val) +{ + /* Only bits 0, 1 and 3 are settable; others are MBZ. */ + val &= 0xb; + vlapic_set_reg(vlapic, APIC_TDCR, val); + + /* Update the demangled timer_divisor. */ + val = ((val & 3) | ((val & 8) >> 1)) + 1; + vlapic->timer_divisor = 1 << (val & 7); +} + static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, unsigned int len, unsigned int *result) { - ASSERT(len == 4 && offset > 0 && offset <= APIC_TDCR); + ASSERT((len == 4) && (offset > 0) && (offset <= APIC_TDCR)); *result = 0; @@ -563,7 +573,7 @@ static unsigned long vlapic_read(struct struct vlapic *vlapic = vcpu_vlapic(v); unsigned int offset = address - vlapic->base_address; - if ( offset > APIC_TDCR) + if ( offset > APIC_TDCR ) return 0; /* some bugs on kernel cause read this with byte*/ @@ -760,8 +770,7 @@ static void vlapic_write(struct vcpu *v, vlapic_set_reg(vlapic, APIC_TMCCT, val); vlapic->timer_last_update = now; - offset = APIC_BUS_CYCLE_NS * - vlapic->timer_divide_count * val; + offset = APIC_BUS_CYCLE_NS * vlapic->timer_divisor * val; set_timer(&vlapic->vlapic_timer, now + offset); @@ -776,19 +785,10 @@ static void vlapic_write(struct vcpu *v, break; case APIC_TDCR: - { - unsigned int tmp1, tmp2; - - tmp1 = val & 0xf; - tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; - vlapic->timer_divide_count = 0x1 << (tmp2 & 0x7); - - vlapic_set_reg(vlapic, APIC_TDCR, val); - - HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divide count is 0x%x", - vlapic->timer_divide_count); - } - break; + vlapic_set_tdcr(vlapic, val & 0xb); + HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divisor is 0x%x", + vlapic->timer_divisor); + break; default: gdprintk(XENLOG_WARNING, @@ -852,8 +852,7 @@ void vlapic_timer_fn(void *data) vlapic_set_reg(vlapic, APIC_TMCCT, tmict); - offset = APIC_BUS_CYCLE_NS * - vlapic->timer_divide_count * tmict; + offset = APIC_BUS_CYCLE_NS * vlapic->timer_divisor * tmict; set_timer(&vlapic->vlapic_timer, now + offset); } @@ -967,6 +966,8 @@ static int vlapic_reset(struct vlapic *v vlapic->flush_tpr_threshold = 0; + vlapic_set_tdcr(vlapic, 0); + vlapic->base_address = vlapic->apic_base_msr & MSR_IA32_APICBASE_BASE; diff -r 5a9b79981a35 -r 617c187322ab xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Thu Nov 09 17:28:12 2006 +0000 +++ b/xen/include/asm-x86/hvm/vlapic.h Thu Nov 09 17:53:05 2006 +0000 @@ -49,7 +49,7 @@ struct vlapic { uint32_t status; uint64_t apic_base_msr; unsigned long base_address; - uint32_t timer_divide_count; + uint32_t timer_divisor; struct timer vlapic_timer; int timer_pending_count; int flush_tpr_threshold; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |