void isr_exn_ud_bottom(struct x86_exregs *regs) { /* see if it's a LOCK NOP. (this is why the "syscall" is so slow.) */ /* NOTE: could extend the kernel data segment to the full address space, * and wrap the user-space pointer. that'd remove the farting around with * the mapping database, page tables, and supervisor space. */ struct thread *current = get_current_thread(); uint8_t buf[2]; size_t n = space_memcpy_from(current->space, buf, regs->eip, 2); if(n < 2) { panic("can't read from #UD eip? what."); } if(buf[0] == 0xf0 && buf[1] == 0x90) { /* it is L4_KernelInterface(). * TODO: proper values */ regs->eip += 2; regs->eax = L4_Address(current->space->kip_area); /* TODO: replace these with proper KIP accessors */ regs->ecx = *(L4_Word_t *)(kip_mem + 0x04); /* API VERSION */ regs->edx = *(L4_Word_t *)(kip_mem + 0x08); /* API FLAGS */ /* id = 23 (because 2 + 3 = 5); subid = 17 * TODO: get proper values at some point. */ regs->esi = (23 << 24) | (17 << 16); /* KERNEL ID */ } else { printf("#UD at eip 0x%lx, esp 0x%lx\n", regs->eip, regs->esp); /* TODO: pop an "invalid opcode" exception. */ thread_halt(current); assert(current->status == TS_STOPPED); return_to_scheduler(); } }
static void thread_entry(void) { cur_tc->tc_entry(cur_tc->tc_arg); thread_halt(); }