From: Simon Horman <horms@kernel.org>
To: Parvathi Pudi <parvathi@couthit.com>
Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, danishanwar@ti.com,
rogerq@kernel.org, pmohan@couthit.com, basharath@couthit.com,
afd@ti.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, alok.a.tiwari@oracle.com,
pratheesh@ti.com, j-rameshbabu@ti.com, vigneshr@ti.com,
praneeth@ti.com, srk@ti.com, rogerq@ti.com, krishna@couthit.com,
mohan@couthit.com
Subject: Re: [PATCH net-next v5 1/3] net: ti: icssm-prueth: Adds helper functions to configure and maintain FDB
Date: Mon, 17 Nov 2025 21:07:19 +0000 [thread overview]
Message-ID: <aRuOh-O99Xwo1nG0@horms.kernel.org> (raw)
In-Reply-To: <20251113101229.675141-2-parvathi@couthit.com>
On Thu, Nov 13, 2025 at 03:40:21PM +0530, Parvathi Pudi wrote:
...
> +static u16 icssm_prueth_sw_fdb_find_open_slot(struct fdb_tbl *fdb_tbl)
> +{
> + u8 flags;
> + u16 i;
> +
> + for (i = 0; i < FDB_MAC_TBL_MAX_ENTRIES; i++) {
> + flags = readb(&fdb_tbl->mac_tbl_a->mac_tbl_entry[i].flags);
> + if (!(flags & FLAG_ACTIVE))
> + break;
Hi Parvathi, all,
If the condition above is never met....
> + }
> +
> + return i;
Then FDB_MAC_TBL_MAX_ENTRIES will be returned here.
Which is written to bkt_info->bucket_idx by
icssm_prueth_sw_insert_fdb_entry()...
> +}
> +
> +static int
> +icssm_prueth_sw_find_fdb_insert(struct fdb_tbl *fdb, struct prueth *prueth,
> + struct fdb_index_tbl_entry __iomem *bkt_info,
> + const u8 *mac, const u8 port)
> +{
> + struct fdb_mac_tbl_array __iomem *mac_tbl = fdb->mac_tbl_a;
> + struct fdb_mac_tbl_entry __iomem *e;
> + u8 mac_from_hw[ETH_ALEN];
> + u16 bucket_entries;
> + u16 mac_tbl_idx;
> + int i, ret;
> + s8 cmp;
> +
> + mac_tbl_idx = readw(&bkt_info->bucket_idx);
That value will be read here...
> + bucket_entries = readw(&bkt_info->bucket_entries);
> +
> + for (i = 0; i < bucket_entries; i++, mac_tbl_idx++) {
> + e = &mac_tbl->mac_tbl_entry[mac_tbl_idx];
And used here, without any bounds checking.
But if mac_tbl_idx is FDB_MAC_TBL_MAX_ENTRIES then
the access to mac_tble_entry will overflow, as
it only has FDB_MAC_TBL_MAX_ENTRIES elements.
This, and most of my review points for this patch set were
flagged by Claude Code with https://github.com/masoncl/review-prompts/
...
> +static int icssm_prueth_sw_insert_fdb_entry(struct prueth_emac *emac,
> + const u8 *mac, u8 is_static)
> +{
> + struct fdb_index_tbl_entry __iomem *bucket_info;
> + struct fdb_mac_tbl_entry __iomem *mac_info;
> + struct prueth *prueth = emac->prueth;
> + struct prueth_emac *other_emac;
> + enum prueth_port other_port_id;
> + u8 hash_val, mac_tbl_idx;
> + struct fdb_tbl *fdb;
> + u8 flags;
> + u16 val;
> + s16 ret;
> + int err;
> +
> + fdb = prueth->fdb_tbl;
> + other_port_id = (emac->port_id == PRUETH_PORT_MII0) ?
> + PRUETH_PORT_MII1 : PRUETH_PORT_MII0;
> +
> + other_emac = prueth->emac[other_port_id - 1];
> +
> + if (fdb->total_entries == FDB_MAC_TBL_MAX_ENTRIES)
> + return -ENOMEM;
Access to total_entries outside of icssm_prueth_sw_fdb_spin_lock.
Seems racy here. Likewise for the similar check in
icssm_prueth_sw_delete_fdb_entry().
Flagged by Claude Code with https://github.com/masoncl/review-prompts/
> +
> + if (ether_addr_equal(mac, emac->mac_addr) ||
> + ether_addr_equal(mac, other_emac->mac_addr)) {
> + /* Don't insert fdb of own mac addr */
> + return -EINVAL;
> + }
> +
> + /* Get the bucket that the mac belongs to */
> + hash_val = icssm_prueth_sw_fdb_hash(mac);
> + bucket_info = FDB_IDX_TBL_ENTRY(hash_val);
> +
> + if (!readw(&bucket_info->bucket_entries)) {
> + mac_tbl_idx = icssm_prueth_sw_fdb_find_open_slot(fdb);
> + writew(mac_tbl_idx, &bucket_info->bucket_idx);
> + }
> +
> + ret = icssm_prueth_sw_find_fdb_insert(fdb, prueth, bucket_info, mac,
> + emac->port_id - 1);
> + if (ret < 0)
> + /* mac is already in fdb table */
> + return 0;
> +
> + mac_tbl_idx = ret;
> +
> + err = icssm_prueth_sw_fdb_spin_lock(fdb);
> + if (err) {
> + dev_err(prueth->dev, "PRU lock timeout %d\n", ret);
> + return err;
> + }
> +
> + mac_info = icssm_prueth_sw_find_free_mac(prueth, bucket_info,
> + mac_tbl_idx, NULL,
> + mac);
> + if (!mac_info) {
> + /* Should not happen */
> + dev_warn(prueth->dev, "OUT of FDB MEM\n");
This appears to leak icssm_prueth_sw_fdb_spin_lock.
Also flagged by Claude Code with https://github.com/masoncl/review-prompts/
> + return -ENOMEM;
> + }
> +
> + memcpy_toio(mac_info->mac, mac, ETH_ALEN);
> + writew(0, &mac_info->age);
> + writeb(emac->port_id - 1, &mac_info->port);
> +
> + flags = readb(&mac_info->flags);
> + if (is_static)
> + flags |= FLAG_IS_STATIC;
> + else
> + flags &= ~FLAG_IS_STATIC;
> +
> + /* bit 1 - active */
> + flags |= FLAG_ACTIVE;
> + writeb(flags, &mac_info->flags);
> +
> + val = readw(&bucket_info->bucket_entries);
> + val++;
> + writew(val, &bucket_info->bucket_entries);
> +
> + fdb->total_entries++;
> +
> + icssm_prueth_sw_fdb_spin_unlock(fdb);
> +
> + dev_dbg(prueth->dev, "added fdb: %pM port=%d total_entries=%u\n",
> + mac, emac->port_id, fdb->total_entries);
Less important, but I think the value of total_entries could
be out of date as it's accessed outside of the lock.
Perhaps it would be good to stash the value into a local variable while
the lock is still held?
Likewise in icssm_prueth_sw_delete_fdb_entry().
> +
> + return 0;
> +}
> +
> +static int icssm_prueth_sw_delete_fdb_entry(struct prueth_emac *emac,
> + const u8 *mac, u8 is_static)
> +{
> + struct fdb_index_tbl_entry __iomem *bucket_info;
> + struct fdb_mac_tbl_entry __iomem *mac_info;
> + struct fdb_mac_tbl_array __iomem *mt;
> + u8 hash_val, mac_tbl_idx;
> + u16 idx, entries, val;
> + struct prueth *prueth;
> + s16 ret, left, right;
> + struct fdb_tbl *fdb;
> + u8 flags;
> + int err;
> +
> + prueth = emac->prueth;
> + fdb = prueth->fdb_tbl;
> + mt = fdb->mac_tbl_a;
> +
> + if (fdb->total_entries == 0)
> + return 0;
> +
> + /* Get the bucket that the mac belongs to */
> + hash_val = icssm_prueth_sw_fdb_hash(mac);
> + bucket_info = FDB_IDX_TBL_ENTRY(hash_val);
> +
> + ret = icssm_prueth_sw_fdb_search(mt, bucket_info, mac);
> + if (ret < 0)
> + return ret;
> +
> + mac_tbl_idx = ret;
> + mac_info = FDB_MAC_TBL_ENTRY(mac_tbl_idx);
> +
> + err = icssm_prueth_sw_fdb_spin_lock(fdb);
> + if (err) {
> + dev_err(prueth->dev, "PRU lock timeout %d\n", ret);
> + return ret;
> + }
> +
> + /* Shift all elements in bucket to the left. No need to
> + * update index table since only shifting within bucket.
> + */
> + left = mac_tbl_idx;
> + idx = readw(&bucket_info->bucket_idx);
> + entries = readw(&bucket_info->bucket_entries);
> + right = idx + entries - 1;
> + icssm_prueth_sw_fdb_move_range_left(prueth, left, right);
> +
> + /* Remove end of bucket from table */
> + mac_info = FDB_MAC_TBL_ENTRY(right);
> + flags = readb(&mac_info->flags);
> + /* active = 0 */
> + flags &= ~FLAG_ACTIVE;
> + writeb(flags, &mac_info->flags);
> + val = readw(&bucket_info->bucket_entries);
> + val--;
> + writew(val, &bucket_info->bucket_entries);
> + fdb->total_entries--;
> +
> + icssm_prueth_sw_fdb_spin_unlock(fdb);
> +
> + dev_dbg(prueth->dev, "del fdb: %pM total_entries=%u\n",
> + mac, fdb->total_entries);
> +
> + return 0;
> +}
...
next prev parent reply other threads:[~2025-11-17 21:07 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-13 10:10 [PATCH net-next v5 0/3] STP/RSTP SWITCH support for PRU-ICSSM Ethernet driver Parvathi Pudi
2025-11-13 10:10 ` [PATCH net-next v5 1/3] net: ti: icssm-prueth: Adds helper functions to configure and maintain FDB Parvathi Pudi
2025-11-17 21:07 ` Simon Horman [this message]
2025-11-20 6:20 ` Parvathi Pudi
2025-11-13 10:10 ` [PATCH net-next v5 2/3] net: ti: icssm-prueth: Adds switchdev support for icssm_prueth driver Parvathi Pudi
2025-11-17 21:08 ` Simon Horman
2025-11-20 6:22 ` Parvathi Pudi
2025-11-13 10:10 ` [PATCH net-next v5 3/3] net: ti: icssm-prueth: Adds support for ICSSM RSTP switch Parvathi Pudi
2025-11-17 21:09 ` Simon Horman
2025-11-20 6:25 ` Parvathi Pudi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aRuOh-O99Xwo1nG0@horms.kernel.org \
--to=horms@kernel.org \
--cc=afd@ti.com \
--cc=alok.a.tiwari@oracle.com \
--cc=andrew+netdev@lunn.ch \
--cc=basharath@couthit.com \
--cc=danishanwar@ti.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=j-rameshbabu@ti.com \
--cc=krishna@couthit.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mohan@couthit.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=parvathi@couthit.com \
--cc=pmohan@couthit.com \
--cc=praneeth@ti.com \
--cc=pratheesh@ti.com \
--cc=rogerq@kernel.org \
--cc=rogerq@ti.com \
--cc=srk@ti.com \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).