2022-10-09 22:10:13

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 01/77] libbpf: Ensure functions with always_inline attribute are inline

From: James Hilliard <[email protected]>

[ Upstream commit d25f40ff68aa61c838947bb9adee6c6b36e77453 ]

GCC expects the always_inline attribute to only be set on inline
functions, as such we should make all functions with this attribute
use the __always_inline macro which makes the function inline and
sets the attribute.

Fixes errors like:
/home/buildroot/bpf-next/tools/testing/selftests/bpf/tools/include/bpf/bpf_tracing.h:439:1: error: ‘always_inline’ function might not be inlinable [-Werror=attributes]
439 | ____##name(unsigned long long *ctx, ##args)
| ^~~~

Signed-off-by: James Hilliard <[email protected]>
Signed-off-by: Andrii Nakryiko <[email protected]>
Acked-by: Jiri Olsa <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
tools/lib/bpf/bpf_tracing.h | 14 +++++++-------
tools/lib/bpf/usdt.bpf.h | 4 ++--
2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
index 43ca3aff2292..5fdb93da423b 100644
--- a/tools/lib/bpf/bpf_tracing.h
+++ b/tools/lib/bpf/bpf_tracing.h
@@ -426,7 +426,7 @@ struct pt_regs;
*/
#define BPF_PROG(name, args...) \
name(unsigned long long *ctx); \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(unsigned long long *ctx, ##args); \
typeof(name(0)) name(unsigned long long *ctx) \
{ \
@@ -435,7 +435,7 @@ typeof(name(0)) name(unsigned long long *ctx) \
return ____##name(___bpf_ctx_cast(args)); \
_Pragma("GCC diagnostic pop") \
} \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(unsigned long long *ctx, ##args)

struct pt_regs;
@@ -460,7 +460,7 @@ struct pt_regs;
*/
#define BPF_KPROBE(name, args...) \
name(struct pt_regs *ctx); \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args); \
typeof(name(0)) name(struct pt_regs *ctx) \
{ \
@@ -469,7 +469,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \
return ____##name(___bpf_kprobe_args(args)); \
_Pragma("GCC diagnostic pop") \
} \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args)

#define ___bpf_kretprobe_args0() ctx
@@ -484,7 +484,7 @@ ____##name(struct pt_regs *ctx, ##args)
*/
#define BPF_KRETPROBE(name, args...) \
name(struct pt_regs *ctx); \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args); \
typeof(name(0)) name(struct pt_regs *ctx) \
{ \
@@ -540,7 +540,7 @@ static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
#define BPF_KSYSCALL(name, args...) \
name(struct pt_regs *ctx); \
extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig; \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args); \
typeof(name(0)) name(struct pt_regs *ctx) \
{ \
@@ -555,7 +555,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \
return ____##name(___bpf_syscall_args(args)); \
_Pragma("GCC diagnostic pop") \
} \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args)

#define BPF_KPROBE_SYSCALL BPF_KSYSCALL
diff --git a/tools/lib/bpf/usdt.bpf.h b/tools/lib/bpf/usdt.bpf.h
index 4f2adc0bd6ca..fdfd235e52c4 100644
--- a/tools/lib/bpf/usdt.bpf.h
+++ b/tools/lib/bpf/usdt.bpf.h
@@ -232,7 +232,7 @@ long bpf_usdt_cookie(struct pt_regs *ctx)
*/
#define BPF_USDT(name, args...) \
name(struct pt_regs *ctx); \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args); \
typeof(name(0)) name(struct pt_regs *ctx) \
{ \
@@ -241,7 +241,7 @@ typeof(name(0)) name(struct pt_regs *ctx) \
return ____##name(___bpf_usdt_args(args)); \
_Pragma("GCC diagnostic pop") \
} \
-static __attribute__((always_inline)) typeof(name(0)) \
+static __always_inline typeof(name(0)) \
____##name(struct pt_regs *ctx, ##args)

#endif /* __USDT_BPF_H__ */
--
2.35.1


2022-10-09 22:10:21

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 02/77] libbpf: Do not require executable permission for shared libraries

From: Hengqi Chen <[email protected]>

[ Upstream commit 9e32084ef1c33a87a736d6ce3fcb95b60dac9aa1 ]

Currently, resolve_full_path() requires executable permission for both
programs and shared libraries. This causes failures on distos like Debian
since the shared libraries are not installed executable and Linux is not
requiring shared libraries to have executable permissions. Let's remove
executable permission check for shared libraries.

Reported-by: Goro Fuji <[email protected]>
Signed-off-by: Hengqi Chen <[email protected]>
Signed-off-by: Andrii Nakryiko <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
tools/lib/bpf/libbpf.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 50d41815f431..c09a781d31bb 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -10662,15 +10662,17 @@ static const char *arch_specific_lib_paths(void)
static int resolve_full_path(const char *file, char *result, size_t result_sz)
{
const char *search_paths[3] = {};
- int i;
+ int i, perm;

if (str_has_sfx(file, ".so") || strstr(file, ".so.")) {
search_paths[0] = getenv("LD_LIBRARY_PATH");
search_paths[1] = "/usr/lib64:/usr/lib";
search_paths[2] = arch_specific_lib_paths();
+ perm = R_OK;
} else {
search_paths[0] = getenv("PATH");
search_paths[1] = "/usr/bin:/usr/sbin";
+ perm = R_OK | X_OK;
}

for (i = 0; i < ARRAY_SIZE(search_paths); i++) {
@@ -10689,8 +10691,8 @@ static int resolve_full_path(const char *file, char *result, size_t result_sz)
if (!seg_len)
continue;
snprintf(result, result_sz, "%.*s/%s", seg_len, s, file);
- /* ensure it is an executable file/link */
- if (access(result, R_OK | X_OK) < 0)
+ /* ensure it has required permissions */
+ if (access(result, perm) < 0)
continue;
pr_debug("resolved '%s' to '%s'\n", file, result);
return 0;
--
2.35.1

2022-10-09 22:10:49

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 07/77] ice: set tx_tstamps when creating new Tx rings via ethtool

From: Jacob Keller <[email protected]>

[ Upstream commit b3b173745c8cab1e24d6821488b60abed3acb24d ]

When the user changes the number of queues via ethtool, the driver
allocates new rings. This allocation did not initialize tx_tstamps. This
results in the tx_tstamps field being zero (due to kcalloc allocation), and
would result in a NULL pointer dereference when attempting a transmit
timestamp on the new ring.

Signed-off-by: Jacob Keller <[email protected]>
Tested-by: Gurucharan <[email protected]> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/intel/ice/ice_ethtool.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
index a6fff8ebaf9d..bbf6a300078e 100644
--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -2826,6 +2826,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
tx_rings[i].count = new_tx_cnt;
tx_rings[i].desc = NULL;
tx_rings[i].tx_buf = NULL;
+ tx_rings[i].tx_tstamps = &pf->ptp.port.tx;
err = ice_setup_tx_ring(&tx_rings[i]);
if (err) {
while (i--)
--
2.35.1

2022-10-09 22:10:59

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 06/77] bpftool: Clear errno after libcap's checks

From: Quentin Monnet <[email protected]>

[ Upstream commit cea558855c39b7f1f02ff50dcf701ca6596bc964 ]

When bpftool is linked against libcap, the library runs a "constructor"
function to compute the number of capabilities of the running kernel
[0], at the beginning of the execution of the program. As part of this,
it performs multiple calls to prctl(). Some of these may fail, and set
errno to a non-zero value:

# strace -e prctl ./bpftool version
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
** fprintf added at the top of main(): we have errno == 1
./bpftool v7.0.0
using libbpf v1.0
features: libbfd, libbpf_strict, skeletons
+++ exited with 0 +++

This has been addressed in libcap 2.63 [1], but until this version is
available everywhere, we can fix it on bpftool side.

Let's clean errno at the beginning of the main() function, to make sure
that these checks do not interfere with the batch mode, where we error
out if errno is set after a bpftool command.

[0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/tree/libcap/cap_alloc.c?h=libcap-2.65#n20
[1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=f25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0

Signed-off-by: Quentin Monnet <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
tools/bpf/bpftool/main.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 451cefc2d0da..ccd7457f92bf 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -435,6 +435,16 @@ int main(int argc, char **argv)

setlinebuf(stdout);

+#ifdef USE_LIBCAP
+ /* Libcap < 2.63 hooks before main() to compute the number of
+ * capabilities of the running kernel, and doing so it calls prctl()
+ * which may fail and set errno to non-zero.
+ * Let's reset errno to make sure this does not interfere with the
+ * batch mode.
+ */
+ errno = 0;
+#endif
+
last_do_help = do_help;
pretty_output = false;
json_output = false;
--
2.35.1

2022-10-09 22:11:56

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 11/77] net: dsa: all DSA masters must be down when changing the tagging protocol

From: Vladimir Oltean <[email protected]>

[ Upstream commit f41ec1fd1c20e2a4e60a4ab8490b3e63423c0a8a ]

The fact that the tagging protocol is set and queried from the
/sys/class/net/<dsa-master>/dsa/tagging file is a bit of a quirk from
the single CPU port days which isn't aging very well now that DSA can
have more than a single CPU port. This is because the tagging protocol
is a switch property, yet in the presence of multiple CPU ports it can
be queried and set from multiple sysfs files, all of which are handled
by the same implementation.

The current logic ensures that the net device whose sysfs file we're
changing the tagging protocol through must be down. That net device is
the DSA master, and this is fine for single DSA master / CPU port setups.

But exactly because the tagging protocol is per switch [ tree, in fact ]
and not per DSA master, this isn't fine any longer with multiple CPU
ports, and we must iterate through the tree and find all DSA masters,
and make sure that all of them are down.

Signed-off-by: Vladimir Oltean <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/dsa/dsa2.c | 10 +++-------
net/dsa/dsa_priv.h | 1 -
net/dsa/master.c | 2 +-
3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index cac48a741f27..b2fe62bfe8dd 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -1238,7 +1238,6 @@ static int dsa_tree_bind_tag_proto(struct dsa_switch_tree *dst,
* they would have formed disjoint trees (different "dsa,member" values).
*/
int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,
- struct net_device *master,
const struct dsa_device_ops *tag_ops,
const struct dsa_device_ops *old_tag_ops)
{
@@ -1254,14 +1253,11 @@ int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,
* attempts to change the tagging protocol. If we ever lift the IFF_UP
* restriction, there needs to be another mutex which serializes this.
*/
- if (master->flags & IFF_UP)
- goto out_unlock;
-
list_for_each_entry(dp, &dst->ports, list) {
- if (!dsa_port_is_user(dp))
- continue;
+ if (dsa_port_is_cpu(dp) && (dp->master->flags & IFF_UP))
+ goto out_unlock;

- if (dp->slave->flags & IFF_UP)
+ if (dsa_port_is_user(dp) && (dp->slave->flags & IFF_UP))
goto out_unlock;
}

diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index d9722e49864b..cc1cc866dc42 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -545,7 +545,6 @@ struct dsa_lag *dsa_tree_lag_find(struct dsa_switch_tree *dst,
int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v);
int dsa_broadcast(unsigned long e, void *v);
int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,
- struct net_device *master,
const struct dsa_device_ops *tag_ops,
const struct dsa_device_ops *old_tag_ops);
void dsa_tree_master_admin_state_change(struct dsa_switch_tree *dst,
diff --git a/net/dsa/master.c b/net/dsa/master.c
index 2851e44c4cf0..32c0a00a8b92 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -307,7 +307,7 @@ static ssize_t tagging_store(struct device *d, struct device_attribute *attr,
*/
goto out;

- err = dsa_tree_change_tag_proto(cpu_dp->ds->dst, dev, new_tag_ops,
+ err = dsa_tree_change_tag_proto(cpu_dp->ds->dst, new_tag_ops,
old_tag_ops);
if (err) {
/* On failure the old tagger is restored, so we don't need the
--
2.35.1

2022-10-09 22:12:00

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 14/77] micrel: ksz8851: fixes struct pointer issue

From: Jerry Ray <[email protected]>

[ Upstream commit fef5de753ff01887cfa50990532c3890fccb9338 ]

Issue found during code review. This bug has no impact as long as the
ks8851_net structure is the first element of the ks8851_net_spi structure.
As long as the offset to the ks8851_net struct is zero, the container_of()
macro is subtracting 0 and therefore no damage done. But if the
ks8851_net_spi struct is ever modified such that the ks8851_net struct
within it is no longer the first element of the struct, then the bug would
manifest itself and cause problems.

struct ks8851_net is contained within ks8851_net_spi.
ks is contained within kss.
kss is the priv_data of the netdev structure.

Signed-off-by: Jerry Ray <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/micrel/ks8851_spi.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/micrel/ks8851_spi.c b/drivers/net/ethernet/micrel/ks8851_spi.c
index 82d55fc27edc..70bc7253454f 100644
--- a/drivers/net/ethernet/micrel/ks8851_spi.c
+++ b/drivers/net/ethernet/micrel/ks8851_spi.c
@@ -413,7 +413,8 @@ static int ks8851_probe_spi(struct spi_device *spi)

spi->bits_per_word = 8;

- ks = netdev_priv(netdev);
+ kss = netdev_priv(netdev);
+ ks = &kss->ks8851;

ks->lock = ks8851_lock_spi;
ks->unlock = ks8851_unlock_spi;
@@ -433,8 +434,6 @@ static int ks8851_probe_spi(struct spi_device *spi)
IRQ_RXPSI) /* RX process stop */
ks->rc_ier = STD_IRQ;

- kss = to_ks8851_spi(ks);
-
kss->spidev = spi;
mutex_init(&kss->lock);
INIT_WORK(&kss->tx_work, ks8851_tx_work);
--
2.35.1

2022-10-09 22:16:21

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 19/77] x86/mce: Retrieve poison range from hardware

From: Jane Chu <[email protected]>

[ Upstream commit f9781bb18ed828e7b83b7bac4a4ad7cd497ee7d7 ]

When memory poison consumption machine checks fire, MCE notifier
handlers like nfit_handle_mce() record the impacted physical address
range which is reported by the hardware in the MCi_MISC MSR. The error
information includes data about blast radius, i.e. how many cachelines
did the hardware determine are impacted. A recent change

7917f9cdb503 ("acpi/nfit: rely on mce->misc to determine poison granularity")

updated nfit_handle_mce() to stop hard coding the blast radius value of
1 cacheline, and instead rely on the blast radius reported in 'struct
mce' which can be up to 4K (64 cachelines).

It turns out that apei_mce_report_mem_error() had a similar problem in
that it hard coded a blast radius of 4K rather than reading the blast
radius from the error information. Fix apei_mce_report_mem_error() to
convey the proper poison granularity.

Signed-off-by: Jane Chu <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
Reviewed-by: Ingo Molnar <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
arch/x86/kernel/cpu/mce/apei.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/mce/apei.c b/arch/x86/kernel/cpu/mce/apei.c
index 717192915f28..8ed341714686 100644
--- a/arch/x86/kernel/cpu/mce/apei.c
+++ b/arch/x86/kernel/cpu/mce/apei.c
@@ -29,15 +29,26 @@
void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)
{
struct mce m;
+ int lsb;

if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return;

+ /*
+ * Even if the ->validation_bits are set for address mask,
+ * to be extra safe, check and reject an error radius '0',
+ * and fall back to the default page size.
+ */
+ if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
+ lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT);
+ else
+ lsb = PAGE_SHIFT;
+
mce_setup(&m);
m.bank = -1;
/* Fake a memory read error with unknown channel */
m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f;
- m.misc = (MCI_MISC_ADDR_PHYS << 6) | PAGE_SHIFT;
+ m.misc = (MCI_MISC_ADDR_PHYS << 6) | lsb;

if (severity >= GHES_SEV_RECOVERABLE)
m.status |= MCI_STATUS_UC;
--
2.35.1

2022-10-09 22:19:16

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 22/77] x86/apic: Don't disable x2APIC if locked

From: Daniel Sneddon <[email protected]>

[ Upstream commit b8d1d163604bd1e600b062fb00de5dc42baa355f ]

The APIC supports two modes, legacy APIC (or xAPIC), and Extended APIC
(or x2APIC). X2APIC mode is mostly compatible with legacy APIC, but
it disables the memory-mapped APIC interface in favor of one that uses
MSRs. The APIC mode is controlled by the EXT bit in the APIC MSR.

The MMIO/xAPIC interface has some problems, most notably the APIC LEAK
[1]. This bug allows an attacker to use the APIC MMIO interface to
extract data from the SGX enclave.

Introduce support for a new feature that will allow the BIOS to lock
the APIC in x2APIC mode. If the APIC is locked in x2APIC mode and the
kernel tries to disable the APIC or revert to legacy APIC mode a GP
fault will occur.

Introduce support for a new MSR (IA32_XAPIC_DISABLE_STATUS) and handle
the new locked mode when the LEGACY_XAPIC_DISABLED bit is set by
preventing the kernel from trying to disable the x2APIC.

On platforms with the IA32_XAPIC_DISABLE_STATUS MSR, if SGX or TDX are
enabled the LEGACY_XAPIC_DISABLED will be set by the BIOS. If
legacy APIC is required, then it SGX and TDX need to be disabled in the
BIOS.

[1]: https://aepicleak.com/aepicleak.pdf

Signed-off-by: Daniel Sneddon <[email protected]>
Signed-off-by: Dave Hansen <[email protected]>
Acked-by: Dave Hansen <[email protected]>
Tested-by: Neelima Krishnan <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
.../admin-guide/kernel-parameters.txt | 4 ++
arch/x86/Kconfig | 7 ++-
arch/x86/include/asm/cpu.h | 2 +
arch/x86/include/asm/msr-index.h | 13 ++++++
arch/x86/kernel/apic/apic.c | 44 +++++++++++++++++--
5 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 426fa892d311..2bc11a61c4d0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3805,6 +3805,10 @@

nox2apic [X86-64,APIC] Do not enable x2APIC mode.

+ NOTE: this parameter will be ignored on systems with the
+ LEGACY_XAPIC_DISABLED bit set in the
+ IA32_XAPIC_DISABLE_STATUS MSR.
+
nps_mtm_hs_ctr= [KNL,ARC]
This parameter sets the maximum duration, in
cycles, each HW thread of the CTOP can run
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f9920f1341c8..159c025ebb03 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -448,6 +448,11 @@ config X86_X2APIC
This allows 32-bit apic IDs (so it can support very large systems),
and accesses the local apic via MSRs not via mmio.

+ Some Intel systems circa 2022 and later are locked into x2APIC mode
+ and can not fall back to the legacy APIC modes if SGX or TDX are
+ enabled in the BIOS. They will be unable to boot without enabling
+ this option.
+
If you don't know what to do here, say N.

config X86_MPPARSE
@@ -1919,7 +1924,7 @@ endchoice

config X86_SGX
bool "Software Guard eXtensions (SGX)"
- depends on X86_64 && CPU_SUP_INTEL
+ depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC
depends on CRYPTO=y
depends on CRYPTO_SHA256=y
select SRCU
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 8cbf623f0ecf..b472ef76826a 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
return p1 & p2;
}

+extern u64 x86_read_arch_cap_msr(void);
+
#endif /* _ASM_X86_CPU_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6674bdb096f3..1e086b37a307 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -155,6 +155,11 @@
* Return Stack Buffer Predictions.
*/

+#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
+ * IA32_XAPIC_DISABLE_STATUS MSR
+ * supported
+ */
+
#define MSR_IA32_FLUSH_CMD 0x0000010b
#define L1D_FLUSH BIT(0) /*
* Writeback and invalidate the
@@ -1054,4 +1059,12 @@
#define MSR_IA32_HW_FEEDBACK_PTR 0x17d0
#define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1

+/* x2APIC locked status */
+#define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD
+#define LEGACY_XAPIC_DISABLED BIT(0) /*
+ * x2APIC mode is locked and
+ * disabling x2APIC will cause
+ * a #GP
+ */
+
#endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 6d303d1d276c..c6876d3ea4b1 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -61,6 +61,7 @@
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/irq_regs.h>
+#include <asm/cpu.h>

unsigned int num_processors;

@@ -1751,11 +1752,26 @@ EXPORT_SYMBOL_GPL(x2apic_mode);

enum {
X2APIC_OFF,
- X2APIC_ON,
X2APIC_DISABLED,
+ /* All states below here have X2APIC enabled */
+ X2APIC_ON,
+ X2APIC_ON_LOCKED
};
static int x2apic_state;

+static bool x2apic_hw_locked(void)
+{
+ u64 ia32_cap;
+ u64 msr;
+
+ ia32_cap = x86_read_arch_cap_msr();
+ if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) {
+ rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr);
+ return (msr & LEGACY_XAPIC_DISABLED);
+ }
+ return false;
+}
+
static void __x2apic_disable(void)
{
u64 msr;
@@ -1793,6 +1809,10 @@ static int __init setup_nox2apic(char *str)
apicid);
return 0;
}
+ if (x2apic_hw_locked()) {
+ pr_warn("APIC locked in x2apic mode, can't disable\n");
+ return 0;
+ }
pr_warn("x2apic already enabled.\n");
__x2apic_disable();
}
@@ -1807,10 +1827,18 @@ early_param("nox2apic", setup_nox2apic);
void x2apic_setup(void)
{
/*
- * If x2apic is not in ON state, disable it if already enabled
+ * Try to make the AP's APIC state match that of the BSP, but if the
+ * BSP is unlocked and the AP is locked then there is a state mismatch.
+ * Warn about the mismatch in case a GP fault occurs due to a locked AP
+ * trying to be turned off.
+ */
+ if (x2apic_state != X2APIC_ON_LOCKED && x2apic_hw_locked())
+ pr_warn("x2apic lock mismatch between BSP and AP.\n");
+ /*
+ * If x2apic is not in ON or LOCKED state, disable it if already enabled
* from BIOS.
*/
- if (x2apic_state != X2APIC_ON) {
+ if (x2apic_state < X2APIC_ON) {
__x2apic_disable();
return;
}
@@ -1831,6 +1859,11 @@ static __init void x2apic_disable(void)
if (x2apic_id >= 255)
panic("Cannot disable x2apic, id: %08x\n", x2apic_id);

+ if (x2apic_hw_locked()) {
+ pr_warn("Cannot disable locked x2apic, id: %08x\n", x2apic_id);
+ return;
+ }
+
__x2apic_disable();
register_lapic_address(mp_lapic_addr);
}
@@ -1889,7 +1922,10 @@ void __init check_x2apic(void)
if (x2apic_enabled()) {
pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n");
x2apic_mode = 1;
- x2apic_state = X2APIC_ON;
+ if (x2apic_hw_locked())
+ x2apic_state = X2APIC_ON_LOCKED;
+ else
+ x2apic_state = X2APIC_ON;
} else if (!boot_cpu_has(X86_FEATURE_X2APIC)) {
x2apic_state = X2APIC_DISABLED;
}
--
2.35.1

2022-10-09 22:20:54

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 21/77] thunderbolt: Add back Intel Falcon Ridge end-to-end flow control workaround

From: Mika Westerberg <[email protected]>

[ Upstream commit 54669e2f17cb5a4c41ade89427f074dc22cecb17 ]

As we are now enabling full end-to-end flow control to the Thunderbolt
networking driver, in order for it to work properly on second generation
Thunderbolt hardware (Falcon Ridge), we need to add back the workaround
that was removed with commit 53f13319d131 ("thunderbolt: Get rid of E2E
workaround"). However, this time we only apply it for Falcon Ridge
controllers as a form of an additional quirk. For non-Falcon Ridge this
does nothing.

While there fix a typo 'reqister' -> 'register' in the comment.

Signed-off-by: Mika Westerberg <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/thunderbolt/nhi.c | 49 +++++++++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index cb8c9c4ae93a..b5cd9673e15d 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -28,7 +28,11 @@
#define RING_TYPE(ring) ((ring)->is_tx ? "TX ring" : "RX ring")

#define RING_FIRST_USABLE_HOPID 1
-
+/*
+ * Used with QUIRK_E2E to specify an unused HopID the Rx credits are
+ * transferred.
+ */
+#define RING_E2E_RESERVED_HOPID RING_FIRST_USABLE_HOPID
/*
* Minimal number of vectors when we use MSI-X. Two for control channel
* Rx/Tx and the rest four are for cross domain DMA paths.
@@ -38,7 +42,9 @@

#define NHI_MAILBOX_TIMEOUT 500 /* ms */

+/* Host interface quirks */
#define QUIRK_AUTO_CLEAR_INT BIT(0)
+#define QUIRK_E2E BIT(1)

static int ring_interrupt_index(struct tb_ring *ring)
{
@@ -458,8 +464,18 @@ static void ring_release_msix(struct tb_ring *ring)

static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
{
+ unsigned int start_hop = RING_FIRST_USABLE_HOPID;
int ret = 0;

+ if (nhi->quirks & QUIRK_E2E) {
+ start_hop = RING_FIRST_USABLE_HOPID + 1;
+ if (ring->flags & RING_FLAG_E2E && !ring->is_tx) {
+ dev_dbg(&nhi->pdev->dev, "quirking E2E TX HopID %u -> %u\n",
+ ring->e2e_tx_hop, RING_E2E_RESERVED_HOPID);
+ ring->e2e_tx_hop = RING_E2E_RESERVED_HOPID;
+ }
+ }
+
spin_lock_irq(&nhi->lock);

if (ring->hop < 0) {
@@ -469,7 +485,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
* Automatically allocate HopID from the non-reserved
* range 1 .. hop_count - 1.
*/
- for (i = RING_FIRST_USABLE_HOPID; i < nhi->hop_count; i++) {
+ for (i = start_hop; i < nhi->hop_count; i++) {
if (ring->is_tx) {
if (!nhi->tx_rings[i]) {
ring->hop = i;
@@ -484,6 +500,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
}
}

+ if (ring->hop > 0 && ring->hop < start_hop) {
+ dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop);
+ ret = -EINVAL;
+ goto err_unlock;
+ }
if (ring->hop < 0 || ring->hop >= nhi->hop_count) {
dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop);
ret = -EINVAL;
@@ -1097,12 +1118,26 @@ static void nhi_shutdown(struct tb_nhi *nhi)

static void nhi_check_quirks(struct tb_nhi *nhi)
{
- /*
- * Intel hardware supports auto clear of the interrupt status
- * reqister right after interrupt is being issued.
- */
- if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL)
+ if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) {
+ /*
+ * Intel hardware supports auto clear of the interrupt
+ * status register right after interrupt is being
+ * issued.
+ */
nhi->quirks |= QUIRK_AUTO_CLEAR_INT;
+
+ switch (nhi->pdev->device) {
+ case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
+ case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
+ /*
+ * Falcon Ridge controller needs the end-to-end
+ * flow control workaround to avoid losing Rx
+ * packets when RING_FLAG_E2E is set.
+ */
+ nhi->quirks |= QUIRK_E2E;
+ break;
+ }
+ }
}

static int nhi_check_iommu_pdev(struct pci_dev *pdev, void *data)
--
2.35.1

2022-10-09 22:20:54

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 28/77] net: broadcom: Fix return type for implementation of

From: GUO Zihua <[email protected]>

[ Upstream commit 12f7bd252221d4f9e000e20530e50129241e3a67 ]

Since Linux now supports CFI, it will be a good idea to fix mismatched
return type for implementation of hooks. Otherwise this might get
cought out by CFI and cause a panic.

bcm4908_enet_start_xmit() would return either NETDEV_TX_BUSY or
NETDEV_TX_OK, so change the return type to netdev_tx_t directly.

Signed-off-by: GUO Zihua <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/broadcom/bcm4908_enet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/bcm4908_enet.c b/drivers/net/ethernet/broadcom/bcm4908_enet.c
index c131d8118489..e5e17a182f9d 100644
--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
@@ -507,7 +507,7 @@ static int bcm4908_enet_stop(struct net_device *netdev)
return 0;
}

-static int bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct bcm4908_enet *enet = netdev_priv(netdev);
struct bcm4908_enet_dma_ring *ring = &enet->tx_ring;
--
2.35.1

2022-10-09 22:20:54

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 13/77] tcp: annotate data-race around tcp_md5sig_pool_populated

From: Eric Dumazet <[email protected]>

[ Upstream commit aacd467c0a576e5e44d2de4205855dc0fe43f6fb ]

tcp_md5sig_pool_populated can be read while another thread
changes its value.

The race has no consequence because allocations
are protected with tcp_md5sig_mutex.

This patch adds READ_ONCE() and WRITE_ONCE() to document
the race and silence KCSAN.

Reported-by: Abhishek Shah <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/ipv4/tcp.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index e373dde1f46f..3733742cebf8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -4442,12 +4442,16 @@ static void __tcp_alloc_md5sig_pool(void)
* to memory. See smp_rmb() in tcp_get_md5sig_pool()
*/
smp_wmb();
- tcp_md5sig_pool_populated = true;
+ /* Paired with READ_ONCE() from tcp_alloc_md5sig_pool()
+ * and tcp_get_md5sig_pool().
+ */
+ WRITE_ONCE(tcp_md5sig_pool_populated, true);
}

bool tcp_alloc_md5sig_pool(void)
{
- if (unlikely(!tcp_md5sig_pool_populated)) {
+ /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
+ if (unlikely(!READ_ONCE(tcp_md5sig_pool_populated))) {
mutex_lock(&tcp_md5sig_mutex);

if (!tcp_md5sig_pool_populated) {
@@ -4458,7 +4462,8 @@ bool tcp_alloc_md5sig_pool(void)

mutex_unlock(&tcp_md5sig_mutex);
}
- return tcp_md5sig_pool_populated;
+ /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
+ return READ_ONCE(tcp_md5sig_pool_populated);
}
EXPORT_SYMBOL(tcp_alloc_md5sig_pool);

@@ -4474,7 +4479,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
{
local_bh_disable();

- if (tcp_md5sig_pool_populated) {
+ /* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
+ if (READ_ONCE(tcp_md5sig_pool_populated)) {
/* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */
smp_rmb();
return this_cpu_ptr(&tcp_md5sig_pool);
--
2.35.1

2022-10-09 22:20:55

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 23/77] net: axienet: Switch to 64-bit RX/TX statistics

From: Robert Hancock <[email protected]>

[ Upstream commit cb45a8bf4693965e89d115cd2c510f12bc127c37 ]

The RX and TX byte/packet statistics in this driver could be overflowed
relatively quickly on a 32-bit platform. Switch these stats to use the
u64_stats infrastructure to avoid this.

Signed-off-by: Robert Hancock <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/xilinx/xilinx_axienet.h | 12 ++++++
.../net/ethernet/xilinx/xilinx_axienet_main.c | 37 +++++++++++++++++--
2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index f2e2261b4b7d..8ff4333de2ad 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -402,6 +402,9 @@ struct axidma_bd {
* @rx_bd_num: Size of RX buffer descriptor ring
* @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being
* accessed currently.
+ * @rx_packets: RX packet count for statistics
+ * @rx_bytes: RX byte count for statistics
+ * @rx_stat_sync: Synchronization object for RX stats
* @napi_tx: NAPI TX control structure
* @tx_dma_cr: Nominal content of TX DMA control register
* @tx_bd_v: Virtual address of the TX buffer descriptor ring
@@ -411,6 +414,9 @@ struct axidma_bd {
* complete. Only updated at runtime by TX NAPI poll.
* @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring
* to be populated.
+ * @tx_packets: TX packet count for statistics
+ * @tx_bytes: TX byte count for statistics
+ * @tx_stat_sync: Synchronization object for TX stats
* @dma_err_task: Work structure to process Axi DMA errors
* @tx_irq: Axidma TX IRQ number
* @rx_irq: Axidma RX IRQ number
@@ -458,6 +464,9 @@ struct axienet_local {
dma_addr_t rx_bd_p;
u32 rx_bd_num;
u32 rx_bd_ci;
+ u64_stats_t rx_packets;
+ u64_stats_t rx_bytes;
+ struct u64_stats_sync rx_stat_sync;

struct napi_struct napi_tx;
u32 tx_dma_cr;
@@ -466,6 +475,9 @@ struct axienet_local {
u32 tx_bd_num;
u32 tx_bd_ci;
u32 tx_bd_tail;
+ u64_stats_t tx_packets;
+ u64_stats_t tx_bytes;
+ struct u64_stats_sync tx_stat_sync;

struct work_struct dma_err_task;

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 1760930ec0c4..9262988d26a3 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -752,8 +752,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)
if (lp->tx_bd_ci >= lp->tx_bd_num)
lp->tx_bd_ci %= lp->tx_bd_num;

- ndev->stats.tx_packets += packets;
- ndev->stats.tx_bytes += size;
+ u64_stats_update_begin(&lp->tx_stat_sync);
+ u64_stats_add(&lp->tx_packets, packets);
+ u64_stats_add(&lp->tx_bytes, size);
+ u64_stats_update_end(&lp->tx_stat_sync);

/* Matches barrier in axienet_start_xmit */
smp_mb();
@@ -984,8 +986,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget)
cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
}

- lp->ndev->stats.rx_packets += packets;
- lp->ndev->stats.rx_bytes += size;
+ u64_stats_update_begin(&lp->rx_stat_sync);
+ u64_stats_add(&lp->rx_packets, packets);
+ u64_stats_add(&lp->rx_bytes, size);
+ u64_stats_update_end(&lp->rx_stat_sync);

if (tail_p)
axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
@@ -1292,10 +1296,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phylink_mii_ioctl(lp->phylink, rq, cmd);
}

+static void
+axienet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
+{
+ struct axienet_local *lp = netdev_priv(dev);
+ unsigned int start;
+
+ netdev_stats_to_stats64(stats, &dev->stats);
+
+ do {
+ start = u64_stats_fetch_begin_irq(&lp->rx_stat_sync);
+ stats->rx_packets = u64_stats_read(&lp->rx_packets);
+ stats->rx_bytes = u64_stats_read(&lp->rx_bytes);
+ } while (u64_stats_fetch_retry_irq(&lp->rx_stat_sync, start));
+
+ do {
+ start = u64_stats_fetch_begin_irq(&lp->tx_stat_sync);
+ stats->tx_packets = u64_stats_read(&lp->tx_packets);
+ stats->tx_bytes = u64_stats_read(&lp->tx_bytes);
+ } while (u64_stats_fetch_retry_irq(&lp->tx_stat_sync, start));
+}
+
static const struct net_device_ops axienet_netdev_ops = {
.ndo_open = axienet_open,
.ndo_stop = axienet_stop,
.ndo_start_xmit = axienet_start_xmit,
+ .ndo_get_stats64 = axienet_get_stats64,
.ndo_change_mtu = axienet_change_mtu,
.ndo_set_mac_address = netdev_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
@@ -1850,6 +1876,9 @@ static int axienet_probe(struct platform_device *pdev)
lp->rx_bd_num = RX_BD_NUM_DEFAULT;
lp->tx_bd_num = TX_BD_NUM_DEFAULT;

+ u64_stats_init(&lp->rx_stat_sync);
+ u64_stats_init(&lp->tx_stat_sync);
+
netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll, NAPI_POLL_WEIGHT);
netif_napi_add(ndev, &lp->napi_tx, axienet_tx_poll, NAPI_POLL_WEIGHT);

--
2.35.1

2022-10-09 22:21:09

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 09/77] openvswitch: Fix double reporting of drops in dropwatch

From: Mike Pattrick <[email protected]>

[ Upstream commit 1100248a5c5ccd57059eb8d02ec077e839a23826 ]

Frames sent to userspace can be reported as dropped in
ovs_dp_process_packet, however, if they are dropped in the netlink code
then netlink_attachskb will report the same frame as dropped.

This patch checks for error codes which indicate that the frame has
already been freed.

Signed-off-by: Mike Pattrick <[email protected]>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2109946
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/openvswitch/datapath.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 6c9d153afbee..b68ba3c72519 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -252,10 +252,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)

upcall.mru = OVS_CB(skb)->mru;
error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
- if (unlikely(error))
- kfree_skb(skb);
- else
+ switch (error) {
+ case 0:
+ case -EAGAIN:
+ case -ERESTARTSYS:
+ case -EINTR:
consume_skb(skb);
+ break;
+ default:
+ kfree_skb(skb);
+ break;
+ }
stats_counter = &stats->n_missed;
goto out;
}
--
2.35.1

2022-10-09 22:21:21

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 29/77] net: xscale: Fix return type for implementation of ndo_start_xmit

From: GUO Zihua <[email protected]>

[ Upstream commit 0dbaf0fa62329d9fe452d9041a707a33f6274f1f ]

Since Linux now supports CFI, it will be a good idea to fix mismatched
return type for implementation of hooks. Otherwise this might get
cought out by CFI and cause a panic.

eth_xmit() would return either NETDEV_TX_BUSY or NETDEV_TX_OK, so
change the return type to netdev_tx_t directly.

Signed-off-by: GUO Zihua <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/xscale/ixp4xx_eth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 3591b9edc9a1..3b05287b6889 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -841,7 +841,7 @@ static void eth_txdone_irq(void *unused)
}
}

-static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t eth_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct port *port = netdev_priv(dev);
unsigned int txreadyq = port->plat->txreadyq;
--
2.35.1

2022-10-09 22:21:30

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 48/77] net: ethernet: litex: Fix return type of liteeth_start_xmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 40662333dd7c64664247a6138bc33f3974e3a331 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of liteeth_start_xmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Reviewed-by: Nathan Chancellor <[email protected]>
Acked-by: Gabriel Somlo <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/litex/litex_liteeth.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/litex/litex_liteeth.c b/drivers/net/ethernet/litex/litex_liteeth.c
index fdd99f0de424..35f24e0f0934 100644
--- a/drivers/net/ethernet/litex/litex_liteeth.c
+++ b/drivers/net/ethernet/litex/litex_liteeth.c
@@ -152,7 +152,8 @@ static int liteeth_stop(struct net_device *netdev)
return 0;
}

-static int liteeth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t liteeth_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
{
struct liteeth *priv = netdev_priv(netdev);
void __iomem *txbuffer;
--
2.35.1

2022-10-09 22:21:31

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 08/77] net: ethernet: ti: davinci_mdio: Add workaround for errata i2329

From: Ravi Gunasekaran <[email protected]>

[ Upstream commit d04807b80691c6041ca8e3dcf1870d1bf1082c22 ]

On the CPSW and ICSS peripherals, there is a possibility that the MDIO
interface returns corrupt data on MDIO reads or writes incorrect data
on MDIO writes. There is also a possibility for the MDIO interface to
become unavailable until the next peripheral reset.

The workaround is to configure the MDIO in manual mode and disable the
MDIO state machine and emulate the MDIO protocol by reading and writing
appropriate fields in MDIO_MANUAL_IF_REG register of the MDIO controller
to manipulate the MDIO clock and data pins.

More details about the errata i2329 and the workaround is available in:
https://www.ti.com/lit/er/sprz487a/sprz487a.pdf

Add implementation to disable MDIO state machine, configure MDIO in manual
mode and achieve MDIO read and writes via MDIO Bitbanging

Signed-off-by: Ravi Gunasekaran <[email protected]>
Reported-by: kernel test robot <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/ti/davinci_mdio.c | 242 +++++++++++++++++++++++--
1 file changed, 231 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index ea3772618043..946b9753ccfb 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -26,6 +26,8 @@
#include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/sys_soc.h>

/*
* This timeout definition is a worst-case ultra defensive measure against
@@ -41,6 +43,7 @@

struct davinci_mdio_of_param {
int autosuspend_delay_ms;
+ bool manual_mode;
};

struct davinci_mdio_regs {
@@ -49,6 +52,15 @@ struct davinci_mdio_regs {
#define CONTROL_IDLE BIT(31)
#define CONTROL_ENABLE BIT(30)
#define CONTROL_MAX_DIV (0xffff)
+#define CONTROL_CLKDIV GENMASK(15, 0)
+
+#define MDIO_MAN_MDCLK_O BIT(2)
+#define MDIO_MAN_OE BIT(1)
+#define MDIO_MAN_PIN BIT(0)
+#define MDIO_MANUALMODE BIT(31)
+
+#define MDIO_PIN 0
+

u32 alive;
u32 link;
@@ -59,7 +71,9 @@ struct davinci_mdio_regs {
u32 userintmasked;
u32 userintmaskset;
u32 userintmaskclr;
- u32 __reserved_1[20];
+ u32 manualif;
+ u32 poll;
+ u32 __reserved_1[18];

struct {
u32 access;
@@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = {

struct davinci_mdio_data {
struct mdio_platform_data pdata;
+ struct mdiobb_ctrl bb_ctrl;
struct davinci_mdio_regs __iomem *regs;
struct clk *clk;
struct device *dev;
@@ -90,6 +105,7 @@ struct davinci_mdio_data {
*/
bool skip_scan;
u32 clk_div;
+ bool manual_mode;
};

static void davinci_mdio_init_clk(struct davinci_mdio_data *data)
@@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)
writel(data->clk_div | CONTROL_ENABLE, &data->regs->control);
}

-static int davinci_mdio_reset(struct mii_bus *bus)
+static void davinci_mdio_disable(struct davinci_mdio_data *data)
+{
+ u32 reg;
+
+ /* Disable MDIO state machine */
+ reg = readl(&data->regs->control);
+
+ reg &= ~CONTROL_CLKDIV;
+ reg |= data->clk_div;
+
+ reg &= ~CONTROL_ENABLE;
+ writel(reg, &data->regs->control);
+}
+
+static void davinci_mdio_enable_manual_mode(struct davinci_mdio_data *data)
+{
+ u32 reg;
+ /* set manual mode */
+ reg = readl(&data->regs->poll);
+ reg |= MDIO_MANUALMODE;
+ writel(reg, &data->regs->poll);
+}
+
+static void davinci_set_mdc(struct mdiobb_ctrl *ctrl, int level)
+{
+ struct davinci_mdio_data *data;
+ u32 reg;
+
+ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
+ reg = readl(&data->regs->manualif);
+
+ if (level)
+ reg |= MDIO_MAN_MDCLK_O;
+ else
+ reg &= ~MDIO_MAN_MDCLK_O;
+
+ writel(reg, &data->regs->manualif);
+}
+
+static void davinci_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output)
+{
+ struct davinci_mdio_data *data;
+ u32 reg;
+
+ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
+ reg = readl(&data->regs->manualif);
+
+ if (output)
+ reg |= MDIO_MAN_OE;
+ else
+ reg &= ~MDIO_MAN_OE;
+
+ writel(reg, &data->regs->manualif);
+}
+
+static void davinci_set_mdio_data(struct mdiobb_ctrl *ctrl, int value)
+{
+ struct davinci_mdio_data *data;
+ u32 reg;
+
+ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
+ reg = readl(&data->regs->manualif);
+
+ if (value)
+ reg |= MDIO_MAN_PIN;
+ else
+ reg &= ~MDIO_MAN_PIN;
+
+ writel(reg, &data->regs->manualif);
+}
+
+static int davinci_get_mdio_data(struct mdiobb_ctrl *ctrl)
+{
+ struct davinci_mdio_data *data;
+ unsigned long reg;
+
+ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
+ reg = readl(&data->regs->manualif);
+ return test_bit(MDIO_PIN, &reg);
+}
+
+static int davinci_mdiobb_read(struct mii_bus *bus, int phy, int reg)
+{
+ int ret;
+
+ ret = pm_runtime_resume_and_get(bus->parent);
+ if (ret < 0)
+ return ret;
+
+ ret = mdiobb_read(bus, phy, reg);
+
+ pm_runtime_mark_last_busy(bus->parent);
+ pm_runtime_put_autosuspend(bus->parent);
+
+ return ret;
+}
+
+static int davinci_mdiobb_write(struct mii_bus *bus, int phy, int reg,
+ u16 val)
+{
+ int ret;
+
+ ret = pm_runtime_resume_and_get(bus->parent);
+ if (ret < 0)
+ return ret;
+
+ ret = mdiobb_write(bus, phy, reg, val);
+
+ pm_runtime_mark_last_busy(bus->parent);
+ pm_runtime_put_autosuspend(bus->parent);
+
+ return ret;
+}
+
+static int davinci_mdio_common_reset(struct davinci_mdio_data *data)
{
- struct davinci_mdio_data *data = bus->priv;
u32 phy_mask, ver;
int ret;

@@ -138,6 +267,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)
if (ret < 0)
return ret;

+ if (data->manual_mode) {
+ davinci_mdio_disable(data);
+ davinci_mdio_enable_manual_mode(data);
+ }
+
/* wait for scan logic to settle */
msleep(PHY_MAX_ADDR * data->access_time);

@@ -171,6 +305,23 @@ static int davinci_mdio_reset(struct mii_bus *bus)
return 0;
}

+static int davinci_mdio_reset(struct mii_bus *bus)
+{
+ struct davinci_mdio_data *data = bus->priv;
+
+ return davinci_mdio_common_reset(data);
+}
+
+static int davinci_mdiobb_reset(struct mii_bus *bus)
+{
+ struct mdiobb_ctrl *ctrl = bus->priv;
+ struct davinci_mdio_data *data;
+
+ data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
+
+ return davinci_mdio_common_reset(data);
+}
+
/* wait until hardware is ready for another user access */
static inline int wait_for_user_access(struct davinci_mdio_data *data)
{
@@ -318,6 +469,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data,
return 0;
}

+struct k3_mdio_soc_data {
+ bool manual_mode;
+};
+
+static const struct k3_mdio_soc_data am65_mdio_soc_data = {
+ .manual_mode = true,
+};
+
+static const struct soc_device_attribute k3_mdio_socinfo[] = {
+ { .family = "AM62X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
+ { .family = "AM64X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
+ { .family = "AM64X", .revision = "SR2.0", .data = &am65_mdio_soc_data },
+ { .family = "AM65X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
+ { .family = "AM65X", .revision = "SR2.0", .data = &am65_mdio_soc_data },
+ { .family = "J7200", .revision = "SR1.0", .data = &am65_mdio_soc_data },
+ { .family = "J7200", .revision = "SR2.0", .data = &am65_mdio_soc_data },
+ { .family = "J721E", .revision = "SR1.0", .data = &am65_mdio_soc_data },
+ { .family = "J721E", .revision = "SR2.0", .data = &am65_mdio_soc_data },
+ { .family = "J721S2", .revision = "SR1.0", .data = &am65_mdio_soc_data},
+ { /* sentinel */ },
+};
+
#if IS_ENABLED(CONFIG_OF)
static const struct davinci_mdio_of_param of_cpsw_mdio_data = {
.autosuspend_delay_ms = 100,
@@ -331,6 +504,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {
MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
#endif

+static const struct mdiobb_ops davinci_mdiobb_ops = {
+ .owner = THIS_MODULE,
+ .set_mdc = davinci_set_mdc,
+ .set_mdio_dir = davinci_set_mdio_dir,
+ .set_mdio_data = davinci_set_mdio_data,
+ .get_mdio_data = davinci_get_mdio_data,
+};
+
static int davinci_mdio_probe(struct platform_device *pdev)
{
struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -345,7 +526,26 @@ static int davinci_mdio_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;

- data->bus = devm_mdiobus_alloc(dev);
+ data->manual_mode = false;
+ data->bb_ctrl.ops = &davinci_mdiobb_ops;
+
+ if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+ const struct soc_device_attribute *soc_match_data;
+
+ soc_match_data = soc_device_match(k3_mdio_socinfo);
+ if (soc_match_data && soc_match_data->data) {
+ const struct k3_mdio_soc_data *socdata =
+ soc_match_data->data;
+
+ data->manual_mode = socdata->manual_mode;
+ }
+ }
+
+ if (data->manual_mode)
+ data->bus = alloc_mdio_bitbang(&data->bb_ctrl);
+ else
+ data->bus = devm_mdiobus_alloc(dev);
+
if (!data->bus) {
dev_err(dev, "failed to alloc mii bus\n");
return -ENOMEM;
@@ -371,11 +571,20 @@ static int davinci_mdio_probe(struct platform_device *pdev)
}

data->bus->name = dev_name(dev);
- data->bus->read = davinci_mdio_read;
- data->bus->write = davinci_mdio_write;
- data->bus->reset = davinci_mdio_reset;
+
+ if (data->manual_mode) {
+ data->bus->read = davinci_mdiobb_read;
+ data->bus->write = davinci_mdiobb_write;
+ data->bus->reset = davinci_mdiobb_reset;
+
+ dev_info(dev, "Configuring MDIO in manual mode\n");
+ } else {
+ data->bus->read = davinci_mdio_read;
+ data->bus->write = davinci_mdio_write;
+ data->bus->reset = davinci_mdio_reset;
+ data->bus->priv = data;
+ }
data->bus->parent = dev;
- data->bus->priv = data;

data->clk = devm_clk_get(dev, "fck");
if (IS_ERR(data->clk)) {
@@ -433,9 +642,13 @@ static int davinci_mdio_remove(struct platform_device *pdev)
{
struct davinci_mdio_data *data = platform_get_drvdata(pdev);

- if (data->bus)
+ if (data->bus) {
mdiobus_unregister(data->bus);

+ if (data->manual_mode)
+ free_mdio_bitbang(data->bus);
+ }
+
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);

@@ -452,7 +665,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev)
ctrl = readl(&data->regs->control);
ctrl &= ~CONTROL_ENABLE;
writel(ctrl, &data->regs->control);
- wait_for_idle(data);
+
+ if (!data->manual_mode)
+ wait_for_idle(data);

return 0;
}
@@ -461,7 +676,12 @@ static int davinci_mdio_runtime_resume(struct device *dev)
{
struct davinci_mdio_data *data = dev_get_drvdata(dev);

- davinci_mdio_enable(data);
+ if (data->manual_mode) {
+ davinci_mdio_disable(data);
+ davinci_mdio_enable_manual_mode(data);
+ } else {
+ davinci_mdio_enable(data);
+ }
return 0;
}
#endif
--
2.35.1

2022-10-09 22:21:43

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 18/77] net: dsa: mv88e6xxx: Allow external SMI if serial

From: Marcus Carlberg <[email protected]>

[ Upstream commit 8532c60efcc5b7b382006129b77aee2c19c43f15 ]

p0_mode set to one of the supported serial mode should not prevent
configuring the external SMI interface in
mv88e6xxx_g2_scratch_gpio_set_smi. The current masking of the p0_mode
only checks the first 2 bits. This results in switches supporting
serial mode cannot setup external SMI on certain serial modes
(Ex: 1000BASE-X and SGMII).

Extend the mask of the p0_mode to include the reduced modes and
serial modes as allowed modes for the external SMI interface.

Signed-off-by: Marcus Carlberg <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/dsa/mv88e6xxx/global2.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 807aeaad9830..7536b8b0ad01 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -298,7 +298,7 @@
#define MV88E6352_G2_SCRATCH_CONFIG_DATA1 0x71
#define MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU BIT(2)
#define MV88E6352_G2_SCRATCH_CONFIG_DATA2 0x72
-#define MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK 0x3
+#define MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK 0xf
#define MV88E6352_G2_SCRATCH_CONFIG_DATA3 0x73
#define MV88E6352_G2_SCRATCH_CONFIG_DATA3_S_SEL BIT(1)

--
2.35.1

2022-10-09 22:22:10

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 25/77] xfrm: Update ipcomp_scratches with NULL when freed

From: Khalid Masum <[email protected]>

[ Upstream commit 8a04d2fc700f717104bfb95b0f6694e448a4537f ]

Currently if ipcomp_alloc_scratches() fails to allocate memory
ipcomp_scratches holds obsolete address. So when we try to free the
percpu scratches using ipcomp_free_scratches() it tries to vfree non
existent vm area. Described below:

static void * __percpu *ipcomp_alloc_scratches(void)
{
...
scratches = alloc_percpu(void *);
if (!scratches)
return NULL;
ipcomp_scratches does not know about this allocation failure.
Therefore holding the old obsolete address.
...
}

So when we free,

static void ipcomp_free_scratches(void)
{
...
scratches = ipcomp_scratches;
Assigning obsolete address from ipcomp_scratches

if (!scratches)
return;

for_each_possible_cpu(i)
vfree(*per_cpu_ptr(scratches, i));
Trying to free non existent page, causing warning: trying to vfree
existent vm area.
...
}

Fix this breakage by updating ipcomp_scrtches with NULL when scratches
is freed

Suggested-by: Herbert Xu <[email protected]>
Reported-by: [email protected]
Tested-by: [email protected]
Signed-off-by: Khalid Masum <[email protected]>
Acked-by: Herbert Xu <[email protected]>
Signed-off-by: Steffen Klassert <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/xfrm/xfrm_ipcomp.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index cb40ff0ff28d..92ad336a83ab 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)
vfree(*per_cpu_ptr(scratches, i));

free_percpu(scratches);
+ ipcomp_scratches = NULL;
}

static void * __percpu *ipcomp_alloc_scratches(void)
--
2.35.1

2022-10-09 22:23:02

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 45/77] net: ax88796c: Fix return type of ax88796c_start_xmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit fcb7c210a24209ea8f6f32593580b57f52382ec2 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of ax88796c_start_xmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Acked-by: Lukasz Stelmach <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/asix/ax88796c_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/asix/ax88796c_main.c b/drivers/net/ethernet/asix/ax88796c_main.c
index 6ba5b024a7be..f1d610efd69e 100644
--- a/drivers/net/ethernet/asix/ax88796c_main.c
+++ b/drivers/net/ethernet/asix/ax88796c_main.c
@@ -381,7 +381,7 @@ static int ax88796c_hard_xmit(struct ax88796c_device *ax_local)
return 1;
}

-static int
+static netdev_tx_t
ax88796c_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct ax88796c_device *ax_local = to_ax88796c_device(ndev);
--
2.35.1

2022-10-09 22:23:03

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 76/77] net: lan966x: Fix return type of lan966x_port_xmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 450a580fc4b5e7f7fb8d9b1a0208bf0d1efc53a8 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of lan966x_port_xmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Reviewed-by: Nathan Chancellor <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/microchip/lan966x/lan966x_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index d928b75f3780..be40c6d3ec68 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -344,7 +344,8 @@ static void lan966x_ifh_set_timestamp(void *ifh, u64 timestamp)
IFH_POS_TIMESTAMP, IFH_LEN * 4, PACK, 0);
}

-static int lan966x_port_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lan966x_port_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
struct lan966x_port *port = netdev_priv(dev);
struct lan966x *lan966x = port->lan966x;
--
2.35.1

2022-10-09 22:23:13

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 73/77] libbpf: Fix overrun in netlink attribute iteration

From: Xin Liu <[email protected]>

[ Upstream commit 51e05a8cf8eb34da7473823b7f236a77adfef0b4 ]

I accidentally found that a change in commit 1045b03e07d8 ("netlink: fix
overrun in attribute iteration") was not synchronized to the function
`nla_ok` in tools/lib/bpf/nlattr.c, I think it is necessary to modify,
this patch will do it.

Signed-off-by: Xin Liu <[email protected]>
Signed-off-by: Andrii Nakryiko <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
tools/lib/bpf/nlattr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
index f57e77a6e40f..3900d052ed19 100644
--- a/tools/lib/bpf/nlattr.c
+++ b/tools/lib/bpf/nlattr.c
@@ -32,7 +32,7 @@ static struct nlattr *nla_next(const struct nlattr *nla, int *remaining)

static int nla_ok(const struct nlattr *nla, int remaining)
{
- return remaining >= sizeof(*nla) &&
+ return remaining >= (int)sizeof(*nla) &&
nla->nla_len >= sizeof(*nla) &&
nla->nla_len <= remaining;
}
--
2.35.1

2022-10-09 22:23:19

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 69/77] bpf: Adjust kprobe_multi entry_ip for CONFIG_X86_KERNEL_IBT

From: Jiri Olsa <[email protected]>

[ Upstream commit c09eb2e578eb1668bbc84dc07e8d8bd6f04b9a02 ]

Martynas reported bpf_get_func_ip returning +4 address when
CONFIG_X86_KERNEL_IBT option is enabled.

When CONFIG_X86_KERNEL_IBT is enabled we'll have endbr instruction
at the function entry, which screws return value of bpf_get_func_ip()
helper that should return the function address.

There's short term workaround for kprobe_multi bpf program made by
Alexei [1], but we need this fixup also for bpf_get_attach_cookie,
that returns cookie based on the entry_ip value.

Moving the fixup in the fprobe handler, so both bpf_get_func_ip
and bpf_get_attach_cookie get expected function address when
CONFIG_X86_KERNEL_IBT option is enabled.

Also renaming kprobe_multi_link_handler entry_ip argument to fentry_ip
so it's clearer this is an ftrace __fentry__ ip.

[1] commit 7f0059b58f02 ("selftests/bpf: Fix kprobe_multi test.")

Cc: Peter Zijlstra <[email protected]>
Reported-by: Martynas Pumputis <[email protected]>
Acked-by: Andrii Nakryiko <[email protected]>
Signed-off-by: Jiri Olsa <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Alexei Starovoitov <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
kernel/trace/bpf_trace.c | 20 +++++++++++++++++--
.../selftests/bpf/progs/kprobe_multi.c | 4 +---
2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 68e5cdd24cef..b1daf7c9b895 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1026,6 +1026,22 @@ static const struct bpf_func_proto bpf_get_func_ip_proto_tracing = {
.arg1_type = ARG_PTR_TO_CTX,
};

+#ifdef CONFIG_X86_KERNEL_IBT
+static unsigned long get_entry_ip(unsigned long fentry_ip)
+{
+ u32 instr;
+
+ /* Being extra safe in here in case entry ip is on the page-edge. */
+ if (get_kernel_nofault(instr, (u32 *) fentry_ip - 1))
+ return fentry_ip;
+ if (is_endbr(instr))
+ fentry_ip -= ENDBR_INSN_SIZE;
+ return fentry_ip;
+}
+#else
+#define get_entry_ip(fentry_ip) fentry_ip
+#endif
+
BPF_CALL_1(bpf_get_func_ip_kprobe, struct pt_regs *, regs)
{
struct kprobe *kp = kprobe_running();
@@ -2414,13 +2430,13 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,
}

static void
-kprobe_multi_link_handler(struct fprobe *fp, unsigned long entry_ip,
+kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
struct pt_regs *regs)
{
struct bpf_kprobe_multi_link *link;

link = container_of(fp, struct bpf_kprobe_multi_link, fp);
- kprobe_multi_link_prog_run(link, entry_ip, regs);
+ kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs);
}

static int symbols_cmp_r(const void *a, const void *b, const void *priv)
diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi.c b/tools/testing/selftests/bpf/progs/kprobe_multi.c
index 08f95a8155d1..98c3399e15c0 100644
--- a/tools/testing/selftests/bpf/progs/kprobe_multi.c
+++ b/tools/testing/selftests/bpf/progs/kprobe_multi.c
@@ -36,15 +36,13 @@ __u64 kretprobe_test6_result = 0;
__u64 kretprobe_test7_result = 0;
__u64 kretprobe_test8_result = 0;

-extern bool CONFIG_X86_KERNEL_IBT __kconfig __weak;
-
static void kprobe_multi_check(void *ctx, bool is_return)
{
if (bpf_get_current_pid_tgid() >> 32 != pid)
return;

__u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
- __u64 addr = bpf_get_func_ip(ctx) - (CONFIG_X86_KERNEL_IBT ? 4 : 0);
+ __u64 addr = bpf_get_func_ip(ctx);

#define SET(__var, __addr, __cookie) ({ \
if (((const void *) addr == __addr) && \
--
2.35.1

2022-10-09 22:23:22

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 39/77] regulator: core: Prevent integer underflow

From: Patrick Rudolph <[email protected]>

[ Upstream commit 8d8e16592022c9650df8aedfe6552ed478d7135b ]

By using a ratio of delay to poll_enabled_time that is not integer
time_remaining underflows and does not exit the loop as expected.
As delay could be derived from DT and poll_enabled_time is defined
in the driver this can easily happen.

Use a signed iterator to make sure that the loop exits once
the remaining time is negative.

Signed-off-by: Patrick Rudolph <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/regulator/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index d3e8dc32832d..c3871565fd7d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2681,7 +2681,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
* return -ETIMEDOUT.
*/
if (rdev->desc->poll_enabled_time) {
- unsigned int time_remaining = delay;
+ int time_remaining = delay;

while (time_remaining > 0) {
_regulator_delay_helper(rdev->desc->poll_enabled_time);
--
2.35.1

2022-10-09 22:23:23

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 67/77] hwmon: (sht4x) do not overflow clamping operation on 32-bit platforms

From: "Jason A. Donenfeld" <[email protected]>

[ Upstream commit f9c0cf8f26de367c58e48b02b1cdb9c377626e6f ]

On 32-bit platforms, long is 32 bits, so (long)UINT_MAX is less than
(long)SHT4X_MIN_POLL_INTERVAL, which means the clamping operation is
bogus. Fix this by clamping at INT_MAX, so that the upperbound is the
same on all platforms.

Signed-off-by: Jason A. Donenfeld <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hwmon/sht4x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
index c19df3ade48e..13ac2d8f22c7 100644
--- a/drivers/hwmon/sht4x.c
+++ b/drivers/hwmon/sht4x.c
@@ -129,7 +129,7 @@ static int sht4x_read_values(struct sht4x_data *data)

static ssize_t sht4x_interval_write(struct sht4x_data *data, long val)
{
- data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, UINT_MAX);
+ data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, INT_MAX);

return 0;
}
--
2.35.1

2022-10-09 22:23:42

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 72/77] net: sched: cls_u32: Avoid memcpy() false-positive warning

From: Kees Cook <[email protected]>

[ Upstream commit 7cba18332e3635aaae60e4e7d4e52849de50d91b ]

To work around a misbehavior of the compiler's ability to see into
composite flexible array structs (as detailed in the coming memcpy()
hardening series[1]), use unsafe_memcpy(), as the sizing,
bounds-checking, and allocation are all very tightly coupled here.
This silences the false-positive reported by syzbot:

memcpy: detected field-spanning write (size 80) of single field "&n->sel" at net/sched/cls_u32.c:1043 (size 16)

[1] https://lore.kernel.org/linux-hardening/[email protected]

Cc: Cong Wang <[email protected]>
Cc: Jiri Pirko <[email protected]>
Reported-by: [email protected]
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Kees Cook <[email protected]>
Reviewed-by: Jamal Hadi Salim <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/sched/cls_u32.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 4d27300c287c..5f33472aad36 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -1040,7 +1040,11 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
}
#endif

- memcpy(&n->sel, s, sel_size);
+ unsafe_memcpy(&n->sel, s, sel_size,
+ /* A composite flex-array structure destination,
+ * which was correctly sized with struct_size(),
+ * bounds-checked against nla_len(), and allocated
+ * above. */);
RCU_INIT_POINTER(n->ht_up, ht);
n->handle = handle;
n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
--
2.35.1

2022-10-09 23:21:49

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 77/77] r8152: Rate limit overflow messages

From: Andrew Gaul <[email protected]>

[ Upstream commit 93e2be344a7db169b7119de21ac1bf253b8c6907 ]

My system shows almost 10 million of these messages over a 24-hour
period which pollutes my logs.

Signed-off-by: Andrew Gaul <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/usb/r8152.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 688905ea0a6d..e7b0b59e2bc8 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1874,7 +1874,9 @@ static void intr_callback(struct urb *urb)
"Stop submitting intr, status %d\n", status);
return;
case -EOVERFLOW:
- netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n");
+ if (net_ratelimit())
+ netif_info(tp, intr, tp->netdev,
+ "intr status -EOVERFLOW\n");
goto resubmit;
/* -EPIPE: should clear the halt */
default:
--
2.35.1

2022-10-09 23:27:02

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 50/77] net: wwan: iosm: Fix return type of ipc_wwan_link_transmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 0c9441c430104dcf2cd066aae74dbeefb9f9e1bf ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of ipc_wwan_link_transmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Acked-by: Sergey Ryazanov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/wwan/iosm/iosm_ipc_wwan.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
index 27151148c782..03757ad21d51 100644
--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
@@ -103,8 +103,8 @@ static int ipc_wwan_link_stop(struct net_device *netdev)
}

/* Transmit a packet */
-static int ipc_wwan_link_transmit(struct sk_buff *skb,
- struct net_device *netdev)
+static netdev_tx_t ipc_wwan_link_transmit(struct sk_buff *skb,
+ struct net_device *netdev)
{
struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(netdev);
struct iosm_wwan *ipc_wwan = priv->ipc_wwan;
--
2.35.1

2022-10-09 23:41:55

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 33/77] net: ftmac100: fix endianness-related issues from 'sparse'

From: Sergei Antonov <[email protected]>

[ Upstream commit 9df696b3b3a4c96c3219eb87c7bf03fb50e490b8 ]

Sparse found a number of endianness-related issues of these kinds:

.../ftmac100.c:192:32: warning: restricted __le32 degrades to integer

.../ftmac100.c:208:23: warning: incorrect type in assignment (different base types)
.../ftmac100.c:208:23: expected unsigned int rxdes0
.../ftmac100.c:208:23: got restricted __le32 [usertype]

.../ftmac100.c:249:23: warning: invalid assignment: &=
.../ftmac100.c:249:23: left side has type unsigned int
.../ftmac100.c:249:23: right side has type restricted __le32

.../ftmac100.c:527:16: warning: cast to restricted __le32

Change type of some fields from 'unsigned int' to '__le32' to fix it.

Signed-off-by: Sergei Antonov <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/faraday/ftmac100.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/faraday/ftmac100.h b/drivers/net/ethernet/faraday/ftmac100.h
index fe986f1673fc..8af32f9070f4 100644
--- a/drivers/net/ethernet/faraday/ftmac100.h
+++ b/drivers/net/ethernet/faraday/ftmac100.h
@@ -122,9 +122,9 @@
* Transmit descriptor, aligned to 16 bytes
*/
struct ftmac100_txdes {
- unsigned int txdes0;
- unsigned int txdes1;
- unsigned int txdes2; /* TXBUF_BADR */
+ __le32 txdes0;
+ __le32 txdes1;
+ __le32 txdes2; /* TXBUF_BADR */
unsigned int txdes3; /* not used by HW */
} __attribute__ ((aligned(16)));

@@ -143,9 +143,9 @@ struct ftmac100_txdes {
* Receive descriptor, aligned to 16 bytes
*/
struct ftmac100_rxdes {
- unsigned int rxdes0;
- unsigned int rxdes1;
- unsigned int rxdes2; /* RXBUF_BADR */
+ __le32 rxdes0;
+ __le32 rxdes1;
+ __le32 rxdes2; /* RXBUF_BADR */
unsigned int rxdes3; /* not used by HW */
} __attribute__ ((aligned(16)));

--
2.35.1

2022-10-09 23:42:33

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 24/77] net-next: Fix IP_UNICAST_IF option behavior for connected sockets

From: Richard Gobert <[email protected]>

[ Upstream commit 0e4d354762cefd3e16b4cff8988ff276e45effc4 ]

The IP_UNICAST_IF socket option is used to set the outgoing interface
for outbound packets.

The IP_UNICAST_IF socket option was added as it was needed by the
Wine project, since no other existing option (SO_BINDTODEVICE socket
option, IP_PKTINFO socket option or the bind function) provided the
needed characteristics needed by the IP_UNICAST_IF socket option. [1]
The IP_UNICAST_IF socket option works well for unconnected sockets,
that is, the interface specified by the IP_UNICAST_IF socket option
is taken into consideration in the route lookup process when a packet
is being sent. However, for connected sockets, the outbound interface
is chosen when connecting the socket, and in the route lookup process
which is done when a packet is being sent, the interface specified by
the IP_UNICAST_IF socket option is being ignored.

This inconsistent behavior was reported and discussed in an issue
opened on systemd's GitHub project [2]. Also, a bug report was
submitted in the kernel's bugzilla [3].

To understand the problem in more detail, we can look at what happens
for UDP packets over IPv4 (The same analysis was done separately in
the referenced systemd issue).
When a UDP packet is sent the udp_sendmsg function gets called and
the following happens:

1. The oif member of the struct ipcm_cookie ipc (which stores the
output interface of the packet) is initialized by the ipcm_init_sk
function to inet->sk.sk_bound_dev_if (the device set by the
SO_BINDTODEVICE socket option).

2. If the IP_PKTINFO socket option was set, the oif member gets
overridden by the call to the ip_cmsg_send function.

3. If no output interface was selected yet, the interface specified
by the IP_UNICAST_IF socket option is used.

4. If the socket is connected and no destination address is
specified in the send function, the struct ipcm_cookie ipc is not
taken into consideration and the cached route, that was calculated in
the connect function is being used.

Thus, for a connected socket, the IP_UNICAST_IF sockopt isn't taken
into consideration.

This patch corrects the behavior of the IP_UNICAST_IF socket option
for connect()ed sockets by taking into consideration the
IP_UNICAST_IF sockopt when connecting the socket.

In order to avoid reconnecting the socket, this option is still
ignored when applied on an already connected socket until connect()
is called again by the Richard Gobert.

Change the __ip4_datagram_connect function, which is called during
socket connection, to take into consideration the interface set by
the IP_UNICAST_IF socket option, in a similar way to what is done in
the udp_sendmsg function.

[1] https://lore.kernel.org/netdev/1328685717.4736.4.camel@edumazet-laptop/T/
[2] https://github.com/systemd/systemd/issues/11935#issuecomment-618691018
[3] https://bugzilla.kernel.org/show_bug.cgi?id=210255

Signed-off-by: Richard Gobert <[email protected]>
Reviewed-by: David Ahern <[email protected]>
Link: https://lore.kernel.org/r/20220829111554.GA1771@debian
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/ipv4/datagram.c | 2 ++
tools/testing/selftests/net/fcnal-test.sh | 30 +++++++++++++++++++++++
tools/testing/selftests/net/nettest.c | 16 ++++++++++--
3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index ffd57523331f..405a8c2aea64 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -42,6 +42,8 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
+ } else if (!oif) {
+ oif = inet->uc_index;
}
fl4 = &inet->cork.fl.u.ip4;
rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr, oif,
diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh
index 03b586760164..31c3b6ebd388 100755
--- a/tools/testing/selftests/net/fcnal-test.sh
+++ b/tools/testing/selftests/net/fcnal-test.sh
@@ -1466,6 +1466,13 @@ ipv4_udp_novrf()
run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP}
log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF"

+ log_start
+ run_cmd_nsb nettest -D -s &
+ sleep 1
+ run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} -U
+ log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF, with connect()"
+
+
log_start
show_hint "Should fail 'Connection refused'"
run_cmd nettest -D -r ${a}
@@ -1525,6 +1532,13 @@ ipv4_udp_novrf()
run_cmd nettest -D -d ${NSA_DEV} -S -r ${a}
log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection"

+ log_start
+ run_cmd nettest -s -D &
+ sleep 1
+ run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} -U
+ log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
+
+
# IPv4 with device bind has really weird behavior - it overrides the
# fib lookup, generates an rtable and tries to send the packet. This
# causes failures for local traffic at different places
@@ -1550,6 +1564,15 @@ ipv4_udp_novrf()
sleep 1
run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S
log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection"
+
+ log_start
+ show_hint "Should fail since addresses on loopback are out of device scope"
+ run_cmd nettest -D -s &
+ sleep 1
+ run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -U
+ log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
+
+
done

a=${NSA_IP}
@@ -3157,6 +3180,13 @@ ipv6_udp_novrf()
sleep 1
run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S
log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection"
+
+ log_start
+ show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope"
+ run_cmd nettest -6 -D -s &
+ sleep 1
+ run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S -U
+ log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
done

a=${NSA_IP6}
diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c
index d9a6fd2cd9d3..7900fa98eccb 100644
--- a/tools/testing/selftests/net/nettest.c
+++ b/tools/testing/selftests/net/nettest.c
@@ -127,6 +127,9 @@ struct sock_args {

/* ESP in UDP encap test */
int use_xfrm;
+
+ /* use send() and connect() instead of sendto */
+ int datagram_connect;
};

static int server_mode;
@@ -979,6 +982,11 @@ static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)
log_err_errno("write failed sending msg to peer");
return 1;
}
+ } else if (args->datagram_connect) {
+ if (send(sd, msg, msglen, 0) < 0) {
+ log_err_errno("send failed sending msg to peer");
+ return 1;
+ }
} else if (args->ifindex && args->use_cmsg) {
if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version))
return 1;
@@ -1659,7 +1667,7 @@ static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
if (args->has_local_ip && bind_socket(sd, args))
goto err;

- if (args->type != SOCK_STREAM)
+ if (args->type != SOCK_STREAM && !args->datagram_connect)
goto out;

if (args->password && tcp_md5sig(sd, addr, alen, args))
@@ -1854,7 +1862,7 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)
return client_status;
}

-#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf"
+#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SUCi6xL:0:1:2:3:Fbqf"
#define OPT_FORCE_BIND_KEY_IFINDEX 1001
#define OPT_NO_BIND_KEY_IFINDEX 1002

@@ -1891,6 +1899,7 @@ static void print_usage(char *prog)
" -I dev bind socket to given device name - server mode\n"
" -S use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n"
" to set device binding\n"
+ " -U Use connect() and send() for datagram sockets\n"
" -f bind socket with the IP[V6]_FREEBIND option\n"
" -C use cmsg and IP_PKTINFO to specify device binding\n"
"\n"
@@ -2074,6 +2083,9 @@ int main(int argc, char *argv[])
case 'x':
args.use_xfrm = 1;
break;
+ case 'U':
+ args.datagram_connect = 1;
+ break;
default:
print_usage(argv[0]);
return 1;
--
2.35.1

2022-10-09 23:42:37

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 55/77] net/sched: taprio: taprio_dump and taprio_change are protected by rtnl_mutex

From: Vladimir Oltean <[email protected]>

[ Upstream commit 18cdd2f0998a4967b1fff4c43ed9aef049e42c39 ]

Since the writer-side lock is taken here, we do not need to open an RCU
read-side critical section, instead we can use rtnl_dereference() to
tell lockdep we are serialized with concurrent writes.

Signed-off-by: Vladimir Oltean <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/sched/sch_taprio.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 86675a79da1e..71408136d4a0 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -1492,10 +1492,8 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
}
INIT_LIST_HEAD(&new_admin->entries);

- rcu_read_lock();
- oper = rcu_dereference(q->oper_sched);
- admin = rcu_dereference(q->admin_sched);
- rcu_read_unlock();
+ oper = rtnl_dereference(q->oper_sched);
+ admin = rtnl_dereference(q->admin_sched);

/* no changes - no new mqprio settings */
if (!taprio_mqprio_cmp(dev, mqprio))
@@ -1888,9 +1886,8 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
struct nlattr *nest, *sched_nest;
unsigned int i;

- rcu_read_lock();
- oper = rcu_dereference(q->oper_sched);
- admin = rcu_dereference(q->admin_sched);
+ oper = rtnl_dereference(q->oper_sched);
+ admin = rtnl_dereference(q->admin_sched);

opt.num_tc = netdev_get_num_tc(dev);
memcpy(opt.prio_tc_map, dev->prio_tc_map, sizeof(opt.prio_tc_map));
@@ -1934,8 +1931,6 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
nla_nest_end(skb, sched_nest);

done:
- rcu_read_unlock();
-
return nla_nest_end(skb, nest);

admin_error:
@@ -1945,7 +1940,6 @@ static int taprio_dump(struct Qdisc *sch, struct sk_buff *skb)
nla_nest_cancel(skb, nest);

start_error:
- rcu_read_unlock();
return -ENOSPC;
}

--
2.35.1

2022-10-09 23:43:09

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 10/77] openvswitch: Fix overreporting of drops in dropwatch

From: Mike Pattrick <[email protected]>

[ Upstream commit c21ab2afa2c64896a7f0e3cbc6845ec63dcfad2e ]

Currently queue_userspace_packet will call kfree_skb for all frames,
whether or not an error occurred. This can result in a single dropped
frame being reported as multiple drops in dropwatch. This functions
caller may also call kfree_skb in case of an error. This patch will
consume the skbs instead and allow caller's to use kfree_skb.

Signed-off-by: Mike Pattrick <[email protected]>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2109957
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/openvswitch/datapath.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index b68ba3c72519..93c596e3b22b 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -558,8 +558,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
out:
if (err)
skb_tx_error(skb);
- kfree_skb(user_skb);
- kfree_skb(nskb);
+ consume_skb(user_skb);
+ consume_skb(nskb);
+
return err;
}

--
2.35.1

2022-10-09 23:43:18

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 59/77] bnxt_en: replace reset with config timestamps

From: Vadim Fedorenko <[email protected]>

[ Upstream commit 8db3d514e96715c897fe793c4d5fc0fd86aca517 ]

Any change to the hardware timestamps configuration triggers nic restart,
which breaks transmition and reception of network packets for a while.
But there is no need to fully restart the device because while configuring
hardware timestamps. The code for changing configuration runs after all
of the initialisation, when the NIC is actually up and running. This patch
changes the code that ioctl will only update configuration registers and
will not trigger carrier status change, but in case of timestamps for
all rx packetes it fallbacks to close()/open() sequnce because of
synchronization issues in the hardware. Tested on BCM57504.

Cc: Richard Cochran <[email protected]>
Signed-off-by: Vadim Fedorenko <[email protected]>
Reviewed-by: Michael Chan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
index 8e316367f6ce..2132ce63193c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
@@ -505,9 +505,13 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
ptp->tstamp_filters = flags;

if (netif_running(bp->dev)) {
- rc = bnxt_close_nic(bp, false, false);
- if (!rc)
- rc = bnxt_open_nic(bp, false, false);
+ if (ptp->rx_filter == HWTSTAMP_FILTER_ALL) {
+ rc = bnxt_close_nic(bp, false, false);
+ if (!rc)
+ rc = bnxt_open_nic(bp, false, false);
+ } else {
+ bnxt_ptp_cfg_tstamp_filters(bp);
+ }
if (!rc && !ptp->tstamp_filters)
rc = -EIO;
}
--
2.35.1

2022-10-09 23:43:21

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 34/77] iavf: Fix race between iavf_close and iavf_reset_task

From: Michal Jaron <[email protected]>

[ Upstream commit 11c12adcbc1598d91e73ab6ddfa41d25a01478ed ]

During stress tests with adding VF to namespace and changing vf's
trust there was a race between iavf_reset_task and iavf_close.
Sometimes when IAVF_FLAG_AQ_DISABLE_QUEUES from iavf_close was sent
to PF after reset and before IAVF_AQ_GET_CONFIG was sent then PF
returns error IAVF_NOT_SUPPORTED to disable queues request and
following requests. There is need to get_config before other
aq_required will be send but iavf_close clears all flags, if
get_config was not sent before iavf_close, then it will not be send
at all.

In case when IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS was sent before
IAVF_FLAG_AQ_DISABLE_QUEUES then there was rtnl_lock deadlock
between iavf_close and iavf_adminq_task until iavf_close timeouts
and disable queues was sent after iavf_close ends.

There was also a problem with sending delete/add filters.
Sometimes when filters was not yet added to PF and in
iavf_close all filters was set to remove there might be a try
to remove nonexistent filters on PF.

Add aq_required_tmp to save aq_required flags and send them after
disable_queues will be handled. Clear flags given to iavf_down
different than IAVF_FLAG_AQ_GET_CONFIG as this flag is necessary
to sent other aq_required. Remove some flags that we don't
want to send as we are in iavf_close and we want to disable
interface. Remove filters which was not yet sent and send del
filters flags only when there are filters to remove.

Signed-off-by: Michal Jaron <[email protected]>
Signed-off-by: Mateusz Palczewski <[email protected]>
Tested-by: Konrad Jankowski <[email protected]>
Signed-off-by: Tony Nguyen <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/intel/iavf/iavf_main.c | 177 ++++++++++++++++----
1 file changed, 141 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index 0c89f16bf1e2..79fef8c59d65 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -1267,66 +1267,138 @@ static void iavf_up_complete(struct iavf_adapter *adapter)
}

/**
- * iavf_down - Shutdown the connection processing
+ * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF
+ * yet and mark other to be removed.
* @adapter: board private structure
- *
- * Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock.
**/
-void iavf_down(struct iavf_adapter *adapter)
+static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
{
- struct net_device *netdev = adapter->netdev;
- struct iavf_vlan_filter *vlf;
- struct iavf_cloud_filter *cf;
- struct iavf_fdir_fltr *fdir;
- struct iavf_mac_filter *f;
- struct iavf_adv_rss *rss;
-
- if (adapter->state <= __IAVF_DOWN_PENDING)
- return;
-
- netif_carrier_off(netdev);
- netif_tx_disable(netdev);
- adapter->link_up = false;
- iavf_napi_disable_all(adapter);
- iavf_irq_disable(adapter);
+ struct iavf_vlan_filter *vlf, *vlftmp;
+ struct iavf_mac_filter *f, *ftmp;

spin_lock_bh(&adapter->mac_vlan_list_lock);
-
/* clear the sync flag on all filters */
__dev_uc_unsync(adapter->netdev, NULL);
__dev_mc_unsync(adapter->netdev, NULL);

/* remove all MAC filters */
- list_for_each_entry(f, &adapter->mac_filter_list, list) {
- f->remove = true;
+ list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list,
+ list) {
+ if (f->add) {
+ list_del(&f->list);
+ kfree(f);
+ } else {
+ f->remove = true;
+ }
}

/* remove all VLAN filters */
- list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
- vlf->remove = true;
+ list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
+ list) {
+ if (vlf->add) {
+ list_del(&vlf->list);
+ kfree(vlf);
+ } else {
+ vlf->remove = true;
+ }
}
-
spin_unlock_bh(&adapter->mac_vlan_list_lock);
+}
+
+/**
+ * iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and
+ * mark other to be removed.
+ * @adapter: board private structure
+ **/
+static void iavf_clear_cloud_filters(struct iavf_adapter *adapter)
+{
+ struct iavf_cloud_filter *cf, *cftmp;

/* remove all cloud filters */
spin_lock_bh(&adapter->cloud_filter_list_lock);
- list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
- cf->del = true;
+ list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
+ list) {
+ if (cf->add) {
+ list_del(&cf->list);
+ kfree(cf);
+ adapter->num_cloud_filters--;
+ } else {
+ cf->del = true;
+ }
}
spin_unlock_bh(&adapter->cloud_filter_list_lock);
+}
+
+/**
+ * iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark
+ * other to be removed.
+ * @adapter: board private structure
+ **/
+static void iavf_clear_fdir_filters(struct iavf_adapter *adapter)
+{
+ struct iavf_fdir_fltr *fdir, *fdirtmp;

/* remove all Flow Director filters */
spin_lock_bh(&adapter->fdir_fltr_lock);
- list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
- fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
+ list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head,
+ list) {
+ if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
+ list_del(&fdir->list);
+ kfree(fdir);
+ adapter->fdir_active_fltr--;
+ } else {
+ fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
+ }
}
spin_unlock_bh(&adapter->fdir_fltr_lock);
+}
+
+/**
+ * iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark
+ * other to be removed.
+ * @adapter: board private structure
+ **/
+static void iavf_clear_adv_rss_conf(struct iavf_adapter *adapter)
+{
+ struct iavf_adv_rss *rss, *rsstmp;

/* remove all advance RSS configuration */
spin_lock_bh(&adapter->adv_rss_lock);
- list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
- rss->state = IAVF_ADV_RSS_DEL_REQUEST;
+ list_for_each_entry_safe(rss, rsstmp, &adapter->adv_rss_list_head,
+ list) {
+ if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) {
+ list_del(&rss->list);
+ kfree(rss);
+ } else {
+ rss->state = IAVF_ADV_RSS_DEL_REQUEST;
+ }
+ }
spin_unlock_bh(&adapter->adv_rss_lock);
+}
+
+/**
+ * iavf_down - Shutdown the connection processing
+ * @adapter: board private structure
+ *
+ * Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock.
+ **/
+void iavf_down(struct iavf_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ if (adapter->state <= __IAVF_DOWN_PENDING)
+ return;
+
+ netif_carrier_off(netdev);
+ netif_tx_disable(netdev);
+ adapter->link_up = false;
+ iavf_napi_disable_all(adapter);
+ iavf_irq_disable(adapter);
+
+ iavf_clear_mac_vlan_filters(adapter);
+ iavf_clear_cloud_filters(adapter);
+ iavf_clear_fdir_filters(adapter);
+ iavf_clear_adv_rss_conf(adapter);

if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) {
/* cancel any current operation */
@@ -1335,11 +1407,16 @@ void iavf_down(struct iavf_adapter *adapter)
* here for this to complete. The watchdog is still running
* and it will take care of this.
*/
- adapter->aq_required = IAVF_FLAG_AQ_DEL_MAC_FILTER;
- adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
- adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
- adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
- adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
+ if (!list_empty(&adapter->mac_filter_list))
+ adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER;
+ if (!list_empty(&adapter->vlan_filter_list))
+ adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
+ if (!list_empty(&adapter->cloud_filter_list))
+ adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
+ if (!list_empty(&adapter->fdir_list_head))
+ adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
+ if (!list_empty(&adapter->adv_rss_list_head))
+ adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
}

@@ -4178,6 +4255,7 @@ static int iavf_open(struct net_device *netdev)
static int iavf_close(struct net_device *netdev)
{
struct iavf_adapter *adapter = netdev_priv(netdev);
+ u64 aq_to_restore;
int status;

mutex_lock(&adapter->crit_lock);
@@ -4190,6 +4268,29 @@ static int iavf_close(struct net_device *netdev)
set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
if (CLIENT_ENABLED(adapter))
adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_CLOSE;
+ /* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before
+ * IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl
+ * deadlock with adminq_task() until iavf_close timeouts. We must send
+ * IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make
+ * disable queues possible for vf. Give only necessary flags to
+ * iavf_down and save other to set them right before iavf_close()
+ * returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and
+ * iavf will be in DOWN state.
+ */
+ aq_to_restore = adapter->aq_required;
+ adapter->aq_required &= IAVF_FLAG_AQ_GET_CONFIG;
+
+ /* Remove flags which we do not want to send after close or we want to
+ * send before disable queues.
+ */
+ aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG |
+ IAVF_FLAG_AQ_ENABLE_QUEUES |
+ IAVF_FLAG_AQ_CONFIGURE_QUEUES |
+ IAVF_FLAG_AQ_ADD_VLAN_FILTER |
+ IAVF_FLAG_AQ_ADD_MAC_FILTER |
+ IAVF_FLAG_AQ_ADD_CLOUD_FILTER |
+ IAVF_FLAG_AQ_ADD_FDIR_FILTER |
+ IAVF_FLAG_AQ_ADD_ADV_RSS_CFG);

iavf_down(adapter);
iavf_change_state(adapter, __IAVF_DOWN_PENDING);
@@ -4213,6 +4314,10 @@ static int iavf_close(struct net_device *netdev)
msecs_to_jiffies(500));
if (!status)
netdev_warn(netdev, "Device resources not yet released\n");
+
+ mutex_lock(&adapter->crit_lock);
+ adapter->aq_required |= aq_to_restore;
+ mutex_unlock(&adapter->crit_lock);
return 0;
}

--
2.35.1

2022-10-09 23:43:31

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 53/77] net: sfp: move quirk handling into sfp.c

From: "Russell King (Oracle)" <[email protected]>

[ Upstream commit 23571c7b96437483d28a990c906cc81f5f66374e ]

We need to handle more quirks than just those which affect the link
modes of the module. Move the quirk lookup into sfp.c, and pass the
quirk to sfp-bus.c

Signed-off-by: Russell King (Oracle) <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/phy/sfp-bus.c | 98 ++-------------------------------------
drivers/net/phy/sfp.c | 94 ++++++++++++++++++++++++++++++++++++-
drivers/net/phy/sfp.h | 9 +++-
3 files changed, 104 insertions(+), 97 deletions(-)

diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 15aa5ac1ff49..82216c7bb470 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -10,12 +10,6 @@

#include "sfp.h"

-struct sfp_quirk {
- const char *vendor;
- const char *part;
- void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
-};
-
/**
* struct sfp_bus - internal representation of a sfp bus
*/
@@ -38,93 +32,6 @@ struct sfp_bus {
bool started;
};

-static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
- unsigned long *modes)
-{
- phylink_set(modes, 2500baseX_Full);
-}
-
-static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
- unsigned long *modes)
-{
- /* Ubiquiti U-Fiber Instant module claims that support all transceiver
- * types including 10G Ethernet which is not truth. So clear all claimed
- * modes and set only one mode which module supports: 1000baseX_Full.
- */
- phylink_zero(modes);
- phylink_set(modes, 1000baseX_Full);
-}
-
-static const struct sfp_quirk sfp_quirks[] = {
- {
- // Alcatel Lucent G-010S-P can operate at 2500base-X, but
- // incorrectly report 2500MBd NRZ in their EEPROM
- .vendor = "ALCATELLUCENT",
- .part = "G010SP",
- .modes = sfp_quirk_2500basex,
- }, {
- // Alcatel Lucent G-010S-A can operate at 2500base-X, but
- // report 3.2GBd NRZ in their EEPROM
- .vendor = "ALCATELLUCENT",
- .part = "3FE46541AA",
- .modes = sfp_quirk_2500basex,
- }, {
- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
- // NRZ in their EEPROM
- .vendor = "HUAWEI",
- .part = "MA5671A",
- .modes = sfp_quirk_2500basex,
- }, {
- // Lantech 8330-262D-E can operate at 2500base-X, but
- // incorrectly report 2500MBd NRZ in their EEPROM
- .vendor = "Lantech",
- .part = "8330-262D-E",
- .modes = sfp_quirk_2500basex,
- }, {
- .vendor = "UBNT",
- .part = "UF-INSTANT",
- .modes = sfp_quirk_ubnt_uf_instant,
- },
-};
-
-static size_t sfp_strlen(const char *str, size_t maxlen)
-{
- size_t size, i;
-
- /* Trailing characters should be filled with space chars */
- for (i = 0, size = 0; i < maxlen; i++)
- if (str[i] != ' ')
- size = i + 1;
-
- return size;
-}
-
-static bool sfp_match(const char *qs, const char *str, size_t len)
-{
- if (!qs)
- return true;
- if (strlen(qs) != len)
- return false;
- return !strncmp(qs, str, len);
-}
-
-static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
-{
- const struct sfp_quirk *q;
- unsigned int i;
- size_t vs, ps;
-
- vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
- ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
-
- for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
- if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
- sfp_match(q->part, id->base.vendor_pn, ps))
- return q;
-
- return NULL;
-}
-
/**
* sfp_parse_port() - Parse the EEPROM base ID, setting the port type
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
@@ -786,12 +693,13 @@ void sfp_link_down(struct sfp_bus *bus)
}
EXPORT_SYMBOL_GPL(sfp_link_down);

-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
+ const struct sfp_quirk *quirk)
{
const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
int ret = 0;

- bus->sfp_quirk = sfp_lookup_quirk(id);
+ bus->sfp_quirk = quirk;

if (ops && ops->module_insert)
ret = ops->module_insert(bus->upstream, id);
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index a38705cf192f..2b06230be94f 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -253,6 +253,8 @@ struct sfp {
unsigned int module_t_start_up;
bool tx_fault_ignore;

+ const struct sfp_quirk *quirk;
+
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
struct delayed_work hwmon_probe;
@@ -309,6 +311,93 @@ static const struct of_device_id sfp_of_match[] = {
};
MODULE_DEVICE_TABLE(of, sfp_of_match);

+static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
+ unsigned long *modes)
+{
+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes);
+}
+
+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
+ unsigned long *modes)
+{
+ /* Ubiquiti U-Fiber Instant module claims that support all transceiver
+ * types including 10G Ethernet which is not truth. So clear all claimed
+ * modes and set only one mode which module supports: 1000baseX_Full.
+ */
+ linkmode_zero(modes);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
+}
+
+static const struct sfp_quirk sfp_quirks[] = {
+ {
+ // Alcatel Lucent G-010S-P can operate at 2500base-X, but
+ // incorrectly report 2500MBd NRZ in their EEPROM
+ .vendor = "ALCATELLUCENT",
+ .part = "G010SP",
+ .modes = sfp_quirk_2500basex,
+ }, {
+ // Alcatel Lucent G-010S-A can operate at 2500base-X, but
+ // report 3.2GBd NRZ in their EEPROM
+ .vendor = "ALCATELLUCENT",
+ .part = "3FE46541AA",
+ .modes = sfp_quirk_2500basex,
+ }, {
+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
+ // NRZ in their EEPROM
+ .vendor = "HUAWEI",
+ .part = "MA5671A",
+ .modes = sfp_quirk_2500basex,
+ }, {
+ // Lantech 8330-262D-E can operate at 2500base-X, but
+ // incorrectly report 2500MBd NRZ in their EEPROM
+ .vendor = "Lantech",
+ .part = "8330-262D-E",
+ .modes = sfp_quirk_2500basex,
+ }, {
+ .vendor = "UBNT",
+ .part = "UF-INSTANT",
+ .modes = sfp_quirk_ubnt_uf_instant,
+ },
+};
+
+static size_t sfp_strlen(const char *str, size_t maxlen)
+{
+ size_t size, i;
+
+ /* Trailing characters should be filled with space chars */
+ for (i = 0, size = 0; i < maxlen; i++)
+ if (str[i] != ' ')
+ size = i + 1;
+
+ return size;
+}
+
+static bool sfp_match(const char *qs, const char *str, size_t len)
+{
+ if (!qs)
+ return true;
+ if (strlen(qs) != len)
+ return false;
+ return !strncmp(qs, str, len);
+}
+
+static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
+{
+ const struct sfp_quirk *q;
+ unsigned int i;
+ size_t vs, ps;
+
+ vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
+ ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
+
+ for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
+ if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
+ sfp_match(q->part, id->base.vendor_pn, ps))
+ return q;
+
+ return NULL;
+}
+
static unsigned long poll_jiffies;

static unsigned int sfp_gpio_get_state(struct sfp *sfp)
@@ -1971,6 +2060,8 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
else
sfp->tx_fault_ignore = false;

+ sfp->quirk = sfp_lookup_quirk(&id);
+
return 0;
}

@@ -2083,7 +2174,8 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
break;

/* Report the module insertion to the upstream device */
- err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id,
+ sfp->quirk);
if (err < 0) {
sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
break;
diff --git a/drivers/net/phy/sfp.h b/drivers/net/phy/sfp.h
index 27226535c72b..03f1d47fe6ca 100644
--- a/drivers/net/phy/sfp.h
+++ b/drivers/net/phy/sfp.h
@@ -6,6 +6,12 @@

struct sfp;

+struct sfp_quirk {
+ const char *vendor;
+ const char *part;
+ void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
+};
+
struct sfp_socket_ops {
void (*attach)(struct sfp *sfp);
void (*detach)(struct sfp *sfp);
@@ -23,7 +29,8 @@ int sfp_add_phy(struct sfp_bus *bus, struct phy_device *phydev);
void sfp_remove_phy(struct sfp_bus *bus);
void sfp_link_up(struct sfp_bus *bus);
void sfp_link_down(struct sfp_bus *bus);
-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
+ const struct sfp_quirk *quirk);
void sfp_module_remove(struct sfp_bus *bus);
int sfp_module_start(struct sfp_bus *bus);
void sfp_module_stop(struct sfp_bus *bus);
--
2.35.1

2022-10-09 23:44:43

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 68/77] net: If sock is dead don't access sock's sk_wq in sk_stream_wait_memory

From: Liu Jian <[email protected]>

[ Upstream commit 3f8ef65af927db247418d4e1db49164d7a158fc5 ]

Fixes the below NULL pointer dereference:

[...]
[ 14.471200] Call Trace:
[ 14.471562] <TASK>
[ 14.471882] lock_acquire+0x245/0x2e0
[ 14.472416] ? remove_wait_queue+0x12/0x50
[ 14.473014] ? _raw_spin_lock_irqsave+0x17/0x50
[ 14.473681] _raw_spin_lock_irqsave+0x3d/0x50
[ 14.474318] ? remove_wait_queue+0x12/0x50
[ 14.474907] remove_wait_queue+0x12/0x50
[ 14.475480] sk_stream_wait_memory+0x20d/0x340
[ 14.476127] ? do_wait_intr_irq+0x80/0x80
[ 14.476704] do_tcp_sendpages+0x287/0x600
[ 14.477283] tcp_bpf_push+0xab/0x260
[ 14.477817] tcp_bpf_sendmsg_redir+0x297/0x500
[ 14.478461] ? __local_bh_enable_ip+0x77/0xe0
[ 14.479096] tcp_bpf_send_verdict+0x105/0x470
[ 14.479729] tcp_bpf_sendmsg+0x318/0x4f0
[ 14.480311] sock_sendmsg+0x2d/0x40
[ 14.480822] ____sys_sendmsg+0x1b4/0x1c0
[ 14.481390] ? copy_msghdr_from_user+0x62/0x80
[ 14.482048] ___sys_sendmsg+0x78/0xb0
[ 14.482580] ? vmf_insert_pfn_prot+0x91/0x150
[ 14.483215] ? __do_fault+0x2a/0x1a0
[ 14.483738] ? do_fault+0x15e/0x5d0
[ 14.484246] ? __handle_mm_fault+0x56b/0x1040
[ 14.484874] ? lock_is_held_type+0xdf/0x130
[ 14.485474] ? find_held_lock+0x2d/0x90
[ 14.486046] ? __sys_sendmsg+0x41/0x70
[ 14.486587] __sys_sendmsg+0x41/0x70
[ 14.487105] ? intel_pmu_drain_pebs_core+0x350/0x350
[ 14.487822] do_syscall_64+0x34/0x80
[ 14.488345] entry_SYSCALL_64_after_hwframe+0x63/0xcd
[...]

The test scenario has the following flow:

thread1 thread2
----------- ---------------
tcp_bpf_sendmsg
tcp_bpf_send_verdict
tcp_bpf_sendmsg_redir sock_close
tcp_bpf_push_locked __sock_release
tcp_bpf_push //inet_release
do_tcp_sendpages sock->ops->release
sk_stream_wait_memory // tcp_close
sk_wait_event sk->sk_prot->close
release_sock(__sk);
***
lock_sock(sk);
__tcp_close
sock_orphan(sk)
sk->sk_wq = NULL
release_sock
****
lock_sock(__sk);
remove_wait_queue(sk_sleep(sk), &wait);
sk_sleep(sk)
//NULL pointer dereference
&rcu_dereference_raw(sk->sk_wq)->wait

While waiting for memory in thread1, the socket is released with its wait
queue because thread2 has closed it. This caused by tcp_bpf_send_verdict
didn't increase the f_count of psock->sk_redir->sk_socket->file in thread1.

We should check if SOCK_DEAD flag is set on wakeup in sk_stream_wait_memory
before accessing the wait queue.

Suggested-by: Jakub Sitnicki <[email protected]>
Signed-off-by: Liu Jian <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Acked-by: John Fastabend <[email protected]>
Cc: Eric Dumazet <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
net/core/stream.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/stream.c b/net/core/stream.c
index ccc083cdef23..1105057ce00a 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -159,7 +159,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
*timeo_p = current_timeo;
}
out:
- remove_wait_queue(sk_sleep(sk), &wait);
+ if (!sock_flag(sk, SOCK_DEAD))
+ remove_wait_queue(sk_sleep(sk), &wait);
return err;

do_error:
--
2.35.1

2022-10-09 23:45:26

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 49/77] net: korina: Fix return type of korina_send_packet

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 106c67ce46f3c82dd276e983668a91d6ed631173 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of korina_send_packet should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Reviewed-by: Nathan Chancellor <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/korina.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index df9a8eefa007..eec6a9ec528b 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -416,7 +416,8 @@ static void korina_abort_rx(struct net_device *dev)
}

/* transmit packet */
-static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t korina_send_packet(struct sk_buff *skb,
+ struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
u32 chain_prev, chain_next;
--
2.35.1

2022-10-09 23:46:12

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 47/77] net: ethernet: ti: davinci_emac: Fix return type of emac_dev_xmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 5972ca946098487c5155fe13654743f9010f5ed5 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of emac_dev_xmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Reviewed-by: Nathan Chancellor <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/ti/davinci_emac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 2a3e4e842fa5..e203a5984f03 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -949,7 +949,7 @@ static void emac_tx_handler(void *token, int len, int status)
*
* Returns success(NETDEV_TX_OK) or error code (typically out of desc's)
*/
-static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct device *emac_dev = &ndev->dev;
int ret_code;
--
2.35.1

2022-10-09 23:46:29

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 51/77] net: wwan: t7xx: Fix return type of t7xx_ccmni_start_xmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 73c99e26036529e633a0f2d628ad7ddff6594668 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of t7xx_ccmni_start_xmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Acked-by: Sergey Ryazanov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/wwan/t7xx/t7xx_netdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wwan/t7xx/t7xx_netdev.c b/drivers/net/wwan/t7xx/t7xx_netdev.c
index c6b6547f2c6f..f71d3bc3b237 100644
--- a/drivers/net/wwan/t7xx/t7xx_netdev.c
+++ b/drivers/net/wwan/t7xx/t7xx_netdev.c
@@ -74,7 +74,7 @@ static int t7xx_ccmni_send_packet(struct t7xx_ccmni *ccmni, struct sk_buff *skb,
return 0;
}

-static int t7xx_ccmni_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t t7xx_ccmni_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct t7xx_ccmni *ccmni = wwan_netdev_drvpriv(dev);
int skb_len = skb->len;
--
2.35.1

2022-10-09 23:46:39

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 12/77] net: mscc: ocelot: adjust forwarding domain for CPU ports in a LAG

From: Vladimir Oltean <[email protected]>

[ Upstream commit 291ac1517af58670740528466ccebe3caefb9093 ]

Currently when we have 2 CPU ports configured for DSA tag_8021q mode and
we put them in a LAG, a PGID dump looks like this:

PGID_SRC[0] = ports 4,
PGID_SRC[1] = ports 4,
PGID_SRC[2] = ports 4,
PGID_SRC[3] = ports 4,
PGID_SRC[4] = ports 0, 1, 2, 3, 4, 5,
PGID_SRC[5] = no ports

(ports 0-3 are user ports, ports 4 and 5 are CPU ports)

There are 2 problems with the configuration above:

- user ports should enable forwarding towards both CPU ports, not just 4,
and the aggregation PGIDs should prune one CPU port or the other from
the destination port mask, based on a hash computed from packet headers.

- CPU ports should not be allowed to forward towards themselves and also
not towards other ports in the same LAG as themselves

The first problem requires fixing up the PGID_SRC of user ports, when
ocelot_port_assigned_dsa_8021q_cpu_mask() is called. We need to say that
when a user port is assigned to a tag_8021q CPU port and that port is in
a LAG, it should forward towards all ports in that LAG.

The second problem requires fixing up the PGID_SRC of port 4, to remove
ports 4 and 5 (in a LAG) from the allowed destinations.

After this change, the PGID source masks look as follows:

PGID_SRC[0] = ports 4, 5,
PGID_SRC[1] = ports 4, 5,
PGID_SRC[2] = ports 4, 5,
PGID_SRC[3] = ports 4, 5,
PGID_SRC[4] = ports 0, 1, 2, 3,
PGID_SRC[5] = no ports

Note that PGID_SRC[5] still looks weird (it should say "0, 1, 2, 3" just
like PGID_SRC[4] does), but I've tested forwarding through this CPU port
and it doesn't seem like anything is affected (it appears that PGID_SRC[4]
is being looked up on forwarding from the CPU, since both ports 4 and 5
have logical port ID 4). The reason why it looks weird is because
we've never called ocelot_port_assign_dsa_8021q_cpu() for any user port
towards port 5 (all user ports are assigned to port 4 which is in a LAG
with 5).

Since things aren't broken, I'm willing to leave it like that for now
and just document the oddity.

Signed-off-by: Vladimir Oltean <[email protected]>
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/mscc/ocelot.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 8f8005bc6eea..708a9aab8c76 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -2071,6 +2071,16 @@ static int ocelot_bond_get_id(struct ocelot *ocelot, struct net_device *bond)
return __ffs(bond_mask);
}

+/* Returns the mask of user ports assigned to this DSA tag_8021q CPU port.
+ * Note that when CPU ports are in a LAG, the user ports are assigned to the
+ * 'primary' CPU port, the one whose physical port number gives the logical
+ * port number of the LAG.
+ *
+ * We leave PGID_SRC poorly configured for the 'secondary' CPU port in the LAG
+ * (to which no user port is assigned), but it appears that forwarding from
+ * this secondary CPU port looks at the PGID_SRC associated with the logical
+ * port ID that it's assigned to, which *is* configured properly.
+ */
static u32 ocelot_dsa_8021q_cpu_assigned_ports(struct ocelot *ocelot,
struct ocelot_port *cpu)
{
@@ -2087,9 +2097,15 @@ static u32 ocelot_dsa_8021q_cpu_assigned_ports(struct ocelot *ocelot,
mask |= BIT(port);
}

+ if (cpu->bond)
+ mask &= ~ocelot_get_bond_mask(ocelot, cpu->bond);
+
return mask;
}

+/* Returns the DSA tag_8021q CPU port that the given port is assigned to,
+ * or the bit mask of CPU ports if said CPU port is in a LAG.
+ */
u32 ocelot_port_assigned_dsa_8021q_cpu_mask(struct ocelot *ocelot, int port)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
@@ -2098,6 +2114,9 @@ u32 ocelot_port_assigned_dsa_8021q_cpu_mask(struct ocelot *ocelot, int port)
if (!cpu_port)
return 0;

+ if (cpu_port->bond)
+ return ocelot_get_bond_mask(ocelot, cpu_port->bond);
+
return BIT(cpu_port->index);
}
EXPORT_SYMBOL_GPL(ocelot_port_assigned_dsa_8021q_cpu_mask);
--
2.35.1

2022-10-09 23:46:58

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 61/77] can: bcm: check the result of can_send() in bcm_can_tx()

From: Ziyang Xuan <[email protected]>

[ Upstream commit 3fd7bfd28cfd68ae80a2fe92ea1615722cc2ee6e ]

If can_send() fail, it should not update frames_abs counter
in bcm_can_tx(). Add the result check for can_send() in bcm_can_tx().

Suggested-by: Marc Kleine-Budde <[email protected]>
Suggested-by: Oliver Hartkopp <[email protected]>
Signed-off-by: Ziyang Xuan <[email protected]>
Link: https://lore.kernel.org/all/9851878e74d6d37aee2f1ee76d68361a46f89458.1663206163.git.william.xuanziyang@huawei.com
Acked-by: Oliver Hartkopp <[email protected]>
Signed-off-by: Marc Kleine-Budde <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/can/bcm.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/can/bcm.c b/net/can/bcm.c
index e60161bec850..f16271a7ae2e 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -274,6 +274,7 @@ static void bcm_can_tx(struct bcm_op *op)
struct sk_buff *skb;
struct net_device *dev;
struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe;
+ int err;

/* no target device? => exit */
if (!op->ifindex)
@@ -298,11 +299,11 @@ static void bcm_can_tx(struct bcm_op *op)
/* send with loopback */
skb->dev = dev;
can_skb_set_owner(skb, op->sk);
- can_send(skb, 1);
+ err = can_send(skb, 1);
+ if (!err)
+ op->frames_abs++;

- /* update statistics */
op->currframe++;
- op->frames_abs++;

/* reached last frame? */
if (op->currframe >= op->nframes)
--
2.35.1

2022-10-09 23:47:48

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 31/77] net: lantiq_etop: Fix return type for implementation of ndo_start_xmit

From: GUO Zihua <[email protected]>

[ Upstream commit c8ef3c94bda0e21123202d057d4a299698fa0ed9 ]

Since Linux now supports CFI, it will be a good idea to fix mismatched
return type for implementation of hooks. Otherwise this might get
cought out by CFI and cause a panic.

ltq_etop_tx() would return either NETDEV_TX_BUSY or NETDEV_TX_OK, so
change the return type to netdev_tx_t directly.

Signed-off-by: GUO Zihua <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/lantiq_etop.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 7cedbe1fdfd7..59aab4086dcc 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -470,7 +470,7 @@ ltq_etop_stop(struct net_device *dev)
return 0;
}

-static int
+static netdev_tx_t
ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
{
int queue = skb_get_queue_mapping(skb);
--
2.35.1

2022-10-09 23:48:02

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 60/77] selftests/bpf: Free the allocated resources after test case succeeds

From: Hou Tao <[email protected]>

[ Upstream commit 103d002fb7d548fb1187e350f2b73788558128b9 ]

Free the created fd or allocated bpf_object after test case succeeds,
else there will be resource leaks.

Spotted by using address sanitizer and checking the content of
/proc/$pid/fd directory.

Signed-off-by: Hou Tao <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Martin KaFai Lau <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
.../bpf/map_tests/array_map_batch_ops.c | 2 ++
.../bpf/map_tests/htab_map_batch_ops.c | 2 ++
.../bpf/map_tests/lpm_trie_map_batch_ops.c | 2 ++
tools/testing/selftests/bpf/test_maps.c | 24 ++++++++++++-------
4 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
index 78c76496b14a..b595556315bc 100644
--- a/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
+++ b/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <unistd.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>
@@ -137,6 +138,7 @@ static void __test_map_lookup_and_update_batch(bool is_pcpu)
free(keys);
free(values);
free(visited);
+ close(map_fd);
}

static void array_map_batch_ops(void)
diff --git a/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
index f807d53fd8dd..1230ccf90128 100644
--- a/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
+++ b/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <unistd.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>
@@ -255,6 +256,7 @@ void __test_map_lookup_and_delete_batch(bool is_pcpu)
free(visited);
if (!is_pcpu)
free(values);
+ close(map_fd);
}

void htab_map_batch_ops(void)
diff --git a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
index 87d07b596e17..b66d56ddb7ef 100644
--- a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
+++ b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
@@ -7,6 +7,7 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>
@@ -150,4 +151,5 @@ void test_lpm_trie_map_batch_ops(void)
free(keys);
free(values);
free(visited);
+ close(map_fd);
}
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index cbebfaa7c1e8..4d42ffea0038 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -658,13 +658,13 @@ static void test_sockmap(unsigned int tasks, void *data)
{
struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
+ struct bpf_object *parse_obj, *verdict_obj, *msg_obj;
int ports[] = {50200, 50201, 50202, 50204};
int err, i, fd, udp, sfd[6] = {0xdeadbeef};
u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
int parse_prog, verdict_prog, msg_prog;
struct sockaddr_in addr;
int one = 1, s, sc, rc;
- struct bpf_object *obj;
struct timeval to;
__u32 key, value;
pid_t pid[tasks];
@@ -760,6 +760,7 @@ static void test_sockmap(unsigned int tasks, void *data)
i, udp);
goto out_sockmap;
}
+ close(udp);

/* Test update without programs */
for (i = 0; i < 6; i++) {
@@ -822,27 +823,27 @@ static void test_sockmap(unsigned int tasks, void *data)

/* Load SK_SKB program and Attach */
err = bpf_prog_test_load(SOCKMAP_PARSE_PROG,
- BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
+ BPF_PROG_TYPE_SK_SKB, &parse_obj, &parse_prog);
if (err) {
printf("Failed to load SK_SKB parse prog\n");
goto out_sockmap;
}

err = bpf_prog_test_load(SOCKMAP_TCP_MSG_PROG,
- BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
+ BPF_PROG_TYPE_SK_MSG, &msg_obj, &msg_prog);
if (err) {
printf("Failed to load SK_SKB msg prog\n");
goto out_sockmap;
}

err = bpf_prog_test_load(SOCKMAP_VERDICT_PROG,
- BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
+ BPF_PROG_TYPE_SK_SKB, &verdict_obj, &verdict_prog);
if (err) {
printf("Failed to load SK_SKB verdict prog\n");
goto out_sockmap;
}

- bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
+ bpf_map_rx = bpf_object__find_map_by_name(verdict_obj, "sock_map_rx");
if (!bpf_map_rx) {
printf("Failed to load map rx from verdict prog\n");
goto out_sockmap;
@@ -854,7 +855,7 @@ static void test_sockmap(unsigned int tasks, void *data)
goto out_sockmap;
}

- bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
+ bpf_map_tx = bpf_object__find_map_by_name(verdict_obj, "sock_map_tx");
if (!bpf_map_tx) {
printf("Failed to load map tx from verdict prog\n");
goto out_sockmap;
@@ -866,7 +867,7 @@ static void test_sockmap(unsigned int tasks, void *data)
goto out_sockmap;
}

- bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
+ bpf_map_msg = bpf_object__find_map_by_name(verdict_obj, "sock_map_msg");
if (!bpf_map_msg) {
printf("Failed to load map msg from msg_verdict prog\n");
goto out_sockmap;
@@ -878,7 +879,7 @@ static void test_sockmap(unsigned int tasks, void *data)
goto out_sockmap;
}

- bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
+ bpf_map_break = bpf_object__find_map_by_name(verdict_obj, "sock_map_break");
if (!bpf_map_break) {
printf("Failed to load map tx from verdict prog\n");
goto out_sockmap;
@@ -1124,7 +1125,9 @@ static void test_sockmap(unsigned int tasks, void *data)
}
close(fd);
close(map_fd_rx);
- bpf_object__close(obj);
+ bpf_object__close(parse_obj);
+ bpf_object__close(msg_obj);
+ bpf_object__close(verdict_obj);
return;
out:
for (i = 0; i < 6; i++)
@@ -1282,8 +1285,11 @@ static void test_map_in_map(void)
printf("Inner map mim.inner was not destroyed\n");
goto out_map_in_map;
}
+
+ close(fd);
}

+ bpf_object__close(obj);
return;

out_map_in_map:
--
2.35.1

2022-10-09 23:48:19

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 74/77] i2c: designware-pci: Group AMD NAVI quirk parts together

From: Andy Shevchenko <[email protected]>

[ Upstream commit 65769162ae4b7f2d82e54998be446226b05fcd8f ]

The code is ogranized in a way that all related parts
to the certain platform quirk go together. This is not
the case for AMD NAVI. Shuffle code to make it happen.

While at it, drop the frequency definition and use
hard coded value as it's done for other platforms and
add a comment to the PCI ID list.

Signed-off-by: Andy Shevchenko <[email protected]>
Acked-by: Jarkko Nikula <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/i2c/busses/i2c-designware-pcidrv.c | 30 +++++++++++-----------
1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 608e61209455..ca368482b246 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -27,7 +27,6 @@
#include "i2c-ccgx-ucsi.h"

#define DRIVER_NAME "i2c-designware-pci"
-#define AMD_CLK_RATE_HZ 100000

enum dw_pci_ctl_id_t {
medfield,
@@ -100,11 +99,6 @@ static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev)
return 25000;
}

-static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev)
-{
- return AMD_CLK_RATE_HZ;
-}
-
static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
{
struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
@@ -126,15 +120,6 @@ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
return -ENODEV;
}

-static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
-{
- struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
-
- dev->flags |= MODEL_AMD_NAVI_GPU;
- dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
- return 0;
-}
-
static int mrfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
{
/*
@@ -159,6 +144,20 @@ static u32 ehl_get_clk_rate_khz(struct dw_i2c_dev *dev)
return 100000;
}

+static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev)
+{
+ return 100000;
+}
+
+static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+{
+ struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
+
+ dev->flags |= MODEL_AMD_NAVI_GPU;
+ dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
+ return 0;
+}
+
static struct dw_pci_controller dw_pci_controllers[] = {
[medfield] = {
.bus_num = -1,
@@ -389,6 +388,7 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x4bbe), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bbf), elkhartlake },
{ PCI_VDEVICE(INTEL, 0x4bc0), elkhartlake },
+ /* AMD NAVI */
{ PCI_VDEVICE(ATI, 0x7314), navi_amd },
{ PCI_VDEVICE(ATI, 0x73a4), navi_amd },
{ PCI_VDEVICE(ATI, 0x73e4), navi_amd },
--
2.35.1

2022-10-09 23:48:28

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 54/77] net: sfp: move Alcatel Lucent 3FE46541AA fixup

From: "Russell King (Oracle)" <[email protected]>

[ Upstream commit 275416754e9a262c97a1ad6f806a4bc6e0464aa2 ]

Add a new fixup mechanism to the SFP quirks, and use it for this
module.

Signed-off-by: Russell King (Oracle) <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/phy/sfp.c | 14 +++++++++-----
drivers/net/phy/sfp.h | 1 +
2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 2b06230be94f..952cd73e4777 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -311,6 +311,11 @@ static const struct of_device_id sfp_of_match[] = {
};
MODULE_DEVICE_TABLE(of, sfp_of_match);

+static void sfp_fixup_long_startup(struct sfp *sfp)
+{
+ sfp->module_t_start_up = T_START_UP_BAD_GPON;
+}
+
static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
unsigned long *modes)
{
@@ -341,6 +346,7 @@ static const struct sfp_quirk sfp_quirks[] = {
.vendor = "ALCATELLUCENT",
.part = "3FE46541AA",
.modes = sfp_quirk_2500basex,
+ .fixup = sfp_fixup_long_startup,
}, {
// Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
// NRZ in their EEPROM
@@ -2048,11 +2054,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
if (sfp->gpio[GPIO_LOS])
sfp->state_hw_mask |= SFP_F_LOS;

- if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) &&
- !memcmp(id.base.vendor_pn, "3FE46541AA ", 16))
- sfp->module_t_start_up = T_START_UP_BAD_GPON;
- else
- sfp->module_t_start_up = T_START_UP;
+ sfp->module_t_start_up = T_START_UP;

if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) &&
!memcmp(id.base.vendor_pn, "MA5671A ", 16))
@@ -2061,6 +2063,8 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
sfp->tx_fault_ignore = false;

sfp->quirk = sfp_lookup_quirk(&id);
+ if (sfp->quirk && sfp->quirk->fixup)
+ sfp->quirk->fixup(sfp);

return 0;
}
diff --git a/drivers/net/phy/sfp.h b/drivers/net/phy/sfp.h
index 03f1d47fe6ca..7ad06deae76c 100644
--- a/drivers/net/phy/sfp.h
+++ b/drivers/net/phy/sfp.h
@@ -10,6 +10,7 @@ struct sfp_quirk {
const char *vendor;
const char *part;
void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
+ void (*fixup)(struct sfp *sfp);
};

struct sfp_socket_ops {
--
2.35.1

2022-10-09 23:49:15

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 46/77] net: davicom: Fix return type of dm9000_start_xmit

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 0191580b000d50089a0b351f7cdbec4866e3d0d2 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of dm9000_start_xmit should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Reviewed-by: Nathan Chancellor <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/davicom/dm9000.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 0985ab216566..186a5e0a7862 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -1012,7 +1012,7 @@ static void dm9000_send_packet(struct net_device *dev,
* Hardware start transmission.
* Send a packet to media from the upper layer.
*/
-static int
+static netdev_tx_t
dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
--
2.35.1

2022-10-09 23:49:53

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 30/77] net: sunplus: Fix return type for implementation of ndo_start_xmit

From: GUO Zihua <[email protected]>

[ Upstream commit 7b620e156097028e4c9b6481a84ec1e1e72877ca ]

Since Linux now supports CFI, it will be a good idea to fix mismatched
return type for implementation of hooks. Otherwise this might get
cought out by CFI and cause a panic.

spl2sw_ethernet_start_xmit() would return either NETDEV_TX_BUSY or
NETDEV_TX_OK, so change the return type to netdev_tx_t directly.

Signed-off-by: GUO Zihua <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/sunplus/spl2sw_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sunplus/spl2sw_driver.c b/drivers/net/ethernet/sunplus/spl2sw_driver.c
index 546206640492..38e478aa415c 100644
--- a/drivers/net/ethernet/sunplus/spl2sw_driver.c
+++ b/drivers/net/ethernet/sunplus/spl2sw_driver.c
@@ -62,7 +62,8 @@ static int spl2sw_ethernet_stop(struct net_device *ndev)
return 0;
}

-static int spl2sw_ethernet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t spl2sw_ethernet_start_xmit(struct sk_buff *skb,
+ struct net_device *ndev)
{
struct spl2sw_mac *mac = netdev_priv(ndev);
struct spl2sw_common *comm = mac->comm;
--
2.35.1

2022-10-09 23:51:04

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 52/77] net: sfp: re-implement soft state polling setup

From: "Russell King (Oracle)" <[email protected]>

[ Upstream commit 8475c4b70b040f9d8cbc308100f2c4d865f810b3 ]

Re-implement the decision making for soft state polling. Instead of
generating the soft state mask in sfp_soft_start_poll() by looking at
which GPIOs are available, record their availability in
sfp_sm_mod_probe() in sfp->state_hw_mask.

This will then allow us to clear bits in sfp->state_hw_mask in module
specific quirks when the hardware signals should not be used, thereby
allowing us to switch to using the software state polling.

Signed-off-by: Russell King (Oracle) <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index 63f90fe9a4d2..a38705cf192f 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -234,6 +234,7 @@ struct sfp {
bool need_poll;

struct mutex st_mutex; /* Protects state */
+ unsigned int state_hw_mask;
unsigned int state_soft_mask;
unsigned int state;
struct delayed_work poll;
@@ -499,17 +500,18 @@ static void sfp_soft_set_state(struct sfp *sfp, unsigned int state)
static void sfp_soft_start_poll(struct sfp *sfp)
{
const struct sfp_eeprom_id *id = &sfp->id;
+ unsigned int mask = 0;

sfp->state_soft_mask = 0;
- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
- !sfp->gpio[GPIO_TX_DISABLE])
- sfp->state_soft_mask |= SFP_F_TX_DISABLE;
- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
- !sfp->gpio[GPIO_TX_FAULT])
- sfp->state_soft_mask |= SFP_F_TX_FAULT;
- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
- !sfp->gpio[GPIO_LOS])
- sfp->state_soft_mask |= SFP_F_LOS;
+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE)
+ mask |= SFP_F_TX_DISABLE;
+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT)
+ mask |= SFP_F_TX_FAULT;
+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS)
+ mask |= SFP_F_LOS;
+
+ // Poll the soft state for hardware pins we want to ignore
+ sfp->state_soft_mask = ~sfp->state_hw_mask & mask;

if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
!sfp->need_poll)
@@ -523,10 +525,11 @@ static void sfp_soft_stop_poll(struct sfp *sfp)

static unsigned int sfp_get_state(struct sfp *sfp)
{
- unsigned int state = sfp->get_state(sfp);
+ unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT);
+ unsigned int state;

- if (state & SFP_F_PRESENT &&
- sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
+ state = sfp->get_state(sfp) & sfp->state_hw_mask;
+ if (state & SFP_F_PRESENT && soft)
state |= sfp_soft_get_state(sfp);

return state;
@@ -1947,6 +1950,15 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
if (ret < 0)
return ret;

+ /* Initialise state bits to use from hardware */
+ sfp->state_hw_mask = SFP_F_PRESENT;
+ if (sfp->gpio[GPIO_TX_DISABLE])
+ sfp->state_hw_mask |= SFP_F_TX_DISABLE;
+ if (sfp->gpio[GPIO_TX_FAULT])
+ sfp->state_hw_mask |= SFP_F_TX_FAULT;
+ if (sfp->gpio[GPIO_LOS])
+ sfp->state_hw_mask |= SFP_F_LOS;
+
if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) &&
!memcmp(id.base.vendor_pn, "3FE46541AA ", 16))
sfp->module_t_start_up = T_START_UP_BAD_GPON;
@@ -2573,6 +2585,8 @@ static int sfp_probe(struct platform_device *pdev)
return PTR_ERR(sfp->gpio[i]);
}

+ sfp->state_hw_mask = SFP_F_PRESENT;
+
sfp->get_state = sfp_gpio_get_state;
sfp->set_state = sfp_gpio_set_state;

--
2.35.1

2022-10-09 23:51:11

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 70/77] bpf: use bpf_prog_pack for bpf_dispatcher

From: Song Liu <[email protected]>

[ Upstream commit 19c02415da2345d0dda2b5c4495bc17cc14b18b5 ]

Allocate bpf_dispatcher with bpf_prog_pack_alloc so that bpf_dispatcher
can share pages with bpf programs.

arch_prepare_bpf_dispatcher() is updated to provide a RW buffer as working
area for arch code to write to.

This also fixes CPA W^X warnning like:

CPA refuse W^X violation: 8000000000000163 -> 0000000000000163 range: ...

Signed-off-by: Song Liu <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Alexei Starovoitov <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
arch/x86/net/bpf_jit_comp.c | 16 ++++++++--------
include/linux/bpf.h | 3 ++-
include/linux/filter.h | 5 +++++
kernel/bpf/core.c | 9 +++++++--
kernel/bpf/dispatcher.c | 27 +++++++++++++++++++++------
5 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index c1f6c1c51d99..362562c832e6 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -2209,7 +2209,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
return ret;
}

-static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs, u8 *image, u8 *buf)
{
u8 *jg_reloc, *prog = *pprog;
int pivot, err, jg_bytes = 1;
@@ -2225,12 +2225,12 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
EMIT2_off32(0x81, add_1reg(0xF8, BPF_REG_3),
progs[a]);
err = emit_cond_near_jump(&prog, /* je func */
- (void *)progs[a], prog,
+ (void *)progs[a], image + (prog - buf),
X86_JE);
if (err)
return err;

- emit_indirect_jump(&prog, 2 /* rdx */, prog);
+ emit_indirect_jump(&prog, 2 /* rdx */, image + (prog - buf));

*pprog = prog;
return 0;
@@ -2255,7 +2255,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
jg_reloc = prog;

err = emit_bpf_dispatcher(&prog, a, a + pivot, /* emit lower_part */
- progs);
+ progs, image, buf);
if (err)
return err;

@@ -2269,7 +2269,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
emit_code(jg_reloc - jg_bytes, jg_offset, jg_bytes);

err = emit_bpf_dispatcher(&prog, a + pivot + 1, /* emit upper_part */
- b, progs);
+ b, progs, image, buf);
if (err)
return err;

@@ -2289,12 +2289,12 @@ static int cmp_ips(const void *a, const void *b)
return 0;
}

-int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
+int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs)
{
- u8 *prog = image;
+ u8 *prog = buf;

sort(funcs, num_funcs, sizeof(funcs[0]), cmp_ips, NULL);
- return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs);
+ return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs, image, buf);
}

struct x64_jit_data {
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 20c26aed7896..80fc8a88c610 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -891,6 +891,7 @@ struct bpf_dispatcher {
struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
int num_progs;
void *image;
+ void *rw_image;
u32 image_off;
struct bpf_ksym ksym;
};
@@ -909,7 +910,7 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampolin
struct bpf_trampoline *bpf_trampoline_get(u64 key,
struct bpf_attach_target_info *tgt_info);
void bpf_trampoline_put(struct bpf_trampoline *tr);
-int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
+int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
#define BPF_DISPATCHER_INIT(_name) { \
.mutex = __MUTEX_INITIALIZER(_name.mutex), \
.func = &_name##_func, \
diff --git a/include/linux/filter.h b/include/linux/filter.h
index a5f21dc3c432..f2c47df5ad2a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1018,6 +1018,8 @@ extern long bpf_jit_limit_max;

typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);

+void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
+
struct bpf_binary_header *
bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
unsigned int alignment,
@@ -1030,6 +1032,9 @@ void bpf_jit_free(struct bpf_prog *fp);
struct bpf_binary_header *
bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);

+void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
+void bpf_prog_pack_free(struct bpf_binary_header *hdr);
+
static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
{
return list_empty(&fp->aux->ksym.lnode) ||
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 3d9eb3ae334c..c4600a5781de 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -825,6 +825,11 @@ struct bpf_prog_pack {
unsigned long bitmap[];
};

+void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
+{
+ memset(area, 0, size);
+}
+
#define BPF_PROG_SIZE_TO_NBITS(size) (round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)

static DEFINE_MUTEX(pack_mutex);
@@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
return pack;
}

-static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
+void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
{
unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
struct bpf_prog_pack *pack;
@@ -905,7 +910,7 @@ static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insn
return ptr;
}

-static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
+void bpf_prog_pack_free(struct bpf_binary_header *hdr)
{
struct bpf_prog_pack *pack = NULL, *tmp;
unsigned int nbits;
diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
index 2444bd15cc2d..fa64b80b8bca 100644
--- a/kernel/bpf/dispatcher.c
+++ b/kernel/bpf/dispatcher.c
@@ -85,12 +85,12 @@ static bool bpf_dispatcher_remove_prog(struct bpf_dispatcher *d,
return false;
}

-int __weak arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
+int __weak arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs)
{
return -ENOTSUPP;
}

-static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
+static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *buf)
{
s64 ips[BPF_DISPATCHER_MAX] = {}, *ipsp = &ips[0];
int i;
@@ -99,12 +99,12 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
if (d->progs[i].prog)
*ipsp++ = (s64)(uintptr_t)d->progs[i].prog->bpf_func;
}
- return arch_prepare_bpf_dispatcher(image, &ips[0], d->num_progs);
+ return arch_prepare_bpf_dispatcher(image, buf, &ips[0], d->num_progs);
}

static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
{
- void *old, *new;
+ void *old, *new, *tmp;
u32 noff;
int err;

@@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
}

new = d->num_progs ? d->image + noff : NULL;
+ tmp = d->num_progs ? d->rw_image + noff : NULL;
if (new) {
- if (bpf_dispatcher_prepare(d, new))
+ /* Prepare the dispatcher in d->rw_image. Then use
+ * bpf_arch_text_copy to update d->image, which is RO+X.
+ */
+ if (bpf_dispatcher_prepare(d, new, tmp))
+ return;
+ if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
return;
}

@@ -140,9 +146,18 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,

mutex_lock(&d->mutex);
if (!d->image) {
- d->image = bpf_jit_alloc_exec_page();
+ d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero);
if (!d->image)
goto out;
+ d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
+ if (!d->rw_image) {
+ u32 size = PAGE_SIZE;
+
+ bpf_arch_text_copy(d->image, &size, sizeof(size));
+ bpf_prog_pack_free((struct bpf_binary_header *)d->image);
+ d->image = NULL;
+ goto out;
+ }
bpf_image_ksym_add(d->image, &d->ksym);
}

--
2.35.1

2022-10-09 23:51:17

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 32/77] netlink: Bounds-check struct nlmsgerr creation

From: Kees Cook <[email protected]>

[ Upstream commit 710d21fdff9a98d621cd4e64167f3ef8af4e2fd1 ]

In preparation for FORTIFY_SOURCE doing bounds-check on memcpy(),
switch from __nlmsg_put to nlmsg_put(), and explain the bounds check
for dealing with the memcpy() across a composite flexible array struct.
Avoids this future run-time warning:

memcpy: detected field-spanning write (size 32) of single field "&errmsg->msg" at net/netlink/af_netlink.c:2447 (size 16)

Cc: Jakub Kicinski <[email protected]>
Cc: Pablo Neira Ayuso <[email protected]>
Cc: Jozsef Kadlecsik <[email protected]>
Cc: Florian Westphal <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: Paolo Abeni <[email protected]>
Cc: syzbot <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Kees Cook <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/netfilter/ipset/ip_set_core.c | 8 +++++---
net/netlink/af_netlink.c | 8 +++++---
2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 16ae92054baa..6b31746f9be3 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1719,11 +1719,13 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
skb2 = nlmsg_new(payload, GFP_KERNEL);
if (!skb2)
return -ENOMEM;
- rep = __nlmsg_put(skb2, NETLINK_CB(skb).portid,
- nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
+ rep = nlmsg_put(skb2, NETLINK_CB(skb).portid,
+ nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
errmsg = nlmsg_data(rep);
errmsg->error = ret;
- memcpy(&errmsg->msg, nlh, nlh->nlmsg_len);
+ unsafe_memcpy(&errmsg->msg, nlh, nlh->nlmsg_len,
+ /* Bounds checked by the skb layer. */);
+
cmdattr = (void *)&errmsg->msg + min_len;

ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, cmdattr,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 0cd91f813a3b..d8d3ed2096a3 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2440,11 +2440,13 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
return;
}

- rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
- NLMSG_ERROR, payload, flags);
+ rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
+ NLMSG_ERROR, payload, flags);
errmsg = nlmsg_data(rep);
errmsg->error = err;
- memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
+ unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg)
+ ? nlh->nlmsg_len : sizeof(*nlh),
+ /* Bounds checked by the skb layer. */);

if (nlk_has_extack && extack) {
if (extack->_msg) {
--
2.35.1

2022-10-09 23:51:37

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 17/77] genetlink: hold read cb_lock during iteration of genl_fam_idr in genl_bind()

From: Jiri Pirko <[email protected]>

[ Upstream commit 8f1948bdcf2fb50e9092c0950c3c9ac591382101 ]

In genl_bind(), currently genl_lock and write cb_lock are taken
for iteration of genl_fam_idr and processing of static values
stored in struct genl_family. Take just read cb_lock for this task
as it is sufficient to guard the idr and the struct against
concurrent genl_register/unregister_family() calls.

This will allow to run genl command processing in genl_rcv() and
mnl_socket_setsockopt(.., NETLINK_ADD_MEMBERSHIP, ..) in parallel.

Reported-by: Vikas Gupta <[email protected]>
Signed-off-by: Jiri Pirko <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/netlink/genetlink.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 57010927e20a..76aed0571e3a 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1362,7 +1362,7 @@ static int genl_bind(struct net *net, int group)
unsigned int id;
int ret = 0;

- genl_lock_all();
+ down_read(&cb_lock);

idr_for_each_entry(&genl_fam_idr, family, id) {
const struct genl_multicast_group *grp;
@@ -1383,7 +1383,7 @@ static int genl_bind(struct net *net, int group)
break;
}

- genl_unlock_all();
+ up_read(&cb_lock);
return ret;
}

--
2.35.1

2022-10-10 00:01:29

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 75/77] net: sparx5: Fix return type of sparx5_port_xmit_impl

From: Nathan Huckleberry <[email protected]>

[ Upstream commit 73ea735073599430818e89b8901452287a15a718 ]

The ndo_start_xmit field in net_device_ops is expected to be of type
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev).

The mismatched return type breaks forward edge kCFI since the underlying
function definition does not match the function hook definition.

The return type of sparx5_port_xmit_impl should be changed from int to
netdev_tx_t.

Reported-by: Dan Carpenter <[email protected]>
Link: https://github.com/ClangBuiltLinux/linux/issues/1703
Cc: [email protected]
Signed-off-by: Nathan Huckleberry <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 2 +-
drivers/net/ethernet/microchip/sparx5/sparx5_packet.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index d071ac3b7106..705d8852078f 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -291,7 +291,7 @@ struct frame_info {
void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
-int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
int sparx5_manual_injection_mode(struct sparx5 *sparx5);
void sparx5_port_inj_timer_setup(struct sparx5_port *port);

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 21844beba72d..83c16ca5b30f 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -222,13 +222,13 @@ static int sparx5_inject(struct sparx5 *sparx5,
return NETDEV_TX_OK;
}

-int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
{
struct net_device_stats *stats = &dev->stats;
struct sparx5_port *port = netdev_priv(dev);
struct sparx5 *sparx5 = port->sparx5;
u32 ifh[IFH_LEN];
- int ret;
+ netdev_tx_t ret;

memset(ifh, 0, IFH_LEN * 4);
sparx5_set_port_ifh(ifh, port->portno);
--
2.35.1

2022-10-10 00:02:56

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 36/77] net: sparx5: fix function return type to match actual type

From: Casper Andersson <[email protected]>

[ Upstream commit 75554fe00f941c3c3d9344e88708093a14d2b4b8 ]

Function returns error integer, not bool.

Does not have any impact on functionality.

Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Casper Andersson <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c | 4 ++--
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
index a5837dbe0c7e..4af285918ea2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
@@ -186,8 +186,8 @@ bool sparx5_mact_getnext(struct sparx5 *sparx5,
return ret == 0;
}

-bool sparx5_mact_find(struct sparx5 *sparx5,
- const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2)
+int sparx5_mact_find(struct sparx5 *sparx5,
+ const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2)
{
int ret;
u32 cfg2;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index b197129044b5..d071ac3b7106 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -307,8 +307,8 @@ int sparx5_mact_learn(struct sparx5 *sparx5, int port,
const unsigned char mac[ETH_ALEN], u16 vid);
bool sparx5_mact_getnext(struct sparx5 *sparx5,
unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2);
-bool sparx5_mact_find(struct sparx5 *sparx5,
- const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2);
+int sparx5_mact_find(struct sparx5 *sparx5,
+ const unsigned char mac[ETH_ALEN], u16 vid, u32 *pcfg2);
int sparx5_mact_forget(struct sparx5 *sparx5,
const unsigned char mac[ETH_ALEN], u16 vid);
int sparx5_add_mact_entry(struct sparx5 *sparx5,
--
2.35.1

2022-10-10 00:04:06

by Sasha Levin

[permalink] [raw]
Subject: [PATCH AUTOSEL 6.0 37/77] net: mscc: ocelot: report FIFO drop counters through stats->rx_dropped

From: Vladimir Oltean <[email protected]>

[ Upstream commit cc160fc29a264726b2bfbc2f551081430db3df03 ]

if_link.h says:

* @rx_dropped: Number of packets received but not processed,
* e.g. due to lack of resources or unsupported protocol.
* For hardware interfaces this counter may include packets discarded
* due to L2 address filtering but should not include packets dropped
* by the device due to buffer exhaustion which are counted separately in
* @rx_missed_errors (since procfs folds those two counters together).

Currently we report "stats->rx_dropped = dev->stats.rx_dropped", the
latter being incremented by various entities in the stack. This is not
wrong, but we'd like to move ocelot_get_stats64() in the common ocelot
switch lib which is independent of struct net_device.

To do that, report the hardware RX drop counters instead. These drops
are due to policer action, or due to no destinations. When we have no
memory in the queue system, report this through rx_missed_errors, as
instructed.

Signed-off-by: Vladimir Oltean <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/net/ethernet/mscc/ocelot_net.c | 27 +++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 330d30841cdc..d7956fd051e6 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -745,7 +745,32 @@ static void ocelot_get_stats64(struct net_device *dev,
s[OCELOT_STAT_RX_1024_1526] +
s[OCELOT_STAT_RX_1527_MAX];
stats->multicast = s[OCELOT_STAT_RX_MULTICAST];
- stats->rx_dropped = dev->stats.rx_dropped;
+ stats->rx_missed_errors = s[OCELOT_STAT_DROP_TAIL];
+ stats->rx_dropped = s[OCELOT_STAT_RX_RED_PRIO_0] +
+ s[OCELOT_STAT_RX_RED_PRIO_1] +
+ s[OCELOT_STAT_RX_RED_PRIO_2] +
+ s[OCELOT_STAT_RX_RED_PRIO_3] +
+ s[OCELOT_STAT_RX_RED_PRIO_4] +
+ s[OCELOT_STAT_RX_RED_PRIO_5] +
+ s[OCELOT_STAT_RX_RED_PRIO_6] +
+ s[OCELOT_STAT_RX_RED_PRIO_7] +
+ s[OCELOT_STAT_DROP_LOCAL] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_0] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_1] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_2] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_3] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_4] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_5] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_6] +
+ s[OCELOT_STAT_DROP_YELLOW_PRIO_7] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_0] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_1] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_2] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_3] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_4] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_5] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_6] +
+ s[OCELOT_STAT_DROP_GREEN_PRIO_7];

/* Get Tx stats */
stats->tx_bytes = s[OCELOT_STAT_TX_OCTETS];
--
2.35.1

2022-10-10 07:44:52

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 52/77] net: sfp: re-implement soft state polling setup

On Sun, Oct 09, 2022 at 06:07:29PM -0400, Sasha Levin wrote:
> From: "Russell King (Oracle)" <[email protected]>
>
> [ Upstream commit 8475c4b70b040f9d8cbc308100f2c4d865f810b3 ]
>
> Re-implement the decision making for soft state polling. Instead of
> generating the soft state mask in sfp_soft_start_poll() by looking at
> which GPIOs are available, record their availability in
> sfp_sm_mod_probe() in sfp->state_hw_mask.
>
> This will then allow us to clear bits in sfp->state_hw_mask in module
> specific quirks when the hardware signals should not be used, thereby
> allowing us to switch to using the software state polling.

NAK.

There is absolutely no point in stable picking up this commit. On its
own, it doesn't do anything beneficial. It isn't a fix for anything.
It isn't stable material.

If you picked up the next two patches in the series, there would be a
point to it - introducing support for the HALNy GPON SFP module, but
as you didn't these three patches on their own are entirely pointless.

I don't see why "net: sfp: move Alcatel Lucent 3FE46541AA fixup" was
selected but not "net: sfp: move Huawei MA5671A fixup". I'm guessing
this is just another illustration why the "AI" you use to select
patches doesn't warrant "inteligence".

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

2022-10-10 08:27:48

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 54/77] net: sfp: move Alcatel Lucent 3FE46541AA fixup

On Sun, Oct 09, 2022 at 06:07:31PM -0400, Sasha Levin wrote:
> From: "Russell King (Oracle)" <[email protected]>
>
> [ Upstream commit 275416754e9a262c97a1ad6f806a4bc6e0464aa2 ]
>
> Add a new fixup mechanism to the SFP quirks, and use it for this
> module.

NAK.

There is absolutely no point in stable picking up this commit. On its
own, it doesn't do anything beneficial. It isn't a fix for anything.
It isn't stable material.

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

2022-10-10 08:41:23

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 53/77] net: sfp: move quirk handling into sfp.c

On Sun, Oct 09, 2022 at 06:07:30PM -0400, Sasha Levin wrote:
> From: "Russell King (Oracle)" <[email protected]>
>
> [ Upstream commit 23571c7b96437483d28a990c906cc81f5f66374e ]
>
> We need to handle more quirks than just those which affect the link
> modes of the module. Move the quirk lookup into sfp.c, and pass the
> quirk to sfp-bus.c

NAK.

There is absolutely no point in stable picking up this commit. On its
own, it doesn't do anything beneficial. It isn't a fix for anything.
It isn't stable material.

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

2022-10-10 12:18:33

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 18/77] net: dsa: mv88e6xxx: Allow external SMI if serial

On Sun, Oct 09, 2022 at 06:06:55PM -0400, Sasha Levin wrote:
> From: Marcus Carlberg <[email protected]>
>
> [ Upstream commit 8532c60efcc5b7b382006129b77aee2c19c43f15 ]
>
> p0_mode set to one of the supported serial mode should not prevent
> configuring the external SMI interface in
> mv88e6xxx_g2_scratch_gpio_set_smi. The current masking of the p0_mode
> only checks the first 2 bits. This results in switches supporting
> serial mode cannot setup external SMI on certain serial modes
> (Ex: 1000BASE-X and SGMII).
>
> Extend the mask of the p0_mode to include the reduced modes and
> serial modes as allowed modes for the external SMI interface.
>
> Signed-off-by: Marcus Carlberg <[email protected]>
> Link: https://lore.kernel.org/r/[email protected]
> Signed-off-by: Jakub Kicinski <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---

Not needed for stable kernels, please drop, thanks.

2022-10-10 12:20:00

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 37/77] net: mscc: ocelot: report FIFO drop counters through stats->rx_dropped

On Sun, Oct 09, 2022 at 06:07:14PM -0400, Sasha Levin wrote:
> From: Vladimir Oltean <[email protected]>
>
> [ Upstream commit cc160fc29a264726b2bfbc2f551081430db3df03 ]
>
> if_link.h says:
>
> * @rx_dropped: Number of packets received but not processed,
> * e.g. due to lack of resources or unsupported protocol.
> * For hardware interfaces this counter may include packets discarded
> * due to L2 address filtering but should not include packets dropped
> * by the device due to buffer exhaustion which are counted separately in
> * @rx_missed_errors (since procfs folds those two counters together).
>
> Currently we report "stats->rx_dropped = dev->stats.rx_dropped", the
> latter being incremented by various entities in the stack. This is not
> wrong, but we'd like to move ocelot_get_stats64() in the common ocelot
> switch lib which is independent of struct net_device.
>
> To do that, report the hardware RX drop counters instead. These drops
> are due to policer action, or due to no destinations. When we have no
> memory in the queue system, report this through rx_missed_errors, as
> instructed.
>
> Signed-off-by: Vladimir Oltean <[email protected]>
> Signed-off-by: David S. Miller <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---

Not needed for stable kernels, please drop, thanks.

2022-10-10 12:35:22

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 11/77] net: dsa: all DSA masters must be down when changing the tagging protocol

On Sun, Oct 09, 2022 at 06:06:48PM -0400, Sasha Levin wrote:
> From: Vladimir Oltean <[email protected]>
>
> [ Upstream commit f41ec1fd1c20e2a4e60a4ab8490b3e63423c0a8a ]
>
> The fact that the tagging protocol is set and queried from the
> /sys/class/net/<dsa-master>/dsa/tagging file is a bit of a quirk from
> the single CPU port days which isn't aging very well now that DSA can
> have more than a single CPU port. This is because the tagging protocol
> is a switch property, yet in the presence of multiple CPU ports it can
> be queried and set from multiple sysfs files, all of which are handled
> by the same implementation.
>
> The current logic ensures that the net device whose sysfs file we're
> changing the tagging protocol through must be down. That net device is
> the DSA master, and this is fine for single DSA master / CPU port setups.
>
> But exactly because the tagging protocol is per switch [ tree, in fact ]
> and not per DSA master, this isn't fine any longer with multiple CPU
> ports, and we must iterate through the tree and find all DSA masters,
> and make sure that all of them are down.
>
> Signed-off-by: Vladimir Oltean <[email protected]>
> Reviewed-by: Florian Fainelli <[email protected]>
> Signed-off-by: Paolo Abeni <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---

Not needed for stable kernels, please drop, thanks.

2022-10-10 12:36:32

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 55/77] net/sched: taprio: taprio_dump and taprio_change are protected by rtnl_mutex

On Sun, Oct 09, 2022 at 06:07:32PM -0400, Sasha Levin wrote:
> From: Vladimir Oltean <[email protected]>
>
> [ Upstream commit 18cdd2f0998a4967b1fff4c43ed9aef049e42c39 ]
>
> Since the writer-side lock is taken here, we do not need to open an RCU
> read-side critical section, instead we can use rtnl_dereference() to
> tell lockdep we are serialized with concurrent writes.
>
> Signed-off-by: Vladimir Oltean <[email protected]>
> Signed-off-by: Jakub Kicinski <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---

Not needed for stable kernels, please drop, thanks.

2022-10-10 12:50:09

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 12/77] net: mscc: ocelot: adjust forwarding domain for CPU ports in a LAG

On Sun, Oct 09, 2022 at 06:06:49PM -0400, Sasha Levin wrote:
> From: Vladimir Oltean <[email protected]>
>
> [ Upstream commit 291ac1517af58670740528466ccebe3caefb9093 ]
>
> Currently when we have 2 CPU ports configured for DSA tag_8021q mode and
> we put them in a LAG, a PGID dump looks like this:
>
> PGID_SRC[0] = ports 4,
> PGID_SRC[1] = ports 4,
> PGID_SRC[2] = ports 4,
> PGID_SRC[3] = ports 4,
> PGID_SRC[4] = ports 0, 1, 2, 3, 4, 5,
> PGID_SRC[5] = no ports
>
> (ports 0-3 are user ports, ports 4 and 5 are CPU ports)
>
> There are 2 problems with the configuration above:
>
> - user ports should enable forwarding towards both CPU ports, not just 4,
> and the aggregation PGIDs should prune one CPU port or the other from
> the destination port mask, based on a hash computed from packet headers.
>
> - CPU ports should not be allowed to forward towards themselves and also
> not towards other ports in the same LAG as themselves
>
> The first problem requires fixing up the PGID_SRC of user ports, when
> ocelot_port_assigned_dsa_8021q_cpu_mask() is called. We need to say that
> when a user port is assigned to a tag_8021q CPU port and that port is in
> a LAG, it should forward towards all ports in that LAG.
>
> The second problem requires fixing up the PGID_SRC of port 4, to remove
> ports 4 and 5 (in a LAG) from the allowed destinations.
>
> After this change, the PGID source masks look as follows:
>
> PGID_SRC[0] = ports 4, 5,
> PGID_SRC[1] = ports 4, 5,
> PGID_SRC[2] = ports 4, 5,
> PGID_SRC[3] = ports 4, 5,
> PGID_SRC[4] = ports 0, 1, 2, 3,
> PGID_SRC[5] = no ports
>
> Note that PGID_SRC[5] still looks weird (it should say "0, 1, 2, 3" just
> like PGID_SRC[4] does), but I've tested forwarding through this CPU port
> and it doesn't seem like anything is affected (it appears that PGID_SRC[4]
> is being looked up on forwarding from the CPU, since both ports 4 and 5
> have logical port ID 4). The reason why it looks weird is because
> we've never called ocelot_port_assign_dsa_8021q_cpu() for any user port
> towards port 5 (all user ports are assigned to port 4 which is in a LAG
> with 5).
>
> Since things aren't broken, I'm willing to leave it like that for now
> and just document the oddity.
>
> Signed-off-by: Vladimir Oltean <[email protected]>
> Signed-off-by: Paolo Abeni <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---

Not needed for stable kernels, please drop, thanks.

2022-10-10 15:51:53

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 17/77] genetlink: hold read cb_lock during iteration of genl_fam_idr in genl_bind()

On Sun, 9 Oct 2022 18:06:54 -0400 Sasha Levin wrote:
> In genl_bind(), currently genl_lock and write cb_lock are taken
> for iteration of genl_fam_idr and processing of static values
> stored in struct genl_family. Take just read cb_lock for this task
> as it is sufficient to guard the idr and the struct against
> concurrent genl_register/unregister_family() calls.
>
> This will allow to run genl command processing in genl_rcv() and
> mnl_socket_setsockopt(.., NETLINK_ADD_MEMBERSHIP, ..) in parallel.

Not stable material, please drop.

2022-10-13 18:15:55

by Sasha Levin

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 54/77] net: sfp: move Alcatel Lucent 3FE46541AA fixup

On Mon, Oct 10, 2022 at 08:16:43AM +0100, Russell King (Oracle) wrote:
>On Sun, Oct 09, 2022 at 06:07:31PM -0400, Sasha Levin wrote:
>> From: "Russell King (Oracle)" <[email protected]>
>>
>> [ Upstream commit 275416754e9a262c97a1ad6f806a4bc6e0464aa2 ]
>>
>> Add a new fixup mechanism to the SFP quirks, and use it for this
>> module.
>
>NAK.
>
>There is absolutely no point in stable picking up this commit. On its
>own, it doesn't do anything beneficial. It isn't a fix for anything.
>It isn't stable material.

I'll drop it, thanks.

--
Thanks,
Sasha

2022-10-13 18:43:23

by Sasha Levin

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 52/77] net: sfp: re-implement soft state polling setup

On Mon, Oct 10, 2022 at 08:21:09AM +0100, Russell King (Oracle) wrote:
>On Sun, Oct 09, 2022 at 06:07:29PM -0400, Sasha Levin wrote:
>> From: "Russell King (Oracle)" <[email protected]>
>>
>> [ Upstream commit 8475c4b70b040f9d8cbc308100f2c4d865f810b3 ]
>>
>> Re-implement the decision making for soft state polling. Instead of
>> generating the soft state mask in sfp_soft_start_poll() by looking at
>> which GPIOs are available, record their availability in
>> sfp_sm_mod_probe() in sfp->state_hw_mask.
>>
>> This will then allow us to clear bits in sfp->state_hw_mask in module
>> specific quirks when the hardware signals should not be used, thereby
>> allowing us to switch to using the software state polling.
>
>NAK.
>
>There is absolutely no point in stable picking up this commit. On its
>own, it doesn't do anything beneficial. It isn't a fix for anything.
>It isn't stable material.
>
>If you picked up the next two patches in the series, there would be a
>point to it - introducing support for the HALNy GPON SFP module, but
>as you didn't these three patches on their own are entirely pointless.

So why not tag those patches for stable to make it explicit?

--
Thanks,
Sasha

2022-10-13 18:48:38

by Sasha Levin

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 17/77] genetlink: hold read cb_lock during iteration of genl_fam_idr in genl_bind()

On Mon, Oct 10, 2022 at 08:49:46AM -0700, Jakub Kicinski wrote:
>On Sun, 9 Oct 2022 18:06:54 -0400 Sasha Levin wrote:
>> In genl_bind(), currently genl_lock and write cb_lock are taken
>> for iteration of genl_fam_idr and processing of static values
>> stored in struct genl_family. Take just read cb_lock for this task
>> as it is sufficient to guard the idr and the struct against
>> concurrent genl_register/unregister_family() calls.
>>
>> This will allow to run genl command processing in genl_rcv() and
>> mnl_socket_setsockopt(.., NETLINK_ADD_MEMBERSHIP, ..) in parallel.
>
>Not stable material, please drop.

Will do, thanks!

--
Thanks,
Sasha

2022-10-13 19:22:05

by Sasha Levin

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 11/77] net: dsa: all DSA masters must be down when changing the tagging protocol

On Mon, Oct 10, 2022 at 02:54:30PM +0300, Vladimir Oltean wrote:
>On Sun, Oct 09, 2022 at 06:06:48PM -0400, Sasha Levin wrote:
>> From: Vladimir Oltean <[email protected]>
>>
>> [ Upstream commit f41ec1fd1c20e2a4e60a4ab8490b3e63423c0a8a ]
>>
>> The fact that the tagging protocol is set and queried from the
>> /sys/class/net/<dsa-master>/dsa/tagging file is a bit of a quirk from
>> the single CPU port days which isn't aging very well now that DSA can
>> have more than a single CPU port. This is because the tagging protocol
>> is a switch property, yet in the presence of multiple CPU ports it can
>> be queried and set from multiple sysfs files, all of which are handled
>> by the same implementation.
>>
>> The current logic ensures that the net device whose sysfs file we're
>> changing the tagging protocol through must be down. That net device is
>> the DSA master, and this is fine for single DSA master / CPU port setups.
>>
>> But exactly because the tagging protocol is per switch [ tree, in fact ]
>> and not per DSA master, this isn't fine any longer with multiple CPU
>> ports, and we must iterate through the tree and find all DSA masters,
>> and make sure that all of them are down.
>>
>> Signed-off-by: Vladimir Oltean <[email protected]>
>> Reviewed-by: Florian Fainelli <[email protected]>
>> Signed-off-by: Paolo Abeni <[email protected]>
>> Signed-off-by: Sasha Levin <[email protected]>
>> ---
>
>Not needed for stable kernels, please drop, thanks.

Ack, I'll drop this and the rest of the patches you've pointed out,
thanks!

--
Thanks,
Sasha

2022-10-13 22:36:00

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH AUTOSEL 6.0 52/77] net: sfp: re-implement soft state polling setup

On Thu, Oct 13, 2022 at 02:01:46PM -0400, Sasha Levin wrote:
> On Mon, Oct 10, 2022 at 08:21:09AM +0100, Russell King (Oracle) wrote:
> > On Sun, Oct 09, 2022 at 06:07:29PM -0400, Sasha Levin wrote:
> > > From: "Russell King (Oracle)" <[email protected]>
> > >
> > > [ Upstream commit 8475c4b70b040f9d8cbc308100f2c4d865f810b3 ]
> > >
> > > Re-implement the decision making for soft state polling. Instead of
> > > generating the soft state mask in sfp_soft_start_poll() by looking at
> > > which GPIOs are available, record their availability in
> > > sfp_sm_mod_probe() in sfp->state_hw_mask.
> > >
> > > This will then allow us to clear bits in sfp->state_hw_mask in module
> > > specific quirks when the hardware signals should not be used, thereby
> > > allowing us to switch to using the software state polling.
> >
> > NAK.
> >
> > There is absolutely no point in stable picking up this commit. On its
> > own, it doesn't do anything beneficial. It isn't a fix for anything.
> > It isn't stable material.
> >
> > If you picked up the next two patches in the series, there would be a
> > point to it - introducing support for the HALNy GPON SFP module, but
> > as you didn't these three patches on their own are entirely pointless.
>
> So why not tag those patches for stable to make it explicit?

Oh, is stable accepting development changes then?

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!