Skip to content

Commit e1adf51

Browse files
authored
feat: add hardware interrupt support (#1272)
* feat: add PIC emulation, OutBAction variants, and guest halt mechanism - Add PvTimerConfig (port 107) and Halt (port 108) to OutBAction enum - Add userspace 8259A PIC emulation for MSHV/WHP (KVM uses in-kernel PIC) - Add halt() function in guest exit module using Halt port instead of HLT - Add default no-op IRQ handler at IDT vector 0x20 for PIC-remapped IRQ0 - Update dispatch epilogue to use Halt port before cli+hlt fallback - Add hw-interrupts feature flag to hyperlight-host Signed-off-by: danbugs <danilochiarlone@gmail.com> * feat(kvm): add hardware interrupt support with in-kernel IRQ chip - Create IRQ chip (PIC + IOAPIC + LAPIC) and PIT before vCPU creation - Add hw-interrupts run loop that handles HLT re-entry, Halt port, and PvTimerConfig port (ignored since in-kernel PIT handles scheduling) - Non-hw-interrupts path also recognizes Halt port for compatibility Signed-off-by: danbugs <danilochiarlone@gmail.com> * feat(mshv): add hardware interrupt support with SynIC timer - Enable LAPIC in partition flags for SynIC direct-mode timer delivery - Configure LAPIC (SVR, TPR, LINT0/1, LVT Timer) during VM creation - Install MSR intercept on IA32_APIC_BASE to prevent guest from disabling the LAPIC globally - Add SynIC STIMER0 configuration via PvTimerConfig IO port - Add userspace PIC emulation integration for MSHV - Restructure run_vcpu into a loop for HLT re-entry and hw IO handling - Bridge PIC EOI to LAPIC EOI for SynIC timer interrupt acknowledgment - Handle PIT/speaker/debug IO ports in userspace Signed-off-by: danbugs <danilochiarlone@gmail.com> * feat(whp): add hardware interrupt support with software timer Add WHP hardware interrupt support using a host-side software timer thread that periodically injects interrupts via WHvRequestInterrupt. Key changes: - Detect LAPIC emulation support via WHvGetCapability - Initialize LAPIC via bulk interrupt-controller state API (WHvGet/SetVirtualProcessorInterruptControllerState2) since individual APIC register writes fail with ACCESS_DENIED - Software timer thread for periodic interrupt injection - LAPIC EOI handling for PIC-only guest acknowledgment - PIC emulation integration for MSHV/WHP shared 8259A - Filter APIC_BASE from set_sregs when LAPIC emulation active - HLT re-entry when timer is active Signed-off-by: danbugs <danilochiarlone@gmail.com> * test: add hardware interrupt unit and integration tests Signed-off-by: danbugs <danilochiarlone@gmail.com> * ci: add hw-interrupts test step to CI and Justfile Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: add halt port IO write and restore hw_timer_interrupts test Add Halt outb (port 108) before cli/hlt in guest init and dummyguest so KVM's in-kernel LAPIC does not absorb the HLT exit. Also restore the hw_timer_interrupts integration test that was inadvertently dropped. Signed-off-by: danbugs <danilochiarlone@gmail.com> * experiment: replace in-kernel PIT with irqfd + host timer thread Replace create_pit2() with a host-side timer thread that fires an EventFd registered via register_irqfd for GSI 0 (IRQ0). The in-kernel IRQ chip (PIC + IOAPIC + LAPIC) is kept for proper interrupt routing. When the guest writes to PvTimerConfig (port 107), the host parses the requested period and spawns a timer thread that periodically writes to the EventFd. Guest PIT port writes (0x40-0x43) exit to userspace and are silently ignored. Tested with nanvix hello-c.elf: works correctly. Signed-off-by: danbugs <danilochiarlone@gmail.com> * experiment: MSHV — replace SynIC timer with request_virtual_interrupt + host timer thread Replace the SynIC-based timer (STIMER0_CONFIG/COUNT + SCONTROL) with a host timer thread that periodically calls request_virtual_interrupt() (HVCALL_ASSERT_VIRTUAL_INTERRUPT, hypercall 148). This makes MSHV consistent with the KVM irqfd and WHP software timer patterns — all three platforms now use: (1) start timer on PvTimerConfig, (2) host thread periodically injects interrupt, (3) stop on Halt/Drop. Changes: - Remove SynIC dependency: make_default_synthetic_features_mask, SCONTROL, STIMER0_CONFIG, STIMER0_COUNT imports and usage - Set synthetic_proc_features to 0 (no SynIC features needed) - Wrap vm_fd in Arc<VmFd> for thread-safe sharing - Add timer_stop + timer_thread fields (same pattern as KVM) - PvTimerConfig handler spawns timer thread with request_virtual_interrupt - Add Drop impl for timer cleanup - Remove build_stimer_config() and period_us_to_100ns() helpers - Remove SynIC-related unit tests Kept unchanged: LAPIC init, MSR intercept, PIC emulation, EOI bridging (all still required for interrupt delivery). NOT RUNTIME TESTED — MSHV not available on this system. Signed-off-by: danbugs <danilochiarlone@gmail.com> * experiment: eliminate PIC state machine — hardcode vector 0x20, no-op PIC ports Remove the Pic struct from both MSHV and WHP. The nanvix guest always remaps IRQ0 to vector 0x20 via PIC ICW2, so the host can hardcode the timer vector instead of tracking the ICW initialization sequence. PIC ports (0x20/0x21/0xA0/0xA1) are now accepted as no-ops. The only PIC-related logic retained is LAPIC EOI bridging: when the guest sends a non-specific EOI on port 0x20, the host clears the LAPIC ISR bit. This is 3 lines of logic vs the ~130-line pic.rs state machine. This addresses the PR 1272 reviewer concern about emulating "a good fraction of the IC controller" — the PIC state machine was the unnecessary complexity, not the timer delivery mechanism. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: delete unused pic.rs file The PIC state machine was eliminated in the previous experimental commits (MSHV/WHP now hardcode vector 0x20 and no-op PIC ports). Remove the orphaned pic.rs file and its mod declaration. Signed-off-by: danbugs <danilochiarlone@gmail.com> * style: rustfmt fixes in kvm.rs Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: address PR 1272 review feedback - Remove _default_irq_handler (timer thread, not PIT, injects IRQs) - Remove cli;hlt after outb port 108 in guest asm and exit.rs - Revert to #[derive(Debug)] for all backends - Revert feature_val to upstream unsafe { features.as_uint64[0] } - Remove MSR intercept entirely from MSHV - Extract shared hw_interrupts module (LAPIC helpers, IO port handling, EOI bridging) to reduce duplication between MSHV and WHP - Replace lapic_timer_active with timer_thread.is_some() - Error on missing LAPIC emulation in WHP instead of fallback path - Remove lapic_emulation field from WhpVm - Remove Nanvix mentions from comments - Add Intel SDM references to LAPIC register writes Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: reset timer_stop flag before spawning timer thread During evolve(), the guest init sequence halts via OutBAction::Halt, which sets timer_stop=true. When the guest later configures a timer via PvTimerConfig, the timer thread inherits the already-true stop flag and exits immediately without ever firing. Reset the flag to false right before spawning the timer thread in both KVM and MSHV backends. WHP was not affected because it creates a fresh AtomicBool each time. Signed-off-by: danbugs <danilochiarlone@gmail.com> * Address copilot review feedback - KVM: data[..4] → data.get(..4) to avoid panic on short IO OUT - KVM/MSHV: stop timer thread when period_us == 0 - WHP: check LAPIC state buffer >= 0x374 before init_lapic_registers - hw_interrupts: add bounds checks + panic messages to write/read_lapic_u32 - init.rs/dispatch.rs: use xor eax,eax; out dx,eax; cli; hlt halt sequence - simpleguest: guard IDT vector 0x20 against short IDT limit - simpleguest: early return on period_us <= 0 Signed-off-by: danbugs <danilochiarlone@gmail.com> * Fix formatting (rustfmt nightly) Signed-off-by: danbugs <danilochiarlone@gmail.com> * Fix clippy collapsible-if in KVM timer config Signed-off-by: Daniil Baturin <daniil.baturin@microsoft.com> Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: remove disallowed assert! macros from LAPIC helpers The hyperlight-host clippy.toml disallows assert!/assert_eq!/assert_ne! in non-test code. Revert to natural slice bounds checking which already panics on out-of-bounds access. Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: extract hw-interrupts and default vCPU run into separate methods Split the two cfg-gated code paths in run_vcpu into run_vcpu_hw_interrupts and run_vcpu_default helper methods on KvmVm, keeping run_vcpu as a thin dispatcher. This makes each path easier to read and reason about independently. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: preserve RAX across halt sequence in init and dispatch The host reads RAX after the init halt to obtain the dispatch_function address (stored by generic_init's return value). Similarly, the host reads RAX after dispatch to get the guest function return value. The previous 'xor eax, eax' before 'out dx, eax' zeroed RAX, causing the host to store NextAction::Call(0) and subsequent guest calls to jump to address 0 (triggering Double Fault on MSHV/WHP). Remove the xor; the port-108 halt signal only needs the port number, not a specific data value. Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: split OutBAction into OutBAction + VmAction, move hw_interrupts to x86_64/ - Split OutBAction enum: PvTimerConfig and Halt moved to new VmAction enum. VmAction ports are intercepted at the hypervisor level in run_vcpu and never reach the sandbox outb handler, so the split eliminates unreachable match arms. - Move hw_interrupts.rs to virtual_machine/x86_64/hw_interrupts.rs since it contains x86-64 specific helpers (LAPIC, PIC, PIT). - Remove halt() from hyperlight_guest::exit — all halt sites use inline assembly with options(noreturn) to avoid stack epilogue issues. - Extract handle_pv_timer_config() method in KVM backend. - Remove intermediate variable in WhpVm::new(). - Restore create_vm_with_args() comment in MSHV backend. - Add memory fence after IDT writes in simpleguest for CoW safety. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: address PR 1272 review feedback (round 2) - Add trace-level log for unexpected VcpuExit::Hlt in KVM hw-interrupts loop (jsturtevant thread 1) - Fix MSHV EINTR handling: always return Cancelled so InterruptHandle::kill() is honoured even when the timer thread is active (jsturtevant thread 3) - Add min/max bounds (100µs–10s) on guest-provided timer period across all backends to prevent runaway injection or excessive sleep (jsturtevant thread 4) - Stop timer thread in WHP Halt handler before returning, matching KVM/MSHV behaviour (jsturtevant thread 6) - Use MSHV_PT_BIT_LAPIC named constant instead of magic 1u64 for pt_flags (ludfjig nit) Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: extract TimerThread struct into shared hw_interrupts module Replace per-backend Arc<AtomicBool> + Option<JoinHandle> + manual Drop with a shared TimerThread struct in x86_64/hw_interrupts.rs. Each backend now passes a closure for the inject call (eventfd.write on KVM, request_virtual_interrupt on MSHV, WHvRequestInterrupt on WHP). This removes ~60 lines of duplicated timer management logic and ensures consistent start/stop/drop semantics across all backends. Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: deduplicate WhpVm::new(), use #[cfg] for test exclusion - WhpVm::new(): partition creation sequence now appears once with #[cfg(feature = "hw-interrupts")] around just the LAPIC capability check and LAPIC-specific setup, eliminating ~20 lines of duplication. - Replace #[cfg_attr(feature = "hw-interrupts", ignore)] with #[cfg(not(feature = "hw-interrupts"))] on tests that don't work with hw-interrupts, so they are excluded at compile time rather than at runtime. Signed-off-by: danbugs <danilochiarlone@gmail.com> * style: fix rustfmt in KVM trace macro Signed-off-by: danbugs <danilochiarlone@gmail.com> * style: fix rustfmt import ordering for TimerThread Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: revert test exclusion to runtime ignore for hw-interrupts compatibility Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: extract shared PvTimerConfig handler and fix timer reconfiguration Extract handle_pv_timer_config() into hw_interrupts.rs as a shared function used by KVM, MSHV, and WHP backends. This eliminates duplicated timer-config parsing/clamping/start logic. Fix MSHV timer reconfiguration: previously MSHV only started a timer if self.timer.is_none(), ignoring reconfiguration requests. Now all backends consistently stop any existing timer before starting a new one when period_us > 0. Fix WHP do_lapic_eoi to log errors from set_lapic_state instead of silently discarding them. Fix MSHV request_virtual_interrupt to log errors via tracing::warn instead of silently discarding them with let _. Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: extract hw-interrupts setup from constructors KVM: extract irqfd/eventfd setup into KvmVm::setup_irqfd(), called from new() via Self::setup_irqfd(&vm_fd). MSHV: extract LAPIC initialization into MshvVm::init_lapic(), called from new() via Self::init_lapic(&vcpu_fd). Move lapic_regs_as_u8 and lapic_regs_as_u8_mut helper functions closer to the hw-interrupts impl block for better locality. WHP: extract check_lapic_emulation_support() and enable_lapic_emulation() from inline blocks in new(). Move LAPIC_STATE_MAX_SIZE and init_lapic_bulk into the hw-interrupts impl block since they are only used with that feature. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix(kvm): return error on unexpected VcpuExit::Hlt in hw-interrupts loop With hw-interrupts enabled, VcpuExit::Hlt should never reach userspace because the in-kernel LAPIC handles HLT internally. Previously this was silently ignored with a trace log and continue. Now it returns RunVcpuError::UnexpectedExit to surface the problem. Add UnexpectedExit(String) variant to RunVcpuError for cases where the vCPU exits in a way that shouldn't happen under normal operation. Signed-off-by: danbugs <danilochiarlone@gmail.com> * refactor: use shared constant for halt port in guest assembly Replace hardcoded port number 108 in dispatch_function and pivot_stack inline assembly with a const operand referencing hyperlight_common::outb::VmAction::Halt. This ensures the guest assembly stays in sync with the host-side port definitions. Signed-off-by: danbugs <danilochiarlone@gmail.com> * style: rustfmt Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix(kvm): copy IO data before calling handle_pv_timer_config The data slice borrows from the KVM run buffer (self.vcpu_fd), so calling self.handle_pv_timer_config(data) would create a conflicting mutable borrow. Copy data to a local Vec before calling the method. Signed-off-by: danbugs <danilochiarlone@gmail.com> * style: fix rustfmt import grouping in error.rs Restore the combined `use {anyhow, serde_json};` import that was split during rebase, matching the format expected by nightly rustfmt. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix(whp): use WHvX64LocalApicEmulationModeXApic constant Replace hardcoded literal 1 with the named constant from the windows crate for LAPIC emulation mode. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix: resolve clippy expect_used and rustfmt rebase artifacts Replace .expect() with match + tracing::warn on eventfd clone failure in KVM handle_pv_timer_config to satisfy clippy::expect_used lint. Restore combined `use {anyhow, serde_json};` import in error.rs that was split during rebase. Signed-off-by: danbugs <danilochiarlone@gmail.com> * fix(kvm): remove UnexpectedExit, let catch-all handle unexpected HLT Remove the dedicated VcpuExit::Hlt match arm and UnexpectedExit error variant in the hw-interrupts run loop. Unexpected HLT now falls through to the Ok(other) catch-all, returning VmExit::Unknown which gets converted to the existing UnexpectedVmExit in hyperlight_vm. Signed-off-by: danbugs <danilochiarlone@gmail.com> --------- Signed-off-by: danbugs <danilochiarlone@gmail.com> Signed-off-by: Daniil Baturin <daniil.baturin@microsoft.com>
1 parent 137e964 commit e1adf51

File tree

17 files changed

+1600
-189
lines changed

17 files changed

+1600
-189
lines changed

.github/workflows/dep_build_test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ jobs:
105105
# with only one driver enabled (kvm/mshv3 features are unix-only, no-op on Windows)
106106
just test ${{ inputs.config }} ${{ inputs.hypervisor == 'mshv3' && 'mshv3' || 'kvm' }}
107107
108+
- name: Run Rust tests with hw-interrupts
109+
run: |
110+
# with hw-interrupts feature enabled (+ explicit driver on Linux)
111+
just test ${{ inputs.config }} ${{ runner.os == 'Linux' && (inputs.hypervisor == 'mshv3' && 'mshv3,hw-interrupts' || 'kvm,hw-interrupts') || 'hw-interrupts' }}
112+
108113
- name: Run Rust Gdb tests
109114
env:
110115
RUST_LOG: debug

Justfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ test-like-ci config=default-target hypervisor="kvm":
8787
@# with only one driver enabled + build-metadata
8888
just test {{config}} build-metadata,{{ if hypervisor == "mshv3" {"mshv3"} else {"kvm"} }}
8989

90+
@# with hw-interrupts enabled (+ explicit driver on Linux)
91+
{{ if os() == "linux" { if hypervisor == "mshv3" { "just test " + config + " mshv3,hw-interrupts" } else { "just test " + config + " kvm,hw-interrupts" } } else { "just test " + config + " hw-interrupts" } }}
92+
9093
@# make sure certain cargo features compile
9194
just check
9295

@@ -151,6 +154,9 @@ build-test-like-ci config=default-target hypervisor="kvm":
151154
@# Run Rust tests with single driver
152155
{{ if os() == "linux" { "just test " + config+ " " + if hypervisor == "mshv3" { "mshv3" } else { "kvm" } } else { "" } }}
153156

157+
@# Run Rust tests with hw-interrupts
158+
{{ if os() == "linux" { if hypervisor == "mshv3" { "just test " + config + " mshv3,hw-interrupts" } else { "just test " + config + " kvm,hw-interrupts" } } else { "just test " + config + " hw-interrupts" } }}
159+
154160
@# Run Rust Gdb tests
155161
just test-rust-gdb-debugging {{config}}
156162

@@ -286,6 +292,7 @@ check:
286292
{{ cargo-cmd }} check -p hyperlight-host --features trace_guest,mem_profile {{ target-triple-flag }}
287293
{{ cargo-cmd }} check -p hyperlight-host --features nanvix-unstable {{ target-triple-flag }}
288294
{{ cargo-cmd }} check -p hyperlight-host --features nanvix-unstable,executable_heap {{ target-triple-flag }}
295+
{{ cargo-cmd }} check -p hyperlight-host --features hw-interrupts {{ target-triple-flag }}
289296

290297
fmt-check: (ensure-nightly-fmt)
291298
cargo +nightly fmt --all -- --check

src/hyperlight_common/src/outb.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ impl TryFrom<u8> for Exception {
8686
}
8787

8888
/// Supported actions when issuing an OUTB actions by Hyperlight.
89+
/// These are handled by the sandbox-level outb dispatcher.
8990
/// - Log: for logging,
9091
/// - CallFunction: makes a call to a host function,
9192
/// - Abort: aborts the execution of the guest,
@@ -106,6 +107,22 @@ pub enum OutBAction {
106107
TraceMemoryFree = 106,
107108
}
108109

110+
/// IO-port actions intercepted at the hypervisor level (in `run_vcpu`)
111+
/// before they ever reach the sandbox outb handler. These are split
112+
/// from [`OutBAction`] so the outb handler does not need unreachable
113+
/// match arms for ports it can never see.
114+
pub enum VmAction {
115+
/// IO port for PV timer configuration. The guest writes a 32-bit
116+
/// LE value representing the desired timer period in microseconds.
117+
/// A value of 0 disables the timer.
118+
PvTimerConfig = 107,
119+
/// IO port the guest writes to signal "I'm done" to the host.
120+
/// This replaces the `hlt` instruction for halt signaling so that
121+
/// KVM's in-kernel LAPIC (which absorbs HLT exits) does not interfere
122+
/// with hyperlight's halt-based guest-host protocol.
123+
Halt = 108,
124+
}
125+
109126
impl TryFrom<u16> for OutBAction {
110127
type Error = anyhow::Error;
111128
fn try_from(val: u16) -> anyhow::Result<Self> {
@@ -124,3 +141,14 @@ impl TryFrom<u16> for OutBAction {
124141
}
125142
}
126143
}
144+
145+
impl TryFrom<u16> for VmAction {
146+
type Error = anyhow::Error;
147+
fn try_from(val: u16) -> anyhow::Result<Self> {
148+
match val {
149+
107 => Ok(VmAction::PvTimerConfig),
150+
108 => Ok(VmAction::Halt),
151+
_ => Err(anyhow::anyhow!("Invalid VmAction value: {}", val)),
152+
}
153+
}
154+
}

src/hyperlight_guest_bin/src/arch/amd64/dispatch.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ core::arch::global_asm!("
6868
mov cr4, rdi
6969
flush_done:
7070
call {internal_dispatch_function}\n
71+
mov dx, {halt_port}\n
72+
out dx, eax\n
73+
cli\n
7174
hlt\n
7275
.cfi_endproc
73-
", internal_dispatch_function = sym crate::guest_function::call::internal_dispatch_function);
76+
",
77+
internal_dispatch_function = sym crate::guest_function::call::internal_dispatch_function,
78+
halt_port = const hyperlight_common::outb::VmAction::Halt as u16,
79+
);

src/hyperlight_guest_bin/src/arch/amd64/init.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ core::arch::global_asm!("
173173
mov rsp, r8\n
174174
xor ebp, ebp\n
175175
call {generic_init}\n
176+
mov dx, {halt_port}\n
177+
out dx, eax\n
178+
cli\n
176179
hlt\n
177180
.cfi_endproc\n
178-
", generic_init = sym crate::generic_init);
181+
",
182+
generic_init = sym crate::generic_init,
183+
halt_port = const hyperlight_common::outb::VmAction::Halt as u16,
184+
);

src/hyperlight_host/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ trace_guest = ["dep:opentelemetry", "dep:tracing-opentelemetry", "dep:hyperlight
133133
mem_profile = [ "trace_guest", "dep:framehop", "dep:fallible-iterator", "hyperlight-common/mem_profile" ]
134134
kvm = ["dep:kvm-bindings", "dep:kvm-ioctls"]
135135
mshv3 = ["dep:mshv-bindings", "dep:mshv-ioctls"]
136+
hw-interrupts = []
136137
# This enables easy debug in the guest
137138
gdb = ["dep:gdbstub", "dep:gdbstub_arch"]
138139
fuzzing = ["hyperlight-common/fuzzing"]

src/hyperlight_host/src/hypervisor/hyperlight_vm/x86_64.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,7 @@ mod tests {
15501550
// Tests
15511551
// ==========================================================================
15521552

1553+
#[cfg_attr(feature = "hw-interrupts", ignore)]
15531554
#[test]
15541555
fn reset_vcpu_simple() {
15551556
// push rax; hlt - aligns stack to 16 bytes
@@ -1695,6 +1696,7 @@ mod tests {
16951696

16961697
use super::*;
16971698

1699+
#[cfg_attr(feature = "hw-interrupts", ignore)]
16981700
#[test]
16991701
fn reset_vcpu_regs() {
17001702
let mut a = CodeAssembler::new(64).unwrap();
@@ -1754,6 +1756,7 @@ mod tests {
17541756
assert_regs_reset(hyperlight_vm.vm.as_ref());
17551757
}
17561758

1759+
#[cfg_attr(feature = "hw-interrupts", ignore)]
17571760
#[test]
17581761
fn reset_vcpu_fpu() {
17591762
#[cfg(kvm)]
@@ -1885,6 +1888,7 @@ mod tests {
18851888
}
18861889
}
18871890

1891+
#[cfg_attr(feature = "hw-interrupts", ignore)]
18881892
#[test]
18891893
fn reset_vcpu_debug_regs() {
18901894
let mut a = CodeAssembler::new(64).unwrap();
@@ -1927,6 +1931,7 @@ mod tests {
19271931
assert_debug_regs_reset(hyperlight_vm.vm.as_ref());
19281932
}
19291933

1934+
#[cfg_attr(feature = "hw-interrupts", ignore)]
19301935
#[test]
19311936
fn reset_vcpu_sregs() {
19321937
// Build code that modifies special registers and halts
@@ -1980,6 +1985,7 @@ mod tests {
19801985

19811986
/// Verifies guest-visible FPU state (via FXSAVE) is properly reset.
19821987
/// Unlike tests using hypervisor API, this runs actual guest code with FXSAVE.
1988+
#[cfg_attr(feature = "hw-interrupts", ignore)]
19831989
#[test]
19841990
fn reset_vcpu_fpu_guest_visible_state() {
19851991
let mut ctx = hyperlight_vm_with_mem_mgr_fxsave();

src/hyperlight_host/src/hypervisor/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ pub(crate) mod tests {
469469
use crate::sandbox::{SandboxConfiguration, UninitializedSandbox};
470470
use crate::{Result, is_hypervisor_present, new_error};
471471

472+
#[cfg_attr(feature = "hw-interrupts", ignore)]
472473
#[test]
473474
fn test_initialise() -> Result<()> {
474475
if !is_hypervisor_present() {

0 commit comments

Comments
 (0)