public static unsafe void ServerLoop() { bool do_wait = true; bool timeouted = false; Timeout timeout; var tag = new Msgtag(); var src = new L4Handle(); var u = NativeMethods.l4api_utcb(); var mr = NativeMethods.l4api_utcb_mr(); L4Handle linux_server_tid = ArchGlobals.LinuxServerTid; var pullTag = new Msgtag((int)Arch.IPCStubs.IPCTag.EXPRESSOS_IPC_FLUSH_RET_QUEUE, 0, 0, 0); while (true) { timeouted = false; timeout = Globals.TimeoutQueue.NextRecvTimeout(); while (timeout == Timeout.RecvZero) { var thr = Globals.TimeoutQueue.Take(); thr.ResumeFromTimeout(); timeout = Globals.TimeoutQueue.NextRecvTimeout(); } while (do_wait && !timeouted) { if (NativeMethods.linux_pending_reply_count() > 0) { tag = NativeMethods.l4api_ipc_send_and_wait(linux_server_tid, u, pullTag, out src, timeout); } else { tag = NativeMethods.l4api_ipc_wait(u, out src, timeout); } do_wait = tag.HasError; if (tag.ErrorCode() == ThreadRegister.L4_IPC_RETIMEOUT) { timeouted = true; break; } } if (timeouted) { continue; } // Get rid of permission mask src._value = (src._value >> L4Handle.L4_CAP_SHIFT) << L4Handle.L4_CAP_SHIFT; HandleMessage(src, ref tag, ref *NativeMethods.l4api_utcb_exc(), ref *mr); do_wait = true; } }
private static int HandleSyscall(L4Handle src, Thread thr, ref Msgtag pt_tag, ref ExceptionRegisters pt_regs) { /* * Make a copy of the registers, as other IPC calls can override * the same area. */ ExceptionRegisters exc = pt_regs; var scno = exc.eax; SyscallProfiler.EnterSyscall(scno); var ret = SyscallDispatcher.Dispatch(thr, ref exc); if (thr.AsyncReturn) { return(REPLY_DEFERRED); } ArchAPI.ReturnFromSyscall(src, ref exc, ret); SyscallProfiler.ExitSyscall(scno); return(REPLY_DEFERRED); }
private static int HandlePageFault(L4Handle src, Thread thr, ref Msgtag tag, ref MessageRegisters mr) { uint pfa; uint pc; uint faultType; ArchAPI.GetPageFaultInfo(ref mr, out pfa, out pc, out faultType); Pointer physicalPage; uint permssion; Pager.HandlePageFault(thr.Parent, faultType, new Pointer(pfa), new Pointer(pc), out physicalPage, out permssion); if (thr.AsyncReturn) { return(REPLY_DEFERRED); } if (physicalPage == Pointer.Zero) { // We got an error, don't reply // thr.Parent.Space.Regions.DumpAll(); Console.Write("Unhandled page fault "); Console.Write(pfa); Console.Write("@"); Console.Write(pc); Console.Write(" thr="); Console.Write(thr.Tid); Console.WriteLine(); thr.Parent.Space.DumpAll(); return(REPLY_DEFERRED); } ArchAPI.ReturnFromPageFault(src, out tag, ref mr, pfa, physicalPage, permssion); return(REPLY_IMMEDIATELY); }
public static extern Msgtag l4api_ipc_wait(Pointer utcb, out L4Handle src, Timeout timeout);
public static extern Msgtag l4api_ipc_send_and_wait(L4Handle dest, Pointer utcb, Msgtag tag, out L4Handle src, Timeout timeout);
public static extern Msgtag l4api_ipc_send(L4Handle dest, Pointer utcb, Msgtag tag, Timeout timeout);
public static extern void l4api_flush_regions(L4Handle l4Handle, Pointer StartAddress, Pointer End, int unmap_rights);
private static Msgtag l4_stub_ipc_call(L4Handle dest, Msgtag tag, Timeout timeout) { return(NativeMethods.l4api_ipc_call(dest, NativeMethods.l4api_utcb(), tag, timeout)); }
private static int HandleMessage(L4Handle src, ref Msgtag tag, ref ExceptionRegisters pt_regs, ref MessageRegisters mr) { Thread thr; if (tag.Label == Msgtag.L4_PROTO_PAGE_FAULT || IsLinuxSyscall(tag, ref pt_regs)) { thr = Globals.Threads.Lookup(src); if (thr == null) { Console.Write("HandleMessage: Unknown thread "); Console.Write(src._value); Console.Write(" tag="); Console.Write(tag.raw); Console.WriteLine(); return(REPLY_DEFERRED); } thr.AsyncReturn = false; if (tag.Label == Msgtag.L4_PROTO_PAGE_FAULT) { return(HandlePageFault(src, thr, ref tag, ref mr)); } else { return(HandleSyscall(src, thr, ref tag, ref pt_regs)); } } else if (tag.Label == (int)Arch.IPCStubs.IPCTag.EXPRESSOS_IPC) { HandleAsyncCall(ref mr); return(REPLY_DEFERRED); } else if (tag.Label == (int)Arch.IPCStubs.IPCTag.EXPRESSOS_IPC_CMD) { switch ((IPCCommand)mr.mr0) { case IPCCommand.EXPRESSOS_CMD_DUMP_PROFILE: SyscallProfiler.Dump(); break; case IPCCommand.EXPRESSOS_CMD_ENABLE_PROFILER: SyscallProfiler.Enable = true; break; case IPCCommand.EXPRESSOS_CMD_DISABLE_PROFILER: SyscallProfiler.Enable = false; break; case IPCCommand.EXPRESSOS_CMD_FLUSH_CONSOLE: Console.Flush(); break; } return(REPLY_DEFERRED); } else { Console.Write("Unhandled exception tag="); Console.Write(tag.raw); Console.Write(" exc_trapno="); Console.Write(pt_regs.trapno); Console.Write(" err="); Console.Write(pt_regs.err); Console.Write(" eip="); Console.Write(pt_regs.ip); Console.Write(" sp="); Console.Write(pt_regs.sp); Console.WriteLine(); } return(REPLY_DEFERRED); }
internal static extern int l4api_start_thread(L4Handle thread, Pointer ip, Pointer sp);
internal static extern Msgtag l4api_ipc_call(L4Handle dest, Pointer utcb, Msgtag tag, Timeout timeout);
public static extern int l4api_set_thread_area(L4Handle thread_id, IntPtr tls_array, int idx, ref userdesc info, int can_allocate);
internal static extern int l4api_create_thread(Pointer utcb, L4Handle parent, out ThreadInfo info);
private static Msgtag l4_stub_ipc_call(L4Handle dest, Msgtag tag, Timeout timeout) { return NativeMethods.l4api_ipc_call(dest, NativeMethods.l4api_utcb(), tag, timeout); }