fix(vkernel): _render 脏行行界由“夹取兜底”改为 fail-fast(越界即报错停机)

按“禁止兜底、改 fail-fast”的要求:_dirty_y_min/_dirty_y_max 是 .bss 全局,
被写坏时(曾观测 fb/pitch/w/h 被随机清零)原夹取会静默掩盖上游写坏源。
现改为越界立即打印 FATAL 并停机,直接暴露写坏。
合法的空脏行集合状态(_dirty_count==0、_dirty_y_max==-1、_dirty_y_min==h)已放行。
This commit is contained in:
TermiNexus committed 2026-10-14 14:55:40 +08:00
1 parent b6cc64a5c9
commit 9cf33ab374
1 file changed
+13 -11
+13 -11
View File
@@ -1305,15 +1305,17 @@ def _render():
t0: uint64 = timer.timer_get_ticks()
row_bytes: int = w * 4
# 行界夹取:_dirty_y_min/_dirty_y_max 若被写坏成异常值,会退化成死循环并越界写
# 到帧缓冲之外的 MMIO(实测把宿主 QEMU 写崩)。这里夹到 [0, h-1]。
_dymin_bg: int = _dirty_y_min
if _dymin_bg < 0: _dymin_bg = 0
_dymax_bg: int = _dirty_y_max
if _dymax_bg > h - 1: _dymax_bg = h - 1
# fail-fast:_dirty_y_min/_dirty_y_max 是 .bss 全局,一旦被写坏(曾观测到 fb/pitch/w/h
# 被随机清零),循环会退化成死循环并把脏行越界写到帧缓冲之外的 MMIO(实测把宿主 QEMU
# 写崩)。这里不做夹取兜底,直接报错停机,暴露上游写坏源。
# 说明:空脏行集合的合法值是 _dirty_count==0 配合 _dirty_y_max==-1(_dirty_y_min 此时为 h)。
if _dirty_y_max < -1 or _dirty_y_max > h - 1 or _dirty_y_min < 0:
serial.puts("[desktop] FATAL: dirty row range corrupted\n")
while True:
sched.Scheduler._yield()
if _bg_row_buf and _dirty_count > 0:
py_bg: int = _dymin_bg
while py_bg <= _dymax_bg:
py_bg: int = _dirty_y_min
while py_bg <= _dirty_y_max:
if _dirty_rows[py_bg]:
string.memcpy(rawptr(uint64(back) + py_bg * row_bytes), _bg_row_buf, row_bytes)
py_bg += 1
@@ -1351,11 +1353,11 @@ def _render():
_wait_vblank()
if _dirty_count > 0:
py_fb: int = _dymin_bg
while py_fb <= _dymax_bg:
py_fb: int = _dirty_y_min
while py_fb <= _dirty_y_max:
if _dirty_rows[py_fb]:
run_start: int = py_fb
while py_fb <= _dymax_bg and _dirty_rows[py_fb]:
while py_fb <= _dirty_y_max and _dirty_rows[py_fb]:
py_fb += 1
run_bytes: int = (py_fb - run_start) * row_bytes
string.memcpy(rawptr(uint64(_fb) + run_start * pitch), rawptr(uint64(back) + run_start * row_bytes), run_bytes)