mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
net: pse-pd: si3474: validate the channels of a PI
si3474_get_of_channels() accepted channel 8, one past the last channel.
The driver then accessed channel 4 instead: quad 1, channel index 0.
It also accepted a 4-pair PI whose two channels are not a channel pair
of one quad. The chip forms a 4-pair port only from channels 0+1 or 2+3
of a quad (2P/4P mode bit in POWER_ALLOCATION, PORT_REMAP default), and
the driver sends every register access of a PI to the quad of its first
channel, so such a PI enabled and measured the wrong channels.
Reject both at probe.
Discovered by an AI code review agent; no shipped device tree triggers
it. Validated and tested on an SDG-9000 board (MediaTek MT7988A, two
Si3474) with Linux 6.18 and a modified device tree: one chip with a
channel at reg 8, the other with a 4-pair PI on channels 1 and 2. The
driver now rejects both at probe, and the unmodified device tree still
probes all eight PIs. No kernel selftest covers PSE hardware.
Fixes: a2317231df ("net: pse-pd: Add Si3474 PSE controller driver")
Signed-off-by: Piotr Kubik <piotr@kubik.pl>
Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
Link: https://patch.msgid.link/20261019162453.1244120-3-piotr@kubik.pl
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
b530456be7
commit
110eb80832
|
|
@ -250,9 +250,9 @@ static int si3474_get_of_channels(struct si3474_priv *priv)
|
|||
"Failed to read channel reg property\n");
|
||||
return ret;
|
||||
}
|
||||
if (chan_id > SI3474_MAX_CHANS) {
|
||||
if (chan_id >= SI3474_MAX_CHANS) {
|
||||
dev_err(&priv->client[0]->dev,
|
||||
"Incorrect channel number: %d\n", chan_id);
|
||||
"Incorrect channel number: %u\n", chan_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -267,6 +267,16 @@ static int si3474_get_of_channels(struct si3474_priv *priv)
|
|||
pi->np);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The 2P/4P mode bit pairs channels 0+1 and 2+3 of a quad */
|
||||
if (pairset_found &&
|
||||
(priv->pi[pi_no].chan[0] ^ 1) != priv->pi[pi_no].chan[1]) {
|
||||
dev_err(&priv->client[0]->dev,
|
||||
"PI %pOF: channels %u and %u are not a channel pair\n",
|
||||
pi->np, priv->pi[pi_no].chan[0],
|
||||
priv->pi[pi_no].chan[1]);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user