Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4ED1FC43217 for ; Tue, 30 Nov 2021 14:53:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243100AbhK3O4W (ORCPT ); Tue, 30 Nov 2021 09:56:22 -0500 Received: from sin.source.kernel.org ([145.40.73.55]:58124 "EHLO sin.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243020AbhK3Oxh (ORCPT ); Tue, 30 Nov 2021 09:53:37 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id ADDA1CE1A5D; Tue, 30 Nov 2021 14:50:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BD2A1C53FCF; Tue, 30 Nov 2021 14:50:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1638283814; bh=Bjexz0kYT2ZxeQujlzx1Ck7HxUZ1U2LiuLmVzBxO43A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Hk/cOShc8GnCWGP30p8wxzD0YjXOcD0m58kUg2WXfAWF4ZRkOxkmz7uzSypUaftz1 wlxyIuYa8Mll1scvAk+WHZm2IjocKx2G7YtZ5JN8CgbSbSxP80arF5zJajzT2YM4rV /1WqkI3VXzYyfosivCdSNFxTIKGUSgW7VoX2HqcX21s6A1A5j2NCROSpjkSVEZEi5G V4xh6huYsVMBhZjPAh+cI1aiEUjisjwLfGg36ywe8kyrtHfEZ+W4M2e/Q2vgj4m77T sXPX7jlWqjPo03Ld5Q0j5aFlReC85dSOYfQhHBjVfNSbgvIOno7qarcCLDz4kzASae xjEAy0/mnw8nQ== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Vladimir Oltean , Richard Cochran , Jakub Kicinski , Sasha Levin , claudiu.manoil@nxp.com, alexandre.belloni@bootlin.com, UNGLinuxDriver@microchip.com, davem@davemloft.net, netdev@vger.kernel.org Subject: [PATCH AUTOSEL 5.15 65/68] net: mscc: ocelot: create a function that replaces an existing VCAP filter Date: Tue, 30 Nov 2021 09:47:01 -0500 Message-Id: <20211130144707.944580-65-sashal@kernel.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211130144707.944580-1-sashal@kernel.org> References: <20211130144707.944580-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vladimir Oltean [ Upstream commit 95706be13b9f755d93b5b82bdc782af439f1ec22 ] VCAP (Versatile Content Aware Processor) is the TCAM-based engine behind tc flower offload on ocelot, among other things. The ingress port mask on which VCAP rules match is present as a bit field in the actual key of the rule. This means that it is possible for a rule to be shared among multiple source ports. When the rule is added one by one on each desired port, that the ingress port mask of the key must be edited and rewritten to hardware. But the API in ocelot_vcap.c does not allow for this. For one thing, ocelot_vcap_filter_add() and ocelot_vcap_filter_del() are not symmetric, because ocelot_vcap_filter_add() works with a preallocated and prepopulated filter and programs it to hardware, and ocelot_vcap_filter_del() does both the job of removing the specified filter from hardware, as well as kfreeing it. That is to say, the only option of editing a filter in place, which is to delete it, modify the structure and add it back, does not work because it results in use-after-free. This patch introduces ocelot_vcap_filter_replace, which trivially reprograms a VCAP entry to hardware, at the exact same index at which it existed before, without modifying any list or allocating any memory. Signed-off-by: Vladimir Oltean Acked-by: Richard Cochran Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mscc/ocelot_vcap.c | 16 ++++++++++++++++ include/soc/mscc/ocelot_vcap.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c index 99d7376a70a74..337cd08b1a543 100644 --- a/drivers/net/ethernet/mscc/ocelot_vcap.c +++ b/drivers/net/ethernet/mscc/ocelot_vcap.c @@ -1217,6 +1217,22 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot, } EXPORT_SYMBOL(ocelot_vcap_filter_del); +int ocelot_vcap_filter_replace(struct ocelot *ocelot, + struct ocelot_vcap_filter *filter) +{ + struct ocelot_vcap_block *block = &ocelot->block[filter->block_id]; + int index; + + index = ocelot_vcap_block_get_filter_index(block, filter); + if (index < 0) + return index; + + vcap_entry_set(ocelot, index, filter); + + return 0; +} +EXPORT_SYMBOL(ocelot_vcap_filter_replace); + int ocelot_vcap_filter_stats_update(struct ocelot *ocelot, struct ocelot_vcap_filter *filter) { diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h index 4869ebbd438d9..56c19068d9911 100644 --- a/include/soc/mscc/ocelot_vcap.h +++ b/include/soc/mscc/ocelot_vcap.h @@ -693,6 +693,8 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot, struct netlink_ext_ack *extack); int ocelot_vcap_filter_del(struct ocelot *ocelot, struct ocelot_vcap_filter *rule); +int ocelot_vcap_filter_replace(struct ocelot *ocelot, + struct ocelot_vcap_filter *filter); struct ocelot_vcap_filter * ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, unsigned long cookie, bool tc_offload); -- 2.33.0