casaroli opened a new pull request, #19559:
URL: https://github.com/apache/nuttx/pull/19559
## Summary
Six independent x86_64 bugs. Each is a separate commit; together they are
what
had to be fixed before an x86_64 target could be built and run at all.
| | Commit | Area | What it breaks |
|---|---|---|---|
| 1 | `make ARCH_INTEL64_HPET_ALARM buildable` | Kconfig | anything
selecting the HPET |
| 2 | `do not demand a TSC frequency for a clock that has none` | boot |
anything selecting the HPET |
| 3 | `define the missing CONFIG_ARCH_HAVE_SYSCALL` | Kconfig |
`knsh_romfs`, `knsh_romfs_pci` |
| 4 | `give the page allocator the physical page pool base` | addrenv |
`knsh_romfs`, `knsh_romfs_pci` |
| 5 | `inherit the kernel low memory mapping in an address environment` |
addrenv | `knsh_romfs`, `knsh_romfs_pci` |
| 6 | `do not wrap the HPET oneshot on a deadline that has passed` | timer |
anything selecting the HPET |
There is a reason there are six of them, and it is bug 3:
`CONFIG_BUILD_KERNEL`
on x86_64 has been unbuildable since May 2025, so nothing behind it has been
exercised in a year, and the HPET alarm looks like it has never been
exercised
at all.
## Why these are reachable from master alone
**Two in-tree configurations are affected directly.**
`qemu-intel64:knsh_romfs`
and `qemu-intel64:knsh_romfs_pci` are the only `CONFIG_BUILD_KERNEL`
configurations in tree. Bugs 3, 4 and 5 each independently stop them from
reaching a shell prompt.
**Bug 3 dates the problem.** 794c325947 ("arch/x64:Syscall support is
enabled by
default", 2025-05-27) switched nine guards from `CONFIG_LIB_SYSCALL` to
`CONFIG_ARCH_HAVE_SYSCALL` without adding the Kconfig symbol. `git grep`
finds
only `ARCH_HAVE_SYSCALL_HOOKS`; the bare symbol is defined nowhere in tree,
so
it is always unset and `x86_64_syscall.c` has not been compiled since — see
`arch/x86_64/src/common/Make.defs:37` and `CMakeLists.txt:41`. Those two
configurations still *link*, because nothing references the missing pieces
and
`libstubs.a` is simply never pulled in, and then die the first time user code
executes `SYSCALL`.
**The HPET path looks like it has never been exercised.** No defconfig in
tree
selects `ARCH_INTEL64_HPET_ALARM`, yet the board code supports it
(`boards/x86_64/qemu/qemu-intel64/src/qemu_bringup.c:55`). Selecting it does
not
compile (bug 1); with that fixed the board panics in `x86_64_lowsetup()`
(bug 2);
with that fixed ostest hangs in `wdog_test` (bug 6).
## Impact
No API, ABI or defconfig change. Bugs 1, 2 and 6 affect only
`ARCH_INTEL64_HPET_ALARM`, which nothing in tree selects today. Bugs 4 and 5
affect only `CONFIG_ARCH_ADDRENV` builds. Bug 3 restores the system call
interface for `CONFIG_BUILD_KERNEL` and `CONFIG_BUILD_PROTECTED` and leaves
`CONFIG_BUILD_FLAT` exactly as it is — `qemu-intel64:nsh` still builds with
`ARCH_HAVE_SYSCALL` unset.
## Dependencies
Needs `nuttx-apps` ≥ 57e761f72 ("build: Omit default priority ELF symbol.",
already merged) to run ostest under `CONFIG_BUILD_KERNEL`. Without it the ELF
loader creates programs that declare `PRIORITY = SCHED_PRIORITY_DEFAULT` at
priority 0, and `qemu-intel64:knsh_romfs` trips
`Assertion failed sched_priority >= 1` at `sched/sched/sched.h:466` before
ostest starts. That is a separate, architecture-independent bug and it is
already fixed on the apps side.
## Testing
**Host:** macOS 26.5.1 on Apple Silicon (arm64), `x86_64-elf-gcc` 16.1.0,
`qemu-system-x86_64` 11.0.3 under TCG — there is no hardware x86
virtualisation
on this host.
```
qemu-system-x86_64 -machine pc,hpet=on -cpu max -m 2G \
-kernel ./nuttx -nographic -no-reboot -net none
```
Three config tweaks are applied to both configurations. None is related to
this
patch set:
* `ARCH_INTEL64_HAVE_PCID=n`, `ARCH_INTEL64_TSC_DEADLINE=n` →
`ARCH_INTEL64_HPET_ALARM=y`. TCG implements neither PCID nor the
TSC-deadline
timer, and `x86_64_check_and_enable_capability()` halts if a requested
feature
is missing. This is *why* the HPET path got exercised, and hence why bugs
1, 2
and 6 were found.
* `SCHED_THREAD_LOCAL=n` — broken on x86_64 on unmodified master, see the
note
at the end. It is off by default in both defconfigs.
### Before
**Bug 1**, stock master, `qemu-intel64:nsh` with the choice moved to the
HPET.
Three stages, each uncovered by fixing the previous one by hand:
```
# ARCH_INTEL64_HPET_ALARM=y
intel64/intel64_hpet_alarm.c:41:24: error:
'CONFIG_ARCH_INTEL64_HPET_ALARM_CHAN' undeclared
# + INTEL64_HPET=y
undefined reference to `oneshot_initialize'
# + INTEL64_ONESHOT=y
intel64_oneshot_lower.c: error: 'const struct oneshot_operations_s' has no
member named 'start_absolute'
intel64_oneshot_lower.c: error: implicit declaration of function
'oneshot_count_init'
(plus four incompatible-pointer-type errors on the ops table)
```
One added `select` closes all three stages, because `INTEL64_ONESHOT` selects
`INTEL64_HPET` in turn.
**Bug 6**, all fixes applied except commit 6, `qemu-intel64:nsh`. ostest
reaches
the wdog test and never returns; killed at a 300 s timeout:
```
user_main: spinlock test
user_main: wdog test
wdtest_once 0 ns
wdtest_once 1 ns
wdtest_once 0 ns
wdtest_once 0 ns
wdtest_once 0 ns
<- nothing further, 300s
```
`apps/testing/ostest/wdog.c:281` asks for a zero delay, `NSEC2TICK()` takes
the
next few (1 ns, 10 ns) to zero ticks as well, and `wdog_test` runs on several
threads, which is why the same line repeats.
Bugs 2, 4 and 5 have no "before" log to show: each stops the machine before
or
during `x86_64_earlyserialinit()`, or triple-faults out of the panic
handler, so
the console stays empty. See the note at the end.
### After
Both configurations, stock `nuttx-apps` master (57e761f72), nothing but these
six commits on top of master.
`qemu-intel64:knsh_romfs` (`CONFIG_BUILD_KERNEL`), ostest loaded from ROMFS:
```
boot -> prompt 0.09s
typed 19 chars 0.03s
command 71.54s
Exiting with status 0
```
`qemu-intel64:nsh` (`CONFIG_BUILD_FLAT`) — the configuration that actually
runs
`wdog_test`, since `ostest_main.c:569` is inside `#ifdef CONFIG_BUILD_FLAT`:
```
boot -> prompt 0.06s
typed 7 chars 0.01s
command 155.79s
Exiting with status 0
```
with the zero-delay watchdog now completing:
```
user_main: wdog test
wdtest_once 0 ns
wdtest_once 1 ns
wdtest_once 10 ns
wdtest_once 100 ns
wdtest_once 1000 ns
wdtest_once 10000 ns
wdtest_once 100000 ns
wdtest_once 1000000 ns
```
`tools/checkpatch.sh -g <commit>` is clean on all six.
## Two problems seen and not fixed here
**Any `PANIC()` before `x86_64_cpu_priv_set(0)` cannot be reported.**
`_assert()`
reads `up_interrupt_context()`, which is `movb %gs:6, ...`, and the GS base
is
not programmed until the second-to-last step of `__nxstart()`. The page
fault at
linear address 6 then double- and triple-faults, so the machine resets with a
completely empty console. Bugs 2, 3 and 4 all presented this way and had to
be
found by attaching gdb to QEMU and reading `RIP`.
**`CONFIG_SCHED_THREAD_LOCAL` is broken on x86_64.**
`sched_thread_local_test()` reads a `__thread` variable, the thread pointer
at
`%fs:0` reads back as 0, the access faults at linear address -8, and the CPU
triple-faults out of the panic handler as above. Reproduces on unmodified
master.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]