Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ jobs:
- name: Test axvisor self-hosted x86_64
use_container: false
runs_on: '["self-hosted","linux","intel","kvm"]'
command: cargo xtask axvisor test qemu --arch x86_64
command: cargo xtask axvisor test qemu --arch x86_64 --test-case smoke-vmx
cache_key: ""
container_image: ""
limit_to_owner: rcore-os
Expand Down Expand Up @@ -597,10 +597,18 @@ jobs:
exit 0
fi

rustup component add llvm-tools
sudo apt-get update
sudo apt-get install -y libudev-dev pkg-config qemu-system-x86
sudo usermod -aG kvm $USER
sg kvm -c "cargo xtask axvisor test qemu --arch x86_64 --test-group svm --test-case smoke"
sg kvm -c '
set -eux
rust_host="$(rustc -vV | awk "/^host:/ { print \$2 }")"
llvm_tools_dir="$(rustc --print sysroot)/lib/rustlib/${rust_host}/bin"
export PATH="${llvm_tools_dir}:${PATH}"
command -v rust-objcopy
cargo xtask axvisor test qemu --arch x86_64 --test-case smoke-svm
'
cache_key: ""
container_image: ""
limit_to_owner: ""
Expand Down
31 changes: 21 additions & 10 deletions components/someboot/src/arch/x86_64/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,28 @@ impl page_table_generic::PageTableEntry for Entry {
if config.lower {
bits |= PTE_USER;
}
if config.dirty {
// Non-leaf page table pointers must not inherit leaf mapping flags
// from the template used by the generic mapper.
let is_leaf = !config.is_dir || config.huge;
if is_leaf && config.dirty {
bits |= PTE_DIRTY;
}
if config.global {
if is_leaf && config.global {
bits |= PTE_GLOBAL;
}
if config.is_dir && config.huge {
bits |= PTE_HUGE;
}
match config.mem_attr {
MemAttributes::Device | MemAttributes::Uncached => {
bits |= PTE_CACHE_DISABLE | PTE_WRITE_THROUGH;
if is_leaf {
match config.mem_attr {
MemAttributes::Device | MemAttributes::Uncached => {
bits |= PTE_CACHE_DISABLE | PTE_WRITE_THROUGH;
}
_ => {}
}
_ => {}
}
// For x86_64, NX on non-leaf entries blocks execution for the whole
// covered range. Only apply NX on leaf mappings (PTE or huge page).
let is_leaf = !config.is_dir || config.huge;
if is_leaf && !config.executable {
bits |= PTE_NO_EXECUTE;
}
Expand Down Expand Up @@ -314,21 +318,28 @@ fn setup_page_table() -> anyhow::Result<()> {

let root = table.root_paddr();
crate::mem::mmu::set_boot_table(table);
// The boot page tables contain NX leaf mappings. Enable NXE before
// loading them, otherwise x86_64 treats the NX bit as reserved.
enable_no_execute();
super::trap::set_cr3(root);
enable_page_features();
Ok(())
}

fn enable_no_execute() {
unsafe {
let efer = rdmsr(IA32_EFER) | IA32_EFER_NXE;
wrmsr(IA32_EFER, efer);
}
}

fn enable_page_features() {
unsafe {
let cr0 = controlregs::cr0() | Cr0::CR0_WRITE_PROTECT;
controlregs::cr0_write(cr0);

let cr4 = controlregs::cr4() | Cr4::CR4_ENABLE_GLOBAL_PAGES;
controlregs::cr4_write(cr4);

let efer = rdmsr(IA32_EFER) | IA32_EFER_NXE;
wrmsr(IA32_EFER, efer);
}
}

Expand Down
2 changes: 1 addition & 1 deletion os/axvisor/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn fallback_platform_for_arch(arch: &str) -> &'static str {
match arch {
"aarch64" => "aarch64-generic",
"loongarch64" => "loongarch64-qemu-virt",
"x86_64" => "x86-qemu-q35",
"x86_64" => "dummy",
"riscv64" => "riscv64-plat-dyn",
_ => "dummy",
}
Expand Down
1 change: 1 addition & 0 deletions os/axvisor/configs/board/qemu-x86_64-linux.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ features = [
"fs",
]
log = "Info"
plat_dyn = true
target = "x86_64-unknown-none"
vm_configs = []
3 changes: 1 addition & 2 deletions os/axvisor/configs/board/qemu-x86_64.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
env = { AX_IP = "10.0.2.15", AX_GW = "10.0.2.2" }
features = [
"ax-hal/x86-qemu-q35",
"ax-driver/virtio-blk",
"ax-driver/plat-static",
"ept-level-4",
"fs",
]
log = "Info"
plat_dyn = true
target = "x86_64-unknown-none"
vm_configs = []
4 changes: 1 addition & 3 deletions os/axvisor/configs/qemu/qemu-x86_64-linux.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ args = [
"-display",
"none",
"-serial",
"stdio",
"-monitor",
"none",
"mon:stdio",
"-cpu",
"host",
"-machine",
Expand Down
4 changes: 4 additions & 0 deletions os/axvisor/configs/vms/qemu/x86_64/linux-svm-smp1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ kernel_load_addr = 0x20_0000
enable_bios = false
# SVM phase-1 smoke keeps a dedicated command line so later stages can
# adjust SVM bring-up independently from the VMX baseline.

cmdline = "console=ttyS0 root=/dev/vda rw rootwait devtmpfs.mount=1 init=/sbin/getty acpi=off pci=conf1 pci=nomsi nox2apic tsc=unstable initcall_blacklist=ahci_pci_driver_init,i8042_init -- -n -l /bin/sh -L 115200 ttyS0 dumb"

## The path of the disk image.
Expand Down Expand Up @@ -75,6 +76,9 @@ passthrough_addresses = [
[0xfe00_0000, 0x00c0_0000],
# Linux probes a q35/ICH system MMIO page at 0xfed8_03c0 after the PIT/HLT path is fixed.
[0xfed8_0000, 0x1000],
# QEMU q35 may assign the virtio PCI 64-bit MMIO BAR differently across hosts.
[0x70_0000_0000, 0x10_0000],
[0x3800_0000_0000, 0x10_0000],
]

# Devices that are not desired to be passed through to the guest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ kernel_path = "/guest/linux/linux-qemu"
kernel_load_addr = 0x20_0000
# Whether to enable BIOS boot flow.
enable_bios = false
# Linux direct boot needs an explicit cmdline; keep no_timer_check from the old
# default to avoid PIT/HPET calibration stalls when Linux marks the TSC unstable.
cmdline = "console=ttyS0 root=/dev/vda rw rootwait devtmpfs.mount=1 init=/sbin/getty acpi=off pci=conf1 pci=nomsi nox2apic tsc=unstable no_timer_check initcall_blacklist=ahci_pci_driver_init,i8042_init -- -n -l /bin/sh -L 115200 ttyS0 dumb"
Comment thread
ZR233 marked this conversation as resolved.

## The path of the disk image.
# disk_path = ""
Expand Down Expand Up @@ -70,6 +73,11 @@ passthrough_devices = [
passthrough_addresses = [
# QEMU q35 low MMIO window needed by PCI/virtio-blk probing.
[0xfe00_0000, 0x00c0_0000],
# Linux probes a q35/ICH system MMIO page after the PIT/HLT path is active.
[0xfed8_0000, 0x1000],
# QEMU q35 may assign the virtio PCI 64-bit MMIO BAR differently across hosts.
[0x70_0000_0000, 0x10_0000],
[0x3800_0000_0000, 0x10_0000],
]

# Devices that are not desired to be passed through to the guest
Expand Down
60 changes: 47 additions & 13 deletions os/axvisor/scripts/quick-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Launch Options (for run/start commands):
--axvisor Launch AxVisor shell smoke (default)
QEMU x86_64:
-n, --nimbos Launch single NimbOS guest (default)
-l, --linux Launch single Linux guest
--nimbos-uefi Launch NimbOS through an external UEFI firmware image
--arceos-uefi Launch a local ArceOS x86_64 UEFI guest image
Phytium Pi:
Expand Down Expand Up @@ -128,6 +129,7 @@ Examples:

# QEMU x86_64
$0 qemu-x86_64 start --nimbos # One-step: prepare + launch NimbOS
$0 qemu-x86_64 start --linux # One-step: prepare + launch Linux
$0 qemu-x86_64 start --nimbos-uefi # One-step: prepare + launch NimbOS through UEFI
$0 qemu-x86_64 start --arceos-uefi # One-step: launch local ArceOS x86_64 UEFI image
$0 qemu-x86_64 start # Same as above (default nimbos)
Expand Down Expand Up @@ -384,6 +386,31 @@ setup_qemu_x86_64_uefi() {
info "=== QEMU x86_64 UEFI Preparation Complete ==="
}

setup_qemu_x86_64_linux() {
info "=== QEMU x86_64 Linux Preparation ==="

run_cmd mkdir -p tmp/{configs,images}

info "Downloading Linux image..."
run_cmd cargo axvisor image pull qemu_x86_64_linux --output-dir tmp/images

info "Preparing dynamic board config file..."
run_cmd cp configs/board/qemu-x86_64-linux.toml tmp/configs/

info "Preparing Linux guest config file..."
run_cmd cp configs/vms/qemu/x86_64/linux-vmx-smp1.toml tmp/configs/linux-x86_64-qemu-smp1.toml
run_cmd sed -i 's|^kernel_path = .*|kernel_path = "../images/qemu_x86_64_linux/linux-qemu"|g' tmp/configs/linux-x86_64-qemu-smp1.toml

info "Preparing QEMU config file..."
run_cmd cp configs/qemu/qemu-x86_64-linux.toml tmp/configs/qemu-x86_64-linux-runtime.toml

local rootfs_path
rootfs_path="$(pwd)/tmp/images/qemu_x86_64_linux/rootfs.img"
run_cmd sed -i 's|file=${workspace}/tmp/axbuild/rootfs/rootfs-x86_64-alpine.img|file='"$rootfs_path"'|g' tmp/configs/qemu-x86_64-linux-runtime.toml

info "=== QEMU x86_64 Linux Preparation Complete ==="
}

setup_qemu_x86_64_arceos_uefi() {
info "=== QEMU x86_64 ArceOS UEFI Preparation ==="

Expand Down Expand Up @@ -467,6 +494,14 @@ run_qemu_x86_64_arceos_uefi() {
--vmconfigs "$(pwd)/tmp/configs/arceos-x86_64-qemu-uefi-smp1.toml"
}

run_qemu_x86_64_linux() {
info "=== Launching QEMU x86_64 Linux Guest ==="
run_axvisor_qemu \
--config "$(pwd)/tmp/configs/qemu-x86_64-linux.toml" \
--qemu-config "$(pwd)/tmp/configs/qemu-x86_64-linux-runtime.toml" \
--vmconfigs "$(pwd)/tmp/configs/linux-x86_64-qemu-smp1.toml"
}

# ============================================================================
# Phytium Pi Board Setup
# ============================================================================
Expand Down Expand Up @@ -1040,6 +1075,9 @@ cmd_setup_qemu_x86_64() {
--arceos-uefi)
setup_qemu_x86_64_arceos_uefi
;;
-l|--linux)
setup_qemu_x86_64_linux
;;
-n|--nimbos|"")
setup_qemu_x86_64
;;
Expand All @@ -1062,25 +1100,15 @@ cmd_run_qemu_x86_64() {
--arceos-uefi)
run_qemu_x86_64_arceos_uefi
;;
-l|--linux)
run_qemu_x86_64_linux
;;
-a|--arceos)
error "QEMU x86_64 ArceOS requires a UEFI guest image; use --arceos-uefi"
echo ""
echo "Set AXVISOR_X86_64_ARCEOS_UEFI_KERNEL=/path/to/arceos-x86_64-uefi.bin first."
exit 1
;;
-l|--linux)
error "Unsupported combination: QEMU x86_64 does not support Linux"
echo ""
echo "QEMU x86_64 platform only supports the following guest system:"
echo " - NimbOS (use --nimbos)"
echo ""
echo "To run Linux, please use one of the following platforms:"
echo " $0 qemu-aarch64 start --linux"
echo " $0 phytiumpi setup && $0 phytiumpi run --linux"
echo " $0 roc-rk3568-pc setup && $0 roc-rk3568-pc run --linux"
echo " $0 rdk-s100 setup && $0 rdk-s100 run --linux"
exit 1
;;
-m|--multi)
error "Unsupported combination: QEMU x86_64 does not support multi-guest mode"
echo ""
Expand All @@ -1099,6 +1127,7 @@ cmd_run_qemu_x86_64() {
echo ""
echo "QEMU x86_64 platform supports the following options:"
echo " -n, --nimbos Launch NimbOS guest"
echo " -l, --linux Launch Linux guest"
echo " --nimbos-uefi Launch NimbOS guest through UEFI firmware"
echo " --arceos-uefi Launch a local ArceOS x86_64 UEFI guest"
exit 1
Expand All @@ -1119,6 +1148,9 @@ cmd_start_qemu_x86_64() {
--arceos-uefi)
# Valid parameters, continue
;;
-l|--linux)
# Valid parameters, continue
;;
*)
# Invalid parameters, report error without executing setup
cmd_run_qemu_x86_64 "$mode"
Expand All @@ -1129,6 +1161,8 @@ cmd_start_qemu_x86_64() {
setup_qemu_x86_64_uefi
elif [[ "$mode" == "--arceos-uefi" ]]; then
setup_qemu_x86_64_arceos_uefi
elif [[ "$mode" == "-l" || "$mode" == "--linux" ]]; then
setup_qemu_x86_64_linux
else
setup_qemu_x86_64
fi
Expand Down
Loading