| @@ -2328,96 +2328,88 @@ static int modify_qp_mask(enum ib_qp_type qp_type, int mask) · 2327 unmodified lines |
| 2328 | } | 2328 | } |
| 2329 | } | 2329 | } |
| 2330 | | 2330 | |
| 2331 | ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, | 2331 | static int modify_qp(struct ib_uverbs_file *file, |
| 2332 | struct ib_device *ib_dev, | 2332 | struct ib_uverbs_ex_modify_qp *cmd, struct ib_udata *udata) |
| 2333 | const char __user *buf, int in_len, | | |
| 2334 | int out_len) | | |
| 2335 | { | 2333 | { |
| 2336 | struct ib_uverbs_modify_qp cmd; | 2334 | struct ib_qp_attr *attr; |
| 2337 | struct ib_udata udata; | 2335 | struct ib_qp *qp; |
| 2338 | struct ib_qp *qp; | 2336 | int ret; |
| 2339 | struct ib_qp_attr *attr; | | |
| 2340 | int ret; | | |
| 2341 | | | |
| 2342 | if (copy_from_user(&cmd, buf, sizeof cmd)) | | |
| 2343 | return -EFAULT; | | |
| 2344 | | | |
| 2345 | INIT_UDATA(&udata, buf + sizeof cmd, NULL, in_len - sizeof cmd, | | |
| 2346 | out_len); | | |
| 2347 | | 2337 | |
| 2348 | attr = kmalloc(sizeof *attr, GFP_KERNEL); | 2338 | attr = kmalloc(sizeof *attr, GFP_KERNEL); |
| 2349 | if (!attr) | 2339 | if (!attr) |
| 2350 | return -ENOMEM; | 2340 | return -ENOMEM; |
| 2351 | | 2341 | |
| 2352 | qp = idr_read_qp(cmd.qp_handle, file->ucontext); | 2342 | qp = idr_read_qp(cmd->base.qp_handle, file->ucontext); |
| 2353 | if (!qp) { | 2343 | if (!qp) { |
| 2354 | ret = -EINVAL; | 2344 | ret = -EINVAL; |
| 2355 | goto out; | 2345 | goto out; |
| 2356 | } | 2346 | } |
| 2357 | | 2347 | |
| 2358 | attr->qp_state = cmd.qp_state; | 2348 | attr->qp_state = cmd->base.qp_state; |
| 2359 | attr->cur_qp_state = cmd.cur_qp_state; | 2349 | attr->cur_qp_state = cmd->base.cur_qp_state; |
| 2360 | attr->path_mtu = cmd.path_mtu; | 2350 | attr->path_mtu = cmd->base.path_mtu; |
| 2361 | attr->path_mig_state = cmd.path_mig_state; | 2351 | attr->path_mig_state = cmd->base.path_mig_state; |
| 2362 | attr->qkey = cmd.qkey; | 2352 | attr->qkey = cmd->base.qkey; |
| 2363 | attr->rq_psn = cmd.rq_psn; | 2353 | attr->rq_psn = cmd->base.rq_psn; |
| 2364 | attr->sq_psn = cmd.sq_psn; | 2354 | attr->sq_psn = cmd->base.sq_psn; |
| 2365 | attr->dest_qp_num = cmd.dest_qp_num; | 2355 | attr->dest_qp_num = cmd->base.dest_qp_num; |
| 2366 | attr->qp_access_flags = cmd.qp_access_flags; | 2356 | attr->qp_access_flags = cmd->base.qp_access_flags; |
| 2367 | attr->pkey_index = cmd.pkey_index; | 2357 | attr->pkey_index = cmd->base.pkey_index; |
| 2368 | attr->alt_pkey_index = cmd.alt_pkey_index; | 2358 | attr->alt_pkey_index = cmd->base.alt_pkey_index; |
| 2369 | attr->en_sqd_async_notify = cmd.en_sqd_async_notify; | 2359 | attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify; |
| 2370 | attr->max_rd_atomic = cmd.max_rd_atomic; | 2360 | attr->max_rd_atomic = cmd->base.max_rd_atomic; |
| 2371 | attr->max_dest_rd_atomic = cmd.max_dest_rd_atomic; | 2361 | attr->max_dest_rd_atomic = cmd->base.max_dest_rd_atomic; |
| 2372 | attr->min_rnr_timer = cmd.min_rnr_timer; | 2362 | attr->min_rnr_timer = cmd->base.min_rnr_timer; |
| 2373 | attr->port_num = cmd.port_num; | 2363 | attr->port_num = cmd->base.port_num; |
| 2374 | attr->timeout = cmd.timeout; | 2364 | attr->timeout = cmd->base.timeout; |
| 2375 | attr->retry_cnt = cmd.retry_cnt; | 2365 | attr->retry_cnt = cmd->base.retry_cnt; |
| 2376 | attr->rnr_retry = cmd.rnr_retry; | 2366 | attr->rnr_retry = cmd->base.rnr_retry; |
| 2377 | attr->alt_port_num = cmd.alt_port_num; | 2367 | attr->alt_port_num = cmd->base.alt_port_num; |
| 2378 | attr->alt_timeout = cmd.alt_timeout; | 2368 | attr->alt_timeout = cmd->base.alt_timeout; |
| 2379 | | 2369 | attr->rate_limit = cmd->rate_limit; |
| 2380 | memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16); | 2370 | |
| 2381 | attr->ah_attr.grh.flow_label = cmd.dest.flow_label; | 2371 | memcpy(attr->ah_attr.grh.dgid.raw, cmd->base.dest.dgid, 16); |
| 2382 | attr->ah_attr.grh.sgid_index = cmd.dest.sgid_index; | 2372 | attr->ah_attr.grh.flow_label = cmd->base.dest.flow_label; |
| 2383 | attr->ah_attr.grh.hop_limit = cmd.dest.hop_limit; | 2373 | attr->ah_attr.grh.sgid_index = cmd->base.dest.sgid_index; |
| 2384 | attr->ah_attr.grh.traffic_class = cmd.dest.traffic_class; | 2374 | attr->ah_attr.grh.hop_limit = cmd->base.dest.hop_limit; |
| 2385 | attr->ah_attr.dlid = cmd.dest.dlid; | 2375 | attr->ah_attr.grh.traffic_class = cmd->base.dest.traffic_class; |
| 2386 | attr->ah_attr.sl = cmd.dest.sl; | 2376 | attr->ah_attr.dlid = cmd->base.dest.dlid; |
| 2387 | attr->ah_attr.src_path_bits = cmd.dest.src_path_bits; | 2377 | attr->ah_attr.sl = cmd->base.dest.sl; |
| 2388 | attr->ah_attr.static_rate = cmd.dest.static_rate; | 2378 | attr->ah_attr.src_path_bits = cmd->base.dest.src_path_bits; |
| 2389 | attr->ah_attr.ah_flags = cmd.dest.is_global ? IB_AH_GRH : 0; | 2379 | attr->ah_attr.static_rate = cmd->base.dest.static_rate; |
| 2390 | attr->ah_attr.port_num = cmd.dest.port_num; | 2380 | attr->ah_attr.ah_flags = cmd->base.dest.is_global ? |
| 2391 | | 2381 | IB_AH_GRH : 0; |
| 2392 | memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16); | 2382 | attr->ah_attr.port_num = cmd->base.dest.port_num; |
| 2393 | attr->alt_ah_attr.grh.flow_label = cmd.alt_dest.flow_label; | 2383 | |
| 2394 | attr->alt_ah_attr.grh.sgid_index = cmd.alt_dest.sgid_index; | 2384 | memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd->base.alt_dest.dgid, 16); |
| 2395 | attr->alt_ah_attr.grh.hop_limit = cmd.alt_dest.hop_limit; | 2385 | attr->alt_ah_attr.grh.flow_label = cmd->base.alt_dest.flow_label; |
| 2396 | attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class; | 2386 | attr->alt_ah_attr.grh.sgid_index = cmd->base.alt_dest.sgid_index; |
| 2397 | attr->alt_ah_attr.dlid = cmd.alt_dest.dlid; | 2387 | attr->alt_ah_attr.grh.hop_limit = cmd->base.alt_dest.hop_limit; |
| 2398 | attr->alt_ah_attr.sl = cmd.alt_dest.sl; | 2388 | attr->alt_ah_attr.grh.traffic_class = cmd->base.alt_dest.traffic_class; |
| 2399 | attr->alt_ah_attr.src_path_bits = cmd.alt_dest.src_path_bits; | 2389 | attr->alt_ah_attr.dlid = cmd->base.alt_dest.dlid; |
| 2400 | attr->alt_ah_attr.static_rate = cmd.alt_dest.static_rate; | 2390 | attr->alt_ah_attr.sl = cmd->base.alt_dest.sl; |
| 2401 | attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0; | 2391 | attr->alt_ah_attr.src_path_bits = cmd->base.alt_dest.src_path_bits; |
| 2402 | attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; | 2392 | attr->alt_ah_attr.static_rate = cmd->base.alt_dest.static_rate; |
| | 2393 | attr->alt_ah_attr.ah_flags = cmd->base.alt_dest.is_global ? |
| | 2394 | IB_AH_GRH : 0; |
| | 2395 | attr->alt_ah_attr.port_num = cmd->base.alt_dest.port_num; |
| 2403 | | 2396 | |
| 2404 | if (qp->real_qp == qp) { | 2397 | if (qp->real_qp == qp) { |
| 2405 | if (cmd.attr_mask & IB_QP_AV) { | 2398 | if (cmd->base.attr_mask & IB_QP_AV) { |
| 2406 | ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr); | 2399 | ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr); |
| 2407 | if (ret) | 2400 | if (ret) |
| 2408 | goto release_qp; | 2401 | goto release_qp; |
| 2409 | } | 2402 | } |
| 2410 | ret = qp->device->modify_qp(qp, attr, | 2403 | ret = qp->device->modify_qp(qp, attr, |
| 2411 | modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata); | 2404 | modify_qp_mask(qp->qp_type, |
| | 2405 | cmd->base.attr_mask), |
| | 2406 | udata); |
| 2412 | } else { | 2407 | } else { |
| 2413 | ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask)); | 2408 | ret = ib_modify_qp(qp, attr, |
| | 2409 | modify_qp_mask(qp->qp_type, |
| | 2410 | cmd->base.attr_mask)); |
| 2414 | } | 2411 | } |
| 2415 | | 2412 | |
| 2416 | if (ret) | | |
| 2417 | goto release_qp; | | |
| 2418 | | | |
| 2419 | ret = in_len; | | |
| 2420 | | | |
| 2421 | release_qp: | 2413 | release_qp: |
| 2422 | put_qp_read(qp); | 2414 | put_qp_read(qp); |
| 2423 | | 2415 | |
| @@ -2427,6 +2419,68 @@ out: · 3 unmodified lines |
| 2427 | return ret; | 2419 | return ret; |
| 2428 | } | 2420 | } |
| 2429 | | 2421 | |
| | 2422 | ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, |
| | 2423 | struct ib_device *ib_dev, |
| | 2424 | const char __user *buf, int in_len, |
| | 2425 | int out_len) |
| | 2426 | { |
| | 2427 | struct ib_uverbs_ex_modify_qp cmd = {}; |
| | 2428 | struct ib_udata udata; |
| | 2429 | int ret; |
| | 2430 | |
| | 2431 | if (copy_from_user(&cmd.base, buf, sizeof(cmd.base))) |
| | 2432 | return -EFAULT; |
| | 2433 | |
| | 2434 | if (cmd.base.attr_mask & |
| | 2435 | ~((IB_USER_LEGACY_LAST_QP_ATTR_MASK << 1) - 1)) |
| | 2436 | return -EOPNOTSUPP; |
| | 2437 | |
| | 2438 | INIT_UDATA(&udata, buf + sizeof(cmd.base), NULL, |
| | 2439 | in_len - sizeof(cmd.base), out_len); |
| | 2440 | |
| | 2441 | ret = modify_qp(file, &cmd, &udata); |
| | 2442 | if (ret) |
| | 2443 | return ret; |
| | 2444 | |
| | 2445 | return in_len; |
| | 2446 | } |
| | 2447 | |
| | 2448 | int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file, |
| | 2449 | struct ib_device *ib_dev, |
| | 2450 | struct ib_udata *ucore, |
| | 2451 | struct ib_udata *uhw) |
| | 2452 | { |
| | 2453 | struct ib_uverbs_ex_modify_qp cmd = {}; |
| | 2454 | int ret; |
| | 2455 | |
| | 2456 | /* |
| | 2457 | * Last bit is reserved for extending the attr_mask by |
| | 2458 | * using another field. |
| | 2459 | */ |
| | 2460 | BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1 << 31)); |
| | 2461 | |
| | 2462 | if (ucore->inlen < sizeof(cmd.base)) |
| | 2463 | return -EINVAL; |
| | 2464 | |
| | 2465 | ret = ib_copy_from_udata(&cmd, ucore, min(sizeof(cmd), ucore->inlen)); |
| | 2466 | if (ret) |
| | 2467 | return ret; |
| | 2468 | |
| | 2469 | if (cmd.base.attr_mask & |
| | 2470 | ~((IB_USER_LAST_QP_ATTR_MASK << 1) - 1)) |
| | 2471 | return -EOPNOTSUPP; |
| | 2472 | |
| | 2473 | if (ucore->inlen > sizeof(cmd)) { |
| | 2474 | if (ib_is_udata_cleared(ucore, sizeof(cmd), |
| | 2475 | ucore->inlen - sizeof(cmd))) |
| | 2476 | return -EOPNOTSUPP; |
| | 2477 | } |
| | 2478 | |
| | 2479 | ret = modify_qp(file, &cmd, uhw); |
| | 2480 | |
| | 2481 | return ret; |
| | 2482 | } |
| | 2483 | |
| 2430 | ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, | 2484 | ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, |
| 2431 | struct ib_device *ib_dev, | 2485 | struct ib_device *ib_dev, |
| 2432 | const char __user *buf, int in_len, | 2486 | const char __user *buf, int in_len, |