Skip to content

fix bug: 'cargo qemu --ch 2 --release' is hung#17

Merged
YdrMaster merged 1 commit into
YdrMaster:mainfrom
rcore-os:main
Jan 8, 2026
Merged

fix bug: 'cargo qemu --ch 2 --release' is hung#17
YdrMaster merged 1 commit into
YdrMaster:mainfrom
rcore-os:main

Conversation

@chyyuu
Copy link
Copy Markdown
Contributor

@chyyuu chyyuu commented Jan 8, 2026

在 release 模式下,cargo qemu --ch 2 --release 卡住的原因有两个:

1. kernel-context/src/lib.rs 中的 execute 函数

原代码:

core::arch::asm!(
    "csrrw {sscratch}, sscratch, {sscratch}  // 交换后 {sscratch} 寄存器变成旧的 sscratch 值
     ...
     csrw sscratch, {sscratch}               // 用错误的值恢复 sscratch
     csrr {sepc}, sepc
    ",
    sscratch = in(reg) self,                 // 编译器在 asm 后仍用这个寄存器访问 self.sepc
    sepc = inlateout(reg) self.sepc,         // 但寄存器已经不是 self 了!
);

csrrw 指令后,存放 self 的寄存器被交换成了旧的 sscratch 值。但编译器在 asm 块后仍然用该寄存器去写 self.sepc,导致写入到错误的内存地址。

修复:使用独立的寄存器保存上下文指针和旧 sscratch 值:

        // 保存 self 指针和 sepc,避免 release 模式下 csrrw 破坏寄存器后的问题
        let ctx_ptr = self as *mut Self;
        let mut sepc = self.sepc;
        let old_sscratch: usize;
        core::arch::asm!(
            "   csrrw {old_ss}, sscratch, {ctx}
                ...
                csrw  sscratch, {old_ss}
                csrr  {sepc}   , sepc
            ",
            ctx           = in       (reg) ctx_ptr,
            old_ss        = out      (reg) old_sscratch,
            sepc          = inlateout(reg) sepc,
            ...
        );
        (*ctx_ptr).sepc = sepc;

2. ch2/src/main.rs 中的用户栈初始化

原代码 let mut user_stack = [0usize; 256]; 在 release 模式下,2048 字节的零初始化数组会触发某些优化问题。

修复:使用 MaybeUninit 跳过零初始化:

        // 设置用户栈(使用 MaybeUninit 避免 release 模式下零初始化的问题)
        let mut user_stack: core::mem::MaybeUninit<[usize; 256]> = core::mem::MaybeUninit::uninit();
        let user_stack_ptr = user_stack.as_mut_ptr() as *mut usize;
        *ctx.sp_mut() = unsafe { user_stack_ptr.add(256) } as usize;

Copilot AI review requested due to automatic review settings January 8, 2026 07:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical bug that causes cargo qemu --ch 2 --release to hang in release mode. The issue stems from aggressive compiler optimizations that break assumptions in inline assembly and stack initialization.

Key changes:

  • Fixed register corruption in LocalContext::execute() by using separate variables for context pointer and old sscratch value
  • Added #[inline(never)] to prevent inlining issues with inline assembly
  • Replaced zero-initialized user stack with MaybeUninit to avoid optimization issues

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
kernel-context/src/lib.rs Fixed register corruption bug in execute() function by separating context pointer from sscratch register and preventing function inlining
ch2/src/main.rs Changed user stack from zero-initialized array to MaybeUninit and added black_box to prevent compiler optimizations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread kernel-context/src/lib.rs
sstatus = inlateout(reg) sstatus,
execute_naked = sym execute_naked,
);
let _ = old_sscratch; // suppress unused warning
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

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

The variable old_sscratch is already used in the inline assembly as an output operand (old_ss), so this line is redundant. The compiler won't produce an "unused variable" warning for variables that are used in inline assembly operands.

Suggested change
let _ = old_sscratch; // suppress unused warning

Copilot uses AI. Check for mistakes.
@YdrMaster YdrMaster merged commit ab06568 into YdrMaster:main Jan 8, 2026
7 checks passed
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.

4 participants