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),
                                &regs);

            // 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),
                                    &regs);
            
            // 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
_______________________________________________
Devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to