1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 */ 6 7 #include <linux/device.h> 8 #include <net/genetlink.h> 9 #include <net/sock.h> 10 #include "devl_internal.h" 11 12 struct devlink_info_req { 13 struct sk_buff *msg; 14 void (*version_cb)(const char *version_name, 15 enum devlink_info_version_type version_type, 16 void *version_cb_priv); 17 void *version_cb_priv; 18 }; 19 20 struct devlink_reload_combination { 21 enum devlink_reload_action action; 22 enum devlink_reload_limit limit; 23 }; 24 25 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = { 26 { 27 /* can't reinitialize driver with no down time */ 28 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT, 29 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET, 30 }, 31 }; 32 33 static bool 34 devlink_reload_combination_is_invalid(enum devlink_reload_action action, 35 enum devlink_reload_limit limit) 36 { 37 int i; 38 39 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) 40 if (devlink_reload_invalid_combinations[i].action == action && 41 devlink_reload_invalid_combinations[i].limit == limit) 42 return true; 43 return false; 44 } 45 46 static bool 47 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action) 48 { 49 return test_bit(action, &devlink->ops->reload_actions); 50 } 51 52 static bool 53 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit) 54 { 55 return test_bit(limit, &devlink->ops->reload_limits); 56 } 57 58 static int devlink_reload_stat_put(struct sk_buff *msg, 59 enum devlink_reload_limit limit, u32 value) 60 { 61 struct nlattr *reload_stats_entry; 62 63 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY); 64 if (!reload_stats_entry) 65 return -EMSGSIZE; 66 67 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) || 68 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value)) 69 goto nla_put_failure; 70 nla_nest_end(msg, reload_stats_entry); 71 return 0; 72 73 nla_put_failure: 74 nla_nest_cancel(msg, reload_stats_entry); 75 return -EMSGSIZE; 76 } 77 78 static int 79 devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote) 80 { 81 struct nlattr *reload_stats_attr, *act_info, *act_stats; 82 int i, j, stat_idx; 83 u32 value; 84 85 if (!is_remote) 86 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS); 87 else 88 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS); 89 90 if (!reload_stats_attr) 91 return -EMSGSIZE; 92 93 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) { 94 if ((!is_remote && 95 !devlink_reload_action_is_supported(devlink, i)) || 96 i == DEVLINK_RELOAD_ACTION_UNSPEC) 97 continue; 98 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO); 99 if (!act_info) 100 goto nla_put_failure; 101 102 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i)) 103 goto action_info_nest_cancel; 104 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS); 105 if (!act_stats) 106 goto action_info_nest_cancel; 107 108 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) { 109 /* Remote stats are shown even if not locally supported. 110 * Stats of actions with unspecified limit are shown 111 * though drivers don't need to register unspecified 112 * limit. 113 */ 114 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC && 115 !devlink_reload_limit_is_supported(devlink, j)) || 116 devlink_reload_combination_is_invalid(i, j)) 117 continue; 118 119 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i; 120 if (!is_remote) 121 value = devlink->stats.reload_stats[stat_idx]; 122 else 123 value = devlink->stats.remote_reload_stats[stat_idx]; 124 if (devlink_reload_stat_put(msg, j, value)) 125 goto action_stats_nest_cancel; 126 } 127 nla_nest_end(msg, act_stats); 128 nla_nest_end(msg, act_info); 129 } 130 nla_nest_end(msg, reload_stats_attr); 131 return 0; 132 133 action_stats_nest_cancel: 134 nla_nest_cancel(msg, act_stats); 135 action_info_nest_cancel: 136 nla_nest_cancel(msg, act_info); 137 nla_put_failure: 138 nla_nest_cancel(msg, reload_stats_attr); 139 return -EMSGSIZE; 140 } 141 142 static int devlink_nl_nested_fill(struct sk_buff *msg, struct devlink *devlink) 143 { 144 unsigned long rel_index; 145 void *unused; 146 int err; 147 148 xa_for_each(&devlink->nested_rels, rel_index, unused) { 149 err = devlink_rel_devlink_handle_put(msg, devlink, 150 rel_index, 151 DEVLINK_ATTR_NESTED_DEVLINK, 152 NULL); 153 if (err) 154 return err; 155 } 156 return 0; 157 } 158 159 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink, 160 enum devlink_command cmd, u32 portid, 161 u32 seq, int flags) 162 { 163 struct nlattr *dev_stats; 164 void *hdr; 165 166 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 167 if (!hdr) 168 return -EMSGSIZE; 169 170 if (devlink_nl_put_handle(msg, devlink)) 171 goto nla_put_failure; 172 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed)) 173 goto nla_put_failure; 174 175 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS); 176 if (!dev_stats) 177 goto nla_put_failure; 178 179 if (devlink_reload_stats_put(msg, devlink, false)) 180 goto dev_stats_nest_cancel; 181 if (devlink_reload_stats_put(msg, devlink, true)) 182 goto dev_stats_nest_cancel; 183 184 nla_nest_end(msg, dev_stats); 185 186 if (devlink_nl_nested_fill(msg, devlink)) 187 goto nla_put_failure; 188 189 genlmsg_end(msg, hdr); 190 return 0; 191 192 dev_stats_nest_cancel: 193 nla_nest_cancel(msg, dev_stats); 194 nla_put_failure: 195 genlmsg_cancel(msg, hdr); 196 return -EMSGSIZE; 197 } 198 199 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd) 200 { 201 struct sk_buff *msg; 202 int err; 203 204 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL); 205 WARN_ON(!devl_is_registered(devlink)); 206 207 if (!devlink_nl_notify_need(devlink)) 208 return; 209 210 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 211 if (!msg) 212 return; 213 214 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0); 215 if (err) { 216 nlmsg_free(msg); 217 return; 218 } 219 220 devlink_nl_notify_send(devlink, msg); 221 } 222 223 int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info) 224 { 225 struct devlink *devlink = info->user_ptr[0]; 226 struct sk_buff *msg; 227 int err; 228 229 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 230 if (!msg) 231 return -ENOMEM; 232 233 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 234 info->snd_portid, info->snd_seq, 0); 235 if (err) { 236 nlmsg_free(msg); 237 return err; 238 } 239 240 return genlmsg_reply(msg, info); 241 } 242 243 static int 244 devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 245 struct netlink_callback *cb, int flags) 246 { 247 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW, 248 NETLINK_CB(cb->skb).portid, 249 cb->nlh->nlmsg_seq, flags); 250 } 251 252 int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 253 { 254 return devlink_nl_dumpit(msg, cb, devlink_nl_get_dump_one); 255 } 256 257 static void devlink_rel_notify_cb(struct devlink *devlink, u32 obj_index) 258 { 259 devlink_notify(devlink, DEVLINK_CMD_NEW); 260 } 261 262 static void devlink_rel_cleanup_cb(struct devlink *devlink, u32 obj_index, 263 u32 rel_index) 264 { 265 xa_erase(&devlink->nested_rels, rel_index); 266 } 267 268 int devl_nested_devlink_set(struct devlink *devlink, 269 struct devlink *nested_devlink) 270 { 271 u32 rel_index; 272 int err; 273 274 err = devlink_rel_nested_in_add(&rel_index, devlink->index, 0, 275 devlink_rel_notify_cb, 276 devlink_rel_cleanup_cb, 277 nested_devlink); 278 if (err) 279 return err; 280 return xa_insert(&devlink->nested_rels, rel_index, 281 xa_mk_value(0), GFP_KERNEL); 282 } 283 EXPORT_SYMBOL_GPL(devl_nested_devlink_set); 284 285 void devlink_notify_register(struct devlink *devlink) 286 { 287 devlink_notify(devlink, DEVLINK_CMD_NEW); 288 devlink_linecards_notify_register(devlink); 289 devlink_ports_notify_register(devlink); 290 devlink_trap_policers_notify_register(devlink); 291 devlink_trap_groups_notify_register(devlink); 292 devlink_traps_notify_register(devlink); 293 devlink_rates_notify_register(devlink); 294 devlink_regions_notify_register(devlink); 295 devlink_params_notify_register(devlink); 296 } 297 298 void devlink_notify_unregister(struct devlink *devlink) 299 { 300 devlink_params_notify_unregister(devlink); 301 devlink_regions_notify_unregister(devlink); 302 devlink_rates_notify_unregister(devlink); 303 devlink_traps_notify_unregister(devlink); 304 devlink_trap_groups_notify_unregister(devlink); 305 devlink_trap_policers_notify_unregister(devlink); 306 devlink_ports_notify_unregister(devlink); 307 devlink_linecards_notify_unregister(devlink); 308 devlink_notify(devlink, DEVLINK_CMD_DEL); 309 } 310 311 static void devlink_reload_failed_set(struct devlink *devlink, 312 bool reload_failed) 313 { 314 if (devlink->reload_failed == reload_failed) 315 return; 316 devlink->reload_failed = reload_failed; 317 devlink_notify(devlink, DEVLINK_CMD_NEW); 318 } 319 320 bool devlink_is_reload_failed(const struct devlink *devlink) 321 { 322 return devlink->reload_failed; 323 } 324 EXPORT_SYMBOL_GPL(devlink_is_reload_failed); 325 326 static void 327 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats, 328 enum devlink_reload_limit limit, u32 actions_performed) 329 { 330 unsigned long actions = actions_performed; 331 int stat_idx; 332 int action; 333 334 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) { 335 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action; 336 reload_stats[stat_idx]++; 337 } 338 devlink_notify(devlink, DEVLINK_CMD_NEW); 339 } 340 341 static void 342 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit, 343 u32 actions_performed) 344 { 345 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit, 346 actions_performed); 347 } 348 349 /** 350 * devlink_remote_reload_actions_performed - Update devlink on reload actions 351 * performed which are not a direct result of devlink reload call. 352 * 353 * This should be called by a driver after performing reload actions in case it was not 354 * a result of devlink reload call. For example fw_activate was performed as a result 355 * of devlink reload triggered fw_activate on another host. 356 * The motivation for this function is to keep data on reload actions performed on this 357 * function whether it was done due to direct devlink reload call or not. 358 * 359 * @devlink: devlink 360 * @limit: reload limit 361 * @actions_performed: bitmask of actions performed 362 */ 363 void devlink_remote_reload_actions_performed(struct devlink *devlink, 364 enum devlink_reload_limit limit, 365 u32 actions_performed) 366 { 367 if (WARN_ON(!actions_performed || 368 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 369 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) || 370 limit > DEVLINK_RELOAD_LIMIT_MAX)) 371 return; 372 373 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit, 374 actions_performed); 375 } 376 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed); 377 378 static struct net *devlink_netns_get(struct sk_buff *skb, 379 struct genl_info *info) 380 { 381 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID]; 382 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD]; 383 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID]; 384 struct net *net; 385 386 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) { 387 NL_SET_ERR_MSG(info->extack, "multiple netns identifying attributes specified"); 388 return ERR_PTR(-EINVAL); 389 } 390 391 if (netns_pid_attr) { 392 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr)); 393 } else if (netns_fd_attr) { 394 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr)); 395 } else if (netns_id_attr) { 396 net = get_net_ns_by_id(sock_net(skb->sk), 397 nla_get_u32(netns_id_attr)); 398 if (!net) 399 net = ERR_PTR(-EINVAL); 400 } else { 401 WARN_ON(1); 402 net = ERR_PTR(-EINVAL); 403 } 404 if (IS_ERR(net)) { 405 NL_SET_ERR_MSG(info->extack, "Unknown network namespace"); 406 return ERR_PTR(-EINVAL); 407 } 408 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { 409 put_net(net); 410 return ERR_PTR(-EPERM); 411 } 412 return net; 413 } 414 415 static void devlink_reload_netns_change(struct devlink *devlink, 416 struct net *curr_net, 417 struct net *dest_net) 418 { 419 /* Userspace needs to be notified about devlink objects 420 * removed from original and entering new network namespace. 421 * The rest of the devlink objects are re-created during 422 * reload process so the notifications are generated separatelly. 423 */ 424 devlink_notify_unregister(devlink); 425 write_pnet(&devlink->_net, dest_net); 426 devlink_notify_register(devlink); 427 devlink_rel_nested_in_notify(devlink); 428 } 429 430 static void devlink_reload_reinit_sanity_check(struct devlink *devlink) 431 { 432 WARN_ON(!list_empty(&devlink->trap_policer_list)); 433 WARN_ON(!list_empty(&devlink->trap_group_list)); 434 WARN_ON(!list_empty(&devlink->trap_list)); 435 WARN_ON(!list_empty(&devlink->dpipe_table_list)); 436 WARN_ON(!list_empty(&devlink->sb_list)); 437 WARN_ON(devlink_rates_check(devlink, NULL, NULL)); 438 WARN_ON(!list_empty(&devlink->linecard_list)); 439 WARN_ON(!xa_empty(&devlink->ports)); 440 } 441 442 int devlink_reload(struct devlink *devlink, struct net *dest_net, 443 enum devlink_reload_action action, 444 enum devlink_reload_limit limit, 445 u32 *actions_performed, struct netlink_ext_ack *extack) 446 { 447 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; 448 struct net *curr_net; 449 int err; 450 451 /* Make sure the reload operations are invoked with the device lock 452 * held to allow drivers to trigger functionality that expects it 453 * (e.g., PCI reset) and to close possible races between these 454 * operations and probe/remove. 455 */ 456 device_lock_assert(devlink->dev); 457 458 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, 459 sizeof(remote_reload_stats)); 460 461 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); 462 if (err) 463 return err; 464 465 curr_net = devlink_net(devlink); 466 if (dest_net && !net_eq(dest_net, curr_net)) 467 devlink_reload_netns_change(devlink, curr_net, dest_net); 468 469 if (action == DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 470 devlink_params_driverinit_load_new(devlink); 471 devlink_reload_reinit_sanity_check(devlink); 472 } 473 474 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); 475 devlink_reload_failed_set(devlink, !!err); 476 if (err) 477 return err; 478 479 WARN_ON(!(*actions_performed & BIT(action))); 480 /* Catch driver on updating the remote action within devlink reload */ 481 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, 482 sizeof(remote_reload_stats))); 483 devlink_reload_stats_update(devlink, limit, *actions_performed); 484 return 0; 485 } 486 487 static int 488 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed, 489 enum devlink_command cmd, struct genl_info *info) 490 { 491 struct sk_buff *msg; 492 void *hdr; 493 494 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 495 if (!msg) 496 return -ENOMEM; 497 498 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd); 499 if (!hdr) 500 goto free_msg; 501 502 if (devlink_nl_put_handle(msg, devlink)) 503 goto nla_put_failure; 504 505 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed, 506 actions_performed)) 507 goto nla_put_failure; 508 genlmsg_end(msg, hdr); 509 510 return genlmsg_reply(msg, info); 511 512 nla_put_failure: 513 genlmsg_cancel(msg, hdr); 514 free_msg: 515 nlmsg_free(msg); 516 return -EMSGSIZE; 517 } 518 519 int devlink_nl_reload_doit(struct sk_buff *skb, struct genl_info *info) 520 { 521 struct devlink *devlink = info->user_ptr[0]; 522 enum devlink_reload_action action; 523 enum devlink_reload_limit limit; 524 struct net *dest_net = NULL; 525 u32 actions_performed; 526 int err; 527 528 err = devlink_resources_validate(devlink, NULL, info); 529 if (err) { 530 NL_SET_ERR_MSG(info->extack, "resources size validation failed"); 531 return err; 532 } 533 534 action = nla_get_u8_default(info->attrs[DEVLINK_ATTR_RELOAD_ACTION], 535 DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 536 537 if (!devlink_reload_action_is_supported(devlink, action)) { 538 NL_SET_ERR_MSG(info->extack, "Requested reload action is not supported by the driver"); 539 return -EOPNOTSUPP; 540 } 541 542 limit = DEVLINK_RELOAD_LIMIT_UNSPEC; 543 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) { 544 struct nla_bitfield32 limits; 545 u32 limits_selected; 546 547 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]); 548 limits_selected = limits.value & limits.selector; 549 if (!limits_selected) { 550 NL_SET_ERR_MSG(info->extack, "Invalid limit selected"); 551 return -EINVAL; 552 } 553 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++) 554 if (limits_selected & BIT(limit)) 555 break; 556 /* UAPI enables multiselection, but currently it is not used */ 557 if (limits_selected != BIT(limit)) { 558 NL_SET_ERR_MSG(info->extack, "Multiselection of limit is not supported"); 559 return -EOPNOTSUPP; 560 } 561 if (!devlink_reload_limit_is_supported(devlink, limit)) { 562 NL_SET_ERR_MSG(info->extack, "Requested limit is not supported by the driver"); 563 return -EOPNOTSUPP; 564 } 565 if (devlink_reload_combination_is_invalid(action, limit)) { 566 NL_SET_ERR_MSG(info->extack, "Requested limit is invalid for this action"); 567 return -EINVAL; 568 } 569 } 570 if (info->attrs[DEVLINK_ATTR_NETNS_PID] || 571 info->attrs[DEVLINK_ATTR_NETNS_FD] || 572 info->attrs[DEVLINK_ATTR_NETNS_ID]) { 573 dest_net = devlink_netns_get(skb, info); 574 if (IS_ERR(dest_net)) 575 return PTR_ERR(dest_net); 576 if (!net_eq(dest_net, devlink_net(devlink)) && 577 action != DEVLINK_RELOAD_ACTION_DRIVER_REINIT) { 578 NL_SET_ERR_MSG_MOD(info->extack, 579 "Changing namespace is only supported for reinit action"); 580 return -EOPNOTSUPP; 581 } 582 } 583 584 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack); 585 586 if (dest_net) 587 put_net(dest_net); 588 589 if (err) 590 return err; 591 /* For backward compatibility generate reply only if attributes used by user */ 592 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) 593 return 0; 594 595 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed, 596 DEVLINK_CMD_RELOAD, info); 597 } 598 599 bool devlink_reload_actions_valid(const struct devlink_ops *ops) 600 { 601 const struct devlink_reload_combination *comb; 602 int i; 603 604 if (!devlink_reload_supported(ops)) { 605 if (WARN_ON(ops->reload_actions)) 606 return false; 607 return true; 608 } 609 610 if (WARN_ON(!ops->reload_actions || 611 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) || 612 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX))) 613 return false; 614 615 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) || 616 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX))) 617 return false; 618 619 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) { 620 comb = &devlink_reload_invalid_combinations[i]; 621 if (ops->reload_actions == BIT(comb->action) && 622 ops->reload_limits == BIT(comb->limit)) 623 return false; 624 } 625 return true; 626 } 627 628 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink, 629 enum devlink_command cmd, u32 portid, 630 u32 seq, int flags) 631 { 632 const struct devlink_ops *ops = devlink->ops; 633 enum devlink_eswitch_encap_mode encap_mode; 634 u8 inline_mode; 635 void *hdr; 636 int err = 0; 637 u16 mode; 638 639 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 640 if (!hdr) 641 return -EMSGSIZE; 642 643 err = devlink_nl_put_handle(msg, devlink); 644 if (err) 645 goto nla_put_failure; 646 647 if (ops->eswitch_mode_get) { 648 err = ops->eswitch_mode_get(devlink, &mode); 649 if (err) 650 goto nla_put_failure; 651 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode); 652 if (err) 653 goto nla_put_failure; 654 } 655 656 if (ops->eswitch_inline_mode_get) { 657 err = ops->eswitch_inline_mode_get(devlink, &inline_mode); 658 if (err) 659 goto nla_put_failure; 660 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, 661 inline_mode); 662 if (err) 663 goto nla_put_failure; 664 } 665 666 if (ops->eswitch_encap_mode_get) { 667 err = ops->eswitch_encap_mode_get(devlink, &encap_mode); 668 if (err) 669 goto nla_put_failure; 670 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode); 671 if (err) 672 goto nla_put_failure; 673 } 674 675 genlmsg_end(msg, hdr); 676 return 0; 677 678 nla_put_failure: 679 genlmsg_cancel(msg, hdr); 680 return err; 681 } 682 683 int devlink_nl_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info) 684 { 685 struct devlink *devlink = info->user_ptr[0]; 686 struct sk_buff *msg; 687 int err; 688 689 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 690 if (!msg) 691 return -ENOMEM; 692 693 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET, 694 info->snd_portid, info->snd_seq, 0); 695 696 if (err) { 697 nlmsg_free(msg); 698 return err; 699 } 700 701 return genlmsg_reply(msg, info); 702 } 703 704 int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info) 705 { 706 struct devlink *devlink = info->user_ptr[0]; 707 const struct devlink_ops *ops = devlink->ops; 708 enum devlink_eswitch_encap_mode encap_mode; 709 u8 inline_mode; 710 int err = 0; 711 u16 mode; 712 713 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { 714 if (!ops->eswitch_mode_set) 715 return -EOPNOTSUPP; 716 err = devlink_rates_check(devlink, devlink_rate_is_node, 717 info->extack); 718 if (err) 719 return err; 720 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]); 721 err = ops->eswitch_mode_set(devlink, mode, info->extack); 722 if (err) 723 return err; 724 } 725 726 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) { 727 if (!ops->eswitch_inline_mode_set) 728 return -EOPNOTSUPP; 729 inline_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]); 730 err = ops->eswitch_inline_mode_set(devlink, inline_mode, 731 info->extack); 732 if (err) 733 return err; 734 } 735 736 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) { 737 if (!ops->eswitch_encap_mode_set) 738 return -EOPNOTSUPP; 739 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]); 740 err = ops->eswitch_encap_mode_set(devlink, encap_mode, 741 info->extack); 742 if (err) 743 return err; 744 } 745 746 return 0; 747 } 748 749 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn) 750 { 751 if (!req->msg) 752 return 0; 753 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn); 754 } 755 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put); 756 757 int devlink_info_board_serial_number_put(struct devlink_info_req *req, 758 const char *bsn) 759 { 760 if (!req->msg) 761 return 0; 762 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, 763 bsn); 764 } 765 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put); 766 767 static int devlink_info_version_put(struct devlink_info_req *req, int attr, 768 const char *version_name, 769 const char *version_value, 770 enum devlink_info_version_type version_type) 771 { 772 struct nlattr *nest; 773 int err; 774 775 if (req->version_cb) 776 req->version_cb(version_name, version_type, 777 req->version_cb_priv); 778 779 if (!req->msg || !*version_value) 780 return 0; 781 782 nest = nla_nest_start_noflag(req->msg, attr); 783 if (!nest) 784 return -EMSGSIZE; 785 786 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME, 787 version_name); 788 if (err) 789 goto nla_put_failure; 790 791 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE, 792 version_value); 793 if (err) 794 goto nla_put_failure; 795 796 nla_nest_end(req->msg, nest); 797 798 return 0; 799 800 nla_put_failure: 801 nla_nest_cancel(req->msg, nest); 802 return err; 803 } 804 805 int devlink_info_version_fixed_put(struct devlink_info_req *req, 806 const char *version_name, 807 const char *version_value) 808 { 809 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED, 810 version_name, version_value, 811 DEVLINK_INFO_VERSION_TYPE_NONE); 812 } 813 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put); 814 815 int devlink_info_version_stored_put(struct devlink_info_req *req, 816 const char *version_name, 817 const char *version_value) 818 { 819 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 820 version_name, version_value, 821 DEVLINK_INFO_VERSION_TYPE_NONE); 822 } 823 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put); 824 825 int devlink_info_version_stored_put_ext(struct devlink_info_req *req, 826 const char *version_name, 827 const char *version_value, 828 enum devlink_info_version_type version_type) 829 { 830 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED, 831 version_name, version_value, 832 version_type); 833 } 834 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext); 835 836 int devlink_info_version_running_put(struct devlink_info_req *req, 837 const char *version_name, 838 const char *version_value) 839 { 840 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 841 version_name, version_value, 842 DEVLINK_INFO_VERSION_TYPE_NONE); 843 } 844 EXPORT_SYMBOL_GPL(devlink_info_version_running_put); 845 846 int devlink_info_version_running_put_ext(struct devlink_info_req *req, 847 const char *version_name, 848 const char *version_value, 849 enum devlink_info_version_type version_type) 850 { 851 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING, 852 version_name, version_value, 853 version_type); 854 } 855 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext); 856 857 static int devlink_nl_driver_info_get(struct device_driver *drv, 858 struct devlink_info_req *req) 859 { 860 if (!drv) 861 return 0; 862 863 if (drv->name[0]) 864 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, 865 drv->name); 866 867 return 0; 868 } 869 870 static int 871 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink, 872 enum devlink_command cmd, u32 portid, 873 u32 seq, int flags, struct netlink_ext_ack *extack) 874 { 875 struct device *dev = devlink_to_dev(devlink); 876 struct devlink_info_req req = {}; 877 void *hdr; 878 int err; 879 880 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 881 if (!hdr) 882 return -EMSGSIZE; 883 884 err = -EMSGSIZE; 885 if (devlink_nl_put_handle(msg, devlink)) 886 goto err_cancel_msg; 887 888 req.msg = msg; 889 if (devlink->ops->info_get) { 890 err = devlink->ops->info_get(devlink, &req, extack); 891 if (err) 892 goto err_cancel_msg; 893 } 894 895 err = devlink_nl_driver_info_get(dev->driver, &req); 896 if (err) 897 goto err_cancel_msg; 898 899 genlmsg_end(msg, hdr); 900 return 0; 901 902 err_cancel_msg: 903 genlmsg_cancel(msg, hdr); 904 return err; 905 } 906 907 int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info) 908 { 909 struct devlink *devlink = info->user_ptr[0]; 910 struct sk_buff *msg; 911 int err; 912 913 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 914 if (!msg) 915 return -ENOMEM; 916 917 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 918 info->snd_portid, info->snd_seq, 0, 919 info->extack); 920 if (err) { 921 nlmsg_free(msg); 922 return err; 923 } 924 925 return genlmsg_reply(msg, info); 926 } 927 928 static int 929 devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 930 struct netlink_callback *cb, int flags) 931 { 932 int err; 933 934 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, 935 NETLINK_CB(cb->skb).portid, 936 cb->nlh->nlmsg_seq, flags, 937 cb->extack); 938 if (err == -EOPNOTSUPP) 939 err = 0; 940 return err; 941 } 942 943 int devlink_nl_info_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) 944 { 945 return devlink_nl_dumpit(msg, cb, devlink_nl_info_get_dump_one); 946 } 947 948 static int devlink_nl_flash_update_fill(struct sk_buff *msg, 949 struct devlink *devlink, 950 enum devlink_command cmd, 951 struct devlink_flash_notify *params) 952 { 953 void *hdr; 954 955 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd); 956 if (!hdr) 957 return -EMSGSIZE; 958 959 if (devlink_nl_put_handle(msg, devlink)) 960 goto nla_put_failure; 961 962 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS) 963 goto out; 964 965 if (params->status_msg && 966 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, 967 params->status_msg)) 968 goto nla_put_failure; 969 if (params->component && 970 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, 971 params->component)) 972 goto nla_put_failure; 973 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, 974 params->done)) 975 goto nla_put_failure; 976 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, 977 params->total)) 978 goto nla_put_failure; 979 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, 980 params->timeout)) 981 goto nla_put_failure; 982 983 out: 984 genlmsg_end(msg, hdr); 985 return 0; 986 987 nla_put_failure: 988 genlmsg_cancel(msg, hdr); 989 return -EMSGSIZE; 990 } 991 992 static void __devlink_flash_update_notify(struct devlink *devlink, 993 enum devlink_command cmd, 994 struct devlink_flash_notify *params) 995 { 996 struct sk_buff *msg; 997 int err; 998 999 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE && 1000 cmd != DEVLINK_CMD_FLASH_UPDATE_END && 1001 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS); 1002 1003 if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 1004 return; 1005 1006 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1007 if (!msg) 1008 return; 1009 1010 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params); 1011 if (err) 1012 goto out_free_msg; 1013 1014 devlink_nl_notify_send(devlink, msg); 1015 return; 1016 1017 out_free_msg: 1018 nlmsg_free(msg); 1019 } 1020 1021 static void devlink_flash_update_begin_notify(struct devlink *devlink) 1022 { 1023 struct devlink_flash_notify params = {}; 1024 1025 __devlink_flash_update_notify(devlink, 1026 DEVLINK_CMD_FLASH_UPDATE, 1027 ¶ms); 1028 } 1029 1030 static void devlink_flash_update_end_notify(struct devlink *devlink) 1031 { 1032 struct devlink_flash_notify params = {}; 1033 1034 __devlink_flash_update_notify(devlink, 1035 DEVLINK_CMD_FLASH_UPDATE_END, 1036 ¶ms); 1037 } 1038 1039 void devlink_flash_update_status_notify(struct devlink *devlink, 1040 const char *status_msg, 1041 const char *component, 1042 unsigned long done, 1043 unsigned long total) 1044 { 1045 struct devlink_flash_notify params = { 1046 .status_msg = status_msg, 1047 .component = component, 1048 .done = done, 1049 .total = total, 1050 }; 1051 1052 __devlink_flash_update_notify(devlink, 1053 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1054 ¶ms); 1055 } 1056 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify); 1057 1058 void devlink_flash_update_timeout_notify(struct devlink *devlink, 1059 const char *status_msg, 1060 const char *component, 1061 unsigned long timeout) 1062 { 1063 struct devlink_flash_notify params = { 1064 .status_msg = status_msg, 1065 .component = component, 1066 .timeout = timeout, 1067 }; 1068 1069 __devlink_flash_update_notify(devlink, 1070 DEVLINK_CMD_FLASH_UPDATE_STATUS, 1071 ¶ms); 1072 } 1073 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); 1074 1075 struct devlink_flash_component_lookup_ctx { 1076 const char *lookup_name; 1077 bool lookup_name_found; 1078 }; 1079 1080 static void 1081 devlink_flash_component_lookup_cb(const char *version_name, 1082 enum devlink_info_version_type version_type, 1083 void *version_cb_priv) 1084 { 1085 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv; 1086 1087 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT || 1088 lookup_ctx->lookup_name_found) 1089 return; 1090 1091 lookup_ctx->lookup_name_found = 1092 !strcmp(lookup_ctx->lookup_name, version_name); 1093 } 1094 1095 static int devlink_flash_component_get(struct devlink *devlink, 1096 struct nlattr *nla_component, 1097 const char **p_component, 1098 struct netlink_ext_ack *extack) 1099 { 1100 struct devlink_flash_component_lookup_ctx lookup_ctx = {}; 1101 struct devlink_info_req req = {}; 1102 const char *component; 1103 int ret; 1104 1105 if (!nla_component) 1106 return 0; 1107 1108 component = nla_data(nla_component); 1109 1110 if (!devlink->ops->info_get) { 1111 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1112 "component update is not supported by this device"); 1113 return -EOPNOTSUPP; 1114 } 1115 1116 lookup_ctx.lookup_name = component; 1117 req.version_cb = devlink_flash_component_lookup_cb; 1118 req.version_cb_priv = &lookup_ctx; 1119 1120 ret = devlink->ops->info_get(devlink, &req, NULL); 1121 if (ret) 1122 return ret; 1123 1124 if (!lookup_ctx.lookup_name_found) { 1125 NL_SET_ERR_MSG_ATTR(extack, nla_component, 1126 "selected component is not supported by this device"); 1127 return -EINVAL; 1128 } 1129 *p_component = component; 1130 return 0; 1131 } 1132 1133 int devlink_nl_flash_update_doit(struct sk_buff *skb, struct genl_info *info) 1134 { 1135 struct nlattr *nla_overwrite_mask, *nla_file_name; 1136 struct devlink_flash_update_params params = {}; 1137 struct devlink *devlink = info->user_ptr[0]; 1138 const char *file_name; 1139 u32 supported_params; 1140 int ret; 1141 1142 if (!devlink->ops->flash_update) 1143 return -EOPNOTSUPP; 1144 1145 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME)) 1146 return -EINVAL; 1147 1148 ret = devlink_flash_component_get(devlink, 1149 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT], 1150 ¶ms.component, info->extack); 1151 if (ret) 1152 return ret; 1153 1154 supported_params = devlink->ops->supported_flash_update_params; 1155 1156 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK]; 1157 if (nla_overwrite_mask) { 1158 struct nla_bitfield32 sections; 1159 1160 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) { 1161 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask, 1162 "overwrite settings are not supported by this device"); 1163 return -EOPNOTSUPP; 1164 } 1165 sections = nla_get_bitfield32(nla_overwrite_mask); 1166 params.overwrite_mask = sections.value & sections.selector; 1167 } 1168 1169 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; 1170 file_name = nla_data(nla_file_name); 1171 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1172 if (ret) { 1173 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, 1174 "failed to locate the requested firmware file"); 1175 return ret; 1176 } 1177 1178 devlink_flash_update_begin_notify(devlink); 1179 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); 1180 devlink_flash_update_end_notify(devlink); 1181 1182 release_firmware(params.fw); 1183 1184 return ret; 1185 } 1186 1187 static void __devlink_compat_running_version(struct devlink *devlink, 1188 char *buf, size_t len) 1189 { 1190 struct devlink_info_req req = {}; 1191 const struct nlattr *nlattr; 1192 struct sk_buff *msg; 1193 int rem, err; 1194 1195 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1196 if (!msg) 1197 return; 1198 1199 req.msg = msg; 1200 err = devlink->ops->info_get(devlink, &req, NULL); 1201 if (err) 1202 goto free_msg; 1203 1204 nla_for_each_attr_type(nlattr, DEVLINK_ATTR_INFO_VERSION_RUNNING, 1205 (void *)msg->data, msg->len, rem) { 1206 const struct nlattr *kv; 1207 int rem_kv; 1208 1209 nla_for_each_nested_type(kv, DEVLINK_ATTR_INFO_VERSION_VALUE, 1210 nlattr, rem_kv) { 1211 strlcat(buf, nla_data(kv), len); 1212 strlcat(buf, " ", len); 1213 } 1214 } 1215 free_msg: 1216 nlmsg_consume(msg); 1217 } 1218 1219 void devlink_compat_running_version(struct devlink *devlink, 1220 char *buf, size_t len) 1221 { 1222 if (!devlink->ops->info_get) 1223 return; 1224 1225 devl_lock(devlink); 1226 if (devl_is_registered(devlink)) 1227 __devlink_compat_running_version(devlink, buf, len); 1228 devl_unlock(devlink); 1229 } 1230 1231 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name) 1232 { 1233 struct devlink_flash_update_params params = {}; 1234 int ret; 1235 1236 devl_lock(devlink); 1237 if (!devl_is_registered(devlink)) { 1238 ret = -ENODEV; 1239 goto out_unlock; 1240 } 1241 1242 if (!devlink->ops->flash_update) { 1243 ret = -EOPNOTSUPP; 1244 goto out_unlock; 1245 } 1246 1247 ret = request_firmware(¶ms.fw, file_name, devlink->dev); 1248 if (ret) 1249 goto out_unlock; 1250 1251 devlink_flash_update_begin_notify(devlink); 1252 ret = devlink->ops->flash_update(devlink, ¶ms, NULL); 1253 devlink_flash_update_end_notify(devlink); 1254 1255 release_firmware(params.fw); 1256 out_unlock: 1257 devl_unlock(devlink); 1258 1259 return ret; 1260 } 1261 1262 static int 1263 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink, 1264 u32 portid, u32 seq, int flags, 1265 struct netlink_ext_ack *extack) 1266 { 1267 struct nlattr *selftests; 1268 void *hdr; 1269 int err; 1270 int i; 1271 1272 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, 1273 DEVLINK_CMD_SELFTESTS_GET); 1274 if (!hdr) 1275 return -EMSGSIZE; 1276 1277 err = -EMSGSIZE; 1278 if (devlink_nl_put_handle(msg, devlink)) 1279 goto err_cancel_msg; 1280 1281 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1282 if (!selftests) 1283 goto err_cancel_msg; 1284 1285 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1286 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1287 if (devlink->ops->selftest_check(devlink, i, extack)) { 1288 err = nla_put_flag(msg, i); 1289 if (err) 1290 goto err_cancel_msg; 1291 } 1292 } 1293 1294 nla_nest_end(msg, selftests); 1295 genlmsg_end(msg, hdr); 1296 return 0; 1297 1298 err_cancel_msg: 1299 genlmsg_cancel(msg, hdr); 1300 return err; 1301 } 1302 1303 int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info) 1304 { 1305 struct devlink *devlink = info->user_ptr[0]; 1306 struct sk_buff *msg; 1307 int err; 1308 1309 if (!devlink->ops->selftest_check) 1310 return -EOPNOTSUPP; 1311 1312 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1313 if (!msg) 1314 return -ENOMEM; 1315 1316 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid, 1317 info->snd_seq, 0, info->extack); 1318 if (err) { 1319 nlmsg_free(msg); 1320 return err; 1321 } 1322 1323 return genlmsg_reply(msg, info); 1324 } 1325 1326 static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg, 1327 struct devlink *devlink, 1328 struct netlink_callback *cb, 1329 int flags) 1330 { 1331 if (!devlink->ops->selftest_check) 1332 return 0; 1333 1334 return devlink_nl_selftests_fill(msg, devlink, 1335 NETLINK_CB(cb->skb).portid, 1336 cb->nlh->nlmsg_seq, flags, 1337 cb->extack); 1338 } 1339 1340 int devlink_nl_selftests_get_dumpit(struct sk_buff *skb, 1341 struct netlink_callback *cb) 1342 { 1343 return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one); 1344 } 1345 1346 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, 1347 enum devlink_selftest_status test_status) 1348 { 1349 struct nlattr *result_attr; 1350 1351 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT); 1352 if (!result_attr) 1353 return -EMSGSIZE; 1354 1355 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) || 1356 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS, 1357 test_status)) 1358 goto nla_put_failure; 1359 1360 nla_nest_end(skb, result_attr); 1361 return 0; 1362 1363 nla_put_failure: 1364 nla_nest_cancel(skb, result_attr); 1365 return -EMSGSIZE; 1366 } 1367 1368 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { 1369 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG }, 1370 }; 1371 1372 int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info) 1373 { 1374 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1]; 1375 struct devlink *devlink = info->user_ptr[0]; 1376 struct nlattr *attrs, *selftests; 1377 struct sk_buff *msg; 1378 void *hdr; 1379 int err; 1380 int i; 1381 1382 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check) 1383 return -EOPNOTSUPP; 1384 1385 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS)) 1386 return -EINVAL; 1387 1388 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS]; 1389 1390 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs, 1391 devlink_selftest_nl_policy, info->extack); 1392 if (err < 0) 1393 return err; 1394 1395 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1396 if (!msg) 1397 return -ENOMEM; 1398 1399 err = -EMSGSIZE; 1400 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, 1401 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN); 1402 if (!hdr) 1403 goto free_msg; 1404 1405 if (devlink_nl_put_handle(msg, devlink)) 1406 goto genlmsg_cancel; 1407 1408 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS); 1409 if (!selftests) 1410 goto genlmsg_cancel; 1411 1412 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1; 1413 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) { 1414 enum devlink_selftest_status test_status; 1415 1416 if (nla_get_flag(tb[i])) { 1417 if (!devlink->ops->selftest_check(devlink, i, 1418 info->extack)) { 1419 if (devlink_selftest_result_put(msg, i, 1420 DEVLINK_SELFTEST_STATUS_SKIP)) 1421 goto selftests_nest_cancel; 1422 continue; 1423 } 1424 1425 test_status = devlink->ops->selftest_run(devlink, i, 1426 info->extack); 1427 if (devlink_selftest_result_put(msg, i, test_status)) 1428 goto selftests_nest_cancel; 1429 } 1430 } 1431 1432 nla_nest_end(msg, selftests); 1433 genlmsg_end(msg, hdr); 1434 return genlmsg_reply(msg, info); 1435 1436 selftests_nest_cancel: 1437 nla_nest_cancel(msg, selftests); 1438 genlmsg_cancel: 1439 genlmsg_cancel(msg, hdr); 1440 free_msg: 1441 nlmsg_free(msg); 1442 return err; 1443 } 1444