{bp-19559} arch/x86_64: six fixes to make BUILD_KERNEL and the HPET alarm work - #19653
Merged
Conversation
ARCH_INTEL64_HPET_ALARM is one of the three members of the "System Timer
Source" choice, but selecting it does not build. Taking qemu-intel64:nsh on
master and moving the choice off ARCH_INTEL64_TSC_DEADLINE onto it:
intel64/intel64_hpet_alarm.c:41:24: error:
'CONFIG_ARCH_INTEL64_HPET_ALARM_CHAN' undeclared
ARCH_INTEL64_HPET_ALARM_CHAN lives inside "if INTEL64_HPET" and nothing
selects INTEL64_HPET. Enabling that by hand moves the failure to link time,
because intel64_oneshot_lower.c is built only when INTEL64_ONESHOT is set:
undefined reference to `oneshot_initialize'
Enabling INTEL64_ONESHOT as well finally reaches the real problem.
intel64_oneshot_lower.c implements the counter flavour of struct
oneshot_operations_s, which exists only with ONESHOT_COUNT:
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'
intel64_oneshot_lower.c: error: initialization of
'int (*)(struct oneshot_lowerhalf_s *, const struct timespec *)' from
incompatible pointer type ... (four more of these)
ONESHOT, ONESHOT_COUNT and ONESHOT_FAST_DIVISION were selected by
ARCH_INTEL64_TSC_DEADLINE and by nothing else, so the other members of the
same choice could never be built.
Select the four from ARCH_INTEL64_HPET_ALARM as well. INTEL64_ONESHOT
selects INTEL64_HPET in turn, which is what brings
ARCH_INTEL64_HPET_ALARM_CHAN into existence, so one added select closes all
three stages.
Impact: build only, and only for a configuration that could not be built
before. No existing defconfig selects ARCH_INTEL64_HPET_ALARM.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
g_x86_64_timer_freq is assigned only under ARCH_INTEL64_TSC_DEADLINE or ARCH_INTEL64_TSC, and is read only by the two intel64_tsc_*.c files those options build. With the HPET as the system clock it stays 0, which is correct and harmless -- but x86_64_timer_calibrate_freq() panics on 0 unconditionally, so the board dies during x86_64_lowsetup(). Require a frequency only where something needs one, which is ARCH_INTEL64_HAVE_TSC. The failure mode is worth recording, because it gives nothing to work from: the PANIC() happens before x86_64_earlyserialinit(), and the panic handler itself then triple-faults, because _assert() reads up_interrupt_context() -- a %gs-relative load -- and the GS base is not programmed until x86_64_cpu_priv_set(). The console stays completely empty and the machine resets. Impact: runtime, ARCH_INTEL64_HPET_ALARM only. Configurations with a TSC are unchanged -- the PANIC() is still compiled for them. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
794c325 ("arch/x64:Syscall support is enabled by default", 2025-05-27) changed nine guards from CONFIG_LIB_SYSCALL to CONFIG_ARCH_HAVE_SYSCALL but never added the Kconfig symbol. Only ARCH_HAVE_SYSCALL_HOOKS exists in tree; ARCH_HAVE_SYSCALL itself is defined nowhere, so it is always unset and since that commit x86_64 has had no x86_64_syscall_entry(), no x86_64_syscall(), no IA32_LSTAR/IA32_STAR programming and no syscall stub layer in any configuration: arch/x86_64/src/common/Make.defs:37 x86_64_syscall.c not compiled arch/x86_64/src/common/CMakeLists.txt:41 likewise arch/x86_64/include/irq.h:86 arch/x86_64/src/intel64/intel64_cpu.c:247, :386 arch/x86_64/src/intel64/intel64_head.S:83, :351, :538 arch/x86_64/src/intel64/intel64_saveusercontext.S:108 qemu-intel64:knsh_romfs and qemu-intel64:knsh_romfs_pci are the two CONFIG_BUILD_KERNEL configurations in tree, and neither can have worked in that time. They still link -- nothing references the missing pieces, so libstubs.a is simply never pulled in -- and then die the first time user code executes SYSCALL. Define the symbol with the condition the code had before that commit, which is LIB_SYSCALL: every protected and every kernel build needs the interface, and a flat build is left exactly as it is today. Impact: restores the system call interface for CONFIG_BUILD_KERNEL and CONFIG_BUILD_PROTECTED on x86_64. CONFIG_BUILD_FLAT is unaffected -- qemu-intel64:nsh still builds with ARCH_HAVE_SYSCALL unset. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
mm_pginitialize() documents heap_start as "the physical address of the start of memory region", and every x86_64 consumer of mm_pgalloc() agrees: create_spgtables(), x86_64_get_pgtable() and up_addrenv_create() all put the result through x86_64_pgvaddr() before touching it. x86_64_pgvaddr() in turn range-checks against CONFIG_ARCH_PGPOOL_PBASE (arch/x86_64/src/common/ pgalloc.h:67). arm64's equivalent passes CONFIG_ARCH_PGPOOL_PBASE. up_allocate_pgheap() passed CONFIG_ARCH_PGPOOL_VBASE instead, and in the other branch X86_64_PGPOOL_BASE + X86_64_LOAD_OFFSET, which is the same mistake spelled out. Every page handed out was therefore a virtual address that fell outside the pool's physical window, x86_64_pgvaddr() returned 0, and the first x86_64_pgwipe() memset NULL. It presents as a page fault in memset() under create_spgtables() the first time a process address environment is created, which is loading the init program. qemu-intel64:knsh_romfs sets PGPOOL_PBASE=0x00c000000 and PGPOOL_VBASE=0x10c000000, so the value passed was off by the 4GB load offset. Impact: runtime, CONFIG_ARCH_ADDRENV builds only (CONFIG_MM_PGALLOC). Assisted-by: Claude:claude-opus-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
…ronment. copy_kernel_mappings() copies exactly one PDPT entry, the 1GB linear window that maps physical 0-1GB at 4GB-5GB. The boot identity mapping of the low 4GB, which lives in PDPT entries 0-3 of g_pdpt_low (intel64_head.S:756, one page directory per 1GB) and is where every MMIO register is reached, is not carried over. A kernel thread never gets an address environment of its own and addrenv_switch() leaves the last one in place for it, so as soon as any process exists, kernel code touching MMIO faults. The HPET at 0xfed00000 finds it immediately -- CR2=fed000f0, in intel64_hpet_getreg() under clock_systime_ticks() on the lpwork thread -- and any MMIO driver would. Inherit the four boot PDPT entries. They point at the boot page directories rather than at copies, so anything intel64_map_region() adds later is inherited too, and they carry no X86_PAGE_USER, so user code still cannot reach them. Impact: runtime, CONFIG_ARCH_ADDRENV builds only. User-space access is unchanged; the entries added are supervisor-only. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
intel64_timer_start_absolute() computed "expected - current_us" unsigned. A watchdog started with a delay of zero asks for a deadline that is already current, the subtraction wraps to nearly 2^64, and the comparator is set so far ahead that the timer never fires. The CONFIG_INTEL64_HPET_MIN_DELAY clamp in intel64_oneshot_start() cannot help: the wrapped value is enormous, not small. Ask for the shortest delay the hardware can take instead of wrapping, and let that existing minimum-delay logic pick it. It presents as ostest hanging in wdog_test with no output and no fault. apps/testing/ostest/wdog.c:281 calls wdtest_once(&test_wdog, param, 0), and NSEC2TICK() takes the next few delays (1ns, 10ns, ...) to zero ticks as well; wdtest_once() then spins forever in its "wait until the callback is triggered exactly once" loop. Impact: runtime, ARCH_INTEL64_HPET_ALARM only. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
jerpelea
requested review from
acassis,
cederom,
linguini1,
lupyuen and
xiaoxiang781216
August 3, 2026 10:59
cederom
approved these changes
Aug 3, 2026
acassis
approved these changes
Aug 3, 2026
xiaoxiang781216
approved these changes
Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Six independent x86_64 bugs. Each is a separate commit; together they are what
| 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 HPEThad to be fixed before an x86_64 target could be built and run at all.
There is a reason there are six of them, and it is bug 3:
CONFIG_BUILD_KERNELon 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.
Impact
RELEASE
Testing
CI