Hi,

To provide a more concrete idea for the discussion. Here is my code skeleton:

static void server_loop(void)                                                                                                                                          
{                                                                                                                                                                        
        while (1) {                                                                                                                                                         
                ....
                handle_exception(&src, &tag);                                                                                                                                                                          
                                                                                                                                                                           
                if (l4_msgtag_flags(tag) & L4_MSGTAG_TRANSFER_FPU)
                        l4_utcb_inherit_fpu_u(u, 1);
                                                                                                                                                                            
                tag = l4_ipc_reply_and_wait(u, tag, &src, L4_IPC_SEND_TIMEOUT_0);                                                                                                   
                                                                                                                                                                            
                l4_utcb_inherit_fpu_u(u, 0);
                ....
        }                                                                                                                                                                  
}    

static int handle_exception(l4_cap_idx_t *src_id, l4_msgtag_t *tag)
{
    l4_exc_regs_t exc;
    memcpy(&exc, l4_utcb_exc(), sizeof(exc));

    if (exc.trapno == 0x7) {
                printf("FPU exception\n");
                *tag = l4_msgtag(0, 0, 0, L4_MSGTAG_TRANSFER_FPU);
                return 0;
     }
     ...
}


Your comments are appreciated.

~Haohui

On Sun, Apr 8, 2012 at 5:22 PM, Mai, Haohui <haohui.mai@gmail.com> wrote:
Hi,

I'm writing a new OS kernel atop of L4Fiasco.OC. I'm having some difficulties to let my OS support user-level processes that uses floating-point instruction.

So far, My OS closely follows L4Linux, it creates a new task for each user-level process, and marks as all threads of the task as alien thread to capture all page faults and exceptions.

My OS works fines with page fault and syscalls. However, I'm confused with what I should do with floating-point exception (exception #7), which is issued to my kernel at the first time it tries to perform floating-point arithmetic.

I tried to return to the user-level process with an empty message ( l4_msgtag_t tag = l4_msgtag(0, 0, 0, 0) ), or an empty message with L4_MSGTAG_TRANSFER_FPU (l4_msgtag_t tag = l4_msgtag(0, 0, 0, L4_MSGTAG_TRANSFER_FPU) ), but I had no luck.

The user-level process immediately calls "int $0x3" and stops.

I read through L4Linux's code and it seems it's doing similar thing, except that it did initialize the FPU state before asking L4 to transfer the FPU state to user-level process.

Am I missing something? What's the recommend way of doing it? Your comments are highly appreciated.

~Haohui