Kernel timekeeping calculates a clock value by keeping a base value and
adding the number of nanoseconds since that time. Those nanoseconds are
calculated from the clocksource delta. Then periodically, the base value is
moved forwards (refer timekeeping_advance()) which is done by the local
timer interrupt handler. It is designed such that there will always be a
timer interrupt before the delta becomes big enough to overflow the 64-bit
multiplication used in the conversion of delta to nanoseconds (refer
timekeeping_delta_to_ns()). Obviously if timer interrupts are stopped, then
the multiplication does eventually overflow.
Timekeeping multiplication overflow results in a "time loop", typically
cycling about every 15 minutes with x86 TSC, for example starting at 10:00:
Because a VMM can deliberately stop timer interrupts for a guest, a virtual
machine can be exposed to this issue.
TDX maintains a monotonically increasing virtual TSC for a TDX guest, so
the overflow is allowing a backwards movement of timekeeping that would not
happen otherwise.
It is considered this could break security of cryptographic protocols that
rely on the timestamps for freshness / replay protection, and consequently
the kernel should prevent such a time loop.
Handle multiplication overflows by falling back to higher precision
calculation when the possibility of an overflow is detected.
Submission: https://lore.kernel.org/all/20240308131512.44324-1-adrian.hunter@intel.com/
Summary:
Kernel timekeeping calculates a clock value by keeping a base value and adding the number of nanoseconds since that time. Those nanoseconds are calculated from the clocksource delta. Then periodically, the base value is moved forwards (refer timekeeping_advance()) which is done by the local timer interrupt handler. It is designed such that there will always be a timer interrupt before the delta becomes big enough to overflow the 64-bit multiplication used in the conversion of delta to nanoseconds (refer timekeeping_delta_to_ns()). Obviously if timer interrupts are stopped, then the multiplication does eventually overflow.
Timekeeping multiplication overflow results in a "time loop", typically cycling about every 15 minutes with x86 TSC, for example starting at 10:00:
10:00, 10:01, 10:02 ... 10:15, 10:00, 10:01, ... 10:15, 10:00, 10:01 ...
Because a VMM can deliberately stop timer interrupts for a guest, a virtual machine can be exposed to this issue.
TDX maintains a monotonically increasing virtual TSC for a TDX guest, so the overflow is allowing a backwards movement of timekeeping that would not happen otherwise.
It is considered this could break security of cryptographic protocols that rely on the timestamps for freshness / replay protection, and consequently the kernel should prevent such a time loop.
Handle multiplication overflows by falling back to higher precision calculation when the possibility of an overflow is detected.