mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-23 09:47:44 +00:00
hv/mod_timer: refine timer interface
1. do not allow external modules to touch internal field of a timer. 2. make timer mode internal, period_in_ticks will decide the mode. API wise: 1. the "mode" parameter was taken out of initialize_timer(). 2. a new function update_timer() was added to update the timeout and period fields. 3. the timer_expired() function was extended with an output parameter to return the remaining cycles before expiration. Also, the "fire_tsc" field name of hv_timer was renamed to "timeout". With the new API, however, this change should not concern user code. Tracked-On: #5920 Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
@@ -260,9 +260,7 @@ static void vlapic_init_timer(struct acrn_vlapic *vlapic)
|
||||
vtimer = &vlapic->vtimer;
|
||||
(void)memset(vtimer, 0U, sizeof(struct vlapic_timer));
|
||||
|
||||
initialize_timer(&vtimer->timer,
|
||||
vlapic_timer_expired, vlapic2vcpu(vlapic),
|
||||
0UL, 0, 0UL);
|
||||
initialize_timer(&vtimer->timer, vlapic_timer_expired, vlapic2vcpu(vlapic), 0UL, 0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,16 +272,12 @@ static void vlapic_reset_timer(struct acrn_vlapic *vlapic)
|
||||
|
||||
timer = &vlapic->vtimer.timer;
|
||||
del_timer(timer);
|
||||
timer->mode = TICK_MODE_ONESHOT;
|
||||
timer->fire_tsc = 0UL;
|
||||
timer->period_in_cycle = 0UL;
|
||||
update_timer(timer, 0UL, 0UL);
|
||||
}
|
||||
|
||||
static bool
|
||||
set_expiration(struct acrn_vlapic *vlapic)
|
||||
{
|
||||
uint64_t now = cpu_ticks();
|
||||
uint64_t delta;
|
||||
struct vlapic_timer *vtimer;
|
||||
struct hv_timer *timer;
|
||||
uint32_t tmicr, divisor_shift;
|
||||
@@ -296,13 +290,11 @@ set_expiration(struct acrn_vlapic *vlapic)
|
||||
if ((tmicr == 0U) || (divisor_shift > 8U)) {
|
||||
ret = false;
|
||||
} else {
|
||||
delta = (uint64_t)tmicr << divisor_shift;
|
||||
uint64_t delta = (uint64_t)tmicr << divisor_shift;
|
||||
timer = &vtimer->timer;
|
||||
|
||||
if (vlapic_lvtt_period(vlapic)) {
|
||||
timer->period_in_cycle = delta;
|
||||
}
|
||||
timer->fire_tsc = now + delta;
|
||||
update_timer(timer, cpu_ticks() + delta,
|
||||
vlapic_lvtt_period(vlapic) ? delta : 0UL);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
@@ -322,10 +314,7 @@ static void vlapic_update_lvtt(struct acrn_vlapic *vlapic,
|
||||
* the timer mode disarms the local APIC timer.
|
||||
*/
|
||||
del_timer(timer);
|
||||
timer->mode = (timer_mode == APIC_LVTT_TM_PERIODIC) ?
|
||||
TICK_MODE_PERIODIC: TICK_MODE_ONESHOT;
|
||||
timer->fire_tsc = 0UL;
|
||||
timer->period_in_cycle = 0UL;
|
||||
update_timer(timer, 0UL, 0UL);
|
||||
|
||||
vtimer->mode = timer_mode;
|
||||
}
|
||||
@@ -333,19 +322,13 @@ static void vlapic_update_lvtt(struct acrn_vlapic *vlapic,
|
||||
|
||||
static uint32_t vlapic_get_ccr(const struct acrn_vlapic *vlapic)
|
||||
{
|
||||
uint64_t now = cpu_ticks();
|
||||
uint32_t remain_count = 0U;
|
||||
const struct vlapic_timer *vtimer;
|
||||
|
||||
vtimer = &vlapic->vtimer;
|
||||
const struct vlapic_timer *vtimer = &vlapic->vtimer;
|
||||
|
||||
if ((vtimer->tmicr != 0U) && (!vlapic_lvtt_tsc_deadline(vlapic))) {
|
||||
uint64_t fire_tsc = vtimer->timer.fire_tsc;
|
||||
|
||||
if (now < fire_tsc) {
|
||||
uint32_t divisor_shift = vtimer->divisor_shift;
|
||||
uint64_t shifted_delta =
|
||||
(fire_tsc - now) >> divisor_shift;
|
||||
uint64_t remains;
|
||||
if (!timer_expired(&vtimer->timer, cpu_ticks(), &remains)) {
|
||||
uint64_t shifted_delta = remains >> vtimer->divisor_shift;
|
||||
remain_count = (uint32_t)shifted_delta;
|
||||
}
|
||||
}
|
||||
@@ -405,7 +388,7 @@ uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic)
|
||||
} else if (!vlapic_lvtt_tsc_deadline(vlapic)) {
|
||||
ret = 0UL;
|
||||
} else {
|
||||
ret = (vlapic->vtimer.timer.fire_tsc == 0UL) ? 0UL :
|
||||
ret = timer_expired(&vlapic->vtimer.timer, cpu_ticks(), NULL) ? 0UL :
|
||||
vcpu_get_guest_msr(vcpu, MSR_IA32_TSC_DEADLINE);
|
||||
}
|
||||
|
||||
@@ -444,14 +427,14 @@ void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg)
|
||||
if (val != 0UL) {
|
||||
/* transfer guest tsc to host tsc */
|
||||
val -= exec_vmread64(VMX_TSC_OFFSET_FULL);
|
||||
timer->fire_tsc = val;
|
||||
update_timer(timer, val, 0UL);
|
||||
/* vlapic_init_timer has been called,
|
||||
* and timer->fire_tsc is not 0,here
|
||||
* add_timer should not return error
|
||||
*/
|
||||
(void)add_timer(timer);
|
||||
} else {
|
||||
timer->fire_tsc = 0UL;
|
||||
update_timer(timer, 0UL, 0UL);
|
||||
}
|
||||
} else {
|
||||
/* No action required */
|
||||
@@ -2039,10 +2022,6 @@ static void vlapic_timer_expired(void *data)
|
||||
if (!vlapic_lvtt_masked(vlapic)) {
|
||||
vlapic_set_intr(vcpu, lapic->lvt[APIC_LVT_TIMER].v & APIC_LVTT_VECTOR, LAPIC_TRIG_EDGE);
|
||||
}
|
||||
|
||||
if (!vlapic_lvtt_period(vlapic)) {
|
||||
vlapic->vtimer.timer.fire_tsc = 0UL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user