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.

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.

1 participant