mirror of
https://github.com/drasko/codezero.git
synced 2026-01-11 18:33:16 +01:00
This patch adds ipc_sendrecv() and opens the way for client/server communication.
ipc_sendrecv() replaces ipc_sendwait() which was flawed. See ipc_sendrecv() for how client/server communication works. Tested with page faults where the kernel does an ipc_sendrecv() to faulty thread's pager and the pager successfully handles the request, and returns back the result, which effectively restarts the faulty thread.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user