diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99e79f69d3..7b10ef7b5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -414,20 +414,19 @@ jobs: with: repo: hermitcore/rusty-loader file: rusty-loader-x86_64-fc - - name: Download firecracker - uses: dsaltares/fetch-gh-release-asset@1.1.1 - with: - repo: firecracker-microvm/firecracker - version: tags/v1.4.1 - file: firecracker-v1.4.1-x86_64.tgz - target: 'firecracker-x86_64.tgz' - name: Install firecracker run: | - tar xzvf firecracker-x86_64.tgz --one-top-level=fc --strip-components 1 + # https://github.com/firecracker-microvm/firecracker/blob/7c5fc8707f26c4244d48a747631ab0fb31fc4c39/docs/getting-started.md#getting-a-firecracker-binary + ARCH="$(uname -m)" + release_url="https://github.com/firecracker-microvm/firecracker/releases" + latest=$(basename $(curl -fsSLI -o /dev/null -w %{url_effective} ${release_url}/latest)) + curl -L ${release_url}/download/${latest}/firecracker-${latest}-${ARCH}.tgz \ + | tar -xz + + # Rename the binary to "firecracker" + mv release-${latest}-$(uname -m)/firecracker-${latest}-${ARCH} firecracker + echo "$PWD" >> $GITHUB_PATH - name: Build minimal profile (debug) run: cargo build -Zbuild-std=std,panic_abort --target x86_64-unknown-hermit --no-default-features --package hello_world - name: Test debug profile (Firecracker) - run: | - ./fc/firecracker-v1.4.1-x86_64 --no-api --config-file ./kernel/fc-config.json & - sleep 1 - kill -KILL $(pidof firecracker-v1.4.1-x86_64) \ No newline at end of file + run: firecracker --no-api --config-file ./kernel/fc-config.json diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index dd76fc939f..d1de318a70 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -11,12 +11,16 @@ use core::sync::atomic::{AtomicU64, Ordering}; use core::{fmt, u32}; use hermit_entry::boot_info::PlatformInfo; -use hermit_sync::{without_interrupts, Lazy}; +use hermit_sync::Lazy; use qemu_exit::QEMUExit; use x86::bits64::segmentation; use x86::controlregs::*; use x86::cpuid::*; use x86::msr::*; +use x86_64::instructions::interrupts::int3; +use x86_64::instructions::tables::lidt; +use x86_64::structures::DescriptorTablePointer; +use x86_64::VirtAddr; #[cfg(feature = "acpi")] use crate::arch::x86_64::kernel::acpi; @@ -975,6 +979,23 @@ pub fn halt() { } } +/// Causes a triple fault. +/// +/// Triple faults cause CPU resets. +/// On KVM, this results in `KVM_EXIT_SHUTDOWN`. +/// This is the preferred way of shutting down the CPU on firecracker. +/// +/// See [Triple Faulting the CPU](http://www.rcollins.org/Productivity/TripleFault.html). +fn triple_fault() -> ! { + let idt = DescriptorTablePointer { + limit: 0, + base: VirtAddr::zero(), + }; + unsafe { lidt(&idt) }; + int3(); + unreachable!() +} + /// Shutdown the system pub fn shutdown() -> ! { info!("Shutting down system"); @@ -994,14 +1015,13 @@ pub fn shutdown() -> ! { Ok(_never) => unreachable!(), Err(()) => { match boot_info().platform_info { - PlatformInfo::LinuxBootParams { .. } => without_interrupts(|| loop { - halt(); - }), - _ => { + PlatformInfo::LinuxBootParams { .. } => triple_fault(), + PlatformInfo::Multiboot { .. } => { // Try QEMU's debug exit let exit_handler = qemu_exit::X86::new(0xf4, 3); exit_handler.exit_success() } + PlatformInfo::Uhyve { .. } => todo!(), } } }