fix(gicv2): use GICv2 CPU target masks - #1803
Conversation
There was a problem hiding this comment.
本 PR 将 GICv2 的逻辑 CPU 编号与硬件 CPU target bit 解耦:在每个 CPU 初始化时读取 banked GICD_ITARGETSR0,并用于 fixed SPI affinity 与 SGI;GICv3 的 MPIDR 路径保持不变。该改动是既有硬件路由行为的 bug 修复,未新增用户可见能力,feature-development.md 不适用。
阻塞问题见行内评论:默认 SPI 初始化仍把 target 写成 bit0,未使用刚读取的 BSP target mask,因此本 PR 要支持的非 bit0 GICv2 映射下默认/早期设备 IRQ 仍会被路由到不存在的 CPU interface。
验证:cargo fmt --check、cargo test -p arm-gic-driver(7 passed)、cargo xtask clippy --package arm-gic-driver 与 cargo xtask clippy --package somehal(8 个 feature 配置)均通过。当前 head 的组织 CI 有成功与预期 matrix 跳过项,但主 PR workflow 已取消,未提供 AArch64 GICv2 的运行覆盖。
已检查既有 GICv2 distributor 初始化、GICv3 的 CPU-slot 发布模式和启动顺序;发现与本改动重复的 base 实现或开放 PR 后未见可替代实现。此前没有 review/issue 评论需要处理。除上述 SPI 默认路由缺口外,未发现其他阻塞问题;修复后应补充非 0x01 mask 的 SPI 配置回归测试,并完成目标板或 QEMU 验证。
Powered by gpt-5.6-terra
| } | ||
| cpu.current_cpu_target() | ||
| }) | ||
| }; |
There was a problem hiding this comment.
阻塞(硬件 IRQ 路由):这里记录到的 banked target mask 只用于后续的 fixed affinity 和 SGI;Gic::init() 更早调用的 configure_interrupt_targets() 仍把每个 SPI 的 ITARGETSR 写成硬编码的 0x01。因此 BSP 读到 GICD_ITARGETSR0 = 0x20 这类非 bit0 映射时,尚未经过单独 affinity 设置的设备 SPI 仍被路由到不存在的 bit0 CPU interface,早期/默认设备中断会丢失。请在取得 BSP mask 后用该 raw mask 重设默认 SPI target(或让 distributor 初始化直接接收 TargetList),并增加非 0x01 mask 下 SPI 配置的回归测试。
625f2d6 to
4b54827
Compare
There was a problem hiding this comment.
本 PR 修复 GICv2 将逻辑/固件 CPU 编号误作 CPU-interface target bit 的问题:BSP 初始化现在用 banked GICD_ITARGETSR0 的原始 mask 设置默认 SPI 路由;各 CPU 发布其硬件 mask,fixed SPI affinity 与定向 SGI/IPI 再按逻辑 CPU 查表转换。GICv3 的 MPIDR affinity 路径未改动,影响范围限于 GICv2 的 IRQ 路由契约。
feature-development.md 不适用:这是既有硬件路由行为的 bug 修复,未新增用户可见能力或公共接口。已复核前一轮行内意见:默认 SPI 初始化已改为使用 BSP mask,并有 0x40 非 bit0 mask 的回归测试,因此该意见已解决;未发现其他活跃问题。base 分支和以 GICv2/CPU target/ITARGETSR 检索到的开放 PR 未发现重复实现;#1829 是独立的 GICv3/VGIC 草案。
验证:review helper 已确认本地 HEAD 与 PR head 一致;cargo fmt --check、cargo test -p arm-gic-driver(7 passed)、cargo clippy --manifest-path drivers/intc/arm-gic-driver/Cargo.toml --all-features -- -D warnings 通过;somehal all-features clippy 通过。somehal host all-features 测试在链接阶段缺少 STACK_SIZE、PAGE_SIZE 与 per-CPU linker symbols,属于宿主测试构型没有内核链接脚本,未反映本改动的编译/逻辑失败。
当前 head 的组织 CI check-runs 为 success=35、skipped=34、failure=1;格式检查及相关 AArch64/板级矩阵成功,跳过项符合 host/container 与路径矩阵。CI workflow 聚合显示 failure,但已检查到的作业没有本改动面上的失败步骤;未见可归因于本 PR 的 CI 失败。无新增 app、syscall ABI 或测试套件布局变更,故无需 QEMU app 流程。审查待办已逐项完成;drivers//IRQ/aarch64 规则匹配的 ZR233 已被请求,无需变更 reviewer 元数据。
结论:APPROVE。
Powered by gpt-5.6-terra
问题
GICv2 的 CPU target 由
GICD_ITARGETSR中的 8 位 CPU interface mask 表示,它与内核逻辑 CPU 编号以及 MPIDR/固件 CPU ID 不是同一概念。原实现将
someboot提供的硬件 CPU ID 直接用于构造 GICv2TargetList。在 MPIDR 不连续或大于 7 的平台上,这可能导致:修改内容
TargetList增加from_raw(),允许保留硬件报告的原始 CPU target mask。CpuInterface增加current_cpu_target(),从当前 CPU bankedGICD_ITARGETSR0读取真实 target mask。实现逻辑
每个 CPU 在初始化自己的 GICv2 CPU interface 后读取 banked
GICD_ITARGETSR0。该寄存器提供当前 CPU interface 对应的真实 target bit。读取结果按照逻辑 CPU 编号保存在原子数组中:
后续 SPI affinity 和定向 SGI/IPI 操作仍以逻辑 CPU 编号作为上层接口,但在 GICv2 后端转换为硬件实际报告的 target mask。
GICv2 的 CPU target 字段只有 8 位,因此映射最多保存 8 个 CPU interface。数组使用 AtomicU8 和 Acquire/Release 顺序,使中断及 IPI 路径可以无锁读取已经发布的 target mask。
GICv3 的 MPIDR affinity 处理保持不变。