Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

周报(2026-03-09 至 2026-03-15)

开发分支


总结

本周核心进展:在上周 Stage-2 / BrkInject 双路径和 deferred attach 机制基本落地的基础上,完成了 guest kretprobe 返回探针机制的实现——包括 per-vCPU return stack、动态 BRK 注入/回收的引用计数管理、以及 handler 侧的 entry/return 分流处理;同时完成了上周遗留的 deferred attach 收口提交和 VMM 依赖解耦。


一、已完成工作

1. deferred attach 收口

  • axvisor 侧d379ab7):shell 的 trace kprobe 命令支持 pending attach 提示,当 TTBR1_EL1 尚未就绪时显式输出 "registered pending enable" 而非报错退出。
  • VMM 依赖解耦ac1068a):将 VM-exit 通知收回到 kernel/src/vmm/mod.rs,去掉对 axvm 新接口的直接依赖,使 guest-kprobe 功能可在不修改 axvm crate 的前提下工作。

2. guest kretprobe 返回探针实现(axebpf)

本周最主要的新功能是 guest kretprobe(a77d6ec),变更量为 +1126/-145 行,涉及 10 个文件。核心设计包括:

2.1 per-vCPU return stack(return_stack.rs,新增文件)

  • 每个 vCPU 维护一个 LIFO 栈(最大深度 16),记录待返回的 probe 信息
  • 支持 pushpop_matching(按 vm_id + return_gva 匹配弹出)、retain(批量清理)
  • 提供 clear_for_vmclear_for_vm_probe 用于 VM 销毁或 probe detach 时的资源回收

2.2 动态 return BRK 引用计数(manager.rs

  • 新增 RETURN_BRK_REFCOUNT 全局注册表,管理 return 地址处的动态 BRK 注入
  • acquire_return_brk:首次调用时注入 BRK 并保存原指令,后续调用仅增加引用计数
  • release_return_brk:引用计数归零时恢复原指令
  • 解决了多个 entry probe 共享同一 return 地址时的 BRK 生命周期问题

2.3 handler 侧 entry/return 分流(handler.rs

  • handle_guest_brk 增加 is_ret 分支:
    • entry hit:直接执行 eBPF 程序(与此前行为一致)
    • return hit(is_ret=true):从 x30 读取返回地址 → 翻译为 HVA → 调用 acquire_return_brk 注入 BRK → 压入 return stack
  • 新增 ReturnProbeHitSingleStep 返回值,指示 caller 需进入 single-step 流程
  • 寄存器接口从 [u64; 8] 扩展为 [u64; 31],覆盖 AArch64 全部通用寄存器

3. trace stream 修复

修复了 trace stream -n <count> 模式下的一个交互问题:当指定了事件数量上限时,不再轮询键盘输入,避免在非交互场景下误触退出。

4. VMM 配置 cmdline 透传

kernel/src/vmm/config.rs 中将 guest 的 cmdline 配置项透传到 AxVMConfig,为后续 guest 启动参数定制提供基础。


二、遇到的问题与解决方案

2.1 多个 entry probe 共享 return 地址

问题:当多个不同入口函数恰好返回到同一地址时,简单的 "注入 BRK / 恢复原指令" 会导致提前恢复,遗漏后续 return hit。 解决方案:引入引用计数(ReturnBrkState.refcount),仅在最后一个引用释放时才恢复原指令。

2.2 寄存器宽度不足

问题:kretprobe 需要读取 x30(LR 寄存器)获取返回地址,但此前 handler 只接收 x0-x7(8 个寄存器)。 解决方案:将接口统一扩展为 [u64; 31],覆盖 AArch64 全部通用寄存器,同时在 build_guest_ctx 中仍只取 x0-x7 作为 eBPF 上下文参数,保持兼容。

2.3 热点地址不是合法 kretprobe 入口

问题:最早用 keepalive_hotspot 做验证时,能反复触发 entry hit,但始终看不到 return hit,return stack 最终被顶满。 根因keepalive_hotspot 是函数内部热点指令,不是函数入口;此时 x30 只是内部 bl 的返回地址,不是真正的函数返回点。 解决方案:改用真实函数入口做验证,并构建专用 keepalive guest,避免把验证点错误与实现问题混淆。

2.4 return stack 溢出风险

问题:递归或高频函数可能导致 return stack 无限增长。 解决方案:设置固定上限 MAX_RETURN_DEPTH = 16,超出时 push 返回错误并自动释放已 acquire 的 return BRK,不会泄漏。


三、提交摘要

axvisor(已提交)

提交 说明
d379ab7 shell 侧支持 deferred attach pending 提示
ac1068a 将 VM-exit 通知收回 root,去掉对 axvm 新接口的依赖

axebpf(已提交)

提交 说明
54740f1 deferred attach:允许先注册、首次条件满足后 enable
a77d6ec guest kretprobe return handling:return stack + 引用计数 + handler 分流

工作区(未提交)

文件 说明
kernel/src/shell/commands/trace.rs 修复 trace stream -n 模式下误触退出
kernel/src/vmm/config.rs 透传 guest cmdline 到 AxVMConfig
.cargo/config.toml 启用 git-fetch-with-cli 解决网络拉取问题

四、工作量统计

仓库 提交数 新增 删除
axvisor 2 +46 -26
axebpf 2 +1680 -183

五、下两周计划(03-16 至 03-29)

第一周(03-16 至 03-22):StarryOS / Linux guest 全功能验证

优先级 任务 验收标准
P0 StarryOS guest 上跑通 hprobe 全流程 tracepoint、hprobe attach/detach/stream 均可稳定工作
P0 StarryOS / Linux guest 上跑通 guest-kprobe(BrkInject + Stage-2) attach → hit → detach 可复现,日志可观测
P0 StarryOS / Linux guest 上跑通 kretprobe entry hit → return hit → detach 全流程通过
P1 提交本周工作区变更并清理 trace stream 修复和 cmdline 透传正式提交
P1 固化回归脚本 一键复现各路径 attach → hit → detach,适配 StarryOS / Linux 两种 guest

第二周(03-23 至 03-29):uprobe 设计与原型

优先级 任务 验收标准
P0 uprobe 方案设计文档 输出设计文档,覆盖 guest 用户态地址翻译、ELF 符号解析、BRK 注入策略、与 kprobe 的复用/差异分析
P0 uprobe 核心数据结构与 manager 原型 axebpf 中新增 probe/uprobe 模块骨架,定义 attach/detach 接口
P1 评估 uprobe 地址翻译路径 明确 guest 用户态 VA → PA 翻译需要哪些新 hook(TTBR0_EL1、用户页表遍历)
P1 评估 vCPU 迁移对 return stack 的影响 明确 kretprobe 是否需要改为 per-vcpu 索引

七、个人复盘

这周的重心从"让基础路径跑通"转到"在已验证的基础设施上扩展能力"。kretprobe 是 guest-kprobe 功能链中第一个需要在 handler 中动态修改 guest 内存的特性(return 地址处的 BRK 注入),和 entry probe 的静态 BRK 注入不同,它的生命周期完全由运行时事件驱动,引入了引用计数和 per-CPU 栈两个新的状态管理维度。

好的一面是:上周建立的 deferred attach 机制和 single-step 基础设施直接被 kretprobe 复用了,没有出现"为新功能重新搭基础"的情况。这说明之前的分层设计(manager 管注册/启用、handler 管命中/分发、single_step 管恢复)是合理的。

需要注意的风险是:return stack 按物理 CPU 索引,如果 vCPU 在两次 VM-exit 之间被调度到不同物理核,return hit 会找不到对应记录。这个问题在单核 guest 上不会暴露,需要在多核验证阶段重点关注。