Skip to content

Conversation

@roypat
Copy link
Contributor

@roypat roypat commented Jul 9, 2024

Backport of #4666

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following Developer
Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md.

PR Checklist

  • If a specific issue led to this PR, this PR closes the issue.
  • The description of changes is clear and encompassing.
  • Any required documentation changes (code and docs) are included in this
    PR.
  • API changes follow the Runbook for Firecracker API changes.
  • User-facing changes are mentioned in CHANGELOG.md.
  • All added/changed functionality is tested.
  • New TODOs link to an issue.
  • Commits meet
    contribution quality standards.

  • This functionality cannot be added in rust-vmm.

roypat added 3 commits July 9, 2024 09:45
When restoring MSRs, we currently do not enforce any sort of relative
ordering. However, some MSRs have implicit dependencies on other MSRs
being restored before them, and failing to fulfill these dependencies
can result in incorrect VM behavior after resuming.

One example of such an implicit dependency between MSRs is the pair
(`MSR_IA32_TSC_DEADLINE`, `MSR_IA32_TSC`). When restoring
`MSR_IA32_TSC_DEADLINE`, KVM internally checks whether the value of this
restoration implies that the guest was waiting for the tsc_deadline
timer to expire at the time of being paused for snapshotting. If yes, it
primes a (either harddware or software depending on support) timer on
the host to make sure the guest will receive the expected interrupt
after restoration. To determine whether this is needed, KVM looks at the
guest's timestamp counter (TSC) and compares it with the requested
tsc_deadline value. The value KVM reads for the guest's TSC depends on
the value of MSR_IA32_TSC. Thus, if MSR_IA32_TSC_DEADLINE is set before
MSR_IA32_TSC is restored, this comparison will yield a wrong result (as
the deadline value is compared with something uninitialized). This can
either result in KVM determining the guest wasn't waiting for a timing
expiry at the time of snapshotting, or cause it to schedule the timer
interrupt too far into the future.

Note that the former is only a problem on AMD platforms, which do not
support the TSC_DEADLINE feature at the hardware level. Here, KVM falls
back to a software timer, which explicitly does not notify the vCPU if
the deadline value is "in the past". The hardware timer used on other
x86 platforms on the other hand always fires (potentially firing
immediately if the deadline value is in the past).

This commit fixes the above by ensuring we always restore MSR_IA32_TSC
before restoring MSR_IA32_TSC_DEADLINE. We realize this by splitting the
lists of MSRs that KVM gives us into one additional chunk containing all
"deferred" MSRs that needs to be restored "as late as possible". This
splitting happens at snapshot creation time, to get it off the hot-path.

Fixes firecracker-microvm#4099

Signed-off-by: Patrick Roy <[email protected]>
add changelog entry about firecracker-microvm#4099

Signed-off-by: Patrick Roy <[email protected]>
As the previous commit shows, the order of restoration of MSRs can be
important. Thus, we should not effectively randomly shuffle them
whenever we construct a VM. With this commit, we preserve the order in
which KVM tells us about MSRs in `KVM_GET_MSR_INDEX_LIST`, under the
assumption that if any dependencies exist, KVM will account for them as
part of the above IOCTL.

Signed-off-by: Patrick Roy <[email protected]>
@roypat roypat requested review from kalyazin, pb8o and xmarcalx as code owners July 9, 2024 08:55
@codecov
Copy link

codecov bot commented Jul 9, 2024

Codecov Report

Attention: Patch coverage is 92.59259% with 2 lines in your changes missing coverage. Please review.

Project coverage is 82.16%. Comparing base (54c2210) to head (4d4e687).

Files Patch % Lines
src/vmm/src/vstate/vcpu/x86_64.rs 91.66% 2 Missing ⚠️
Additional details and impacted files
@@                Coverage Diff                @@
##           firecracker-v1.8    #4671   +/-   ##
=================================================
  Coverage             82.16%   82.16%           
=================================================
  Files                   255      255           
  Lines                 31307    31325   +18     
=================================================
+ Hits                  25722    25738   +16     
- Misses                 5585     5587    +2     
Flag Coverage Δ
4.14-c5n.metal 79.66% <92.59%> (+<0.01%) ⬆️
4.14-c7g.metal ?
4.14-m5n.metal 79.65% <92.59%> (+<0.01%) ⬆️
4.14-m6a.metal 78.88% <92.59%> (+<0.01%) ⬆️
4.14-m6g.metal 76.70% <ø> (ø)
4.14-m6i.metal 79.65% <92.59%> (+<0.01%) ⬆️
4.14-m7g.metal 76.70% <ø> (ø)
5.10-c5n.metal 82.18% <92.59%> (+<0.01%) ⬆️
5.10-c7g.metal ?
5.10-m5n.metal 82.16% <92.59%> (-0.01%) ⬇️
5.10-m6a.metal 81.47% <92.59%> (+<0.01%) ⬆️
5.10-m6g.metal 79.47% <ø> (ø)
5.10-m6i.metal 82.16% <92.59%> (+<0.01%) ⬆️
5.10-m7g.metal 79.47% <ø> (ø)
6.1-c5n.metal 82.17% <92.59%> (+<0.01%) ⬆️
6.1-c7g.metal ?
6.1-m5n.metal 82.16% <92.59%> (+<0.01%) ⬆️
6.1-m6a.metal 81.47% <92.59%> (+<0.01%) ⬆️
6.1-m6g.metal 79.46% <ø> (ø)
6.1-m6i.metal 82.16% <92.59%> (+<0.01%) ⬆️
6.1-m7g.metal 79.47% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ShadowCurse ShadowCurse merged commit f84e4a5 into firecracker-microvm:firecracker-v1.8 Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants