本文将记录下Intel® Architecture Instruction Set Extensions Programming Reference中的user-timer events技术。笔者特意裁剪了本文相关的描述: user-timer events

The feature defines a new 64-bit value called the user deadline. Software may read and write the user deadline. When the user deadline is not zero, a user-timer event becomes pending when the logical processor’s timestamp counter (TSC) is greater than or equal to the user deadline.

A pending user-timer event is processed by the processor when CPL = 3 and certain other conditions apply. When processed, the event results in a user interrupt with the user-timer vector. (Software may read and write the user-timer vector). Specifically, the processor sets the bit in the UIRR (user interrupt request register) corresponding to the user timer vector. The processing also clears the user deadline, ensuring that there will be no subsequent user-timer events until software writes the user deadline again.

User Deadline

A logical processor that supports user-timer events supports a 64-bit value called the user deadline. If the user deadline is non-zero, the logical processor pends a user-timer event when the timestamp counter (TSC) reaches or exceeds the user deadline.

Software can write the user deadline using instructions. The processor enforces the following:

  • Writing zero to the user deadline disables user-timer events and cancels any that were pending. As a result, no user-timer event is pending after zero is written to the user deadline.
  • If software writes the user deadline with a non-zero value that is less than the TSC, a user-timer event will be pending upon completion of that write.
  • If software writes the user deadline with a non-zero value that is greater than that of the TSC, no user-timer event will be pending after the write until the TSC reaches the new user deadline.
  • A logical processor processes a pending user-timer event under certain conditions; The logical processor clears the user deadline after pending a user-timer event.

User Timer: Architectural State

The user-timer architecture defines a new MSR, IA32_UINTR_TIMER. This MSR can be accessed using MSR index 1B00H.

The IA32_UINTR_TIMER MSR has the following format:

  • Bits 5:0 are the user-timer vector. Processing of a user-timer event results in the pending of a user interrupt with this vector.
  • Bits 63:6 are the upper 56 bits of the user deadline.

Note that no bits are reserved in the MSR and that writes to the MSR will not fault due to the value of the instruction’s source operand. The IA32_UINTR_TIMER MSR can be accessed via the following instructions: RDMSR, RDMSRLIST, URDMSR, UWRMSR, WRMSR, WRMSRLIST, and WRMSRNS.

If the IA32_UINTR_TIMER MSR is written with value X, the user-timer vector gets value X & 3FH; the user deadline gets value X & ~3FH.

If the user-timer vector is V (0 ≤ V ≤ 63) and the user deadline is D, a read from the IA32_UINTR_TIMER MSR return value (D & ~3FH) | V.

Pending and Processing of User-Timer Events

There is a user-timer event pending whenever the user deadline is non-zero and is less than or equal to the value of the timestamp counter (TSC).

If CR4.UINTR = 1, a logical processor processes a pending user-timer event at an instruction boundary at which the following conditions all hold1: (1) IA32_EFER.LMA = CS.L = 1 (the logical processor is in 64-bit mode); (2) CPL = 3; (3) UIF = 1; and (4) the logical processor is not in the shutdown state or in the wait-for-SIPI state.

When the conditions just identified hold, the logical processor processes a user-timer event. User-timer events have priority just above that of user-interrupt delivery. If the logical processor was in a state entered using the TPAUSE and UMWAIT instructions, it first wakes up from that state and becomes active.
当上述条件成立时,logical processor就会处理用户定时器事件。用户定时器事件的优先级仅高于user-interrupt delivery。如果logical processor处于使用TPAUSE和UMWAIT指令进入的状态,它将首先从该状态中唤醒并进入活动状态。

The following pseudocode details the processing of a user-timer event:

  • UIRR[UserTimerVector] := 1;
  • recognize a pending user interrupt;// may be delivered immediately after processing
  • IA32_UINTR_TIMER := 0;// clears the deadline and the vector

VMX support

One new 64-bit VM-execution control field is defined called the virtual user-timer control. It can be accessed with the encoding pair 2050H/2051H.

Software can read and write the IA32_UINTR_TIMER MSR using certain instructions. The operation of those instructions is changed when they are executed in VMX non-root operation:

  • Any read from the IA32_UINTR_TIMER MSR (e.g., by RDMSR) returns the value of the virtual user-timer control.
  • Any write to the IA32_UINTR_TIMER MSR (e.g., by WRMSR) is treated as follows:
    • The source operand is written to the virtual user-timer control (updating the VMCS).
    • Bits 5:0 of the source operand are written to the user-timer vector.
    • If bits 63:6 of the source operand are zero, the user deadline (the value that actually controls when hardware generates a user time event) is cleared to 0.
    • If bits 63:6 of the source operand are not all zero, the user deadline is computed as follows. The source operand (with the low 6 bits cleared) is interpreted as a virtual user deadline. The processor converts that value to the actual user deadline based on the current configuration of TSC offsetting and TSC scaling.
    • Following such a write, the value of the IA32_UINTR_TIMER MSR (e.g., as would be observed following a subsequent VM exit) is such that bits 63:6 contain the actual user deadline (not the virtual user deadline), while bits 5:0 contain the user-timer vector.

相关指令汇总

  • RDMSR
  • RDMSRLIST
  • URDMSR
  • UWRMSR
  • WRMSR
  • WRMSRLIST
  • WRMSRNS
  • TPAUSE
  • UMWAIT

总结

笔者认为user-timer就是TSC deadline模式的lapic timer在user interrupt中的拓展。而user-timer虚拟化的核心就是IA32_UINTR_TIMER MSR的虚拟化。