Esempio n. 1
0
void listen_for_connection(int *listener) {
  int connection, connect_result;
  connect_result = -1;
  do {
    connect_result = wait_for_connection(*listener, &connection);
  } while(connect_result < 0);
  pthread_create(&listener_thread, NULL, (void *(*)(void *))
		listen_for_connection, listener);
  handle_rpc(connection);
}
Esempio n. 2
0
static void call_tee(uintptr_t parg32, struct teesmc32_arg *arg32)
{
	u32 ret;
	u32 funcid;
	struct smc_param param = { 0 };

	if (irqs_disabled())
		funcid = TEESMC32_FASTCALL_WITH_ARG;
	else
		funcid = TEESMC32_CALL_WITH_ARG;

	param.a1 = parg32;
	while (true) {
		param.a0 = funcid;

		tee_smc_call(&param);
		ret = param.a0;

		if (ret == TEESMC_RETURN_EBUSY) {
			/* "Can't happen" */
			BUG_ON(1);
		} else if (TEESMC_RETURN_IS_RPC(ret)) {
			/* Process the RPC. */
			funcid = handle_rpc(&param);
		} else {
			break;
		}
	}

	switch (ret) {
	case TEESMC_RETURN_UNKNOWN_FUNCTION:
		arg32->ret = TEEC_ERROR_NOT_IMPLEMENTED;
		arg32->ret_origin = TEEC_ORIGIN_COMMS;
		break;
	case TEESMC_RETURN_OK:
		/* arg32->ret set by secure world */
		break;
	default:
		/* Should not happen */
		arg32->ret = TEEC_ERROR_COMMUNICATION;
		arg32->ret_origin = TEEC_ORIGIN_COMMS;
		break;
	}
}
Esempio n. 3
0
static void
do_listen(struct ovs_cmdl_context *ctx)
{
    struct pstream *pstream;
    struct jsonrpc **rpcs;
    size_t n_rpcs, allocated_rpcs;
    bool done;
    int error;

    error = jsonrpc_pstream_open(ctx->argv[1], &pstream, DSCP_DEFAULT);
    if (error) {
        ovs_fatal(error, "could not listen on \"%s\"", ctx->argv[1]);
    }

    daemonize();

    rpcs = NULL;
    n_rpcs = allocated_rpcs = 0;
    done = false;
    for (;;) {
        struct stream *stream;
        size_t i;

        /* Accept new connections. */
        error = pstream_accept(pstream, &stream);
        if (!error) {
            if (n_rpcs >= allocated_rpcs) {
                rpcs = x2nrealloc(rpcs, &allocated_rpcs, sizeof *rpcs);
            }
            rpcs[n_rpcs++] = jsonrpc_open(stream);
        } else if (error != EAGAIN) {
            ovs_fatal(error, "pstream_accept failed");
        }

        /* Service existing connections. */
        for (i = 0; i < n_rpcs; ) {
            struct jsonrpc *rpc = rpcs[i];
            struct jsonrpc_msg *msg;

            jsonrpc_run(rpc);
            if (!jsonrpc_get_backlog(rpc)) {
                error = jsonrpc_recv(rpc, &msg);
                if (!error) {
                    error = handle_rpc(rpc, msg, &done);
                    jsonrpc_msg_destroy(msg);
                } else if (error == EAGAIN) {
                    error = 0;
                }
            }

            if (!error) {
                error = jsonrpc_get_status(rpc);
            }
            if (error) {
                jsonrpc_close(rpc);
                ovs_error(error, "connection closed");
                memmove(&rpcs[i], &rpcs[i + 1],
                        (n_rpcs - i - 1) * sizeof *rpcs);
                n_rpcs--;
            } else {
                i++;
            }
        }

        /* Wait for something to do. */
        if (done && !n_rpcs) {
            break;
        }
        pstream_wait(pstream);
        for (i = 0; i < n_rpcs; i++) {
            struct jsonrpc *rpc = rpcs[i];

            jsonrpc_wait(rpc);
            if (!jsonrpc_get_backlog(rpc)) {
                jsonrpc_recv_wait(rpc);
            }
        }
        poll_block();
    }
    free(rpcs);
    pstream_close(pstream);
}
Esempio n. 4
0
static void handle_client_rpc(struct arbiter_thread *abt, 
			      struct abt_request *req)
{
	struct rpc_header *hdr;
	struct client_desc *c;
	//sanitization
	if (req->pkt_size <= 0) {
		AB_MSG("arbiter: NULL packet or recieved failed!\n");
		return;
	}
	
	if (req->pkt_size < sizeof(struct rpc_header)) {
		AB_MSG("arbiter: incomplete packt received.\n");
		return;
	}
	
	//retrieve the header
	hdr = (struct rpc_header *)req->data;
	if (hdr->abt_magic != ABT_RPC_MAGIC || hdr->msg_len < sizeof(struct rpc_header)) {
		AB_MSG("arbiter: malformed message received.\n");
		return;
	}
	
	//retrive the client information according to the client socket addr
	c = arbiter_lookup_client(abt, req->client_addr, req->client_addr_len);

	if (c == NULL ) {
		AB_MSG("arbiter: unknown client, opcode=%d\n", hdr->opcode);
		return;
	}

	#ifdef _RPC_COUNT
	static int rpc_count[10] = {0};
	rpc_count[hdr->opcode] += 1;
	printf("RPC count:\n" 
		"pthread_create: %d\n"
		"pthread_join: %d\n"
		"malloc: %d\n"
		"free: %d\n"
		"create_category: %d\n"
		"get_label: %d\n"
		"get_ownership: %d\n"
		"get_mem_label: %d\n"
		"calloc: %d\n"
		"realloc: %d\n", 
		rpc_count[0], rpc_count[1], rpc_count[2], rpc_count[3], rpc_count[4],
		rpc_count[5], rpc_count[6], rpc_count[7], rpc_count[8], rpc_count[9]);
	#endif

	switch(hdr->opcode) {
	case ABT_CREATE_CAT:
	{
		AB_INFO("arbiter: create_cat rpc received. req no=%d.\n", req->pkt_sn);
		handle_create_cat_rpc(abt, c, req, hdr);		
		break;
	}
	case ABT_FORK:
	{
		AB_INFO("arbiter: fork rpc received. req no=%d.\n", req->pkt_sn);
		handle_fork_rpc(abt, c, req, hdr);		
		break;
	}
	case ABT_PTHREAD_JOIN:
	{
		AB_INFO("arbiter: pthread_join rpc received. req no=%d.\n", req->pkt_sn);
		handle_pthread_join_rpc(abt, c, req, hdr);		
		break;
	}
	case ABT_MALLOC:
	{
		AB_INFO("arbiter: malloc rpc received. req no=%d.\n", req->pkt_sn);

		//the handling routine
		handle_malloc_rpc(abt, c, req, hdr);
		break;
	}
	case ABT_FREE:
	{
		AB_INFO("arbiter: free rpc received. req no=%d.\n", req->pkt_sn);
		handle_free_rpc(abt, c, req, hdr);
		break;
	}
	case ABT_GET_LABEL:
	{
		AB_INFO("arbiter: get_label rpc received. req no=%d.\n", req->pkt_sn);
		handle_get_label_rpc(abt, c, req, hdr);
		break;
	}
	case ABT_GET_OWNERSHIP:
	{
		AB_INFO("arbiter: get_ownership rpc received. req no=%d.\n", req->pkt_sn);
		handle_get_ownership_rpc(abt, c, req, hdr);
		break;
	}	
	case ABT_GET_MEM_LABEL:
	{
		AB_INFO("arbiter: get_mem_label rpc received. req no=%d.\n", req->pkt_sn);
		handle_get_mem_label_rpc(abt, c, req, hdr);
		break;
	}
	case ABT_CALLOC:
	{
		AB_INFO("arbiter: calloc rpc received. req no=%d.\n", req->pkt_sn);

		//the handling routine
		handle_calloc_rpc(abt, c, req, hdr);
		break;
	}
	case ABT_REALLOC:
	{
		AB_INFO("arbiter: realloc rpc received. req no=%d.\n", req->pkt_sn);

		//the handling routine
		handle_realloc_rpc(abt, c, req, hdr);
		break;
	}
	case ABT_RPC:
	{
		//the handling routine
		handle_rpc(abt, c, req, hdr);
		break;
	}

	default:
		AB_MSG("arbiter rpc: Invallid OP code!\n");

	}
}
Esempio n. 5
0
static void call_tee(struct tee_tz *ptee,
			uintptr_t parg32, struct teesmc32_arg *arg32)
{
	u32 ret;
	u32 funcid;
	struct smc_param param = { 0 };

	if (irqs_disabled())
		funcid = TEESMC32_FASTCALL_WITH_ARG;
	else
		funcid = TEESMC32_CALL_WITH_ARG;

	/*
	 * Commented out elements used to visualize the layout dynamic part
	 * of the struct. Note that these fields are not available at all
	 * if num_params == 0.
	 *
	 * params is accessed through the macro TEESMC32_GET_PARAMS
	 */

	/* struct teesmc32_param params[num_params]; */


	param.a1 = parg32;
	e_lock_teez(ptee);
	while (true) {
		param.a0 = funcid;

		tee_smc_call(&param);
		ret = param.a0;

		if (ret == TEESMC_RETURN_EBUSY) {
			/*
			 * Since secure world returned busy, release the
			 * lock we had when entering this function and wait
			 * for "something to happen" (something else to
			 * exit from secure world and needed resources may
			 * have become available).
			 */
			e_lock_wait_completion_teez(ptee);
		} else if (TEESMC_RETURN_IS_RPC(ret)) {
			/* Process the RPC. */
			e_unlock_teez(ptee);
			funcid = handle_rpc(ptee, &param);
			e_lock_teez(ptee);
		} else {
			break;
		}
	}
	e_unlock_teez(ptee);

	switch (ret) {
	case TEESMC_RETURN_UNKNOWN_FUNCTION:
		break;
	case TEESMC_RETURN_OK:
		/* arg32->ret set by secure world */
		break;
	default:
		/* Should not happen */
		arg32->ret = TEEC_ERROR_COMMUNICATION;
		arg32->ret_origin = TEEC_ORIGIN_COMMS;
		break;
	}
}