Skip to content

Hyper-V Synthetic Timers and AutoEOI - #855

Open
Teknomancer wants to merge 8 commits into
VirtualBox:mainfrom
Teknomancer:hyperv-stimer
Open

Teknomancer wants to merge 8 commits into
VirtualBox:mainfrom
Teknomancer:hyperv-stimer

Conversation

@Teknomancer

Copy link
Copy Markdown
Contributor

Base work for Hyper-V synthetic timers (VP assist page) and AutoEOI.

SMP VMs are still a todo (will R3 release assert).

Work-in-progress. Currently Windows 11 uses them, doesn't use direct mode yet,
but since Hyper-V EOI assist is not implemented results in significantly more EOIs than when using SVM AVIC.
…r and fix fMsgPending even when SINT is masked.

Also SIMP enabled and SINT masking doesn't apply in direct-mode.
Timer message delivery is busted on SMP VMs because timers always fire on last EMT.
Also, we should consider MMIO2 mapping of the SIM page after checking large-page issue bugref:7532.
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Sep 7, 2026
@Teknomancer

Copy link
Copy Markdown
Contributor Author

There is a race between apicPostInterrupt and apicUpdatePendingInterrupts/apicGetInterrupt in the above changes.

Working on fixing that with the current lockfree approach. It requires extending the PIB to hold one more bit per vector for the AutoEOI status but this is more work than initially anticipated and also touches the regular APIC interrupt path more.

… apicUpdatePendingInterrupts when Hyper-V AutoEOIs are used.

Put the AutoEOI state as part of the edge-triggered PIB itself.
Use distinct types so edge-triggered and level-sensitive stay distinct.
@Teknomancer

Copy link
Copy Markdown
Contributor Author

Commit 7f018c15d4e024ccff0d37ab1411e6966c04f0ce now fixes the potential race mentioned in the above comment.

To elaborate the race condition: Posting an AutoEOI interrupt made the vector pending in PIB and separately in AutoEOI bitmap. This meant the target EMT can consume and deliver the interrupt with the wrong AutoEOI state in-between and leaving the stale AutoEOI bit which will apply to the next interrupt using the same vector.

The APIC PIB (pending interrupt bitmap) was split into edge-triggered and level-sensitive types (since we handle them differently anyway). The edge-triggered bitmap now gains an additional bit for every vector:

#define APIC_PIB_INTR_NOT_PENDING         0x0
#define APIC_PIB_INTR_PENDING             0x1
#define APIC_PIB_INTR_PENDING_AUTO_EOI    0x2
#define APIC_PIB_INTR_RSVD                0x3

This change means regular APIC code was touched, so it requires as much testing as it can. All the guests I tested continue to work normally but my test setup is very limited. There is still some cleanup I can do in the APIC PIB state/code (e.g. alloc, and removal of some long dead/commented out code) which I deliberately chose not to do here. Can be done later.

one of the things I want to check is why the edge-triggered PIB is allocated separately and accessed via "pvApicPibR0", "pvApicPibR3" but level-sensitive PIB we just use the type directly and make it part of the APICCPU structure itself.

@aleksey-ilyushin aleksey-ilyushin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add fallthrough and will make idxStimer declaration conditional (VBOX_WITH_STATISTICS).

++cPending;
break;
case APIC_PIB_INTR_RSVD:
pHlp->pfnPrintf(pHlp, " (%#02x Invalid)", uVector);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs RT_FALL_THROUGH(); after this line.


/* Get the VCPU's synthetic timer config and timer index. */
uint64_t const uStimerConfig = pHvStimer->uStimerConfigMsr;
uint16_t const idxStimer = pHvStimer->idxStimer;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idxStimer is never used in release builds without statistics.

aleksey-ilyushin added a commit that referenced this pull request Sep 28, 2026
…toEOI). ??github:gh-8 github-merge-author:Teknomancer <v.ramshankar@gmail.com>5

svn:sync-xref-src-repo-rev: r175206
aleksey-ilyushin added a commit that referenced this pull request Sep 28, 2026
svn:sync-xref-src-repo-rev: r175207
aleksey-ilyushin added a commit that referenced this pull request Sep 28, 2026
svn:sync-xref-src-repo-rev: r175208
aleksey-ilyushin added a commit that referenced this pull request Sep 28, 2026
svn:sync-xref-src-repo-rev: r175209
aleksey-ilyushin pushed a commit that referenced this pull request Sep 28, 2026
svn:sync-xref-src-repo-rev: r175210
aleksey-ilyushin added a commit that referenced this pull request Sep 28, 2026
…(Hyper-V Synthetic Timers and AutoEOI). ​github:gh-855

github-merge-author:Teknomancer <​v.ramshankar@gmail.com>

svn:sync-xref-src-repo-rev: r175211
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants