mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-04 21:29:43 +00:00
transcode, edit, and upload HLD 0.7 section 3.6 (Timer) Also, fix the hv sections file names to be consistent. Tracked-on: #1623 Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
61 lines
2.6 KiB
ReStructuredText
61 lines
2.6 KiB
ReStructuredText
.. _timer-hld:
|
||
|
||
Timer
|
||
#####
|
||
|
||
Because ACRN is a flexible, lightweight reference hypervisor, we provide
|
||
limited timer management services:
|
||
|
||
- Only lapic tsc-deadline timer is supported as the clock source.
|
||
|
||
- A timer can only be added on the logical CPU for a process or thread. Timer
|
||
scheduling or timer migrating are not supported.
|
||
|
||
How it works
|
||
************
|
||
|
||
When the system boots, we check that the hardware supports lapic
|
||
tsc-deadline timer by checking CPUID.01H:ECX.TSC_Deadline[bit 24]. If
|
||
support is missing, we output an error message and panic the hypervisor.
|
||
If supported, we register the timer interrupt callback that raises a
|
||
timer softirq on each logical CPU and set the lapic timer mode to
|
||
tsc-deadline timer mode by writing the local APIC LVT register.
|
||
|
||
Data Structures and APIs
|
||
************************
|
||
|
||
.. note:: API link to hv_timer and per_cpu_timer structs in include/arch/x86/timer.h
|
||
And to the function APIs there too.
|
||
|
||
Before adding a timer, we must initialize the timer with
|
||
*initialize_timer*. The processor generates a timer interrupt when the
|
||
value of timer-stamp counter is greater than or equal to the *fire_tsc*
|
||
field. If you want to add a periodic timer, you should also pass the
|
||
period (unit in tsc cycles), otherwise, period_in_cycle will be ignored.
|
||
When the timer interrupt is generated, it will call the callback
|
||
function *func* with parameter *priv_data*.
|
||
|
||
The *initialize_timer* function only initialize the timer data
|
||
structure; it will not program the ``IA32_TSC_DEADLINE_MSR`` to generate
|
||
the timer interrupt. If you want to generate a timer interrupt, you must
|
||
call *add_timer* to add the timer to the *per_cpu_timer* timer_list. In
|
||
return, we will chose the nearest expired timer on the timer_list and
|
||
program ``IA32_TSC_DEADLINE_MSR`` by writing its value to fire_ts. Then
|
||
when the fire_tsc expires, it raises the interrupt whose callback raises
|
||
a softirq. We will handle the software interrupt before the VM reenters
|
||
the guest. (Currently, the hypervisor only uses the timer for the
|
||
console).
|
||
|
||
The timer softirq handler will check each expired timer on its
|
||
timer_list. Before calling the expired timer callback handler, it will
|
||
remove the timer from its logical cpu timer_list. After calling the
|
||
timer callback handler, it will re-add the timer to the timer_list if
|
||
it’s a periodic timer. If you want to modify a timer before it expires,
|
||
you should call del_timer to remove the timer from the timer_list, then
|
||
call add_timer again after updating the timer fields.
|
||
|
||
.. note::
|
||
|
||
Only call initialize_timer only once for each timer.
|
||
Don't call add_timer or del_timer in the timer callback function.
|