commit 881c6377d4b550f742935f30340d6a2fc92426f0 from: lex0de date: Mon Aug 31 17:31:45 2026 UTC Fix duplicate shell input delivery commit - 11244300a5210268239c9b0962a5886da0a15d0a commit + 881c6377d4b550f742935f30340d6a2fc92426f0 blob - 345b414e121360deb8d2863df854cf784d8336f7 blob + d2f8c1fdb899a833e10af3bccfc4d275b6f63e82 --- changelog.md +++ changelog.md @@ -11,6 +11,7 @@ - Fixed x86_64 timer and IPI interrupt returns overwriting the restored `%rax` register before `iretq`, which caused intermittent user-mode faults during service startup. - Made scheduler block, wake, and timed-sleep transitions atomic with interrupt state, preventing lost wakeups and invalid task-state transitions. - Updated blockd to poll one representative portal because portals owned by one task share the same mailbox, preventing duplicate readiness handling. +- Fixed shell input executing one command late by removing the raw serial stdin fallback and duplicate architecture receive rings. Interactive input now reaches tasks only through the console line discipline and PTY mailbox. - Verified the Clang 21.1.8 Mercuron build, six x86_64 UEFI boots to the shell, and one legacy boot to the shell. The SMP test build completes, but the existing AP trampoline startup still blocks SMP boot before userland. # 2025-12-09 blob - 86a959ebb7aef8409e867a903c6982f9f5e63562 blob + d62639eb01a80c90d20f0aae4b00aa755c0aa206 --- kernel/arch/arm64/serial.c +++ kernel/arch/arm64/serial.c @@ -6,11 +6,6 @@ #include "log/printk.h" #include "console/line.h" -#define SERIAL_RX_BUFSZ 256 -static volatile char serial_rx_buf[SERIAL_RX_BUFSZ]; -static volatile unsigned int serial_rx_head; -static volatile unsigned int serial_rx_tail; - #define PL011_BASE 0x09000000UL #define PL011_DR 0x000 #define PL011_FR 0x018 @@ -39,15 +34,10 @@ uart_read(uintptr_t reg) } static void -serial_buffer_push(char c) +serial_receive_char(char c) { - unsigned int next = (serial_rx_head + 1U) % SERIAL_RX_BUFSZ; static int serial_rx_debug; - if (next == serial_rx_tail) - return; - serial_rx_buf[serial_rx_head] = c; - serial_rx_head = next; if (serial_rx_debug < 8) { const char hex[] = "0123456789abcdef"; char buf[3]; @@ -117,21 +107,11 @@ serial_write(const char *s, size_t n) serial_putc(s[i]); } -int -serial_getc_nonblock(char *c) -{ - if (serial_rx_head == serial_rx_tail) - return 0; - *c = serial_rx_buf[serial_rx_tail]; - serial_rx_tail = (serial_rx_tail + 1U) % SERIAL_RX_BUFSZ; - return 1; -} - void serial_irq(void) { while ((uart_read(PL011_FR) & PL011_FR_RXFE) == 0) { - serial_buffer_push((char)uart_read(PL011_DR)); + serial_receive_char((char)uart_read(PL011_DR)); } uart_write(PL011_ICR, PL011_IMSC_RXIM); } @@ -140,6 +120,6 @@ void serial_poll_rx(void) { while ((uart_read(PL011_FR) & PL011_FR_RXFE) == 0) { - serial_buffer_push((char)uart_read(PL011_DR)); + serial_receive_char((char)uart_read(PL011_DR)); } } blob - 1ca53ff2e1283aaa0ad036ef2170da5afda5b6a5 blob + 2dbbeecb2b6794f1744db62b0631b3d4f748493e --- kernel/arch/x86_64/serial.c +++ kernel/arch/x86_64/serial.c @@ -26,11 +26,6 @@ extern void x86_serial_isr(void); #define SERIAL_WITH_IRQ 1 #define COM1_IRQ 4 #define COM1_VECTOR (32 + COM1_IRQ) -#define SERIAL_RX_BUFSZ 256 - -static volatile char serial_rx_buf[SERIAL_RX_BUFSZ]; -static volatile unsigned int serial_rx_head; -static volatile unsigned int serial_rx_tail; #endif #define COM1 0x3F8 @@ -59,18 +54,12 @@ serial_outb(unsigned short port, unsigned char value) #if SERIAL_WITH_IRQ static void -serial_buffer_push(char c) +serial_receive_char(char c) { - unsigned int next; #if SERIAL_DEBUG_RX static int serial_rx_debug; #endif - next = (serial_rx_head + 1U) % SERIAL_RX_BUFSZ; - if (next == serial_rx_tail) - return; - serial_rx_buf[serial_rx_head] = c; - serial_rx_head = next; #if SERIAL_DEBUG_RX && !defined(UEFI_BUILD) if (serial_rx_debug < 8) { const char hex[] = "0123456789abcdef"; @@ -174,16 +163,7 @@ serial_write(const char *s, size_t n) serial_putc(s[i]); } -int -serial_getc_nonblock(char *c) #if SERIAL_WITH_IRQ -{ - if (serial_rx_head == serial_rx_tail) - return 0; - *c = serial_rx_buf[serial_rx_tail]; - serial_rx_tail = (serial_rx_tail + 1U) % SERIAL_RX_BUFSZ; - return 1; -} void serial_irq(void) { @@ -235,7 +215,7 @@ serial_irq(void) } printk("\n"); } - serial_buffer_push(ch); + serial_receive_char(ch); } } @@ -315,20 +295,10 @@ serial_poll_rx(void) serial_poll_debug++; } #endif - serial_buffer_push(ch); + serial_receive_char(ch); } } #else -{ - if ((serial_inb(COM1 + 5) & 0x01) == 0) - return 0; - *c = (char)serial_inb(COM1 + 0); -#ifndef UEFI_BUILD - console_line_rx(*c); -#endif - return 1; -} - void serial_irq(void) { blob - a6b3abb5e512e27986266b281e2aeb4940e4cb1d blob + c88cdd588bda2ad2877381f7c08dcb5f6ee4dac6 --- kernel/log/serial.h +++ kernel/log/serial.h @@ -7,6 +7,5 @@ int serial_ready(void); void serial_putc(char c); void serial_write(const char *s, size_t n); static inline void serial_write_string(const char *s, size_t n) { serial_write(s, n); } -int serial_getc_nonblock(char *c); void serial_irq(void); void serial_poll_rx(void); blob - 14e2d19d0193143deb01bc709aa969391c47876b blob + 58abc97dbe1f732713866996c62e648b8b9f265e --- kernel/sys/syscall.c +++ kernel/sys/syscall.c @@ -1385,24 +1385,6 @@ sys_read_impl(uint64_t fd, uint64_t buf_addr, uint64_t return syscall_make_result(copied, 0); } - /* Fallback: try to pull characters directly from serial if mailbox is empty. - * NOTE: serial_getc_nonblock() only READS characters without processing. - * serial_poll_rx() handles line discipline processing. */ - /* DISABLED: Only console task should poll serial */ - /* serial_poll_rx(); */ - #if 1 /* Re-enable: getc no longer processes, just reads */ - { - char tmpc; - while (copied < n && serial_getc_nonblock(&tmpc)) { - if (syscall_copy_to_user(buf_addr + copied, &tmpc, 1) != 0) - return syscall_make_result(-SYSCALL_EFAULT, 0); - copied++; - } - if (copied > 0) - return syscall_make_result(copied, 0); - } - #endif - if (mbox == NULL) return syscall_make_result(-SYSCALL_EBADF, 0); deadlock_recv_start(task, 5000);