Hello, I have done some debugging and I think I know what's going on, and it looks related to this very patch. The device_read_inband () call actually succeeds, and glibc tries to echo the same thing back (that's how devstream works, arguably maybe it shouldn't, but whatever); and when it tries to do the RPC is calls everyone's-since-recently-favorite-function, __mig_get_reply_port (), and...
#0 i386_exception (exc=exc@entry=1, code=code@entry=2, subcode=128) at ../i386/i386/trap.c:638 #1 0xffffffff8103410b in user_page_fault_continue (kr=kr@entry=2) at ../i386/i386/trap.c:119 #2 0xffffffff81056346 in vm_fault (map=<optimized out>, vaddr=vaddr@entry=0, fault_type=1, change_wiring=change_wiring@entry=0, resume=resume@entry=0, continuation=continuation@entry=0xffffffff810340e0 <user_page_fault_continue>) at ../vm/vm_fault.c:1484 #3 0xffffffff81033f5b in user_trap (regs=0xffffffff90fe3868) at ../i386/i386/trap.c:518 #4 0xffffffff81011b73 in _take_trap () at ../x86_64/locore.S:549 subcode is the address of the fault, and 128 just so happens to be 0x80, and %fs:0x80 is of course tcb->reply_port. So it looks like fs_base was not restored to its proper value when context-switching to the thread, and gets instead set to 0, and so accessing the reply port to make an RPC faults. But how come all the previous RPCs worked? Well, it looks like fs_base is restored/preserved correctly when just doing synchronous kernel RPC calls, but not when the thread is continued after reading via io_done_thread_continue/thread_invoke/call_continuation. Sergey