Merge branches 'cxgb4', 'flowsteer' and 'misc' into for-linus
This commit is contained in:
commit
22f12c60e1
|
@ -181,9 +181,16 @@ static void add_ref(struct iw_cm_id *cm_id)
|
||||||
static void rem_ref(struct iw_cm_id *cm_id)
|
static void rem_ref(struct iw_cm_id *cm_id)
|
||||||
{
|
{
|
||||||
struct iwcm_id_private *cm_id_priv;
|
struct iwcm_id_private *cm_id_priv;
|
||||||
|
int cb_destroy;
|
||||||
|
|
||||||
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
|
cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
|
||||||
if (iwcm_deref_id(cm_id_priv) &&
|
|
||||||
test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
|
/*
|
||||||
|
* Test bit before deref in case the cm_id gets freed on another
|
||||||
|
* thread.
|
||||||
|
*/
|
||||||
|
cb_destroy = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
|
||||||
|
if (iwcm_deref_id(cm_id_priv) && cb_destroy) {
|
||||||
BUG_ON(!list_empty(&cm_id_priv->work_list));
|
BUG_ON(!list_empty(&cm_id_priv->work_list));
|
||||||
free_cm_id(cm_id_priv);
|
free_cm_id(cm_id_priv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,20 @@
|
||||||
|
|
||||||
#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
|
#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
|
||||||
do { \
|
do { \
|
||||||
(udata)->inbuf = (void __user *) (ibuf); \
|
(udata)->inbuf = (const void __user *) (ibuf); \
|
||||||
(udata)->outbuf = (void __user *) (obuf); \
|
(udata)->outbuf = (void __user *) (obuf); \
|
||||||
(udata)->inlen = (ilen); \
|
(udata)->inlen = (ilen); \
|
||||||
(udata)->outlen = (olen); \
|
(udata)->outlen = (olen); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen) \
|
||||||
|
do { \
|
||||||
|
(udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL; \
|
||||||
|
(udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL; \
|
||||||
|
(udata)->inlen = (ilen); \
|
||||||
|
(udata)->outlen = (olen); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our lifetime rules for these structs are the following:
|
* Our lifetime rules for these structs are the following:
|
||||||
*
|
*
|
||||||
|
|
|
@ -2593,6 +2593,9 @@ out_put:
|
||||||
static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec,
|
static int kern_spec_to_ib_spec(struct ib_uverbs_flow_spec *kern_spec,
|
||||||
union ib_flow_spec *ib_spec)
|
union ib_flow_spec *ib_spec)
|
||||||
{
|
{
|
||||||
|
if (kern_spec->reserved)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ib_spec->type = kern_spec->type;
|
ib_spec->type = kern_spec->type;
|
||||||
|
|
||||||
switch (ib_spec->type) {
|
switch (ib_spec->type) {
|
||||||
|
@ -2646,6 +2649,9 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
|
||||||
void *ib_spec;
|
void *ib_spec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (ucore->inlen < sizeof(cmd))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (ucore->outlen < sizeof(resp))
|
if (ucore->outlen < sizeof(resp))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
|
@ -2671,6 +2677,10 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
|
||||||
(cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec)))
|
(cmd.flow_attr.num_of_specs * sizeof(struct ib_uverbs_flow_spec)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (cmd.flow_attr.reserved[0] ||
|
||||||
|
cmd.flow_attr.reserved[1])
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (cmd.flow_attr.num_of_specs) {
|
if (cmd.flow_attr.num_of_specs) {
|
||||||
kern_flow_attr = kmalloc(sizeof(*kern_flow_attr) + cmd.flow_attr.size,
|
kern_flow_attr = kmalloc(sizeof(*kern_flow_attr) + cmd.flow_attr.size,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
@ -2731,6 +2741,7 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
|
||||||
if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {
|
if (cmd.flow_attr.size || (i != flow_attr->num_of_specs)) {
|
||||||
pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n",
|
pr_warn("create flow failed, flow %d: %d bytes left from uverb cmd\n",
|
||||||
i, cmd.flow_attr.size);
|
i, cmd.flow_attr.size);
|
||||||
|
err = -EINVAL;
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER);
|
flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER);
|
||||||
|
@ -2791,10 +2802,16 @@ int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file,
|
||||||
struct ib_uobject *uobj;
|
struct ib_uobject *uobj;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (ucore->inlen < sizeof(cmd))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
|
ret = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (cmd.comp_mask)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle,
|
uobj = idr_write_uobj(&ib_uverbs_rule_idr, cmd.flow_handle,
|
||||||
file->ucontext);
|
file->ucontext);
|
||||||
if (!uobj)
|
if (!uobj)
|
||||||
|
|
|
@ -668,25 +668,30 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
|
||||||
if ((hdr.in_words + ex_hdr.provider_in_words) * 8 != count)
|
if ((hdr.in_words + ex_hdr.provider_in_words) * 8 != count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (ex_hdr.cmd_hdr_reserved)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (ex_hdr.response) {
|
if (ex_hdr.response) {
|
||||||
if (!hdr.out_words && !ex_hdr.provider_out_words)
|
if (!hdr.out_words && !ex_hdr.provider_out_words)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!access_ok(VERIFY_WRITE,
|
||||||
|
(void __user *) (unsigned long) ex_hdr.response,
|
||||||
|
(hdr.out_words + ex_hdr.provider_out_words) * 8))
|
||||||
|
return -EFAULT;
|
||||||
} else {
|
} else {
|
||||||
if (hdr.out_words || ex_hdr.provider_out_words)
|
if (hdr.out_words || ex_hdr.provider_out_words)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_UDATA(&ucore,
|
INIT_UDATA_BUF_OR_NULL(&ucore, buf, (unsigned long) ex_hdr.response,
|
||||||
(hdr.in_words) ? buf : 0,
|
hdr.in_words * 8, hdr.out_words * 8);
|
||||||
(unsigned long)ex_hdr.response,
|
|
||||||
hdr.in_words * 8,
|
|
||||||
hdr.out_words * 8);
|
|
||||||
|
|
||||||
INIT_UDATA(&uhw,
|
INIT_UDATA_BUF_OR_NULL(&uhw,
|
||||||
(ex_hdr.provider_in_words) ? buf + ucore.inlen : 0,
|
buf + ucore.inlen,
|
||||||
(ex_hdr.provider_out_words) ? (unsigned long)ex_hdr.response + ucore.outlen : 0,
|
(unsigned long) ex_hdr.response + ucore.outlen,
|
||||||
ex_hdr.provider_in_words * 8,
|
ex_hdr.provider_in_words * 8,
|
||||||
ex_hdr.provider_out_words * 8);
|
ex_hdr.provider_out_words * 8);
|
||||||
|
|
||||||
err = uverbs_ex_cmd_table[command](file,
|
err = uverbs_ex_cmd_table[command](file,
|
||||||
&ucore,
|
&ucore,
|
||||||
|
|
|
@ -978,7 +978,7 @@ struct ib_uobject {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ib_udata {
|
struct ib_udata {
|
||||||
void __user *inbuf;
|
const void __user *inbuf;
|
||||||
void __user *outbuf;
|
void __user *outbuf;
|
||||||
size_t inlen;
|
size_t inlen;
|
||||||
size_t outlen;
|
size_t outlen;
|
||||||
|
|
Loading…
Reference in a new issue