-
Notifications
You must be signed in to change notification settings - Fork 162
feat: add hardware interrupt support (PIC, KVM IRQ chip, MSHV SynIC, WHP software timer) #1272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
41b8916
76f452d
779d77f
946df68
abbacae
23a1f06
50914a1
a2d0f84
dc2521b
a7414c6
4487d3e
60bede8
e84c56d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,5 +66,8 @@ core::arch::global_asm!(" | |
| mov cr4, rdi | ||
| flush_done: | ||
| call {internal_dispatch_function}\n | ||
| mov dx, 108\n | ||
| out dx, al\n | ||
| cli\n | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any use for this wfi fallback at the end here? If the guest does resume execution on interrupt delivery from a hlt here, something has gone very wrong. |
||
| hlt\n | ||
| ", internal_dispatch_function = sym crate::guest_function::call::internal_dispatch_function); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -172,6 +172,24 @@ global_asm!( | |
| hl_exception_handler = sym super::handle::hl_exception_handler, | ||
| ); | ||
|
|
||
| // Default no-op IRQ handler for hardware interrupts (vectors 0x20-0x2F). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIUI this is code that should be running in target_arch = i686 only right now, so perhaps ought not be in amd64? |
||
| // Sends a non-specific EOI to the master PIC and returns. | ||
| // This prevents unhandled-interrupt faults when the in-kernel PIT fires | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This race condition is still present since this is only being installed in init_idt after the guest has already been running instructions for some time? If this is a serious concern, surely we need the host to control the vm state a bit better---either only enabling interrupts after initialize() has finished and the guest kernel is up, or presetting the idt state before entering the guest for the first time (although I'm unsure if there is API for that) |
||
| // before a guest has installed its own IRQ handler. | ||
| global_asm!( | ||
| ".globl _default_irq_handler", | ||
| "_default_irq_handler:", | ||
| "push rax", | ||
| "mov al, 0x20", | ||
| "out 0x20, al", // PIC EOI | ||
| "pop rax", | ||
| "iretq", | ||
| ); | ||
|
|
||
| unsafe extern "C" { | ||
| fn _default_irq_handler(); | ||
| } | ||
|
|
||
| pub(in super::super) fn init_idt(pc: *mut ProcCtrl) { | ||
| let idt = unsafe { &raw mut (*pc).idt }; | ||
| let set_idt_entry = |idx, handler: unsafe extern "C" fn()| { | ||
|
|
@@ -203,6 +221,14 @@ pub(in super::super) fn init_idt(pc: *mut ProcCtrl) { | |
| set_idt_entry(Exception::VirtualizationException, _do_excp20); // Virtualization Exception | ||
| set_idt_entry(Exception::SecurityException, _do_excp30); // Security Exception | ||
|
|
||
| // Install a default no-op IRQ handler at vector 0x20 (IRQ0 after PIC remapping). | ||
| // This ensures HLT can wake when an in-kernel PIT is active, even before the | ||
| // guest installs its own IRQ handler. | ||
| let irq_handler_addr = _default_irq_handler as *const () as u64; | ||
| unsafe { | ||
| (&raw mut (*idt).entries[0x20]).write_volatile(IdtEntry::new(irq_handler_addr)); | ||
| } | ||
|
|
||
| let idtr = IdtPointer { | ||
| limit: (core::mem::size_of::<IDT>() - 1) as u16, | ||
| base: idt as u64, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment (and maybe name) (and commit message) should clarify that this is meant to be used for wfi rather than actually ending execution as we've been using hlt for in the past?