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 <[email protected]>
This commit is contained in:
Isaac J. Manjarres 2020-05-06 15:16:08 -07:00 • committed by Gerrit - the friendly Code Review server
commit 0acf9c70a8

View file

@ -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;