mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
ANDROID: gunyah: Sync with latest "gunyah: rsc_mgr: Add resource manager RPC core"
Align resource manager and rpc to v12 of Gunyah patches posted to kernel.org. - Rename "buff" to "buf" - printk adjustments - Comments - Stylistic tweaks https://lore.kernel.org/all/20230509204801.2824351-7-quic_eberman@quicinc.com/ Bug: 279506910 Change-Id: Iff216a9cb3afeb9de75f0b42bf58f139da2ca4bd Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
This commit is contained in:
committed by
Carlos Llamas
parent
6889a3fbe4
commit
fea63fe1f1
@@ -380,7 +380,7 @@ static void gh_rm_notif_work(struct work_struct *work)
|
||||
|
||||
blocking_notifier_call_chain(&rm->nh, connection->msg_id, connection->payload);
|
||||
|
||||
gh_rm_put(rm);
|
||||
put_device(rm->dev);
|
||||
kfree(connection->payload);
|
||||
kfree(connection);
|
||||
}
|
||||
@@ -401,14 +401,14 @@ static void gh_rm_process_notif(struct gh_rm *rm, void *msg, size_t msg_size)
|
||||
connection->type = RM_RPC_TYPE_NOTIF;
|
||||
connection->msg_id = hdr->msg_id;
|
||||
|
||||
gh_rm_get(rm);
|
||||
get_device(rm->dev);
|
||||
connection->notification.rm = rm;
|
||||
INIT_WORK(&connection->notification.work, gh_rm_notif_work);
|
||||
|
||||
ret = gh_rm_init_connection_payload(connection, msg, sizeof(*hdr), msg_size);
|
||||
if (ret) {
|
||||
dev_err(rm->dev, "Failed to initialize connection for notification: %d\n", ret);
|
||||
gh_rm_put(rm);
|
||||
put_device(rm->dev);
|
||||
kfree(connection);
|
||||
return;
|
||||
}
|
||||
@@ -482,7 +482,7 @@ static void gh_rm_try_complete_connection(struct gh_rm *rm)
|
||||
schedule_work(&connection->notification.work);
|
||||
break;
|
||||
default:
|
||||
dev_err_ratelimited(rm->dev, "Invalid message type (%d) received\n",
|
||||
dev_err_ratelimited(rm->dev, "Invalid message type (%u) received\n",
|
||||
connection->type);
|
||||
gh_rm_abort_connection(rm);
|
||||
break;
|
||||
@@ -536,11 +536,11 @@ static void gh_rm_msgq_tx_done(struct mbox_client *cl, void *mssg, int r)
|
||||
}
|
||||
|
||||
static int gh_rm_send_request(struct gh_rm *rm, u32 message_id,
|
||||
const void *req_buff, size_t req_buf_size,
|
||||
const void *req_buf, size_t req_buf_size,
|
||||
struct gh_rm_connection *connection)
|
||||
{
|
||||
size_t buf_size_remaining = req_buf_size;
|
||||
const void *req_buf_curr = req_buff;
|
||||
const void *req_buf_curr = req_buf;
|
||||
struct gh_msgq_tx_data *msg;
|
||||
struct gh_rm_rpc_hdr *hdr, hdr_template;
|
||||
u32 cont_fragments = 0;
|
||||
@@ -549,8 +549,8 @@ static int gh_rm_send_request(struct gh_rm *rm, u32 message_id,
|
||||
int ret;
|
||||
|
||||
if (req_buf_size > GH_RM_MAX_NUM_FRAGMENTS * GH_RM_MAX_MSG_SIZE) {
|
||||
dev_warn(rm->dev, "Limit exceeded for the number of fragments: %u\n",
|
||||
cont_fragments);
|
||||
dev_warn(rm->dev, "Limit (%lu bytes) exceeded for the maximum message size: %lu\n",
|
||||
GH_RM_MAX_NUM_FRAGMENTS * GH_RM_MAX_MSG_SIZE, req_buf_size);
|
||||
dump_stack();
|
||||
return -E2BIG;
|
||||
}
|
||||
@@ -560,7 +560,7 @@ static int gh_rm_send_request(struct gh_rm *rm, u32 message_id,
|
||||
|
||||
hdr_template.api = RM_RPC_API;
|
||||
hdr_template.type = FIELD_PREP(RM_RPC_TYPE_MASK, RM_RPC_TYPE_REQUEST) |
|
||||
FIELD_PREP(RM_RPC_FRAGMENTS_MASK, cont_fragments);
|
||||
FIELD_PREP(RM_RPC_FRAGMENTS_MASK, cont_fragments);
|
||||
hdr_template.seq = cpu_to_le16(connection->reply.seq);
|
||||
hdr_template.msg_id = cpu_to_le32(message_id);
|
||||
|
||||
@@ -568,7 +568,6 @@ static int gh_rm_send_request(struct gh_rm *rm, u32 message_id,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Consider also the 'request' packet for the loop count */
|
||||
do {
|
||||
msg = kmem_cache_zalloc(rm->cache, GFP_KERNEL);
|
||||
if (!msg) {
|
||||
@@ -577,11 +576,11 @@ static int gh_rm_send_request(struct gh_rm *rm, u32 message_id,
|
||||
}
|
||||
|
||||
/* Fill header */
|
||||
hdr = (struct gh_rm_rpc_hdr *)msg->data;
|
||||
hdr = (struct gh_rm_rpc_hdr *)&msg->data[0];
|
||||
*hdr = hdr_template;
|
||||
|
||||
/* Copy payload */
|
||||
payload = hdr + 1;
|
||||
payload = &msg->data[0] + sizeof(*hdr);
|
||||
payload_size = min(buf_size_remaining, GH_RM_MAX_MSG_SIZE);
|
||||
memcpy(payload, req_buf_curr, payload_size);
|
||||
req_buf_curr += payload_size;
|
||||
@@ -615,23 +614,23 @@ out:
|
||||
* gh_rm_call: Achieve request-response type communication with RPC
|
||||
* @rm: Pointer to Gunyah resource manager internal data
|
||||
* @message_id: The RM RPC message-id
|
||||
* @req_buff: Request buffer that contains the payload
|
||||
* @req_buf: Request buffer that contains the payload
|
||||
* @req_buf_size: Total size of the payload
|
||||
* @resp_buf: Pointer to a response buffer
|
||||
* @resp_buf_size: Size of the response buffer
|
||||
*
|
||||
* Make a request to the RM-VM and wait for reply back. For a successful
|
||||
* Make a request to the Resource Manager and wait for reply back. For a successful
|
||||
* response, the function returns the payload. The size of the payload is set in
|
||||
* resp_buf_size. The resp_buf should be freed by the caller when 0 is returned
|
||||
* resp_buf_size. The resp_buf must be freed by the caller when 0 is returned
|
||||
* and resp_buf_size != 0.
|
||||
*
|
||||
* req_buff should be not NULL for req_buf_size >0. If req_buf_size == 0,
|
||||
* req_buff *can* be NULL and no additional payload is sent.
|
||||
* req_buf should be not NULL for req_buf_size >0. If req_buf_size == 0,
|
||||
* req_buf *can* be NULL and no additional payload is sent.
|
||||
*
|
||||
* Context: Process context. Will sleep waiting for reply.
|
||||
* Return: 0 on success. <0 if error.
|
||||
*/
|
||||
int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buff, size_t req_buf_size,
|
||||
int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buf, size_t req_buf_size,
|
||||
void **resp_buf, size_t *resp_buf_size)
|
||||
{
|
||||
struct gh_rm_connection *connection;
|
||||
@@ -639,7 +638,7 @@ int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buff, size_t req_buf_
|
||||
int ret;
|
||||
|
||||
/* message_id 0 is reserved. req_buf_size implies req_buf is not NULL */
|
||||
if (!message_id || (!req_buff && req_buf_size) || !rm)
|
||||
if (!rm || !message_id || (!req_buf && req_buf_size))
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -660,7 +659,7 @@ int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buff, size_t req_buf_
|
||||
connection->reply.seq = lower_16_bits(seq_id);
|
||||
|
||||
/* Send the request to the Resource Manager */
|
||||
ret = gh_rm_send_request(rm, message_id, req_buff, req_buf_size, connection);
|
||||
ret = gh_rm_send_request(rm, message_id, req_buf, req_buf_size, connection);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
struct gh_rm;
|
||||
int gh_rm_call(struct gh_rm *rsc_mgr, u32 message_id, void *req_buff, size_t req_buf_size,
|
||||
int gh_rm_call(struct gh_rm *rsc_mgr, u32 message_id, void *req_buf, size_t req_buf_size,
|
||||
void **resp_buf, size_t *resp_buf_size);
|
||||
|
||||
int gh_rm_platform_pre_mem_share(struct gh_rm *rm, struct gh_rm_mem_parcel *mem_parcel);
|
||||
|
||||
@@ -60,7 +60,7 @@ struct gh_rm_mem_release_req {
|
||||
} __packed;
|
||||
|
||||
/* Call: MEM_APPEND */
|
||||
#define GH_MEM_APPEND_REQ_FLAGS_END BIT(0)
|
||||
#define GH_MEM_APPEND_REQ_FLAGS_END BIT(0)
|
||||
|
||||
struct gh_rm_mem_append_req_header {
|
||||
__le32 mem_handle;
|
||||
@@ -76,7 +76,7 @@ struct gh_rm_vm_alloc_vmid_resp {
|
||||
} __packed;
|
||||
|
||||
/* Call: VM_STOP */
|
||||
#define GH_RM_VM_STOP_FLAG_FORCE_STOP BIT(0)
|
||||
#define GH_RM_VM_STOP_FLAG_FORCE_STOP BIT(0)
|
||||
|
||||
#define GH_RM_VM_STOP_REASON_FORCE_STOP 3
|
||||
|
||||
@@ -184,6 +184,7 @@ static int gh_rm_mem_append(struct gh_rm *rm, u32 mem_handle,
|
||||
static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_mem_parcel *p)
|
||||
{
|
||||
size_t msg_size = 0, initial_mem_entries = p->n_mem_entries, resp_size;
|
||||
size_t acl_section_size, mem_section_size;
|
||||
struct gh_rm_mem_share_req_acl_section *acl_section;
|
||||
struct gh_rm_mem_share_req_mem_section *mem_section;
|
||||
struct gh_rm_mem_share_req_header *req_header;
|
||||
@@ -199,6 +200,8 @@ static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_
|
||||
if (initial_mem_entries > GH_RM_MAX_MEM_ENTRIES)
|
||||
initial_mem_entries = GH_RM_MAX_MEM_ENTRIES;
|
||||
|
||||
acl_section_size = struct_size(acl_section, entries, p->n_acl_entries);
|
||||
mem_section_size = struct_size(mem_section, entries, initial_mem_entries);
|
||||
/* The format of the message goes:
|
||||
* request header
|
||||
* ACL entries (which VMs get what kind of access to this memory parcel)
|
||||
@@ -206,8 +209,8 @@ static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_
|
||||
* Memory attributes (currently unused, we'll hard-code the size to 0)
|
||||
*/
|
||||
msg_size += sizeof(struct gh_rm_mem_share_req_header);
|
||||
msg_size += struct_size(acl_section, entries, p->n_acl_entries);
|
||||
msg_size += struct_size(mem_section, entries, initial_mem_entries);
|
||||
msg_size += acl_section_size;
|
||||
msg_size += mem_section_size;
|
||||
msg_size += sizeof(u32); /* for memory attributes, currently unused */
|
||||
|
||||
msg = kzalloc(msg_size, GFP_KERNEL);
|
||||
@@ -222,8 +225,8 @@ static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_
|
||||
|
||||
req_header = msg;
|
||||
acl_section = (void *)req_header + sizeof(*req_header);
|
||||
mem_section = (void *)acl_section + struct_size(acl_section, entries, p->n_acl_entries);
|
||||
attr_section = (void *)mem_section + struct_size(mem_section, entries, initial_mem_entries);
|
||||
mem_section = (void *)acl_section + acl_section_size;
|
||||
attr_section = (void *)mem_section + mem_section_size;
|
||||
|
||||
req_header->mem_type = p->mem_type;
|
||||
if (initial_mem_entries != p->n_mem_entries)
|
||||
@@ -231,11 +234,12 @@ static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_
|
||||
req_header->label = cpu_to_le32(p->label);
|
||||
|
||||
acl_section->n_entries = cpu_to_le32(p->n_acl_entries);
|
||||
memcpy(acl_section->entries, p->acl_entries, sizeof(*(p->acl_entries)) * p->n_acl_entries);
|
||||
memcpy(acl_section->entries, p->acl_entries,
|
||||
flex_array_size(acl_section, entries, p->n_acl_entries));
|
||||
|
||||
mem_section->n_entries = cpu_to_le16(initial_mem_entries);
|
||||
memcpy(mem_section->entries, p->mem_entries,
|
||||
sizeof(*(p->mem_entries)) * initial_mem_entries);
|
||||
flex_array_size(mem_section, entries, initial_mem_entries));
|
||||
|
||||
/* Set n_entries for memory attribute section to 0 */
|
||||
*attr_section = 0;
|
||||
@@ -249,6 +253,7 @@ static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_
|
||||
}
|
||||
|
||||
p->mem_handle = le32_to_cpu(*resp);
|
||||
kfree(resp);
|
||||
|
||||
if (initial_mem_entries != p->n_mem_entries) {
|
||||
ret = gh_rm_mem_append(rm, p->mem_handle,
|
||||
@@ -260,14 +265,13 @@ static int gh_rm_mem_lend_common(struct gh_rm *rm, u32 message_id, struct gh_rm_
|
||||
}
|
||||
}
|
||||
|
||||
kfree(resp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gh_rm_mem_lend() - Lend memory to other virtual machines.
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @parcel: Package the memory information of the memory to be lent.
|
||||
* @parcel: Information about the memory to be lent.
|
||||
*
|
||||
* Lending removes Linux's access to the memory while the memory parcel is lent.
|
||||
*/
|
||||
@@ -280,7 +284,7 @@ int gh_rm_mem_lend(struct gh_rm *rm, struct gh_rm_mem_parcel *parcel)
|
||||
/**
|
||||
* gh_rm_mem_share() - Share memory with other virtual machines.
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @parcel: Package the memory information of the memory to be shared.
|
||||
* @parcel: Information about the memory to be shared.
|
||||
*
|
||||
* Sharing keeps Linux's access to the memory while the memory parcel is shared.
|
||||
*/
|
||||
@@ -292,7 +296,7 @@ int gh_rm_mem_share(struct gh_rm *rm, struct gh_rm_mem_parcel *parcel)
|
||||
/**
|
||||
* gh_rm_mem_reclaim() - Reclaim a memory parcel
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @parcel: Package the memory information of the memory to be reclaimed.
|
||||
* @parcel: Information about the memory to be reclaimed.
|
||||
*
|
||||
* RM maps the associated memory back into the stage-2 page tables of the owner VM.
|
||||
*/
|
||||
@@ -366,7 +370,7 @@ int gh_rm_alloc_vmid(struct gh_rm *rm, u16 vmid)
|
||||
}
|
||||
|
||||
/**
|
||||
* gh_rm_dealloc_vmid() - Dispose the VMID
|
||||
* gh_rm_dealloc_vmid() - Dispose of a VMID
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @vmid: VM identifier allocated with gh_rm_alloc_vmid
|
||||
*/
|
||||
@@ -376,11 +380,11 @@ int gh_rm_dealloc_vmid(struct gh_rm *rm, u16 vmid)
|
||||
}
|
||||
|
||||
/**
|
||||
* gh_rm_vm_reset() - Reset the VM's resources
|
||||
* gh_rm_vm_reset() - Reset a VM's resources
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @vmid: VM identifier allocated with gh_rm_alloc_vmid
|
||||
*
|
||||
* While tearing down the VM, request RM to clean up all the VM resources
|
||||
* As part of tearing down the VM, request RM to clean up all the VM resources
|
||||
* associated with the VM. Only after this, Linux can clean up all the
|
||||
* references it maintains to resources.
|
||||
*/
|
||||
@@ -390,7 +394,7 @@ int gh_rm_vm_reset(struct gh_rm *rm, u16 vmid)
|
||||
}
|
||||
|
||||
/**
|
||||
* gh_rm_vm_start() - Move the VM into "ready to run" state
|
||||
* gh_rm_vm_start() - Move a VM into "ready to run" state
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @vmid: VM identifier allocated with gh_rm_alloc_vmid
|
||||
*
|
||||
@@ -432,9 +436,7 @@ int gh_rm_vm_stop(struct gh_rm *rm, u16 vmid)
|
||||
* @image_size: Size of the VM image
|
||||
* @dtb_offset: Start address of the devicetree binary with VM configuration,
|
||||
* relative to start of memparcel.
|
||||
* @dtb_size: Maximum size of devicetree binary. Resource manager applies
|
||||
* an overlay to the DTB and dtb_size should include room for
|
||||
* the overlay.
|
||||
* @dtb_size: Maximum size of devicetree binary.
|
||||
*/
|
||||
int gh_rm_vm_configure(struct gh_rm *rm, u16 vmid, enum gh_rm_vm_auth_mechanism auth_mechanism,
|
||||
u32 mem_handle, u64 image_offset, u64 image_size, u64 dtb_offset, u64 dtb_size)
|
||||
@@ -470,6 +472,7 @@ int gh_rm_vm_init(struct gh_rm *rm, u16 vmid)
|
||||
* @rm: Handle to a Gunyah resource manager
|
||||
* @vmid: VMID of the other VM to get the resources of
|
||||
* @resources: Set by gh_rm_get_hyp_resources and contains the returned hypervisor resources.
|
||||
* Caller must free the resources pointer if successful.
|
||||
*/
|
||||
int gh_rm_get_hyp_resources(struct gh_rm *rm, u16 vmid,
|
||||
struct gh_rm_hyp_resources **resources)
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#define GH_MEM_HANDLE_INVAL U32_MAX
|
||||
|
||||
struct gh_rm;
|
||||
int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buff, size_t req_buff_size,
|
||||
void **resp_buf, size_t *resp_buff_size);
|
||||
int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buf, size_t req_buf_size,
|
||||
void **resp_buf, size_t *resp_buf_size);
|
||||
int gh_rm_notifier_register(struct gh_rm *rm, struct notifier_block *nb);
|
||||
int gh_rm_notifier_unregister(struct gh_rm *rm, struct notifier_block *nb);
|
||||
struct device *gh_rm_get(struct gh_rm *rm);
|
||||
|
||||
Reference in New Issue
Block a user