diff --git a/include/l4/api/ipc.h b/include/l4/api/ipc.h index c62f893..9b75fa3 100644 --- a/include/l4/api/ipc.h +++ b/include/l4/api/ipc.h @@ -16,7 +16,8 @@ #if defined (__KERNEL__) /* These are kernel internal calls */ /* A helper call for sys_ipc() or internally created ipc paths. */ -int ipc_send(l4id_t tid); +int ipc_send(l4id_t to); +int ipc_sendrecv(l4id_t to, l4id_t from); /* * This version sends an extra wait ipc to its receiver so that diff --git a/loader/start.axf.S b/loader/start.axf.S deleted file mode 100644 index 964cb9d..0000000 --- a/loader/start.axf.S +++ /dev/null @@ -1,16 +0,0 @@ - -/* - * loader/start.axf.S autogenerated from build/start.axf - * - * This file is included by the loader sources so that any - * kernel symbol address can be known in advance and stopped - * at by debuggers before virtual memory is enabled. - */ - - -.section .text -.align 4 -.global break_virtual; -.type break_virtual, function; -.equ break_virtual, 0x106f9c - diff --git a/src/api/ipc.c b/src/api/ipc.c index 5870085..79e45a1 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -154,28 +154,31 @@ int ipc_sendwait(l4id_t to) } /* - * We currently only support send-receiving from the same task. The receive - * stage is initiated with the special L4_IPC_TAG_IPCRETURN. This tag is used by - * client tasks for receiving returned ipc results back. This is by far the most - * common ipc pattern between client tasks and servers since every such ipc - * request expects a result. + * Both sends and receives mregs in the same call. This is mainly by user + * tasks for client server communication with system servers. + * + * Timeline of client/server communication using ipc_sendrecv(): + * + * (1) User task (client) calls ipc_sendrecv(); + * (2) System task (server) calls ipc_recv() with from == ANYTHREAD. + * (3) Rendezvous occurs. Both tasks exchange mrs and leave rendezvous. + * (4,5) User task, immediately calls ipc_recv(), expecting a reply from server. + * (4,5) System task handles the request in userspace. + * (6) System task calls ipc_send() sending the return result. + * (7) Rendezvous occurs. Both tasks exchange mrs and leave rendezvous. */ int ipc_sendrecv(l4id_t to, l4id_t from) { int ret = 0; if (to == from) { - - /* IPC send request stage */ + /* Send ipc request */ ipc_send(to); /* - * IPC result return stage. - * - * If the receiving task is scheduled here, (likely to be a - * server which shouldn't block too long) it would only block - * for a fixed amount of time between these send and receive - * calls. + * Get reply. + * A client would block its server only very briefly + * between these calls. */ ipc_recv(from); } else { diff --git a/src/arch/arm/exception.c b/src/arch/arm/exception.c index e4e290a..a00cb68 100644 --- a/src/arch/arm/exception.c +++ b/src/arch/arm/exception.c @@ -59,7 +59,7 @@ void fault_ipc_to_pager(u32 faulty_pc, u32 fsr, u32 far) offsetof(syscall_args_t, r3)); /* Send ipc to the task's pager */ - ipc_sendwait(current->pagerid); + ipc_sendrecv(current->pagerid, current->pagerid); /* * Pager is now notified and handling the fault. We now sleep on diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index d746b45..e0c95fa 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -368,10 +368,11 @@ int do_anon_page(struct fault_data *fault) * - page needs write access: * action: read the page in, give write access. */ -void do_page_fault(struct fault_data *fault) +int do_page_fault(struct fault_data *fault) { unsigned int vma_flags = (fault->vma) ? fault->vma->flags : VM_NONE; unsigned int reason = fault->reason; + int err; /* vma flags show no access */ if (vma_flags & VM_NONE) { @@ -394,9 +395,15 @@ void do_page_fault(struct fault_data *fault) /* Handle legitimate read faults on the vma */ if (vma_flags & VMA_ANON) - do_anon_page(fault); + err = do_anon_page(fault); else - do_file_page(fault); + err = do_file_page(fault); + + /* Return the ipc and by doing so restart the faulty thread */ + printf("Finished handling fault. Restarting thread by returning.\n"); + + l4_ipc_return(err); + return 0; } void vm_file_pager_read_page(struct fault_data *fault, void *dest_page)