Loading drivers/virt/haven/hh_rm_drv_private.h +27 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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); Loading drivers/virt/haven/hh_rm_iface.c +153 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); include/linux/haven/hh_common.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 include/linux/haven/hh_rm_drv.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/virt/haven/hh_rm_drv_private.h +27 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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); Loading
drivers/virt/haven/hh_rm_iface.c +153 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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);
include/linux/haven/hh_common.h +6 −0 Original line number Diff line number Diff line Loading @@ -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
include/linux/haven/hh_rm_drv.h +6 −0 Original line number Diff line number Diff line Loading @@ -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