lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1600063682-17313-15-git-send-email-moshe@mellanox.com>
Date:   Mon, 14 Sep 2020 09:08:01 +0300
From:   Moshe Shemesh <moshe@...lanox.com>
To:     "David S. Miller" <davem@...emloft.net>,
        Jakub Kicinski <kuba@...nel.org>,
        Jiri Pirko <jiri@...lanox.com>
Cc:     netdev@...r.kernel.org, linux-kernel@...r.kernel.org,
        Moshe Shemesh <moshe@...lanox.com>
Subject: [PATCH net-next RFC v4 14/15] net/mlx5: Add support for devlink reload action limit level no reset

Add support for devlink reload action fw_activate with limit level
no_reset which does firmware live patching, updating the firmware image
without reset, no downtime and no configuration lose. The driver checks
if the firmware is capable of handling the pending firmware changes as a
live patch. If it is then it triggers firmware live patching flow.

Signed-off-by: Moshe Shemesh <moshe@...lanox.com>
---
v3 -> v4:
- Have action fw_activate with limit level no_reset instead of action
  fw_activate_no_reset
v2 -> v3:
- Replace fw_live_patch action by fw_activate_no_reset
v1 -> v2:
- Have fw_live_patch action instead of level
---
 .../net/ethernet/mellanox/mlx5/core/devlink.c | 37 ++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index 175e933cf19c..f2cc62b7232d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -115,6 +115,29 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
 	return err;
 }
 
+static int mlx5_devlink_trigger_fw_live_patch(struct devlink *devlink,
+					      struct netlink_ext_ack *extack)
+{
+	struct mlx5_core_dev *dev = devlink_priv(devlink);
+	u8 reset_level;
+	int err;
+
+	err = mlx5_reg_mfrl_query(dev, &reset_level, NULL);
+	if (err)
+		return err;
+	if (!(reset_level & MLX5_MFRL_REG_RESET_LEVEL0)) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "FW upgrade to the stored FW can't be done by FW live patching");
+		return -EINVAL;
+	}
+
+	err = mlx5_fw_set_live_patch(dev);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
 				    enum devlink_reload_action action,
 				    enum devlink_reload_action_limit_level limit_level,
@@ -122,11 +145,19 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
 {
 	struct mlx5_core_dev *dev = devlink_priv(devlink);
 
+	if (limit_level == DEVLINK_RELOAD_ACTION_LIMIT_LEVEL_NO_RESET &&
+	    action != DEVLINK_RELOAD_ACTION_FW_ACTIVATE) {
+		NL_SET_ERR_MSG_MOD(extack, "Requested limit level is not supported");
+		return -EOPNOTSUPP;
+	}
+
 	switch (action) {
 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 		mlx5_unload_one(dev, false);
 		return 0;
 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
+		if (limit_level == DEVLINK_RELOAD_ACTION_LIMIT_LEVEL_NO_RESET)
+			return mlx5_devlink_trigger_fw_live_patch(devlink, extack);
 		return mlx5_devlink_reload_fw_activate(devlink, extack);
 	default:
 		/* Unsupported action should not get to this function */
@@ -146,7 +177,10 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
 
 	switch (action) {
 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
+		return mlx5_load_one(dev, false);
 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
+		if (limit_level == DEVLINK_RELOAD_ACTION_LIMIT_LEVEL_NO_RESET)
+			break;
 		/* On fw_activate action, also driver is reloaded and reinit performed */
 		if (actions_performed)
 			*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
@@ -175,7 +209,8 @@ static const struct devlink_ops mlx5_devlink_ops = {
 	.info_get = mlx5_devlink_info_get,
 	.supported_reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
 				    BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
-	.supported_reload_action_limit_levels = BIT(DEVLINK_RELOAD_ACTION_LIMIT_LEVEL_NONE),
+	.supported_reload_action_limit_levels = BIT(DEVLINK_RELOAD_ACTION_LIMIT_LEVEL_NONE) |
+						BIT(DEVLINK_RELOAD_ACTION_LIMIT_LEVEL_NO_RESET),
 	.reload_down = mlx5_devlink_reload_down,
 	.reload_up = mlx5_devlink_reload_up,
 };
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ