Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp3796662imm; Mon, 18 Jun 2018 04:20:32 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJ5a+usJhTRGlA5BwUzOezwXXvwqxWnOic5DEkm/jmVqq4NzX/CntcDbeFEadHY+DFDBSgs X-Received: by 2002:a65:660a:: with SMTP id w10-v6mr10442124pgv.366.1529320832854; Mon, 18 Jun 2018 04:20:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529320832; cv=none; d=google.com; s=arc-20160816; b=Cxw308USAAddHS1X5zynH1lvayvJg30w/PBCOXw1+NBgSV/QZCTZCewKYO9CTifnOA GssShVc61r0bDWyoY1bh98Vhw8zJrMGTqdx4uldmWueYPi4Luc2UnCHuy7tm1cyQZYWt gMHZYUa+9ueyFlnhYa22i/mSDHzgtaTZDeH96XEv8ZQEyYukkWiSIA/BJdpnZmAGIhkm ev03lxu/S5QinTmbYMXm4Xen7tqZoaUlURNhuSJ/JyJmFPN7gPXQhF/iKoQI3dlh+qHW i1sr/HEhLXFtGF6sj80JmPCs992QVST/CO1vJzpWOoFL/4G+CwrO9RuGaoi+7/jHP6PE kFVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=XxQl08u4bOYi1XjOecfmDCkxipyLoupMWYTPgaNXo1w=; b=ejzgXG222gdgQWMzfSiSUuWG8XZHNtJn+TD26Z0MPGDoEvHawwRCPQGhw9V+5FzYTd SSo3a/PgBxkvDET+ruy51Cl7215Y83mwfEEZyX4tdfAdJtlMvY5pXpn8F1NekQHdhegI 9RU0afH1BSEqfeWYIBAX5mjfBhGIrR3gNpZxNmR5xWBTFPhSfihY/I2SfYo7t/Su8y30 s3vCs1zgYnpBkuus+sKK6LTXsfzcdK2Q3N5+ZAwqlGyb0LuotNgkB05jpdoXXS61WwNJ QC/znkTr3KMuW4uKu3Ol9ngXXO9xWIFSMDPcXJOBdq0TRiyrY1xZQAdrneyXMgjn63eo uOeg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g9-v6si4212733pgs.385.2018.06.18.04.20.19; Mon, 18 Jun 2018 04:20:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965776AbeFRKDr (ORCPT + 99 others); Mon, 18 Jun 2018 06:03:47 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:54514 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935034AbeFRISO (ORCPT ); Mon, 18 Jun 2018 04:18:14 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 98FB1C83; Mon, 18 Jun 2018 08:18:13 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Julian Wiedmann , "David S. Miller" , Sasha Levin Subject: [PATCH 4.16 073/279] s390/qeth: fix MAC address update sequence Date: Mon, 18 Jun 2018 10:10:58 +0200 Message-Id: <20180618080611.840311686@linuxfoundation.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180618080608.851973560@linuxfoundation.org> References: <20180618080608.851973560@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.16-stable review patch. If anyone has any objections, please let me know. ------------------ From: Julian Wiedmann [ Upstream commit bcacfcbc82b4235d280ed9b067aa4567f4a0c756 ] When changing the MAC address on a L2 qeth device, current code first unregisters the old address, then registers the new one. If HW rejects the new address (or the IO fails), the device ends up with no operable address at all. Re-order the code flow so that the old address only gets dropped if the new address was registered successfully. While at it, add logic to catch some corner-cases. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/s390/net/qeth_l2_main.c | 55 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 24 deletions(-) --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -122,13 +122,10 @@ static int qeth_l2_send_setmac(struct qe QETH_CARD_TEXT(card, 2, "L2Setmac"); rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC); if (rc == 0) { - card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; - ether_addr_copy(card->dev->dev_addr, mac); dev_info(&card->gdev->dev, - "MAC address %pM successfully registered on device %s\n", - card->dev->dev_addr, card->dev->name); + "MAC address %pM successfully registered on device %s\n", + mac, card->dev->name); } else { - card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; switch (rc) { case -EEXIST: dev_warn(&card->gdev->dev, @@ -143,19 +140,6 @@ static int qeth_l2_send_setmac(struct qe return rc; } -static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) -{ - int rc; - - QETH_CARD_TEXT(card, 2, "L2Delmac"); - if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) - return 0; - rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC); - if (rc == 0) - card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; - return rc; -} - static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac) { enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ? @@ -522,6 +506,7 @@ static int qeth_l2_set_mac_address(struc { struct sockaddr *addr = p; struct qeth_card *card = dev->ml_priv; + u8 old_addr[ETH_ALEN]; int rc = 0; QETH_CARD_TEXT(card, 3, "setmac"); @@ -533,14 +518,35 @@ static int qeth_l2_set_mac_address(struc return -EOPNOTSUPP; } QETH_CARD_HEX(card, 3, addr->sa_data, ETH_ALEN); + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { QETH_CARD_TEXT(card, 3, "setmcREC"); return -ERESTARTSYS; } - rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); - if (!rc || (rc == -ENOENT)) - rc = qeth_l2_send_setmac(card, addr->sa_data); - return rc ? -EINVAL : 0; + + if (!qeth_card_hw_is_reachable(card)) { + ether_addr_copy(dev->dev_addr, addr->sa_data); + return 0; + } + + /* don't register the same address twice */ + if (ether_addr_equal_64bits(dev->dev_addr, addr->sa_data) && + (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) + return 0; + + /* add the new address, switch over, drop the old */ + rc = qeth_l2_send_setmac(card, addr->sa_data); + if (rc) + return rc; + ether_addr_copy(old_addr, dev->dev_addr); + ether_addr_copy(dev->dev_addr, addr->sa_data); + + if (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED) + qeth_l2_remove_mac(card, old_addr); + card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; + return 0; } static void qeth_promisc_to_bridge(struct qeth_card *card) @@ -1067,8 +1073,9 @@ static int __qeth_l2_set_online(struct c goto out_remove; } - if (card->info.type != QETH_CARD_TYPE_OSN) - qeth_l2_send_setmac(card, &card->dev->dev_addr[0]); + if (card->info.type != QETH_CARD_TYPE_OSN && + !qeth_l2_send_setmac(card, card->dev->dev_addr)) + card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) { if (card->info.hwtrap &&