Skip to content

fix(aarch64): use dc civac instead of dc ivac in invalidate_dcache_range#312

Merged
Inquisitor-201 merged 1 commit into
syswonder:devfrom
Inquisitor-201:fix/aarch64-dcache-clean-inval
May 26, 2026
Merged

fix(aarch64): use dc civac instead of dc ivac in invalidate_dcache_range#312
Inquisitor-201 merged 1 commit into
syswonder:devfrom
Inquisitor-201:fix/aarch64-dcache-clean-inval

Conversation

@Inquisitor-201
Copy link
Copy Markdown
Contributor

问题

invalidate_dcache_range() 使用 dc ivac(Data Cache Invalidate by VA to PoC)。该指令仅作废 cache line,不写回 dirty 数据。如果 cache line 处于 dirty 状态(有未写回 DRAM 的改动),数据会被静默丢弃。

影响

zone 创建流程中,arch_zone_reset() 在 guest VM 启动前对所有非 IO 内存区域做统一 cache clean & invalidate("insurance")。此时如果 hypervisor 或内核模块此前向该区域写入过数据(如 DTB、内核镜像、IVC 信息等),对应的 cache line 可能仍为 dirty。

触发路径:

zone_create()
  └─ arch_zone_reset()
       └─ invalidate_dcache_range()

在 root zone 初始化(main.rs)和通过 hypercall 创建 guest VM(hypercall/mod.rs)时均会执行。

修复

dc ivacdc civac(Clean & Invalidate):

  • Clean:先写回 dirty cache line 到 Point of Coherency(PoC)
  • Invalidate:再作废本地 PE 的 cache line

dc civacdc ivac 的严格超集。同时修正了 arch_zone_reset 中注释的错误陈述(原注释声称 "invalidate operation will broadcast to all cores"),改为说明 InnerShareable 域中硬件一致性协议处理跨核 coherency 的正确理由。

影响范围

仅 aarch64 平台。单行指令变更,零回归风险。CIVAC 的 clean 步骤对 clean cache line 无额外开销,仅 dirty line 需写回,实际影响可忽略。

测试说明

该 bug 在 QEMU 上不可现(QEMU 不精确模拟 cache 行为,cache 操作通常是 no-op),在物理硬件(rk3588 等)上修复有效。

@github-actions github-actions Bot added aarch64 bug Something isn't working labels May 26, 2026
@Inquisitor-201 Inquisitor-201 requested a review from liulog May 26, 2026 08:04
@liulog
Copy link
Copy Markdown
Contributor

liulog commented May 26, 2026

I agree with replacing ivac with civac, but I'm not entirely certain about broadcast.

Based on the diagram below, broadcasts using ivac and civac might not consider the share attribute. (Diagram from ARM Cortex-A Series Programmer’s Guide for ARMv8-A). Or perhaps I misunderstood.

image

dc ivac discards dirty cache lines without write-back, potentially
corrupting guest data on the main VM creation path. dc civac first
writes back dirty data to PoC before invalidating, ensuring data
coherency.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Inquisitor-201 Inquisitor-201 force-pushed the fix/aarch64-dcache-clean-inval branch from 8fc90a7 to 7a26c8d Compare May 26, 2026 08:42
@Inquisitor-201
Copy link
Copy Markdown
Contributor Author

Thanks for the review! I have reverted the comment change in zone.rs — the original broadcast claim is correct per ARM ARM Table 14-1 (both DC IVAC and DC CIVAC broadcast). The PR is now reduced to just the 1-line instruction fix in cache.rs.

The justification for ivac → civac remains: on the VM creation path, the root zone data writes (kernel image, DTB, etc.) can leave dirty cache lines on the same PE. dc ivac discards them silently, while dc civac writes back before invalidating.

@Inquisitor-201 Inquisitor-201 merged commit c1a00ad into syswonder:dev May 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aarch64 bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants