Skip to content

Commit f4b77d3

Browse files
committed
runtime-fix #3: provide no-op rtbridge stubs + panic on stray vm_page_alloc
After fixes #1 and #2, helloworld reaches ifioctl() / IP configuration and crashes again with SIGSEGV in rt_ifmsg(): rt_ifmsg -> ifioctl -> ff_freebsd_init -> ff_init -> main FreeBSD 14.0+ refactored rt_ifmsg() / rt_routemsg() to dispatch via a new "rtbridge" function pointer table: rtsock_callback_p->ifmsg_f(ifp, if_flags_mask); netlink_callback_p->ifmsg_f(ifp, if_flags_mask); The earlier M5 stub set both pointers to NULL, which is exactly what rt_ifmsg() then dereferences. F-Stack does not implement an in-process routing-socket or netlink subsystem, but it must not crash either. Provide a static `ff_stub_rtbridge_noop` whose route_f / ifmsg_f are empty shims, and point both rtsock_callback_p and netlink_callback_p at it. rt_ifmsg() / rt_routemsg() now dispatch into harmless no-ops. Forward-declare the minimal types (struct rtbridge / route_event_f / ifmsg_event_f) locally instead of pulling in <net/route/route_ctl.h> — including that header creates conflicting prototypes with several other rib_* stubs already defined later in this file. Additionally, harden the original vm_page_alloc_noobj_domain stub (and add a vm_page_alloc_noobj sibling) to panic() instead of silently returning NULL. With the UMA_USE_DMAP fix in place, these stubs should never be reached in the normal F-Stack flow; if a future regression accidentally takes the vm-page path again, the process aborts loudly with a clear pointer at vmparam.h instead of spinning the CPU forever. Verified end-to-end: helloworld runs to "helloworld init success", `tools/sbin/ifconfig` lists the f-stack-0 interface (UP/RUNNING), and `tools/sbin/netstat -an` shows tcp4/tcp6 *.80 LISTEN.
1 parent ee424b8 commit f4b77d3

1 file changed

Lines changed: 79 additions & 3 deletions

File tree

lib/ff_stub_14_extra.c

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@
3434
#include <vm/vm_page.h>
3535
#include <machine/pmap.h>
3636

37+
/*
38+
* F-Stack DP-RT-2026-06-01: forward declarations for rtbridge no-op stubs.
39+
* We deliberately avoid including <net/route/route_ctl.h> here because doing
40+
* so pulls in conflicting prototypes for other rib_* stubs further down in
41+
* this file. Instead, declare just the minimal types we need to define the
42+
* rtbridge initializer below.
43+
*/
44+
struct ifnet;
45+
struct rib_cmd_info;
46+
typedef void route_event_f(uint32_t fibnum, const struct rib_cmd_info *rc);
47+
typedef void ifmsg_event_f(struct ifnet *ifp, int if_flags_mask);
48+
struct rtbridge {
49+
route_event_f *route_f;
50+
ifmsg_event_f *ifmsg_f;
51+
};
52+
3753
/* Forward decls for opaque kernel types not pulled by includes above. */
3854
struct kaiocb;
3955
typedef int (aio_cancel_fn_t)(struct kaiocb *);
@@ -270,7 +286,37 @@ void mtx_wait_unlocked(struct mtx *m)
270286

271287
}
272288

273-
struct rtbridge *netlink_callback_p = NULL;
289+
/*
290+
* F-Stack DP-RT-2026-06-01: rtbridge no-op stubs.
291+
*
292+
* Background: 14.0+ refactored rt_ifmsg() / rt_routemsg() to dispatch via
293+
* rtsock_callback_p->ifmsg_f() and netlink_callback_p->ifmsg_f() (see
294+
* 15.0 net/route.c:rt_ifmsg). The original M5 stubs set both pointers to
295+
* NULL, which causes a SIGSEGV in ifioctl() when configuring an IP via
296+
* the example startup path.
297+
*
298+
* F-Stack does not implement kernel routing-socket or netlink subsystems
299+
* in user space, but we must not crash. Provide a static rtbridge whose
300+
* function pointers are no-op shims; rt_ifmsg() / rt_routemsg() callers
301+
* will then dispatch into harmless no-ops instead of dereferencing NULL.
302+
*/
303+
static void
304+
ff_stub_rt_ifmsg_noop(struct ifnet *ifp __unused, int if_flags_mask __unused)
305+
{
306+
}
307+
308+
static void
309+
ff_stub_rt_routemsg_noop(uint32_t fibnum __unused,
310+
const struct rib_cmd_info *rc __unused)
311+
{
312+
}
313+
314+
static struct rtbridge ff_stub_rtbridge_noop = {
315+
.route_f = ff_stub_rt_routemsg_noop,
316+
.ifmsg_f = ff_stub_rt_ifmsg_noop,
317+
};
318+
319+
struct rtbridge *netlink_callback_p = &ff_stub_rtbridge_noop;
274320

275321
bool nlattr_add(struct nl_writer *nw, uint16_t attr_type, uint16_t attr_len, const void *data);
276322
bool nlattr_add(struct nl_writer *nw, uint16_t attr_type, uint16_t attr_len, const void *data)
@@ -550,7 +596,8 @@ bool rt_is_host(const struct rtentry *rt)
550596
return (false);
551597
}
552598

553-
struct rtbridge *rtsock_callback_p = NULL;
599+
/* See ff_stub_rtbridge_noop above for context. */
600+
struct rtbridge *rtsock_callback_p = &ff_stub_rtbridge_noop;
554601

555602
int sendfile_wait_generic(struct sendfile_sync *sfs, int *err);
556603
int sendfile_wait_generic(struct sendfile_sync *sfs, int *err)
@@ -708,10 +755,39 @@ int uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
708755
return (EFAULT);
709756
}
710757

758+
/*
759+
* F-Stack runtime-fix DP-RT-2026-06-01: vm_page_alloc_noobj_domain panic stub.
760+
*
761+
* Background: M5 introduced a "return NULL" stub here so example/ could link.
762+
* Runtime debug found this causes an infinite spin loop in uma_startup1 ->
763+
* keg_fetch_slab when UMA_USE_DMAP picks uma_small_alloc as the allocator
764+
* (root cause: amd64/arm64 vmparam.h forgot the #ifndef FSTACK guard around
765+
* UMA_USE_DMAP after the 14.0+ rename from UMA_MD_SMALL_ALLOC).
766+
*
767+
* The vmparam.h fix already routes uma to page_alloc -> kmem_malloc, so this
768+
* stub should NEVER be called at runtime in normal F-Stack flows. Make any
769+
* stray call fail loudly via panic() so a future regression (e.g. another
770+
* subsystem accidentally taking the vm_page path) is exposed immediately
771+
* instead of silently spinning the CPU.
772+
*/
711773
vm_page_t vm_page_alloc_noobj_domain(int domain, int req);
712774
vm_page_t vm_page_alloc_noobj_domain(int domain, int req)
713775
{
714-
return (NULL);
776+
panic("F-Stack: vm_page_alloc_noobj_domain stub called (domain=%d req=%#x); "
777+
"this indicates UMA picked uma_small_alloc — check UMA_USE_DMAP guard "
778+
"in freebsd/{amd64,arm64}/include/vmparam.h",
779+
domain, req);
780+
return (NULL); /* unreachable, keeps compiler happy */
781+
}
782+
783+
vm_page_t vm_page_alloc_noobj(int req);
784+
vm_page_t vm_page_alloc_noobj(int req)
785+
{
786+
panic("F-Stack: vm_page_alloc_noobj stub called (req=%#x); "
787+
"this indicates pcpu_page_alloc / similar vm-page path was taken — "
788+
"check UMA_USE_DMAP guard in freebsd/{amd64,arm64}/include/vmparam.h",
789+
req);
790+
return (NULL); /* unreachable */
715791
}
716792

717793
struct bitset *vm_page_dump = NULL;

0 commit comments

Comments
 (0)