Skip to content

fix(ci): add safe.directory config for container submodule checkout#198

Merged
MRNIU merged 3930 commits intoSimple-XX:mainfrom
MRNIU:fix/ci-safe-directory
Mar 20, 2026
Merged

fix(ci): add safe.directory config for container submodule checkout#198
MRNIU merged 3930 commits intoSimple-XX:mainfrom
MRNIU:fix/ci-safe-directory

Conversation

@MRNIU
Copy link
Member

@MRNIU MRNIU commented Mar 20, 2026

Summary

修复 CI 流水线两个问题:

1. Shallow submodule init exit code 128

使用 container: 运行 job 时,容器以 root 用户运行,但 actions/checkout 创建的工作目录归属于 runner 用户。git submodule update 在子目录中触发 git 的 safe.directory 检查,导致 exit code 128。

Fix: 在两个 build job 的 submodule init 步骤前添加 git config --global --add safe.directory '*'

2. riscv64 system test 无法检测到测试失败

riscv64 的 system test 步骤只检查 cmake 退出码(始终为 0),即使 QEMU 内的测试失败也会报告 passed。

Fix: 与 aarch64 对齐,捕获输出到文件并 grep "Failed: 0" 来判断通过/失败。

Failed runs

MRNIU added 30 commits February 28, 2026 11:14
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Replace custom Singleton<T> with etl::singleton<T> using per-type
named aliases (e.g. BasicInfoSingleton, TaskManagerSingleton) defined
centrally in kernel.h. Delete singleton.hpp. Update all call sites
from Singleton<T>::GetInstance() to TypeSingleton::instance() and
assignment-construction to TypeSingleton::create(). Update all
documentation references.

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
…e interrupt controllers Interrupt members

Move arch-specific singleton type aliases from shared kernel.h into
per-arch directories, and convert interrupt controller singletons
(PlicSingleton, ApicSingleton) into private members of each arch's
Interrupt class, following the existing aarch64 pattern where Gic is
already an Interrupt member.

- Move Pl011Singleton to src/arch/aarch64/include/pl011_singleton.h
- Move SerialSingleton to file-local scope in x86_64/early_console.cpp
- Move Ns16550aSingleton to file-local scope in riscv64/interrupt_main.cpp
- Add Plic plic_ member to riscv64 Interrupt with InitPlic() deferred init
- Add Apic apic_ member to x86_64 Interrupt with InitApic() deferred init
- Move APIC creation from ArchInit() to InterruptInit() (boot order fix)
- Remove arch-specific #includes and #ifdefs from kernel.h

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Since Interrupt is used as etl::singleton (only one instance), static
class members are semantically equivalent to non-static members. Remove
static to eliminate the need for out-of-class definitions in .cpp files.

- aarch64: interrupt_handlers -> interrupt_handlers_ (non-static member)
- riscv64: interrupt_handlers_, exception_handlers_ (drop static + defs)
- x86_64: interrupt_handlers_, idts_ (drop static + defs, keep alignas)

The alignas(4096) on x86_64 members propagates correctly through
etl::singleton via uninitialized_buffer_of<T> which uses
alignas(etl::alignment_of<T>::value) on its storage.

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
…irectories

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
- C1: Add ReapTask(current) for orphan tasks in Exit() to prevent TCB leak
- C2: Start FSM after default-constructing TCB in Clone() to avoid null deref
- I2: Use STATE_ID constant in StateExited::on_event(MsgReap)
- I3: Move GetStatus() implementation from header to .cpp file
- I4: Enqueue idle task in kReady state, then transition to kRunning
- M2: Restore dropped @todo SIGCHLD comment in exit.cpp
- M5: Add [[nodiscard]] attribute to GetStatus()

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
…_router

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
…ification

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
MRNIU and others added 24 commits March 20, 2026 13:05
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
U-Boot's image.h requires openssl/evp.h for FIT image signing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
…uild

OP-TEE's build system requires aarch64-linux-gnu-cpp which was not
symlinked via update-alternatives.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Add kSyscallSchedGetaffinity and kSyscallSchedSetaffinity constants for
all architectures. Add dispatcher cases for sys_kill, sys_sigaction,
sys_sigprocmask, sys_sched_getaffinity, and sys_sched_setaffinity.
Implement sys_kill, sys_sigaction, and sys_sigprocmask function bodies
that delegate to TaskManager signal methods.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
- signal_test: SIGTERM/SIGKILL default, SIG_IGN, sigprocmask, error paths
- affinity_test: get/set affinity syscalls, cross-task, error paths
- tick_test: tick increment, sleep timing, runtime tracking
- zombie_reap_test: zombie reaping, orphan reparenting, multi-child Wait
- stress_test: 20 concurrent tasks, wait non-child, rapid create-exit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
…w clone

- Split single serial job into parallel build-riscv64 + build-aarch64 jobs
- Add dev-image.yml workflow to build/push dev container to GHCR
- Replace devcontainers/ci per-step with container: for shared container
- Use shallow clone (fetch-depth: 1) and shallow submodules (--depth 1)
- Add CMake build cache via actions/cache
- Reduce system test runs to 3 for PRs (10 for push/release)
- Add concurrency group to cancel superseded runs
- Upgrade codecov-action v3->v4, actions-gh-pages v3->v4

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Copilot AI review requested due to automatic review settings March 20, 2026 16:26
MRNIU added 2 commits March 21, 2026 00:28
When running inside a container job, git submodule update fails with
exit code 128 due to directory ownership mismatch (container runs as
root, workspace owned by runner user). Adding safe.directory wildcard
before submodule init resolves this.

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
Copy link

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 addresses CI failures during shallow submodule initialization in containerized GitHub Actions jobs by adding a Git safe.directory configuration, and also includes substantial kernel/runtime updates (scheduler balancing, signals, tests) and removal of x86_64 support across build/docs.

Changes:

  • Update GitHub Actions workflow to run riscv64/aarch64 builds in a container with shallow submodule init and safe.directory config.
  • Add/expand kernel features and correctness fixes: cross-core wakeup, Wait/Exit locking changes, periodic load balancing, basic signal support, and improved memory allocator locking.
  • Expand system/unit tests and remove x86_64-related build presets, tooling, and documentation.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/x86_64_qemu_virt.its.in Remove x86_64 QEMU FIT template tooling.
tools/x86_64_boot_scr.txt Remove x86_64 U-Boot boot script.
tools/README.md Remove x86_64 tooling references.
tools/Dockerfile Remove legacy tools Dockerfile.
tools/.pre-commit-config.yaml.in Adjust commented clang-tidy exclude filters.
tests/unit_test/balance_test.cpp Add unit tests for RR scheduler “steal” primitive.
tests/unit_test/README.md Remove x86_64 unit test documentation entry.
tests/unit_test/CMakeLists.txt Add balance_test.cpp to unit test build.
tests/system_test/yield_test.cpp Add sys_yield system test.
tests/system_test/wait_system_test.cpp Fix PID retrieval after move; rename wait entrypoint.
tests/system_test/tick_test.cpp Add tick/sleep/runtime tracking system tests.
tests/system_test/thread_group_system_test.cpp Use generated PIDs; rename entrypoint; run subtests sequentially.
tests/system_test/system_test.h Rename test function declarations; add new test declarations; update QemuExit behavior.
tests/system_test/stress_test.cpp Add basic stress system tests (many tasks/wait/rapid exit).
tests/system_test/spinlock_test.cpp Improve barrier loop ordering; change timeout behavior.
tests/system_test/ramfs_system_test.cpp Rename ramfs test entrypoint and logs/messages.
tests/system_test/main.cpp Expand test registry; fix PID capture after AddTask; runner reaping logic; add atomic boot guard.
tests/system_test/fork_test.cpp Add fork-related system tests.
tests/system_test/exit_system_test.cpp Use local PID counter; rename exit entrypoint; adjust thread/zombie scenarios.
tests/system_test/ctor_dtor_test.cpp Remove aarch64 FPU setup call from ctor/dtor test.
tests/system_test/clone_system_test.cpp Capture child PIDs correctly; reap children to avoid runner accounting issues; rename entrypoint.
tests/system_test/balance_test.cpp Add Balance() behavior system tests (migration + affinity).
tests/system_test/affinity_test.cpp Add sched_get/setaffinity system tests.
tests/system_test/CMakeLists.txt Rename system test sources; add many new system test sources; remove x86_64 QEMU flags.
tests/integration_test/aarch64_minimal/main.cpp Update brief; remove custom FPU setup.
tests/integration_test/CMakeLists.txt Remove x86_64-specific boot flags/subdirs.
tests/AGENTS.md Update unit test command docs to build_{arch}.
src/task/wakeup.cpp Refactor Wakeup to accept CpuSchedData; implement cross-core Wakeup/WakeupOne.
src/task/wait.cpp Change lock ordering; add atomic block-with-locks to prevent lost wakeups; return ECHILD-like error.
src/task/tick_update.cpp Call Balance() periodically (every 64 ticks).
src/task/task_manager.cpp Implement Balance() work-stealing for kNormal tasks.
src/task/sleep.cpp Check pending signals after sleep returns.
src/task/signal.cpp Add basic signal mechanisms (pending/mask/actions) and delivery logic.
src/task/schedule.cpp Introduce kernel_thread_bootstrap; set scheduler_started after taking lock.
src/task/mutex.cpp Add fast path; prevent lost wakeups by blocking under scheduler lock; WakeupOne on unlock.
src/task/include/task_manager.hpp Add signal APIs; add overloads for Block/Wakeup with CpuSchedData; add WakeupOne.
src/task/include/task_fsm.hpp Add cached atomic state id to allow thread-safe state reads.
src/task/include/task_control_block.hpp Add per-task SignalState storage.
src/task/include/scheduler_base.hpp Declare kernel_thread_bootstrap for asm entry stubs.
src/task/exit.cpp Move Wakeup out of scheduler lock; restructure leader reparenting timing.
src/task/block.cpp Split Block into locked/unlocked variants; enforce capacity check before blocking.
src/task/CMakeLists.txt Add signal.cpp to build.
src/task/AGENTS.md Update docs to reflect Balance() implemented.
src/syscall.cpp Dispatch + implement sys_kill/sys_sigaction/sys_sigprocmask.
src/memory/memory.cpp Add bmalloc lock implementation for thread-safety.
src/memory/include/virtual_memory.hpp Update doc to reflect supported arch list.
src/main.cpp Remove demo tasks; add atomic boot guard for SMP entry.
src/libc/sk_stdlib.c Remove x86_64/SSE path for strtod.
src/libc/include/sk_stdlib.h Remove x86_64/SSE path for strtod declarations.
src/include/syscall.hpp Add syscall numbers and declarations for signal + affinity syscalls; drop x86_64 syscall ids.
src/include/signal.hpp Add signal types/constants/state helpers/default actions.
src/include/kernel_config.hpp Increase task/scheduler/map capacities.
src/include/interrupt_base.h Update docs to remove x86_64/APIC references.
src/include/expected.hpp Remove APIC error codes; add signal error codes and messages.
src/filesystem/vfs/open.cpp Call FileOps::Open during VFS open to prepare backend handle.
src/filesystem/vfs/include/vfs_types.hpp Add default virtual FileOps::Open; comment cleanups.
src/filesystem/fatfs/include/fatfs.hpp Declare FatFsFileOps::Open override.
src/filesystem/fatfs/fatfs.cpp Handle FR_EXIST for mkdir; implement FatFS file Open hook.
src/arch/x86_64/timer.cpp Remove x86_64 timer stub.
src/arch/x86_64/syscall.cpp Remove x86_64 syscall stub.
src/arch/x86_64/switch.S Remove x86_64 switch stub.
src/arch/x86_64/macro.S Remove x86_64 macro stub.
src/arch/x86_64/interrupt_main.cpp Remove x86_64 interrupt init implementation.
src/arch/x86_64/interrupt.cpp Remove x86_64 interrupt implementation.
src/arch/x86_64/interrupt.S Remove x86_64 interrupt asm stub.
src/arch/x86_64/include/sipi.h Remove SIPI header.
src/arch/x86_64/include/interrupt.h Remove x86_64 interrupt header.
src/arch/x86_64/early_console.cpp Remove x86_64 early console.
src/arch/x86_64/boot.S Remove x86_64 boot code.
src/arch/x86_64/backtrace.cpp Remove x86_64 backtrace.
src/arch/x86_64/arch_main.cpp Remove x86_64 arch init.
src/arch/x86_64/apic/io_apic.cpp Remove x86_64 IO APIC driver.
src/arch/x86_64/apic/include/io_apic.h Remove x86_64 IO APIC header.
src/arch/x86_64/apic/include/apic.h Remove x86_64 APIC header.
src/arch/x86_64/apic/apic.cpp Remove x86_64 APIC implementation.
src/arch/x86_64/apic/README.md Remove x86_64 APIC docs.
src/arch/x86_64/apic/CMakeLists.txt Remove APIC subdir build config.
src/arch/riscv64/timer.cpp Deliver pending signals during timer tick handling.
src/arch/riscv64/switch.S Route kernel thread entry through kernel_thread_bootstrap.
src/arch/riscv64/macro.S Reduce saved context footprint (remove FP saves); adjust offsets.
src/arch/riscv64/link.ld Comment cleanup in linker script.
src/arch/riscv64/interrupt.S Fix offsets for sstatus.SPP check after context layout change.
src/arch/aarch64/timer.cpp Deliver pending signals during timer tick handling.
src/arch/aarch64/switch.S Route kernel thread entry through kernel_thread_bootstrap.
src/arch/aarch64/macro.S Reduce saved context footprint (remove SIMD/FP saves); adjust offsets.
src/arch/aarch64/link.ld Comment cleanup in linker script.
src/arch/aarch64/interrupt_main.cpp Ignore spurious INTIDs (>=1020) early.
src/arch/aarch64/interrupt.cpp Change EOIR write ordering relative to handler dispatch.
src/arch/aarch64/interrupt.S Fix offsets used when checking return-to-user and restoring ttbr0_el1.
src/arch/README.md Update docs to reflect only riscv64/aarch64 supported.
src/arch/CMakeLists.txt Remove x86_64 arch subdir integration.
src/arch/AGENTS.md Update docs to remove x86_64 references.
src/CMakeLists.txt Remove x86_64 QEMU flags.
docs/docker.md Update examples from x86_64 to riscv64; adjust QEMU/tool notes.
cmake/x86_64-gcc.cmake Remove x86_64 toolchain file.
cmake/functions.cmake Ensure /srv/tftp exists before linking artifacts.
cmake/compile_config.cmake Remove x86_64 compile/link options.
cmake/3rd.cmake Remove x86_64 U-Boot defconfig.
README_ENG.md Update docs to remove x86_64 references.
README.md Update docs to remove x86_64 references.
CMakePresets.json Remove x86_64 preset; tweak QEMU flags/device; remove debug “int” logging.
AGENTS.md Update top-level docs to remove x86_64 preset references.
3rd/cpu_io Update cpu_io submodule revision.
.gitignore Ignore .claude.
.github/workflows/workflow.yml Split into riscv64/aarch64 jobs in container; add shallow submodule init and safe.directory config; publish docs via artifact.
.github/workflows/dev-image.yml Add workflow to build/push devcontainer image to GHCR.
.devcontainer/devcontainer.json Remove x86_64 assembly extension recommendation.
.devcontainer/Dockerfile Update tool packages; remove qemu-system-x86 and x86_64 cross toolchain; ensure /srv/tftp exists.
Comments suppressed due to low confidence (2)

tests/system_test/main.cpp:1

  • Same issue as in src/main.cpp: test_and_set(memory_order_acquire) doesn't provide release semantics to publish initialization to secondary cores. Use memory_order_acq_rel (or an explicit release/acquire pairing) to avoid subtle SMP startup races in the system test binary.
    src/task/task_manager.cpp:1
  • GetQueueSize() is called across cores without holding the corresponding cpu_sched.lock. If the underlying ready queue size is not atomic/thread-safe, this is a data race (UB) even if used heuristically. A safer approach is to either (1) take the per-core lock before reading queue size, or (2) maintain an atomic per-core load counter updated under the lock and read atomically here.

Comment on lines +36 to +37
git config --global --add safe.directory '*'
git submodule update --init --recursive --depth 1
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

git config --global --add safe.directory '*' disables Git's ownership safety checks for all directories inside the container, which is overly broad for CI and can mask genuine repo ownership issues. Prefer adding only the workspace + submodule directories (e.g., add $GITHUB_WORKSPACE and each submodule path via git submodule foreach --recursive ...) so the safety bypass is scoped to the checkout.

Suggested change
git config --global --add safe.directory '*'
git submodule update --init --recursive --depth 1
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git submodule update --init --recursive --depth 1
git submodule foreach --recursive 'git config --global --add safe.directory "$PWD"'

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 3
# Copyright The SimpleKernel Contributors

name: build
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

The PR title/description focuses on a CI safe.directory fix for submodule checkout, but the diff includes large functional changes (scheduler balancing, signals, VFS open behavior, test expansion, and removal of x86_64 support). This makes the change hard to review/rollback and increases risk; consider splitting into focused PRs (CI-only vs kernel features vs arch support removal).

Copilot uses AI. Check for mistakes.
Comment on lines 64 to 65
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

EOI is being written before running the handler. On GICv3, signaling EOI early can allow the interrupt to be considered complete while the handler still runs, potentially enabling re-entrancy/priority issues and breaking device protocols. Write EOIR after the handler completes (and if the design requires it, also consider the required DIR write for deactivation, depending on your GIC configuration).

Suggested change
interrupt_handlers_[cause](cause, context);
cpu_io::ICC_EOIR1_EL1::Write(cause);

Copilot uses AI. Check for mistakes.
The riscv64 system test step only checked the cmake exit code, which
is always 0 even when individual tests fail inside QEMU. Align with
the aarch64 approach: capture output to file, grep for "Failed: 0"
to determine pass/fail.

Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
@MRNIU MRNIU merged commit 2826e7c into Simple-XX:main Mar 20, 2026
2 of 4 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.

2 participants