boards/qemu-intel64: add citest configuration - #20030
Open
raiden00pl wants to merge 12 commits into
Open
Conversation
xiaoxiang781216
previously approved these changes
Sep 1, 2026
|
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
4 times, most recently
from
September 2, 2026 06:41
08f275e to
75606b3
Compare
xiaoxiang781216
previously approved these changes
Sep 2, 2026
Member
Author
|
CI container uses old QEMU version that doens't support x2APIC, so we need this PR to run it #20044 |
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
2 times, most recently
from
September 2, 2026 10:27
df4246b to
bcf65ba
Compare
xiaoxiang781216
previously approved these changes
Sep 2, 2026
xiaoxiang781216
approved these changes
Sep 2, 2026
Contributor
|
@raiden00pl please take a look: At the end of the log there is also a Warning about CPython and gcc support to qemu |
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
from
September 7, 2026 06:09
9c86a2f to
4ef0e89
Compare
xiaoxiang781216
previously approved these changes
Sep 7, 2026
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
from
September 7, 2026 12:46
e5cd15d to
a1ebb30
Compare
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
2 times, most recently
from
September 7, 2026 19:15
adc6c86 to
aa43481
Compare
| /* Send while we still have data in the TX buffer & room in the fifo. | ||
| * | ||
| * uart_putxmitchar() advances xmit.head from thread context without | ||
| * holding the critical section, so on SMP it can move (and wrap) while |
Contributor
There was a problem hiding this comment.
but the critical section is held at line 63
Member
Author
There was a problem hiding this comment.
the producer writes head outside any lock. This ring is a single-producer/single-consumer ring:
Lines 279 to 286 in 35e8eeb
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
4 times, most recently
from
September 8, 2026 14:09
95727ab to
c6dd1a3
Compare
CI/NTFC testing config for intel64 Signed-off-by: raiden00pl <raiden00@railab.me>
intel64_oneshot_start() takes g_oneshot_spin and then, if the timer is already running, calls intel64_oneshot_cancel(), which takes the same spinlock again. Spinlocks are not recursive, so the CPU spins forever on its own lock while holding the critical section; the HPET timer ISR on another CPU then blocks on g_cpu_irqlock and the system hangs. This is hit as soon as the tickless scheduler re-arms a running HPET oneshot timer under SMP (ostest task_restart, LTP aio tests). Stop the running timer inline instead of calling cancel: disable the interrupt, detach the ISR so up_enable_irq() does not assert on a busy IRQ, and clear the running flag. The ISR, comparator and interrupt enable are reprogrammed by the rest of the function anyway. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
work_cancel() used to return -ENOENT when the work structure was not in the queue, and callers depend on that: aio_cancel() tears down the AIO container (file_put() + aioc_free()) only when work_cancel() reports success, because a work item that is not queued may already be executing on a worker thread (see the comment in fs/aio/aio_cancel.c). Since commit 6f72f54 ("sched/wqueue: Refactor delayed and periodical workqueue") work_cancel() returns OK unconditionally, and commit d2e01b9 ("sched/wqueue: harden custom queue lifecycle") kept that behaviour and dropped -ENOENT from the function documentation. Under SMP the LTP aio_cancel tests then free the aio container and its file while the lpwork thread is still executing aio_write_worker() on it, which ends in a page fault in file_write() (f_inode == NULL) and a panic. Return -ENOENT again when the work is not queued, and document it. For the synchronous variant "not queued" alone does not tell whether the callback is running: the worker scan does, so report OK when a running callback was found and waited for, and -ENOENT only when the work was neither queued nor running. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
fix nxstyle issues in intel64_hpet.c Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
intel64_hpet_setisr() with a NULL handler detached the ISR with irq_attach(irq, NULL), which installs irq_unexpected_isr(). The oneshot driver does this every time the timer expires or is re-armed, so an HPET interrupt already in flight to another CPU lands on the unexpected ISR and panics the system: irq_unexpected_isr: ERROR irq: 34 seen under SMP with the LTP test suite. Just mask the interrupt and keep the ISR attached; intel64_oneshot_handler() already treats an interrupt that arrives while the timer is not running as spurious. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
fix nxstyle issues in lio_listio.c Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
lio_listio(LIO_NOWAIT) submits the requests first and only afterwards installs the SIGPOLL handler and attaches the per-request private data in lio_sigsetup(). Under SMP the requests complete on the low priority work queue while this is going on, and aio_signal() queues SIGPOLL for each of them as it finishes: - A signal delivered for a request that lio_sigsetup() found already finished (aio_priv left NULL) made lio_sighandler() dereference a NULL private pointer (LTP lio_listio 10-1, 15-1, 2-1 crash with a page fault in lio_sighandler on qemu-intel64 SMP). - A signal delivered between the aio_result check and the aio_priv store of the last outstanding request was consumed without private data, no later signal arrived, and the caller was never notified. - If every request had completed by the time the loop ran, no handler invocation could ever see the private data and the caller hung. - After the completing handler had notified the caller, signals still queued for other requests ran the handler again with their own copy of the private data. Block SIGPOLL while the handler is installed and the private data is attached, so that the completion signals are delivered only once every entry is set up. Ignore a signal for a request without private data, notify the caller directly from lio_sigsetup() when everything had already completed, and detach the private data of every entry once the list is done so that late signals find nothing to do. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
The "cancel everything on this descriptor" loop in aio_cancel() only moved to the next container inside the branch taken when work_cancel() succeeded. When work_cancel() reports -ENOENT because a worker thread is already executing the request, the loop restarted its search from the same container and spun forever, hanging the task (and, since the scan runs with interrupts enabled but never yields, that CPU) without any output. This was hit by the LTP aio_cancel tests on SMP. Capture the next container before calling work_cancel() so the loop always makes progress. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
uart_putxmitchar() advances xmit.head from thread context without holding the critical section, so on SMP the head index can move, and wrap around, while uart_xmitchars() runs in the TX interrupt on another CPU. Since commit b319c27 ("serial: Added APIs for receiving and sending multiple chars") the sendbuf path of uart_xmitchars() reads xmit.head twice: once to decide whether the pending data is contiguous and again to compute its length. If the producer wraps the index in between, the computed length goes negative, is passed to sendbuf() as a huge size_t and the driver transmits memory far beyond the ring buffer. The per-byte path reads the index only once and is not affected, which is why this went unnoticed: the batch path is only used by drivers that implement sendbuf, and the 16550 driver gained it in commit 45c38d8 ("drivers/serial/16550: add polling mode support for serial drivers"). qemu-intel64 with SMP is the first configuration combining a sendbuf driver with a producer running on another CPU. On qemu-intel64 SMP this shows up as an endless stream of NUL bytes on the console (captured with gdb: head = 1, tail = 8, size = 16, and u16550_sendbuf() called with size = (size_t)-7), which makes the ntfc test harness fail every test that runs while the flood lasts. Read the head index once per loop iteration and use that snapshot for both the contiguity test and the length. The producer only ever moves the index forward, so a stale snapshot merely sends less now. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
Same issue as the previous commit, on the receive side: uart_read() advances recv.tail from thread context without holding the critical section, but the recvbuf batch path of uart_recvchars() reads recv.tail several times (the full check, the watermark count and the free-space computation). If uart_read() moves and wraps the index in between, the computed free space goes negative and is passed to recvbuf() as a huge size_t, which lets the driver store past the end of the ring buffer. Read recv.tail once per loop iteration and derive everything from that snapshot. The consumer only ever moves the index forward, so a stale snapshot merely stores less now. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
intel64_oneshot_handler() cleared oneshot->handler and oneshot->arg after picking them up, without holding g_oneshot_spin, while intel64_oneshot_start() re-arms the timer under that lock from another CPU. Now that the HPET ISR stays attached across a re-arm, a stale interrupt can interleave with start(): it reads the freshly installed handler, clears it, and start() then sets running = true again, so the genuine expiry that follows finds running == true with a NULL handler and jumps to address zero from interrupt context (page fault at RIP 0 in the CPU0 IDLE task while the LTP lio_listio tests were running), or the alarm is simply lost and the tickless system stops. The handler and its argument are owned by start() and cancel(); the ISR only needs to read them. Leave them alone in the ISR and skip the call if none is installed. The remaining effect of a stale interrupt is an early invocation of the alarm callback, which is harmless: the tickless scheduler re-evaluates its expirations and re-arms the timer. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
The aio worker functions started by decanting the container, which frees the container back to the pool and drops the file reference, and only then performed the I/O through the aiocb. Nothing was holding the file open while the read/write/fsync was in progress, and the request was no longer on the pending list, so a concurrent close() or aio_cancel() could pull the file from under the running operation. Keep the container until the operation has completed and decant it just before signalling completion. Assisted-by: Claude Code Signed-off-by: raiden00pl <raiden00@railab.me>
raiden00pl
force-pushed
the
nuttx-qemu-pr
branch
from
September 8, 2026 14:11
c6dd1a3 to
c6fe98d
Compare
This was referenced Sep 9, 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
CI/NTFC testing config for intel64
Impact
CI tests for intel64
Testing
CI