Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1c2a149 authored by Prakruthi Deepak Heragu's avatar Prakruthi Deepak Heragu Committed by Elliot Berman
Browse files

haven: Add VM management support for clients



Add VM management APIs so that clients can start VMs and allocate/get
vmids associated with VMs.

Change-Id: I7a9138a9479665f6c09aae98390a30c23011b3b1
Signed-off-by: default avatarPrakruthi Deepak Heragu <pheragu@codeaurora.org>
Signed-off-by: default avatarElliot Berman <eberman@codeaurora.org>
parent f57d0c27
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -27,6 +27,11 @@ struct hh_rm_rpc_reply_hdr {
	u32 err_code;
} __packed;

/* VM specific properties to be cached */
struct hh_vm_property {
	hh_vmid_t vmid;
};

/* RPC Header versions */
#define HH_RM_RPC_HDR_VERSION_ONE	0x1

@@ -87,6 +92,26 @@ struct hh_rm_rpc_reply_hdr {
/* End Call type Message IDs */
/* End RPC Message IDs */

/* Call: VM_ALLOCATE */
struct hh_vm_allocate_req_payload {
	u8 vmid:4;
	u8 reserved:4;
} __packed;

struct hh_vm_allocate_resp_payload {
	u32 vmid;
} __packed;

/* Call: VM_START */
struct hh_vm_start_req_payload {
	u8 vmid:4;
	u8 reserved:4;
} __packed;

struct hh_vm_start_resp_payload {
	u32 response;
} __packed;

/* Message ID headers */
/* Call: VM_GET_HYP_RESOURCES */
#define HH_RM_RES_TYPE_DB_TX	0
@@ -129,6 +154,8 @@ struct hh_vm_irq_accept_resp_payload {
/* End Message ID headers */

/* Common function declerations */
int hh_update_vm_prop_table(enum hh_vm_names vm_name,
			struct hh_vm_property *vm_prop);
void *hh_rm_call(hh_rm_msgid_t message_id,
			void *req_buff, size_t req_buff_size,
			size_t *resp_buff_size, int *reply_err_code);
+153 −0
Original line number Diff line number Diff line
@@ -12,6 +12,65 @@

#include "hh_rm_drv_private.h"

static struct hh_vm_property hh_vm_table[HH_VM_MAX];

int hh_update_vm_prop_table(enum hh_vm_names vm_name,
			struct hh_vm_property *vm_prop)
{
	if (vm_prop->vmid <= 0)
		return -EINVAL;
	hh_vm_table[vm_name].vmid = vm_prop->vmid;

	return 0;
}

/**
 * hh_rm_get_vmid: Translate VM name to vmid
 * @vm_name: VM name to lookup
 * @vmid: out pointer to store found vmid if VM is ofund
 *
 * If no VM is known to RM with the supplied name, -EINVAL is returned.
 * 0 otherwise.
 */
int hh_rm_get_vmid(enum hh_vm_names vm_name, hh_vmid_t *vmid)
{
	hh_vmid_t _vmid = hh_vm_table[vm_name].vmid;

	if (!_vmid) {
		pr_err("%s: No vmid associated with the vm\n", __func__);
		return -EINVAL;
	}

	if (vmid)
		*vmid = _vmid;

	return 0;
}
EXPORT_SYMBOL(hh_rm_get_vmid);

/**
 * hh_rm_get_vm_name: Translate vmid to vm name
 * @vmid: vmid to lookup
 * @vm_name: out pointer to store found VM name if vmid is found
 *
 * If no VM is known to RM with the supplied VMID, -EINVAL is returned.
 * 0 otherwise.
 */
int hh_rm_get_vm_name(hh_vmid_t vmid, enum hh_vm_names *vm_name)
{
	enum hh_vm_names i;

	for (i = 0; i < HH_VM_MAX; i++)
		if (hh_vm_table[i].vmid == vmid) {
			if (vm_name)
				*vm_name = i;
			return 0;
		}

	return -EINVAL;
}
EXPORT_SYMBOL(hh_rm_get_vm_name);

/**
 * hh_rm_vm_get_hyp_res: Get info about a series of resources for this VM
 * @vmid: vmid whose info is needed. Pass 0 for self
@@ -125,3 +184,97 @@ int hh_rm_vm_irq_accept(hh_virq_handle_t virq_handle, int virq)
	kfree(resp_payload);
	return ret;
}

/**
 * hh_rm_vm_alloc_vmid: Return a vmid associated with the vm loaded into
 *			memory. This call should be called only during
			initialization.
 * @vm_name: The enum value of the vm that has been loaded.
 *
 * The function encodes the error codes via ERR_PTR. Hence, the caller is
 * responsible to check it with IS_ERR_OR_NULL().
 */
int hh_rm_vm_alloc_vmid(enum hh_vm_names vm_name)
{
	struct hh_vm_allocate_resp_payload *resp_payload;
	struct hh_vm_allocate_req_payload req_payload;
	size_t resp_payload_size;
	struct hh_vm_property vm_prop;
	int err, reply_err_code;

	/* Look up for the vm_name<->vmid pair if already present.
	 * If so, return.
	 */
	if (!hh_vm_table[vm_name].vmid) {
		pr_err("%s: VM_ALLOCATE already called for this VM\n",
			__func__);
		return -EINVAL;
	}

	req_payload.vmid = 0;

	resp_payload = hh_rm_call(HH_RM_RPC_MSG_ID_CALL_VM_ALLOCATE,
				&req_payload, sizeof(req_payload),
				&resp_payload_size, &reply_err_code);
	if (reply_err_code || IS_ERR_OR_NULL(resp_payload)) {
		err = PTR_ERR(resp_payload);
		pr_err("%s: VM_ALLOCATE failed with err: %d\n",
			__func__, err);
		return err;
	}

	if (resp_payload_size != sizeof(*resp_payload)) {
		pr_err("%s: Invalid size received for VM_ALLOCATE: %u\n",
			__func__, resp_payload_size);
		kfree(resp_payload);
		return -EINVAL;
	}

	vm_prop.vmid = resp_payload->vmid;
	err = hh_update_vm_prop_table(vm_name, &vm_prop);

	if (err) {
		pr_err("%s: Invalid vmid sent for updating table: %u\n",
			__func__, resp_payload_size);
		return -EINVAL;
	}
	return resp_payload->vmid;
}
EXPORT_SYMBOL(hh_rm_vm_alloc_vmid);

/**
 * hh_rm_vm_start: Send a request to Resource Manager VM to start a VM.
 * @vmid: The vmid of the vm to be started.
 *
 * The function encodes the error codes via ERR_PTR. Hence, the caller is
 * responsible to check it with IS_ERR_OR_NULL().
 */
int hh_rm_vm_start(int vmid)
{
	struct hh_vm_start_resp_payload *resp_payload;
	struct hh_vm_start_req_payload req_payload;
	size_t resp_payload_size;
	int err, reply_err_code;

	req_payload.vmid = (hh_vmid_t) vmid;

	resp_payload = hh_rm_call(HH_RM_RPC_MSG_ID_CALL_VM_START,
				&req_payload, sizeof(req_payload),
				&resp_payload_size, &reply_err_code);
	if (reply_err_code || IS_ERR_OR_NULL(resp_payload)) {
		err = PTR_ERR(resp_payload);
		pr_err("%s: VM_ALLOCATE failed with err: %d\n",
			__func__, err);
		return err;
	}

	if (resp_payload_size != sizeof(*resp_payload)) {
		pr_err("%s: Invalid size received for VM_IRQ_ACCEPT: %u\n",
			__func__, resp_payload_size);
		kfree(resp_payload);
		return -EINVAL;
	}

	return resp_payload->response;
}
EXPORT_SYMBOL(hh_rm_vm_start);
+6 −0
Original line number Diff line number Diff line
@@ -15,4 +15,10 @@ typedef u32 hh_label_t;
typedef u64 hh_capid_t;
typedef u64 hh_dbl_flags_t;

enum hh_vm_names {
	HH_PRIMARY_VM,
	HH_TRUSTED_VM,
	HH_VM_MAX
};

#endif
+6 −0
Original line number Diff line number Diff line
@@ -116,4 +116,10 @@ int hh_rm_register_notifier(struct notifier_block *nb);
int hh_rm_unregister_notifier(struct notifier_block *nb);
int hh_rm_vm_irq_accept(hh_virq_handle_t virq_handle, int virq);

/* Client APIs for VM management */
int hh_rm_vm_alloc_vmid(enum hh_vm_names vm_name);
int hh_rm_get_vmid(enum hh_vm_names vm_name, hh_vmid_t *vmid);
int hh_rm_get_vm_name(hh_vmid_t vmid, enum hh_vm_names *vm_name);
int hh_rm_vm_start(int vmid);

#endif