Skip to content

refactor(axvm): handle vCPU exits in arch adapters#1528

Merged
ZR233 merged 2 commits into
rcore-os:devfrom
ZR233:codex/axvm-arch-local-exit-handling
Jul 7, 2026
Merged

refactor(axvm): handle vCPU exits in arch adapters#1528
ZR233 merged 2 commits into
rcore-os:devfrom
ZR233:codex/axvm-arch-local-exit-handling

Conversation

@ZR233

@ZR233 ZR233 commented Jul 7, 2026

Copy link
Copy Markdown
Member

问题

axvm 运行层原先统一消费 axvm_types::VmExit,导致 VM/vCPU 通用状态机、runtime 调度循环和各架构 exit 语义耦合在一起。AArch64 已经有自己的 ArmVmExit,但进入 AxVM 后仍需要转换成统一 VmExit;同时旧的通用层还会理解 Continue、host IRQ 等 exit 细节,边界仍然偏低。

改动

  • VmArchVcpuOps 增加关联类型 Exit,将 run() 改为返回架构本地 exit 类型。
  • 将通用 vCPU 运行边界上移到 ArchOps::run_vcpu() 默认骨架:统一处理 bind/unbind、current-vCPU scope、pending interrupt 注入、重复 re-enter、post-unbind deferred work。
  • VcpuRunAction 收敛为 runtime 调度语义:YieldWaitStop(StopReason);新增 BoundVcpuExit<D> 表达 bound exit handling 的 ContinueCompleteDefer
  • 将 runtime 层原先对 VmExit/HostInterrupt/Continue 的处理移入 arch cfg;runtime 只调用 CurrentArch::run_vcpu() 并消费调度动作。
  • AArch64 直接 match ArmVmExit,外部中断类工作通过 Aarch64DeferredRunWorkunbind() 后完成。
  • x86/RISC-V/LoongArch 暂继续用 legacy VmExit,但统一走 arch-local transitional handler,并用 LegacyDeferredRunWork 延后处理 host IRQ、timer、EOI、idle 等需要 host-side side effect 的事件。
  • 清理 vm.rs 中的 arch-specific 操作:AxVM::handle_mmio_write() 只做设备写和 fw_cfg DMA;LoongArch PCH-PIC assert/drain 逻辑移回 arch/loongarch64vm.rs 不再 import/use CurrentArchArchOpsVcpuRunAction
  • 增加 source contract regression test,固定 vm.rs/runtime/vcpus.rs 不再泄漏架构 exit 细节。
  • 保留 axvm_types::VmExit 作为兼容/过渡 normalized event,并在文档中说明不再是所有架构 raw exit 的唯一接口。

设计说明

通用层只保留 VM/vCPU 生命周期骨架和可复用的小粒度 helper,不解释 MPIDR、hart、APIC、IOCSR 等架构语义。架构模块先把本地 exit 转换成这些 helper 需要的规范化输入,再决定继续运行、yield、wait、停止 VM,或把需要 unbind 后执行的工作放进 deferred work。

这次为了降低风险,非 AArch64 后端没有同步拆分底层 raw exit enum,而是先把 legacy VmExit 的消费边界搬进各自 arch cfg 模块。

验证

  • cargo fmt --check
  • cargo test -p axvm --test arch_boundary_contract
  • cargo test -p axvm-types
  • cargo xtask clippy --package axvm
  • cargo xtask clippy --package arm_vcpu
  • cargo check -p axvm --target aarch64-unknown-none-softfloat
  • cargo check -p axvm --target x86_64-unknown-none
  • cargo check -p axvm --target riscv64gc-unknown-none-elf
  • cargo check -p axvm --target loongarch64-unknown-none-softfloat
  • cargo xtask axvisor test qemu --arch riscv64
  • cargo xtask axvisor test qemu --arch aarch64 --test-group normal --test-case smoke

@ZR233
ZR233 marked this pull request as ready for review July 7, 2026 07:10
@ZR233
ZR233 marked this pull request as draft July 7, 2026 07:40
@ZR233
ZR233 marked this pull request as ready for review July 7, 2026 07:48
@ZR233
ZR233 force-pushed the codex/axvm-arch-local-exit-handling branch from 0b9ab68 to 7d4575a Compare July 7, 2026 07:57

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

改动概述

本 PR 将 axvm 运行层的 vCPU exit 处理从通用层(vm.rs / vcpu_run())重构到各架构适配器内部,是一次结构清晰的关注点分离重构:

  • VmArchVcpuOps 新增关联类型 Exitrun() 返回架构本地 exit 类型而非统一的 VmExit
  • AxVM::run_vcpu() 简化为通用骨架:bind → inject pending IRQ → vcpu.run()CurrentArch::handle_vcpu_exit() → 按 VcpuRunAction 决定 continue/yield/wait/stop → unbind。
  • vcpu_run() 从原来 150+ 行的大 match 缩减为 5 个 action 的处理。
  • AArch64 直接 match ArmVmExit,消除中间的 arm_exit_to_ax 转换层。
  • x86/RISC-V/LoongArch 暂通过 handle_transitional_vm_exit 处理 legacy VmExit,为后续拆分预留空间。
  • 公共 MMIO/PIO/sysreg/hypercall/CPU up/IPI/NPT fallback 逻辑抽取为 arch/mod.rs 中可复用的 helper 函数。

设计评价

重构方向正确:通用层不再解释架构语义(MPIDR、hart、APIC、IOCSR),arch 模块自主决定如何消费本地 exit 并映射到通用 action。VcpuRunAction 五个变体(Continue、HostInterrupt、Yield、Wait、Stop)精简且语义清晰。

过渡方案合理:非 AArch64 后端先复用 legacy VmExit 通过 handle_transitional_vm_exit 处理,避免一次性拆分所有后端 raw exit enum 的风险。VmExit 保留为兼容类型并带文档标注。

验证结果

本地验证全部通过:

  • cargo fmt --check
  • cargo test -p axvm-types ✓ (2 tests passed)
  • cargo test -p axvm ✓ (90 tests passed)
  • cargo clippy -p axvm-types --all-features -- -D warnings
  • cargo clippy -p axvm -- -D warnings
  • cargo check -p axvm --target aarch64-unknown-none-softfloat ✓(仅一个 dead_code warning:HostInterrupt 变体在 AArch64 上未使用,属预期行为)
  • cargo check -p axvm --target x86_64-unknown-none
  • cargo check -p axvm --target riscv64gc-unknown-none-elf
  • cargo check -p axvm --target loongarch64-unknown-none-softfloat

CI 状态

PR CI(run 28850794710)仍在运行中。当前 Detect changed pathsCancel stale CI runs 已通过;Check formatting / run_host 和 lint 相关 jobs 正在执行。由于本 PR 仅修改 virtualization/ 下的 axvm 相关 crate,各 Test jobs 按 path filter 正确标记为 skipped。本地 fmt/clippy/test/cross-check 均已覆盖 PR 声明的验证项。

重复/重叠分析

  • 搜索 open PR:仅本 PR #1528#1451(IRQ runtime 重构,完全不重叠)涉及 axvm 相关改动,无冲突或重复风险。
  • base 分支检查:origin/dev 上最近的 axvm 重构(#1477 generic NPT、#1471 axvisor arch 解耦、#1467 vcpu backend 解耦)均为本 PR 的前置工作,本 PR 在此基础之上继续推进架构解耦方向。

代码质量

  • 所有 VmArchVcpuOps 实现者(AArch64、x86_64 VMX/SVM/no-backend、riscv64、loongarch64)均已添加 type Exit 声明,无遗漏。
  • AArch64 ExternalInterrupt 处理从原来的 unbind 后执行改为在 handle_vcpu_exit 内内联执行(Yield 返回后再 unbind),由于 gic::handle_irq 不依赖 vCPU 绑定状态,行为等价。
  • unhandled exit 从旧代码的 warn! + continue 改为 ax_err!(Unsupported, ...) 返回错误,行为更严格但正确——未预期的 exit 不应被静默忽略。
  • handle_haltfn(&VmRuntimeHandle) -> bool 简化为 fn() -> VcpuRunAction,x86_64 从 true(continue)等价改为 VcpuRunAction::Yield,默认实现从 false(wait)改为 VcpuRunAction::Wait,语义完全一致。
  • width_mask / sign_extend_valuevm.rs 私有函数改为 pub(crate)arch/mod.rs 使用,访问控制合理。
  • 编译期测试覆盖:axvm-types 新增 MockExit 验证 VmArchVcpuOps::Exit 关联类型可用;AArch64 模块新增 assert_arm_exit_type::<AxvmArmVcpu>() 锁定 Exit = ArmVmExit

结论

无阻塞性问题。架构解耦方向清晰,过渡方案稳妥,所有本地验证通过。建议合入。

APPROVE

Powered by deepseek-v4-pro

@mai-team-app
mai-team-app Bot requested review from Ivans-11 and numpy1314 July 7, 2026 08:04

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查总结

改动概述

PR 分两步将 axvm 的 vCPU exit 处理完全收敛到各架构适配器内部:

Commit 1 (7d4575a): 为 VmArchVcpuOps 增加关联类型 Exit,将 run() 改为返回架构本地 exit;新增 handle_vcpu_exit_bound/finish_deferred_run_work 两个 ArchOps 方法;AArch64 直接 match ArmVmExit 消除 arm_exit_to_ax 中间层;x86/RISC-V/LoongArch 通过 handle_transitional_vm_exit 处理 legacy VmExit

Commit 2 (398319ba): 将 run_vcpu()vm.rs 上提到 ArchOps::run_vcpu() 默认实现骨架,统一处理 bind/unbind、pending interrupt 注入、handle_vcpu_exit_bound re-enter 循环、BoundVcpuExit::Deferfinish_deferred_run_work 的 unbind 后执行链;LoongArch PCH-PIC assert/drain 逻辑从 vm.rs 移入 arch/loongarch64;新增 arch_boundary_contract.rs 编译期回归测试。

设计评价

架构解耦方向完全正确:

  • 通用层 (vm.rs / runtime/vcpus.rs) 不再 import CurrentArchArchOpsVcpuRunAction 或任何架构 exit 细节,只消费 Yield/Wait/Stop 三种调度动作。
  • 架构模块通过 BoundVcpuExit::Complete/Defer/Continue 自主决定 exit 处理节奏,非 AArch64 后端保留 deprecated handle_transitional_vm_exit 过渡路径。
  • VcpuRunAction 从原先 5 个变体精简为 3 个(Yield/Wait/Stop),HostInterruptContinue 不再泄漏到 runtime 层。
  • BoundVcpuExit<D> 泛型 deferred work 设计干净,AArch64 用 Aarch64DeferredRunWork::ExternalInterrupt,legacy 后端用 LegacyDeferredRunWork,互不干扰。

验证结果

本地全部通过:

  • cargo fmt --check
  • cargo clippy -p axvm-types --all-features -- -D warnings
  • cargo clippy -p axvm -- -D warnings
  • cargo test -p axvm-types ✓ (2 tests)
  • cargo test -p axvm ✓ (90 unit tests + 2 arch_boundary_contract tests)
  • cargo check -p axvm --target aarch64-unknown-none-softfloat
  • cargo check -p axvm --target x86_64-unknown-none

CI (run 28855505135, head 398319ba):

  • Check formatting / run_host
  • Run spin-lint / run_container
  • Run sync-lint / run_container
  • Test axvisor riscv64 qemu / run_host
  • Test axvisor loongarch64 qemu / run_container
  • Test axvisor aarch64 qemu / run_container 按 path filter 被 skipped(此 PR 不改 aarch64 以外的 axvisor 测试路径,预期行为)
  • 所有 Starry/ArceOS/board test jobs 按 path filter 正确 skipped
  • 无任何 failed/cancelled job

重复/重叠分析

  • open PR 搜索:仅本 PR #1528 涉及 axvm vCPU exit 重构;#1322(axdevice 统一设备注册表)是完全不同的子系统,无重叠。
  • base 分支检查:origin/dev 上最近的 #1477(generic NPT)、#1471(axvisor arch 解耦)、#1467(vcpu backend 解耦)均为本 PR 的前置解耦工作,本 PR 在此基础上继续推进,方向一致。

前次审查

mai-team-app[bot] 已在 commit 7d4575a 提交 APPROVE。该审查覆盖了 commit 1 的核心设计(Exit 关联类型、arch-local handler、transitional handler),结论仍然有效。Commit 2 在此基础上进一步完成 run_vcpu() 上提和 boundary contract test,属于同一重构方向的收尾工作。

代码质量要点

  • arch_boundary_contract.rs 通过 include_str! + contains 断言确保 vm.rsruntime/vcpus.rs 不再包含架构 exit 细节,是低开销的编译期回归测试。
  • handle_vcpu_exit_bound 中 AArch64 ExternalInterrupt 通过 BoundVcpuExit::Defer + finish_deferred_run_work 在 unbind 后执行,与旧行为等价(gic::handle_irq 不依赖绑定状态)。
  • BoundVcpuExit::Continuerun_vcpu()unreachable!() 断言正确——loop 内不会将 Continue 返回给调用者。
  • LoongArch external_irq_vector / drain_pch_pic_eventsvm.rs 移入 arch/loongarch64,函数签名改为接收 &AxVMRef 并通过 vm.get_devices() 访问设备,解耦干净。
  • width_mask / sign_extend_valuevm.rs 私有函数变为 pub(crate),被 arch/mod.rshandle_mmio_read 复用,访问控制合理。

结论

无阻塞性问题。架构解耦方向清晰,过渡方案稳妥,本地和 CI 验证全部通过。arch_boundary_contract 测试保证了重构后的边界不会退化。

APPROVE

Powered by deepseek-v4-pro

@ZR233
ZR233 merged commit 0c510eb into rcore-os:dev Jul 7, 2026
56 checks passed
@ZR233
ZR233 deleted the codex/axvm-arch-local-exit-handling branch July 7, 2026 12:23
This was referenced Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant