Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp3039940pxb; Mon, 18 Oct 2021 07:07:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwR2uCUhHyO1oa8APkrATG1Cs0zA6sRU4d7/sVjs+Z2DfG8rrYM3kFIvmwoi5GCFLLXZkmU X-Received: by 2002:aa7:d556:: with SMTP id u22mr15704570edr.226.1634566033296; Mon, 18 Oct 2021 07:07:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634566033; cv=none; d=google.com; s=arc-20160816; b=xWcjte+RNfRV5l3Ea/7BEKLG08+XA1ptV0NCT9YryZiPl+5Cs/euDjoWXVAqFLx4f7 qHz0bwqcmXErftDE7gcjEROrCy3a1gfK8cJAbKX/0GOGQkoNYhRN9WBmLaMzGZySNmfR IzU1fL8bhbdeoQ6vyFA7feyf8pgP2v4zGr1s6047w7MNWkNvHmPc5lEgLGJjgleJmNfy 43Ko5pMbDXQnJCdX10unht5QKt4jiloIVfsDYKPyDkn3ZjRggtLKDwfA1Pfcxoq43F5Y olLSq4VhMzefICAMNqLkNRWG21ig0gQHioO9Xp3MrptVmD6wd4+nyJ4CWdtO1e+dJOHb RWvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=D/ir4D+1vk0Afkyw2x0+ydZSM44fdLKkxQjeUySpdHo=; b=fcHUtCiJZYkUlG0POGLlpHdV1Ca8p6tZ4NLuuJ5iNYNzEhhrG1bKisaxGaRHIhqR9j QtYTUSpDt1X1X+qhbp0Z2wkGt4fb6wpdb/vfMEXCHpwHK3k4hsDmDBT3CLAfR5PMF0h8 1EEXrqYvpgH6/mzWhcQh9yZaPag8sdDVj7+Wo7inYlpyzbuNeB8Mli7ydNy5wzF8eD+C aUanffudeRAUa62OSUbdiIZnYguFcNSkw8D0bqmFPpguEKYM19WZexgVJVUAnUVGTRGE XfzefTfRTElr0janSvrZVBd3Iea5eJJoBvpDd4GO+aapfKYkuRvCCKXQcGH3Cs53bGj1 3caA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=RYnoHJDz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o11si30662272edc.51.2021.10.18.07.06.46; Mon, 18 Oct 2021 07:07:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=RYnoHJDz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233532AbhJROGF (ORCPT + 99 others); Mon, 18 Oct 2021 10:06:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:38668 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234762AbhJROCu (ORCPT ); Mon, 18 Oct 2021 10:02:50 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7B90C61505; Mon, 18 Oct 2021 13:43:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1634564595; bh=wsqFQ2T8wYvjlsxPJLXpdG+TGN0aTjW6u3LdLVfbp6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RYnoHJDzAIN7eyXHlkO7Z2+GfwWRmKTJLUtTwnqUsauJvEKrT1wPS8GfKK3j5mbKT ICVoOALo/ufHOYmcjy264YpAiezEZMBvQlVh55IymKbYRIaEusSdKi05Kp1qaju6hm 7jGuzjBGKNy1uXTAkn7NJKI0TxAimG1wi0o8HYAc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vladimir Oltean , Jakub Kicinski Subject: [PATCH 5.14 149/151] net: mscc: ocelot: cross-check the sequence id from the timestamp FIFO with the skb PTP header Date: Mon, 18 Oct 2021 15:25:28 +0200 Message-Id: <20211018132345.502711115@linuxfoundation.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211018132340.682786018@linuxfoundation.org> References: <20211018132340.682786018@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vladimir Oltean commit ebb4c6a990f786d7e0e4618a0d3766cd660125d8 upstream. The sad reality is that when a PTP frame with a TX timestamping request is transmitted, it isn't guaranteed that it will make it all the way to the wire (due to congestion inside the switch), and that a timestamp will be taken by the hardware and placed in the timestamp FIFO where an IRQ will be raised for it. The implication is that if enough PTP frames are silently dropped by the hardware such that the timestamp ID has rolled over, it is possible to match a timestamp to an old skb. Furthermore, nobody will match on the real skb corresponding to this timestamp, since we stupidly matched on a previous one that was stale in the queue, and stopped there. So PTP timestamping will be broken and there will be no way to recover. It looks like the hardware parses the sequenceID from the PTP header, and also provides that metadata for each timestamp. The driver currently ignores this, but it shouldn't. As an extra resiliency measure, do the following: - check whether the PTP sequenceID also matches between the skb and the timestamp, treat the skb as stale otherwise and free it - if we see a stale skb, don't stop there and try to match an skb one more time, chances are there's one more skb in the queue with the same timestamp ID, otherwise we wouldn't have ever found the stale one (it is by timestamp ID that we matched it). While this does not prevent PTP packet drops, it at least prevents the catastrophic consequences of incorrect timestamp matching. Since we already call ptp_classify_raw in the TX path, save the result in the skb->cb of the clone, and just use that result in the interrupt code path. Fixes: 4e3b0468e6d7 ("net: mscc: PTP Hardware Clock (PHC) support") Signed-off-by: Vladimir Oltean Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mscc/ocelot.c | 24 +++++++++++++++++++++++- include/soc/mscc/ocelot.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -642,6 +642,7 @@ int ocelot_port_txtstamp_request(struct return err; OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd; + OCELOT_SKB_CB(*clone)->ptp_class = ptp_class; } return 0; @@ -675,6 +676,17 @@ static void ocelot_get_hwtimestamp(struc spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); } +static bool ocelot_validate_ptp_skb(struct sk_buff *clone, u16 seqid) +{ + struct ptp_header *hdr; + + hdr = ptp_parse_header(clone, OCELOT_SKB_CB(clone)->ptp_class); + if (WARN_ON(!hdr)) + return false; + + return seqid == ntohs(hdr->sequence_id); +} + void ocelot_get_txtstamp(struct ocelot *ocelot) { int budget = OCELOT_PTP_QUEUE_SZ; @@ -682,10 +694,10 @@ void ocelot_get_txtstamp(struct ocelot * while (budget--) { struct sk_buff *skb, *skb_tmp, *skb_match = NULL; struct skb_shared_hwtstamps shhwtstamps; + u32 val, id, seqid, txport; struct ocelot_port *port; struct timespec64 ts; unsigned long flags; - u32 val, id, txport; val = ocelot_read(ocelot, SYS_PTP_STATUS); @@ -698,6 +710,7 @@ void ocelot_get_txtstamp(struct ocelot * /* Retrieve the ts ID and Tx port */ id = SYS_PTP_STATUS_PTP_MESS_ID_X(val); txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val); + seqid = SYS_PTP_STATUS_PTP_MESS_SEQ_ID(val); port = ocelot->ports[txport]; @@ -707,6 +720,7 @@ void ocelot_get_txtstamp(struct ocelot * spin_unlock(&ocelot->ts_id_lock); /* Retrieve its associated skb */ +try_again: spin_lock_irqsave(&port->tx_skbs.lock, flags); skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { @@ -722,6 +736,14 @@ void ocelot_get_txtstamp(struct ocelot * if (WARN_ON(!skb_match)) continue; + if (!ocelot_validate_ptp_skb(skb_match, seqid)) { + dev_err_ratelimited(ocelot->dev, + "port %d received stale TX timestamp for seqid %d, discarding\n", + txport, seqid); + dev_kfree_skb_any(skb); + goto try_again; + } + /* Get the h/w timestamp */ ocelot_get_hwtimestamp(ocelot, &ts); --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -694,6 +694,7 @@ struct ocelot_policer { struct ocelot_skb_cb { struct sk_buff *clone; + unsigned int ptp_class; /* valid only for clones */ u8 ptp_cmd; u8 ts_id; };