Hello, I am working on a syscall handler in user-space and want to implement a trap-and-emulate like mechanism. Firstly, some background information and motivation. I see that the seL4 system call API uses negative syscall numbers. This allows me theoretically to use positive syscall numbers to implement an additional syscall API. The seL4 kernel triggers an UnknownSyscall Exception whenever it encounters different syscalls and leads it to the fault handler endpoint in user space of the corresponding CAmkES component. I work with CAmkES and was able to create a fault handler similar to the one implemented in GDBMem with the help of templates. I am generally able to catch the exception in a thread in the same component and get the corresponding arguments. What I don't seem to manage is redirecting the program flow of the control thread so that we return to right after the faulting syscall instruction (should be faultIP + 2). It generally just retriggers the same exception or a different one (the VMFault exception). To better understand what I did, I quickly provide the code: - My C code: Triggers the system call number 60 with 6 arguments: ```bash int run(void) { while(1){ register int rax __asm__ ("rax") = 60; register int rdi __asm__("rdi") = 1; register int rsi __asm__("rsi") = 2; register int rdx __asm__("rdx") = 3; register int r10 __asm__("r10") = 4; register int r8 __asm__("r8") = 5; register int r9 __asm__("r9") = 6; __asm__ __volatile__ ( "syscall" : "+r" (rax) : "r" (rdi), "r" (rsi), "r" (rdx), "r" (r10), "r" (r8), "r" (r9) : "rcx", "r11", "memory"); printf("After the syscall instruction!\n"); } } ``` - My CAmkES code: We connect two threads of the component CompA, the faultIn thread is related to the From Template, the faultOut thread is related to the To template. ```bash connector camkesFaultHandlerThread { from Procedure; to Procedure; } procedure CAmkES_FaultHandlerThread { void bla(); } component CompA { control; uses CAmkES_FaultHandlerThread faultIn; provides CAmkES_FaultHandlerThread faultOut; } assembly { composition { component CompA compA; connection camkesFaultHandlerThread fault0 (from compA.faultIn, to compA.faultOut); } } ``` - The to Template: gets triggered with every fault, should handle the system call and then redirect program flow ```bash /*- set fault_ep = alloc("fault", seL4_EndpointObject, read=True, write=True, grantreply=True) -*/ /*- set info = c_symbol('info') -*/ int /*? me.interface.name ?*/__run(void) { seL4_Word fault_type; seL4_Word length; seL4_Word delegate_tcb; seL4_UserContext regs; seL4_MessageInfo_t info; while (1) { info = seL4_Recv(/*? fault_ep ?*/, &delegate_tcb); seL4_Fault_t fault = seL4_getFault(info); fault_type = seL4_MessageInfo_get_label(info); if(fault_type == seL4_Fault_UnknownSyscall){ printf("faulting PC: %zx\n",seL4_Fault_UnknownSyscall_get_FaultIP(fault)); //handle the syscall ... length = seL4_MessageInfo_get_length(info); seL4_TCB_ReadRegisters(delegate_tcb, false, 0, sizeof(seL4_UserContext) / sizeof(seL4_Word), ®s); // Which registers should I set for the faultIn thread?, right now simply jump over the syscall instruction regs.rip += 2; // Write registers back seL4_TCB_WriteRegisters(delegate_tcb, false, 0, sizeof(seL4_UserContext) / sizeof(seL4_Word), ®s); // Resume the caller seL4_MessageInfo_t info = seL4_MessageInfo_new(0, 0, 0, length); seL4_Reply(info); } else if(fault_type = seL4_Fault_VMFault){ // Why do we get in here after replying to UnknownSyscallException? } } } ``` I simply want to handle the UnknownSyscall Exception (in the faultOut thread) and then return to the instruction right after the original syscall in the control thread. But no matter how I change the IP, it just retriggers the exception or causes a VM Fault Exception. I see that there is a NextIP virtual register field in kernel/include/arch/x86/arch/64/mode/machine/registerset.h. Can I somehow set this one from userspace with setRegister? Has anyone ever tried something similar? Help would be very much appreciated. Thank you very much! Kind Regards, Lukas