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