From 0acf9c70a8cc24c2c7a03e0a8f8918db823674a2 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 6 May 2020 15:16:08 -0700 Subject: [PATCH] haven: Fix non-zero input SG-List handling for MEM_ACCEPT The MEM_ACCEPT interface assumes that the Resource Manager (RM) will always return an SG-List. This is not correct when the caller provides an SG-List, in which case the RM will not return an SG-List, as it doesn't need to, since the caller knows where the memory has been mapped. Thus, if the caller specifies an SG-List, and the MEM_ACCEPT call is successful, then simply return the SG-List that they provided. Change-Id: I0ba98adc2f8fc858b1a653da909026a9b626c965 Signed-off-by: Isaac J. Manjarres --- drivers/virt/haven/hh_rm_iface.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/virt/haven/hh_rm_iface.c b/drivers/virt/haven/hh_rm_iface.c index ee8f4a5f5064..0d9751b986fc 100644 --- a/drivers/virt/haven/hh_rm_iface.c +++ b/drivers/virt/haven/hh_rm_iface.c @@ -981,8 +981,11 @@ EXPORT_SYMBOL(hh_rm_mem_reclaim); * * * On success, the function will return a pointer to an sg-list to convey where - * the memory has been mapped. After the SG-List is no longer needed, the - * caller must free the table. On a failure, a negative number will be returned. + * the memory has been mapped. If the @sgl_desc parameter was not NULL, then the + * return value will be a pointer to the same SG-List. Otherwise, the return + * value will be a pointer to a newly allocated SG-List. After the SG-List is + * no longer needed, the caller must free the table. On a failure, a negative + * number will be returned. */ struct hh_sgl_desc *hh_rm_mem_accept(hh_memparcel_handle_t handle, u8 mem_type, u8 trans_type, u8 flags, hh_label_t label, @@ -1052,18 +1055,19 @@ struct hh_sgl_desc *hh_rm_mem_accept(hh_memparcel_handle_t handle, u8 mem_type, goto err_rm_call; } - /* - * TODO: Shouldn't we have an input for the number of SG entries - * associated with the memparcel, so we can validate that the size of - * the response buffer is what we expect? - */ - ret_sgl = kmemdup(resp_payload, offsetof(struct hh_sgl_desc, - sgl_entries[resp_payload->n_sgl_entries]), - GFP_KERNEL); - if (!ret_sgl) - ret_sgl = ERR_PTR(-ENOMEM); - kfree(resp_payload); + if (sgl_desc) { + ret_sgl = sgl_desc; + } else { + ret_sgl = kmemdup(resp_payload, offsetof(struct hh_sgl_desc, + sgl_entries[resp_payload->n_sgl_entries]), + GFP_KERNEL); + if (!ret_sgl) + ret_sgl = ERR_PTR(-ENOMEM); + + kfree(resp_payload); + } + err_rm_call: kfree(req_buf); return ret_sgl;