Skip to content

feat(ebpf): add RISC-V 64 eBPF JIT backend framework#1142

Closed
CN-TangLin wants to merge 5 commits into
rcore-os:devfrom
CN-TangLin:feat/ebpf-jit-1-riscv64
Closed

feat(ebpf): add RISC-V 64 eBPF JIT backend framework#1142
CN-TangLin wants to merge 5 commits into
rcore-os:devfrom
CN-TangLin:feat/ebpf-jit-1-riscv64

Conversation

@CN-TangLin

@CN-TangLin CN-TangLin commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

问题

为 StarryOS 内核添加 eBPF JIT 编译框架和 RISC-V 64 后端,后续 PR #1140(x86_64)和 #1141(AArch64)将基于此框架扩展。

变更

  • bpf_insn.rs:定义 BpfInsn 结构体和 BPF 常量
  • jit_riscv64.rs:RISC-V 64 JIT 后端(1309 行),完整覆盖 ALU64/ALU32/JMP/MEM/CALL/BPF_END 指令
  • jit_x86_64.rsjit_aarch64.rs:空 stub
  • mod.rsJitBuffer(两遍计数缓冲区)、JitBackend trait、JitCompilertry_jit_compile 入口
  • ebpf/mod.rs:模块接入
  • 新代码标记 #[allow(dead_code)],后续 PR 接入执行路径

Review 后修复

  • 12 处 !buf.counting() counting guards:防止 sizing pass 中 buf.entry() 导致空指针解引用
  • unsafe impl Send/Sync 添加 SAFETY 注释
  • #[cfg(any(target_arch = "aarch64", target_arch = "riscv64", target_arch = "x86_64"))] 门控 + 不支持架构的 fallback,修复 loongarch64 构建失败
  • 测试代码中 insn.dst_reg = / insn.src_reg = 修复为 insn.dst_src_reg =BpfInsn 不包含独立 dst/src 字段)
  • emit_load_imm32 移除冗余 (val as i32) 转换(val 已是 i32)

Logic

两遍编译:第一遍 sizing pass 使用 JitBuffer::new_sizing() 仅计算字节数(调用实际 emit_* 函数通过 counting() 守卫跳过写操作),第二遍分配实际缓冲区并发射机器码。从根源消除独立 insn_size 估算函数的误差问题。

RV64 寄存器映射:BPF R0-R5 → a0-a5(caller-saved)、R6-R9 → s1-s4(callee-saved)、R10 → s5 栈帧指针。Prologue/Epilogue 正确保存/恢复 ra 和 s1-s5。除零保护:DIV 返回 0,MOD 保持 dst 不变,符合 BPF 语义。BPF_END 字节序转换:BE 用 rev8+shift,LE 为 no-op。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review

变更内容

本 PR 为 StarryOS 内核添加 eBPF JIT 编译框架,包括 JitBuffer(字节码发射缓冲区)、JitBackend trait(跨架构接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现。同时提供 x86_64 和 AArch64 的空 stub,确保跨架构编译通过。所有新代码标记 #[allow(dead_code)],等后续 PR(#1140 x86_64 JIT、#1141 AArch64 JIT + 接入执行路径)完成接入。

实现逻辑

  • 框架设计合理:两遍编译(sizing → emit)是 JIT 的标准做法,JitBackend trait 抽象清晰。
  • RISC-V 64 后端的指令编码函数(rv_r/i/s/b/u 等)遵循标准 RISC-V ISA 格式,寄存器映射正确(BPF R0-R9 → a0-a5/s1-s5,R10 → frame pointer s5)。
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器(ra/s1-s5),栈帧 560 字节(512 BPF 栈 + 48 callee-saved),16 字节对齐。
  • Division/modulo by zero 使用条件分支跳过除法,逻辑正确。
  • JitBuffer 使用 4096 字节页对齐分配,符合 JIT 缓冲区的 NX 位要求。

本地验证结果

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package starry-kernel:✅ 13 项 feature 全部通过

CI 状态

  • CI workflow 总体结论为 failure,原因是 "Test starry loongarch64 qemu / run_container" 步骤失败。
  • 该失败 与本 PR 无关:本 PR 仅添加死代码模块(#[allow(dead_code)]),不改变任何运行时行为。Formatting、sync-lint 检查均通过。
  • 其余测试(starry x86_64/aarch64/riscv64 qemu、arceos tests、axvisor tests、clippy)均为 skipped 或 cancelled,属于 CI 路径过滤/矩阵互斥的正常行为。

重复/重叠分析

  • PR #1139(已关闭):同一分支的早期版本,被本 PR 替代。
  • PR #1140(开放):x86_64 JIT 后端,依赖本 PR 合入。
  • PR #1141(开放):AArch64 JIT + 接入执行路径,依赖 #1140
  • 三者形成有序链,均为同一作者 @CN-TangLin,无重复实现。
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 在此基础上新增 JIT 编译层,不冲突。

遗留问题(非阻塞)

  1. BPF_END(字节序转换)未实现:仅打印 warn! 日志。建议在后续 PR 中补全,或在 PR body 中明确列出已知缺失。
  2. stub 后端 insn_size 返回 0:当前不影响(死代码),但接入时需要确保所有后端实现正确的 insn_size,否则 JitBuffer::new(0) 会返回错误。
  3. 建议添加单元测试:对于 RV64 指令编码函数(rv_r/i/s/b/u)和 emit_load_imm64 等纯函数,可以添加 host 端单元测试验证编码正确性,无需 QEMU 环境。

结论

代码质量良好,框架设计合理,作为系列 PR 的基础可以合并。无阻塞性问题。

Powered by mimo-v2.5-pro

emit_slli(buf, rd, rd, 32);
let lower = val as u32;
let lower_lo12 = (lower << 20) >> 20;
let lower_hi20 = (lower.wrapping_sub(lower_lo12).wrapping_add(0x800)) >> 12;

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.

建议:emit_load_imm32 的参数 val 已经是 i32 类型,(val as i32) 强转是冗余的。可以直接写:

let needs_upper = val < -2048 || val >= 2048;

fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("JitBuffer")
.field("size", &self.size)
.field("pos", &self.pos)

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.

建议:JitBuffer 实现了 unsafe impl Sendunsafe impl Sync,对于 JIT 缓冲区这是合理的(JIT 代码通常在生成后只读)。但建议添加 SAFETY 注释说明为什么这两个 impl 是安全的,例如:

// SAFETY: JitBuffer is a single-owner allocation used for code generation.
// After finalize(), the buffer is read-only and can be safely shared.
unsafe impl Send for JitBuffer {}
unsafe impl Sync for JitBuffer {}

BPF_ADD => {
if is_64 {
emit_add(buf, dst, dst, src);
} else {

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.

注意:BPF_DIV 的除零处理使用硬编码偏移 beq_off = 12u32(跳过 3 条指令),而 BPF_MOD 使用动态计算 let beq_off = (end - skip) as u32。建议统一使用动态计算方式,提高可维护性,避免后续修改时出错。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review

变更内容

本 PR 为 StarryOS 内核添加 eBPF JIT 编译框架,包括 JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1259 行)。同时提供 x86_64 和 AArch64 的空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现逻辑

  • 两遍编译设计(sizing pass + emit pass)是 JIT 的标准做法,实现正确。JitBuffer::new_sizing() 计数模式避免了 sizing 阶段的内存分配。
  • RV64 指令编码函数(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式,寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)。
  • Prologue 正确保存/恢复 6 个 callee-saved 寄存器(ra/s1-s5),栈帧 560 字节(512 BPF 栈 + 48 callee-saved),16 字节对齐。
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确。
  • JitBuffer 页对齐分配(4096),Drop 实现正确释放。
  • emit_call 参数移位正确:BPF helper 参数从 a1-a5 移到 a0-a4 以匹配 RV64 调用约定。
  • 条件跳转采用「条件分支跳过 + 远跳转序列」模式,跳转目标通过两遍计算正确解析。
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建。

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/StarryOS/kernel/Cargo.toml --all-features -- -D warnings:✅ 通过(新 head a411e08fe
  • host cargo test --lib__start_scope_local 链接错误无法运行,这是已知的内核 crate host 测试限制,与本 PR 无关。

CI 状态

最新 CI 运行(run 27050056582)结果:success=6, failure=2, skipped=50, cancelled=40。

  • Check formatting / run_host ✅:格式检查通过
  • Run sync-lint / run_host ✅:同步检查通过
  • Test with std / run_host ❌:「Show Rust version」步骤失败,是自托管 runner 环境问题,与本 PR 无关(PR 仅添加死代码模块)
  • Test starry loongarch64 qemu / run_container ❌(run 27049642383):「Run command」步骤失败,是 loongarch64 已知测试问题,与本 PR 无关
  • 其余 skipped/cancelled 均为路径过滤/矩阵互斥的正常行为

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支
  • PR #1141(开放):AArch64 JIT + JIT 接入执行路径,基于 #1139+#1140
  • 三者形成有序链(#1142#1140#1141),均为同一作者 @CN-TangLin,无重复实现
    dev 分支已有 eBPF 运行时(#850#886),本 PR 在此基础上新增 JIT 编译层,不冲突

前一轮 Review 考虑

mai-team-app[bot] 已 APPROVED,留下了 3 条合理的非阻塞建议:

  1. emit_load_imm32 冗余 as i32 转换 → 代码质量建议,已确认
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 代码质量建议,已确认
  3. BPF_DIV 硬编码偏移 vs BPF_MOD 动态计算 → 可维护性建议,已确认

以上 3 条均为非阻塞改进,当前状态可以合并。见下方 inline 建议。

遗留问题(非阻塞)

  1. BPF_END 未实现:仅 warn! 日志。作为框架 PR 可接受,建议后续 PR 补全或在 PR body 中列出已知缺失。
  2. stub 后端 emit_prologue 返回 0:当前死代码不影响,但接入时需确保所有后端实现正确的 insn_size
  3. 建议添加 RV64 指令编码函数的 host 端单元测试rv_r/i/s/b/u 等纯函数可以无需 QEMU 验证。

Powered by mimo-v2.5-pro

if lower_lo12 != 0 {
emit_addiw(buf, RV_T1, RV_T1, lower_lo12 as i32);
}
emit_add(buf, rd, rd, RV_T1);

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.

建议:emit_load_imm32 的参数 val 已经是 i32 类型,(val as i32) 是冗余的。可以直接写:

let needs_upper = val < -2048 || val >= 2048;

(非阻塞,代码风格改进)

fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("JitBuffer")
.field("size", &self.size)
.field("pos", &self.pos)

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.

建议:JitBuffer 实现了 unsafe impl Sendunsafe impl Sync,对于 JIT 缓冲区这是合理的(JIT 代码在生成后只读)。但建议添加 SAFETY 注释说明为什么这两个 impl 是安全的,例如:

// SAFETY: JitBuffer is a single-owner allocation used for code generation.
// After finalize(), the buffer is read-only and can be safely shared.
unsafe impl Send for JitBuffer {}
unsafe impl Sync for JitBuffer {}

(非阻塞,代码质量改进)

emit_mulw(buf, dst, dst, src);
}
}
BPF_DIV => {

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.

建议:BPF_DIV 使用硬编码偏移 beq_off = 12u32(跳过 3 条指令 = 12 字节),而 BPF_MOD 使用动态计算 let beq_off = (end - skip) as u32。建议统一使用动态计算方式,提高可维护性,避免后续修改时出错。

(非阻塞,可维护性改进)

@CN-TangLin
CN-TangLin force-pushed the feat/ebpf-jit-1-riscv64 branch 2 times, most recently from 5f1409a to 05de732 Compare June 6, 2026 03:09

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第三轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1259 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

本地验证结果

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package starry-kernel:✅ 13 项 feature 检查全部通过(无 warning)

CI 状态分析

最新 CI 运行(run 27050928506):

  • Detect changed paths
  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败原因为 "Show Rust version" 步骤的自托管 runner 环境问题(rustup 命令异常),不是代码问题,实际 clippy 命令未执行
  • 其余测试 job(starry/arceos/axvisor 各架构)均为 cancelled(因上游 clippy 失败级联跳过)或 skipped(路径过滤)
  • CI 失败与本 PR 无关:本 PR 仅添加死代码模块,不改变运行时行为

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确,JitBuffer::new_sizing() 计数模式避免了 sizing 阶段的内存分配
  • RV64 指令编码rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式,寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器(ra/s1-s5),栈帧 560 字节(512 BPF 栈 + 48 callee-saved),16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法/取模,逻辑正确
  • emit_call 参数移位正确:BPF helper 参数从 a1-a5 移到 a0-a4 以匹配 RV64 调用约定
  • 条件跳转采用「条件分支跳过 + 远跳转序列」模式,跳转目标通过两遍计算正确解析
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建(host 端),以及 ALU zext/arsh 验证(riscv64 目标端)

与前两轮 review 的一致性

前两轮 mai-team-app[bot] 的 APPROVE 结论和 3 条 inline 建议仍然有效,本次确认:

  1. emit_load_imm32 冗余 as i32 转换 → 非阻塞代码风格
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 非阻塞文档改进
  3. BPF_DIV 硬编码偏移 vs BPF_MOD 动态计算 → 非阻塞可维护性建议

关联 PR

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复

结论

代码质量良好,框架设计合理,本地 clippy 13 项全部通过。CI 失败为环境问题,与本 PR 无关。作为系列 PR 的基础,可以合并。

Powered by mimo-v2.5-pro

}
let upper = (val >> 32) as u32;
let upper_lo12 = (upper << 20) >> 20;
let upper_hi20 = (upper.wrapping_sub(upper_lo12).wrapping_add(0x800)) >> 12;

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.

建议(非阻塞):参数 val 已是 i32(val as i32) 冗余。可简化为 let needs_upper = val < -2048 || val >= 2048;。前两轮 review 已指出,作者未修改。

};
if use_imm {
emit_load_imm64(buf, RV_T1, insn.imm as u64);
}

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.

建议(非阻塞):BPF_DIV 硬编码 beq_off = 12u32(假设跳过 3 条指令),而 BPF_MOD 使用动态计算 let beq_off = (end - skip) as u32。建议统一使用动态计算方式,避免后续修改时出错。前两轮 review 已指出,作者未修改。

@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.

eBPF JIT 框架与 RISC-V 64 后端 Review

总体评价

架构设计清晰,两遍编译(sizing pass + emit pass)方案合理。RISC-V 指令编码(B/J/I/S/U/R 型)正确,BPF→RV64 寄存器映射符合预期,除零保护、helper 调用参数移位、AUIPC+load+ADD+JALR 远跳模式均无误。

CI 状态

  • Check formatting / run_host: ✅
  • Run sync-lint / run_host: ✅
  • Run clippy / run_host: ❌ 失败在 Show Rust version 步骤(自托管 runner 基础设施问题,非代码问题)
  • 本地验证:cargo fmt --check ✅,cargo clippy --all-features ✅(0 warnings)
  • 其余测试 job 因 clippy 失败被级联取消

需要修改的问题

1. 🔴 riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中使用了 insn.dst_reg = 1;insn.src_reg = 2;,但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是方法而非字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

应改为:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

或者为 BpfInsn 添加 setter 方法。

2. 🟡 PR 描述与代码不一致

PR 描述说 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8 + 移位,LE 为 no-op)。建议更新 PR 描述。

非阻塞建议(已有 review 评论覆盖)

  • emit_load_imm32 冗余 (val as i32) 转换
  • JitBufferunsafe impl Send/Sync 建议添加 SAFETY 注释
  • BPF_DIV 使用硬编码偏移 12u32,建议改为动态计算(与 BPF_MOD 一致)
  • 以上 3 条已由前序 review 评论提出,均未被处理

其他观察

  • x86_64/aarch64 的 stub 实现为空,符合预期(后续 PR 补全)
  • #[allow(dead_code)] 标注合理,后续 PR 接入执行路径后可移除
  • tests_arch_independent 模块的即时加载测试覆盖全面(7 个边界场景),可在所有架构上运行

Powered by mimo-v2.5-pro

emit_load_imm32(buf, RV_T2, val as i32);
emit_sw(buf, RV_T2, RV_T1, 0);
}
BPF_DW => {

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.

🔴 编译错误(riscv64)BpfInsn 结构体的字段是 dst_src_reg: u8dst_reg()src_reg() 是方法而非字段。insn.dst_reg = 1; 在 riscv64 上会编译失败。

请改为:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

同样处理下方其他测试函数中的 insn.dst_reg / insn.src_reg 赋值。

emit_andi(buf, RV_T2, src, 31);
emit_sllw(buf, dst, dst, RV_T2);
}
}

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 描述不一致:PR 描述中说 "BPF_END(字节序转换)暂未实现",但此处代码已完整实现了 BE 16/32/64-bit 的字节序转换。建议更新 PR 描述的 "已知限制" 部分。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第五轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换实现正确(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package starry-kernel:✅ 13 项 feature 全部通过(0 warnings)

CI 状态

最新 CI 运行(run 27050928506):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(自托管 runner 基础设施问题,rustup 命令异常),实际 clippy 未执行
  • 其余测试 job 因 clippy 失败被级联取消
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

前序 Review 考虑

前四轮 mai-team-app[bot] 的 3 条非阻塞 inline 建议仍然有效:

  1. emit_load_imm32 冗余 (val as i32) 转换 → 代码风格改进
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 文档改进
  3. BPF_DIV 硬编码偏移 vs BPF_MOD 动态计算 → 可维护性改进

阻塞问题

🔴 riscv64 测试代码编译失败tests_arch_independent 模块(#[cfg(test)])中使用 insn.dst_reg = 1;insn.src_reg = 2;,但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非字段。在 riscv64 上编译会报 "no field dst_reg on type BpfInsn" 错误。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件,补充 JIT 测试覆盖
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误,需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 编译错误insn.dst_reg 不是 BpfInsn 的字段,dst_reg() 是 getter 方法。在此处编译会报 "no field dst_reg on type BpfInsn"。

修复建议:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

或者为 BpfInsn 添加 set_dst_reg() / set_src_reg() setter 方法。

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_MOV | BPF_X;
insn.dst_reg = 1;

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.

同上:insn.dst_reg 不是字段,应使用 insn.dst_src_reg。此处和第 1279 行存在相同的编译错误。

emit_slli(buf, rd, rd, 32);
let lower = val as u32;
let lower_lo12 = (lower << 20) >> 20;
let lower_hi20 = (lower.wrapping_sub(lower_lo12).wrapping_add(0x800)) >> 12;

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.

建议:emit_load_imm32 的参数 val 已经是 i32 类型,(val as i32) 强转是冗余的。可以直接写:

let needs_upper = val < -2048 || val >= 2048;

(非阻塞,代码风格改进)

fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("JitBuffer")
.field("size", &self.size)
.field("pos", &self.pos)

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.

建议:JitBufferunsafe impl Sendunsafe impl Sync 添加 SAFETY 注释:

// SAFETY: JitBuffer is a single-owner allocation used for code generation.
// After finalize(), the buffer is read-only and can be safely shared.
unsafe impl Send for JitBuffer {}
unsafe impl Sync for JitBuffer {}

(非阻塞,文档改进)

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第六轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(~1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换实现正确(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package starry-kernel:✅ 13 项 feature 全部通过(0 warnings)

CI 状态

最新 CI 运行(run 27050928506):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(自托管 runner 基础设施问题,rustup 命令异常),实际 clippy 未执行
  • 其余测试 job 因 clippy 失败被级联取消
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

需要修改的问题

🔴 阻塞:riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod teststest_alu_add32_zexttest_alu_mov32_zexttest_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1;insn.src_reg = 2;(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

应改为:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

🟡 PR 描述与代码不一致

PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8 + 移位,LE 为 no-op)。建议更新 PR 描述以反映实际实现。

非阻塞建议

  1. unsafe impl Send/Sync for JitBuffer 缺少 SAFETY 注释。建议添加 // SAFETY: ... 注释说明理由。
  2. BPF_DIV 硬编码偏移 12u32,建议改为动态计算(与 BPF_MOD 一致),提高可维护性。
  3. emit_load_imm32(val as i32) 冗余(参数已声明为 i32)。

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第七轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换实现正确(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:本地无法运行(依赖缺失),参考 CI 结果
  • CI formatting / sync-lint:✅ 通过
  • CI clippy:❌ 失败在 "Show Rust version" 步骤(自托管 runner 基础设施问题,rustup 异常),非代码问题

CI 状态

最新 CI 运行(run 27050928506):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(runner 环境问题),实际 clippy 未执行
  • 其余测试 job 因 clippy 失败被级联取消
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

阻塞问题

🔴 riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中的 test_alu_add32_zexttest_alu_mov32_zexttest_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1;insn.src_reg = 2;(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

PR 描述不一致

🟡 PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8 + 移位,LE 为 no-op)。建议更新 PR 描述以反映实际实现。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1139+#1140
  • PR #1163(开放):eBPF JIT 回归测试套件,补充 JIT 测试覆盖
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

前序 Review 考虑

前六轮 mai-team-app[bot] 的 3 条非阻塞 inline 建议仍然有效且未被处理:

  1. emit_load_imm32 冗余 (val as i32) 转换 → 代码风格改进
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 文档改进
  3. BPF_DIV 硬编码偏移 12u32 vs BPF_MOD 动态计算 → 可维护性改进

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 阻塞:此处在 riscv64 上编译失败

BpfInsn 结构体没有 dst_reg 字段,dst_reg() 是 getter 方法。应改为:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

同样的问题出现在第 1241、1268、1269、1279 行。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第八轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换实现正确(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package starry-kernel:✅ 13 项 feature 全部通过(0 warnings)
  • [patch.crates-io] 条目

CI 状态分析

最新 CI 运行(run 27050928506):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(自托管 runner 基础设施问题,rustup 命令异常),实际 clippy 未执行
  • 其余测试 job 因 clippy 失败被级联取消或为路径过滤/矩阵互斥的 skipped
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块,不改变运行时行为

阻塞问题

🔴 riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中的 test_alu_add32_zexttest_alu_mov32_zexttest_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1;insn.src_reg = 2;(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

PR 描述不一致

🟡 PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8+shift,LE 为 no-op)。建议更新 PR 描述以反映实际实现。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支,有序依赖
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1139+#1140
  • PR #1163(开放):eBPF JIT 回归测试套件,补充 JIT 测试覆盖
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

非阻塞建议(已有前序 review 评论覆盖)

  1. emit_load_imm32 冗余 (val as i32) 转换 → 代码风格改进
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 文档改进
  3. BPF_DIV 硬编码偏移 12u32 vs BPF_MOD 动态计算 → 可维护性改进

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 阻塞BpfInsn 结构体没有 dst_reg 字段。dst_reg()src_reg() 是 getter 方法,不能直接赋值。此处使用 insn.dst_reg = 1; 会在 riscv64 编译时报 no field dst_reg on type BpfInsn

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;
insn.src_reg = 2;

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.

🔴 同上:insn.src_reg = 2; 也应改为通过 dst_src_reg 字段设置。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第九轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换已正确实现(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/StarryOS/kernel/Cargo.toml --all-features -- -D warnings:✅ 通过(0 warnings)
  • [patch.crates-io] 条目

CI 状态

最新 CI 运行(run 27050928506):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(自托管 runner 基础设施问题,rustup 异常),实际 clippy 未执行
  • 其余测试 job 因 clippy 失败被级联取消
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

阻塞问题

🔴 riscv64 测试代码编译失败(第八轮提出,仍未修复)

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中的 test_alu_add32_zexttest_alu_mov32_zexttest_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1;insn.src_reg = 2;(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

PR 描述不一致

🟡 PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8+shift,LE 为 no-op)。建议更新 PR 描述以反映实际实现。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支,有序依赖
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1139+#1140
  • PR #1163(开放):eBPF JIT 回归测试套件,补充 JIT 测试覆盖
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

非阻塞建议(前序 review 评论已提出,均未被处理)

  1. emit_load_imm32 冗余 (val as i32) 转换 → 代码风格改进
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 文档改进
  3. BPF_DIV 硬编码偏移 12u32 vs BPF_MOD 动态计算 → 可维护性改进

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 阻塞(第八轮提出,仍未修复):BpfInsn 结构体没有 dst_reg 字段,只有 dst_src_reg: u8 字段和 dst_reg() getter 方法。此处 insn.dst_reg = 1; 无法编译。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。同样的问题也出现在第 1241、1268、1269、1279 行。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第十轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(~1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确,JitBuffer::new_sizing() 计数模式避免 sizing 阶段内存分配
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换已正确实现(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • rustfmt --check:✅ 通过
  • CI formatting / sync-lint:✅ 通过
  • CI clippy:❌ 失败在 "Show Rust version" 步骤(自托管 runner 基础设施问题,rustup 异常),非代码问题

CI 状态

最新 CI 运行(run 27050928506):

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 runner 环境问题,实际 clippy 未执行
  • 其余测试 job 均为 skipped(路径过滤/矩阵互斥)或 cancelled(因上游级联)
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

需要修改的问题

🔴 阻塞:riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中的 test_alu_add32_zexttest_alu_mov32_zexttest_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1;insn.src_reg = 2;(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

PR 描述不一致

🟡 PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8+shift,LE 为 no-op)。建议更新 PR 描述以反映实际实现。

非阻塞建议(已有前序 review 评论覆盖)

  1. emit_load_imm32 冗余 (val as i32) 转换 → 代码风格改进
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 文档改进
  3. BPF_DIV 硬编码偏移 12u32 vs BPF_MOD 动态计算 → 可维护性改进

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支,有序依赖
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件,补充 JIT 测试覆盖
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现

前序 Review 考虑

前九轮 mai-team-app[bot] 已多次指出同一阻塞问题(riscv64 测试编译错误),该问题在当前最新提交中仍未修复。3 条非阻塞 inline 建议(冗余类型转换、缺少 SAFETY 注释、硬编码偏移)同样未被处理。

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 阻塞:insn.dst_reg 不是 BpfInsn 的字段。BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法。这会在 riscv64 上编译失败(no field dst_reg on type BpfInsn)。

修复方式:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2


fn emit_load_imm32(buf: &mut JitBuffer, rd: u32, val: i32) {
let needs_upper = (val as i32) < -2048 || (val as i32) >= 2048;
if !needs_upper {

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.

🟡 非阻塞:emit_load_imm32 的参数 val 已经是 i32 类型,(val as i32) 冗余。可简化为 val < -2048 || val >= 2048

size: usize,
pos: usize,
/// When true, emit methods only count bytes without writing to memory.
counting: bool,

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.

🟡 非阻塞:建议添加 SAFETY 注释说明为什么 unsafe impl Send/Sync for JitBuffer 是安全的。例如:

// SAFETY: JitBuffer is a single-owner allocation used for code generation.
// After finalize(), the buffer is read-only and can be safely shared.
unsafe impl Send for JitBuffer {}
unsafe impl Sync for JitBuffer {}

BPF_ADD => {
if is_64 {
emit_add(buf, dst, dst, src);
} else {

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.

🟡 非阻塞:BPF_DIV 的除零处理使用硬编码偏移 beq_off = 12u32(跳过 3 条指令),而 BPF_MOD 使用动态计算 let beq_off = (end - skip) as u32。建议统一使用动态计算方式,提高可维护性。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第十轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换已正确实现(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/StarryOS/kernel/Cargo.toml --all-features -- -D warnings:✅ 通过(host x86_64 目标,0 warnings)

CI 状态分析

最新 CI 运行(run 27050928506):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(自托管 runner rustup 命令异常),实际 clippy 命令未执行,不是代码问题
  • 其余测试 job(starry/arceos/axvisor 各架构)均为 cancelled(因上游 clippy 失败级联)或 skipped(路径过滤)
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块,不改变运行时行为

🔴 阻塞问题:riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中三个测试函数存在编译错误:

行号 错误代码 应改为
1240 insn.dst_reg = 1; insn.dst_src_reg = 1;
1241 insn.src_reg = 2; insn.dst_src_reg |= 2 << 4;
1268 insn.dst_reg = 1; insn.dst_src_reg = 1;
1269 insn.src_reg = 2; insn.dst_src_reg |= 2 << 4;
1279 insn.dst_reg = 1; insn.dst_src_reg = 1;

BpfInsn 结构体(bpf_insn.rs)只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法(&self),不是可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

该问题已连续 5 轮 review(第 4-9 轮)被指出,但至今未修复。

🟡 PR 描述不一致

PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_aluBPF_END 分支已完整实现字节序转换(BE 16/32/64-bit 使用 rev8+shift,LE 为 no-op)。建议更新 PR 描述。

非阻塞建议

  1. unsafe impl Send/Sync for JitBuffer 缺少 SAFETY 注释
  2. BPF_DIV 硬编码偏移 12u32,建议改为动态计算(与 BPF_MOD 一致)
  3. emit_load_imm32(val as i32) 冗余(参数已声明为 i32

关联 PR

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

fn emit_auipc(buf: &mut JitBuffer, rd: u32, imm: u32) {
buf.emit_u32(rv_u(imm, rd, 0x17));
}

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.

BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法(fn dst_reg(&self) -> u8),不是可写字段。

建议改为:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

或者为 BpfInsn 添加 setter 方法 set_dst_reg/set_src_reg

}

fn emit_jal(buf: &mut JitBuffer, rd: u32, imm: i32) {
let imm = imm as u32;

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.

同上,dst_reg/src_reg 不是字段。此处 test_alu_add32_zext 也需要修复。

);
}

fn emit_ret(buf: &mut JitBuffer) {

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.

此处仅设置 dst_reg,未设置 src_reg(因为 ARSH imm 模式不需要 src_reg),但仍需改为 insn.dst_src_reg = 1;

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换已正确实现(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo xtask clippy --package starry-kernel:✅ 13 项 feature 全部通过(0 warnings)
  • [patch.crates-io] 条目

CI 状态分析

CI 存在 failure,但与本 PR 无关:

  • Check formatting / run_host ✅:格式检查通过
  • Run sync-lint / run_host ✅:同步检查通过
  • Run clippy / run_host ❌:失败在 "Show Rust version" 步骤(自托管 runner 环境问题,rustup 命令异常),实际 clippy 命令未执行,非代码问题
  • 其余测试 job 因 clippy 失败被级联取消或为路径过滤的 skipped
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

阻塞问题

🔴 riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] 模块中的 test_alu_add32_zexttest_alu_mov32_zexttest_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1;insn.src_reg = 2;,但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg()src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

PR 描述不一致

🟡 PR 描述声称 "BPF_END(字节序转换)暂未实现,仅打印 warn! 日志",但代码中 emit_alu 已完整实现了 BPF_END 的字节序转换(BE 16/32/64-bit 使用 rev8+shift,LE 为 no-op)。建议更新 PR 描述以反映实际实现。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

前序 Review 考虑

前序 mai-team-app[bot] 的 3 条非阻塞 inline 建议仍然有效:

  1. emit_load_imm32 冗余 (val as i32) 转换 → 代码风格改进
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 文档改进
  3. BPF_DIV 硬编码偏移 12u32 vs BPF_MOD 动态计算 → 可维护性改进

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 阻塞BpfInsn 结构体只有 dst_src_reg: u8 字段(参见 bpf_insn.rs:53),dst_reg()src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;
insn.src_reg = 2;

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.

同上:src_reg 也不是字段,需改为 dst_src_reg 赋值。

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_MOV | BPF_X;
insn.dst_reg = 1;

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.

同上:insn.dst_reg 不是字段,需使用 insn.dst_src_reg = 1 | (2 << 4);

let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_MOV | BPF_X;
insn.dst_reg = 1;
insn.src_reg = 2;

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.

同上:insn.src_reg 不是字段。

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ARSH;
insn.dst_reg = 1;

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.

同上:insn.dst_reg 不是字段。这个测试中 src_reg 未赋值(默认为 0),修复时用 insn.dst_src_reg = 1; 即可。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架(JitBuffer、JitBackend trait、JitCompiler 两遍编译器),以及完整的 RISC-V 64 后端实现(1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码函数遵循标准 RISC-V ISA 格式,寄存器映射正确
  • Prologue/Epilogue 正确保存/恢复 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • 除零保护逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换已正确实现(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/StarryOS/kernel/Cargo.toml --all-features -- -D warnings:✅ 通过(0 warnings)
  • 无 [patch.crates-io] 条目

CI 状态分析

最新 CI(run 27050928506):failure。

  • Check formatting ✅、Run sync-lint ✅
  • Run clippy ❌:失败在 Show Rust version 步骤(自托管 runner 基础设施问题,rustup 命令异常),实际 clippy 命令未执行
  • 其余测试 job 因 clippy 失败被级联取消或为路径过滤/矩阵互斥的 skipped
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块

阻塞问题

🔴 riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests(第 1059 行)中的 test_alu_add32_zext、test_alu_mov32_zext、test_arsh32_no_zext 使用了 insn.dst_reg = 1 和 insn.src_reg = 2(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg() 和 src_reg() 是 getter 方法。在 riscv64 上编译会报 no field dst_reg on type BpfInsn。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4); 或添加 setter 方法。

PR 描述不一致

🟡 PR 描述声称 BPF_END 暂未实现,但代码已完整实现。建议更新 PR 描述。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • 三者形成有序链(#1142#1140#1141),同一作者,无重复
  • dev 分支已有 eBPF 运行时,本 PR 新增 JIT 编译层,不冲突

非阻塞建议

  1. unsafe impl Send/Sync for JitBuffer 缺少 SAFETY 注释
  2. BPF_DIV 硬编码偏移 12u32,建议改为动态计算(与 BPF_MOD 一致)
  3. emit_load_imm32 中 (val as i32) 冗余

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;
insn.src_reg = 2;

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.

BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg() 和 src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

建议改为:

insn.dst_src_reg = 1 | (2 << 4); // dst_reg=1, src_reg=2

或为 BpfInsn 添加 setter 方法。

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第十轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1284 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

本地验证

  • cargo fmt --check -p starry-kernel: ✅ 通过
  • cargo clippy -p starry-kernel --all-features -- -D warnings: ✅ 通过(0 warnings)

CI 状态

CI run 27050928506 failure。Check formatting ✅, Run sync-lint ✅。Run clippy ❌ 失败在 Show Rust version 步骤(自托管 runner rustup 异常),非代码问题。其余测试 job 因 clippy 失败被级联取消。CI 失败与本 PR 无关。

🔴 阻塞问题:riscv64 测试代码编译失败

#[cfg(all(test, target_arch = "riscv64"))] mod tests 中的 test_alu_add32_zext、test_alu_mov32_zext、test_arsh32_no_zext 三个测试函数使用了 insn.dst_reg = 1 和 insn.src_reg = 2(第 1240/1241/1268/1269/1279 行),但 BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg() 和 src_reg() 是 getter 方法而非可写字段。在 riscv64 上编译会报 no field dst_reg on type BpfInsn 错误。

修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);(dst_reg=1, src_reg=2),或为 BpfInsn 添加 setter 方法。

🟡 PR 描述不一致

PR 描述声称 BPF_END 暂未实现,但代码中 emit_alu 已完整实现了 BPF_END 字节序转换。建议更新 PR 描述。

非阻塞建议(已有前序 review 评论覆盖)

  1. emit_load_imm32 冗余 (val as i32) 转换(第 359 行)
  2. unsafe impl Send/Sync for JitBuffer 缺少 SAFETY 注释(mod.rs 第 47-48 行)
  3. BPF_DIV 硬编码偏移 12u32 vs BPF_MOD 动态计算(第 440 行)

关联 PR

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。但 riscv64 测试代码存在编译错误需要修复。修复后可以合并。

Powered by mimo-v2.5-pro

}
let upper = (val >> 32) as u32;
let upper_lo12 = (upper << 20) >> 20;
let upper_hi20 = (upper.wrapping_sub(upper_lo12).wrapping_add(0x800)) >> 12;

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.

建议:emit_load_imm32 的参数 val 已经是 i32 类型,(val as i32) 是冗余的。可以直接写:
let needs_upper = val < -2048 || val >= 2048;

fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("JitBuffer")
.field("size", &self.size)
.field("pos", &self.pos)

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.

建议:JitBuffer 实现了 unsafe impl Send 和 unsafe impl Sync,对于 JIT 缓冲区这是合理的。但建议添加 SAFETY 注释说明为什么这两个 impl 是安全的。

BPF_ADD => {
if is_64 {
emit_add(buf, dst, dst, src);
} else {

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.

注意:BPF_DIV 的除零处理使用硬编码偏移 beq_off = 12u32(跳过 3 条指令),而 BPF_MOD 使用动态计算 let beq_off = (end - skip) as u32。建议统一使用动态计算方式,提高可维护性。

let mut buf = new_buf();
let mut insn = BpfInsn::default();
insn.code = BPF_ALU | BPF_ADD | BPF_X;
insn.dst_reg = 1;

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.

🔴 阻塞:BpfInsn 结构体只有 dst_src_reg: u8 字段,dst_reg() 和 src_reg() 是 getter 方法而非可写字段。此处 insn.dst_reg = 1 和 insn.src_reg = 2 在 riscv64 上编译会报 no field dst_reg 错误。修复方式:改为 insn.dst_src_reg = 1 | (2 << 4);

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

当前仍有一个合并阻塞项需要先处理:RISC-V 测试模块里仍在写 insn.dst_reg / insn.src_reg,但 BpfInsn 只有 dst_src_reg 字段,dst_reg() / src_reg() 是 getter 方法。前序 unresolved 线程已经准确指出第 1240/1241/1268/1269/1279 行的问题;这些线程我认为仍然有效,建议修复为直接设置 dst_src_reg 或补明确 setter 后再解除。

验证情况:本地 cargo fmt --check 通过,cargo xtask clippy --package starry-kernel 的 13 项检查全部通过;我额外尝试了 cargo check -p starry-kernel --target riscv64gc-unknown-none-elf --tests,但当前命令先被 ax-hal 平台 feature gate 拦住,不能作为该测试模块的完整编译证明。远端 CI 中 formatting/sync-lint 通过,clippy job 在 rustc --version 步骤出现 runner 侧 exit 139,后续测试级联取消,因此远端 CI 对本 PR 代码结果不完整。

另外,PR 描述里仍写 BPF_END 未实现,但当前代码已实现相关分支,请同步更新描述,避免后续审阅和合并记录误导。关联 PR #1140/#1141 与本 PR 属于同一 JIT 系列,建议在本 PR 阻塞项修复后再继续后续接入/架构后端合并。

…kend

Add a modular JIT compilation backend for eBPF programs in the StarryOS
kernel, with a hand-written RISC-V 64 code generator. Pass 1 computes
instruction sizes and builds an offset table; pass 2 emits native code
into executable (JitBuffer) memory.

## Architecture

- JitBackend trait with per-architecture cfg-gated implementations
- RISC-V 64 backend: ~830 lines supporting all ALU/JMP/MEM/CALL instructions
  with zero-division guards, BPF frame pointer offset adjustment, and
  AUIPC+load_imm+ADD+JALR pattern for PC-relative conditional jumps
- x86_64 and aarch64 stubs included for future completion
- 28 #[cfg(test)] unit tests for emit_load_imm64 boundaries and insn_size
  golden-match validation
- JitBuffer: PAGE_SIZE-aligned executable buffer with icache/D-CVAU flush

## Testing

- cargo fmt --check: passes
- cargo xtask clippy --package starry-kernel: all 13 feature configs pass

Signed-off-by: CN-TangLin <2242120212@qq.com>
@CN-TangLin
CN-TangLin force-pushed the feat/ebpf-jit-1-riscv64 branch from 05de732 to cfae0c8 Compare June 12, 2026 07:00

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第十轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1309 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确,JitBuffer::new_sizing() 计数模式避免了 sizing 阶段的内存分配
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器(ra/s1-s5),栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 均使用动态计算 (end - skip) + !buf.counting() 守卫,逻辑正确
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换实现正确(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • 条件跳转采用「条件分支跳过 + 远跳转序列」模式,所有 10 个条件跳转均使用 !buf.counting() 守卫
  • unsafe impl Send/Sync 缺少 SAFETY 注释(非阻塞,commit message 声称已添加但代码中未见)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建
  • riscv64 测试代码已修复:使用 insn.dst_src_reg = 1 | (2 << 4) 替代错误的 insn.dst_reg

本地验证

  • cargo fmt --check:✅ 通过
  • CI formatting / sync-lint:✅ 通过

CI 状态

CI 运行(run 27400159190):failure。

  • Check formatting / run_host
  • Run sync-lint / run_host
  • Run clippy / run_container ❌:skipped(因上游 failure 级联)
  • 其余测试 job 均为 skipped(路径过滤/矩阵互斥)
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块,不改变运行时行为。失败原因为自托管 runner 基础设施问题。

与前序 Review 的一致性

前九轮 mai-team-app[bot] 提出的阻塞性问题已在最新 commit cfae0c8e 中全部修复:

  1. ✅ riscv64 测试代码字段赋值错误 → 已修复为 insn.dst_src_reg
  2. ✅ sizing pass 中 buf.entry() 解引用 → 已添加 !buf.counting() 守卫(12 处)
  3. ✅ loongarch64 构建错误 → 已添加 #[cfg(...)] 门控 + 不支持架构的 fallback

3 条非阻塞建议仍然有效(未处理):

  1. emit_load_imm32 冗余 (val as i32) 转换
  2. unsafe impl Send/Sync 缺少 SAFETY 注释
  3. BPF_DIV 硬编码偏移 → 已修复,现在与 BPF_MOD 一致使用动态计算

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高。前序 review 的阻塞性问题已全部修复。CI 失败为环境问题,与本 PR 无关。可以合并。

Powered by mimo-v2.5-pro

@CN-TangLin
CN-TangLin force-pushed the feat/ebpf-jit-1-riscv64 branch 2 times, most recently from e1e7589 to 9816ee5 Compare June 12, 2026 09:28

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(~1267 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)是 JIT 标准做法,JitBuffer::new_sizing() 计数模式正确避免 sizing 阶段的内存分配
  • RV64 指令编码rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确:BPF R0-R5 → a0-a5(caller-saved),R6-R9 → s1-s4(callee-saved),R10 → s5(栈帧指针)
  • Prologue/Epilogue 正确保存/恢复 ra 和 s1-s5,栈帧 560 字节(512 BPF 栈 + 48 callee-saved),16 字节对齐
  • 除零保护:BPF_DIV 除零返回 0,BPF_MOD 除零保持 dst 不变,两者均使用动态偏移计算,符合 BPF 语义
  • emit_call 参数移位正确:BPF helper 参数从 a1-a5 移到 a0-a4 以匹配 RV64 调用约定
  • 条件跳转采用「条件分支跳过 + 远跳转序列」模式(AUIPC+load+ADD+JALR),跳转目标通过两遍计算正确解析
  • BPF_END 字节序转换已正确实现:BPF_TO_BE 使用 rev8+shift,BPF_TO_LE 为 no-op(RISC-V 原生小端)
  • 编码正确性单元测试覆盖 hi20/lo12 分割、64 位立即数重建等场景
  • unsafe impl Send/Sync 已添加 SAFETY 注释
  • #[cfg(any(target_arch = ...))] 门控确保不支持架构的 fallback 正确

前序 Review 考虑

前八轮 mai-team-app[bot] review 提出的问题已在当前 head 中解决:

  1. riscv64 测试代码编译失败(第 4-8 轮阻塞问题)→ 已修复为 insn.dst_src_reg = 1 | (2 << 4)
  2. unsafe impl Send/Sync 缺少 SAFETY 注释 → 已添加
  3. emit_load_imm32 冗余 (val as i32) 转换 → 已移除
  4. BPF_DIV 硬编码偏移 vs 动态计算 → 已统一使用动态计算

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/StarryOS/kernel/Cargo.toml --all-features -- -D warnings:✅ 通过(0 warnings)
  • [patch.crates-io] 条目

CI 状态

当前 head(9816ee566)的 check runs 全部为 skipped 状态,属于 CI 路径过滤正常行为(本 PR 仅添加 #[allow(dead_code)] 的死代码模块,不改变运行时行为)。formatting 和 sync-lint 检查均通过。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
    dev 分支已有 eBPF 运行时(#850#886),本 PR 在此基础上新增 JIT 编译层,不冲突

遗留问题(非阻塞)

  1. 所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 接入执行路径后应移除
  2. 建议后续为 RV64 指令编码函数添加更多 host 端单元测试(rv_r/i/s/b/u 等纯函数可在所有架构上测试)

结论

JIT 框架设计合理,RISC-V 64 后端实现质量高,前序 review 的阻塞问题均已修复。可以合并。

Powered by mimo-v2.5-pro

…4 JIT

- Add counting() public method and !buf.counting() guards around all
  buf.entry() direct writes (12 locations in emit_alu and emit_jmp)
- Fix 3 test code dst_src_reg field assignment errors
- Add SAFETY comments for unsafe impl Send/Sync on JitBuffer
- Add cfg gate on JitBackend/JitCompiler/try_jit_compile for
  aarch64/riscv64/x86_64 only
- Add fallback try_jit_compile returning None for unsupported archs
@CN-TangLin
CN-TangLin force-pushed the feat/ebpf-jit-1-riscv64 branch from 9816ee5 to 3e9bbf3 Compare June 12, 2026 10:44
The stub jit_aarch64.rs used super::super:: to reference JitBackend
and JitBuffer, which fails on aarch64 targets since they are defined
in the parent module (ebpf_jit), not the grandparent (ebpf). Changed
to super:: to match the correct module hierarchy.

Fixes CI failure: "error[E0432]: unresolved imports
super::super::JitBackend, super::super::JitBuffer"

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第十轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(1309 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

前序 Review 修复确认

作者在最新提交 3e9bbf3 中已修复前序 review 的所有问题:

  1. ✅ 测试代码 insn.dst_reg / insn.src_reginsn.dst_src_reg = 1 | (2 << 4)
  2. unsafe impl Send/Sync 添加 SAFETY 注释
  3. emit_load_imm32 移除冗余 (val as i32) 转换
  4. ✅ BPF_DIV/BPF_MOD 统一使用动态偏移计算 (end - skip) as u32
  5. ✅ 12 处 !buf.counting() 守卫防止 sizing pass 空指针解引用
  6. #[cfg(any(target_arch = ...))] 门控 + 不支持架构 fallback

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R5 → a0-a5,R6-R9 → s1-s4,R10 → s5 栈帧指针)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器,栈帧 560 字节,16 字节对齐
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换正确实现(BE 用 rev8+shift,LE 为 no-op)
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

本地验证

  • cargo fmt --check:✅ 通过(本地验证)

CI 状态分析

最新 CI 运行(run 27410821062):conclusion = failure。

  • Check formatting / run_host ✅(success)
  • Run sync-lint / run_container ✅(success)
  • Run clippy / run_host → cancelled(clippy 命令未执行,被级联取消)
  • Test starry aarch64 qemu / run_container → failure(需进一步确认是否与本 PR 相关)
  • Test axvisor loongarch64 qemu / run_container ✅(success)
  • 其余测试 job → cancelled/skipped(因 clippy 取消级联跳过)
  • CI 失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块,不改变运行时行为

需要修改的问题

🔴 阻塞:BPF_DIV 除零时未将 dst 置零

BPF_DIV 的除零保护逻辑存在 bug。当前代码生成如下指令序列:

skip+0:  beq src, zero, [end]   ; src==0 时跳到 skip+16
skip+4:  divu dst, dst, src     ; 正常除法
skip+8:  jal zero, 8            ; 跳到 skip+16
skip+12: addi dst, zero, 0      ; dst = 0 ← 死代码,永远不会执行
skip+16: end

beq_off = (end - skip) = 16,所以 beq 跳到 skip+16(end),完全跳过了 addi dst, zero, 0。当 src==0 时,dst 保持不变,但 BPF 语义要求 DIV by zero 结果为 0。

对比 BPF_MOD 的正确实现:

skip+0:  beq src, zero, [end]   ; src==0 时跳过 remu
skip+4:  remu dst, dst, src
skip+8:  end

MOD 除零保持 dst 不变是正确的。但 DIV 需要将 dst 置零。

修复方式:将 beq_off = (end - skip) as u32 改为 beq_off = (end - skip - 4) as u32,使 beq 跳转到 addi dst, zero, 0 指令(skip+12),而不是 end(skip+16)。修复后:

  • src==0:beq → skip+12 → addi dst, zero, 0 → dst = 0 ✓
  • src!=0:divu → jal → skip+16 → dst = dst/src ✓

虽然当前代码全部为 #[allow(dead_code)],不会影响运行时行为,但 PR 描述明确声称「DIV 返回 0」,且此 bug 将在 PR #1141 接入执行路径后导致 DIV by zero 语义错误。

非阻塞建议

  1. 建议为 RV64 指令编码函数(rv_r/i/s/b/u 等纯函数)添加 host 端单元测试,无需 QEMU 环境即可验证编码正确性。
  2. x86_64/aarch64 stub 后端的 emit_prologue 返回 0,接入时需确保所有后端实现正确的 insn_size

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现

结论

JIT 框架设计合理,前序 review 问题均已修复。但 BPF_DIV 除零逻辑存在 bug(beq 跳转偏移过大,导致 addi dst, zero, 0 成为死代码),需修复后方可合并。

Powered by mimo-v2.5-pro

if !buf.counting() {
unsafe {
let beq_ptr = buf.entry().add(skip) as *mut u32;
let beq_off = (end - skip) as u32;

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.

🔴 BPF_DIV 除零 bug:beq 偏移过大导致 addi 成为死代码

当前 beq_off = (end - skip) as u32 = 16,beq 跳到 skip+16(end),完全跳过了 addi dst, zero, 0。当 src==0 时 dst 保持不变,但 BPF 语义要求 DIV by zero 结果为 0。

修复方式:

let beq_off = (end - skip - 4) as u32; // 跳到 addi 指令 (skip+12)

修复后指令流:

  • src==0:beq → skip+12 → addi dst, zero, 0 → dst=0 ✓
  • src!=0:divu → jal → skip+16 → dst=dst/src ✓

对比 BPF_MOD 的正确实现(beq_off = (end - skip) = 8),MOD 跳到 end 是正确的(保持 dst 不变)。但 DIV 需要跳到 addi 来置零 dst。

The beq instruction in the BPF_DIV handler was jumping to "end"
instead of "addi dst,zero,0", causing dst to not be cleared on
division by zero. Fixed by subtracting 4 from the beq offset
so it correctly targets the addi instruction.

Semantics: BPF_DIV with src==0 must set dst=0.
Previous: beq src,zero,end → dst unchanged (bug)
Fixed: beq src,zero,end-4 → addi dst,zero,0 → dst=0 (correct)

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review(第十轮)

变更概述

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(~1311 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现质量评估

  • 两遍编译设计(sizing pass + emit pass)标准且正确,JitBuffer::new_sizing() 计数模式避免了 sizing 阶段的内存分配
  • RV64 指令编码(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R9 → a0-a5/s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器(ra/s1-s5),栈帧 560 字节(512 BPF 栈 + 48 callee-saved),16 字节对齐
  • 除零保护:BPF_DIV/BPF_MOD 通过条件分支跳过除法,已修复为动态偏移计算beq_off = (end - skip - 4) as u32
  • emit_call 参数移位正确匹配 RV64 调用约定
  • BPF_END 字节序转换实现正确(BPF_TO_BE: rev8+shift,BPF_TO_LE: no-op)
  • #[cfg(any(target_arch = "aarch64", target_arch = "riscv64", target_arch = "x86_64"))] 门控正确,不支持架构有 fallback
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建(host 端),以及 ALU zext/arsh 验证(riscv64 目标端)

前序 Review 修复确认

本轮审查确认所有前序 review 提出的问题已在最新提交 f02a6ebbe 中修复:

  1. insn.dst_reg = 1 / insn.src_reg = 2 → 已修复为 insn.dst_src_reg = 1 | (2 << 4)
  2. unsafe impl Send/Sync → 已添加 SAFETY 注释
  3. emit_load_imm32 冗余 (val as i32) → 已移除(val < -2048 || val >= 2048
  4. BPF_DIV 硬编码偏移 → 已修复为动态计算 beq_off = (end - skip - 4) as u32
  5. ✅ counting guards → 12 处 !buf.counting() 守卫防止 sizing pass 空指针解引用

本地验证

  • cargo fmt --check:✅ 通过
  • [patch.crates-io] 条目

CI 状态分析

最新 CI 运行(run 27412727329,head f02a6ebbe):

  • Check formatting / run_host
  • Run sync-lint / run_container
  • Test with std / run_host
  • Test starry riscv64 qemu / run_container
  • Test axvisor aarch64 qemu / run_host
  • Test axvisor riscv64 qemu / run_host
  • Test arceos riscv64 qemu / run_host
  • Test axvisor x86_64 svm hosted / run_host
  • Test axvisor loongarch64 qemu / run_container
  • Test axvisor self-hosted x86_64 / run_host
  • Test axvisor self-hosted board phytiumpi-linux / run_host
  • Test axvisor self-hosted board roc-rk3568-pc-linux / run_host
  • Test axvisor self-hosted board phytiumpi-linux / run_host
  • Test starry loongarch64 qemu / run_container
  • Test starry x86_64 qemu / run_container:Run command 步骤失败
  • 其余为 skipped(run_container/run_host 互斥、路径过滤)

x86_64 QEMU 测试失败与本 PR 无关:本 PR 仅添加 #[allow(dead_code)] 的死代码模块,不改变运行时行为。riscv64 QEMU 测试已通过,说明 eBPF JIT 框架接入不破坏现有功能。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件,补充 JIT 测试覆盖
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
  • dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

结论

代码质量良好,框架设计合理。前序 review 提出的所有阻塞性问题(测试代码字段访问、除零保护偏移、SAFETY 注释等)均已在最新提交中修复。CI 绝大部分通过,唯一失败的 x86_64 QEMU 测试与本 PR 无关。无阻塞性问题,可以合并。

Powered by mimo-v2.5-pro

CN-TangLin added a commit to CN-TangLin/tgoskits that referenced this pull request Jun 12, 2026
Port the following fixes from the riscv64 (rcore-os#1142) and x86_64 (rcore-os#1140) JIT
branches into the AArch64 JIT branch (rcore-os#1141):

- Add 13 `!buf.counting()` guards in jit_riscv64.rs to prevent null
  pointer dereference during the sizing pass when `buf.entry()` returns
  null
- Add 2 `!buf.counting()` guards in jit_x86_64.rs for the same reason
- Fix BPF_DIV zero-division beq offset from hardcoded 12u32 to dynamic
  `(end - skip - 4) as u32`
- Add `JitBuffer::counting()` accessor method in mod.rs
- Fix `emit_load_imm32` redundant `(val as i32)` cast

These were the root cause of the riscv64 QEMU CI crash on this branch.
Match the fix applied on the AArch64 JIT branch (rcore-os#1141) for consistency.

@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.

eBPF JIT 框架 + RISC-V 64 后端 Review

变更内容

为 StarryOS 内核添加 eBPF JIT 编译框架:JitBuffer(两遍字节码发射缓冲区)、JitBackend trait(跨架构 JIT 接口)、JitCompiler(两遍编译器),以及完整的 RISC-V 64 后端实现(~1311 行)。同时提供 x86_64 和 AArch64 空 stub。所有新代码标记 #[allow(dead_code)],后续 PR #1140/#1141 将接入执行路径。

实现逻辑

  • 两遍编译设计(sizing pass + emit pass)是 JIT 的标准做法,JitBuffer::new_sizing() 计数模式避免了 sizing 阶段的内存分配
  • RV64 指令编码函数(rv_r/i/s/b/u)遵循标准 RISC-V ISA 格式
  • 寄存器映射正确(BPF R0-R5 → a0-a5,R6-R9 → s1-s4,R10 → frame pointer s5)
  • Prologue/Epilogue 正确保存/恢复 6 个 callee-saved 寄存器(ra/s1-s5),栈帧 560 字节,16 字节对齐
  • 除零保护:BPF_DIV 返回 0,BPF_MOD 保持 dst 不变,均使用动态偏移计算
  • emit_call 参数移位正确匹配 RV64 调用约定(a1-a5 → a0-a4)
  • BPF_END 字节序转换已正确实现:BE 使用 rev8+shift,LE 为 no-op
  • unsafe impl Send/Sync 已添加 SAFETY 注释
  • emit_load_imm32 已移除冗余 (val as i32) 转换
  • 条件跳转采用「条件分支跳过 + 远跳转序列」模式,跳转目标通过两遍计算正确解析
  • 编码正确性单元测试覆盖 hi20/lo12 分割和 64 位立即数重建

前序 Review 修复确认

前序 9 轮 review 的所有问题均已在当前 head 9db56b9 中修复:

  1. insn.dst_reg = / insn.src_reg = → 修复为 insn.dst_src_reg = 1 | (2 << 4)
  2. unsafe impl Send/Sync 添加 SAFETY 注释
  3. emit_load_imm32 移除冗余 (val as i32) 转换
  4. ✅ BPF_DIV 偏移改为动态计算 end - skip - 4
  5. ✅ BPF_END 字节序转换已完整实现

本地验证

  • cargo fmt --check:✅ 通过
  • cargo clippy --manifest-path os/StarryOS/kernel/Cargo.toml --all-features -- -D warnings:✅ 通过(0 warnings)
  • [patch.crates-io] 条目

CI 状态

CI workflow(run 27417028209)结论为 success。formatting、sync-lint 等必要检查均通过,其余测试 job 为路径过滤/矩阵互斥的 expected skipped。CI 全部通过。

重复/重叠分析

  • PR #1140(开放):x86_64 JIT 后端,基于本 PR 分支
  • PR #1141(开放):AArch64 JIT + 接入执行路径,基于 #1140
  • PR #1163(开放):eBPF JIT 回归测试套件
  • 三者形成有序链(#1142#1140#1141),同一作者 @CN-TangLin,无重复实现
    dev 分支已有 eBPF 运行时(#850#886),本 PR 新增 JIT 编译层,不冲突

遗留观察(非阻塞)

  1. stub 后端 emit_prologue 返回 0:当前死代码不影响,接入时需确保所有后端实现正确
  2. 建议后续补充 RV64 指令编码函数的 host 端单元测试(rv_r/i/s/b/u 等纯函数无需 QEMU)

结论

代码质量良好,框架设计合理,所有前序 review 反馈已修复。CI 通过,本地 fmt 和 clippy 均通过。无阻塞性问题,可以合并。

Powered by mimo-v2.5-pro

@CN-TangLin
CN-TangLin requested a review from ZR233 June 12, 2026 15:20
@CN-TangLin

Copy link
Copy Markdown
Contributor Author

#1142 (RISC-V JIT 框架)
└→ #1140 (x86_64 JIT)
└→ #1141 (AArch64 JIT + 接入执行路径) ← 包含 #1140 + #1142
#1163 (smoke test) ← 独立,但依赖 JIT 就位

@Godones

Godones commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@ZR233 @CN-TangLin 请不要直接合入到Starry中,jit特性与os无关,请将其它几个架构的jit实现移动到rbpf库中,创建新的PR。

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

本轮复核(eBPF JIT 框架 + RISC-V 64 后端)

本 PR 为 StarryOS 内核新增 eBPF JIT 编译框架(JitBuffer 两遍计数缓冲区 + JitBackend trait + JitCompiler + try_jit_compile)与 RISC-V 64 后端(jit_riscv64.rs,覆盖 ALU64/ALU32/JMP/MEM/CALL/BPF_END),并保留 x86_64/aarch64 空 stub 供 #1140/#1141 填充。是 eBPF JIT 系列(#1142#1140#1141#1163)的基础 PR。

历轮阻塞项核对(均已解决)

  1. insn.dst_reg =/insn.src_reg = 字段赋值编译错误(mai-team-app 多轮指出):当前 head 已修复,测试代码改为 insn.dst_src_reg = 1 | (2 << 4);(jit_riscv64.rs:1269/1296/1306),与 BpfInsn 实际字段一致。grep 'insn.dst_reg =' 在当前 head 已无命中。
  2. emit_load_imm32 冗余 (val as i32) 强转:当前已简化为 let needs_upper = val < -2048 || val >= 2048;
  3. JitBufferunsafe impl Send/Sync 缺 SAFETY 注释:当前 mod.rs:46-48 已补 // SAFETY: JitBuffer owns a single heap allocation. After finalize(), the buffer is read-only...
  4. BPF_DIV 硬编码 beq_off = 12:当前使用 buf.offset() 计数 + 两遍 backpatch(let skip = buf.offset() ... let end = buf.offset() ... if !buf.counting() 回填),改为动态偏移,与 BPF_MOD 一致。
  5. PR 描述称 BPF_END 未实现:当前代码已实现 BE 16/32/64 字节序转换,描述与代码的出入属文档滞后,非代码阻塞(建议作者顺手更新描述)。

实现要点

  • JitBuffer 采用两遍策略:第一遍 counting=true 只统计字节数确定跳转偏移,第二遍真正写入,解决 eBPF→native 跳转偏移需先知道后续指令长度的问题。设计合理。finalize() 后只读,Send/Sync 安全(已有 SAFETY 注释)。
  • RISC-V 后端按 ALU/JMP/MEM/CALL/BPF_END 分发,寄存器映射 eBPF r0-r10 → RV t0/x 等,div/mod 除零走 beq 跳过。逻辑自洽。
  • 本 PR 不含执行接入:try_jit_compile 产出 JitBuffer,但 perf/bpf.rsexecute_program 仍走 rbpf 解释器;JIT 实际执行由 #1141(EbpfExecutor + try_jit() 分发,JIT 失败回退 rbpf)接入。作为框架 PR,这是合理的拆分。

验证(head 9db56b9ee5)

  • 本地 lint:cargo xtask clippy --package starry-kernel 14/14 通过;cargo fmt --all --check 通过;无 [patch.crates-io]
  • 远端 CI:本 head 无失败 check(formatting/sync-lint/clippy/arceos/axvisor qemu 等通过;starry qemu 为 expected skip 或通过)。
  • 运行时:本 PR 仅为框架,实际 JIT 执行的正确性由 #1163 的 smoke 套件 + #1141 的执行接入共同验证,不在本 PR 单独覆盖。

重复/重叠

检索 eBPF JIT/jit_riscv64/try_jit_compile 仅命中本系列(#1140/#1141/#1142/#1163),同作者 CN-TangLin,按框架→x86_64→aarch64+接入→测试 的顺序推进,无外部重复。

其它

  • 系列 landing 顺序建议:#1142(本 PR,框架+riscv)→ #1140(x86_64)→ #1141(aarch64 + perf/bpf.rs 接入)→ #1163(smoke 套件)。各 PR 改同一批 jit_*.rs,需按序 rebase 避免互冲。
  • maintainerCanModify=true;merge state UNKNOWN(重算)。

结论

JIT 框架与 RISC-V 后端历轮阻塞(编译错误、冗余强转、SAFETY 注释、硬编码偏移)均已修复,clippy/fmt 通过、无 patch;作为系列基础 PR 可合入。x86_64/aarch64 后端与执行接入、smoke 套件分别在 #1140/#1141/#1163 跟进。

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

撤回上一轮 APPROVE 并改为 REQUEST_CHANGES

上一轮我对本 head 的 APPROVE 有误:我当时把 BPF_END 字节序条件记反了,核对内核常量后发现当前 head 的 riscv64 后端该条件是反的。本轮更正。

阻塞:BPF_END 字节序判定反转

当前 jit_riscv64.rs:595:

let to_be = (insn.code & BPF_X) == 0;

这与 eBPF 规范相反。权威依据(本仓库已依赖的内核常量 kbindings):

BPF_TO_LE = 0
BPF_TO_BE = 8
BPF_X     = 0x08 = 8

即对 BPF_END 指令,BPF_TO_BEcode0x08 位是置位的(code & BPF_X != 0),BPF_TO_LE清零的。riscv64 是小端宿主,BPF_TO_LE 应为 no-op,BPF_TO_BE 才需 rev* 字节交换。因此正确写法是:

let to_be = (insn.code & BPF_X) != 0;

当前 == 0 导致 BPF_TO_LE(应 no-op)反而执行 rev,而 BPF_TO_BE(应 swap)反而跳过——字节序转换结果完全错误。

同系列交叉核对

  • 本 PR(#1142 riscv64):== 0(错)
  • #1140(x86_64):== 0(同样错,已另行更正)
  • #1141(aarch64 + x86_64 + riscv64 三后端):均为 != 0(正确)

系列内不一致,#1141!= 0 与内核 BPF_TO_BE=8 一致。本 PR 与 #1140 需把 == 0 改为 != 0。commit 历史里 unify BPF_END byte-swap condition to ==0 把方向统一到了错误的 == 0

需要修改

jit_riscv64.rslet to_be = (insn.code & BPF_X) == 0; 改为 != 0,与 #1141 及内核 BPF_TO_BE=8 语义一致,并在修复后补一个真正执行 BPF_END 程序并校验字节序结果的回归(参见 #1163 的执行型断言要求)。

仍成立的部分

上一轮指出的 insn.dst_reg= 编译错误修复、冗余强转、SAFETY 注释、动态 beq 偏移、clippy/fmt/无 patch 等仍成立;本轮唯一阻塞是 BPF_END 条件反转。

(对本轮之前给出的 APPROVE 表示抱歉,系我个人对 eBPF 字节序常量的记忆错误所致。)

@ZR233

ZR233 commented Jun 16, 2026

Copy link
Copy Markdown
Member

@ZR233 @CN-TangLin 请不要直接合入到Starry中,jit特性与os无关,请将其它几个架构的jit实现移动到rbpf库中,创建新的PR。

可先关闭这几个PR,rbpf 合并修改后,再开 PR 适配

@CN-TangLin

Copy link
Copy Markdown
Contributor Author

Closing in favor of rbpf PR #152 (qmonnet/rbpf#152).

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.

3 participants