On 29/01/2015 20:00, Yann Droneaud wrote:
> As specified in "Extending Verbs API" presentation [1] by Tzahi Oved
> during OFA International Developer Workshop 2013, the request's
> comp_mask should describe the request data: it's describe the
> availability of extended fields in the request.
> Conversely, the response's comp_mask should describe the presence
> of extended fields in the response.
>
> So instead of silently truncating extended QUERY_DEVICE uverb's
> response, see commit 5a77abf9a97a ("IB/core: Add support for
> extended query device caps")), this patch makes function
> ib_uverbs_ex_query_device() check the available space in the
> response buffer against the minimal response structure and fail
> with -ENOSPC if this base structure cannot be returned to
> userspace: it's required to be able to return the comp_mask's
> value, at least.
>
> For extended features, currently only IB_USER_VERBS_EX_QUERY_DEVICE_ODP
> per commit 860f10a799c8 ("IB/core: Add flags for on demand paging
> support"), the extension's data is returned if the needed space
> is available in the response buffer: it is expected that newer
> userspace program pass a bigger response buffer so that it can
> retrieve extended features. The comp_mask value will match the fields
> that were effectively returned to userspace.
>
> In the end:
> - userspace won't get truncated responses;
> - newer kernel would be able to support older binaries and
> older binaries will work flawlessly with newer kernel;
> - additionally, newer binaries would even be able to support
> older kernel, as far as they don't set new feature bit in
> request's comp_mask.
>
> Note: as offsetof() is used to retrieve the size of the lower chunk
> of the response, beware that it only works if the upper chunk
> is right after, without any implicit padding. And, as the size of
> the latter chunk is added to the base size, implicit padding at the
> end of the structure is not taken in account. Both point must be
> taken in account when extending the uverbs functionalities.
>
> [1]
> https://www.openfabrics.org/images/docs/2013_Dev_Workshop/Tues_0423/2013_Workshop_Tues_0830_Tzahi_Oved-verbs_extensions_ofa_2013-tzahio.pdf
>
> Link: http://mid.gmane.org/[email protected]
> Cc: Sagi Grimberg <[email protected]>
> Cc: Shachar Raindel <[email protected]>
> Cc: Eli Cohen <[email protected]>
> Cc: Haggai Eran <[email protected]>
Reviewed-by: Haggai Eran <[email protected]>
> Signed-off-by: Yann Droneaud <[email protected]>
> ---
> drivers/infiniband/core/uverbs_cmd.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/infiniband/core/uverbs_cmd.c
> b/drivers/infiniband/core/uverbs_cmd.c
> index fbcc54b86795..81d8b5aa2eb6 100644
> --- a/drivers/infiniband/core/uverbs_cmd.c
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -3302,6 +3302,7 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file
> *file,
> struct ib_uverbs_ex_query_device cmd;
> struct ib_device_attr attr;
> struct ib_device *device;
> + size_t resp_len;
> int err;
>
> device = file->device->ib_dev;
> @@ -3318,6 +3319,11 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file
> *file,
> if (cmd.reserved)
> return -EINVAL;
>
> + resp_len = offsetof(typeof(resp), odp_caps);
> +
> + if (ucore->outlen < resp_len)
> + return -ENOSPC;
> +
> err = device->query_device(device, &attr);
> if (err)
> return err;
> @@ -3326,6 +3332,9 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file
> *file,
> copy_query_dev_fields(file, &resp.base, &attr);
> resp.comp_mask = 0;
>
> + if (ucore->outlen < resp_len + sizeof(resp.odp_caps))
> + goto end;
> +
> #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
> resp.odp_caps.general_caps = attr.odp_caps.general_caps;
> resp.odp_caps.per_transport_caps.rc_odp_caps =
> @@ -3336,8 +3345,10 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file
> *file,
> attr.odp_caps.per_transport_caps.ud_odp_caps;
> #endif
> resp.comp_mask |= IB_USER_VERBS_EX_QUERY_DEVICE_ODP;
> + resp_len += sizeof(resp.odp_caps);
>
> - err = ib_copy_to_udata(ucore, &resp, sizeof(resp));
> +end:
> + err = ib_copy_to_udata(ucore, &resp, resp_len);
> if (err)
> return err;
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-api" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html