int call_func_ta(int ta_num,int func_id,int simp_arg,void *data,size_t size,seL4_Word *res){ int length = size/(double)sizeof(seL4_Word); if((length+5) > seL4_MsgMaxLength){ printf("Params too large. operation failed\n"); return -1; }else{ seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 5+length); seL4_SetTag(tag); seL4_SetMR(0, CALL_FUNC_CMD); seL4_SetMR(1, ta_num); seL4_SetMR(2,func_id); seL4_SetMR(3,simp_arg); seL4_SetMR(4,length); seL4_Word* blockptr = (seL4_Word*)data; for(int i =0; i < length;++i){ seL4_SetMR(i+5,*blockptr); blockptr++; } seL4_Call(TEE_EP_CPTR,tag); int res_val = seL4_GetMR(0); if(res != NULL){ int len = seL4_GetMR(1); for(int i =0; i < len;++i){ res[i] = seL4_GetMR(i+2); } } return res_val; } }
void /*? me.interface.name ?*/__run(void) { while(1) { /*- set cnode = alloc_cap('cnode', my_cnode, write=True) -*/ /*- set reply_cap_slot = alloc_cap('reply_cap_slot', None) -*/ int result UNUSED; unsigned int len; ip_addr_t addr; struct pbuf *p; seL4_Word badge; seL4_Wait(/*? ep ?*/, &badge); result = seL4_CNode_SaveCaller(/*? cnode ?*/, /*? reply_cap_slot ?*/, 32); assert(result == seL4_NoError); len = seL4_GetMR(0); if (len < 4096) { addr.addr = seL4_GetMR(1); lwip_lock(); p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); if (p) { memcpy(p->payload, /*? me.interface.name?*/_buf_buf(badge), len); switch (badge) { /*- for client, source, dest in clients -*/ case /*? client ?*/: udp_sendto(upcb[/*? loop.index0 ?*/], p, &addr, /*? dest ?*/); break; /*- endfor -*/ } pbuf_free(p); } lwip_unlock(); } seL4_Send(/*? reply_cap_slot ?*/, seL4_MessageInfo_new(0, 0, 0, 0)); }
static int test_full_cspace(env_t env) { int error; seL4_CPtr cnode[CONFIG_WORD_SIZE]; seL4_CPtr ep = vka_alloc_endpoint_leaky(&env->vka); seL4_Word ep_pos = 1; /* Create 32 or 64 cnodes, each resolving one bit. */ for (unsigned int i = 0; i < CONFIG_WORD_SIZE; i++) { cnode[i] = vka_alloc_cnode_object_leaky(&env->vka, 1); assert(cnode[i]); } /* Copy cnode i to alternating slots in cnode i-1. */ seL4_Word slot = 0; for (unsigned int i = 1; i < CONFIG_WORD_SIZE; i++) { error = seL4_CNode_Copy( cnode[i - 1], slot, 1, env->cspace_root, cnode[i], seL4_WordBits, seL4_AllRights); test_assert(!error); ep_pos |= (slot << i); slot ^= 1; } /* In the final cnode, put an IPC endpoint in slot 1. */ error = seL4_CNode_Copy( cnode[CONFIG_WORD_SIZE - 1], slot, 1, env->cspace_root, ep, seL4_WordBits, seL4_AllRights); test_assert(!error); /* Start a helper thread in our own cspace, to let it get set up. */ helper_thread_t t; create_helper_thread(env, &t); start_helper(env, &t, ipc_caller, ep, ep_pos, CONFIG_WORD_SIZE, 0); /* Wait for it. */ seL4_MessageInfo_t tag; seL4_Word sender_badge = 0; tag = seL4_Recv(ep, &sender_badge); test_assert(seL4_MessageInfo_get_length(tag) == 1); test_assert(seL4_GetMR(0) == READY_MAGIC); /* Now switch its cspace. */ error = seL4_TCB_SetSpace(t.thread.tcb.cptr, t.fault_endpoint, cnode[0], seL4_NilData, env->page_directory, seL4_NilData); test_assert(!error); /* And now wait for it to do some tests and return to us. */ tag = seL4_Recv(ep, &sender_badge); test_assert(seL4_MessageInfo_get_length(tag) == 1); test_assert(seL4_GetMR(0) == SUCCESS_MAGIC); cleanup_helper(env, &t); return sel4test_get_result(); }
int dispatch_vm_fault(struct procserv_msg *m, void **userptr) { if (check_dispatch_fault(m, userptr) != DISPATCH_SUCCESS) { return DISPATCH_PASS; } (void) userptr; /* Find the faulting client's PCB. */ struct proc_pcb *pcb = pid_get_pcb_from_badge(&procServ.PIDList, m->badge); if (!pcb) { ROS_WARNING("Unknown client."); return DISPATCH_ERROR; } assert(pcb->magic == REFOS_PCB_MAGIC); assert(pcb->pid == m->badge - PID_BADGE_BASE); /* Fill out the VM fault message info structure. */ struct procserv_vmfault_msg vmfault; vmfault.pcb = pcb; vmfault.pc = seL4_GetMR(seL4_VMFault_IP); vmfault.faultAddr = seL4_GetMR(seL4_VMFault_Addr); vmfault.instruction = seL4_GetMR(seL4_VMFault_PrefetchFault); vmfault.fsr = seL4_GetMR(seL4_VMFault_FSR); vmfault.read = sel4utils_is_read_fault(); /* Handle the VM fault. */ handle_vm_fault(m, &vmfault); return DISPATCH_SUCCESS; }
/* Handle an incoming IPC from a server node */ void irq_server_handle_irq_ipc(irq_server_t irq_server UNUSED) { seL4_Word badge; uintptr_t node_ptr; badge = seL4_GetMR(0); node_ptr = seL4_GetMR(1); if (node_ptr == 0) { ZF_LOGE("Invalid data in irq server IPC\n"); } else { irq_server_node_handle_irq((struct irq_server_node*)node_ptr, badge); } }
int /*? me.from_interface.name ?*/_poll(unsigned int *len, uint16_t *port, ip_addr_t *addr) { int status; seL4_MessageInfo_t UNUSED info; info = seL4_Call(/*? ep ?*/, seL4_MessageInfo_new(0, 0, 0, 0)); assert(seL4_MessageInfo_get_length(info) > 0); status = seL4_GetMR(0); if (status != -1) { *len = seL4_GetMR(1); *port = seL4_GetMR(2); *addr = (ip_addr_t){.addr = seL4_GetMR(3)}; assert(*len < 4096); } return status; }
pid_t my_id(void) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 1); seL4_SetMR (0, SYSCALL_PROCESS_GETPID); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
int read (fildes_t file, char *buf, size_t nbyte) { if (nbyte >= (1 << 12)) { return -1; /* FIXME: crappy limitation */ } struct sos_fhandle* fh = sos_lookup_fhandle (file); if (!fh) { return -1; } seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, pawpaw_share_attach (fh->share), 3); //seL4_SetCap (0, fh->share->cap); seL4_SetMR (0, VFS_READ); seL4_SetMR (1, fh->share->id); seL4_SetMR (2, nbyte); seL4_Call (fh->cap, msg); int read = seL4_GetMR (0); if (read > 0) { memcpy (buf, fh->share->buf, read); } return read; }
void handle_pagefault(void) { seL4_Word pc = seL4_GetMR(0); seL4_Word fault_addr = seL4_GetMR(1); bool ifault = (bool)seL4_GetMR(2); seL4_Word fsr = seL4_GetMR(3); dprintf(0, "vm fault at 0x%08x, align = 0x%08x, pc = 0x%08x, proc = %d, %s\n", fault_addr, PAGE_ALIGN(fault_addr), pc, proc_get_id(), ifault ? "iFault" : "dFault"); seL4_CPtr reply_cap; /* Save the caller */ reply_cap = cspace_save_reply_cap(cur_cspace); assert(reply_cap != CSPACE_NULL); dprintf(3, "handle_pagefault: reply_cap = %d\n", (int)reply_cap); sos_VMFaultHandler(reply_cap, fault_addr, fsr, ifault); }
/*! @brief Handle messages received by the CPIO file server. @param s The global file server state. (No ownership transfer) @param msg The received message. (No ownership transfer) @return DISPATCH_SUCCESS if message dispatched, DISPATCH_ERROR if unknown message. */ static int fileserv_handle_message(struct fs_state *s, srv_msg_t *msg) { int result; int label = seL4_GetMR(0); void *userptr; (void) result; if (dispatch_notification(msg) == DISPATCH_SUCCESS) { return DISPATCH_SUCCESS; } if (check_dispatch_serv(msg, &userptr) == DISPATCH_SUCCESS) { result = rpc_sv_serv_dispatcher(userptr, label); assert(result == DISPATCH_SUCCESS); return DISPATCH_SUCCESS; } if (check_dispatch_data(msg, &userptr) == DISPATCH_SUCCESS) { result = rpc_sv_data_dispatcher(userptr, label); assert(result == DISPATCH_SUCCESS); return DISPATCH_SUCCESS; } dprintf("Unknown message (badge = %d msgInfo = %d label = %d (0x%x)).\n", msg->badge, seL4_MessageInfo_get_label(msg->message), label, label); ROS_ERROR("File server unknown message."); assert(!"File server unknown message."); return DISPATCH_ERROR; }
pid_t process_wait(pid_t pid) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 2); seL4_SetMR (0, SYSCALL_PROCESS_WAIT); seL4_SetMR (1, pid); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
int process_delete(pid_t pid) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 2); seL4_SetMR (0, SYSCALL_PROCESS_DESTROY); seL4_SetMR (1, pid); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
int wait_for_helper(helper_thread_t *thread) { seL4_Word badge; seL4_Wait(thread->local_endpoint.cptr, &badge); return seL4_GetMR(0); }
uint32_t rpc_unmarshall(uint32_t cur_mr, char *str, uint32_t slen) { assert(str); if (slen == 0) return cur_mr; int i; for (i = 0; i < ROUND_DOWN(slen, 4); i+=4, str+=4) { *(seL4_Word*) str = seL4_GetMR(cur_mr++); } if (i != slen) { seL4_Word w = seL4_GetMR(cur_mr++); memcpy(str, &w, slen - i); } return cur_mr; }
int /*? me.interface.name ?*/__run(void) { seL4_Word fault_type; seL4_Word length; seL4_MessageInfo_t info; seL4_Word args[4]; seL4_Word reply_cap = /*? reply_cap_slot ?*/; while (1) { /* Wait for fault */ info = seL4_Recv(/*? ep ?*/, &gdb_state.current_thread_tcb); /* Get the relevant registers */ fault_type = seL4_MessageInfo_get_label(info); length = seL4_MessageInfo_get_length(info); for (int i = 0; i < length; i++) { args[i] = seL4_GetMR(i); } gdb_state.current_pc = args[0]; ZF_LOGD("------------------------------"); ZF_LOGD("Received fault for tcb %zu", gdb_state.current_thread_tcb); ZF_LOGD("Stopped at %zx", gdb_state.current_pc); ZF_LOGD("Length: %zu", length); // Save the reply cap seL4_CNode_SaveCaller(/*? cnode ?*/, reply_cap, 32); gdb_state.stop_reason = find_stop_reason(fault_type, args); gdb_state.current_thread_step_mode = false; /* Send fault message to gdb client */ gdb_handle_fault(&gdb_state); /* Wait for gdb client to deal with fault */ int UNUSED error = b_wait(); /* Reply to the fault ep to restart the thread. We look inside the gdb_state struct to interpret how to restart the thread. */ if (gdb_state.stop_reason == stop_step && gdb_state.current_thread_step_mode==false) { /* If this was a Debug Exception, then we respond with a bp_num and the number of instruction to step Since we're going to continue, we set MR0 to 0 */ info = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, 0); seL4_Send(reply_cap, info); } else if (gdb_state.stop_reason == stop_none) { /* If this was a fault, set the instruction pointer to what we expect it to be */ info = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, gdb_state.current_pc); seL4_Send(reply_cap, info); } else { ZF_LOGD("Responding to some other debug exception %d", gdb_state.stop_reason); seL4_Signal(reply_cap); } } UNREACHABLE(); }
/* sends: * vaddr in process address space of processes buffer (should do map-in-out) * maximum number to place in buffer */ int process_status(process_t *processes, unsigned max) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 3); seL4_SetMR (0, SYSCALL_PROCESS_SEND_STATUS); seL4_SetMR (1, (seL4_Word)processes); seL4_SetMR (2, max); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
int check_dispatch_serv(srv_msg_t *m, void **userptr) { int label = seL4_GetMR(0); if (label == RPC_SERV_CONNECT_DIRECT && m->badge != 0) { return DISPATCH_PASS; } return check_dispatch_interface(m, userptr, RPC_SERV_LABEL_MIN, RPC_SERV_LABEL_MAX); }
pid_t process_create_args_env (const char* path, const char* argv[], const int argc, const char* envv[], const int envc) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 3); seL4_SetMR (0, SYSCALL_PROCESS_CREATE); seL4_SetMR (1, (seL4_Word)path); seL4_SetMR (2, (seL4_Word)argv); char* seL4_SetMR (3, argc + envc) seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
static int handle_exception(vm_t* vm, seL4_Word ip) { seL4_UserContext regs; seL4_CPtr tcb = vm_get_tcb(vm); int err; printf("%sInvalid instruction from [%s] at PC: 0x"XFMT"%s\n", CERROR, vm->name, seL4_GetMR(0), CNORMAL); err = seL4_TCB_ReadRegisters(tcb, false, 0, sizeof(regs) / sizeof(regs.pc), ®s); assert(!err); print_ctx_regs(®s); return 1; }
pid_t process_create_args (const char* path, const char* argv[]) { #endif seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 3); seL4_SetMR (0, SYSCALL_PROCESS_CREATE); seL4_SetMR (1, (seL4_Word)path); seL4_SetMR (2, strlen (path)); //seL4_SetMR (2, (seL4_Word)argv); //seL4_SetMR (3, ) seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
/** Performs the IPC register setup for a write() call to the server. * * The Server's ABI for the write() request has changed a little: the server * now returns the number of bytes it wrote out to the serial in a msg-reg, * aside from also returning an error code in the "label" of the header. * * @param conn Initialized connection token returned by * serial_server_client_connect(). * @param len length of the data in the buffer. * @param server_nbytes_written The value the server reports that it actually * wrote to the serial device. * @return 0 on success, or integer error value on error. */ static ssize_t serial_server_write_ipc_invoke(serial_client_context_t *conn, ssize_t len) { seL4_MessageInfo_t tag; seL4_SetMR(SSMSGREG_FUNC, FUNC_WRITE_REQ); seL4_SetMR(SSMSGREG_WRITE_REQ_BUFF_LEN, len); tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_WRITE_REQ_END); tag = seL4_Call(conn->badged_server_ep_cspath.capPtr, tag); if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_WRITE_ACK) { ZF_LOGE(SERSERVC"printf: Reply message was not a WRITE_ACK as " "expected."); return - seL4_IllegalOperation; } if (seL4_MessageInfo_get_label(tag) != 0) { return - seL4_MessageInfo_get_label(tag); } return seL4_GetMR(SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN); }
static int ipc_test_helper_1(ipc_test_data_t *data) { seL4_Word sender_badge = 0; seL4_MessageInfo_t tag; int result = 0; /* TEST PART 1 */ /* Receive a pending send. */ CHECK_STEP(ipc_test_step, 1); tag = seL4_Recv(data->ep1, &sender_badge); /* As soon as the wait is performed, we should be preempted. */ /* Thread 3 will give us a chance to check our message. */ CHECK_STEP(ipc_test_step, 3); CHECK_TESTCASE(result, seL4_MessageInfo_get_length(tag) == 20); for (int i = 0; i < seL4_MessageInfo_get_length(tag); i++) { CHECK_TESTCASE(result, seL4_GetMR(i) == i); } /* Now we bounce to allow thread 3 control again. */ seL4_MessageInfo_ptr_set_length(&tag, 0); seL4_Call(data->ep0, tag); /* TEST PART 2 */ /* Receive a send that is not yet pending. */ CHECK_STEP(ipc_test_step, 5); tag = seL4_Recv(data->ep1, &sender_badge); CHECK_STEP(ipc_test_step, 8); CHECK_TESTCASE(result, seL4_MessageInfo_get_length(tag) == 19); for (int i = 0; i < seL4_MessageInfo_get_length(tag); i++) { CHECK_TESTCASE(result, seL4_GetMR(i) == i); } return result; }
void init(){ printf("client-os: client os has started\n"); seL4_Word sender_badge; seL4_MessageInfo_t tag; seL4_Word msg,func_id; printf("client-os:receiver...........\n"); tag = seL4_Recv(TEE_EP_CPTR,&sender_badge); msg = seL4_GetMR(0); printf("client-os: msg = %d \n",msg ); seL4_SetMR(0,3221); seL4_ReplyRecv(TEE_EP_CPTR,tag,&sender_badge); }
static inline seL4_Word fault_handler_start(seL4_CPtr ep, seL4_CPtr done_ep, seL4_CPtr reply) { seL4_Word ip; /* signal driver to convert us to passive and block */ if (config_set(CONFIG_KERNEL_RT)) { api_nbsend_recv(done_ep, seL4_MessageInfo_new(0, 0, 0, 0), ep, NULL, reply); ip = seL4_GetMR(0); } else { /* wait for first fault */ seL4_RecvWith1MR(ep, &ip, reply); } return ip; }
static int handle_syscall(vm_t* vm, seL4_Word length) { seL4_Word syscall, ip; seL4_UserContext regs; seL4_CPtr tcb; int err; syscall = seL4_GetMR(EXCEPT_IPC_SYS_MR_SYSCALL), ip = seL4_GetMR(EXCEPT_IPC_SYS_MR_PC); tcb = vm_get_tcb(vm); err = seL4_TCB_ReadRegisters(tcb, false, 0, sizeof(regs) / sizeof(regs.pc), ®s); assert(!err); regs.pc += 4; DSTRACE("Syscall %d from [%s]\n", syscall, vm->name); switch (syscall) { case 65: sys_pa_to_ipa(vm, ®s); break; case 66: sys_ipa_to_pa(vm, ®s); break; case 67: sys_nop(vm, ®s); break; default: printf("%sBad syscall from [%s]: scno "DFMT" at PC: 0x"XFMT"%s\n", CERROR, vm->name, syscall, ip, CNORMAL); return -1; } err = seL4_TCB_WriteRegisters(tcb, false, 0, sizeof(regs) / sizeof(regs.pc), ®s); assert(!err); return 0; }
int stat (const char *path, stat_t *buf) { seL4_MessageInfo_t msg; if (!vfs_ep) { vfs_ep = pawpaw_service_lookup ("svc_vfs"); } struct pawpaw_share* share = pawpaw_share_new (); if (!share) { return -1; } memset (share->buf, 0, PAPAYA_IPC_PAGE_SIZE); if (path && path[0] != '/') { strcpy (share->buf, cwd); int cwdlen = strlen (cwd); if (cwdlen > 0 && cwd[cwdlen - 1] != '/') { strcat (share->buf, "/"); } strcat (share->buf, path); /* XXX: check if buffer overflows */ } else { strcpy (share->buf, path); } msg = seL4_MessageInfo_new (0, 0, 1, 2); seL4_CPtr recv_cap = pawpaw_cspace_alloc_slot (); if (!recv_cap) { pawpaw_share_unmount (share); return -1; } seL4_SetCapReceivePath (PAPAYA_ROOT_CNODE_SLOT, recv_cap, PAPAYA_CSPACE_DEPTH); seL4_SetCap (0, share->cap); seL4_SetMR (0, VFS_STAT); seL4_SetMR (1, share->id); seL4_Call (vfs_ep, msg); int status = seL4_GetMR (0); if (status == 0) { memcpy (buf, share->buf, sizeof (stat_t)); } pawpaw_share_unmount (share); return status; }
int start_ta(char *ta_name){ seL4_Word msg; int arg_len = strlen(ta_name); seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 2+arg_len); seL4_SetTag(tag); seL4_SetMR(0, START_TA_CMD); printf("client-os: Calling TEE-CONTAINER to start TA \n"); seL4_Word *ptr = (seL4_Word*)ta_name; for(int i=0;i < arg_len;++i){ seL4_SetMR(i+2,*ptr); ptr++; } ptr = ta_name; seL4_SetMR(1,arg_len); seL4_Call(TEE_EP_CPTR,tag); msg = seL4_GetMR(0); return msg; }
void handle_vm_fault(seL4_Word badge, int pid) { seL4_CPtr reply_cap; seL4_Word fault_vaddr = seL4_GetMR(1); if (SOS_DEBUG) printf("handle_vm_fault, %p\n", (void *) fault_vaddr); // Get the page of the fault address fault_vaddr &= PAGE_MASK; //dprintf(0, "Handling fault at: 0x%08x\n", fault_vaddr); reply_cap = cspace_save_reply_cap(cur_cspace); int err = map_if_valid(fault_vaddr, pid, handle_vm_fault_cb, NULL, reply_cap); if (err == GUARD_PAGE_FAULT || err == UNKNOWN_REGION || err == NULL_DEREF) { //kill the process as it has faulted invalid memory kill_process(pid, pid, reply_cap); } if (SOS_DEBUG) printf("handle_vm_fault finished\n"); }
/*! @brief Process server IPC message handler. Handles dispatching of all process server IPC messages. Calls each individual dispatcher until the correct dispatcher for the message type has been found. @param s The process server global state. @param msg The process server recieved message info. */ static void proc_server_handle_message(struct procserv_state *s, struct procserv_msg *msg) { int result; int label = seL4_GetMR(0); void *userptr = NULL; (void) result; /* Attempt to dispatch to procserv syscall dispatcher. */ if (check_dispatch_syscall(msg, &userptr) == DISPATCH_SUCCESS) { result = rpc_sv_proc_dispatcher(userptr, label); assert(result == DISPATCH_SUCCESS); mem_syscall_postaction(); proc_syscall_postaction(); return; } /* Attempt to dispatch to VM fault dispatcher. */ if (check_dispatch_fault(msg, &userptr) == DISPATCH_SUCCESS) { result = dispatch_vm_fault(msg, &userptr); assert(result == DISPATCH_SUCCESS); return; } /* Attempt to dispatch to RAM dataspace syscall dispatcher. */ if (check_dispatch_dataspace(msg, &userptr) == DISPATCH_SUCCESS) { result = rpc_sv_data_dispatcher(userptr, label); assert(result == DISPATCH_SUCCESS); mem_syscall_postaction(); return; } /* Attempt to dispatch to nameserv syscall dispatcher. */ if (check_dispatch_nameserv(msg, &userptr) == DISPATCH_SUCCESS) { result = rpc_sv_name_dispatcher(userptr, label); assert(result == DISPATCH_SUCCESS); return; } /* Unknown message. Block calling client indefinitely. */ dprintf("Unknown message (badge = %d msgInfo = %d syscall = 0x%x).\n", msg->badge, seL4_MessageInfo_get_label(msg->message), label); ROS_ERROR("Process server unknown message. ¯\(º_o)/¯"); }
int serial_server_kill(serial_client_context_t *conn) { seL4_MessageInfo_t tag; if (conn == NULL) { return seL4_InvalidArgument; } seL4_SetMR(SSMSGREG_FUNC, FUNC_KILL_REQ); tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_KILL_REQ_END); tag = seL4_Call(conn->badged_server_ep_cspath.capPtr, tag); if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_KILL_ACK) { ZF_LOGE(SERSERVC"kill: Reply message was not a KILL_ACK as expected."); return seL4_IllegalOperation; } return seL4_MessageInfo_get_label(tag); }