From b9971c206f01e087229e44d1d683cbe92185502d Mon Sep 17 00:00:00 2001 From: "Li, Fei1" Date: Thu, 3 May 2018 10:08:59 +0800 Subject: [PATCH] hv: vlapic_timer: remove vlapic one-shot/periodic timer implement These code is useless since it just pseudocode. Current it doesn't support vlapic one-shot/periodic timer. Signed-off-by: Li, Fei1 Acked-by: Eddie Dong --- hypervisor/arch/x86/cpuid.c | 7 +- hypervisor/arch/x86/guest/time.h | 118 ----------- hypervisor/arch/x86/guest/vlapic.c | 250 +----------------------- hypervisor/arch/x86/guest/vlapic_priv.h | 8 - 4 files changed, 6 insertions(+), 377 deletions(-) delete mode 100644 hypervisor/arch/x86/guest/time.h diff --git a/hypervisor/arch/x86/cpuid.c b/hypervisor/arch/x86/cpuid.c index ad9e39458..cf1f3aa51 100644 --- a/hypervisor/arch/x86/cpuid.c +++ b/hypervisor/arch/x86/cpuid.c @@ -165,14 +165,11 @@ static void init_vcpuid_entry(__unused struct vm *vm, * * EAX: (Virtual) TSC frequency in kHz. * TSC frequency is calculated from PIT in ACRN - * EBX: (Virtual) Bus (local apic timer) frequency in kHz. - * Bus (local apic timer) frequency is hardcoded as - * (128 * 1024 * 1024) in ACRN - * ECX, EDX: RESERVED (reserved fields are set to zero). + * EBX, ECX, EDX: RESERVED (reserved fields are set to zero). */ case 0x40000010: entry->eax = (uint32_t)(tsc_hz / 1000); - entry->ebx = (128 * 1024 * 1024) / 1000; + entry->ebx = 0; entry->ecx = 0; entry->edx = 0; break; diff --git a/hypervisor/arch/x86/guest/time.h b/hypervisor/arch/x86/guest/time.h deleted file mode 100644 index 9265837ef..000000000 --- a/hypervisor/arch/x86/guest/time.h +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2018 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)time.h 8.5 (Berkeley) 5/4/95 - * $FreeBSD$ - */ - -#ifndef _TIME_H_ -#define _TIME_H_ - -struct callout { - void *c_arg; /* function argument */ - void (*c_func)(void *); /* function to call */ - short c_flags; /* User State */ -}; - -#define CALLOUT_ACTIVE 0x0002 /* callout is currently active */ -#define CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */ -#define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE) -#define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE) -#define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING) - -typedef int64_t time_t; -typedef int64_t sbintime_t; - -struct bintime { - time_t sec; - uint64_t frac; -}; - -static inline void -bintime_add(struct bintime *_bt, const struct bintime *_bt2) -{ - uint64_t _u; - - _u = _bt->frac; - _bt->frac += _bt2->frac; - if (_u > _bt->frac) - _bt->sec++; - _bt->sec += _bt2->sec; -} - -static inline void -bintime_sub(struct bintime *_bt, const struct bintime *_bt2) -{ - uint64_t _u; - - _u = _bt->frac; - _bt->frac -= _bt2->frac; - if (_u < _bt->frac) - _bt->sec--; - _bt->sec -= _bt2->sec; -} - -static inline void -bintime_mul(struct bintime *_bt, uint32_t _x) -{ - uint64_t _p1, _p2; - - _p1 = (_bt->frac & 0xffffffffull) * _x; - _p2 = (_bt->frac >> 32) * _x + (_p1 >> 32); - _bt->sec *= _x; - _bt->sec += (_p2 >> 32); - _bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull); -} - -#define bintime_cmp(a, b, cmp) \ - (((a)->sec == (b)->sec) ? \ - ((a)->frac cmp(b)->frac) : \ - ((a)->sec cmp(b)->sec)) - -#define SBT_1S ((sbintime_t)1 << 32) -#define SBT_1US (SBT_1S / 1000000) - -#define BT2FREQ(bt) \ - (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \ - ((bt)->frac >> 1)) - -#define FREQ2BT(freq, bt) \ -{ \ - (bt)->sec = 0; \ - (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \ -} - -static inline sbintime_t -bttosbt(const struct bintime _bt) -{ - - return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32)); -} - -#endif /* !_TIME_H_ */ diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 6de19efb9..9bcfd53d8 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -40,7 +40,6 @@ #include "instr_emul_wrapper.h" #include "instr_emul.h" -#include "time.h" #include "vlapic_priv.h" #define VLAPIC_VERBOS 0 @@ -86,22 +85,6 @@ do { \ #define VLAPIC_CTR_ISR(vlapic, msg) #endif -/* - * The 'vlapic->timer_mtx' is used to provide mutual exclusion between the - * vlapic_callout_handler() and vcpu accesses to: - * - timer_freq_bt, timer_period_bt, timer_fire_bt - * - timer LVT register - */ -#define VLAPIC_TIMER_LOCK(vlapic) spinlock_obtain(&((vlapic)->timer_mtx)) -#define VLAPIC_TIMER_UNLOCK(vlapic) spinlock_release(&((vlapic)->timer_mtx)) - -/* - * APIC timer frequency: - * - arbitrary but chosen to be in the ballpark of contemporary hardware. - * - power-of-two to avoid loss of precision when converted to a bintime. - */ -#define VLAPIC_BUS_FREQ (128 * 1024 * 1024) - /* TIMER_LVT bit[18:17] == 0x10 TSD DEADLINE mode */ #define VLAPIC_TSCDEADLINE(lvt) (((lvt) & 0x60000) == 0x40000) @@ -265,124 +248,13 @@ vlapic_id_write_handler(struct vlapic *vlapic) lapic->id = vlapic_get_id(vlapic); } -static void -binuptime(struct bintime *bt) +static uint32_t vlapic_get_ccr(__unused struct vlapic *vlapic) { - uint64_t now = TICKS_TO_US(rdtsc()); - - bt->sec = now / 1000000; - bt->frac = ((now - bt->sec * 1000000) * - (uint64_t)0x80000000 / 1000000) << 33; -} - -int -callout_reset_sbt(struct callout *c, __unused sbintime_t sbt, - __unused sbintime_t prec, void (*ftn)(void *), - void *arg, __unused int flags) -{ - c->c_flags |= CALLOUT_PENDING; - c->c_func = ftn; - c->c_arg = arg; - - /* TODO: add expire timer*/ - - c->c_flags &= ~CALLOUT_PENDING; - c->c_flags |= CALLOUT_ACTIVE; - return 0; } -int -callout_stop(struct callout *c) +static void vlapic_dcr_write_handler(__unused struct vlapic *vlapic) { - callout_deactivate(c); - c->c_flags |= CALLOUT_PENDING; - - return 0; -} - -static int -vlapic_timer_divisor(uint32_t dcr) -{ - switch (dcr & 0xB) { - case APIC_TDCR_1: - return 1; - case APIC_TDCR_2: - return 2; - case APIC_TDCR_4: - return 4; - case APIC_TDCR_8: - return 8; - case APIC_TDCR_16: - return 16; - case APIC_TDCR_32: - return 32; - case APIC_TDCR_64: - return 64; - case APIC_TDCR_128: - return 128; - default: - panic("vlapic_timer_divisor: invalid dcr"); - } -} - -static uint32_t -vlapic_get_ccr(struct vlapic *vlapic) -{ - struct bintime bt_now, bt_rem; - struct lapic *lapic; - uint32_t ccr; - - ccr = 0; - lapic = vlapic->apic_page; - - VLAPIC_TIMER_LOCK(vlapic); - if (callout_active(&vlapic->callout)) { - /* - * If the timer is scheduled to expire in the future then - * compute the value of 'ccr' based on the remaining time. - */ - binuptime(&bt_now); - if (bintime_cmp(&vlapic->timer_fire_bt, &bt_now, >)) { - bt_rem = vlapic->timer_fire_bt; - bintime_sub(&bt_rem, &bt_now); - ccr += bt_rem.sec * BT2FREQ(&vlapic->timer_freq_bt); - ccr += bt_rem.frac / vlapic->timer_freq_bt.frac; - } - } - ASSERT(ccr <= lapic->icr_timer, - "vlapic_get_ccr: invalid ccr %#x, icr_timer is %#x", - ccr, lapic->icr_timer); - dev_dbg(ACRN_DBG_LAPIC, "vlapic ccr_timer = %#x, icr_timer = %#x", - ccr, lapic->icr_timer); - VLAPIC_TIMER_UNLOCK(vlapic); - return ccr; -} - -static void -vlapic_dcr_write_handler(struct vlapic *vlapic) -{ - struct lapic *lapic; - int divisor; - - lapic = vlapic->apic_page; - VLAPIC_TIMER_LOCK(vlapic); - - divisor = vlapic_timer_divisor(lapic->dcr_timer); - dev_dbg(ACRN_DBG_LAPIC, "vlapic dcr_timer=%#x, divisor=%d", - lapic->dcr_timer, divisor); - - /* - * Update the timer frequency and the timer period. - * - * XXX changes to the frequency divider will not take effect until - * the timer is reloaded. - */ - FREQ2BT(VLAPIC_BUS_FREQ / divisor, &vlapic->timer_freq_bt); - vlapic->timer_period_bt = vlapic->timer_freq_bt; - bintime_mul(&vlapic->timer_period_bt, lapic->icr_timer); - - VLAPIC_TIMER_UNLOCK(vlapic); } static void @@ -784,17 +656,6 @@ vlapic_set_error(struct vlapic *vlapic, uint32_t mask) vlapic->esr_firing = 0; } -static void -vlapic_fire_timer(struct vlapic *vlapic) -{ - uint32_t lvt; - - /* The timer LVT always uses the fixed delivery mode.*/ - lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_TIMER_LVT); - if (vlapic_fire_lvt(vlapic, lvt | APIC_LVT_DM_FIXED)) - dev_dbg(ACRN_DBG_LAPIC, "vlapic timer fired"); -} - static int vlapic_trigger_lvt(struct vlapic *vlapic, int vector) { @@ -850,97 +711,8 @@ vlapic_trigger_lvt(struct vlapic *vlapic, int vector) return 0; } -static void -vlapic_callout_handler(void *arg) +static void vlapic_icrtmr_write_handler(__unused struct vlapic *vlapic) { - struct vlapic *vlapic; - struct bintime bt, btnow; - sbintime_t rem_sbt; - - vlapic = arg; - - VLAPIC_TIMER_LOCK(vlapic); - if (callout_pending(&vlapic->callout)) /* callout was reset */ - goto done; - - if (!callout_active(&vlapic->callout)) /* callout was stopped */ - goto done; - - callout_deactivate(&vlapic->callout); - - vlapic_fire_timer(vlapic); - - if (vlapic_periodic_timer(vlapic)) { - binuptime(&btnow); - ASSERT(bintime_cmp(&btnow, &vlapic->timer_fire_bt, >=), - "vlapic callout at %#lx.%#lx, expected at %#lx.#%lx", - btnow.sec, btnow.frac, vlapic->timer_fire_bt.sec, - vlapic->timer_fire_bt.frac); - - /* - * Compute the delta between when the timer was supposed to - * fire and the present time. - */ - bt = btnow; - bintime_sub(&bt, &vlapic->timer_fire_bt); - - rem_sbt = bttosbt(vlapic->timer_period_bt); - if (bintime_cmp(&bt, &vlapic->timer_period_bt, <)) { - /* - * Adjust the time until the next countdown downward - * to account for the lost time. - */ - rem_sbt -= bttosbt(bt); - } else { - /* - * If the delta is greater than the timer period then - * just reset our time base instead of trying to catch - * up. - */ - vlapic->timer_fire_bt = btnow; - - dev_dbg(ACRN_DBG_LAPIC, - "vlapic timer lagged by %lu usecs, period is %lu usecs", - bttosbt(bt) / SBT_1US, - bttosbt(vlapic->timer_period_bt) / SBT_1US); - - dev_dbg(ACRN_DBG_LAPIC, "resetting time base"); - } - - bintime_add(&vlapic->timer_fire_bt, &vlapic->timer_period_bt); - callout_reset_sbt(&vlapic->callout, rem_sbt, 0, - vlapic_callout_handler, vlapic, 0); - } -done: - VLAPIC_TIMER_UNLOCK(vlapic); -} - -static void -vlapic_icrtmr_write_handler(struct vlapic *vlapic) -{ - struct lapic *lapic; - sbintime_t sbt; - uint32_t icr_timer; - - VLAPIC_TIMER_LOCK(vlapic); - - lapic = vlapic->apic_page; - icr_timer = lapic->icr_timer; - - vlapic->timer_period_bt = vlapic->timer_freq_bt; - bintime_mul(&vlapic->timer_period_bt, icr_timer); - - if (icr_timer != 0) { - binuptime(&vlapic->timer_fire_bt); - bintime_add(&vlapic->timer_fire_bt, &vlapic->timer_period_bt); - - sbt = bttosbt(vlapic->timer_period_bt); - callout_reset_sbt(&vlapic->callout, sbt, 0, - vlapic_callout_handler, vlapic, 0); - } else - callout_stop(&vlapic->callout); - - VLAPIC_TIMER_UNLOCK(vlapic); } /* @@ -1312,13 +1084,10 @@ vlapic_svr_write_handler(struct vlapic *vlapic) if ((changed & APIC_SVR_ENABLE) != 0) { if ((new & APIC_SVR_ENABLE) == 0) { /* - * The apic is now disabled so stop the apic timer + * TODO: The apic is now disabled so stop the apic timer * and mask all the LVT entries. */ dev_dbg(ACRN_DBG_LAPIC, "vlapic is software-disabled"); - VLAPIC_TIMER_LOCK(vlapic); - callout_stop(&vlapic->callout); - VLAPIC_TIMER_UNLOCK(vlapic); vlapic_mask_lvts(vlapic); /* the only one enabled LINT0-ExtINT vlapic disabled */ if (vlapic->vm->vpic_wire_mode == VPIC_WIRE_NULL) { @@ -1592,12 +1361,7 @@ vlapic_init(struct vlapic *vlapic) /* * If the vlapic is configured in x2apic mode then it will be * accessed in the critical section via the MSR emulation code. - * - * Therefore the timer mutex must be a spinlock because blockable - * mutexes cannot be acquired in a critical section. */ - spinlock_init(&vlapic->timer_mtx); - vlapic->msr_apicbase = DEFAULT_APIC_BASE | APICBASE_ENABLED; if (vlapic->vcpu->vcpu_id == 0) @@ -1631,12 +1395,6 @@ void vlapic_restore(struct vlapic *vlapic, struct lapic_regs *regs) lapic->dcr_timer = regs->tdcr; } -void -vlapic_cleanup(__unused struct vlapic *vlapic) -{ - callout_stop(&vlapic->callout); -} - static uint64_t vlapic_get_apicbase(struct vlapic *vlapic) { diff --git a/hypervisor/arch/x86/guest/vlapic_priv.h b/hypervisor/arch/x86/guest/vlapic_priv.h index 6b4d2ea21..961ead7df 100644 --- a/hypervisor/arch/x86/guest/vlapic_priv.h +++ b/hypervisor/arch/x86/guest/vlapic_priv.h @@ -118,14 +118,8 @@ struct vlapic { uint32_t esr_pending; int esr_firing; - struct callout callout; /* vlapic timer */ - struct bintime timer_fire_bt; /* callout expiry time */ - struct bintime timer_freq_bt; /* timer frequency */ - struct bintime timer_period_bt; /* timer period */ struct timer timer; - spinlock_t timer_mtx; - /* * The 'isrvec_stk' is a stack of vectors injected by the local apic. * A vector is popped from the stack when the processor does an EOI. @@ -148,6 +142,4 @@ struct vlapic { struct pir_desc pir; }; -void vlapic_cleanup(struct vlapic *vlapic); - #endif /* _VLAPIC_PRIV_H_ */