--- /dev/null
+From ee46cf76c0bf2199c37e946c6dbd18eed16bdf25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 12:33:25 -0500
+Subject: ACPI: CPPC: Don't require flexible address space if X86_FEATURE_CPPC
+ is supported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 09073396ea62d0a10b03f5661dcabfd8eca3f098 ]
+
+Commit 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space")
+changed _CPC probing to require flexible address space to be negotiated
+for CPPC to work.
+
+However it was observed that this caused a regression for Arek's ROG
+Zephyrus G15 GA503QM which previously CPPC worked, but now it stopped
+working.
+
+To avoid causing a regression waive this failure when the CPU is known
+to support CPPC.
+
+Cc: Pierre Gondois <pierre.gondois@arm.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216248
+Fixes: 0651ab90e4ad ("ACPI: CPPC: Check _OSC for flexible address space")
+Reported-and-tested-by: Arek Ruśniak <arek.rusi@gmail.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 57ca7aa0e169..b8e26b6b5523 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -764,7 +764,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+
+ if (!osc_cpc_flexible_adr_space_confirmed) {
+ pr_debug("Flexible address space capability not supported\n");
+- goto out_free;
++ if (!cpc_supported_by_cpu())
++ goto out_free;
+ }
+
+ addr = ioremap(gas_t->address, gas_t->bit_width/8);
+@@ -791,7 +792,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+ }
+ if (!osc_cpc_flexible_adr_space_confirmed) {
+ pr_debug("Flexible address space capability not supported\n");
+- goto out_free;
++ if (!cpc_supported_by_cpu())
++ goto out_free;
+ }
+ } else {
+ if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) {
+--
+2.35.1
+
--- /dev/null
+From 1aad232e5300cafc32cef302b73710003be8a07b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:06 +0000
+Subject: amt: add missing regeneration nonce logic in request logic
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 627f16931bf3cb20d50274d9341380ac2c3035fd ]
+
+When AMT gateway starts sending a new request message, it should
+regenerate the nonce variable.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index ff859d4a4b50..2fe56640e493 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -963,9 +963,13 @@ static void amt_event_send_request(struct amt_dev *amt)
+ amt->remote_ip = 0;
+ amt_update_gw_status(amt, AMT_STATUS_INIT, false);
+ amt->req_cnt = 0;
++ amt->nonce = 0;
+ goto out;
+ }
+
++ if (!amt->req_cnt)
++ get_random_bytes(&amt->nonce, sizeof(__be32));
++
+ amt_send_request(amt, false);
+ amt_send_request(amt, true);
+ amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true);
+--
+2.35.1
+
--- /dev/null
+From 23bbd6d80d0c52a2f54a94689c6e1ba36b46531f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:10 +0000
+Subject: amt: do not use amt->nr_tunnels outside of lock
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 989918482bbccbbce3ba2bb9156eb4c193319983 ]
+
+amt->nr_tunnels is protected by amt->lock.
+But, amt_request_handler() has been using this variable without the
+amt->lock.
+So, it expands context of amt->lock in the amt_request_handler() to
+protect amt->nr_tunnels variable.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 4277924ab3b9..acf5ea96652f 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -2679,7 +2679,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+ if (tunnel->ip4 == iph->saddr)
+ goto send;
+
++ spin_lock_bh(&amt->lock);
+ if (amt->nr_tunnels >= amt->max_tunnels) {
++ spin_unlock_bh(&amt->lock);
+ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
+ return true;
+ }
+@@ -2687,8 +2689,10 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+ tunnel = kzalloc(sizeof(*tunnel) +
+ (sizeof(struct hlist_head) * amt->hash_buckets),
+ GFP_ATOMIC);
+- if (!tunnel)
++ if (!tunnel) {
++ spin_unlock_bh(&amt->lock);
+ return true;
++ }
+
+ tunnel->source_port = udph->source;
+ tunnel->ip4 = iph->saddr;
+@@ -2701,10 +2705,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+
+ INIT_DELAYED_WORK(&tunnel->gc_wq, amt_tunnel_expire);
+
+- spin_lock_bh(&amt->lock);
+ list_add_tail_rcu(&tunnel->list, &amt->tunnel_list);
+ tunnel->key = amt->key;
+- amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true);
++ __amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true);
+ amt->nr_tunnels++;
+ mod_delayed_work(amt_wq, &tunnel->gc_wq,
+ msecs_to_jiffies(amt_gmi(amt)));
+--
+2.35.1
+
--- /dev/null
+From fe24430c2ccdb830e200af9cda2a7f0fb7b5b3a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:07 +0000
+Subject: amt: drop unexpected advertisement message
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 40185f359fbabaa61da754cc29d12f3a41e0a987 ]
+
+AMT gateway interface should not receive unexpected advertisement messages.
+In order to drop these packets, it should check nonce and amt->status.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 2fe56640e493..0811a5211ec4 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -2260,6 +2260,10 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
+ ipv4_is_zeronet(amta->ip4))
+ return true;
+
++ if (amt->status != AMT_STATUS_SENT_DISCOVERY ||
++ amt->nonce != amta->nonce)
++ return true;
++
+ amt->remote_ip = amta->ip4;
+ netdev_dbg(amt->dev, "advertised remote ip = %pI4\n", &amt->remote_ip);
+ mod_delayed_work(amt_wq, &amt->req_wq, 0);
+@@ -2975,6 +2979,7 @@ static int amt_dev_open(struct net_device *dev)
+
+ amt->req_cnt = 0;
+ amt->remote_ip = 0;
++ amt->nonce = 0;
+ get_random_bytes(&amt->key, sizeof(siphash_key_t));
+
+ amt->status = AMT_STATUS_INIT;
+--
+2.35.1
+
--- /dev/null
+From 3fb14c649b53247bd990d4026a8947ad32946954 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:09 +0000
+Subject: amt: drop unexpected multicast data
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit e882827d5b8942a27b4d28548aa27562a3a7e94c ]
+
+AMT gateway interface should not receive unexpected multicast data.
+Multicast data message type should be received after sending an update
+message, which means all establishment between gateway and relay is
+finished.
+So, amt_multicast_data_handler() checks amt->status.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 5c65908abd5a..4277924ab3b9 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -2282,6 +2282,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
+ struct ethhdr *eth;
+ struct iphdr *iph;
+
++ if (READ_ONCE(amt->status) != AMT_STATUS_SENT_UPDATE)
++ return true;
++
+ hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
+ if (!pskb_may_pull(skb, hdr_size))
+ return true;
+--
+2.35.1
+
--- /dev/null
+From cb68360e82547bdfaeb48bba930a96a13729a7cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:08 +0000
+Subject: amt: drop unexpected query message
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 239d886601e38d948a28f3b2a1c9ce5f01bf75f2 ]
+
+AMT gateway interface should not receive unexpected query messages.
+In order to drop unexpected query messages, it checks nonce.
+And it also checks ready4 and ready6 variables to drop duplicated messages.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 0811a5211ec4..5c65908abd5a 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -967,8 +967,11 @@ static void amt_event_send_request(struct amt_dev *amt)
+ goto out;
+ }
+
+- if (!amt->req_cnt)
++ if (!amt->req_cnt) {
++ WRITE_ONCE(amt->ready4, false);
++ WRITE_ONCE(amt->ready6, false);
+ get_random_bytes(&amt->nonce, sizeof(__be32));
++ }
+
+ amt_send_request(amt, false);
+ amt_send_request(amt, true);
+@@ -2353,6 +2356,9 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ if (amtmq->reserved || amtmq->version)
+ return true;
+
++ if (amtmq->nonce != amt->nonce)
++ return true;
++
+ hdr_size -= sizeof(*eth);
+ if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false))
+ return true;
+@@ -2367,6 +2373,9 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+
+ iph = ip_hdr(skb);
+ if (iph->version == 4) {
++ if (READ_ONCE(amt->ready4))
++ return true;
++
+ if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS +
+ sizeof(*ihv3)))
+ return true;
+@@ -2389,6 +2398,9 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ struct mld2_query *mld2q;
+ struct ipv6hdr *ip6h;
+
++ if (READ_ONCE(amt->ready6))
++ return true;
++
+ if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS +
+ sizeof(*mld2q)))
+ return true;
+--
+2.35.1
+
--- /dev/null
+From a4d1e4764eef136c55857e0b90cd80f732ca45fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:04 +0000
+Subject: amt: remove unnecessary locks
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 9c343ea6185febe5f6b74f7f7b3757f3dd9c5af6 ]
+
+By the previous patch, amt gateway handlers are changed to worked by
+a single thread.
+So, most locks for gateway are not needed.
+So, it removes.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 32 +++++---------------------------
+ 1 file changed, 5 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index f8e8381e266b..615f26a553ae 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -577,8 +577,8 @@ static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt)
+ return skb;
+ }
+
+-static void __amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
+- bool validate)
++static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
++ bool validate)
+ {
+ if (validate && amt->status >= status)
+ return;
+@@ -600,14 +600,6 @@ static void __amt_update_relay_status(struct amt_tunnel_list *tunnel,
+ tunnel->status = status;
+ }
+
+-static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
+- bool validate)
+-{
+- spin_lock_bh(&amt->lock);
+- __amt_update_gw_status(amt, status, validate);
+- spin_unlock_bh(&amt->lock);
+-}
+-
+ static void amt_update_relay_status(struct amt_tunnel_list *tunnel,
+ enum amt_status status, bool validate)
+ {
+@@ -700,9 +692,7 @@ static void amt_send_discovery(struct amt_dev *amt)
+ if (unlikely(net_xmit_eval(err)))
+ amt->dev->stats.tx_errors++;
+
+- spin_lock_bh(&amt->lock);
+- __amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true);
+- spin_unlock_bh(&amt->lock);
++ amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true);
+ out:
+ rcu_read_unlock();
+ }
+@@ -937,18 +927,14 @@ static void amt_secret_work(struct work_struct *work)
+
+ static void amt_event_send_discovery(struct amt_dev *amt)
+ {
+- spin_lock_bh(&amt->lock);
+ if (amt->status > AMT_STATUS_SENT_DISCOVERY)
+ goto out;
+ get_random_bytes(&amt->nonce, sizeof(__be32));
+- spin_unlock_bh(&amt->lock);
+
+ amt_send_discovery(amt);
+- spin_lock_bh(&amt->lock);
+ out:
+ mod_delayed_work(amt_wq, &amt->discovery_wq,
+ msecs_to_jiffies(AMT_DISCOVERY_TIMEOUT));
+- spin_unlock_bh(&amt->lock);
+ }
+
+ static void amt_discovery_work(struct work_struct *work)
+@@ -966,7 +952,6 @@ static void amt_event_send_request(struct amt_dev *amt)
+ {
+ u32 exp;
+
+- spin_lock_bh(&amt->lock);
+ if (amt->status < AMT_STATUS_RECEIVED_ADVERTISEMENT)
+ goto out;
+
+@@ -976,21 +961,18 @@ static void amt_event_send_request(struct amt_dev *amt)
+ amt->ready4 = false;
+ amt->ready6 = false;
+ amt->remote_ip = 0;
+- __amt_update_gw_status(amt, AMT_STATUS_INIT, false);
++ amt_update_gw_status(amt, AMT_STATUS_INIT, false);
+ amt->req_cnt = 0;
+ goto out;
+ }
+- spin_unlock_bh(&amt->lock);
+
+ amt_send_request(amt, false);
+ amt_send_request(amt, true);
+- spin_lock_bh(&amt->lock);
+- __amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true);
++ amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true);
+ amt->req_cnt++;
+ out:
+ exp = min_t(u32, (1 * (1 << amt->req_cnt)), AMT_MAX_REQ_TIMEOUT);
+ mod_delayed_work(amt_wq, &amt->req_wq, msecs_to_jiffies(exp * 1000));
+- spin_unlock_bh(&amt->lock);
+ }
+
+ static void amt_req_work(struct work_struct *work)
+@@ -2386,12 +2368,10 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
+- spin_lock_bh(&amt->lock);
+ amt->ready4 = true;
+ amt->mac = amtmq->response_mac;
+ amt->req_cnt = 0;
+ amt->qi = ihv3->qqic;
+- spin_unlock_bh(&amt->lock);
+ skb->protocol = htons(ETH_P_IP);
+ eth->h_proto = htons(ETH_P_IP);
+ ip_eth_mc_map(iph->daddr, eth->h_dest);
+@@ -2411,12 +2391,10 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
+- spin_lock_bh(&amt->lock);
+ amt->ready6 = true;
+ amt->mac = amtmq->response_mac;
+ amt->req_cnt = 0;
+ amt->qi = mld2q->mld2q_qqic;
+- spin_unlock_bh(&amt->lock);
+ skb->protocol = htons(ETH_P_IPV6);
+ eth->h_proto = htons(ETH_P_IPV6);
+ ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
+--
+2.35.1
+
--- /dev/null
+From a9f51247a9d8b971feba0f3b2418a9543b39a5d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:05 +0000
+Subject: amt: use READ_ONCE() in amt module
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 928f353cb8672f0d6078aad75eeec0ed33875b12 ]
+
+There are some data races in the amt module.
+amt->ready4, amt->ready6, and amt->status can be accessed concurrently
+without locks.
+So, it uses READ_ONCE() and WRITE_ONCE().
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 615f26a553ae..ff859d4a4b50 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -584,7 +584,7 @@ static void amt_update_gw_status(struct amt_dev *amt, enum amt_status status,
+ return;
+ netdev_dbg(amt->dev, "Update GW status %s -> %s",
+ status_str[amt->status], status_str[status]);
+- amt->status = status;
++ WRITE_ONCE(amt->status, status);
+ }
+
+ static void __amt_update_relay_status(struct amt_tunnel_list *tunnel,
+@@ -958,8 +958,8 @@ static void amt_event_send_request(struct amt_dev *amt)
+ if (amt->req_cnt > AMT_MAX_REQ_COUNT) {
+ netdev_dbg(amt->dev, "Gateway is not ready");
+ amt->qi = AMT_INIT_REQ_TIMEOUT;
+- amt->ready4 = false;
+- amt->ready6 = false;
++ WRITE_ONCE(amt->ready4, false);
++ WRITE_ONCE(amt->ready6, false);
+ amt->remote_ip = 0;
+ amt_update_gw_status(amt, AMT_STATUS_INIT, false);
+ amt->req_cnt = 0;
+@@ -1239,7 +1239,8 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+ /* Gateway only passes IGMP/MLD packets */
+ if (!report)
+ goto free;
+- if ((!v6 && !amt->ready4) || (v6 && !amt->ready6))
++ if ((!v6 && !READ_ONCE(amt->ready4)) ||
++ (v6 && !READ_ONCE(amt->ready6)))
+ goto free;
+ if (amt_send_membership_update(amt, skb, v6))
+ goto free;
+@@ -2368,7 +2369,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
+- amt->ready4 = true;
++ WRITE_ONCE(amt->ready4, true);
+ amt->mac = amtmq->response_mac;
+ amt->req_cnt = 0;
+ amt->qi = ihv3->qqic;
+@@ -2391,7 +2392,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
+ skb_reset_transport_header(skb);
+ skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
+- amt->ready6 = true;
++ WRITE_ONCE(amt->ready6, true);
+ amt->mac = amtmq->response_mac;
+ amt->req_cnt = 0;
+ amt->qi = mld2q->mld2q_qqic;
+@@ -2898,7 +2899,7 @@ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
+ break;
+ case AMT_MSG_REQUEST:
+ case AMT_MSG_MEMBERSHIP_UPDATE:
+- if (amt->status >= AMT_STATUS_RECEIVED_ADVERTISEMENT)
++ if (READ_ONCE(amt->status) >= AMT_STATUS_RECEIVED_ADVERTISEMENT)
+ mod_delayed_work(amt_wq, &amt->req_wq, 0);
+ break;
+ default:
+--
+2.35.1
+
--- /dev/null
+From 84b52bc654c938bac4f3abfd7e884de79c2c0559 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:09:03 +0000
+Subject: amt: use workqueue for gateway side message handling
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 30e22a6ebca039572ce9bc10f1934f4eabfb5b7f ]
+
+There are some synchronization issues(amt->status, amt->req_cnt, etc)
+if the interface is in gateway mode because gateway message handlers
+are processed concurrently.
+This applies a work queue for processing these messages instead of
+expanding the locking context.
+
+So, the purposes of this patch are to fix exist race conditions and to make
+gateway to be able to validate a gateway status more correctly.
+
+When the AMT gateway interface is created, it tries to establish to relay.
+The establishment step looks stateless, but it should be managed well.
+In order to handle messages in the gateway, it saves the current
+status(i.e. AMT_STATUS_XXX).
+This patch makes gateway code to be worked with a single thread.
+
+Now, all messages except the multicast are triggered(received or
+delay expired), and these messages will be stored in the event
+queue(amt->events).
+Then, the single worker processes stored messages asynchronously one
+by one.
+The multicast data message type will be still processed immediately.
+
+Now, amt->lock is only needed to access the event queue(amt->events)
+if an interface is the gateway mode.
+
+Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 159 +++++++++++++++++++++++++++++++++++++++++-----
+ include/net/amt.h | 20 ++++++
+ 2 files changed, 164 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 6c64953db487..f8e8381e266b 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -900,6 +900,28 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
+ }
+ #endif
+
++static bool amt_queue_event(struct amt_dev *amt, enum amt_event event,
++ struct sk_buff *skb)
++{
++ int index;
++
++ spin_lock_bh(&amt->lock);
++ if (amt->nr_events >= AMT_MAX_EVENTS) {
++ spin_unlock_bh(&amt->lock);
++ return 1;
++ }
++
++ index = (amt->event_idx + amt->nr_events) % AMT_MAX_EVENTS;
++ amt->events[index].event = event;
++ amt->events[index].skb = skb;
++ amt->nr_events++;
++ amt->event_idx %= AMT_MAX_EVENTS;
++ queue_work(amt_wq, &amt->event_wq);
++ spin_unlock_bh(&amt->lock);
++
++ return 0;
++}
++
+ static void amt_secret_work(struct work_struct *work)
+ {
+ struct amt_dev *amt = container_of(to_delayed_work(work),
+@@ -913,12 +935,8 @@ static void amt_secret_work(struct work_struct *work)
+ msecs_to_jiffies(AMT_SECRET_TIMEOUT));
+ }
+
+-static void amt_discovery_work(struct work_struct *work)
++static void amt_event_send_discovery(struct amt_dev *amt)
+ {
+- struct amt_dev *amt = container_of(to_delayed_work(work),
+- struct amt_dev,
+- discovery_wq);
+-
+ spin_lock_bh(&amt->lock);
+ if (amt->status > AMT_STATUS_SENT_DISCOVERY)
+ goto out;
+@@ -933,11 +951,19 @@ static void amt_discovery_work(struct work_struct *work)
+ spin_unlock_bh(&amt->lock);
+ }
+
+-static void amt_req_work(struct work_struct *work)
++static void amt_discovery_work(struct work_struct *work)
+ {
+ struct amt_dev *amt = container_of(to_delayed_work(work),
+ struct amt_dev,
+- req_wq);
++ discovery_wq);
++
++ if (amt_queue_event(amt, AMT_EVENT_SEND_DISCOVERY, NULL))
++ mod_delayed_work(amt_wq, &amt->discovery_wq,
++ msecs_to_jiffies(AMT_DISCOVERY_TIMEOUT));
++}
++
++static void amt_event_send_request(struct amt_dev *amt)
++{
+ u32 exp;
+
+ spin_lock_bh(&amt->lock);
+@@ -967,6 +993,17 @@ static void amt_req_work(struct work_struct *work)
+ spin_unlock_bh(&amt->lock);
+ }
+
++static void amt_req_work(struct work_struct *work)
++{
++ struct amt_dev *amt = container_of(to_delayed_work(work),
++ struct amt_dev,
++ req_wq);
++
++ if (amt_queue_event(amt, AMT_EVENT_SEND_REQUEST, NULL))
++ mod_delayed_work(amt_wq, &amt->req_wq,
++ msecs_to_jiffies(100));
++}
++
+ static bool amt_send_membership_update(struct amt_dev *amt,
+ struct sk_buff *skb,
+ bool v6)
+@@ -2392,12 +2429,14 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
+ skb->pkt_type = PACKET_MULTICAST;
+ skb->ip_summed = CHECKSUM_NONE;
+ len = skb->len;
++ local_bh_disable();
+ if (__netif_rx(skb) == NET_RX_SUCCESS) {
+ amt_update_gw_status(amt, AMT_STATUS_RECEIVED_QUERY, true);
+ dev_sw_netstats_rx_add(amt->dev, len);
+ } else {
+ amt->dev->stats.rx_dropped++;
+ }
++ local_bh_enable();
+
+ return false;
+ }
+@@ -2688,6 +2727,38 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
+ return false;
+ }
+
++static void amt_gw_rcv(struct amt_dev *amt, struct sk_buff *skb)
++{
++ int type = amt_parse_type(skb);
++ int err = 1;
++
++ if (type == -1)
++ goto drop;
++
++ if (amt->mode == AMT_MODE_GATEWAY) {
++ switch (type) {
++ case AMT_MSG_ADVERTISEMENT:
++ err = amt_advertisement_handler(amt, skb);
++ break;
++ case AMT_MSG_MEMBERSHIP_QUERY:
++ err = amt_membership_query_handler(amt, skb);
++ if (!err)
++ return;
++ break;
++ default:
++ netdev_dbg(amt->dev, "Invalid type of Gateway\n");
++ break;
++ }
++ }
++drop:
++ if (err) {
++ amt->dev->stats.rx_dropped++;
++ kfree_skb(skb);
++ } else {
++ consume_skb(skb);
++ }
++}
++
+ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ {
+ struct amt_dev *amt;
+@@ -2719,8 +2790,12 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ err = true;
+ goto drop;
+ }
+- err = amt_advertisement_handler(amt, skb);
+- break;
++ if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) {
++ netdev_dbg(amt->dev, "AMT Event queue full\n");
++ err = true;
++ goto drop;
++ }
++ goto out;
+ case AMT_MSG_MULTICAST_DATA:
+ if (iph->saddr != amt->remote_ip) {
+ netdev_dbg(amt->dev, "Invalid Relay IP\n");
+@@ -2738,11 +2813,12 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ err = true;
+ goto drop;
+ }
+- err = amt_membership_query_handler(amt, skb);
+- if (err)
++ if (amt_queue_event(amt, AMT_EVENT_RECEIVE, skb)) {
++ netdev_dbg(amt->dev, "AMT Event queue full\n");
++ err = true;
+ goto drop;
+- else
+- goto out;
++ }
++ goto out;
+ default:
+ err = true;
+ netdev_dbg(amt->dev, "Invalid type of Gateway\n");
+@@ -2780,6 +2856,46 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
+ return 0;
+ }
+
++static void amt_event_work(struct work_struct *work)
++{
++ struct amt_dev *amt = container_of(work, struct amt_dev, event_wq);
++ struct sk_buff *skb;
++ u8 event;
++ int i;
++
++ for (i = 0; i < AMT_MAX_EVENTS; i++) {
++ spin_lock_bh(&amt->lock);
++ if (amt->nr_events == 0) {
++ spin_unlock_bh(&amt->lock);
++ return;
++ }
++ event = amt->events[amt->event_idx].event;
++ skb = amt->events[amt->event_idx].skb;
++ amt->events[amt->event_idx].event = AMT_EVENT_NONE;
++ amt->events[amt->event_idx].skb = NULL;
++ amt->nr_events--;
++ amt->event_idx++;
++ amt->event_idx %= AMT_MAX_EVENTS;
++ spin_unlock_bh(&amt->lock);
++
++ switch (event) {
++ case AMT_EVENT_RECEIVE:
++ amt_gw_rcv(amt, skb);
++ break;
++ case AMT_EVENT_SEND_DISCOVERY:
++ amt_event_send_discovery(amt);
++ break;
++ case AMT_EVENT_SEND_REQUEST:
++ amt_event_send_request(amt);
++ break;
++ default:
++ if (skb)
++ kfree_skb(skb);
++ break;
++ }
++ }
++}
++
+ static int amt_err_lookup(struct sock *sk, struct sk_buff *skb)
+ {
+ struct amt_dev *amt;
+@@ -2867,6 +2983,8 @@ static int amt_dev_open(struct net_device *dev)
+
+ amt->ready4 = false;
+ amt->ready6 = false;
++ amt->event_idx = 0;
++ amt->nr_events = 0;
+
+ err = amt_socket_create(amt);
+ if (err)
+@@ -2892,6 +3010,8 @@ static int amt_dev_stop(struct net_device *dev)
+ struct amt_dev *amt = netdev_priv(dev);
+ struct amt_tunnel_list *tunnel, *tmp;
+ struct socket *sock;
++ struct sk_buff *skb;
++ int i;
+
+ cancel_delayed_work_sync(&amt->req_wq);
+ cancel_delayed_work_sync(&amt->discovery_wq);
+@@ -2904,6 +3024,15 @@ static int amt_dev_stop(struct net_device *dev)
+ if (sock)
+ udp_tunnel_sock_release(sock);
+
++ cancel_work_sync(&amt->event_wq);
++ for (i = 0; i < AMT_MAX_EVENTS; i++) {
++ skb = amt->events[i].skb;
++ if (skb)
++ kfree_skb(skb);
++ amt->events[i].event = AMT_EVENT_NONE;
++ amt->events[i].skb = NULL;
++ }
++
+ amt->ready4 = false;
+ amt->ready6 = false;
+ amt->req_cnt = 0;
+@@ -3146,8 +3275,8 @@ static int amt_newlink(struct net *net, struct net_device *dev,
+ INIT_DELAYED_WORK(&amt->discovery_wq, amt_discovery_work);
+ INIT_DELAYED_WORK(&amt->req_wq, amt_req_work);
+ INIT_DELAYED_WORK(&amt->secret_wq, amt_secret_work);
++ INIT_WORK(&amt->event_wq, amt_event_work);
+ INIT_LIST_HEAD(&amt->tunnel_list);
+-
+ return 0;
+ err:
+ dev_put(amt->stream_dev);
+@@ -3280,7 +3409,7 @@ static int __init amt_init(void)
+ if (err < 0)
+ goto unregister_notifier;
+
+- amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 1);
++ amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 0);
+ if (!amt_wq) {
+ err = -ENOMEM;
+ goto rtnl_unregister;
+diff --git a/include/net/amt.h b/include/net/amt.h
+index 7a4db8b903ee..44acadf3a69e 100644
+--- a/include/net/amt.h
++++ b/include/net/amt.h
+@@ -78,6 +78,15 @@ enum amt_status {
+
+ #define AMT_STATUS_MAX (__AMT_STATUS_MAX - 1)
+
++/* Gateway events only */
++enum amt_event {
++ AMT_EVENT_NONE,
++ AMT_EVENT_RECEIVE,
++ AMT_EVENT_SEND_DISCOVERY,
++ AMT_EVENT_SEND_REQUEST,
++ __AMT_EVENT_MAX,
++};
++
+ struct amt_header {
+ #if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 type:4,
+@@ -292,6 +301,12 @@ struct amt_group_node {
+ struct hlist_head sources[];
+ };
+
++#define AMT_MAX_EVENTS 16
++struct amt_events {
++ enum amt_event event;
++ struct sk_buff *skb;
++};
++
+ struct amt_dev {
+ struct net_device *dev;
+ struct net_device *stream_dev;
+@@ -308,6 +323,7 @@ struct amt_dev {
+ struct delayed_work req_wq;
+ /* Protected by RTNL */
+ struct delayed_work secret_wq;
++ struct work_struct event_wq;
+ /* AMT status */
+ enum amt_status status;
+ /* Generated key */
+@@ -345,6 +361,10 @@ struct amt_dev {
+ /* Used only in gateway mode */
+ u64 mac:48,
+ reserved:16;
++ /* AMT gateway side message handler queue */
++ struct amt_events events[AMT_MAX_EVENTS];
++ u8 event_idx;
++ u8 nr_events;
+ };
+
+ #define AMT_TOS 0xc0
+--
+2.35.1
+
--- /dev/null
+From 5563ce72e26195246cef30f9275e9ba78edca938 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Jul 2022 11:51:34 +0300
+Subject: be2net: Fix buffer overflow in be_get_module_eeprom
+
+From: Hristo Venev <hristo@venev.name>
+
+[ Upstream commit d7241f679a59cfe27f92cb5c6272cb429fb1f7ec ]
+
+be_cmd_read_port_transceiver_data assumes that it is given a buffer that
+is at least PAGE_DATA_LEN long, or twice that if the module supports SFF
+8472. However, this is not always the case.
+
+Fix this by passing the desired offset and length to
+be_cmd_read_port_transceiver_data so that we only copy the bytes once.
+
+Fixes: e36edd9d26cf ("be2net: add ethtool "-m" option support")
+Signed-off-by: Hristo Venev <hristo@venev.name>
+Link: https://lore.kernel.org/r/20220716085134.6095-1-hristo@venev.name
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/emulex/benet/be_cmds.c | 10 +++---
+ drivers/net/ethernet/emulex/benet/be_cmds.h | 2 +-
+ .../net/ethernet/emulex/benet/be_ethtool.c | 31 ++++++++++++-------
+ 3 files changed, 25 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
+index 528eb0f223b1..b4f5e57d0285 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
+@@ -2287,7 +2287,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
+
+ /* Uses sync mcc */
+ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
+- u8 page_num, u8 *data)
++ u8 page_num, u32 off, u32 len, u8 *data)
+ {
+ struct be_dma_mem cmd;
+ struct be_mcc_wrb *wrb;
+@@ -2321,10 +2321,10 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
+ req->port = cpu_to_le32(adapter->hba_port_num);
+ req->page_num = cpu_to_le32(page_num);
+ status = be_mcc_notify_wait(adapter);
+- if (!status) {
++ if (!status && len > 0) {
+ struct be_cmd_resp_port_type *resp = cmd.va;
+
+- memcpy(data, resp->page_data, PAGE_DATA_LEN);
++ memcpy(data, resp->page_data + off, len);
+ }
+ err:
+ mutex_unlock(&adapter->mcc_lock);
+@@ -2415,7 +2415,7 @@ int be_cmd_query_cable_type(struct be_adapter *adapter)
+ int status;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- page_data);
++ 0, PAGE_DATA_LEN, page_data);
+ if (!status) {
+ switch (adapter->phy.interface_type) {
+ case PHY_TYPE_QSFP:
+@@ -2440,7 +2440,7 @@ int be_cmd_query_sfp_info(struct be_adapter *adapter)
+ int status;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- page_data);
++ 0, PAGE_DATA_LEN, page_data);
+ if (!status) {
+ strlcpy(adapter->phy.vendor_name, page_data +
+ SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
+diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
+index db1f3b908582..e2085c68c0ee 100644
+--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
++++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
+@@ -2427,7 +2427,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
+ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num,
+ u32 *state);
+ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
+- u8 page_num, u8 *data);
++ u8 page_num, u32 off, u32 len, u8 *data);
+ int be_cmd_query_cable_type(struct be_adapter *adapter);
+ int be_cmd_query_sfp_info(struct be_adapter *adapter);
+ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
+diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+index dfa784339781..bd0df189d871 100644
+--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
++++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
+@@ -1344,7 +1344,7 @@ static int be_get_module_info(struct net_device *netdev,
+ return -EOPNOTSUPP;
+
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- page_data);
++ 0, PAGE_DATA_LEN, page_data);
+ if (!status) {
+ if (!page_data[SFP_PLUS_SFF_8472_COMP]) {
+ modinfo->type = ETH_MODULE_SFF_8079;
+@@ -1362,25 +1362,32 @@ static int be_get_module_eeprom(struct net_device *netdev,
+ {
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int status;
++ u32 begin, end;
+
+ if (!check_privilege(adapter, MAX_PRIVILEGES))
+ return -EOPNOTSUPP;
+
+- status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
+- data);
+- if (status)
+- goto err;
++ begin = eeprom->offset;
++ end = eeprom->offset + eeprom->len;
++
++ if (begin < PAGE_DATA_LEN) {
++ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, begin,
++ min_t(u32, end, PAGE_DATA_LEN) - begin,
++ data);
++ if (status)
++ goto err;
++
++ data += PAGE_DATA_LEN - begin;
++ begin = PAGE_DATA_LEN;
++ }
+
+- if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) {
+- status = be_cmd_read_port_transceiver_data(adapter,
+- TR_PAGE_A2,
+- data +
+- PAGE_DATA_LEN);
++ if (end > PAGE_DATA_LEN) {
++ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A2,
++ begin - PAGE_DATA_LEN,
++ end - begin, data);
+ if (status)
+ goto err;
+ }
+- if (eeprom->offset)
+- memcpy(data, data + eeprom->offset, eeprom->len);
+ err:
+ return be_cmd_status(status);
+ }
+--
+2.35.1
+
--- /dev/null
+From 2ae8f99c20beb25b6ae3f3d009470c21c0cf9483 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 17:56:23 +0800
+Subject: can: rcar_canfd: Add missing of_node_put() in rcar_canfd_probe()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 7b66dfcc6e1e1f018492619c3d0fc432b6b54272 ]
+
+We should use of_node_put() for the reference returned by
+of_get_child_by_name() which has increased the refcount.
+
+Fixes: 45721c406dcf ("can: rcar_canfd: Add support for r8a779a0 SoC")
+Link: https://lore.kernel.org/all/20220712095623.364287-1-windhl@126.com
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/rcar/rcar_canfd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 589996cef5db..8d457d2c3bcc 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1850,6 +1850,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)
+ of_child = of_get_child_by_name(pdev->dev.of_node, name);
+ if (of_child && of_device_is_available(of_child))
+ channels_mask |= BIT(i);
++ of_node_put(of_child);
+ }
+
+ if (chip_id != RENESAS_RZG2L) {
+--
+2.35.1
+
--- /dev/null
+From 113cb9b1c60315f51b3dd5d052b24b72fb565769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 16:13:37 +0800
+Subject: drm/imx/dcss: Add missing of_node_put() in fail path
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 02c87df2480ac855d88ee308ce3fa857d9bd55a8 ]
+
+In dcss_dev_create() and dcss_dev_destroy(), we should call of_node_put()
+in fail path or before the dcss's destroy as of_graph_get_port_by_id() has
+increased the refcount.
+
+Fixes: 9021c317b770 ("drm/imx: Add initial support for DCSS on iMX8MQ")
+Signed-off-by: Liang He <windhl@126.com>
+Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+Signed-off-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220714081337.374761-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/dcss/dcss-dev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c
+index c849533ca83e..3f5750cc2673 100644
+--- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
++++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
+@@ -207,6 +207,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output)
+
+ ret = dcss_submodules_init(dcss);
+ if (ret) {
++ of_node_put(dcss->of_port);
+ dev_err(dev, "submodules initialization failed\n");
+ goto clks_err;
+ }
+@@ -237,6 +238,8 @@ void dcss_dev_destroy(struct dcss_dev *dcss)
+ dcss_clocks_disable(dcss);
+ }
+
++ of_node_put(dcss->of_port);
++
+ pm_runtime_disable(dcss->dev);
+
+ dcss_submodules_stop(dcss);
+--
+2.35.1
+
--- /dev/null
+From 500089e5299e88f4ab6379b79f142cccd6f44b5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 16:38:56 -0400
+Subject: drm/panel-edp: Fix variable typo when saving hpd absent delay from DT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: NÃcolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit ef2084a8388b19c8812356106e0c8d29915f9d8b ]
+
+The value read from the "hpd-absent-delay-ms" property in DT was being
+saved to the wrong variable, overriding the hpd_reliable delay. Fix the
+typo.
+
+Fixes: 5540cf8f3e8d ("drm/panel-edp: Implement generic "edp-panel"s probed by EDID")
+Signed-off-by: NÃcolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: André Almeida <andrealmeid@igalia.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220719203857.1488831-4-nfraprado@collabora.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-edp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
+index f7bfcf63d48e..701a258d2e11 100644
+--- a/drivers/gpu/drm/panel/panel-edp.c
++++ b/drivers/gpu/drm/panel/panel-edp.c
+@@ -713,7 +713,7 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
+ of_property_read_u32(dev->of_node, "hpd-reliable-delay-ms", &reliable_ms);
+ desc->delay.hpd_reliable = reliable_ms;
+ of_property_read_u32(dev->of_node, "hpd-absent-delay-ms", &absent_ms);
+- desc->delay.hpd_reliable = absent_ms;
++ desc->delay.hpd_absent = absent_ms;
+
+ /* Power the panel on so we can read the EDID */
+ ret = pm_runtime_get_sync(dev);
+--
+2.35.1
+
--- /dev/null
+From 75b0b2ae3c0626ea0fe5c551d008d6a0dbc6f5a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 10:09:05 +0300
+Subject: e1000e: Enable GPT clock before sending message to CSME
+
+From: Sasha Neftin <sasha.neftin@intel.com>
+
+[ Upstream commit b49feacbeffc7635cc6692cbcc6a1eae2c17da6f ]
+
+On corporate (CSME) ADL systems, the Ethernet Controller may stop working
+("HW unit hang") after exiting from the s0ix state. The reason is that
+CSME misses the message sent by the host. Enabling the dynamic GPT clock
+solves this problem. This clock is cleared upon HW initialization.
+
+Fixes: 3e55d231716e ("e1000e: Add handshake with the CSME to support S0ix")
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=214821
+Reviewed-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
+Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
+Tested-by: Chia-Lin Kao (AceLan) <acelan.kao@canonical.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index fa06f68c8c80..c64102b29862 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -6494,6 +6494,10 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
+
+ if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+ hw->mac.type >= e1000_pch_adp) {
++ /* Keep the GPT clock enabled for CSME */
++ mac_data = er32(FEXTNVM);
++ mac_data |= BIT(3);
++ ew32(FEXTNVM, mac_data);
+ /* Request ME unconfigure the device from S0ix */
+ mac_data = er32(H2ME);
+ mac_data &= ~E1000_H2ME_START_DPG;
+--
+2.35.1
+
--- /dev/null
+From 959c6048a5b5dc7b55af4a8a0935feb3c98c7c9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 13:09:09 +0530
+Subject: gpio: gpio-xilinx: Fix integer overflow
+
+From: Srinivas Neeli <srinivas.neeli@xilinx.com>
+
+[ Upstream commit 32c094a09d5829ad9b02cdf667569aefa8de0ea6 ]
+
+Current implementation is not able to configure more than 32 pins
+due to incorrect data type. So type casting with unsigned long
+to avoid it.
+
+Fixes: 02b3f84d9080 ("xilinx: Switch to use bitmap APIs")
+Signed-off-by: Srinivas Neeli <srinivas.neeli@xilinx.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-xilinx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
+index b6d3a57e27ed..7f8e2fed2988 100644
+--- a/drivers/gpio/gpio-xilinx.c
++++ b/drivers/gpio/gpio-xilinx.c
+@@ -99,7 +99,7 @@ static inline void xgpio_set_value32(unsigned long *map, int bit, u32 v)
+ const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
+
+ map[index] &= ~(0xFFFFFFFFul << offset);
+- map[index] |= v << offset;
++ map[index] |= (unsigned long)v << offset;
+ }
+
+ static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
+--
+2.35.1
+
--- /dev/null
+From da76ddae38779744b9a179225f2e59539d4095b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:31:41 +0800
+Subject: gpio: pca953x: only use single read/write for No AI mode
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit db8edaa09d7461ec08672a92a2eef63d5882bb79 ]
+
+For the device use NO AI mode(not support auto address increment),
+only use the single read/write when config the regmap.
+
+We meet issue on PCA9557PW on i.MX8QXP/DXL evk board, this device
+do not support AI mode, but when do the regmap sync, regmap will
+sync 3 byte data to register 1, logically this means write first
+data to register 1, write second data to register 2, write third data
+to register 3. But this device do not support AI mode, finally, these
+three data write only into register 1 one by one. the reault is the
+value of register 1 alway equal to the latest data, here is the third
+data, no operation happened on register 2 and register 3. This is
+not what we expect.
+
+Fixes: 49427232764d ("gpio: pca953x: Perform basic regmap conversion")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-pca953x.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index 33683295a0bf..f334c8556a22 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -351,6 +351,9 @@ static const struct regmap_config pca953x_i2c_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
++ .use_single_read = true,
++ .use_single_write = true,
++
+ .readable_reg = pca953x_readable_register,
+ .writeable_reg = pca953x_writeable_register,
+ .volatile_reg = pca953x_volatile_register,
+--
+2.35.1
+
--- /dev/null
+From ba321311ad4bd6bb17e54e2020d5ecac0ae84ba8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:31:42 +0800
+Subject: gpio: pca953x: use the correct range when do regmap sync
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 2abc17a93867dc816f0ed9d32021dda8078e7330 ]
+
+regmap will sync a range of registers, here use the correct range
+to make sure the sync do not touch other unexpected registers.
+
+Find on pca9557pw on imx8qxp/dxl evk board, this device support
+8 pin, so only need one register(8 bits) to cover all the 8 pins's
+property setting. But when sync the output, we find it actually
+update two registers, output register and the following register.
+
+Fixes: b76574300504 ("gpio: pca953x: Restore registers after suspend/resume cycle")
+Fixes: ec82d1eba346 ("gpio: pca953x: Zap ad-hoc reg_output cache")
+Fixes: 0f25fda840a9 ("gpio: pca953x: Zap ad-hoc reg_direction cache")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-pca953x.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index f334c8556a22..60b7616dd4aa 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -900,12 +900,12 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
+ int ret;
+
+ ret = regcache_sync_region(chip->regmap, chip->regs->output,
+- chip->regs->output + NBANK(chip));
++ chip->regs->output + NBANK(chip) - 1);
+ if (ret)
+ goto out;
+
+ ret = regcache_sync_region(chip->regmap, chip->regs->direction,
+- chip->regs->direction + NBANK(chip));
++ chip->regs->direction + NBANK(chip) - 1);
+ if (ret)
+ goto out;
+
+@@ -1118,14 +1118,14 @@ static int pca953x_regcache_sync(struct device *dev)
+ * sync these registers first and only then sync the rest.
+ */
+ regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0);
+- ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip));
++ ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret);
+ return ret;
+ }
+
+ regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0);
+- ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip));
++ ret = regcache_sync_region(chip->regmap, regaddr, regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret);
+ return ret;
+@@ -1135,7 +1135,7 @@ static int pca953x_regcache_sync(struct device *dev)
+ if (chip->driver_data & PCA_PCAL) {
+ regaddr = pca953x_recalc_addr(chip, PCAL953X_IN_LATCH, 0);
+ ret = regcache_sync_region(chip->regmap, regaddr,
+- regaddr + NBANK(chip));
++ regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync INT latch registers: %d\n",
+ ret);
+@@ -1144,7 +1144,7 @@ static int pca953x_regcache_sync(struct device *dev)
+
+ regaddr = pca953x_recalc_addr(chip, PCAL953X_INT_MASK, 0);
+ ret = regcache_sync_region(chip->regmap, regaddr,
+- regaddr + NBANK(chip));
++ regaddr + NBANK(chip) - 1);
+ if (ret) {
+ dev_err(dev, "Failed to sync INT mask registers: %d\n",
+ ret);
+--
+2.35.1
+
--- /dev/null
+From 80475579d6be301c558ff781e8dc2092b0a31559 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:31:43 +0800
+Subject: gpio: pca953x: use the correct register address when regcache sync
+ during init
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit b8c768ccdd8338504fb78370747728d5002b1b5a ]
+
+For regcache_sync_region, we need to use pca953x_recalc_addr() to get
+the real register address.
+
+Fixes: ec82d1eba346 ("gpio: pca953x: Zap ad-hoc reg_output cache")
+Fixes: 0f25fda840a9 ("gpio: pca953x: Zap ad-hoc reg_direction cache")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-pca953x.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index 60b7616dd4aa..64befd6f702b 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -897,15 +897,18 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
+ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
+ {
+ DECLARE_BITMAP(val, MAX_LINE);
++ u8 regaddr;
+ int ret;
+
+- ret = regcache_sync_region(chip->regmap, chip->regs->output,
+- chip->regs->output + NBANK(chip) - 1);
++ regaddr = pca953x_recalc_addr(chip, chip->regs->output, 0);
++ ret = regcache_sync_region(chip->regmap, regaddr,
++ regaddr + NBANK(chip) - 1);
+ if (ret)
+ goto out;
+
+- ret = regcache_sync_region(chip->regmap, chip->regs->direction,
+- chip->regs->direction + NBANK(chip) - 1);
++ regaddr = pca953x_recalc_addr(chip, chip->regs->direction, 0);
++ ret = regcache_sync_region(chip->regmap, regaddr,
++ regaddr + NBANK(chip) - 1);
+ if (ret)
+ goto out;
+
+--
+2.35.1
+
--- /dev/null
+From 0548da11a9cc7f75319f24341d8060a8929fa111 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 17:29:19 -0600
+Subject: i2c: cadence: Change large transfer count reset logic to be
+ unconditional
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 4ca8ca873d454635c20d508261bfc0081af75cf8 ]
+
+Problems were observed on the Xilinx ZynqMP platform with large I2C reads.
+When a read of 277 bytes was performed, the controller NAKed the transfer
+after only 252 bytes were transferred and returned an ENXIO error on the
+transfer.
+
+There is some code in cdns_i2c_master_isr to handle this case by resetting
+the transfer count in the controller before it reaches 0, to allow larger
+transfers to work, but it was conditional on the CDNS_I2C_BROKEN_HOLD_BIT
+quirk being set on the controller, and ZynqMP uses the r1p14 version of
+the core where this quirk is not being set. The requirement to do this to
+support larger reads seems like an inherently required workaround due to
+the core only having an 8-bit transfer size register, so it does not
+appear that this should be conditional on the broken HOLD bit quirk which
+is used elsewhere in the driver.
+
+Remove the dependency on the CDNS_I2C_BROKEN_HOLD_BIT for this transfer
+size reset logic to fix this problem.
+
+Fixes: 63cab195bf49 ("i2c: removed work arounds in i2c driver for Zynq Ultrascale+ MPSoC")
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@amd.com>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-cadence.c | 30 +++++-------------------------
+ 1 file changed, 5 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index 3d6f8ee355bf..630cfa4ddd46 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -388,9 +388,9 @@ static irqreturn_t cdns_i2c_slave_isr(void *ptr)
+ */
+ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ {
+- unsigned int isr_status, avail_bytes, updatetx;
++ unsigned int isr_status, avail_bytes;
+ unsigned int bytes_to_send;
+- bool hold_quirk;
++ bool updatetx;
+ struct cdns_i2c *id = ptr;
+ /* Signal completion only after everything is updated */
+ int done_flag = 0;
+@@ -410,11 +410,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ * Check if transfer size register needs to be updated again for a
+ * large data receive operation.
+ */
+- updatetx = 0;
+- if (id->recv_count > id->curr_recv_count)
+- updatetx = 1;
+-
+- hold_quirk = (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx;
++ updatetx = id->recv_count > id->curr_recv_count;
+
+ /* When receiving, handle data interrupt and completion interrupt */
+ if (id->p_recv_buf &&
+@@ -445,7 +441,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ break;
+ }
+
+- if (cdns_is_holdquirk(id, hold_quirk))
++ if (cdns_is_holdquirk(id, updatetx))
+ break;
+ }
+
+@@ -456,7 +452,7 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ * maintain transfer size non-zero while performing a large
+ * receive operation.
+ */
+- if (cdns_is_holdquirk(id, hold_quirk)) {
++ if (cdns_is_holdquirk(id, updatetx)) {
+ /* wait while fifo is full */
+ while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) !=
+ (id->curr_recv_count - CDNS_I2C_FIFO_DEPTH))
+@@ -478,22 +474,6 @@ static irqreturn_t cdns_i2c_master_isr(void *ptr)
+ CDNS_I2C_XFER_SIZE_OFFSET);
+ id->curr_recv_count = id->recv_count;
+ }
+- } else if (id->recv_count && !hold_quirk &&
+- !id->curr_recv_count) {
+-
+- /* Set the slave address in address register*/
+- cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK,
+- CDNS_I2C_ADDR_OFFSET);
+-
+- if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) {
+- cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE,
+- CDNS_I2C_XFER_SIZE_OFFSET);
+- id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE;
+- } else {
+- cdns_i2c_writereg(id->recv_count,
+- CDNS_I2C_XFER_SIZE_OFFSET);
+- id->curr_recv_count = id->recv_count;
+- }
+ }
+
+ /* Clear hold (if not repeated start) and signal completion */
+--
+2.35.1
+
--- /dev/null
+From 044de546b5632cba88368bd929993f244fc9c43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 12:14:05 +0300
+Subject: i2c: mlxcpld: Fix register setting for 400KHz frequency
+
+From: Vadim Pasternak <vadimp@nvidia.com>
+
+[ Upstream commit e1f77ecc75aaee6bed04e8fd7830e00032af012e ]
+
+Fix setting of 'Half Cycle' register for 400KHz frequency.
+
+Fixes: fa1049135c15 ("i2c: mlxcpld: Modify register setting for 400KHz frequency")
+Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-mlxcpld.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
+index 56aa424fd71d..815cc561386b 100644
+--- a/drivers/i2c/busses/i2c-mlxcpld.c
++++ b/drivers/i2c/busses/i2c-mlxcpld.c
+@@ -49,7 +49,7 @@
+ #define MLXCPLD_LPCI2C_NACK_IND 2
+
+ #define MLXCPLD_I2C_FREQ_1000KHZ_SET 0x04
+-#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0c
++#define MLXCPLD_I2C_FREQ_400KHZ_SET 0x0e
+ #define MLXCPLD_I2C_FREQ_100KHZ_SET 0x42
+
+ enum mlxcpld_i2c_frequency {
+--
+2.35.1
+
--- /dev/null
+From cba876e0bab468b2ced4a58da7d7ecdd1b126552 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 14:45:41 -0700
+Subject: i40e: Fix erroneous adapter reinitialization during recovery process
+
+From: Dawid Lukwinski <dawid.lukwinski@intel.com>
+
+[ Upstream commit f838a63369818faadec4ad1736cfbd20ab5da00e ]
+
+Fix an issue when driver incorrectly detects state
+of recovery process and erroneously reinitializes interrupts,
+which results in a kernel error and call trace message.
+
+The issue was caused by a combination of two factors:
+1. Assuming the EMP reset issued after completing
+firmware recovery means the whole recovery process is complete.
+2. Erroneous reinitialization of interrupt vector after detecting
+the above mentioned EMP reset.
+
+Fixes (1) by changing how recovery state change is detected
+and (2) by adjusting the conditional expression to ensure using proper
+interrupt reinitialization method, depending on the situation.
+
+Fixes: 4ff0ee1af016 ("i40e: Introduce recovery mode support")
+Signed-off-by: Dawid Lukwinski <dawid.lukwinski@intel.com>
+Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://lore.kernel.org/r/20220715214542.2968762-1-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 77eb9c726205..6f01bffd7e5c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -10645,7 +10645,7 @@ static int i40e_reset(struct i40e_pf *pf)
+ **/
+ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ {
+- int old_recovery_mode_bit = test_bit(__I40E_RECOVERY_MODE, pf->state);
++ const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf);
+ struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+ struct i40e_hw *hw = &pf->hw;
+ i40e_status ret;
+@@ -10653,13 +10653,11 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ int v;
+
+ if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) &&
+- i40e_check_recovery_mode(pf)) {
++ is_recovery_mode_reported)
+ i40e_set_ethtool_ops(pf->vsi[pf->lan_vsi]->netdev);
+- }
+
+ if (test_bit(__I40E_DOWN, pf->state) &&
+- !test_bit(__I40E_RECOVERY_MODE, pf->state) &&
+- !old_recovery_mode_bit)
++ !test_bit(__I40E_RECOVERY_MODE, pf->state))
+ goto clear_recovery;
+ dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n");
+
+@@ -10686,13 +10684,12 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ * accordingly with regard to resources initialization
+ * and deinitialization
+ */
+- if (test_bit(__I40E_RECOVERY_MODE, pf->state) ||
+- old_recovery_mode_bit) {
++ if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
+ if (i40e_get_capabilities(pf,
+ i40e_aqc_opc_list_func_capabilities))
+ goto end_unlock;
+
+- if (test_bit(__I40E_RECOVERY_MODE, pf->state)) {
++ if (is_recovery_mode_reported) {
+ /* we're staying in recovery mode so we'll reinitialize
+ * misc vector here
+ */
+--
+2.35.1
+
--- /dev/null
+From b9bf6d90b5623a3c713faadbbb51ac4487ba21a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 19:07:42 -0400
+Subject: iavf: Disallow changing rx/tx-frames and rx/tx-frames-irq
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit 4635fd3a9d77581498f34ab9a7e4bcc211bf0a4c ]
+
+Remove from supported_coalesce_params ETHTOOL_COALESCE_MAX_FRAMES
+and ETHTOOL_COALESCE_MAX_FRAMES_IRQ. As tx-frames-irq allowed
+user to change budget for iavf_clean_tx_irq, remove work_limit
+and use define for budget.
+
+Without this patch there would be possibility to change rx/tx-frames
+and rx/tx-frames-irq, which for rx/tx-frames did nothing, while for
+rx/tx-frames-irq it changed rx/tx-frames and only changed budget
+for cleaning NAPI poll.
+
+Fixes: fbb7ddfef253 ("i40evf: core ethtool functionality")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>
+Tested-by: Marek Szlosek <marek.szlosek@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h | 1 -
+ drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 10 ----------
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 1 -
+ drivers/net/ethernet/intel/iavf/iavf_txrx.c | 2 +-
+ 4 files changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 86bc61c300a7..2a7b3c085aa9 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -64,7 +64,6 @@ struct iavf_vsi {
+ u16 id;
+ DECLARE_BITMAP(state, __IAVF_VSI_STATE_SIZE__);
+ int base_vector;
+- u16 work_limit;
+ u16 qs_handle;
+ void *priv; /* client driver data reference. */
+ };
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+index 3bb56714beb0..e535d4c3da49 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c
+@@ -692,12 +692,8 @@ static int __iavf_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec, int queue)
+ {
+ struct iavf_adapter *adapter = netdev_priv(netdev);
+- struct iavf_vsi *vsi = &adapter->vsi;
+ struct iavf_ring *rx_ring, *tx_ring;
+
+- ec->tx_max_coalesced_frames = vsi->work_limit;
+- ec->rx_max_coalesced_frames = vsi->work_limit;
+-
+ /* Rx and Tx usecs per queue value. If user doesn't specify the
+ * queue, return queue 0's value to represent.
+ */
+@@ -825,12 +821,8 @@ static int __iavf_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec, int queue)
+ {
+ struct iavf_adapter *adapter = netdev_priv(netdev);
+- struct iavf_vsi *vsi = &adapter->vsi;
+ int i;
+
+- if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
+- vsi->work_limit = ec->tx_max_coalesced_frames_irq;
+-
+ if (ec->rx_coalesce_usecs == 0) {
+ if (ec->use_adaptive_rx_coalesce)
+ netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
+@@ -1969,8 +1961,6 @@ static int iavf_set_rxfh(struct net_device *netdev, const u32 *indir,
+
+ static const struct ethtool_ops iavf_ethtool_ops = {
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
+- ETHTOOL_COALESCE_MAX_FRAMES |
+- ETHTOOL_COALESCE_MAX_FRAMES_IRQ |
+ ETHTOOL_COALESCE_USE_ADAPTIVE,
+ .get_drvinfo = iavf_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 2a8643e66331..2e2c153ce46a 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2240,7 +2240,6 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter)
+
+ adapter->vsi.back = adapter;
+ adapter->vsi.base_vector = 1;
+- adapter->vsi.work_limit = IAVF_DEFAULT_IRQ_WORK;
+ vsi->netdev = adapter->netdev;
+ vsi->qs_handle = adapter->vsi_res->qset_handle;
+ if (adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+index 978f651c6b09..7bf8c25dc824 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+@@ -194,7 +194,7 @@ static bool iavf_clean_tx_irq(struct iavf_vsi *vsi,
+ struct iavf_tx_buffer *tx_buf;
+ struct iavf_tx_desc *tx_desc;
+ unsigned int total_bytes = 0, total_packets = 0;
+- unsigned int budget = vsi->work_limit;
++ unsigned int budget = IAVF_DEFAULT_IRQ_WORK;
+
+ tx_buf = &tx_ring->tx_bi[i];
+ tx_desc = IAVF_TX_DESC(tx_ring, i);
+--
+2.35.1
+
--- /dev/null
+From 3180e648dfd431a5adfbd7f3ca3d1e6f8de3c4c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:33:01 -0700
+Subject: iavf: Fix handling of dummy receive descriptors
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit a9f49e0060301a9bfebeca76739158d0cf91cdf6 ]
+
+Fix memory leak caused by not handling dummy receive descriptor properly.
+iavf_get_rx_buffer now sets the rx_buffer return value for dummy receive
+descriptors. Without this patch, when the hardware writes a dummy
+descriptor, iavf would not free the page allocated for the previous receive
+buffer. This is an unlikely event but can still happen.
+
+[Jesse: massaged commit message]
+
+Fixes: efa14c398582 ("iavf: allow null RX descriptors")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_txrx.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_txrx.c b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+index 7bf8c25dc824..06d18797d25a 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_txrx.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_txrx.c
+@@ -1285,11 +1285,10 @@ static struct iavf_rx_buffer *iavf_get_rx_buffer(struct iavf_ring *rx_ring,
+ {
+ struct iavf_rx_buffer *rx_buffer;
+
+- if (!size)
+- return NULL;
+-
+ rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean];
+ prefetchw(rx_buffer->page);
++ if (!size)
++ return rx_buffer;
+
+ /* we are reusing so sync this buffer for CPU use */
+ dma_sync_single_range_for_cpu(rx_ring->dev,
+--
+2.35.1
+
--- /dev/null
+From 34521a3e81076acd1fb8afc93e587ffdc13e83e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 13:57:20 -0400
+Subject: iavf: Fix missing state logs
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit d8fa2fd791a72087c1ce3336fbeefec4057c37c8 ]
+
+Fix debug prints, by adding missing state prints.
+
+Extend iavf_state_str by strings for __IAVF_INIT_EXTENDED_CAPS and
+__IAVF_INIT_CONFIG_ADAPTER.
+
+Without this patch, when enabling debug prints for iavf.h, user will
+see:
+iavf 0000:06:0e.0: state transition from:__IAVF_INIT_GET_RESOURCES to:__IAVF_UNKNOWN_STATE
+iavf 0000:06:0e.0: state transition from:__IAVF_UNKNOWN_STATE to:__IAVF_UNKNOWN_STATE
+
+Fixes: 605ca7c5c670 ("iavf: Fix kernel BUG in free_msi_irqs")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 2a7b3c085aa9..0ea0361cd86b 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -464,6 +464,10 @@ static inline const char *iavf_state_str(enum iavf_state_t state)
+ return "__IAVF_INIT_VERSION_CHECK";
+ case __IAVF_INIT_GET_RESOURCES:
+ return "__IAVF_INIT_GET_RESOURCES";
++ case __IAVF_INIT_EXTENDED_CAPS:
++ return "__IAVF_INIT_EXTENDED_CAPS";
++ case __IAVF_INIT_CONFIG_ADAPTER:
++ return "__IAVF_INIT_CONFIG_ADAPTER";
+ case __IAVF_INIT_SW:
+ return "__IAVF_INIT_SW";
+ case __IAVF_INIT_FAILED:
+--
+2.35.1
+
--- /dev/null
+From 44361badefb6dfbf7d3faf771f8671a940433730 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 14:15:54 +0200
+Subject: iavf: Fix VLAN_V2 addition/rejection
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit 968996c070ef080ee7d6150faa98a4e562ce4625 ]
+
+Fix VLAN addition, so that PF driver does not reject whole VLAN batch.
+Add VLAN reject handling, so rejected VLANs, won't litter VLAN filter
+list. Fix handling of active_(c/s)vlans, so it will be possible to
+re-add VLAN filters for user.
+Without this patch, after changing trust to off, with VLAN filters
+saturated, no VLAN is added, due to PF rejecting addition.
+
+Fixes: 92fc50859872 ("iavf: Restrict maximum VLAN filters for VIRTCHNL_VF_OFFLOAD_VLAN_V2")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h | 9 ++-
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 10 ++-
+ .../net/ethernet/intel/iavf/iavf_virtchnl.c | 65 ++++++++++++++++++-
+ 3 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 49aed3e506a6..86bc61c300a7 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -159,8 +159,12 @@ struct iavf_vlan {
+ struct iavf_vlan_filter {
+ struct list_head list;
+ struct iavf_vlan vlan;
+- bool remove; /* filter needs to be removed */
+- bool add; /* filter needs to be added */
++ struct {
++ u8 is_new_vlan:1; /* filter is new, wait for PF answer */
++ u8 remove:1; /* filter needs to be removed */
++ u8 add:1; /* filter needs to be added */
++ u8 padding:5;
++ };
+ };
+
+ #define IAVF_MAX_TRAFFIC_CLASS 4
+@@ -520,6 +524,7 @@ int iavf_get_vf_config(struct iavf_adapter *adapter);
+ int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
+ int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
+ void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
++u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
+ void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
+ void iavf_configure_queues(struct iavf_adapter *adapter);
+ void iavf_deconfigure_queues(struct iavf_adapter *adapter);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index f3ecb3bca33d..2a8643e66331 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -843,7 +843,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)
+ * iavf_get_num_vlans_added - get number of VLANs added
+ * @adapter: board private structure
+ */
+-static u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
++u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
+ {
+ return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
+ bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
+@@ -906,11 +906,6 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
+ if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))))
+ return -ENOMEM;
+
+- if (proto == cpu_to_be16(ETH_P_8021Q))
+- set_bit(vid, adapter->vsi.active_cvlans);
+- else
+- set_bit(vid, adapter->vsi.active_svlans);
+-
+ return 0;
+ }
+
+@@ -2956,6 +2951,9 @@ static void iavf_reset_task(struct work_struct *work)
+ adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
+ iavf_misc_irq_enable(adapter);
+
++ bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
++ bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);
++
+ mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);
+
+ /* We were running when the reset started, so we need to restore some
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+index 782450d5c12f..1603e99bae4a 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+@@ -626,6 +626,33 @@ static void iavf_mac_add_reject(struct iavf_adapter *adapter)
+ spin_unlock_bh(&adapter->mac_vlan_list_lock);
+ }
+
++/**
++ * iavf_vlan_add_reject
++ * @adapter: adapter structure
++ *
++ * Remove VLAN filters from list based on PF response.
++ **/
++static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
++{
++ struct iavf_vlan_filter *f, *ftmp;
++
++ spin_lock_bh(&adapter->mac_vlan_list_lock);
++ list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
++ if (f->is_new_vlan) {
++ if (f->vlan.tpid == ETH_P_8021Q)
++ clear_bit(f->vlan.vid,
++ adapter->vsi.active_cvlans);
++ else
++ clear_bit(f->vlan.vid,
++ adapter->vsi.active_svlans);
++
++ list_del(&f->list);
++ kfree(f);
++ }
++ }
++ spin_unlock_bh(&adapter->mac_vlan_list_lock);
++}
++
+ /**
+ * iavf_add_vlans
+ * @adapter: adapter structure
+@@ -683,6 +710,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+ vvfl->vlan_id[i] = f->vlan.vid;
+ i++;
+ f->add = false;
++ f->is_new_vlan = true;
+ if (i == count)
+ break;
+ }
+@@ -695,10 +723,18 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+ iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
+ kfree(vvfl);
+ } else {
++ u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
++ u16 current_vlans = iavf_get_num_vlans_added(adapter);
+ struct virtchnl_vlan_filter_list_v2 *vvfl_v2;
+
+ adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;
+
++ if ((count + current_vlans) > max_vlans &&
++ current_vlans < max_vlans) {
++ count = max_vlans - iavf_get_num_vlans_added(adapter);
++ more = true;
++ }
++
+ len = sizeof(*vvfl_v2) + ((count - 1) *
+ sizeof(struct virtchnl_vlan_filter));
+ if (len > IAVF_MAX_AQ_BUF_SIZE) {
+@@ -725,6 +761,9 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+ &adapter->vlan_v2_caps.filtering.filtering_support;
+ struct virtchnl_vlan *vlan;
+
++ if (i == count)
++ break;
++
+ /* give priority over outer if it's enabled */
+ if (filtering_support->outer)
+ vlan = &vvfl_v2->filters[i].outer;
+@@ -736,8 +775,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
+
+ i++;
+ f->add = false;
+- if (i == count)
+- break;
++ f->is_new_vlan = true;
+ }
+ }
+
+@@ -2080,6 +2118,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+ */
+ iavf_netdev_features_vlan_strip_set(netdev, true);
+ break;
++ case VIRTCHNL_OP_ADD_VLAN_V2:
++ iavf_vlan_add_reject(adapter);
++ dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
++ iavf_stat_str(&adapter->hw, v_retval));
++ break;
+ default:
+ dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
+ v_retval, iavf_stat_str(&adapter->hw, v_retval),
+@@ -2332,6 +2375,24 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+ spin_unlock_bh(&adapter->adv_rss_lock);
+ }
+ break;
++ case VIRTCHNL_OP_ADD_VLAN_V2: {
++ struct iavf_vlan_filter *f;
++
++ spin_lock_bh(&adapter->mac_vlan_list_lock);
++ list_for_each_entry(f, &adapter->vlan_filter_list, list) {
++ if (f->is_new_vlan) {
++ f->is_new_vlan = false;
++ if (f->vlan.tpid == ETH_P_8021Q)
++ set_bit(f->vlan.vid,
++ adapter->vsi.active_cvlans);
++ else
++ set_bit(f->vlan.vid,
++ adapter->vsi.active_svlans);
++ }
++ }
++ spin_unlock_bh(&adapter->mac_vlan_list_lock);
++ }
++ break;
+ case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
+ /* PF enabled vlan strip on this VF.
+ * Update netdev->features if needed to be in sync with ethtool.
+--
+2.35.1
+
--- /dev/null
+From 69a37ac608180c621c7091069eadd5185f6d22b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 18:58:11 +0300
+Subject: igc: Reinstate IGC_REMOVED logic and implement it properly
+
+From: Lennert Buytenhek <buytenh@wantstofly.org>
+
+[ Upstream commit 7c1ddcee5311f3315096217881d2dbe47cc683f9 ]
+
+The initially merged version of the igc driver code (via commit
+146740f9abc4, "igc: Add support for PF") contained the following
+IGC_REMOVED checks in the igc_rd32/wr32() MMIO accessors:
+
+ u32 igc_rd32(struct igc_hw *hw, u32 reg)
+ {
+ u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr);
+ u32 value = 0;
+
+ if (IGC_REMOVED(hw_addr))
+ return ~value;
+
+ value = readl(&hw_addr[reg]);
+
+ /* reads should not return all F's */
+ if (!(~value) && (!reg || !(~readl(hw_addr))))
+ hw->hw_addr = NULL;
+
+ return value;
+ }
+
+And:
+
+ #define wr32(reg, val) \
+ do { \
+ u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
+ if (!IGC_REMOVED(hw_addr)) \
+ writel((val), &hw_addr[(reg)]); \
+ } while (0)
+
+E.g. igb has similar checks in its MMIO accessors, and has a similar
+macro E1000_REMOVED, which is implemented as follows:
+
+ #define E1000_REMOVED(h) unlikely(!(h))
+
+These checks serve to detect and take note of an 0xffffffff MMIO read
+return from the device, which can be caused by a PCIe link flap or some
+other kind of PCI bus error, and to avoid performing MMIO reads and
+writes from that point onwards.
+
+However, the IGC_REMOVED macro was not originally implemented:
+
+ #ifndef IGC_REMOVED
+ #define IGC_REMOVED(a) (0)
+ #endif /* IGC_REMOVED */
+
+This led to the IGC_REMOVED logic to be removed entirely in a
+subsequent commit (commit 3c215fb18e70, "igc: remove IGC_REMOVED
+function"), with the rationale that such checks matter only for
+virtualization and that igc does not support virtualization -- but a
+PCIe device can become detached even without virtualization being in
+use, and without proper checks, a PCIe bus error affecting an igc
+adapter will lead to various NULL pointer dereferences, as the first
+access after the error will set hw->hw_addr to NULL, and subsequent
+accesses will blindly dereference this now-NULL pointer.
+
+This patch reinstates the IGC_REMOVED checks in igc_rd32/wr32(), and
+implements IGC_REMOVED the way it is done for igb, by checking for the
+unlikely() case of hw_addr being NULL. This change prevents the oopses
+seen when a PCIe link flap occurs on an igc adapter.
+
+Fixes: 146740f9abc4 ("igc: Add support for PF")
+Signed-off-by: Lennert Buytenhek <buytenh@arista.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Acked-by: Sasha Neftin <sasha.neftin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 3 +++
+ drivers/net/ethernet/intel/igc/igc_regs.h | 5 ++++-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 74b2c590ed5d..38e46e9ba8bb 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -6171,6 +6171,9 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg)
+ u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr);
+ u32 value = 0;
+
++ if (IGC_REMOVED(hw_addr))
++ return ~value;
++
+ value = readl(&hw_addr[reg]);
+
+ /* reads should not return all F's */
+diff --git a/drivers/net/ethernet/intel/igc/igc_regs.h b/drivers/net/ethernet/intel/igc/igc_regs.h
+index e197a33d93a0..026c3b65fc37 100644
+--- a/drivers/net/ethernet/intel/igc/igc_regs.h
++++ b/drivers/net/ethernet/intel/igc/igc_regs.h
+@@ -306,7 +306,8 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg);
+ #define wr32(reg, val) \
+ do { \
+ u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
+- writel((val), &hw_addr[(reg)]); \
++ if (!IGC_REMOVED(hw_addr)) \
++ writel((val), &hw_addr[(reg)]); \
+ } while (0)
+
+ #define rd32(reg) (igc_rd32(hw, reg))
+@@ -318,4 +319,6 @@ do { \
+
+ #define array_rd32(reg, offset) (igc_rd32(hw, (reg) + ((offset) << 2)))
+
++#define IGC_REMOVED(h) unlikely(!(h))
++
+ #endif
+--
+2.35.1
+
--- /dev/null
+From 0f5f36fc7f4cd8086af89611acde3d35beee8e26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:42 -0700
+Subject: igmp: Fix a data-race around sysctl_igmp_max_memberships.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 6305d821e3b9b5379d348528e5b5faf316383bc2 ]
+
+While reading sysctl_igmp_max_memberships, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/igmp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index 0bde3774505f..d07d290bf0b9 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -2197,7 +2197,7 @@ static int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr,
+ count++;
+ }
+ err = -ENOBUFS;
+- if (count >= net->ipv4.sysctl_igmp_max_memberships)
++ if (count >= READ_ONCE(net->ipv4.sysctl_igmp_max_memberships))
+ goto done;
+ iml = sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
+ if (!iml)
+--
+2.35.1
+
--- /dev/null
+From 53aa741fd60839ca0259c78e932938c054cc0216 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:41 -0700
+Subject: igmp: Fix data-races around sysctl_igmp_llm_reports.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit f6da2267e71106474fbc0943dc24928b9cb79119 ]
+
+While reading sysctl_igmp_llm_reports, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+This test can be packed into a helper, so such changes will be in the
+follow-up series after net is merged into net-next.
+
+ if (ipv4_is_local_multicast(pmc->multiaddr) &&
+ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+
+Fixes: df2cf4a78e48 ("IGMP: Inhibit reports for local multicast groups")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/igmp.c | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index 1d9e6d5e9a76..0bde3774505f 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -467,7 +467,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
+
+ if (pmc->multiaddr == IGMP_ALL_HOSTS)
+ return skb;
+- if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(pmc->multiaddr) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return skb;
+
+ mtu = READ_ONCE(dev->mtu);
+@@ -593,7 +594,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
+ if (pmc->multiaddr == IGMP_ALL_HOSTS)
+ continue;
+ if (ipv4_is_local_multicast(pmc->multiaddr) &&
+- !net->ipv4.sysctl_igmp_llm_reports)
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ continue;
+ spin_lock_bh(&pmc->lock);
+ if (pmc->sfcount[MCAST_EXCLUDE])
+@@ -736,7 +737,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
+ if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
+ return igmpv3_send_report(in_dev, pmc);
+
+- if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(group) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return 0;
+
+ if (type == IGMP_HOST_LEAVE_MESSAGE)
+@@ -920,7 +922,8 @@ static bool igmp_heard_report(struct in_device *in_dev, __be32 group)
+
+ if (group == IGMP_ALL_HOSTS)
+ return false;
+- if (ipv4_is_local_multicast(group) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(group) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return false;
+
+ rcu_read_lock();
+@@ -1045,7 +1048,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ continue;
+ if (ipv4_is_local_multicast(im->multiaddr) &&
+- !net->ipv4.sysctl_igmp_llm_reports)
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ continue;
+ spin_lock_bh(&im->lock);
+ if (im->tm_running)
+@@ -1296,7 +1299,8 @@ static void __igmp_group_dropped(struct ip_mc_list *im, gfp_t gfp)
+ #ifdef CONFIG_IP_MULTICAST
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ return;
+- if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(im->multiaddr) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return;
+
+ reporter = im->reporter;
+@@ -1338,7 +1342,8 @@ static void igmp_group_added(struct ip_mc_list *im)
+ #ifdef CONFIG_IP_MULTICAST
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ return;
+- if (ipv4_is_local_multicast(im->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
++ if (ipv4_is_local_multicast(im->multiaddr) &&
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ return;
+
+ if (in_dev->dead)
+@@ -1642,7 +1647,7 @@ static void ip_mc_rejoin_groups(struct in_device *in_dev)
+ if (im->multiaddr == IGMP_ALL_HOSTS)
+ continue;
+ if (ipv4_is_local_multicast(im->multiaddr) &&
+- !net->ipv4.sysctl_igmp_llm_reports)
++ !READ_ONCE(net->ipv4.sysctl_igmp_llm_reports))
+ continue;
+
+ /* a failover is happening and switches
+--
+2.35.1
+
--- /dev/null
+From 43401b941ac676305fb5909413893d19cc5adcb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:43 -0700
+Subject: igmp: Fix data-races around sysctl_igmp_max_msf.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 6ae0f2e553737b8cce49a1372573c81130ffa80e ]
+
+While reading sysctl_igmp_max_msf, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/igmp.c | 2 +-
+ net/ipv4/ip_sockglue.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index d07d290bf0b9..655d2ab946e0 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -2384,7 +2384,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
+ }
+ /* else, add a new source to the filter */
+
+- if (psl && psl->sl_count >= net->ipv4.sysctl_igmp_max_msf) {
++ if (psl && psl->sl_count >= READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) {
+ err = -ENOBUFS;
+ goto done;
+ }
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index d497d525dea3..a8a323ecbb54 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -782,7 +782,7 @@ static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen)
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ err = -ENOBUFS;
+ if (gsf->gf_numsrc >= 0x1ffffff ||
+- gsf->gf_numsrc > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
++ gsf->gf_numsrc > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
+ goto out_free_gsf;
+
+ err = -EINVAL;
+@@ -832,7 +832,7 @@ static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
+
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
+ err = -ENOBUFS;
+- if (n > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
++ if (n > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
+ goto out_free_gsf;
+ err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
+ &gf32->gf_group, gf32->gf_slist_flex);
+@@ -1244,7 +1244,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, int optname,
+ }
+ /* numsrc >= (1G-4) overflow in 32 bits */
+ if (msf->imsf_numsrc >= 0x3ffffffcU ||
+- msf->imsf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
++ msf->imsf_numsrc > READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) {
+ kfree(msf);
+ err = -ENOBUFS;
+ break;
+--
+2.35.1
+
--- /dev/null
+From d4809dc0fad64ad1c538b6af11b57363beb8cd2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:44 -0700
+Subject: igmp: Fix data-races around sysctl_igmp_qrv.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 8ebcc62c738f68688ee7c6fec2efe5bc6d3d7e60 ]
+
+While reading sysctl_igmp_qrv, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+This test can be packed into a helper, so such changes will be in the
+follow-up series after net is merged into net-next.
+
+ qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+
+Fixes: a9fe8e29945d ("ipv4: implement igmp_qrv sysctl to tune igmp robustness variable")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 4 ++--
+ net/ipv4/igmp.c | 24 +++++++++++++-----------
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 14fe03dbd9b1..6c64953db487 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -563,7 +563,7 @@ static struct sk_buff *amt_build_igmp_gq(struct amt_dev *amt)
+ ihv3->nsrcs = 0;
+ ihv3->resv = 0;
+ ihv3->suppress = false;
+- ihv3->qrv = amt->net->ipv4.sysctl_igmp_qrv;
++ ihv3->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv);
+ ihv3->csum = 0;
+ csum = &ihv3->csum;
+ csum_start = (void *)ihv3;
+@@ -3095,7 +3095,7 @@ static int amt_newlink(struct net *net, struct net_device *dev,
+ goto err;
+ }
+ if (amt->mode == AMT_MODE_RELAY) {
+- amt->qrv = amt->net->ipv4.sysctl_igmp_qrv;
++ amt->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv);
+ amt->qri = 10;
+ dev->needed_headroom = amt->stream_dev->needed_headroom +
+ AMT_RELAY_HLEN;
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index 655d2ab946e0..0a0010f89627 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -827,7 +827,7 @@ static void igmp_ifc_event(struct in_device *in_dev)
+ struct net *net = dev_net(in_dev->dev);
+ if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev))
+ return;
+- WRITE_ONCE(in_dev->mr_ifc_count, in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv);
++ WRITE_ONCE(in_dev->mr_ifc_count, in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv));
+ igmp_ifc_start_timer(in_dev, 1);
+ }
+
+@@ -1009,7 +1009,7 @@ static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
+ * received value was zero, use the default or statically
+ * configured value.
+ */
+- in_dev->mr_qrv = ih3->qrv ?: net->ipv4.sysctl_igmp_qrv;
++ in_dev->mr_qrv = ih3->qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ in_dev->mr_qi = IGMPV3_QQIC(ih3->qqic)*HZ ?: IGMP_QUERY_INTERVAL;
+
+ /* RFC3376, 8.3. Query Response Interval:
+@@ -1189,7 +1189,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im,
+ pmc->interface = im->interface;
+ in_dev_hold(in_dev);
+ pmc->multiaddr = im->multiaddr;
+- pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ pmc->sfmode = im->sfmode;
+ if (pmc->sfmode == MCAST_INCLUDE) {
+ struct ip_sf_list *psf;
+@@ -1240,9 +1240,11 @@ static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im)
+ swap(im->tomb, pmc->tomb);
+ swap(im->sources, pmc->sources);
+ for (psf = im->sources; psf; psf = psf->sf_next)
+- psf->sf_crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ psf->sf_crcount = in_dev->mr_qrv ?:
++ READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ } else {
+- im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ im->crcount = in_dev->mr_qrv ?:
++ READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ }
+ in_dev_put(pmc->interface);
+ kfree_pmc(pmc);
+@@ -1349,7 +1351,7 @@ static void igmp_group_added(struct ip_mc_list *im)
+ if (in_dev->dead)
+ return;
+
+- im->unsolicit_count = net->ipv4.sysctl_igmp_qrv;
++ im->unsolicit_count = READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) {
+ spin_lock_bh(&im->lock);
+ igmp_start_timer(im, IGMP_INITIAL_REPORT_DELAY);
+@@ -1363,7 +1365,7 @@ static void igmp_group_added(struct ip_mc_list *im)
+ * IN() to IN(A).
+ */
+ if (im->sfmode == MCAST_EXCLUDE)
+- im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ im->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+
+ igmp_ifc_event(in_dev);
+ #endif
+@@ -1754,7 +1756,7 @@ static void ip_mc_reset(struct in_device *in_dev)
+
+ in_dev->mr_qi = IGMP_QUERY_INTERVAL;
+ in_dev->mr_qri = IGMP_QUERY_RESPONSE_INTERVAL;
+- in_dev->mr_qrv = net->ipv4.sysctl_igmp_qrv;
++ in_dev->mr_qrv = READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ }
+ #else
+ static void ip_mc_reset(struct in_device *in_dev)
+@@ -1888,7 +1890,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
+ #ifdef CONFIG_IP_MULTICAST
+ if (psf->sf_oldin &&
+ !IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) {
+- psf->sf_crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ psf->sf_crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ psf->sf_next = pmc->tomb;
+ pmc->tomb = psf;
+ rv = 1;
+@@ -1952,7 +1954,7 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ /* filter mode change */
+ pmc->sfmode = MCAST_INCLUDE;
+ #ifdef CONFIG_IP_MULTICAST
+- pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount);
+ for (psf = pmc->sources; psf; psf = psf->sf_next)
+ psf->sf_crcount = 0;
+@@ -2131,7 +2133,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
+ #ifdef CONFIG_IP_MULTICAST
+ /* else no filters; keep old mode for reports */
+
+- pmc->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv;
++ pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount);
+ for (psf = pmc->sources; psf; psf = psf->sf_next)
+ psf->sf_crcount = 0;
+--
+2.35.1
+
--- /dev/null
+From e069be3ccde4d0e9f3592d4cab9efd0a765d2452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:57 -0700
+Subject: ip: Fix a data-race around sysctl_fwmark_reflect.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 85d0b4dbd74b95cc492b1f4e34497d3f894f5d9a ]
+
+While reading sysctl_fwmark_reflect, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: e110861f8609 ("net: add a sysctl to reflect the fwmark on replies")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 05fe313f72fa..4a15b6bcb4b8 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -384,7 +384,7 @@ void ipfrag_init(void);
+ void ip_static_sysctl_init(void);
+
+ #define IP4_REPLY_MARK(net, mark) \
+- ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0)
++ (READ_ONCE((net)->ipv4.sysctl_fwmark_reflect) ? (mark) : 0)
+
+ static inline bool ip_is_fragment(const struct iphdr *iph)
+ {
+--
+2.35.1
+
--- /dev/null
+From 72b3cbb749d4c8616914e465be7b03be18329503 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:56 -0700
+Subject: ip: Fix a data-race around sysctl_ip_autobind_reuse.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 0db232765887d9807df8bcb7b6f29b2871539eab ]
+
+While reading sysctl_ip_autobind_reuse, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 4b01a9674231 ("tcp: bind(0) remove the SO_REUSEADDR restriction when ephemeral ports are exhausted.")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_connection_sock.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 1e5b53c2bb26..dfb5a2d7ad85 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -259,7 +259,7 @@ inet_csk_find_open_port(struct sock *sk, struct inet_bind_bucket **tb_ret, int *
+ goto other_half_scan;
+ }
+
+- if (net->ipv4.sysctl_ip_autobind_reuse && !relax) {
++ if (READ_ONCE(net->ipv4.sysctl_ip_autobind_reuse) && !relax) {
+ /* We still have a chance to connect to different destinations */
+ relax = true;
+ goto ports_exhausted;
+--
+2.35.1
+
--- /dev/null
+From 86610c0280fac8bfb7d6832a67e02dd0529febce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:54 -0700
+Subject: ip: Fix data-races around sysctl_ip_fwd_update_priority.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 7bf9e18d9a5e99e3c83482973557e9f047b051e7 ]
+
+While reading sysctl_ip_fwd_update_priority, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 432e05d32892 ("net: ipv4: Control SKB reprioritization after forwarding")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 3 ++-
+ net/ipv4/ip_forward.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 5ec9bc321566..994bd2e14e55 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -10462,13 +10462,14 @@ static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp)
+ static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
+ {
+ struct net *net = mlxsw_sp_net(mlxsw_sp);
+- bool usp = net->ipv4.sysctl_ip_fwd_update_priority;
+ char rgcr_pl[MLXSW_REG_RGCR_LEN];
+ u64 max_rifs;
++ bool usp;
+
+ if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_RIFS))
+ return -EIO;
+ max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
++ usp = READ_ONCE(net->ipv4.sysctl_ip_fwd_update_priority);
+
+ mlxsw_reg_rgcr_pack(rgcr_pl, true, true);
+ mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, max_rifs);
+diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
+index 92ba3350274b..03bb7c51b618 100644
+--- a/net/ipv4/ip_forward.c
++++ b/net/ipv4/ip_forward.c
+@@ -151,7 +151,7 @@ int ip_forward(struct sk_buff *skb)
+ !skb_sec_path(skb))
+ ip_rt_send_redirect(skb);
+
+- if (net->ipv4.sysctl_ip_fwd_update_priority)
++ if (READ_ONCE(net->ipv4.sysctl_ip_fwd_update_priority))
+ skb->priority = rt_tos2priority(iph->tos);
+
+ return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,
+--
+2.35.1
+
--- /dev/null
+From d751f13df1b6b52737cfb9a617fb8eedb96b7ac9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:53 -0700
+Subject: ip: Fix data-races around sysctl_ip_fwd_use_pmtu.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 60c158dc7b1f0558f6cadd5b50d0386da0000d50 ]
+
+While reading sysctl_ip_fwd_use_pmtu, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: f87c10a8aa1e ("ipv4: introduce ip_dst_mtu_maybe_forward and protect forwarding path against pmtu spoofing")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 2 +-
+ net/ipv4/route.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 26fffda78cca..05fe313f72fa 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -446,7 +446,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
+ struct net *net = dev_net(dst->dev);
+ unsigned int mtu;
+
+- if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
++ if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
+ ip_mtu_locked(dst) ||
+ !forwarding) {
+ mtu = rt->rt_pmtu;
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index ed01063d8f30..8363e575c455 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1397,7 +1397,7 @@ u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr)
+ struct fib_info *fi = res->fi;
+ u32 mtu = 0;
+
+- if (dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu ||
++ if (READ_ONCE(dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu) ||
+ fi->fib_metrics->metrics[RTAX_LOCK - 1] & (1 << RTAX_MTU))
+ mtu = fi->fib_mtu;
+
+--
+2.35.1
+
--- /dev/null
+From bfaef3475afe611117963912146b1afae2291e9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:52 -0700
+Subject: ip: Fix data-races around sysctl_ip_no_pmtu_disc.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 0968d2a441bf6afb551fd99e60fa65ed67068963 ]
+
+While reading sysctl_ip_no_pmtu_disc, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/af_inet.c | 2 +-
+ net/ipv4/icmp.c | 2 +-
+ net/ipv6/af_inet6.c | 2 +-
+ net/xfrm/xfrm_state.c | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 98bc180563d1..8c0a22a5b36c 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -335,7 +335,7 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
+ inet->hdrincl = 1;
+ }
+
+- if (net->ipv4.sysctl_ip_no_pmtu_disc)
++ if (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc))
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ inet->pmtudisc = IP_PMTUDISC_WANT;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index c13ceda9ce5d..d8cfa6241c04 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -878,7 +878,7 @@ static bool icmp_unreach(struct sk_buff *skb)
+ * values please see
+ * Documentation/networking/ip-sysctl.rst
+ */
+- switch (net->ipv4.sysctl_ip_no_pmtu_disc) {
++ switch (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc)) {
+ default:
+ net_dbg_ratelimited("%pI4: fragmentation needed and DF set\n",
+ &iph->daddr);
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 7d7b7523d126..ef1e6545d869 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -226,7 +226,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
+ RCU_INIT_POINTER(inet->mc_list, NULL);
+ inet->rcv_tos = 0;
+
+- if (net->ipv4.sysctl_ip_no_pmtu_disc)
++ if (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc))
+ inet->pmtudisc = IP_PMTUDISC_DONT;
+ else
+ inet->pmtudisc = IP_PMTUDISC_WANT;
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index b749935152ba..b4ce16a934a2 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2620,7 +2620,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
+ int err;
+
+ if (family == AF_INET &&
+- xs_net(x)->ipv4.sysctl_ip_no_pmtu_disc)
++ READ_ONCE(xs_net(x)->ipv4.sysctl_ip_no_pmtu_disc))
+ x->props.flags |= XFRM_STATE_NOPMTUDISC;
+
+ err = -EPROTONOSUPPORT;
+--
+2.35.1
+
--- /dev/null
+From 94faea13460d82bb34ade1222ea70b87b866b1bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:55 -0700
+Subject: ip: Fix data-races around sysctl_ip_nonlocal_bind.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 289d3b21fb0bfc94c4e98f10635bba1824e5f83c ]
+
+While reading sysctl_ip_nonlocal_bind, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_sock.h | 2 +-
+ net/sctp/protocol.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index 48e4c59d85e2..2f6b715acc15 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -373,7 +373,7 @@ static inline bool inet_get_convert_csum(struct sock *sk)
+ static inline bool inet_can_nonlocal_bind(struct net *net,
+ struct inet_sock *inet)
+ {
+- return net->ipv4.sysctl_ip_nonlocal_bind ||
++ return READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind) ||
+ inet->freebind || inet->transparent;
+ }
+
+diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
+index 35928fefae33..1a094b087d88 100644
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -358,7 +358,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
+ if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
+ ret != RTN_LOCAL &&
+ !sp->inet.freebind &&
+- !net->ipv4.sysctl_ip_nonlocal_bind)
++ !READ_ONCE(net->ipv4.sysctl_ip_nonlocal_bind))
+ return 0;
+
+ if (ipv6_only_sock(sctp_opt2sk(sp)))
+--
+2.35.1
+
--- /dev/null
+From fb7af1483fcff57091e4b7b0523db29fb4788f7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:42 -0700
+Subject: ip: Fix data-races around sysctl_ip_prot_sock.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 9b55c20f83369dd54541d9ddbe3a018a8377f451 ]
+
+sysctl_ip_prot_sock is accessed concurrently, and there is always a chance
+of data-race. So, all readers and writers need some basic protection to
+avoid load/store-tearing.
+
+Fixes: 4548b683b781 ("Introduce a sysctl that modifies the value of PROT_SOCK.")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 2 +-
+ net/ipv4/sysctl_net_ipv4.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 4a15b6bcb4b8..1c979fd1904c 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -357,7 +357,7 @@ static inline bool sysctl_dev_name_is_allowed(const char *name)
+
+ static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port)
+ {
+- return port < net->ipv4.sysctl_ip_prot_sock;
++ return port < READ_ONCE(net->ipv4.sysctl_ip_prot_sock);
+ }
+
+ #else
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 6b718688865e..344cdcd5a7d5 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -88,7 +88,7 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
+ * port limit.
+ */
+ if ((range[1] < range[0]) ||
+- (range[0] < net->ipv4.sysctl_ip_prot_sock))
++ (range[0] < READ_ONCE(net->ipv4.sysctl_ip_prot_sock)))
+ ret = -EINVAL;
+ else
+ set_local_port_range(net, range);
+@@ -114,7 +114,7 @@ static int ipv4_privileged_ports(struct ctl_table *table, int write,
+ .extra2 = &ip_privileged_port_max,
+ };
+
+- pports = net->ipv4.sysctl_ip_prot_sock;
++ pports = READ_ONCE(net->ipv4.sysctl_ip_prot_sock);
+
+ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+@@ -126,7 +126,7 @@ static int ipv4_privileged_ports(struct ctl_table *table, int write,
+ if (range[0] < pports)
+ ret = -EINVAL;
+ else
+- net->ipv4.sysctl_ip_prot_sock = pports;
++ WRITE_ONCE(net->ipv4.sysctl_ip_prot_sock, pports);
+ }
+
+ return ret;
+--
+2.35.1
+
--- /dev/null
+From 630d2f8f9f50e8f3d3a1c9af9706017528dad868 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:39 -0700
+Subject: ipv4: Fix a data-race around sysctl_fib_multipath_use_neigh.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 87507bcb4f5de16bb419e9509d874f4db6c0ad0f ]
+
+While reading sysctl_fib_multipath_use_neigh, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: a6db4494d218 ("net: ipv4: Consider failed nexthops in multipath routes")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/fib_semantics.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index 720f65f7bd0b..9f5c1c26c8f2 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -2216,7 +2216,7 @@ void fib_select_multipath(struct fib_result *res, int hash)
+ }
+
+ change_nexthops(fi) {
+- if (net->ipv4.sysctl_fib_multipath_use_neigh) {
++ if (READ_ONCE(net->ipv4.sysctl_fib_multipath_use_neigh)) {
+ if (!fib_good_nh(nexthop_nh))
+ continue;
+ if (!first) {
+--
+2.35.1
+
--- /dev/null
+From 9ea1e5b9df11186418e0d41c8235c810e91beef4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:40 -0700
+Subject: ipv4: Fix data-races around sysctl_fib_multipath_hash_policy.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 7998c12a08c97cc26660532c9f90a34bd7d8da5a ]
+
+While reading sysctl_fib_multipath_hash_policy, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: bf4e0a3db97e ("net: ipv4: add support for ECMP hash policy choice")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +-
+ net/ipv4/route.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 994bd2e14e55..6bcb0f1b0816 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -10263,7 +10263,7 @@ static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp,
+ unsigned long *fields = config->fields;
+ u32 hash_fields;
+
+- switch (net->ipv4.sysctl_fib_multipath_hash_policy) {
++ switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) {
+ case 0:
+ mlxsw_sp_mp4_hash_outer_addr(config);
+ break;
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 8363e575c455..907cb11cbea5 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2047,7 +2047,7 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
+ struct flow_keys hash_keys;
+ u32 mhash = 0;
+
+- switch (net->ipv4.sysctl_fib_multipath_hash_policy) {
++ switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) {
+ case 0:
+ memset(&hash_keys, 0, sizeof(hash_keys));
+ hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+--
+2.35.1
+
--- /dev/null
+From 3a93a3cdc8a6cddad5a05df14c5e7fe4d12d5d4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:41 -0700
+Subject: ipv4: Fix data-races around sysctl_fib_multipath_hash_fields.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 8895a9c2ac76fb9d3922fed4fe092c8ec5e5cccc ]
+
+While reading sysctl_fib_multipath_hash_fields, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: ce5c9c20d364 ("ipv4: Add a sysctl to control multipath hash fields")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +-
+ net/ipv4/route.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 6bcb0f1b0816..c00d6c4ed37c 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -10281,7 +10281,7 @@ static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp,
+ mlxsw_sp_mp_hash_inner_l3(config);
+ break;
+ case 3:
+- hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ /* Outer */
+ MLXSW_SP_MP_HASH_HEADER_SET(headers, IPV4_EN_NOT_TCP_NOT_UDP);
+ MLXSW_SP_MP_HASH_HEADER_SET(headers, IPV4_EN_TCP_UDP);
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 907cb11cbea5..02a0a397a2f3 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1928,7 +1928,7 @@ static u32 fib_multipath_custom_hash_outer(const struct net *net,
+ const struct sk_buff *skb,
+ bool *p_has_inner)
+ {
+- u32 hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ u32 hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ struct flow_keys keys, hash_keys;
+
+ if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_OUTER_MASK))
+@@ -1957,7 +1957,7 @@ static u32 fib_multipath_custom_hash_inner(const struct net *net,
+ const struct sk_buff *skb,
+ bool has_inner)
+ {
+- u32 hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ u32 hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ struct flow_keys keys, hash_keys;
+
+ /* We assume the packet carries an encapsulation, but if none was
+@@ -2017,7 +2017,7 @@ static u32 fib_multipath_custom_hash_skb(const struct net *net,
+ static u32 fib_multipath_custom_hash_fl4(const struct net *net,
+ const struct flowi4 *fl4)
+ {
+- u32 hash_fields = net->ipv4.sysctl_fib_multipath_hash_fields;
++ u32 hash_fields = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_fields);
+ struct flow_keys hash_keys;
+
+ if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_OUTER_MASK))
+--
+2.35.1
+
--- /dev/null
+From 783ffb515bba414fcd6ad869ce1f6b8089f9d89a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 14:44:56 -0700
+Subject: ixgbe: Add locking to prevent panic when setting sriov_numvfs to zero
+
+From: Piotr Skajewski <piotrx.skajewski@intel.com>
+
+[ Upstream commit 1e53834ce541d4fe271cdcca7703e50be0a44f8a ]
+
+It is possible to disable VFs while the PF driver is processing requests
+from the VF driver. This can result in a panic.
+
+BUG: unable to handle kernel paging request at 000000000000106c
+PGD 0 P4D 0
+Oops: 0000 [#1] SMP NOPTI
+CPU: 8 PID: 0 Comm: swapper/8 Kdump: loaded Tainted: G I --------- -
+Hardware name: Dell Inc. PowerEdge R740/06WXJT, BIOS 2.8.2 08/27/2020
+RIP: 0010:ixgbe_msg_task+0x4c8/0x1690 [ixgbe]
+Code: 00 00 48 8d 04 40 48 c1 e0 05 89 7c 24 24 89 fd 48 89 44 24 10 83 ff
+01 0f 84 b8 04 00 00 4c 8b 64 24 10 4d 03 a5 48 22 00 00 <41> 80 7c 24 4c
+00 0f 84 8a 03 00 00 0f b7 c7 83 f8 08 0f 84 8f 0a
+RSP: 0018:ffffb337869f8df8 EFLAGS: 00010002
+RAX: 0000000000001020 RBX: 0000000000000000 RCX: 000000000000002b
+RDX: 0000000000000002 RSI: 0000000000000008 RDI: 0000000000000006
+RBP: 0000000000000006 R08: 0000000000000002 R09: 0000000000029780
+R10: 00006957d8f42832 R11: 0000000000000000 R12: 0000000000001020
+R13: ffff8a00e8978ac0 R14: 000000000000002b R15: ffff8a00e8979c80
+FS: 0000000000000000(0000) GS:ffff8a07dfd00000(0000) knlGS:00000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000000106c CR3: 0000000063e10004 CR4: 00000000007726e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <IRQ>
+ ? ttwu_do_wakeup+0x19/0x140
+ ? try_to_wake_up+0x1cd/0x550
+ ? ixgbevf_update_xcast_mode+0x71/0xc0 [ixgbevf]
+ ixgbe_msix_other+0x17e/0x310 [ixgbe]
+ __handle_irq_event_percpu+0x40/0x180
+ handle_irq_event_percpu+0x30/0x80
+ handle_irq_event+0x36/0x53
+ handle_edge_irq+0x82/0x190
+ handle_irq+0x1c/0x30
+ do_IRQ+0x49/0xd0
+ common_interrupt+0xf/0xf
+
+This can be eventually be reproduced with the following script:
+
+while :
+do
+ echo 63 > /sys/class/net/<devname>/device/sriov_numvfs
+ sleep 1
+ echo 0 > /sys/class/net/<devname>/device/sriov_numvfs
+ sleep 1
+done
+
+Add lock when disabling SR-IOV to prevent process VF mailbox communication.
+
+Fixes: d773d1310625 ("ixgbe: Fix memory leak when SR-IOV VFs are direct assigned")
+Signed-off-by: Piotr Skajewski <piotrx.skajewski@intel.com>
+Tested-by: Marek Szlosek <marek.szlosek@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://lore.kernel.org/r/20220715214456.2968711-1-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 +
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++
+ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 6 ++++++
+ 3 files changed, 10 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+index 921a4d977d65..8813b4dd6872 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+@@ -779,6 +779,7 @@ struct ixgbe_adapter {
+ #ifdef CONFIG_IXGBE_IPSEC
+ struct ixgbe_ipsec *ipsec;
+ #endif /* CONFIG_IXGBE_IPSEC */
++ spinlock_t vfs_lock;
+ };
+
+ static inline int ixgbe_determine_xdp_q_idx(int cpu)
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+index c4a4954aa317..6c403f112d29 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -6402,6 +6402,9 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
+ /* n-tuple support exists, always init our spinlock */
+ spin_lock_init(&adapter->fdir_perfect_lock);
+
++ /* init spinlock to avoid concurrency of VF resources */
++ spin_lock_init(&adapter->vfs_lock);
++
+ #ifdef CONFIG_IXGBE_DCB
+ ixgbe_init_dcb(adapter);
+ #endif
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+index d4e63f0644c3..a1e69c734863 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+@@ -205,10 +205,13 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs)
+ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
+ {
+ unsigned int num_vfs = adapter->num_vfs, vf;
++ unsigned long flags;
+ int rss;
+
++ spin_lock_irqsave(&adapter->vfs_lock, flags);
+ /* set num VFs to 0 to prevent access to vfinfo */
+ adapter->num_vfs = 0;
++ spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+
+ /* put the reference to all of the vf devices */
+ for (vf = 0; vf < num_vfs; ++vf) {
+@@ -1355,8 +1358,10 @@ static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)
+ void ixgbe_msg_task(struct ixgbe_adapter *adapter)
+ {
+ struct ixgbe_hw *hw = &adapter->hw;
++ unsigned long flags;
+ u32 vf;
+
++ spin_lock_irqsave(&adapter->vfs_lock, flags);
+ for (vf = 0; vf < adapter->num_vfs; vf++) {
+ /* process any reset requests */
+ if (!ixgbe_check_for_rst(hw, vf))
+@@ -1370,6 +1375,7 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter)
+ if (!ixgbe_check_for_ack(hw, vf))
+ ixgbe_rcv_ack_from_vf(adapter, vf);
+ }
++ spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+ }
+
+ static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf)
+--
+2.35.1
+
--- /dev/null
+From 2699b1909387b268cbabb71ae4f359a539613c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 18:16:58 +0300
+Subject: net: dsa: fix dsa_port_vlan_filtering when global
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 4db2a5ef4ccbe6d138828284cfab241b434b5d95 ]
+
+The blamed refactoring commit changed a "port" iterator with "other_dp",
+but still looked at the slave_dev of the dp outside the loop, instead of
+other_dp->slave from the loop.
+
+As a result, dsa_port_vlan_filtering() would not call
+dsa_slave_manage_vlan_filtering() except for the port in cause, and not
+for all switch ports as expected.
+
+Fixes: d0004a020bb5 ("net: dsa: remove the "dsa_to_port in a loop" antipattern from the core")
+Reported-by: Lucian Banu <Lucian.Banu@westermo.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/port.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/dsa/port.c b/net/dsa/port.c
+index bdccb613285d..4b72513cc9e4 100644
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -752,7 +752,7 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
+ ds->vlan_filtering = vlan_filtering;
+
+ dsa_switch_for_each_user_port(other_dp, ds) {
+- struct net_device *slave = dp->slave;
++ struct net_device *slave = other_dp->slave;
+
+ /* We might be called in the unbind path, so not
+ * all slave devices might still be registered.
+--
+2.35.1
+
--- /dev/null
+From a65e9e13c2b00d9f6f16c5a2af32b99c52280129 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 18:16:59 +0300
+Subject: net: dsa: fix NULL pointer dereference in
+ dsa_port_reset_vlan_filtering
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 1699b4d502eda3c7ea4070debad3ee570b5091b1 ]
+
+The "ds" iterator variable used in dsa_port_reset_vlan_filtering() ->
+dsa_switch_for_each_port() overwrites the "dp" received as argument,
+which is later used to call dsa_port_vlan_filtering() proper.
+
+As a result, switches which do enter that code path (the ones with
+vlan_filtering_is_global=true) will dereference an invalid dp in
+dsa_port_reset_vlan_filtering() after leaving a VLAN-aware bridge.
+
+Use a dedicated "other_dp" iterator variable to avoid this from
+happening.
+
+Fixes: d0004a020bb5 ("net: dsa: remove the "dsa_to_port in a loop" antipattern from the core")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/port.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/dsa/port.c b/net/dsa/port.c
+index 6aab5768ef96..7bc79e28d48e 100644
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -248,6 +248,7 @@ static void dsa_port_reset_vlan_filtering(struct dsa_port *dp,
+ struct netlink_ext_ack extack = {0};
+ bool change_vlan_filtering = false;
+ struct dsa_switch *ds = dp->ds;
++ struct dsa_port *other_dp;
+ bool vlan_filtering;
+ int err;
+
+@@ -270,8 +271,8 @@ static void dsa_port_reset_vlan_filtering(struct dsa_port *dp,
+ * VLAN-aware bridge.
+ */
+ if (change_vlan_filtering && ds->vlan_filtering_is_global) {
+- dsa_switch_for_each_port(dp, ds) {
+- struct net_device *br = dsa_port_bridge_dev_get(dp);
++ dsa_switch_for_each_port(other_dp, ds) {
++ struct net_device *br = dsa_port_bridge_dev_get(other_dp);
+
+ if (br && br_vlan_enabled(br)) {
+ change_vlan_filtering = false;
+--
+2.35.1
+
--- /dev/null
+From 90db07204bba1bc7be0cfef504e0f70c3d61dbd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 23:31:38 +0800
+Subject: net: dsa: microchip: ksz_common: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit a14bd7475452c51835dd5a0cee4c8fa48dd0b539 ]
+
+In ksz_switch_register(), we should call of_node_put() for the
+reference returned by of_get_child_by_name() which has increased
+the refcount.
+
+Fixes: 912aae27c6af ("net: dsa: microchip: really look for phy-mode in port nodes")
+Signed-off-by: Liang He <windhl@126.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20220714153138.375919-1-windhl@126.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/microchip/ksz_common.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
+index 8014b18d9391..aa0bcf01e20a 100644
+--- a/drivers/net/dsa/microchip/ksz_common.c
++++ b/drivers/net/dsa/microchip/ksz_common.c
+@@ -447,18 +447,21 @@ int ksz_switch_register(struct ksz_device *dev,
+ ports = of_get_child_by_name(dev->dev->of_node, "ethernet-ports");
+ if (!ports)
+ ports = of_get_child_by_name(dev->dev->of_node, "ports");
+- if (ports)
++ if (ports) {
+ for_each_available_child_of_node(ports, port) {
+ if (of_property_read_u32(port, "reg",
+ &port_num))
+ continue;
+ if (!(dev->port_mask & BIT(port_num))) {
+ of_node_put(port);
++ of_node_put(ports);
+ return -EINVAL;
+ }
+ of_get_phy_mode(port,
+ &dev->ports[port_num].interface);
+ }
++ of_node_put(ports);
++ }
+ dev->synclko_125 = of_property_read_bool(dev->dev->of_node,
+ "microchip,synclko-125");
+ dev->synclko_disable = of_property_read_bool(dev->dev->of_node,
+--
+2.35.1
+
--- /dev/null
+From dfda14d3714a46544c813cab3f566fb54eb42c8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 18:46:21 +0300
+Subject: net: dsa: move reset of VLAN filtering to
+ dsa_port_switchdev_unsync_attrs
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 8e9e678e4758b69b6231d3ad4d26d3381fdb5f3f ]
+
+In dsa_port_switchdev_unsync_attrs() there is a comment that resetting
+the VLAN filtering isn't done where it is expected. And since commit
+108dc8741c20 ("net: dsa: Avoid cross-chip syncing of VLAN filtering"),
+there is no reason to handle this in switch.c either.
+
+Therefore, move the logic to port.c, and adapt it slightly to the data
+structures and naming conventions from there.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/port.c | 60 +++++++++++++++++++++++++++++++++++++++++++++---
+ net/dsa/switch.c | 58 ----------------------------------------------
+ 2 files changed, 57 insertions(+), 61 deletions(-)
+
+diff --git a/net/dsa/port.c b/net/dsa/port.c
+index 4b72513cc9e4..6aab5768ef96 100644
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -242,6 +242,59 @@ void dsa_port_disable(struct dsa_port *dp)
+ rtnl_unlock();
+ }
+
++static void dsa_port_reset_vlan_filtering(struct dsa_port *dp,
++ struct dsa_bridge bridge)
++{
++ struct netlink_ext_ack extack = {0};
++ bool change_vlan_filtering = false;
++ struct dsa_switch *ds = dp->ds;
++ bool vlan_filtering;
++ int err;
++
++ if (ds->needs_standalone_vlan_filtering &&
++ !br_vlan_enabled(bridge.dev)) {
++ change_vlan_filtering = true;
++ vlan_filtering = true;
++ } else if (!ds->needs_standalone_vlan_filtering &&
++ br_vlan_enabled(bridge.dev)) {
++ change_vlan_filtering = true;
++ vlan_filtering = false;
++ }
++
++ /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
++ * event for changing vlan_filtering setting upon slave ports leaving
++ * it. That is a good thing, because that lets us handle it and also
++ * handle the case where the switch's vlan_filtering setting is global
++ * (not per port). When that happens, the correct moment to trigger the
++ * vlan_filtering callback is only when the last port leaves the last
++ * VLAN-aware bridge.
++ */
++ if (change_vlan_filtering && ds->vlan_filtering_is_global) {
++ dsa_switch_for_each_port(dp, ds) {
++ struct net_device *br = dsa_port_bridge_dev_get(dp);
++
++ if (br && br_vlan_enabled(br)) {
++ change_vlan_filtering = false;
++ break;
++ }
++ }
++ }
++
++ if (!change_vlan_filtering)
++ return;
++
++ err = dsa_port_vlan_filtering(dp, vlan_filtering, &extack);
++ if (extack._msg) {
++ dev_err(ds->dev, "port %d: %s\n", dp->index,
++ extack._msg);
++ }
++ if (err && err != -EOPNOTSUPP) {
++ dev_err(ds->dev,
++ "port %d failed to reset VLAN filtering to %d: %pe\n",
++ dp->index, vlan_filtering, ERR_PTR(err));
++ }
++}
++
+ static int dsa_port_inherit_brport_flags(struct dsa_port *dp,
+ struct netlink_ext_ack *extack)
+ {
+@@ -313,7 +366,8 @@ static int dsa_port_switchdev_sync_attrs(struct dsa_port *dp,
+ return 0;
+ }
+
+-static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp)
++static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp,
++ struct dsa_bridge bridge)
+ {
+ /* Configure the port for standalone mode (no address learning,
+ * flood everything).
+@@ -333,7 +387,7 @@ static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp)
+ */
+ dsa_port_set_state_now(dp, BR_STATE_FORWARDING, true);
+
+- /* VLAN filtering is handled by dsa_switch_bridge_leave */
++ dsa_port_reset_vlan_filtering(dp, bridge);
+
+ /* Ageing time may be global to the switch chip, so don't change it
+ * here because we have no good reason (or value) to change it to.
+@@ -502,7 +556,7 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
+ "port %d failed to notify DSA_NOTIFIER_BRIDGE_LEAVE: %pe\n",
+ dp->index, ERR_PTR(err));
+
+- dsa_port_switchdev_unsync_attrs(dp);
++ dsa_port_switchdev_unsync_attrs(dp, info.bridge);
+ }
+
+ int dsa_port_lag_change(struct dsa_port *dp,
+diff --git a/net/dsa/switch.c b/net/dsa/switch.c
+index d25cd1da3eb3..d8a80cf9742c 100644
+--- a/net/dsa/switch.c
++++ b/net/dsa/switch.c
+@@ -115,62 +115,10 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds,
+ return 0;
+ }
+
+-static int dsa_switch_sync_vlan_filtering(struct dsa_switch *ds,
+- struct dsa_notifier_bridge_info *info)
+-{
+- struct netlink_ext_ack extack = {0};
+- bool change_vlan_filtering = false;
+- bool vlan_filtering;
+- struct dsa_port *dp;
+- int err;
+-
+- if (ds->needs_standalone_vlan_filtering &&
+- !br_vlan_enabled(info->bridge.dev)) {
+- change_vlan_filtering = true;
+- vlan_filtering = true;
+- } else if (!ds->needs_standalone_vlan_filtering &&
+- br_vlan_enabled(info->bridge.dev)) {
+- change_vlan_filtering = true;
+- vlan_filtering = false;
+- }
+-
+- /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
+- * event for changing vlan_filtering setting upon slave ports leaving
+- * it. That is a good thing, because that lets us handle it and also
+- * handle the case where the switch's vlan_filtering setting is global
+- * (not per port). When that happens, the correct moment to trigger the
+- * vlan_filtering callback is only when the last port leaves the last
+- * VLAN-aware bridge.
+- */
+- if (change_vlan_filtering && ds->vlan_filtering_is_global) {
+- dsa_switch_for_each_port(dp, ds) {
+- struct net_device *br = dsa_port_bridge_dev_get(dp);
+-
+- if (br && br_vlan_enabled(br)) {
+- change_vlan_filtering = false;
+- break;
+- }
+- }
+- }
+-
+- if (change_vlan_filtering) {
+- err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
+- vlan_filtering, &extack);
+- if (extack._msg)
+- dev_err(ds->dev, "port %d: %s\n", info->port,
+- extack._msg);
+- if (err && err != -EOPNOTSUPP)
+- return err;
+- }
+-
+- return 0;
+-}
+-
+ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
+ struct dsa_notifier_bridge_info *info)
+ {
+ struct dsa_switch_tree *dst = ds->dst;
+- int err;
+
+ if (dst->index == info->tree_index && ds->index == info->sw_index &&
+ ds->ops->port_bridge_leave)
+@@ -182,12 +130,6 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
+ info->sw_index, info->port,
+ info->bridge);
+
+- if (ds->dst->index == info->tree_index && ds->index == info->sw_index) {
+- err = dsa_switch_sync_vlan_filtering(ds, info);
+- if (err)
+- return err;
+- }
+-
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 90d3203d9b48d2cbd003e290d5a213f32afb2ea6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 15:58:30 +0200
+Subject: net: dsa: sja1105: silent spi_device_id warnings
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 855fe49984a8a3899f07ae1d149d46cd8d4acb52 ]
+
+Add spi_device_id entries to silent following warnings:
+ SPI driver sja1105 has no spi_device_id for nxp,sja1105e
+ SPI driver sja1105 has no spi_device_id for nxp,sja1105t
+ SPI driver sja1105 has no spi_device_id for nxp,sja1105p
+ SPI driver sja1105 has no spi_device_id for nxp,sja1105q
+ SPI driver sja1105 has no spi_device_id for nxp,sja1105r
+ SPI driver sja1105 has no spi_device_id for nxp,sja1105s
+ SPI driver sja1105 has no spi_device_id for nxp,sja1110a
+ SPI driver sja1105 has no spi_device_id for nxp,sja1110b
+ SPI driver sja1105 has no spi_device_id for nxp,sja1110c
+ SPI driver sja1105 has no spi_device_id for nxp,sja1110d
+
+Fixes: 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible")
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20220717135831.2492844-1-o.rempel@pengutronix.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/sja1105/sja1105_main.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index b33841c6507a..7734c6b1baca 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -3383,12 +3383,28 @@ static const struct of_device_id sja1105_dt_ids[] = {
+ };
+ MODULE_DEVICE_TABLE(of, sja1105_dt_ids);
+
++static const struct spi_device_id sja1105_spi_ids[] = {
++ { "sja1105e" },
++ { "sja1105t" },
++ { "sja1105p" },
++ { "sja1105q" },
++ { "sja1105r" },
++ { "sja1105s" },
++ { "sja1110a" },
++ { "sja1110b" },
++ { "sja1110c" },
++ { "sja1110d" },
++ { },
++};
++MODULE_DEVICE_TABLE(spi, sja1105_spi_ids);
++
+ static struct spi_driver sja1105_driver = {
+ .driver = {
+ .name = "sja1105",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(sja1105_dt_ids),
+ },
++ .id_table = sja1105_spi_ids,
+ .probe = sja1105_probe,
+ .remove = sja1105_remove,
+ .shutdown = sja1105_shutdown,
+--
+2.35.1
+
--- /dev/null
+From 955afa5e1b2ba43fbc24031cbae3205afcb47acb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 15:58:31 +0200
+Subject: net: dsa: vitesse-vsc73xx: silent spi_device_id warnings
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 1774559f07993e1cac33c2406e99049d4bdea6c8 ]
+
+Add spi_device_id entries to silent SPI warnings.
+
+Fixes: 5fa6863ba692 ("spi: Check we have a spi_device_id for each DT compatible")
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/20220717135831.2492844-2-o.rempel@pengutronix.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/vitesse-vsc73xx-spi.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/net/dsa/vitesse-vsc73xx-spi.c b/drivers/net/dsa/vitesse-vsc73xx-spi.c
+index 3110895358d8..97a92e6da60d 100644
+--- a/drivers/net/dsa/vitesse-vsc73xx-spi.c
++++ b/drivers/net/dsa/vitesse-vsc73xx-spi.c
+@@ -205,10 +205,20 @@ static const struct of_device_id vsc73xx_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, vsc73xx_of_match);
+
++static const struct spi_device_id vsc73xx_spi_ids[] = {
++ { "vsc7385" },
++ { "vsc7388" },
++ { "vsc7395" },
++ { "vsc7398" },
++ { },
++};
++MODULE_DEVICE_TABLE(spi, vsc73xx_spi_ids);
++
+ static struct spi_driver vsc73xx_spi_driver = {
+ .probe = vsc73xx_spi_probe,
+ .remove = vsc73xx_spi_remove,
+ .shutdown = vsc73xx_spi_shutdown,
++ .id_table = vsc73xx_spi_ids,
+ .driver = {
+ .name = "vsc73xx-spi",
+ .of_match_table = vsc73xx_of_match,
+--
+2.35.1
+
--- /dev/null
+From 940d5f465e5a3f89833501af66dc2438c6e68c2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:40:36 +0200
+Subject: net: lan966x: Fix taking rtnl_lock while holding spin_lock
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 45533a534a45cb12c20c81615d17306176cb1c57 ]
+
+When the HW deletes an entry in MAC table then it generates an
+interrupt. The SW will go through it's own list of MAC entries and if it
+is not found then it would notify the listeners about this. The problem
+is that when the SW will go through it's own list it would take a spin
+lock(lan966x->mac_lock) and when it notifies that the entry is deleted.
+But to notify the listeners it taking the rtnl_lock which is illegal.
+
+This is fixed by instead of notifying right away that the entry is
+deleted, move the entry on a temp list and once, it checks all the
+entries then just notify that the entries from temp list are deleted.
+
+Fixes: 5ccd66e01cbe ("net: lan966x: add support for interrupts from analyzer")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/lan966x/lan966x_mac.c | 27 ++++++++++++-------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+index 005e56ea5da1..2d2b83c03796 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+@@ -325,10 +325,13 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ {
+ struct lan966x_mac_entry *mac_entry, *tmp;
+ unsigned char mac[ETH_ALEN] __aligned(2);
++ struct list_head mac_deleted_entries;
+ u32 dest_idx;
+ u32 column;
+ u16 vid;
+
++ INIT_LIST_HEAD(&mac_deleted_entries);
++
+ spin_lock(&lan966x->mac_lock);
+ list_for_each_entry_safe(mac_entry, tmp, &lan966x->mac_entries, list) {
+ bool found = false;
+@@ -362,20 +365,26 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ }
+
+ if (!found) {
+- /* Notify the bridge that the entry doesn't exist
+- * anymore in the HW and remove the entry from the SW
+- * list
+- */
+- lan966x_mac_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
+- mac_entry->mac, mac_entry->vid,
+- lan966x->ports[mac_entry->port_index]->dev);
+-
+ list_del(&mac_entry->list);
+- kfree(mac_entry);
++ /* Move the entry from SW list to a tmp list such that
++ * it would be deleted later
++ */
++ list_add_tail(&mac_entry->list, &mac_deleted_entries);
+ }
+ }
+ spin_unlock(&lan966x->mac_lock);
+
++ list_for_each_entry_safe(mac_entry, tmp, &mac_deleted_entries, list) {
++ /* Notify the bridge that the entry doesn't exist
++ * anymore in the HW
++ */
++ lan966x_mac_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
++ mac_entry->mac, mac_entry->vid,
++ lan966x->ports[mac_entry->port_index]->dev);
++ list_del(&mac_entry->list);
++ kfree(mac_entry);
++ }
++
+ /* Now go to the list of columns and see if any entry was not in the SW
+ * list, then that means that the entry is new so it needs to notify the
+ * bridge.
+--
+2.35.1
+
--- /dev/null
+From 01f94fe4a75a85db3c9102a24db15c6f1eb60182 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:40:39 +0200
+Subject: net: lan966x: Fix usage of lan966x->mac_lock inside
+ lan966x_mac_irq_handler
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit c1924684369762b112428a333ad00eac6ca89d96 ]
+
+The problem with this spin lock is that it was just protecting the list
+of the MAC entries in SW and not also the access to the MAC entries in HW.
+Because the access to HW is indirect, then it could happen to have race
+conditions.
+For example when SW introduced an entry in MAC table and the irq mac is
+trying to read something from the MAC.
+Update such that also the access to MAC entries in HW is protected by
+this lock.
+
+Fixes: 5ccd66e01cbef ("net: lan966x: add support for interrupts from analyzer")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/lan966x/lan966x_mac.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+index d0b8eba0a66d..69e343b7f4af 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+@@ -183,7 +183,7 @@ static struct lan966x_mac_entry *lan966x_mac_alloc_entry(const unsigned char *ma
+ {
+ struct lan966x_mac_entry *mac_entry;
+
+- mac_entry = kzalloc(sizeof(*mac_entry), GFP_KERNEL);
++ mac_entry = kzalloc(sizeof(*mac_entry), GFP_ATOMIC);
+ if (!mac_entry)
+ return NULL;
+
+@@ -310,8 +310,8 @@ void lan966x_mac_purge_entries(struct lan966x *lan966x)
+ spin_lock(&lan966x->mac_lock);
+ list_for_each_entry_safe(mac_entry, tmp, &lan966x->mac_entries,
+ list) {
+- lan966x_mac_forget(lan966x, mac_entry->mac, mac_entry->vid,
+- ENTRYTYPE_LOCKED);
++ lan966x_mac_forget_locked(lan966x, mac_entry->mac,
++ mac_entry->vid, ENTRYTYPE_LOCKED);
+
+ list_del(&mac_entry->list);
+ kfree(mac_entry);
+@@ -427,13 +427,14 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ if (WARN_ON(dest_idx >= lan966x->num_phys_ports))
+ continue;
+
++ spin_lock(&lan966x->mac_lock);
+ mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx);
+- if (!mac_entry)
++ if (!mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
+ return;
++ }
+
+ mac_entry->row = row;
+-
+- spin_lock(&lan966x->mac_lock);
+ list_add_tail(&mac_entry->list, &lan966x->mac_entries);
+ spin_unlock(&lan966x->mac_lock);
+
+@@ -455,6 +456,7 @@ irqreturn_t lan966x_mac_irq_handler(struct lan966x *lan966x)
+ lan966x, ANA_MACTINDX);
+
+ while (1) {
++ spin_lock(&lan966x->mac_lock);
+ lan_rmw(ANA_MACACCESS_MAC_TABLE_CMD_SET(MACACCESS_CMD_SYNC_GET_NEXT),
+ ANA_MACACCESS_MAC_TABLE_CMD,
+ lan966x, ANA_MACACCESS);
+@@ -478,12 +480,15 @@ irqreturn_t lan966x_mac_irq_handler(struct lan966x *lan966x)
+ stop = false;
+
+ if (column == LAN966X_MAC_COLUMNS - 1 &&
+- index == 0 && stop)
++ index == 0 && stop) {
++ spin_unlock(&lan966x->mac_lock);
+ break;
++ }
+
+ entry[column].mach = lan_rd(lan966x, ANA_MACHDATA);
+ entry[column].macl = lan_rd(lan966x, ANA_MACLDATA);
+ entry[column].maca = lan_rd(lan966x, ANA_MACACCESS);
++ spin_unlock(&lan966x->mac_lock);
+
+ /* Once all the columns are read process them */
+ if (column == LAN966X_MAC_COLUMNS - 1) {
+--
+2.35.1
+
--- /dev/null
+From cdfc8ff376b28adb614f4c626b7636146eeb7263 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:40:37 +0200
+Subject: net: lan966x: Fix usage of lan966x->mac_lock when entry is added
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 43243bb3195b0dc27741679471e23baed1efe98e ]
+
+To add an entry to the MAC table, it is required first to setup the
+entry and then issue a command for the MAC to learn the entry.
+So if it happens for two threads to add simultaneously an entry in MAC
+table then it would be a race condition.
+Fix this by using lan966x->mac_lock to protect the HW access.
+
+Fixes: fc0c3fe7486f2 ("net: lan966x: Add function lan966x_mac_ip_learn()")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan966x/lan966x_mac.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+index 2d2b83c03796..4f8fd5cde950 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+@@ -75,6 +75,9 @@ static int __lan966x_mac_learn(struct lan966x *lan966x, int pgid,
+ unsigned int vid,
+ enum macaccess_entry_type type)
+ {
++ int ret;
++
++ spin_lock(&lan966x->mac_lock);
+ lan966x_mac_select(lan966x, mac, vid);
+
+ /* Issue a write command */
+@@ -86,7 +89,10 @@ static int __lan966x_mac_learn(struct lan966x *lan966x, int pgid,
+ ANA_MACACCESS_MAC_TABLE_CMD_SET(MACACCESS_CMD_LEARN),
+ lan966x, ANA_MACACCESS);
+
+- return lan966x_mac_wait_for_completion(lan966x);
++ ret = lan966x_mac_wait_for_completion(lan966x);
++ spin_unlock(&lan966x->mac_lock);
++
++ return ret;
+ }
+
+ /* The mask of the front ports is encoded inside the mac parameter via a call
+--
+2.35.1
+
--- /dev/null
+From 8f9371365506afcae7e15388edee24b7eec71c53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:40:38 +0200
+Subject: net: lan966x: Fix usage of lan966x->mac_lock when entry is removed
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 99343cfa4f7560abf933fff7ab3ea58a6905c917 ]
+
+To remove an entry to the MAC table, it is required first to setup the
+entry and then issue a command for the MAC to forget the entry.
+So if it happens for two threads to remove simultaneously an entry
+in MAC table then it would be a race condition.
+Fix this by using lan966x->mac_lock to protect the HW access.
+
+Fixes: e18aba8941b40 ("net: lan966x: add mactable support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/lan966x/lan966x_mac.c | 24 +++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+index 4f8fd5cde950..d0b8eba0a66d 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+@@ -119,11 +119,13 @@ int lan966x_mac_learn(struct lan966x *lan966x, int port,
+ return __lan966x_mac_learn(lan966x, port, false, mac, vid, type);
+ }
+
+-int lan966x_mac_forget(struct lan966x *lan966x,
+- const unsigned char mac[ETH_ALEN],
+- unsigned int vid,
+- enum macaccess_entry_type type)
++static int lan966x_mac_forget_locked(struct lan966x *lan966x,
++ const unsigned char mac[ETH_ALEN],
++ unsigned int vid,
++ enum macaccess_entry_type type)
+ {
++ lockdep_assert_held(&lan966x->mac_lock);
++
+ lan966x_mac_select(lan966x, mac, vid);
+
+ /* Issue a forget command */
+@@ -134,6 +136,20 @@ int lan966x_mac_forget(struct lan966x *lan966x,
+ return lan966x_mac_wait_for_completion(lan966x);
+ }
+
++int lan966x_mac_forget(struct lan966x *lan966x,
++ const unsigned char mac[ETH_ALEN],
++ unsigned int vid,
++ enum macaccess_entry_type type)
++{
++ int ret;
++
++ spin_lock(&lan966x->mac_lock);
++ ret = lan966x_mac_forget_locked(lan966x, mac, vid, type);
++ spin_unlock(&lan966x->mac_lock);
++
++ return ret;
++}
++
+ int lan966x_mac_cpu_learn(struct lan966x *lan966x, const char *addr, u16 vid)
+ {
+ return lan966x_mac_learn(lan966x, PGID_CPU, addr, vid, ENTRYTYPE_LOCKED);
+--
+2.35.1
+
--- /dev/null
+From a7bac1cd72d5fb104869d7dd24d13dc7d62dcc33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:40:40 +0200
+Subject: net: lan966x: Fix usage of lan966x->mac_lock when used by FDB
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 675c807ae26b267233b97cd5006979a6bb8d54d4 ]
+
+When the SW bridge was trying to add/remove entries to/from HW, the
+access to HW was not protected by any lock. In this way, it was
+possible to have race conditions.
+Fix this by using the lan966x->mac_lock to protect parallel access to HW
+for this cases.
+
+Fixes: 25ee9561ec622 ("net: lan966x: More MAC table functionality")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/lan966x/lan966x_mac.c | 34 +++++++++++++------
+ 1 file changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+index 69e343b7f4af..5893770bfd94 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
+@@ -201,7 +201,6 @@ static struct lan966x_mac_entry *lan966x_mac_find_entry(struct lan966x *lan966x,
+ struct lan966x_mac_entry *res = NULL;
+ struct lan966x_mac_entry *mac_entry;
+
+- spin_lock(&lan966x->mac_lock);
+ list_for_each_entry(mac_entry, &lan966x->mac_entries, list) {
+ if (mac_entry->vid == vid &&
+ ether_addr_equal(mac, mac_entry->mac) &&
+@@ -210,7 +209,6 @@ static struct lan966x_mac_entry *lan966x_mac_find_entry(struct lan966x *lan966x,
+ break;
+ }
+ }
+- spin_unlock(&lan966x->mac_lock);
+
+ return res;
+ }
+@@ -253,8 +251,11 @@ int lan966x_mac_add_entry(struct lan966x *lan966x, struct lan966x_port *port,
+ {
+ struct lan966x_mac_entry *mac_entry;
+
+- if (lan966x_mac_lookup(lan966x, addr, vid, ENTRYTYPE_NORMAL))
++ spin_lock(&lan966x->mac_lock);
++ if (lan966x_mac_lookup(lan966x, addr, vid, ENTRYTYPE_NORMAL)) {
++ spin_unlock(&lan966x->mac_lock);
+ return 0;
++ }
+
+ /* In case the entry already exists, don't add it again to SW,
+ * just update HW, but we need to look in the actual HW because
+@@ -263,21 +264,25 @@ int lan966x_mac_add_entry(struct lan966x *lan966x, struct lan966x_port *port,
+ * add the entry but without the extern_learn flag.
+ */
+ mac_entry = lan966x_mac_find_entry(lan966x, addr, vid, port->chip_port);
+- if (mac_entry)
+- return lan966x_mac_learn(lan966x, port->chip_port,
+- addr, vid, ENTRYTYPE_LOCKED);
++ if (mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
++ goto mac_learn;
++ }
+
+ mac_entry = lan966x_mac_alloc_entry(addr, vid, port->chip_port);
+- if (!mac_entry)
++ if (!mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
+ return -ENOMEM;
++ }
+
+- spin_lock(&lan966x->mac_lock);
+ list_add_tail(&mac_entry->list, &lan966x->mac_entries);
+ spin_unlock(&lan966x->mac_lock);
+
+- lan966x_mac_learn(lan966x, port->chip_port, addr, vid, ENTRYTYPE_LOCKED);
+ lan966x_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED, addr, vid, port->dev);
+
++mac_learn:
++ lan966x_mac_learn(lan966x, port->chip_port, addr, vid, ENTRYTYPE_LOCKED);
++
+ return 0;
+ }
+
+@@ -291,8 +296,9 @@ int lan966x_mac_del_entry(struct lan966x *lan966x, const unsigned char *addr,
+ list) {
+ if (mac_entry->vid == vid &&
+ ether_addr_equal(addr, mac_entry->mac)) {
+- lan966x_mac_forget(lan966x, mac_entry->mac, mac_entry->vid,
+- ENTRYTYPE_LOCKED);
++ lan966x_mac_forget_locked(lan966x, mac_entry->mac,
++ mac_entry->vid,
++ ENTRYTYPE_LOCKED);
+
+ list_del(&mac_entry->list);
+ kfree(mac_entry);
+@@ -428,6 +434,12 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
+ continue;
+
+ spin_lock(&lan966x->mac_lock);
++ mac_entry = lan966x_mac_find_entry(lan966x, mac, vid, dest_idx);
++ if (mac_entry) {
++ spin_unlock(&lan966x->mac_lock);
++ continue;
++ }
++
+ mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx);
+ if (!mac_entry) {
+ spin_unlock(&lan966x->mac_lock);
+--
+2.35.1
+
--- /dev/null
+From 985d2e63a27e4ff87a9494a6a37e5789bf34f47d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 15:55:50 +0300
+Subject: net: prestera: acl: use proper mask for port selector
+
+From: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
+
+[ Upstream commit 1e20904e417738066b26490de2daf7ef3ed34483 ]
+
+Adjusted as per packet processor documentation.
+This allows to properly match 'indev' for clsact rules.
+
+Fixes: 47327e198d42 ("net: prestera: acl: migrate to new vTCAM api")
+
+Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/prestera/prestera_flower.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+index 921959a980ee..d8cfa4a7de0f 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+@@ -139,12 +139,12 @@ static int prestera_flower_parse_meta(struct prestera_acl_rule *rule,
+ }
+ port = netdev_priv(ingress_dev);
+
+- mask = htons(0x1FFF);
+- key = htons(port->hw_id);
++ mask = htons(0x1FFF << 3);
++ key = htons(port->hw_id << 3);
+ rule_match_set(r_match->key, SYS_PORT, key);
+ rule_match_set(r_match->mask, SYS_PORT, mask);
+
+- mask = htons(0x1FF);
++ mask = htons(0x3FF);
+ key = htons(port->dev_id);
+ rule_match_set(r_match->key, SYS_DEV, key);
+ rule_match_set(r_match->mask, SYS_DEV, mask);
+--
+2.35.1
+
--- /dev/null
+From 810361365f2781c5c7d37fb0feb817256fd14ee6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 15:24:09 +0300
+Subject: net/sched: cls_api: Fix flow action initialization
+
+From: Oz Shlomo <ozsh@nvidia.com>
+
+[ Upstream commit c0f47c2822aadeb8b2829f3e4c3792f184c7be33 ]
+
+The cited commit refactored the flow action initialization sequence to
+use an interface method when translating tc action instances to flow
+offload objects. The refactored version skips the initialization of the
+generic flow action attributes for tc actions, such as pedit, that allocate
+more than one offload entry. This can cause potential issues for drivers
+mapping flow action ids.
+
+Populate the generic flow action fields for all the flow action entries.
+
+Fixes: c54e1d920f04 ("flow_offload: add ops to tc_action_ops for flow action setup")
+Signed-off-by: Oz Shlomo <ozsh@nvidia.com>
+Reviewed-by: Roi Dayan <roid@nvidia.com>
+
+----
+v1 -> v2:
+ - coalese the generic flow action fields initialization to a single loop
+Reviewed-by: Baowen Zheng <baowen.zheng@corigine.com>
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_api.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index 2d4dc1468a9a..6fd33c75d6bb 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -3531,7 +3531,7 @@ int tc_setup_action(struct flow_action *flow_action,
+ struct tc_action *actions[],
+ struct netlink_ext_ack *extack)
+ {
+- int i, j, index, err = 0;
++ int i, j, k, index, err = 0;
+ struct tc_action *act;
+
+ BUILD_BUG_ON(TCA_ACT_HW_STATS_ANY != FLOW_ACTION_HW_STATS_ANY);
+@@ -3551,14 +3551,18 @@ int tc_setup_action(struct flow_action *flow_action,
+ if (err)
+ goto err_out_locked;
+
+- entry->hw_stats = tc_act_hw_stats(act->hw_stats);
+- entry->hw_index = act->tcfa_index;
+ index = 0;
+ err = tc_setup_offload_act(act, entry, &index, extack);
+- if (!err)
+- j += index;
+- else
++ if (err)
+ goto err_out_locked;
++
++ for (k = 0; k < index ; k++) {
++ entry[k].hw_stats = tc_act_hw_stats(act->hw_stats);
++ entry[k].hw_index = act->tcfa_index;
++ }
++
++ j += index;
++
+ spin_unlock_bh(&act->tcfa_lock);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 32dfd8e511b752242f68b8491351d8e8c07f272a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 15:47:01 +0800
+Subject: net: stmmac: fix dma queue left shift overflow issue
+
+From: Junxiao Chang <junxiao.chang@intel.com>
+
+[ Upstream commit 613b065ca32e90209024ec4a6bb5ca887ee70980 ]
+
+When queue number is > 4, left shift overflows due to 32 bits
+integer variable. Mask calculation is wrong for MTL_RXQ_DMA_MAP1.
+
+If CONFIG_UBSAN is enabled, kernel dumps below warning:
+[ 10.363842] ==================================================================
+[ 10.363882] UBSAN: shift-out-of-bounds in /build/linux-intel-iotg-5.15-8e6Tf4/
+linux-intel-iotg-5.15-5.15.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c:224:12
+[ 10.363929] shift exponent 40 is too large for 32-bit type 'unsigned int'
+[ 10.363953] CPU: 1 PID: 599 Comm: NetworkManager Not tainted 5.15.0-1003-intel-iotg
+[ 10.363956] Hardware name: ADLINK Technology Inc. LEC-EL/LEC-EL, BIOS 0.15.11 12/22/2021
+[ 10.363958] Call Trace:
+[ 10.363960] <TASK>
+[ 10.363963] dump_stack_lvl+0x4a/0x5f
+[ 10.363971] dump_stack+0x10/0x12
+[ 10.363974] ubsan_epilogue+0x9/0x45
+[ 10.363976] __ubsan_handle_shift_out_of_bounds.cold+0x61/0x10e
+[ 10.363979] ? wake_up_klogd+0x4a/0x50
+[ 10.363983] ? vprintk_emit+0x8f/0x240
+[ 10.363986] dwmac4_map_mtl_dma.cold+0x42/0x91 [stmmac]
+[ 10.364001] stmmac_mtl_configuration+0x1ce/0x7a0 [stmmac]
+[ 10.364009] ? dwmac410_dma_init_channel+0x70/0x70 [stmmac]
+[ 10.364020] stmmac_hw_setup.cold+0xf/0xb14 [stmmac]
+[ 10.364030] ? page_pool_alloc_pages+0x4d/0x70
+[ 10.364034] ? stmmac_clear_tx_descriptors+0x6e/0xe0 [stmmac]
+[ 10.364042] stmmac_open+0x39e/0x920 [stmmac]
+[ 10.364050] __dev_open+0xf0/0x1a0
+[ 10.364054] __dev_change_flags+0x188/0x1f0
+[ 10.364057] dev_change_flags+0x26/0x60
+[ 10.364059] do_setlink+0x908/0xc40
+[ 10.364062] ? do_setlink+0xb10/0xc40
+[ 10.364064] ? __nla_validate_parse+0x4c/0x1a0
+[ 10.364068] __rtnl_newlink+0x597/0xa10
+[ 10.364072] ? __nla_reserve+0x41/0x50
+[ 10.364074] ? __kmalloc_node_track_caller+0x1d0/0x4d0
+[ 10.364079] ? pskb_expand_head+0x75/0x310
+[ 10.364082] ? nla_reserve_64bit+0x21/0x40
+[ 10.364086] ? skb_free_head+0x65/0x80
+[ 10.364089] ? security_sock_rcv_skb+0x2c/0x50
+[ 10.364094] ? __cond_resched+0x19/0x30
+[ 10.364097] ? kmem_cache_alloc_trace+0x15a/0x420
+[ 10.364100] rtnl_newlink+0x49/0x70
+
+This change fixes MTL_RXQ_DMA_MAP1 mask issue and channel/queue
+mapping warning.
+
+Fixes: d43042f4da3e ("net: stmmac: mapping mtl rx to dma channel")
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216195
+Reported-by: Cedric Wassenaar <cedric@bytespeed.nl>
+Signed-off-by: Junxiao Chang <junxiao.chang@intel.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index fd41db65fe1d..af3339041134 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -219,6 +219,9 @@ static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan)
+ if (queue == 0 || queue == 4) {
+ value &= ~MTL_RXQ_DMA_Q04MDMACH_MASK;
+ value |= MTL_RXQ_DMA_Q04MDMACH(chan);
++ } else if (queue > 4) {
++ value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue - 4);
++ value |= MTL_RXQ_DMA_QXMDMACH(chan, queue - 4);
+ } else {
+ value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue);
+ value |= MTL_RXQ_DMA_QXMDMACH(chan, queue);
+--
+2.35.1
+
--- /dev/null
+From 4f1abbea33fd205881539360d1255db99ea3ce5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:00:13 +0800
+Subject: net: stmmac: fix pm runtime issue in stmmac_dvr_remove()
+
+From: Biao Huang <biao.huang@mediatek.com>
+
+[ Upstream commit 0d9a15913b871e03fdd3b3d90a2e665fb22f9bcf ]
+
+If netif is running when stmmac_dvr_remove is invoked,
+the unregister_netdev will call ndo_stop(stmmac_release) and
+vlan_kill_rx_filter(stmmac_vlan_rx_kill_vid).
+
+Currently, stmmac_dvr_remove() will disable pm runtime before
+unregister_netdev. When stmmac_vlan_rx_kill_vid is invoked,
+pm_runtime_resume_and_get in it returns EACCESS error number,
+and reports:
+
+ dwmac-mediatek 11021000.ethernet eth0: stmmac_dvr_remove: removing driver
+ dwmac-mediatek 11021000.ethernet eth0: FPE workqueue stop
+ dwmac-mediatek 11021000.ethernet eth0: failed to kill vid 0081/0
+
+Move the pm_runtime_disable to the end of stmmac_dvr_remove
+to fix this issue.
+
+Fixes: 6449520391dfc ("net: stmmac: properly handle with runtime pm in stmmac_dvr_remove()")
+Signed-off-by: Biao Huang <biao.huang@mediatek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 2525a80353b7..d43c9ba0b270 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -7220,8 +7220,6 @@ int stmmac_dvr_remove(struct device *dev)
+ netdev_info(priv->dev, "%s: removing driver", __func__);
+
+ pm_runtime_get_sync(dev);
+- pm_runtime_disable(dev);
+- pm_runtime_put_noidle(dev);
+
+ stmmac_stop_all_dma(priv);
+ stmmac_mac_set(priv, priv->ioaddr, false);
+@@ -7248,6 +7246,9 @@ int stmmac_dvr_remove(struct device *dev)
+ mutex_destroy(&priv->lock);
+ bitmap_free(priv->af_xdp_zc_qps);
+
++ pm_runtime_disable(dev);
++ pm_runtime_put_noidle(dev);
++
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(stmmac_dvr_remove);
+--
+2.35.1
+
--- /dev/null
+From 1c157dbb3a0ba203cf08104dbeb84dfb9d4b56cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:00:14 +0800
+Subject: net: stmmac: fix unbalanced ptp clock issue in suspend/resume flow
+
+From: Biao Huang <biao.huang@mediatek.com>
+
+[ Upstream commit f4c7d8948e866918d61493264dbbd67e45ef2bda ]
+
+Current stmmac driver will prepare/enable ptp_ref clock in
+stmmac_init_tstamp_counter().
+
+The stmmac_pltfr_noirq_suspend will disable it once in suspend flow.
+
+But in resume flow,
+ stmmac_pltfr_noirq_resume --> stmmac_init_tstamp_counter
+ stmmac_resume --> stmmac_hw_setup --> stmmac_init_ptp --> stmmac_init_tstamp_counter
+ptp_ref clock reference counter increases twice, which leads to unbalance
+ptp clock when resume back.
+
+Move ptp_ref clock prepare/enable out of stmmac_init_tstamp_counter to fix it.
+
+Fixes: 0735e639f129d ("net: stmmac: skip only stmmac_ptp_register when resume from suspend")
+Signed-off-by: Biao Huang <biao.huang@mediatek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 17 ++++++++---------
+ .../ethernet/stmicro/stmmac/stmmac_platform.c | 8 +++++++-
+ 2 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index d43c9ba0b270..6a7f63a58aef 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -834,19 +834,10 @@ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags)
+ struct timespec64 now;
+ u32 sec_inc = 0;
+ u64 temp = 0;
+- int ret;
+
+ if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
+ return -EOPNOTSUPP;
+
+- ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
+- if (ret < 0) {
+- netdev_warn(priv->dev,
+- "failed to enable PTP reference clock: %pe\n",
+- ERR_PTR(ret));
+- return ret;
+- }
+-
+ stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
+ priv->systime_flags = systime_flags;
+
+@@ -3270,6 +3261,14 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
+
+ stmmac_mmc_setup(priv);
+
++ if (ptp_register) {
++ ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
++ if (ret < 0)
++ netdev_warn(priv->dev,
++ "failed to enable PTP reference clock: %pe\n",
++ ERR_PTR(ret));
++ }
++
+ ret = stmmac_init_ptp(priv);
+ if (ret == -EOPNOTSUPP)
+ netdev_info(priv->dev, "PTP not supported by HW\n");
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 11e1055e8260..9f5cac4000da 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -815,7 +815,13 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
+ if (ret)
+ return ret;
+
+- stmmac_init_tstamp_counter(priv, priv->systime_flags);
++ ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
++ if (ret < 0) {
++ netdev_warn(priv->dev,
++ "failed to enable PTP reference clock: %pe\n",
++ ERR_PTR(ret));
++ return ret;
++ }
+ }
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 6a746160d5b6442c4063db2bc4aece0bae689528 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 20:24:02 +0800
+Subject: net: stmmac: remove redunctant disable xPCS EEE call
+
+From: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+
+[ Upstream commit da791bac104a3169b05b54270afe75daacba4641 ]
+
+Disable is done in stmmac_init_eee() on the event of MAC link down.
+Since setting enable/disable EEE via ethtool will eventually trigger
+a MAC down, removing this redunctant call in stmmac_ethtool.c to avoid
+calling xpcs_config_eee() twice.
+
+Fixes: d4aeaed80b0e ("net: stmmac: trigger PCS EEE to turn off on link down")
+Signed-off-by: Wong Vee Khee <vee.khee.wong@linux.intel.com>
+Link: https://lore.kernel.org/r/20220715122402.1017470-1-vee.khee.wong@linux.intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index abfb3cd5958d..9c3055ee2608 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -803,14 +803,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
+ netdev_warn(priv->dev,
+ "Setting EEE tx-lpi is not supported\n");
+
+- if (priv->hw->xpcs) {
+- ret = xpcs_config_eee(priv->hw->xpcs,
+- priv->plat->mult_fact_100ns,
+- edata->eee_enabled);
+- if (ret)
+- return ret;
+- }
+-
+ if (!edata->eee_enabled)
+ stmmac_disable_eee_mode(priv);
+
+--
+2.35.1
+
--- /dev/null
+From 24939f37799f8deeb3daa67e1e1750012ff2def2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 11:42:16 +0300
+Subject: net/tls: Fix race in TLS device down flow
+
+From: Tariq Toukan <tariqt@nvidia.com>
+
+[ Upstream commit f08d8c1bb97c48f24a82afaa2fd8c140f8d3da8b ]
+
+Socket destruction flow and tls_device_down function sync against each
+other using tls_device_lock and the context refcount, to guarantee the
+device resources are freed via tls_dev_del() by the end of
+tls_device_down.
+
+In the following unfortunate flow, this won't happen:
+- refcount is decreased to zero in tls_device_sk_destruct.
+- tls_device_down starts, skips the context as refcount is zero, going
+ all the way until it flushes the gc work, and returns without freeing
+ the device resources.
+- only then, tls_device_queue_ctx_destruction is called, queues the gc
+ work and frees the context's device resources.
+
+Solve it by decreasing the refcount in the socket's destruction flow
+under the tls_device_lock, for perfect synchronization. This does not
+slow down the common likely destructor flow, in which both the refcount
+is decreased and the spinlock is acquired, anyway.
+
+Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure")
+Reviewed-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_device.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
+index 3a61bb594544..9c3933781ad4 100644
+--- a/net/tls/tls_device.c
++++ b/net/tls/tls_device.c
+@@ -97,13 +97,16 @@ static void tls_device_queue_ctx_destruction(struct tls_context *ctx)
+ unsigned long flags;
+
+ spin_lock_irqsave(&tls_device_lock, flags);
++ if (unlikely(!refcount_dec_and_test(&ctx->refcount)))
++ goto unlock;
++
+ list_move_tail(&ctx->list, &tls_device_gc_list);
+
+ /* schedule_work inside the spinlock
+ * to make sure tls_device_down waits for that work.
+ */
+ schedule_work(&tls_device_gc_work);
+-
++unlock:
+ spin_unlock_irqrestore(&tls_device_lock, flags);
+ }
+
+@@ -194,8 +197,7 @@ void tls_device_sk_destruct(struct sock *sk)
+ clean_acked_data_disable(inet_csk(sk));
+ }
+
+- if (refcount_dec_and_test(&tls_ctx->refcount))
+- tls_device_queue_ctx_destruction(tls_ctx);
++ tls_device_queue_ctx_destruction(tls_ctx);
+ }
+ EXPORT_SYMBOL_GPL(tls_device_sk_destruct);
+
+--
+2.35.1
+
--- /dev/null
+From 6f77ac046a2324c27b4ec103062ce991b8ccd3e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 15:07:26 +0200
+Subject: perf/core: Fix data race between perf_event_set_output() and
+ perf_mmap_close()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 68e3c69803dada336893640110cb87221bb01dcf ]
+
+Yang Jihing reported a race between perf_event_set_output() and
+perf_mmap_close():
+
+ CPU1 CPU2
+
+ perf_mmap_close(e2)
+ if (atomic_dec_and_test(&e2->rb->mmap_count)) // 1 - > 0
+ detach_rest = true
+
+ ioctl(e1, IOC_SET_OUTPUT, e2)
+ perf_event_set_output(e1, e2)
+
+ ...
+ list_for_each_entry_rcu(e, &e2->rb->event_list, rb_entry)
+ ring_buffer_attach(e, NULL);
+ // e1 isn't yet added and
+ // therefore not detached
+
+ ring_buffer_attach(e1, e2->rb)
+ list_add_rcu(&e1->rb_entry,
+ &e2->rb->event_list)
+
+After this; e1 is attached to an unmapped rb and a subsequent
+perf_mmap() will loop forever more:
+
+ again:
+ mutex_lock(&e->mmap_mutex);
+ if (event->rb) {
+ ...
+ if (!atomic_inc_not_zero(&e->rb->mmap_count)) {
+ ...
+ mutex_unlock(&e->mmap_mutex);
+ goto again;
+ }
+ }
+
+The loop in perf_mmap_close() holds e2->mmap_mutex, while the attach
+in perf_event_set_output() holds e1->mmap_mutex. As such there is no
+serialization to avoid this race.
+
+Change perf_event_set_output() to take both e1->mmap_mutex and
+e2->mmap_mutex to alleviate that problem. Additionally, have the loop
+in perf_mmap() detach the rb directly, this avoids having to wait for
+the concurrent perf_mmap_close() to get around to doing it to make
+progress.
+
+Fixes: 9bb5d40cd93c ("perf: Fix mmap() accounting hole")
+Reported-by: Yang Jihong <yangjihong1@huawei.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Yang Jihong <yangjihong1@huawei.com>
+Link: https://lkml.kernel.org/r/YsQ3jm2GR38SW7uD@worktop.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 45 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 31 insertions(+), 14 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 950b25c3f210..82238406f5f5 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -6254,10 +6254,10 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
+
+ if (!atomic_inc_not_zero(&event->rb->mmap_count)) {
+ /*
+- * Raced against perf_mmap_close() through
+- * perf_event_set_output(). Try again, hope for better
+- * luck.
++ * Raced against perf_mmap_close(); remove the
++ * event and try again.
+ */
++ ring_buffer_attach(event, NULL);
+ mutex_unlock(&event->mmap_mutex);
+ goto again;
+ }
+@@ -11826,14 +11826,25 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
+ goto out;
+ }
+
++static void mutex_lock_double(struct mutex *a, struct mutex *b)
++{
++ if (b < a)
++ swap(a, b);
++
++ mutex_lock(a);
++ mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
++}
++
+ static int
+ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
+ {
+ struct perf_buffer *rb = NULL;
+ int ret = -EINVAL;
+
+- if (!output_event)
++ if (!output_event) {
++ mutex_lock(&event->mmap_mutex);
+ goto set;
++ }
+
+ /* don't allow circular references */
+ if (event == output_event)
+@@ -11871,8 +11882,15 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
+ event->pmu != output_event->pmu)
+ goto out;
+
++ /*
++ * Hold both mmap_mutex to serialize against perf_mmap_close(). Since
++ * output_event is already on rb->event_list, and the list iteration
++ * restarts after every removal, it is guaranteed this new event is
++ * observed *OR* if output_event is already removed, it's guaranteed we
++ * observe !rb->mmap_count.
++ */
++ mutex_lock_double(&event->mmap_mutex, &output_event->mmap_mutex);
+ set:
+- mutex_lock(&event->mmap_mutex);
+ /* Can't redirect output if we've got an active mmap() */
+ if (atomic_read(&event->mmap_count))
+ goto unlock;
+@@ -11882,6 +11900,12 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
+ rb = ring_buffer_get(output_event);
+ if (!rb)
+ goto unlock;
++
++ /* did we race against perf_mmap_close() */
++ if (!atomic_read(&rb->mmap_count)) {
++ ring_buffer_put(rb);
++ goto unlock;
++ }
+ }
+
+ ring_buffer_attach(event, rb);
+@@ -11889,20 +11913,13 @@ perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
+ ret = 0;
+ unlock:
+ mutex_unlock(&event->mmap_mutex);
++ if (output_event)
++ mutex_unlock(&output_event->mmap_mutex);
+
+ out:
+ return ret;
+ }
+
+-static void mutex_lock_double(struct mutex *a, struct mutex *b)
+-{
+- if (b < a)
+- swap(a, b);
+-
+- mutex_lock(a);
+- mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
+-}
+-
+ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id)
+ {
+ bool nmi_safe = false;
+--
+2.35.1
+
--- /dev/null
+From 41ecbc96b6e85fc568a739b8e98d8e8401a1b359 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:34:59 +0300
+Subject: perf tests: Fix Convert perf time to TSC test for hybrid
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit deb44a6249f696106645c63c0603eab08a6122af ]
+
+The test does not always correctly determine the number of events for
+hybrids, nor allow for more than 1 evsel when parsing.
+
+Fix by iterating the events actually created and getting the correct
+evsel for the events processed.
+
+Fixes: d9da6f70eb235110 ("perf tests: Support 'Convert perf time to TSC' test for hybrid")
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jin Yao <yao.jin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220713123459.24145-3-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/perf-time-to-tsc.c | 18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
+index 8d6d60173693..7c7d20fc503a 100644
+--- a/tools/perf/tests/perf-time-to-tsc.c
++++ b/tools/perf/tests/perf-time-to-tsc.c
+@@ -20,8 +20,6 @@
+ #include "tsc.h"
+ #include "mmap.h"
+ #include "tests.h"
+-#include "pmu.h"
+-#include "pmu-hybrid.h"
+
+ /*
+ * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. Just
+@@ -106,18 +104,8 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
+
+ evlist__config(evlist, &opts, NULL);
+
+- evsel = evlist__first(evlist);
+-
+- evsel->core.attr.comm = 1;
+- evsel->core.attr.disabled = 1;
+- evsel->core.attr.enable_on_exec = 0;
+-
+- /*
+- * For hybrid "cycles:u", it creates two events.
+- * Init the second evsel here.
+- */
+- if (perf_pmu__has_hybrid() && perf_pmu__hybrid_mounted("cpu_atom")) {
+- evsel = evsel__next(evsel);
++ /* For hybrid "cycles:u", it creates two events */
++ evlist__for_each_entry(evlist, evsel) {
+ evsel->core.attr.comm = 1;
+ evsel->core.attr.disabled = 1;
+ evsel->core.attr.enable_on_exec = 0;
+@@ -170,10 +158,12 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
+ goto next_event;
+
+ if (strcmp(event->comm.comm, comm1) == 0) {
++ CHECK_NOT_NULL__(evsel = evlist__event2evsel(evlist, event));
+ CHECK__(evsel__parse_sample(evsel, event, &sample));
+ comm1_time = sample.time;
+ }
+ if (strcmp(event->comm.comm, comm2) == 0) {
++ CHECK_NOT_NULL__(evsel = evlist__event2evsel(evlist, event));
+ CHECK__(evsel__parse_sample(evsel, event, &sample));
+ comm2_time = sample.time;
+ }
+--
+2.35.1
+
--- /dev/null
+From 4f0ea073db56b2f23905c617bef7411b6a080727 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:34:58 +0300
+Subject: perf tests: Stop Convert perf time to TSC test opening events twice
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 498c7a54f169b2699104d3060604d840424f15d2 ]
+
+Do not call evlist__open() twice.
+
+Fixes: 5bb017d4b97a0f13 ("perf test: Fix error message for test case 71 on s390, where it is not supported")
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220713123459.24145-2-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/perf-time-to-tsc.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
+index 4ad0dfbc8b21..8d6d60173693 100644
+--- a/tools/perf/tests/perf-time-to-tsc.c
++++ b/tools/perf/tests/perf-time-to-tsc.c
+@@ -123,11 +123,14 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su
+ evsel->core.attr.enable_on_exec = 0;
+ }
+
+- if (evlist__open(evlist) == -ENOENT) {
+- err = TEST_SKIP;
++ ret = evlist__open(evlist);
++ if (ret < 0) {
++ if (ret == -ENOENT)
++ err = TEST_SKIP;
++ else
++ pr_debug("evlist__open() failed\n");
+ goto out_err;
+ }
+- CHECK__(evlist__open(evlist));
+
+ CHECK__(evlist__mmap(evlist, UINT_MAX));
+
+--
+2.35.1
+
--- /dev/null
+From 1fbad22a066761592cb106483d64b27bbcf30bbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 02:37:44 +0300
+Subject: pinctrl: armada-37xx: make irq_lock a raw spinlock to avoid invalid
+ wait context
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 984245b66cf32c494b1e4f95f5ed6ba16b8771eb ]
+
+The irqchip->irq_set_type method is called by __irq_set_trigger() under
+the desc->lock raw spinlock.
+
+The armada-37xx implementation, armada_37xx_irq_set_type(), takes a
+plain spinlock, the kind that becomes sleepable on RT.
+
+Therefore, this is an invalid locking scheme for which we get a kernel
+splat stating just that ("[ BUG: Invalid wait context ]"), because the
+context in which the plain spinlock may sleep is atomic due to the raw
+spinlock. We need to go raw spinlocks all the way.
+
+Replace the driver's irq_lock with a raw spinlock, to disable preemption
+even on RT.
+
+Cc: <stable@vger.kernel.org> # 5.15+
+Fixes: 2f227605394b ("pinctrl: armada-37xx: Add irqchip support")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/20220716233745.1704677-2-vladimir.oltean@nxp.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 38 ++++++++++-----------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+index 226798d9c067..b920dd5237c7 100644
+--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+@@ -101,7 +101,7 @@ struct armada_37xx_pinctrl {
+ struct device *dev;
+ struct gpio_chip gpio_chip;
+ struct irq_chip irq_chip;
+- spinlock_t irq_lock;
++ raw_spinlock_t irq_lock;
+ struct pinctrl_desc pctl;
+ struct pinctrl_dev *pctl_dev;
+ struct armada_37xx_pin_group *groups;
+@@ -522,9 +522,9 @@ static void armada_37xx_irq_ack(struct irq_data *d)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ writel(d->mask, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+
+ static void armada_37xx_irq_mask(struct irq_data *d)
+@@ -535,10 +535,10 @@ static void armada_37xx_irq_mask(struct irq_data *d)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ writel(val & ~d->mask, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+
+ static void armada_37xx_irq_unmask(struct irq_data *d)
+@@ -549,10 +549,10 @@ static void armada_37xx_irq_unmask(struct irq_data *d)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ writel(val | d->mask, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+
+ static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
+@@ -563,14 +563,14 @@ static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ if (on)
+ val |= (BIT(d->hwirq % GPIO_PER_REG));
+ else
+ val &= ~(BIT(d->hwirq % GPIO_PER_REG));
+ writel(val, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+
+ return 0;
+ }
+@@ -582,7 +582,7 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
+ u32 val, reg = IRQ_POL;
+ unsigned long flags;
+
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ armada_37xx_irq_update_reg(®, d);
+ val = readl(info->base + reg);
+ switch (type) {
+@@ -606,11 +606,11 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
+ break;
+ }
+ default:
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ return -EINVAL;
+ }
+ writel(val, info->base + reg);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+
+ return 0;
+ }
+@@ -625,7 +625,7 @@ static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
+
+ regmap_read(info->regmap, INPUT_VAL + 4*reg_idx, &l);
+
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ p = readl(info->base + IRQ_POL + 4 * reg_idx);
+ if ((p ^ l) & (1 << bit_num)) {
+ /*
+@@ -646,7 +646,7 @@ static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
+ ret = -1;
+ }
+
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ return ret;
+ }
+
+@@ -663,11 +663,11 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
+ u32 status;
+ unsigned long flags;
+
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ status = readl_relaxed(info->base + IRQ_STATUS + 4 * i);
+ /* Manage only the interrupt that was enabled */
+ status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ while (status) {
+ u32 hwirq = ffs(status) - 1;
+ u32 virq = irq_find_mapping(d, hwirq +
+@@ -694,12 +694,12 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
+
+ update_status:
+ /* Update status in case a new IRQ appears */
+- spin_lock_irqsave(&info->irq_lock, flags);
++ raw_spin_lock_irqsave(&info->irq_lock, flags);
+ status = readl_relaxed(info->base +
+ IRQ_STATUS + 4 * i);
+ /* Manage only the interrupt that was enabled */
+ status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
+- spin_unlock_irqrestore(&info->irq_lock, flags);
++ raw_spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+ }
+ chained_irq_exit(chip, desc);
+@@ -730,7 +730,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
+ struct device *dev = &pdev->dev;
+ unsigned int i, nr_irq_parent;
+
+- spin_lock_init(&info->irq_lock);
++ raw_spin_lock_init(&info->irq_lock);
+
+ nr_irq_parent = of_irq_count(np);
+ if (!nr_irq_parent) {
+--
+2.35.1
+
--- /dev/null
+From 1fad4e983cabddce502d41b43ceb0daa4c420dca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Apr 2022 13:36:04 +0300
+Subject: pinctrl: armada-37xx: Reuse GPIO fwnode in
+ armada_37xx_irqchip_register()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 46d34d4d502ea1030f5de434e6677ec96ca131c3 ]
+
+Since we have fwnode of the first found GPIO controller assigned to the
+struct gpio_chip, we may reuse it in the armada_37xx_irqchip_register().
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+index 5fc305222d2f..226798d9c067 100644
+--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+@@ -726,23 +726,13 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
+ struct gpio_chip *gc = &info->gpio_chip;
+ struct irq_chip *irqchip = &info->irq_chip;
+ struct gpio_irq_chip *girq = &gc->irq;
++ struct device_node *np = to_of_node(gc->fwnode);
+ struct device *dev = &pdev->dev;
+- struct device_node *np;
+- int ret = -ENODEV, i, nr_irq_parent;
+-
+- /* Check if we have at least one gpio-controller child node */
+- for_each_child_of_node(dev->of_node, np) {
+- if (of_property_read_bool(np, "gpio-controller")) {
+- ret = 0;
+- break;
+- }
+- }
+- if (ret)
+- return dev_err_probe(dev, ret, "no gpio-controller child node\n");
++ unsigned int i, nr_irq_parent;
+
+- nr_irq_parent = of_irq_count(np);
+ spin_lock_init(&info->irq_lock);
+
++ nr_irq_parent = of_irq_count(np);
+ if (!nr_irq_parent) {
+ dev_err(dev, "invalid or no IRQ\n");
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 597153309812e65b98a453281e6c995eb0590bfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 21:37:49 +0200
+Subject: pinctrl: ocelot: Fix pincfg for lan966x
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit dc62db7138aa9365480254dda4c3e1316b1b1bbc ]
+
+The blamed commit introduce support for lan966x which use the same
+pinconf_ops as sparx5. The problem is that pinconf_ops is specific to
+sparx5. More precisely the offset of the bits in the pincfg register are
+different and also lan966x doesn't have support for
+PIN_CONFIG_INPUT_SCHMITT_ENABLE.
+
+Fix this by making pinconf_ops more generic such that it can be also
+used by lan966x. This is done by introducing 'ocelot_pincfg_data' which
+contains the offset and what is supported for each SOC.
+
+Fixes: 531d6ab36571 ("pinctrl: ocelot: Extend support for lan966x")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220713193750.4079621-2-horatiu.vultur@microchip.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-ocelot.c | 195 ++++++++++++++++++++-----------
+ 1 file changed, 124 insertions(+), 71 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index 6a956ee94494..2866365132fd 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -28,19 +28,12 @@
+ #define ocelot_clrsetbits(addr, clear, set) \
+ writel((readl(addr) & ~(clear)) | (set), (addr))
+
+-/* PINCONFIG bits (sparx5 only) */
+ enum {
+ PINCONF_BIAS,
+ PINCONF_SCHMITT,
+ PINCONF_DRIVE_STRENGTH,
+ };
+
+-#define BIAS_PD_BIT BIT(4)
+-#define BIAS_PU_BIT BIT(3)
+-#define BIAS_BITS (BIAS_PD_BIT|BIAS_PU_BIT)
+-#define SCHMITT_BIT BIT(2)
+-#define DRIVE_BITS GENMASK(1, 0)
+-
+ /* GPIO standard registers */
+ #define OCELOT_GPIO_OUT_SET 0x0
+ #define OCELOT_GPIO_OUT_CLR 0x4
+@@ -314,6 +307,13 @@ struct ocelot_pin_caps {
+ unsigned char a_functions[OCELOT_FUNC_PER_PIN]; /* Additional functions */
+ };
+
++struct ocelot_pincfg_data {
++ u8 pd_bit;
++ u8 pu_bit;
++ u8 drive_bits;
++ u8 schmitt_bit;
++};
++
+ struct ocelot_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+@@ -321,10 +321,16 @@ struct ocelot_pinctrl {
+ struct regmap *map;
+ struct regmap *pincfg;
+ struct pinctrl_desc *desc;
++ const struct ocelot_pincfg_data *pincfg_data;
+ struct ocelot_pmx_func func[FUNC_MAX];
+ u8 stride;
+ };
+
++struct ocelot_match_data {
++ struct pinctrl_desc desc;
++ struct ocelot_pincfg_data pincfg_data;
++};
++
+ #define LUTON_P(p, f0, f1) \
+ static struct ocelot_pin_caps luton_pin_##p = { \
+ .pin = p, \
+@@ -1318,6 +1324,7 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
+ int ret = -EOPNOTSUPP;
+
+ if (info->pincfg) {
++ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+ u32 regcfg;
+
+ ret = regmap_read(info->pincfg, pin, ®cfg);
+@@ -1327,15 +1334,15 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
+ ret = 0;
+ switch (reg) {
+ case PINCONF_BIAS:
+- *val = regcfg & BIAS_BITS;
++ *val = regcfg & (opd->pd_bit | opd->pu_bit);
+ break;
+
+ case PINCONF_SCHMITT:
+- *val = regcfg & SCHMITT_BIT;
++ *val = regcfg & opd->schmitt_bit;
+ break;
+
+ case PINCONF_DRIVE_STRENGTH:
+- *val = regcfg & DRIVE_BITS;
++ *val = regcfg & opd->drive_bits;
+ break;
+
+ default:
+@@ -1372,23 +1379,27 @@ static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
+ int ret = -EOPNOTSUPP;
+
+ if (info->pincfg) {
++ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+
+ ret = 0;
+ switch (reg) {
+ case PINCONF_BIAS:
+- ret = ocelot_pincfg_clrsetbits(info, pin, BIAS_BITS,
++ ret = ocelot_pincfg_clrsetbits(info, pin,
++ opd->pd_bit | opd->pu_bit,
+ val);
+ break;
+
+ case PINCONF_SCHMITT:
+- ret = ocelot_pincfg_clrsetbits(info, pin, SCHMITT_BIT,
++ ret = ocelot_pincfg_clrsetbits(info, pin,
++ opd->schmitt_bit,
+ val);
+ break;
+
+ case PINCONF_DRIVE_STRENGTH:
+ if (val <= 3)
+ ret = ocelot_pincfg_clrsetbits(info, pin,
+- DRIVE_BITS, val);
++ opd->drive_bits,
++ val);
+ else
+ ret = -EINVAL;
+ break;
+@@ -1418,17 +1429,20 @@ static int ocelot_pinconf_get(struct pinctrl_dev *pctldev,
+ if (param == PIN_CONFIG_BIAS_DISABLE)
+ val = (val == 0);
+ else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
+- val = (val & BIAS_PD_BIT ? true : false);
++ val = !!(val & info->pincfg_data->pd_bit);
+ else /* PIN_CONFIG_BIAS_PULL_UP */
+- val = (val & BIAS_PU_BIT ? true : false);
++ val = !!(val & info->pincfg_data->pu_bit);
+ break;
+
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++ if (!info->pincfg_data->schmitt_bit)
++ return -EOPNOTSUPP;
++
+ err = ocelot_hw_get_value(info, pin, PINCONF_SCHMITT, &val);
+ if (err)
+ return err;
+
+- val = (val & SCHMITT_BIT ? true : false);
++ val = !!(val & info->pincfg_data->schmitt_bit);
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+@@ -1472,6 +1486,7 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *configs, unsigned int num_configs)
+ {
+ struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
++ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+ u32 param, arg, p;
+ int cfg, err = 0;
+
+@@ -1484,8 +1499,8 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
+- (param == PIN_CONFIG_BIAS_PULL_UP) ? BIAS_PU_BIT :
+- BIAS_PD_BIT;
++ (param == PIN_CONFIG_BIAS_PULL_UP) ?
++ opd->pu_bit : opd->pd_bit;
+
+ err = ocelot_hw_set_value(info, pin, PINCONF_BIAS, arg);
+ if (err)
+@@ -1494,7 +1509,10 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ break;
+
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+- arg = arg ? SCHMITT_BIT : 0;
++ if (!opd->schmitt_bit)
++ return -EOPNOTSUPP;
++
++ arg = arg ? opd->schmitt_bit : 0;
+ err = ocelot_hw_set_value(info, pin, PINCONF_SCHMITT,
+ arg);
+ if (err)
+@@ -1555,69 +1573,94 @@ static const struct pinctrl_ops ocelot_pctl_ops = {
+ .dt_free_map = pinconf_generic_dt_free_map,
+ };
+
+-static struct pinctrl_desc luton_desc = {
+- .name = "luton-pinctrl",
+- .pins = luton_pins,
+- .npins = ARRAY_SIZE(luton_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data luton_desc = {
++ .desc = {
++ .name = "luton-pinctrl",
++ .pins = luton_pins,
++ .npins = ARRAY_SIZE(luton_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc serval_desc = {
+- .name = "serval-pinctrl",
+- .pins = serval_pins,
+- .npins = ARRAY_SIZE(serval_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data serval_desc = {
++ .desc = {
++ .name = "serval-pinctrl",
++ .pins = serval_pins,
++ .npins = ARRAY_SIZE(serval_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc ocelot_desc = {
+- .name = "ocelot-pinctrl",
+- .pins = ocelot_pins,
+- .npins = ARRAY_SIZE(ocelot_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data ocelot_desc = {
++ .desc = {
++ .name = "ocelot-pinctrl",
++ .pins = ocelot_pins,
++ .npins = ARRAY_SIZE(ocelot_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc jaguar2_desc = {
+- .name = "jaguar2-pinctrl",
+- .pins = jaguar2_pins,
+- .npins = ARRAY_SIZE(jaguar2_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data jaguar2_desc = {
++ .desc = {
++ .name = "jaguar2-pinctrl",
++ .pins = jaguar2_pins,
++ .npins = ARRAY_SIZE(jaguar2_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc servalt_desc = {
+- .name = "servalt-pinctrl",
+- .pins = servalt_pins,
+- .npins = ARRAY_SIZE(servalt_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data servalt_desc = {
++ .desc = {
++ .name = "servalt-pinctrl",
++ .pins = servalt_pins,
++ .npins = ARRAY_SIZE(servalt_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .owner = THIS_MODULE,
++ },
+ };
+
+-static struct pinctrl_desc sparx5_desc = {
+- .name = "sparx5-pinctrl",
+- .pins = sparx5_pins,
+- .npins = ARRAY_SIZE(sparx5_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &ocelot_pmx_ops,
+- .confops = &ocelot_confops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data sparx5_desc = {
++ .desc = {
++ .name = "sparx5-pinctrl",
++ .pins = sparx5_pins,
++ .npins = ARRAY_SIZE(sparx5_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &ocelot_pmx_ops,
++ .confops = &ocelot_confops,
++ .owner = THIS_MODULE,
++ },
++ .pincfg_data = {
++ .pd_bit = BIT(4),
++ .pu_bit = BIT(3),
++ .drive_bits = GENMASK(1, 0),
++ .schmitt_bit = BIT(2),
++ },
+ };
+
+-static struct pinctrl_desc lan966x_desc = {
+- .name = "lan966x-pinctrl",
+- .pins = lan966x_pins,
+- .npins = ARRAY_SIZE(lan966x_pins),
+- .pctlops = &ocelot_pctl_ops,
+- .pmxops = &lan966x_pmx_ops,
+- .confops = &ocelot_confops,
+- .owner = THIS_MODULE,
++static struct ocelot_match_data lan966x_desc = {
++ .desc = {
++ .name = "lan966x-pinctrl",
++ .pins = lan966x_pins,
++ .npins = ARRAY_SIZE(lan966x_pins),
++ .pctlops = &ocelot_pctl_ops,
++ .pmxops = &lan966x_pmx_ops,
++ .confops = &ocelot_confops,
++ .owner = THIS_MODULE,
++ },
++ .pincfg_data = {
++ .pd_bit = BIT(3),
++ .pu_bit = BIT(2),
++ .drive_bits = GENMASK(1, 0),
++ },
+ };
+
+ static int ocelot_create_group_func_map(struct device *dev,
+@@ -1906,6 +1949,7 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
+
+ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ {
++ const struct ocelot_match_data *data;
+ struct device *dev = &pdev->dev;
+ struct ocelot_pinctrl *info;
+ struct regmap *pincfg;
+@@ -1921,7 +1965,16 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ if (!info)
+ return -ENOMEM;
+
+- info->desc = (struct pinctrl_desc *)device_get_match_data(dev);
++ data = device_get_match_data(dev);
++ if (!data)
++ return -EINVAL;
++
++ info->desc = devm_kmemdup(dev, &data->desc, sizeof(*info->desc),
++ GFP_KERNEL);
++ if (!info->desc)
++ return -ENOMEM;
++
++ info->pincfg_data = &data->pincfg_data;
+
+ base = devm_ioremap_resource(dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
+--
+2.35.1
+
--- /dev/null
+From 7a6afe153cfbc746f792ee43f16e8a4befe77f00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 21:37:50 +0200
+Subject: pinctrl: ocelot: Fix pincfg
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit ba9c4745fca70bf773b2d5c602dcd85d1a40b07a ]
+
+The blamed commit changed to use regmaps instead of __iomem. But it
+didn't update the register offsets to be at word offset, so it uses byte
+offset.
+Another issue with the same commit is that it has a limit of 32 registers
+which is incorrect. The sparx5 has 64 while lan966x has 77.
+
+Fixes: 076d9e71bcf8 ("pinctrl: ocelot: convert pinctrl to regmap")
+Acked-by: Colin Foster <colin.foster@in-advantage.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Link: https://lore.kernel.org/r/20220713193750.4079621-3-horatiu.vultur@microchip.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-ocelot.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index 2866365132fd..6ee9f0de8ede 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -1327,7 +1327,9 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
+ const struct ocelot_pincfg_data *opd = info->pincfg_data;
+ u32 regcfg;
+
+- ret = regmap_read(info->pincfg, pin, ®cfg);
++ ret = regmap_read(info->pincfg,
++ pin * regmap_get_reg_stride(info->pincfg),
++ ®cfg);
+ if (ret)
+ return ret;
+
+@@ -1359,14 +1361,18 @@ static int ocelot_pincfg_clrsetbits(struct ocelot_pinctrl *info, u32 regaddr,
+ u32 val;
+ int ret;
+
+- ret = regmap_read(info->pincfg, regaddr, &val);
++ ret = regmap_read(info->pincfg,
++ regaddr * regmap_get_reg_stride(info->pincfg),
++ &val);
+ if (ret)
+ return ret;
+
+ val &= ~clrbits;
+ val |= setbits;
+
+- ret = regmap_write(info->pincfg, regaddr, val);
++ ret = regmap_write(info->pincfg,
++ regaddr * regmap_get_reg_stride(info->pincfg),
++ val);
+
+ return ret;
+ }
+@@ -1926,7 +1932,8 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
+ {},
+ };
+
+-static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
++static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev,
++ const struct ocelot_pinctrl *info)
+ {
+ void __iomem *base;
+
+@@ -1934,7 +1941,7 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+- .max_register = 32,
++ .max_register = info->desc->npins * 4,
+ .name = "pincfg",
+ };
+
+@@ -1995,7 +2002,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+
+ /* Pinconf registers */
+ if (info->desc->confops) {
+- pincfg = ocelot_pinctrl_create_pincfg(pdev);
++ pincfg = ocelot_pinctrl_create_pincfg(pdev, info);
+ if (IS_ERR(pincfg))
+ dev_dbg(dev, "Failed to create pincfg regmap\n");
+ else
+--
+2.35.1
+
--- /dev/null
+From fca1b7c10ba41f30f82bf0da0192a500718d82b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 23:49:22 +0800
+Subject: pinctrl: ralink: Check for null return of devm_kcalloc
+
+From: William Dean <williamsukatube@gmail.com>
+
+[ Upstream commit c3b821e8e406d5650e587b7ac624ac24e9b780a8 ]
+
+Because of the possible failure of the allocation, data->domains might
+be NULL pointer and will cause the dereference of the NULL pointer
+later.
+Therefore, it might be better to check it and directly return -ENOMEM
+without releasing data manually if fails, because the comment of the
+devm_kmalloc() says "Memory allocated with this function is
+automatically freed on driver detach.".
+
+Fixes: a86854d0c599b ("treewide: devm_kzalloc() -> devm_kcalloc()")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@gmail.com>
+Link: https://lore.kernel.org/r/20220710154922.2610876-1-williamsukatube@163.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/ralink/pinctrl-ralink.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pinctrl/ralink/pinctrl-ralink.c b/drivers/pinctrl/ralink/pinctrl-ralink.c
+index 841f23f55c95..3a8268a43d74 100644
+--- a/drivers/pinctrl/ralink/pinctrl-ralink.c
++++ b/drivers/pinctrl/ralink/pinctrl-ralink.c
+@@ -266,6 +266,8 @@ static int ralink_pinmux_pins(struct ralink_priv *p)
+ p->func[i]->pin_count,
+ sizeof(int),
+ GFP_KERNEL);
++ if (!p->func[i]->pins)
++ return -ENOMEM;
+ for (j = 0; j < p->func[i]->pin_count; j++)
+ p->func[i]->pins[j] = p->func[i]->pin_first + j;
+
+--
+2.35.1
+
--- /dev/null
+From 3e8e459593beb1e5ddc78972e74caacf70105a6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 20:39:03 +0300
+Subject: pinctrl: ralink: rename MT7628(an) functions to MT76X8
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arınç ÜNAL <arinc.unal@arinc9.com>
+
+[ Upstream commit 150438c86f55989632005b92c94f4aa2ec562ed6 ]
+
+The functions that include "MT7628(an)" are for MT7628 and MT7688 SoCs.
+Rename them to MT76X8 to refer to both of the SoCs.
+
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Acked-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20220414173916.5552-2-arinc.unal@arinc9.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/ralink/pinctrl-mt7620.c | 218 ++++++++++++------------
+ 1 file changed, 109 insertions(+), 109 deletions(-)
+
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7620.c b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+index 6853b5b8b0fe..d3f9feec1f74 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7620.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+@@ -112,260 +112,260 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
++static struct rt2880_pmx_func pwm1_grp_mt76x8[] = {
+ FUNC("sdxc d6", 3, 19, 1),
+ FUNC("utif", 2, 19, 1),
+ FUNC("gpio", 1, 19, 1),
+ FUNC("pwm1", 0, 19, 1),
+ };
+
+-static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
++static struct rt2880_pmx_func pwm0_grp_mt76x8[] = {
+ FUNC("sdxc d7", 3, 18, 1),
+ FUNC("utif", 2, 18, 1),
+ FUNC("gpio", 1, 18, 1),
+ FUNC("pwm0", 0, 18, 1),
+ };
+
+-static struct rt2880_pmx_func uart2_grp_mt7628[] = {
++static struct rt2880_pmx_func uart2_grp_mt76x8[] = {
+ FUNC("sdxc d5 d4", 3, 20, 2),
+ FUNC("pwm", 2, 20, 2),
+ FUNC("gpio", 1, 20, 2),
+ FUNC("uart2", 0, 20, 2),
+ };
+
+-static struct rt2880_pmx_func uart1_grp_mt7628[] = {
++static struct rt2880_pmx_func uart1_grp_mt76x8[] = {
+ FUNC("sw_r", 3, 45, 2),
+ FUNC("pwm", 2, 45, 2),
+ FUNC("gpio", 1, 45, 2),
+ FUNC("uart1", 0, 45, 2),
+ };
+
+-static struct rt2880_pmx_func i2c_grp_mt7628[] = {
++static struct rt2880_pmx_func i2c_grp_mt76x8[] = {
+ FUNC("-", 3, 4, 2),
+ FUNC("debug", 2, 4, 2),
+ FUNC("gpio", 1, 4, 2),
+ FUNC("i2c", 0, 4, 2),
+ };
+
+-static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("refclk", 0, 37, 1) };
+-static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };
+-static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };
+-static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
++static struct rt2880_pmx_func refclk_grp_mt76x8[] = { FUNC("refclk", 0, 37, 1) };
++static struct rt2880_pmx_func perst_grp_mt76x8[] = { FUNC("perst", 0, 36, 1) };
++static struct rt2880_pmx_func wdt_grp_mt76x8[] = { FUNC("wdt", 0, 38, 1) };
++static struct rt2880_pmx_func spi_grp_mt76x8[] = { FUNC("spi", 0, 7, 4) };
+
+-static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
++static struct rt2880_pmx_func sd_mode_grp_mt76x8[] = {
+ FUNC("jtag", 3, 22, 8),
+ FUNC("utif", 2, 22, 8),
+ FUNC("gpio", 1, 22, 8),
+ FUNC("sdxc", 0, 22, 8),
+ };
+
+-static struct rt2880_pmx_func uart0_grp_mt7628[] = {
++static struct rt2880_pmx_func uart0_grp_mt76x8[] = {
+ FUNC("-", 3, 12, 2),
+ FUNC("-", 2, 12, 2),
+ FUNC("gpio", 1, 12, 2),
+ FUNC("uart0", 0, 12, 2),
+ };
+
+-static struct rt2880_pmx_func i2s_grp_mt7628[] = {
++static struct rt2880_pmx_func i2s_grp_mt76x8[] = {
+ FUNC("antenna", 3, 0, 4),
+ FUNC("pcm", 2, 0, 4),
+ FUNC("gpio", 1, 0, 4),
+ FUNC("i2s", 0, 0, 4),
+ };
+
+-static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
++static struct rt2880_pmx_func spi_cs1_grp_mt76x8[] = {
+ FUNC("-", 3, 6, 1),
+ FUNC("refclk", 2, 6, 1),
+ FUNC("gpio", 1, 6, 1),
+ FUNC("spi cs1", 0, 6, 1),
+ };
+
+-static struct rt2880_pmx_func spis_grp_mt7628[] = {
++static struct rt2880_pmx_func spis_grp_mt76x8[] = {
+ FUNC("pwm_uart2", 3, 14, 4),
+ FUNC("utif", 2, 14, 4),
+ FUNC("gpio", 1, 14, 4),
+ FUNC("spis", 0, 14, 4),
+ };
+
+-static struct rt2880_pmx_func gpio_grp_mt7628[] = {
++static struct rt2880_pmx_func gpio_grp_mt76x8[] = {
+ FUNC("pcie", 3, 11, 1),
+ FUNC("refclk", 2, 11, 1),
+ FUNC("gpio", 1, 11, 1),
+ FUNC("gpio", 0, 11, 1),
+ };
+
+-static struct rt2880_pmx_func p4led_kn_grp_mt7628[] = {
++static struct rt2880_pmx_func p4led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 30, 1),
+ FUNC("utif", 2, 30, 1),
+ FUNC("gpio", 1, 30, 1),
+ FUNC("p4led_kn", 0, 30, 1),
+ };
+
+-static struct rt2880_pmx_func p3led_kn_grp_mt7628[] = {
++static struct rt2880_pmx_func p3led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 31, 1),
+ FUNC("utif", 2, 31, 1),
+ FUNC("gpio", 1, 31, 1),
+ FUNC("p3led_kn", 0, 31, 1),
+ };
+
+-static struct rt2880_pmx_func p2led_kn_grp_mt7628[] = {
++static struct rt2880_pmx_func p2led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 32, 1),
+ FUNC("utif", 2, 32, 1),
+ FUNC("gpio", 1, 32, 1),
+ FUNC("p2led_kn", 0, 32, 1),
+ };
+
+-static struct rt2880_pmx_func p1led_kn_grp_mt7628[] = {
++static struct rt2880_pmx_func p1led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 33, 1),
+ FUNC("utif", 2, 33, 1),
+ FUNC("gpio", 1, 33, 1),
+ FUNC("p1led_kn", 0, 33, 1),
+ };
+
+-static struct rt2880_pmx_func p0led_kn_grp_mt7628[] = {
++static struct rt2880_pmx_func p0led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 34, 1),
+ FUNC("rsvd", 2, 34, 1),
+ FUNC("gpio", 1, 34, 1),
+ FUNC("p0led_kn", 0, 34, 1),
+ };
+
+-static struct rt2880_pmx_func wled_kn_grp_mt7628[] = {
++static struct rt2880_pmx_func wled_kn_grp_mt76x8[] = {
+ FUNC("rsvd", 3, 35, 1),
+ FUNC("rsvd", 2, 35, 1),
+ FUNC("gpio", 1, 35, 1),
+ FUNC("wled_kn", 0, 35, 1),
+ };
+
+-static struct rt2880_pmx_func p4led_an_grp_mt7628[] = {
++static struct rt2880_pmx_func p4led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 39, 1),
+ FUNC("utif", 2, 39, 1),
+ FUNC("gpio", 1, 39, 1),
+ FUNC("p4led_an", 0, 39, 1),
+ };
+
+-static struct rt2880_pmx_func p3led_an_grp_mt7628[] = {
++static struct rt2880_pmx_func p3led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 40, 1),
+ FUNC("utif", 2, 40, 1),
+ FUNC("gpio", 1, 40, 1),
+ FUNC("p3led_an", 0, 40, 1),
+ };
+
+-static struct rt2880_pmx_func p2led_an_grp_mt7628[] = {
++static struct rt2880_pmx_func p2led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 41, 1),
+ FUNC("utif", 2, 41, 1),
+ FUNC("gpio", 1, 41, 1),
+ FUNC("p2led_an", 0, 41, 1),
+ };
+
+-static struct rt2880_pmx_func p1led_an_grp_mt7628[] = {
++static struct rt2880_pmx_func p1led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 42, 1),
+ FUNC("utif", 2, 42, 1),
+ FUNC("gpio", 1, 42, 1),
+ FUNC("p1led_an", 0, 42, 1),
+ };
+
+-static struct rt2880_pmx_func p0led_an_grp_mt7628[] = {
++static struct rt2880_pmx_func p0led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 43, 1),
+ FUNC("rsvd", 2, 43, 1),
+ FUNC("gpio", 1, 43, 1),
+ FUNC("p0led_an", 0, 43, 1),
+ };
+
+-static struct rt2880_pmx_func wled_an_grp_mt7628[] = {
++static struct rt2880_pmx_func wled_an_grp_mt76x8[] = {
+ FUNC("rsvd", 3, 44, 1),
+ FUNC("rsvd", 2, 44, 1),
+ FUNC("gpio", 1, 44, 1),
+ FUNC("wled_an", 0, 44, 1),
+ };
+
+-#define MT7628_GPIO_MODE_MASK 0x3
+-
+-#define MT7628_GPIO_MODE_P4LED_KN 58
+-#define MT7628_GPIO_MODE_P3LED_KN 56
+-#define MT7628_GPIO_MODE_P2LED_KN 54
+-#define MT7628_GPIO_MODE_P1LED_KN 52
+-#define MT7628_GPIO_MODE_P0LED_KN 50
+-#define MT7628_GPIO_MODE_WLED_KN 48
+-#define MT7628_GPIO_MODE_P4LED_AN 42
+-#define MT7628_GPIO_MODE_P3LED_AN 40
+-#define MT7628_GPIO_MODE_P2LED_AN 38
+-#define MT7628_GPIO_MODE_P1LED_AN 36
+-#define MT7628_GPIO_MODE_P0LED_AN 34
+-#define MT7628_GPIO_MODE_WLED_AN 32
+-#define MT7628_GPIO_MODE_PWM1 30
+-#define MT7628_GPIO_MODE_PWM0 28
+-#define MT7628_GPIO_MODE_UART2 26
+-#define MT7628_GPIO_MODE_UART1 24
+-#define MT7628_GPIO_MODE_I2C 20
+-#define MT7628_GPIO_MODE_REFCLK 18
+-#define MT7628_GPIO_MODE_PERST 16
+-#define MT7628_GPIO_MODE_WDT 14
+-#define MT7628_GPIO_MODE_SPI 12
+-#define MT7628_GPIO_MODE_SDMODE 10
+-#define MT7628_GPIO_MODE_UART0 8
+-#define MT7628_GPIO_MODE_I2S 6
+-#define MT7628_GPIO_MODE_CS1 4
+-#define MT7628_GPIO_MODE_SPIS 2
+-#define MT7628_GPIO_MODE_GPIO 0
+-
+-static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
+- GRP_G("pwm1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_PWM1),
+- GRP_G("pwm0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_PWM0),
+- GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_UART2),
+- GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_UART1),
+- GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_I2C),
+- GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK),
+- GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST),
+- GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT),
+- GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI),
+- GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_SDMODE),
+- GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_UART0),
+- GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_I2S),
+- GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_CS1),
+- GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_SPIS),
+- GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_GPIO),
+- GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_WLED_AN),
+- GRP_G("p0led_an", p0led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P0LED_AN),
+- GRP_G("p1led_an", p1led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P1LED_AN),
+- GRP_G("p2led_an", p2led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P2LED_AN),
+- GRP_G("p3led_an", p3led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P3LED_AN),
+- GRP_G("p4led_an", p4led_an_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P4LED_AN),
+- GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_WLED_KN),
+- GRP_G("p0led_kn", p0led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P0LED_KN),
+- GRP_G("p1led_kn", p1led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P1LED_KN),
+- GRP_G("p2led_kn", p2led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P2LED_KN),
+- GRP_G("p3led_kn", p3led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P3LED_KN),
+- GRP_G("p4led_kn", p4led_kn_grp_mt7628, MT7628_GPIO_MODE_MASK,
+- 1, MT7628_GPIO_MODE_P4LED_KN),
++#define MT76X8_GPIO_MODE_MASK 0x3
++
++#define MT76X8_GPIO_MODE_P4LED_KN 58
++#define MT76X8_GPIO_MODE_P3LED_KN 56
++#define MT76X8_GPIO_MODE_P2LED_KN 54
++#define MT76X8_GPIO_MODE_P1LED_KN 52
++#define MT76X8_GPIO_MODE_P0LED_KN 50
++#define MT76X8_GPIO_MODE_WLED_KN 48
++#define MT76X8_GPIO_MODE_P4LED_AN 42
++#define MT76X8_GPIO_MODE_P3LED_AN 40
++#define MT76X8_GPIO_MODE_P2LED_AN 38
++#define MT76X8_GPIO_MODE_P1LED_AN 36
++#define MT76X8_GPIO_MODE_P0LED_AN 34
++#define MT76X8_GPIO_MODE_WLED_AN 32
++#define MT76X8_GPIO_MODE_PWM1 30
++#define MT76X8_GPIO_MODE_PWM0 28
++#define MT76X8_GPIO_MODE_UART2 26
++#define MT76X8_GPIO_MODE_UART1 24
++#define MT76X8_GPIO_MODE_I2C 20
++#define MT76X8_GPIO_MODE_REFCLK 18
++#define MT76X8_GPIO_MODE_PERST 16
++#define MT76X8_GPIO_MODE_WDT 14
++#define MT76X8_GPIO_MODE_SPI 12
++#define MT76X8_GPIO_MODE_SDMODE 10
++#define MT76X8_GPIO_MODE_UART0 8
++#define MT76X8_GPIO_MODE_I2S 6
++#define MT76X8_GPIO_MODE_CS1 4
++#define MT76X8_GPIO_MODE_SPIS 2
++#define MT76X8_GPIO_MODE_GPIO 0
++
++static struct rt2880_pmx_group mt76x8_pinmux_data[] = {
++ GRP_G("pwm1", pwm1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_PWM1),
++ GRP_G("pwm0", pwm0_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_PWM0),
++ GRP_G("uart2", uart2_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_UART2),
++ GRP_G("uart1", uart1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_UART1),
++ GRP_G("i2c", i2c_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_I2C),
++ GRP("refclk", refclk_grp_mt76x8, 1, MT76X8_GPIO_MODE_REFCLK),
++ GRP("perst", perst_grp_mt76x8, 1, MT76X8_GPIO_MODE_PERST),
++ GRP("wdt", wdt_grp_mt76x8, 1, MT76X8_GPIO_MODE_WDT),
++ GRP("spi", spi_grp_mt76x8, 1, MT76X8_GPIO_MODE_SPI),
++ GRP_G("sdmode", sd_mode_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_SDMODE),
++ GRP_G("uart0", uart0_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_UART0),
++ GRP_G("i2s", i2s_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_I2S),
++ GRP_G("spi cs1", spi_cs1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_CS1),
++ GRP_G("spis", spis_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_SPIS),
++ GRP_G("gpio", gpio_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_GPIO),
++ GRP_G("wled_an", wled_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_WLED_AN),
++ GRP_G("p0led_an", p0led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P0LED_AN),
++ GRP_G("p1led_an", p1led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P1LED_AN),
++ GRP_G("p2led_an", p2led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P2LED_AN),
++ GRP_G("p3led_an", p3led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P3LED_AN),
++ GRP_G("p4led_an", p4led_an_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P4LED_AN),
++ GRP_G("wled_kn", wled_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_WLED_KN),
++ GRP_G("p0led_kn", p0led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P0LED_KN),
++ GRP_G("p1led_kn", p1led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P1LED_KN),
++ GRP_G("p2led_kn", p2led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P2LED_KN),
++ GRP_G("p3led_kn", p3led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P3LED_KN),
++ GRP_G("p4led_kn", p4led_kn_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
++ 1, MT76X8_GPIO_MODE_P4LED_KN),
+ { 0 }
+ };
+
+ static int mt7620_pinmux_probe(struct platform_device *pdev)
+ {
+ if (is_mt76x8())
+- return rt2880_pinmux_init(pdev, mt7628an_pinmux_data);
++ return rt2880_pinmux_init(pdev, mt76x8_pinmux_data);
+ else
+ return rt2880_pinmux_init(pdev, mt7620a_pinmux_data);
+ }
+--
+2.35.1
+
--- /dev/null
+From 50713b0081f9f855b2c1899d110eaf3e90d89920 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 20:39:04 +0300
+Subject: pinctrl: ralink: rename pinctrl-rt2880 to pinctrl-ralink
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arınç ÜNAL <arinc.unal@arinc9.com>
+
+[ Upstream commit 6b3dd85b0bdec1a8308fa5dcbafcd5d55b5f3608 ]
+
+pinctrl-rt2880.c and pinmux.h make up the Ralink pinctrl driver. Rename
+pinctrl-rt2880.c to pinctrl-ralink.c. Rename pinmux.h to pinctrl-ralink.h.
+Fix references to it. Rename functions that include "rt2880" to "ralink".
+
+Remove PINCTRL_RT2880 symbol and make the existing PINCTRL_RALINK symbol
+compile pinctrl-ralink.c. Change the bool to "Ralink pinctrl driver".
+
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Acked-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20220414173916.5552-3-arinc.unal@arinc9.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/ralink/Kconfig | 16 ++--
+ drivers/pinctrl/ralink/Makefile | 2 +-
+ drivers/pinctrl/ralink/pinctrl-mt7620.c | 92 +++++++++----------
+ drivers/pinctrl/ralink/pinctrl-mt7621.c | 30 +++---
+ .../{pinctrl-rt2880.c => pinctrl-ralink.c} | 90 +++++++++---------
+ .../ralink/{pinmux.h => pinctrl-ralink.h} | 16 ++--
+ drivers/pinctrl/ralink/pinctrl-rt288x.c | 20 ++--
+ drivers/pinctrl/ralink/pinctrl-rt305x.c | 44 ++++-----
+ drivers/pinctrl/ralink/pinctrl-rt3883.c | 28 +++---
+ 9 files changed, 167 insertions(+), 171 deletions(-)
+ rename drivers/pinctrl/ralink/{pinctrl-rt2880.c => pinctrl-ralink.c} (73%)
+ rename drivers/pinctrl/ralink/{pinmux.h => pinctrl-ralink.h} (75%)
+
+diff --git a/drivers/pinctrl/ralink/Kconfig b/drivers/pinctrl/ralink/Kconfig
+index a76ee3deb8c3..d0f0a8f2b9b7 100644
+--- a/drivers/pinctrl/ralink/Kconfig
++++ b/drivers/pinctrl/ralink/Kconfig
+@@ -3,37 +3,33 @@ menu "Ralink pinctrl drivers"
+ depends on RALINK
+
+ config PINCTRL_RALINK
+- bool "Ralink pin control support"
+- default y if RALINK
+-
+-config PINCTRL_RT2880
+- bool "RT2880 pinctrl driver for RALINK/Mediatek SOCs"
++ bool "Ralink pinctrl driver"
+ select PINMUX
+ select GENERIC_PINCONF
+
+ config PINCTRL_MT7620
+ bool "mt7620 pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_MT7620
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_MT7621
+ bool "mt7621 pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_MT7621
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_RT288X
+ bool "RT288X pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_RT288X
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_RT305X
+ bool "RT305X pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_RT305X
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ config PINCTRL_RT3883
+ bool "RT3883 pinctrl driver for RALINK/Mediatek SOCs"
+ depends on RALINK && SOC_RT3883
+- select PINCTRL_RT2880
++ select PINCTRL_RALINK
+
+ endmenu
+diff --git a/drivers/pinctrl/ralink/Makefile b/drivers/pinctrl/ralink/Makefile
+index a15610206ced..2c1323b74e96 100644
+--- a/drivers/pinctrl/ralink/Makefile
++++ b/drivers/pinctrl/ralink/Makefile
+@@ -1,5 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+-obj-$(CONFIG_PINCTRL_RT2880) += pinctrl-rt2880.o
++obj-$(CONFIG_PINCTRL_RALINK) += pinctrl-ralink.o
+
+ obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o
+ obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7620.c b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+index d3f9feec1f74..51b863d85c51 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7620.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7620.c
+@@ -5,7 +5,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define MT7620_GPIO_MODE_UART0_SHIFT 2
+ #define MT7620_GPIO_MODE_UART0_MASK 0x7
+@@ -54,20 +54,20 @@
+ #define MT7620_GPIO_MODE_EPHY 15
+ #define MT7620_GPIO_MODE_PA 20
+
+-static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
+-static struct rt2880_pmx_func mdio_grp[] = {
++static struct ralink_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
++static struct ralink_pmx_func mdio_grp[] = {
+ FUNC("mdio", MT7620_GPIO_MODE_MDIO, 22, 2),
+ FUNC("refclk", MT7620_GPIO_MODE_MDIO_REFCLK, 22, 2),
+ };
+-static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
+-static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
+-static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
+-static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
+-static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
+-static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
+-static struct rt2880_pmx_func uartf_grp[] = {
++static struct ralink_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
++static struct ralink_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
++static struct ralink_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
++static struct ralink_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
++static struct ralink_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
++static struct ralink_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
++static struct ralink_pmx_func uartf_grp[] = {
+ FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8),
+ FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8),
+ FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8),
+@@ -76,20 +76,20 @@ static struct rt2880_pmx_func uartf_grp[] = {
+ FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4),
+ FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-static struct rt2880_pmx_func wdt_grp[] = {
++static struct ralink_pmx_func wdt_grp[] = {
+ FUNC("wdt rst", 0, 17, 1),
+ FUNC("wdt refclk", 0, 17, 1),
+ };
+-static struct rt2880_pmx_func pcie_rst_grp[] = {
++static struct ralink_pmx_func pcie_rst_grp[] = {
+ FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1),
+ FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1)
+ };
+-static struct rt2880_pmx_func nd_sd_grp[] = {
++static struct ralink_pmx_func nd_sd_grp[] = {
+ FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15),
+ FUNC("sd", MT7620_GPIO_MODE_SD, 47, 13)
+ };
+
+-static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
++static struct ralink_pmx_group mt7620a_pinmux_data[] = {
+ GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C),
+ GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK,
+ MT7620_GPIO_MODE_UART0_SHIFT),
+@@ -112,166 +112,166 @@ static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_func pwm1_grp_mt76x8[] = {
++static struct ralink_pmx_func pwm1_grp_mt76x8[] = {
+ FUNC("sdxc d6", 3, 19, 1),
+ FUNC("utif", 2, 19, 1),
+ FUNC("gpio", 1, 19, 1),
+ FUNC("pwm1", 0, 19, 1),
+ };
+
+-static struct rt2880_pmx_func pwm0_grp_mt76x8[] = {
++static struct ralink_pmx_func pwm0_grp_mt76x8[] = {
+ FUNC("sdxc d7", 3, 18, 1),
+ FUNC("utif", 2, 18, 1),
+ FUNC("gpio", 1, 18, 1),
+ FUNC("pwm0", 0, 18, 1),
+ };
+
+-static struct rt2880_pmx_func uart2_grp_mt76x8[] = {
++static struct ralink_pmx_func uart2_grp_mt76x8[] = {
+ FUNC("sdxc d5 d4", 3, 20, 2),
+ FUNC("pwm", 2, 20, 2),
+ FUNC("gpio", 1, 20, 2),
+ FUNC("uart2", 0, 20, 2),
+ };
+
+-static struct rt2880_pmx_func uart1_grp_mt76x8[] = {
++static struct ralink_pmx_func uart1_grp_mt76x8[] = {
+ FUNC("sw_r", 3, 45, 2),
+ FUNC("pwm", 2, 45, 2),
+ FUNC("gpio", 1, 45, 2),
+ FUNC("uart1", 0, 45, 2),
+ };
+
+-static struct rt2880_pmx_func i2c_grp_mt76x8[] = {
++static struct ralink_pmx_func i2c_grp_mt76x8[] = {
+ FUNC("-", 3, 4, 2),
+ FUNC("debug", 2, 4, 2),
+ FUNC("gpio", 1, 4, 2),
+ FUNC("i2c", 0, 4, 2),
+ };
+
+-static struct rt2880_pmx_func refclk_grp_mt76x8[] = { FUNC("refclk", 0, 37, 1) };
+-static struct rt2880_pmx_func perst_grp_mt76x8[] = { FUNC("perst", 0, 36, 1) };
+-static struct rt2880_pmx_func wdt_grp_mt76x8[] = { FUNC("wdt", 0, 38, 1) };
+-static struct rt2880_pmx_func spi_grp_mt76x8[] = { FUNC("spi", 0, 7, 4) };
++static struct ralink_pmx_func refclk_grp_mt76x8[] = { FUNC("refclk", 0, 37, 1) };
++static struct ralink_pmx_func perst_grp_mt76x8[] = { FUNC("perst", 0, 36, 1) };
++static struct ralink_pmx_func wdt_grp_mt76x8[] = { FUNC("wdt", 0, 38, 1) };
++static struct ralink_pmx_func spi_grp_mt76x8[] = { FUNC("spi", 0, 7, 4) };
+
+-static struct rt2880_pmx_func sd_mode_grp_mt76x8[] = {
++static struct ralink_pmx_func sd_mode_grp_mt76x8[] = {
+ FUNC("jtag", 3, 22, 8),
+ FUNC("utif", 2, 22, 8),
+ FUNC("gpio", 1, 22, 8),
+ FUNC("sdxc", 0, 22, 8),
+ };
+
+-static struct rt2880_pmx_func uart0_grp_mt76x8[] = {
++static struct ralink_pmx_func uart0_grp_mt76x8[] = {
+ FUNC("-", 3, 12, 2),
+ FUNC("-", 2, 12, 2),
+ FUNC("gpio", 1, 12, 2),
+ FUNC("uart0", 0, 12, 2),
+ };
+
+-static struct rt2880_pmx_func i2s_grp_mt76x8[] = {
++static struct ralink_pmx_func i2s_grp_mt76x8[] = {
+ FUNC("antenna", 3, 0, 4),
+ FUNC("pcm", 2, 0, 4),
+ FUNC("gpio", 1, 0, 4),
+ FUNC("i2s", 0, 0, 4),
+ };
+
+-static struct rt2880_pmx_func spi_cs1_grp_mt76x8[] = {
++static struct ralink_pmx_func spi_cs1_grp_mt76x8[] = {
+ FUNC("-", 3, 6, 1),
+ FUNC("refclk", 2, 6, 1),
+ FUNC("gpio", 1, 6, 1),
+ FUNC("spi cs1", 0, 6, 1),
+ };
+
+-static struct rt2880_pmx_func spis_grp_mt76x8[] = {
++static struct ralink_pmx_func spis_grp_mt76x8[] = {
+ FUNC("pwm_uart2", 3, 14, 4),
+ FUNC("utif", 2, 14, 4),
+ FUNC("gpio", 1, 14, 4),
+ FUNC("spis", 0, 14, 4),
+ };
+
+-static struct rt2880_pmx_func gpio_grp_mt76x8[] = {
++static struct ralink_pmx_func gpio_grp_mt76x8[] = {
+ FUNC("pcie", 3, 11, 1),
+ FUNC("refclk", 2, 11, 1),
+ FUNC("gpio", 1, 11, 1),
+ FUNC("gpio", 0, 11, 1),
+ };
+
+-static struct rt2880_pmx_func p4led_kn_grp_mt76x8[] = {
++static struct ralink_pmx_func p4led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 30, 1),
+ FUNC("utif", 2, 30, 1),
+ FUNC("gpio", 1, 30, 1),
+ FUNC("p4led_kn", 0, 30, 1),
+ };
+
+-static struct rt2880_pmx_func p3led_kn_grp_mt76x8[] = {
++static struct ralink_pmx_func p3led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 31, 1),
+ FUNC("utif", 2, 31, 1),
+ FUNC("gpio", 1, 31, 1),
+ FUNC("p3led_kn", 0, 31, 1),
+ };
+
+-static struct rt2880_pmx_func p2led_kn_grp_mt76x8[] = {
++static struct ralink_pmx_func p2led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 32, 1),
+ FUNC("utif", 2, 32, 1),
+ FUNC("gpio", 1, 32, 1),
+ FUNC("p2led_kn", 0, 32, 1),
+ };
+
+-static struct rt2880_pmx_func p1led_kn_grp_mt76x8[] = {
++static struct ralink_pmx_func p1led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 33, 1),
+ FUNC("utif", 2, 33, 1),
+ FUNC("gpio", 1, 33, 1),
+ FUNC("p1led_kn", 0, 33, 1),
+ };
+
+-static struct rt2880_pmx_func p0led_kn_grp_mt76x8[] = {
++static struct ralink_pmx_func p0led_kn_grp_mt76x8[] = {
+ FUNC("jtag", 3, 34, 1),
+ FUNC("rsvd", 2, 34, 1),
+ FUNC("gpio", 1, 34, 1),
+ FUNC("p0led_kn", 0, 34, 1),
+ };
+
+-static struct rt2880_pmx_func wled_kn_grp_mt76x8[] = {
++static struct ralink_pmx_func wled_kn_grp_mt76x8[] = {
+ FUNC("rsvd", 3, 35, 1),
+ FUNC("rsvd", 2, 35, 1),
+ FUNC("gpio", 1, 35, 1),
+ FUNC("wled_kn", 0, 35, 1),
+ };
+
+-static struct rt2880_pmx_func p4led_an_grp_mt76x8[] = {
++static struct ralink_pmx_func p4led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 39, 1),
+ FUNC("utif", 2, 39, 1),
+ FUNC("gpio", 1, 39, 1),
+ FUNC("p4led_an", 0, 39, 1),
+ };
+
+-static struct rt2880_pmx_func p3led_an_grp_mt76x8[] = {
++static struct ralink_pmx_func p3led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 40, 1),
+ FUNC("utif", 2, 40, 1),
+ FUNC("gpio", 1, 40, 1),
+ FUNC("p3led_an", 0, 40, 1),
+ };
+
+-static struct rt2880_pmx_func p2led_an_grp_mt76x8[] = {
++static struct ralink_pmx_func p2led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 41, 1),
+ FUNC("utif", 2, 41, 1),
+ FUNC("gpio", 1, 41, 1),
+ FUNC("p2led_an", 0, 41, 1),
+ };
+
+-static struct rt2880_pmx_func p1led_an_grp_mt76x8[] = {
++static struct ralink_pmx_func p1led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 42, 1),
+ FUNC("utif", 2, 42, 1),
+ FUNC("gpio", 1, 42, 1),
+ FUNC("p1led_an", 0, 42, 1),
+ };
+
+-static struct rt2880_pmx_func p0led_an_grp_mt76x8[] = {
++static struct ralink_pmx_func p0led_an_grp_mt76x8[] = {
+ FUNC("jtag", 3, 43, 1),
+ FUNC("rsvd", 2, 43, 1),
+ FUNC("gpio", 1, 43, 1),
+ FUNC("p0led_an", 0, 43, 1),
+ };
+
+-static struct rt2880_pmx_func wled_an_grp_mt76x8[] = {
++static struct ralink_pmx_func wled_an_grp_mt76x8[] = {
+ FUNC("rsvd", 3, 44, 1),
+ FUNC("rsvd", 2, 44, 1),
+ FUNC("gpio", 1, 44, 1),
+@@ -308,7 +308,7 @@ static struct rt2880_pmx_func wled_an_grp_mt76x8[] = {
+ #define MT76X8_GPIO_MODE_SPIS 2
+ #define MT76X8_GPIO_MODE_GPIO 0
+
+-static struct rt2880_pmx_group mt76x8_pinmux_data[] = {
++static struct ralink_pmx_group mt76x8_pinmux_data[] = {
+ GRP_G("pwm1", pwm1_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
+ 1, MT76X8_GPIO_MODE_PWM1),
+ GRP_G("pwm0", pwm0_grp_mt76x8, MT76X8_GPIO_MODE_MASK,
+@@ -365,9 +365,9 @@ static struct rt2880_pmx_group mt76x8_pinmux_data[] = {
+ static int mt7620_pinmux_probe(struct platform_device *pdev)
+ {
+ if (is_mt76x8())
+- return rt2880_pinmux_init(pdev, mt76x8_pinmux_data);
++ return ralink_pinmux_init(pdev, mt76x8_pinmux_data);
+ else
+- return rt2880_pinmux_init(pdev, mt7620a_pinmux_data);
++ return ralink_pinmux_init(pdev, mt7620a_pinmux_data);
+ }
+
+ static const struct of_device_id mt7620_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinctrl-mt7621.c b/drivers/pinctrl/ralink/pinctrl-mt7621.c
+index 7d96144c474e..14b89cb43d4c 100644
+--- a/drivers/pinctrl/ralink/pinctrl-mt7621.c
++++ b/drivers/pinctrl/ralink/pinctrl-mt7621.c
+@@ -3,7 +3,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define MT7621_GPIO_MODE_UART1 1
+ #define MT7621_GPIO_MODE_I2C 2
+@@ -34,40 +34,40 @@
+ #define MT7621_GPIO_MODE_SDHCI_SHIFT 18
+ #define MT7621_GPIO_MODE_SDHCI_GPIO 1
+
+-static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
+-static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
+-static struct rt2880_pmx_func uart3_grp[] = {
++static struct ralink_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
++static struct ralink_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
++static struct ralink_pmx_func uart3_grp[] = {
+ FUNC("uart3", 0, 5, 4),
+ FUNC("i2s", 2, 5, 4),
+ FUNC("spdif3", 3, 5, 4),
+ };
+-static struct rt2880_pmx_func uart2_grp[] = {
++static struct ralink_pmx_func uart2_grp[] = {
+ FUNC("uart2", 0, 9, 4),
+ FUNC("pcm", 2, 9, 4),
+ FUNC("spdif2", 3, 9, 4),
+ };
+-static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
+-static struct rt2880_pmx_func wdt_grp[] = {
++static struct ralink_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
++static struct ralink_pmx_func wdt_grp[] = {
+ FUNC("wdt rst", 0, 18, 1),
+ FUNC("wdt refclk", 2, 18, 1),
+ };
+-static struct rt2880_pmx_func pcie_rst_grp[] = {
++static struct ralink_pmx_func pcie_rst_grp[] = {
+ FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1),
+ FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1)
+ };
+-static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
+-static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
+-static struct rt2880_pmx_func spi_grp[] = {
++static struct ralink_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
++static struct ralink_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
++static struct ralink_pmx_func spi_grp[] = {
+ FUNC("spi", 0, 34, 7),
+ FUNC("nand1", 2, 34, 7),
+ };
+-static struct rt2880_pmx_func sdhci_grp[] = {
++static struct ralink_pmx_func sdhci_grp[] = {
+ FUNC("sdhci", 0, 41, 8),
+ FUNC("nand2", 2, 41, 8),
+ };
+-static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
++static struct ralink_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
+
+-static struct rt2880_pmx_group mt7621_pinmux_data[] = {
++static struct ralink_pmx_group mt7621_pinmux_data[] = {
+ GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1),
+ GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C),
+ GRP_G("uart3", uart3_grp, MT7621_GPIO_MODE_UART3_MASK,
+@@ -92,7 +92,7 @@ static struct rt2880_pmx_group mt7621_pinmux_data[] = {
+
+ static int mt7621_pinmux_probe(struct platform_device *pdev)
+ {
+- return rt2880_pinmux_init(pdev, mt7621_pinmux_data);
++ return ralink_pinmux_init(pdev, mt7621_pinmux_data);
+ }
+
+ static const struct of_device_id mt7621_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt2880.c b/drivers/pinctrl/ralink/pinctrl-ralink.c
+similarity index 73%
+rename from drivers/pinctrl/ralink/pinctrl-rt2880.c
+rename to drivers/pinctrl/ralink/pinctrl-ralink.c
+index 96fc06d1b8b9..841f23f55c95 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt2880.c
++++ b/drivers/pinctrl/ralink/pinctrl-ralink.c
+@@ -19,23 +19,23 @@
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/mt7620.h>
+
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+ #include "../core.h"
+ #include "../pinctrl-utils.h"
+
+ #define SYSC_REG_GPIO_MODE 0x60
+ #define SYSC_REG_GPIO_MODE2 0x64
+
+-struct rt2880_priv {
++struct ralink_priv {
+ struct device *dev;
+
+ struct pinctrl_pin_desc *pads;
+ struct pinctrl_desc *desc;
+
+- struct rt2880_pmx_func **func;
++ struct ralink_pmx_func **func;
+ int func_count;
+
+- struct rt2880_pmx_group *groups;
++ struct ralink_pmx_group *groups;
+ const char **group_names;
+ int group_count;
+
+@@ -43,27 +43,27 @@ struct rt2880_priv {
+ int max_pins;
+ };
+
+-static int rt2880_get_group_count(struct pinctrl_dev *pctrldev)
++static int ralink_get_group_count(struct pinctrl_dev *pctrldev)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ return p->group_count;
+ }
+
+-static const char *rt2880_get_group_name(struct pinctrl_dev *pctrldev,
++static const char *ralink_get_group_name(struct pinctrl_dev *pctrldev,
+ unsigned int group)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ return (group >= p->group_count) ? NULL : p->group_names[group];
+ }
+
+-static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
++static int ralink_get_group_pins(struct pinctrl_dev *pctrldev,
+ unsigned int group,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ if (group >= p->group_count)
+ return -EINVAL;
+@@ -74,35 +74,35 @@ static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
+ return 0;
+ }
+
+-static const struct pinctrl_ops rt2880_pctrl_ops = {
+- .get_groups_count = rt2880_get_group_count,
+- .get_group_name = rt2880_get_group_name,
+- .get_group_pins = rt2880_get_group_pins,
++static const struct pinctrl_ops ralink_pctrl_ops = {
++ .get_groups_count = ralink_get_group_count,
++ .get_group_name = ralink_get_group_name,
++ .get_group_pins = ralink_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinconf_generic_dt_free_map,
+ };
+
+-static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev)
++static int ralink_pmx_func_count(struct pinctrl_dev *pctrldev)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ return p->func_count;
+ }
+
+-static const char *rt2880_pmx_func_name(struct pinctrl_dev *pctrldev,
++static const char *ralink_pmx_func_name(struct pinctrl_dev *pctrldev,
+ unsigned int func)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ return p->func[func]->name;
+ }
+
+-static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
++static int ralink_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
+ unsigned int func,
+ const char * const **groups,
+ unsigned int * const num_groups)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ if (p->func[func]->group_count == 1)
+ *groups = &p->group_names[p->func[func]->groups[0]];
+@@ -114,10 +114,10 @@ static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
+ return 0;
+ }
+
+-static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
++static int ralink_pmx_group_enable(struct pinctrl_dev *pctrldev,
+ unsigned int func, unsigned int group)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+ u32 mode = 0;
+ u32 reg = SYSC_REG_GPIO_MODE;
+ int i;
+@@ -158,11 +158,11 @@ static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
+ return 0;
+ }
+
+-static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
++static int ralink_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin)
+ {
+- struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
++ struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev);
+
+ if (!p->gpio[pin]) {
+ dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
+@@ -172,28 +172,28 @@ static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
+ return 0;
+ }
+
+-static const struct pinmux_ops rt2880_pmx_group_ops = {
+- .get_functions_count = rt2880_pmx_func_count,
+- .get_function_name = rt2880_pmx_func_name,
+- .get_function_groups = rt2880_pmx_group_get_groups,
+- .set_mux = rt2880_pmx_group_enable,
+- .gpio_request_enable = rt2880_pmx_group_gpio_request_enable,
++static const struct pinmux_ops ralink_pmx_group_ops = {
++ .get_functions_count = ralink_pmx_func_count,
++ .get_function_name = ralink_pmx_func_name,
++ .get_function_groups = ralink_pmx_group_get_groups,
++ .set_mux = ralink_pmx_group_enable,
++ .gpio_request_enable = ralink_pmx_group_gpio_request_enable,
+ };
+
+-static struct pinctrl_desc rt2880_pctrl_desc = {
++static struct pinctrl_desc ralink_pctrl_desc = {
+ .owner = THIS_MODULE,
+- .name = "rt2880-pinmux",
+- .pctlops = &rt2880_pctrl_ops,
+- .pmxops = &rt2880_pmx_group_ops,
++ .name = "ralink-pinmux",
++ .pctlops = &ralink_pctrl_ops,
++ .pmxops = &ralink_pmx_group_ops,
+ };
+
+-static struct rt2880_pmx_func gpio_func = {
++static struct ralink_pmx_func gpio_func = {
+ .name = "gpio",
+ };
+
+-static int rt2880_pinmux_index(struct rt2880_priv *p)
++static int ralink_pinmux_index(struct ralink_priv *p)
+ {
+- struct rt2880_pmx_group *mux = p->groups;
++ struct ralink_pmx_group *mux = p->groups;
+ int i, j, c = 0;
+
+ /* count the mux functions */
+@@ -248,7 +248,7 @@ static int rt2880_pinmux_index(struct rt2880_priv *p)
+ return 0;
+ }
+
+-static int rt2880_pinmux_pins(struct rt2880_priv *p)
++static int ralink_pinmux_pins(struct ralink_priv *p)
+ {
+ int i, j;
+
+@@ -311,10 +311,10 @@ static int rt2880_pinmux_pins(struct rt2880_priv *p)
+ return 0;
+ }
+
+-int rt2880_pinmux_init(struct platform_device *pdev,
+- struct rt2880_pmx_group *data)
++int ralink_pinmux_init(struct platform_device *pdev,
++ struct ralink_pmx_group *data)
+ {
+- struct rt2880_priv *p;
++ struct ralink_priv *p;
+ struct pinctrl_dev *dev;
+ int err;
+
+@@ -322,23 +322,23 @@ int rt2880_pinmux_init(struct platform_device *pdev,
+ return -ENOTSUPP;
+
+ /* setup the private data */
+- p = devm_kzalloc(&pdev->dev, sizeof(struct rt2880_priv), GFP_KERNEL);
++ p = devm_kzalloc(&pdev->dev, sizeof(struct ralink_priv), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ p->dev = &pdev->dev;
+- p->desc = &rt2880_pctrl_desc;
++ p->desc = &ralink_pctrl_desc;
+ p->groups = data;
+ platform_set_drvdata(pdev, p);
+
+ /* init the device */
+- err = rt2880_pinmux_index(p);
++ err = ralink_pinmux_index(p);
+ if (err) {
+ dev_err(&pdev->dev, "failed to load index\n");
+ return err;
+ }
+
+- err = rt2880_pinmux_pins(p);
++ err = ralink_pinmux_pins(p);
+ if (err) {
+ dev_err(&pdev->dev, "failed to load pins\n");
+ return err;
+diff --git a/drivers/pinctrl/ralink/pinmux.h b/drivers/pinctrl/ralink/pinctrl-ralink.h
+similarity index 75%
+rename from drivers/pinctrl/ralink/pinmux.h
+rename to drivers/pinctrl/ralink/pinctrl-ralink.h
+index 0046abe3bcc7..134969409585 100644
+--- a/drivers/pinctrl/ralink/pinmux.h
++++ b/drivers/pinctrl/ralink/pinctrl-ralink.h
+@@ -3,8 +3,8 @@
+ * Copyright (C) 2012 John Crispin <john@phrozen.org>
+ */
+
+-#ifndef _RT288X_PINMUX_H__
+-#define _RT288X_PINMUX_H__
++#ifndef _PINCTRL_RALINK_H__
++#define _PINCTRL_RALINK_H__
+
+ #define FUNC(name, value, pin_first, pin_count) \
+ { name, value, pin_first, pin_count }
+@@ -19,9 +19,9 @@
+ .func = _func, .gpio = _gpio, \
+ .func_count = ARRAY_SIZE(_func) }
+
+-struct rt2880_pmx_group;
++struct ralink_pmx_group;
+
+-struct rt2880_pmx_func {
++struct ralink_pmx_func {
+ const char *name;
+ const char value;
+
+@@ -35,7 +35,7 @@ struct rt2880_pmx_func {
+ int enabled;
+ };
+
+-struct rt2880_pmx_group {
++struct ralink_pmx_group {
+ const char *name;
+ int enabled;
+
+@@ -43,11 +43,11 @@ struct rt2880_pmx_group {
+ const char mask;
+ const char gpio;
+
+- struct rt2880_pmx_func *func;
++ struct ralink_pmx_func *func;
+ int func_count;
+ };
+
+-int rt2880_pinmux_init(struct platform_device *pdev,
+- struct rt2880_pmx_group *data);
++int ralink_pinmux_init(struct platform_device *pdev,
++ struct ralink_pmx_group *data);
+
+ #endif
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt288x.c b/drivers/pinctrl/ralink/pinctrl-rt288x.c
+index 0744aebbace5..40c45140ff8a 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt288x.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt288x.c
+@@ -4,7 +4,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define RT2880_GPIO_MODE_I2C BIT(0)
+ #define RT2880_GPIO_MODE_UART0 BIT(1)
+@@ -15,15 +15,15 @@
+ #define RT2880_GPIO_MODE_SDRAM BIT(6)
+ #define RT2880_GPIO_MODE_PCI BIT(7)
+
+-static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
+-static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
+-static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
+-static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
+-static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
++static struct ralink_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
++static struct ralink_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct ralink_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct ralink_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
++static struct ralink_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
+
+-static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
++static struct ralink_pmx_group rt2880_pinmux_data_act[] = {
+ GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI),
+ GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0),
+@@ -36,7 +36,7 @@ static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
+
+ static int rt288x_pinmux_probe(struct platform_device *pdev)
+ {
+- return rt2880_pinmux_init(pdev, rt2880_pinmux_data_act);
++ return ralink_pinmux_init(pdev, rt2880_pinmux_data_act);
+ }
+
+ static const struct of_device_id rt288x_pinmux_match[] = {
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt305x.c b/drivers/pinctrl/ralink/pinctrl-rt305x.c
+index 5d8fa156c003..25527ca1ccaa 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt305x.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt305x.c
+@@ -5,7 +5,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define RT305X_GPIO_MODE_UART0_SHIFT 2
+ #define RT305X_GPIO_MODE_UART0_MASK 0x7
+@@ -31,9 +31,9 @@
+ #define RT3352_GPIO_MODE_LNA 18
+ #define RT3352_GPIO_MODE_PA 20
+
+-static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartf_func[] = {
++static struct ralink_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartf_func[] = {
+ FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8),
+ FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8),
+ FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8),
+@@ -42,28 +42,28 @@ static struct rt2880_pmx_func uartf_func[] = {
+ FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4),
+ FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
+-static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
+-static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
+-static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
+-static struct rt2880_pmx_func rt5350_cs1_func[] = {
++static struct ralink_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
++static struct ralink_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct ralink_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct ralink_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
++static struct ralink_pmx_func rt5350_cs1_func[] = {
+ FUNC("spi_cs1", 0, 27, 1),
+ FUNC("wdg_cs1", 1, 27, 1),
+ };
+-static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
+-static struct rt2880_pmx_func rt3352_rgmii_func[] = {
++static struct ralink_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
++static struct ralink_pmx_func rt3352_rgmii_func[] = {
+ FUNC("rgmii", 0, 24, 12)
+ };
+-static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
+-static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
+-static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
+-static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
+-static struct rt2880_pmx_func rt3352_cs1_func[] = {
++static struct ralink_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
++static struct ralink_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
++static struct ralink_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
++static struct ralink_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
++static struct ralink_pmx_func rt3352_cs1_func[] = {
+ FUNC("spi_cs1", 0, 45, 1),
+ FUNC("wdg_cs1", 1, 45, 1),
+ };
+
+-static struct rt2880_pmx_group rt3050_pinmux_data[] = {
++static struct ralink_pmx_group rt3050_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
+@@ -76,7 +76,7 @@ static struct rt2880_pmx_group rt3050_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_group rt3352_pinmux_data[] = {
++static struct ralink_pmx_group rt3352_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
+@@ -92,7 +92,7 @@ static struct rt2880_pmx_group rt3352_pinmux_data[] = {
+ { 0 }
+ };
+
+-static struct rt2880_pmx_group rt5350_pinmux_data[] = {
++static struct ralink_pmx_group rt5350_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
+@@ -107,11 +107,11 @@ static struct rt2880_pmx_group rt5350_pinmux_data[] = {
+ static int rt305x_pinmux_probe(struct platform_device *pdev)
+ {
+ if (soc_is_rt5350())
+- return rt2880_pinmux_init(pdev, rt5350_pinmux_data);
++ return ralink_pinmux_init(pdev, rt5350_pinmux_data);
+ else if (soc_is_rt305x() || soc_is_rt3350())
+- return rt2880_pinmux_init(pdev, rt3050_pinmux_data);
++ return ralink_pinmux_init(pdev, rt3050_pinmux_data);
+ else if (soc_is_rt3352())
+- return rt2880_pinmux_init(pdev, rt3352_pinmux_data);
++ return ralink_pinmux_init(pdev, rt3352_pinmux_data);
+ else
+ return -EINVAL;
+ }
+diff --git a/drivers/pinctrl/ralink/pinctrl-rt3883.c b/drivers/pinctrl/ralink/pinctrl-rt3883.c
+index 3e0e1b4caa64..0b8674dbe188 100644
+--- a/drivers/pinctrl/ralink/pinctrl-rt3883.c
++++ b/drivers/pinctrl/ralink/pinctrl-rt3883.c
+@@ -3,7 +3,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/of.h>
+-#include "pinmux.h"
++#include "pinctrl-ralink.h"
+
+ #define RT3883_GPIO_MODE_UART0_SHIFT 2
+ #define RT3883_GPIO_MODE_UART0_MASK 0x7
+@@ -39,9 +39,9 @@
+ #define RT3883_GPIO_MODE_LNA_G_GPIO 0x3
+ #define RT3883_GPIO_MODE_LNA_G _RT3883_GPIO_MODE_LNA_G(RT3883_GPIO_MODE_LNA_G_MASK)
+
+-static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
+-static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
+-static struct rt2880_pmx_func uartf_func[] = {
++static struct ralink_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
++static struct ralink_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
++static struct ralink_pmx_func uartf_func[] = {
+ FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8),
+ FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8),
+ FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8),
+@@ -50,21 +50,21 @@ static struct rt2880_pmx_func uartf_func[] = {
+ FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4),
+ FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4),
+ };
+-static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
+-static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
+-static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
+-static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
+-static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) };
+-static struct rt2880_pmx_func pci_func[] = {
++static struct ralink_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
++static struct ralink_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
++static struct ralink_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
++static struct ralink_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
++static struct ralink_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) };
++static struct ralink_pmx_func pci_func[] = {
+ FUNC("pci-dev", 0, 40, 32),
+ FUNC("pci-host2", 1, 40, 32),
+ FUNC("pci-host1", 2, 40, 32),
+ FUNC("pci-fnc", 3, 40, 32)
+ };
+-static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
+-static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) };
++static struct ralink_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
++static struct ralink_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) };
+
+-static struct rt2880_pmx_group rt3883_pinmux_data[] = {
++static struct ralink_pmx_group rt3883_pinmux_data[] = {
+ GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C),
+ GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI),
+ GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK,
+@@ -83,7 +83,7 @@ static struct rt2880_pmx_group rt3883_pinmux_data[] = {
+
+ static int rt3883_pinmux_probe(struct platform_device *pdev)
+ {
+- return rt2880_pinmux_init(pdev, rt3883_pinmux_data);
++ return ralink_pinmux_init(pdev, rt3883_pinmux_data);
+ }
+
+ static const struct of_device_id rt3883_pinmux_match[] = {
+--
+2.35.1
+
--- /dev/null
+From 813593b032046338f6c1d1352c70a476ce55d793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 23:48:22 +0800
+Subject: pinctrl: sunplus: Add check for kcalloc
+
+From: William Dean <williamsukatube@gmail.com>
+
+[ Upstream commit acf50233fc979b566e3b87d329191dcd01e2a72c ]
+
+As the potential failure of the kcalloc(),
+it should be better to check it in order to
+avoid the dereference of the NULL pointer.
+
+Fixes: aa74c44be19c8 ("pinctrl: Add driver for Sunplus SP7021")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@gmail.com>
+Link: https://lore.kernel.org/r/20220710154822.2610801-1-williamsukatube@163.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/sunplus/sppctl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c
+index 3ba47040ac42..2b3335ab56c6 100644
+--- a/drivers/pinctrl/sunplus/sppctl.c
++++ b/drivers/pinctrl/sunplus/sppctl.c
+@@ -871,6 +871,9 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
+ }
+
+ *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
++ if (*map == NULL)
++ return -ENOMEM;
++
+ for (i = 0; i < (*num_maps); i++) {
+ dt_pin = be32_to_cpu(list[i]);
+ pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
+--
+2.35.1
+
--- /dev/null
+From 4bd9269b9b936b826cd929404fab80a96902afd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:10:09 +0400
+Subject: power/reset: arm-versatile: Fix refcount leak in
+ versatile_reboot_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 80192eff64eee9b3bc0594a47381937b94b9d65a ]
+
+of_find_matching_node_and_match() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 0e545f57b708 ("power: reset: driver for the Versatile syscon reboot")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/reset/arm-versatile-reboot.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/power/reset/arm-versatile-reboot.c b/drivers/power/reset/arm-versatile-reboot.c
+index 08d0a07b58ef..c7624d7611a7 100644
+--- a/drivers/power/reset/arm-versatile-reboot.c
++++ b/drivers/power/reset/arm-versatile-reboot.c
+@@ -146,6 +146,7 @@ static int __init versatile_reboot_probe(void)
+ versatile_reboot_type = (enum versatile_reboot)reboot_id->data;
+
+ syscon_regmap = syscon_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(syscon_regmap))
+ return PTR_ERR(syscon_regmap);
+
+--
+2.35.1
+
--- /dev/null
+From 438bde062456d8356a462c8e841580b7ba0c9e63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 10:42:49 +0800
+Subject: power: supply: ab8500_fg: add missing destroy_workqueue in
+ ab8500_fg_probe
+
+From: Gao Chao <gaochao49@huawei.com>
+
+[ Upstream commit 0f5de2f0532229752d923c769a5b202ae437523b ]
+
+In ab8500_fg_probe, misses destroy_workqueue in error path, this patch
+fixes that.
+
+Fixes: 010ddb813f35 ("power: supply: ab8500_fg: Allocate wq in probe")
+Signed-off-by: Gao Chao <gaochao49@huawei.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/ab8500_fg.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
+index ec8a404d71b4..4339fa9ff009 100644
+--- a/drivers/power/supply/ab8500_fg.c
++++ b/drivers/power/supply/ab8500_fg.c
+@@ -3148,6 +3148,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ ret = ab8500_fg_init_hw_registers(di);
+ if (ret) {
+ dev_err(dev, "failed to initialize registers\n");
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+
+@@ -3159,6 +3160,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ di->fg_psy = devm_power_supply_register(dev, &ab8500_fg_desc, &psy_cfg);
+ if (IS_ERR(di->fg_psy)) {
+ dev_err(dev, "failed to register FG psy\n");
++ destroy_workqueue(di->fg_wq);
+ return PTR_ERR(di->fg_psy);
+ }
+
+@@ -3174,8 +3176,10 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ /* Register primary interrupt handlers */
+ for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) {
+ irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name);
+- if (irq < 0)
++ if (irq < 0) {
++ destroy_workqueue(di->fg_wq);
+ return irq;
++ }
+
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ ab8500_fg_irq[i].isr,
+@@ -3185,6 +3189,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ if (ret != 0) {
+ dev_err(dev, "failed to request %s IRQ %d: %d\n",
+ ab8500_fg_irq[i].name, irq, ret);
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+ dev_dbg(dev, "Requested %s IRQ %d: %d\n",
+@@ -3200,6 +3205,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ ret = ab8500_fg_sysfs_init(di);
+ if (ret) {
+ dev_err(dev, "failed to create sysfs entry\n");
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+
+@@ -3207,6 +3213,7 @@ static int ab8500_fg_probe(struct platform_device *pdev)
+ if (ret) {
+ dev_err(dev, "failed to create FG psy\n");
+ ab8500_fg_sysfs_exit(di);
++ destroy_workqueue(di->fg_wq);
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 73b3de2752d1e783e93f0451666a8d78424aa59b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:36 -0500
+Subject: RDMA/irdma: Do not advertise 1GB page size for x722
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 5e8afb8792f3b6ae7ccf700f8c19225382636401 ]
+
+x722 does not support 1GB page size but the irdma driver incorrectly
+advertises 1GB page size support for x722 device to ib_core to compute the
+best page size to use on this MR. This could lead to incorrect start
+offsets computed by hardware on the MR.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/i40iw_hw.c | 1 +
+ drivers/infiniband/hw/irdma/icrdma_hw.c | 1 +
+ drivers/infiniband/hw/irdma/irdma.h | 1 +
+ drivers/infiniband/hw/irdma/verbs.c | 4 ++--
+ 4 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/i40iw_hw.c b/drivers/infiniband/hw/irdma/i40iw_hw.c
+index e46fc110004d..50299f58b6b3 100644
+--- a/drivers/infiniband/hw/irdma/i40iw_hw.c
++++ b/drivers/infiniband/hw/irdma/i40iw_hw.c
+@@ -201,6 +201,7 @@ void i40iw_init_hw(struct irdma_sc_dev *dev)
+ dev->hw_attrs.uk_attrs.max_hw_read_sges = I40IW_MAX_SGE_RD;
+ dev->hw_attrs.max_hw_device_pages = I40IW_MAX_PUSH_PAGE_COUNT;
+ dev->hw_attrs.uk_attrs.max_hw_inline = I40IW_MAX_INLINE_DATA_SIZE;
++ dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M;
+ dev->hw_attrs.max_hw_ird = I40IW_MAX_IRD_SIZE;
+ dev->hw_attrs.max_hw_ord = I40IW_MAX_ORD_SIZE;
+ dev->hw_attrs.max_hw_wqes = I40IW_MAX_WQ_ENTRIES;
+diff --git a/drivers/infiniband/hw/irdma/icrdma_hw.c b/drivers/infiniband/hw/irdma/icrdma_hw.c
+index cf53b17510cd..5986fd906308 100644
+--- a/drivers/infiniband/hw/irdma/icrdma_hw.c
++++ b/drivers/infiniband/hw/irdma/icrdma_hw.c
+@@ -139,6 +139,7 @@ void icrdma_init_hw(struct irdma_sc_dev *dev)
+ dev->cqp_db = dev->hw_regs[IRDMA_CQPDB];
+ dev->cq_ack_db = dev->hw_regs[IRDMA_CQACK];
+ dev->irq_ops = &icrdma_irq_ops;
++ dev->hw_attrs.page_size_cap = SZ_4K | SZ_2M | SZ_1G;
+ dev->hw_attrs.max_hw_ird = ICRDMA_MAX_IRD_SIZE;
+ dev->hw_attrs.max_hw_ord = ICRDMA_MAX_ORD_SIZE;
+ dev->hw_attrs.max_stat_inst = ICRDMA_MAX_STATS_COUNT;
+diff --git a/drivers/infiniband/hw/irdma/irdma.h b/drivers/infiniband/hw/irdma/irdma.h
+index 46c12334c735..4789e85d717b 100644
+--- a/drivers/infiniband/hw/irdma/irdma.h
++++ b/drivers/infiniband/hw/irdma/irdma.h
+@@ -127,6 +127,7 @@ struct irdma_hw_attrs {
+ u64 max_hw_outbound_msg_size;
+ u64 max_hw_inbound_msg_size;
+ u64 max_mr_size;
++ u64 page_size_cap;
+ u32 min_hw_qp_id;
+ u32 min_hw_aeq_size;
+ u32 max_hw_aeq_size;
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 52f3e88f8569..6daa149dcbda 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -30,7 +30,7 @@ static int irdma_query_device(struct ib_device *ibdev,
+ props->vendor_part_id = pcidev->device;
+
+ props->hw_ver = rf->pcidev->revision;
+- props->page_size_cap = SZ_4K | SZ_2M | SZ_1G;
++ props->page_size_cap = hw_attrs->page_size_cap;
+ props->max_mr_size = hw_attrs->max_mr_size;
+ props->max_qp = rf->max_qp - rf->used_qps;
+ props->max_qp_wr = hw_attrs->max_qp_wr;
+@@ -2764,7 +2764,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+
+ if (req.reg_type == IRDMA_MEMREG_TYPE_MEM) {
+ iwmr->page_size = ib_umem_find_best_pgsz(region,
+- SZ_4K | SZ_2M | SZ_1G,
++ iwdev->rf->sc_dev.hw_attrs.page_size_cap,
+ virt);
+ if (unlikely(!iwmr->page_size)) {
+ kfree(iwmr);
+--
+2.35.1
+
--- /dev/null
+From f1feef3fba959058181744c89d3945f41e5ce6e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:37 -0500
+Subject: RDMA/irdma: Fix sleep from invalid context BUG
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit cc0315564d6eec91c716d314b743321be24c70b3 ]
+
+Taking the qos_mutex to process RoCEv2 QP's on netdev events causes a
+kernel splat.
+
+Fix this by removing the handling for RoCEv2 in
+irdma_cm_teardown_connections that uses the mutex. This handling is only
+needed for iWARP to avoid having connections established while the link is
+down or having connections remain functional after the IP address is
+removed.
+
+ BUG: sleeping function called from invalid context at kernel/locking/mutex.
+ Call Trace:
+ kernel: dump_stack+0x66/0x90
+ kernel: ___might_sleep.cold.92+0x8d/0x9a
+ kernel: mutex_lock+0x1c/0x40
+ kernel: irdma_cm_teardown_connections+0x28e/0x4d0 [irdma]
+ kernel: ? check_preempt_curr+0x7a/0x90
+ kernel: ? select_idle_sibling+0x22/0x3c0
+ kernel: ? select_task_rq_fair+0x94c/0xc90
+ kernel: ? irdma_exec_cqp_cmd+0xc27/0x17c0 [irdma]
+ kernel: ? __wake_up_common+0x7a/0x190
+ kernel: irdma_if_notify+0x3cc/0x450 [irdma]
+ kernel: ? sched_clock_cpu+0xc/0xb0
+ kernel: irdma_inet6addr_event+0xc6/0x150 [irdma]
+
+Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager")
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/cm.c | 50 --------------------------------
+ 1 file changed, 50 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
+index 638bf4a1ed94..646fa8677490 100644
+--- a/drivers/infiniband/hw/irdma/cm.c
++++ b/drivers/infiniband/hw/irdma/cm.c
+@@ -4231,10 +4231,6 @@ void irdma_cm_teardown_connections(struct irdma_device *iwdev, u32 *ipaddr,
+ struct irdma_cm_node *cm_node;
+ struct list_head teardown_list;
+ struct ib_qp_attr attr;
+- struct irdma_sc_vsi *vsi = &iwdev->vsi;
+- struct irdma_sc_qp *sc_qp;
+- struct irdma_qp *qp;
+- int i;
+
+ INIT_LIST_HEAD(&teardown_list);
+
+@@ -4251,52 +4247,6 @@ void irdma_cm_teardown_connections(struct irdma_device *iwdev, u32 *ipaddr,
+ irdma_cm_disconn(cm_node->iwqp);
+ irdma_rem_ref_cm_node(cm_node);
+ }
+- if (!iwdev->roce_mode)
+- return;
+-
+- INIT_LIST_HEAD(&teardown_list);
+- for (i = 0; i < IRDMA_MAX_USER_PRIORITY; i++) {
+- mutex_lock(&vsi->qos[i].qos_mutex);
+- list_for_each_safe (list_node, list_core_temp,
+- &vsi->qos[i].qplist) {
+- u32 qp_ip[4];
+-
+- sc_qp = container_of(list_node, struct irdma_sc_qp,
+- list);
+- if (sc_qp->qp_uk.qp_type != IRDMA_QP_TYPE_ROCE_RC)
+- continue;
+-
+- qp = sc_qp->qp_uk.back_qp;
+- if (!disconnect_all) {
+- if (nfo->ipv4)
+- qp_ip[0] = qp->udp_info.local_ipaddr[3];
+- else
+- memcpy(qp_ip,
+- &qp->udp_info.local_ipaddr[0],
+- sizeof(qp_ip));
+- }
+-
+- if (disconnect_all ||
+- (nfo->vlan_id == (qp->udp_info.vlan_tag & VLAN_VID_MASK) &&
+- !memcmp(qp_ip, ipaddr, nfo->ipv4 ? 4 : 16))) {
+- spin_lock(&iwdev->rf->qptable_lock);
+- if (iwdev->rf->qp_table[sc_qp->qp_uk.qp_id]) {
+- irdma_qp_add_ref(&qp->ibqp);
+- list_add(&qp->teardown_entry,
+- &teardown_list);
+- }
+- spin_unlock(&iwdev->rf->qptable_lock);
+- }
+- }
+- mutex_unlock(&vsi->qos[i].qos_mutex);
+- }
+-
+- list_for_each_safe (list_node, list_core_temp, &teardown_list) {
+- qp = container_of(list_node, struct irdma_qp, teardown_entry);
+- attr.qp_state = IB_QPS_ERR;
+- irdma_modify_qp_roce(&qp->ibqp, &attr, IB_QP_STATE, NULL);
+- irdma_qp_rem_ref(&qp->ibqp);
+- }
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 01b5a83ad771ae15e27c3232cd772a5bf9b386e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 May 2022 11:52:54 +0300
+Subject: Revert "e1000e: Fix possible HW unit hang after an s0ix exit"
+
+From: Sasha Neftin <sasha.neftin@intel.com>
+
+[ Upstream commit 6cfa45361d3eac31ba67d7d0bbef547151450106 ]
+
+This reverts commit 1866aa0d0d6492bc2f8d22d0df49abaccf50cddd.
+
+Commit 1866aa0d0d64 ("e1000e: Fix possible HW unit hang after an s0ix
+exit") was a workaround for CSME problem to handle messages comes via H2ME
+mailbox. This problem has been fixed by patch "e1000e: Enable the GPT
+clock before sending message to the CSME".
+
+Fixes: 3e55d231716e ("e1000e: Add handshake with the CSME to support S0ix")
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=214821
+Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e1000e/hw.h | 1 -
+ drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 ----
+ drivers/net/ethernet/intel/e1000e/ich8lan.h | 1 -
+ drivers/net/ethernet/intel/e1000e/netdev.c | 26 ---------------------
+ 4 files changed, 32 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
+index 13382df2f2ef..bcf680e83811 100644
+--- a/drivers/net/ethernet/intel/e1000e/hw.h
++++ b/drivers/net/ethernet/intel/e1000e/hw.h
+@@ -630,7 +630,6 @@ struct e1000_phy_info {
+ bool disable_polarity_correction;
+ bool is_mdix;
+ bool polarity_correction;
+- bool reset_disable;
+ bool speed_downgraded;
+ bool autoneg_wait_to_complete;
+ };
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+index e6c8e6d5234f..9466f65a6da7 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+@@ -2050,10 +2050,6 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
+ bool blocked = false;
+ int i = 0;
+
+- /* Check the PHY (LCD) reset flag */
+- if (hw->phy.reset_disable)
+- return true;
+-
+ while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
+ (i++ < 30))
+ usleep_range(10000, 11000);
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+index 638a3ddd7ada..2504b11c3169 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+@@ -271,7 +271,6 @@
+ #define I217_CGFREG_ENABLE_MTA_RESET 0x0002
+ #define I217_MEMPWR PHY_REG(772, 26)
+ #define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
+-#define I217_MEMPWR_MOEM 0x1000
+
+ /* Receive Address Initial CRC Calculation */
+ #define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index c64102b29862..f1729940e46c 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -6991,21 +6991,8 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
+ struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+- struct e1000_hw *hw = &adapter->hw;
+- u16 phy_data;
+ int rc;
+
+- if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+- hw->mac.type >= e1000_pch_adp) {
+- /* Mask OEM Bits / Gig Disable / Restart AN (772_26[12] = 1) */
+- e1e_rphy(hw, I217_MEMPWR, &phy_data);
+- phy_data |= I217_MEMPWR_MOEM;
+- e1e_wphy(hw, I217_MEMPWR, phy_data);
+-
+- /* Disable LCD reset */
+- hw->phy.reset_disable = true;
+- }
+-
+ e1000e_flush_lpic(pdev);
+
+ e1000e_pm_freeze(dev);
+@@ -7027,8 +7014,6 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
+ struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+- struct e1000_hw *hw = &adapter->hw;
+- u16 phy_data;
+ int rc;
+
+ /* Introduce S0ix implementation */
+@@ -7039,17 +7024,6 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
+ if (rc)
+ return rc;
+
+- if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
+- hw->mac.type >= e1000_pch_adp) {
+- /* Unmask OEM Bits / Gig Disable / Restart AN 772_26[12] = 0 */
+- e1e_rphy(hw, I217_MEMPWR, &phy_data);
+- phy_data &= ~I217_MEMPWR_MOEM;
+- e1e_wphy(hw, I217_MEMPWR, phy_data);
+-
+- /* Enable LCD reset */
+- hw->phy.reset_disable = false;
+- }
+-
+ return e1000e_pm_thaw(dev);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 96a978bb92e8850489367b169751b9f83ab4daaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 19:06:01 +0800
+Subject: selftests: gpio: fix include path to kernel headers for out of tree
+ builds
+
+From: Kent Gibson <warthog618@gmail.com>
+
+[ Upstream commit f63731e18e8d8350e05b0176e39a76639f6483c7 ]
+
+When building selftests out of the kernel tree the gpio.h the include
+path is incorrect and the build falls back to the system includes
+which may be outdated.
+
+Add the KHDR_INCLUDES to the CFLAGS to include the gpio.h from the
+build tree.
+
+Fixes: 4f4d0af7b2d9 ("selftests: gpio: restore CFLAGS options")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Kent Gibson <warthog618@gmail.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/gpio/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile
+index 71b306602368..616ed4019655 100644
+--- a/tools/testing/selftests/gpio/Makefile
++++ b/tools/testing/selftests/gpio/Makefile
+@@ -3,6 +3,6 @@
+ TEST_PROGS := gpio-mockup.sh gpio-sim.sh
+ TEST_FILES := gpio-mockup-sysfs.sh
+ TEST_GEN_PROGS_EXTENDED := gpio-mockup-cdev gpio-chip-info gpio-line-name
+-CFLAGS += -O2 -g -Wall -I../../../../usr/include/
++CFLAGS += -O2 -g -Wall -I../../../../usr/include/ $(KHDR_INCLUDES)
+
+ include ../lib.mk
+--
+2.35.1
+
pci-hv-fix-interrupt-mapping-for-multi-msi.patch
r8152-fix-a-wol-issue.patch
ip-fix-data-races-around-sysctl_ip_default_ttl.patch
+xfrm-xfrm_policy-fix-a-possible-double-xfrm_pols_put.patch
+power-supply-ab8500_fg-add-missing-destroy_workqueue.patch
+power-reset-arm-versatile-fix-refcount-leak-in-versa.patch
+rdma-irdma-do-not-advertise-1gb-page-size-for-x722.patch
+rdma-irdma-fix-sleep-from-invalid-context-bug.patch
+pinctrl-ralink-rename-mt7628-an-functions-to-mt76x8.patch
+pinctrl-ralink-rename-pinctrl-rt2880-to-pinctrl-rali.patch
+pinctrl-ralink-check-for-null-return-of-devm_kcalloc.patch
+pinctrl-sunplus-add-check-for-kcalloc.patch
+perf-core-fix-data-race-between-perf_event_set_outpu.patch
+e1000e-enable-gpt-clock-before-sending-message-to-cs.patch
+revert-e1000e-fix-possible-hw-unit-hang-after-an-s0i.patch
+igc-reinstate-igc_removed-logic-and-implement-it-pro.patch
+ip-fix-data-races-around-sysctl_ip_no_pmtu_disc.patch
+ip-fix-data-races-around-sysctl_ip_fwd_use_pmtu.patch
+ip-fix-data-races-around-sysctl_ip_fwd_update_priori.patch
+ip-fix-data-races-around-sysctl_ip_nonlocal_bind.patch
+ip-fix-a-data-race-around-sysctl_ip_autobind_reuse.patch
+ip-fix-a-data-race-around-sysctl_fwmark_reflect.patch
+tcp-dccp-fix-a-data-race-around-sysctl_tcp_fwmark_ac.patch
+tcp-sk-sk_bound_dev_if-once-in-inet_request_bound_de.patch
+tcp-fix-data-races-around-sysctl_tcp_l3mdev_accept.patch
+tcp-fix-data-races-around-sysctl_tcp_mtu_probing.patch
+tcp-fix-data-races-around-sysctl_tcp_base_mss.patch
+tcp-fix-data-races-around-sysctl_tcp_min_snd_mss.patch
+tcp-fix-a-data-race-around-sysctl_tcp_mtu_probe_floo.patch
+tcp-fix-a-data-race-around-sysctl_tcp_probe_threshol.patch
+tcp-fix-a-data-race-around-sysctl_tcp_probe_interval.patch
+stmmac-dwmac-mediatek-fix-clock-issue.patch
+net-stmmac-fix-pm-runtime-issue-in-stmmac_dvr_remove.patch
+net-stmmac-fix-unbalanced-ptp-clock-issue-in-suspend.patch
+net-dsa-microchip-ksz_common-fix-refcount-leak-bug.patch
+tcp-udp-make-early_demux-back-namespacified.patch
+i2c-mlxcpld-fix-register-setting-for-400khz-frequenc.patch
+i2c-cadence-change-large-transfer-count-reset-logic-.patch
+perf-tests-stop-convert-perf-time-to-tsc-test-openin.patch
+perf-tests-fix-convert-perf-time-to-tsc-test-for-hyb.patch
+pinctrl-ocelot-fix-pincfg-for-lan966x.patch
+pinctrl-ocelot-fix-pincfg.patch
+net-stmmac-fix-dma-queue-left-shift-overflow-issue.patch
+net-tls-fix-race-in-tls-device-down-flow.patch
+net-prestera-acl-use-proper-mask-for-port-selector.patch
+igmp-fix-data-races-around-sysctl_igmp_llm_reports.patch
+igmp-fix-a-data-race-around-sysctl_igmp_max_membersh.patch
+igmp-fix-data-races-around-sysctl_igmp_max_msf.patch
+igmp-fix-data-races-around-sysctl_igmp_qrv.patch
+tcp-fix-data-races-around-keepalive-sysctl-knobs.patch
+tcp-fix-data-races-around-sysctl_tcp_syn-ack-_retrie.patch
+tcp-fix-data-races-around-sysctl_tcp_syncookies.patch
+tcp-fix-data-races-around-sysctl_tcp_migrate_req.patch
+tcp-fix-data-races-around-sysctl_tcp_reordering.patch
+tcp-fix-data-races-around-some-timeout-sysctl-knobs.patch
+tcp-fix-a-data-race-around-sysctl_tcp_notsent_lowat.patch
+tcp-fix-a-data-race-around-sysctl_tcp_tw_reuse.patch
+tcp-fix-data-races-around-sysctl_max_syn_backlog.patch
+tcp-fix-data-races-around-sysctl_tcp_fastopen.patch
+tcp-fix-data-races-around-sysctl_tcp_fastopen_blackh.patch
+iavf-fix-vlan_v2-addition-rejection.patch
+iavf-disallow-changing-rx-tx-frames-and-rx-tx-frames.patch
+iavf-fix-handling-of-dummy-receive-descriptors.patch
+iavf-fix-missing-state-logs.patch
+acpi-cppc-don-t-require-flexible-address-space-if-x8.patch
+pinctrl-armada-37xx-reuse-gpio-fwnode-in-armada_37xx.patch
+pinctrl-armada-37xx-make-irq_lock-a-raw-spinlock-to-.patch
+net-lan966x-fix-taking-rtnl_lock-while-holding-spin_.patch
+net-lan966x-fix-usage-of-lan966x-mac_lock-when-entry.patch
+net-lan966x-fix-usage-of-lan966x-mac_lock-when-entry.patch-25162
+net-lan966x-fix-usage-of-lan966x-mac_lock-inside-lan.patch
+net-lan966x-fix-usage-of-lan966x-mac_lock-when-used-.patch
+i40e-fix-erroneous-adapter-reinitialization-during-r.patch
+ixgbe-add-locking-to-prevent-panic-when-setting-srio.patch
+net-dsa-fix-dsa_port_vlan_filtering-when-global.patch
+net-dsa-move-reset-of-vlan-filtering-to-dsa_port_swi.patch
+net-dsa-fix-null-pointer-dereference-in-dsa_port_res.patch
+net-stmmac-remove-redunctant-disable-xpcs-eee-call.patch
+gpio-pca953x-only-use-single-read-write-for-no-ai-mo.patch
+gpio-pca953x-use-the-correct-range-when-do-regmap-sy.patch
+gpio-pca953x-use-the-correct-register-address-when-r.patch
+be2net-fix-buffer-overflow-in-be_get_module_eeprom.patch
+net-dsa-sja1105-silent-spi_device_id-warnings.patch
+net-dsa-vitesse-vsc73xx-silent-spi_device_id-warning.patch
+amt-use-workqueue-for-gateway-side-message-handling.patch
+amt-remove-unnecessary-locks.patch
+amt-use-read_once-in-amt-module.patch
+amt-add-missing-regeneration-nonce-logic-in-request-.patch
+amt-drop-unexpected-advertisement-message.patch
+amt-drop-unexpected-query-message.patch
+amt-drop-unexpected-multicast-data.patch
+amt-do-not-use-amt-nr_tunnels-outside-of-lock.patch
+drm-panel-edp-fix-variable-typo-when-saving-hpd-abse.patch
+drm-imx-dcss-add-missing-of_node_put-in-fail-path.patch
+can-rcar_canfd-add-missing-of_node_put-in-rcar_canfd.patch
+ipv4-fix-a-data-race-around-sysctl_fib_multipath_use.patch
+ipv4-fix-data-races-around-sysctl_fib_multipath_hash.patch
+ipv4-fix-data-races-around-sysctl_fib_multipath_hash.patch-13729
+ip-fix-data-races-around-sysctl_ip_prot_sock.patch
+udp-fix-a-data-race-around-sysctl_udp_l3mdev_accept.patch
+tcp-fix-data-races-around-sysctl-knobs-related-to-sy.patch
+tcp-fix-a-data-race-around-sysctl_tcp_early_retrans.patch
+tcp-fix-data-races-around-sysctl_tcp_recovery.patch
+tcp-fix-a-data-race-around-sysctl_tcp_thin_linear_ti.patch
+tcp-fix-data-races-around-sysctl_tcp_slow_start_afte.patch
+tcp-fix-a-data-race-around-sysctl_tcp_retrans_collap.patch
+tcp-fix-a-data-race-around-sysctl_tcp_stdurg.patch
+tcp-fix-a-data-race-around-sysctl_tcp_rfc1337.patch
+tcp-fix-a-data-race-around-sysctl_tcp_abort_on_overf.patch
+tcp-fix-data-races-around-sysctl_tcp_max_reordering.patch
+net-sched-cls_api-fix-flow-action-initialization.patch
+selftests-gpio-fix-include-path-to-kernel-headers-fo.patch
+gpio-gpio-xilinx-fix-integer-overflow.patch
--- /dev/null
+From c6d91967bbf3bd30fb3e39202baba6fb0fa03980 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:00:12 +0800
+Subject: stmmac: dwmac-mediatek: fix clock issue
+
+From: Biao Huang <biao.huang@mediatek.com>
+
+[ Upstream commit fa4b3ca60e8011d3046765b3de8d3f1ffc53af28 ]
+
+The pm_runtime takes care of the clock handling in current
+stmmac drivers, and dwmac-mediatek implement the
+mediatek_dwmac_clks_config() as the callback for pm_runtime.
+
+Then, stripping duplicated clocks handling in old init()/exit()
+to fix clock issue in suspend/resume test.
+
+As to clocks in probe/remove, vendor need symmetric handling to
+ensure clocks balance.
+
+Test pass, including suspend/resume and ko insertion/remove.
+
+Fixes: 3186bdad97d5 ("stmmac: dwmac-mediatek: add platform level clocks management")
+Signed-off-by: Biao Huang <biao.huang@mediatek.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/stmicro/stmmac/dwmac-mediatek.c | 49 ++++++++-----------
+ 1 file changed, 21 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+index 6ff88df58767..ca8ab290013c 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+@@ -576,32 +576,7 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
+ }
+ }
+
+- ret = clk_bulk_prepare_enable(variant->num_clks, plat->clks);
+- if (ret) {
+- dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
+- return ret;
+- }
+-
+- ret = clk_prepare_enable(plat->rmii_internal_clk);
+- if (ret) {
+- dev_err(plat->dev, "failed to enable rmii internal clk, err = %d\n", ret);
+- goto err_clk;
+- }
+-
+ return 0;
+-
+-err_clk:
+- clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
+- return ret;
+-}
+-
+-static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
+-{
+- struct mediatek_dwmac_plat_data *plat = priv;
+- const struct mediatek_dwmac_variant *variant = plat->variant;
+-
+- clk_disable_unprepare(plat->rmii_internal_clk);
+- clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
+ }
+
+ static int mediatek_dwmac_clks_config(void *priv, bool enabled)
+@@ -643,7 +618,6 @@ static int mediatek_dwmac_common_data(struct platform_device *pdev,
+ plat->addr64 = priv_plat->variant->dma_bit_mask;
+ plat->bsp_priv = priv_plat;
+ plat->init = mediatek_dwmac_init;
+- plat->exit = mediatek_dwmac_exit;
+ plat->clks_config = mediatek_dwmac_clks_config;
+ if (priv_plat->variant->dwmac_fix_mac_speed)
+ plat->fix_mac_speed = priv_plat->variant->dwmac_fix_mac_speed;
+@@ -712,13 +686,32 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
+ mediatek_dwmac_common_data(pdev, plat_dat, priv_plat);
+ mediatek_dwmac_init(pdev, priv_plat);
+
++ ret = mediatek_dwmac_clks_config(priv_plat, true);
++ if (ret)
++ return ret;
++
+ ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+ if (ret) {
+ stmmac_remove_config_dt(pdev, plat_dat);
+- return ret;
++ goto err_drv_probe;
+ }
+
+ return 0;
++
++err_drv_probe:
++ mediatek_dwmac_clks_config(priv_plat, false);
++ return ret;
++}
++
++static int mediatek_dwmac_remove(struct platform_device *pdev)
++{
++ struct mediatek_dwmac_plat_data *priv_plat = get_stmmac_bsp_priv(&pdev->dev);
++ int ret;
++
++ ret = stmmac_pltfr_remove(pdev);
++ mediatek_dwmac_clks_config(priv_plat, false);
++
++ return ret;
+ }
+
+ static const struct of_device_id mediatek_dwmac_match[] = {
+@@ -733,7 +726,7 @@ MODULE_DEVICE_TABLE(of, mediatek_dwmac_match);
+
+ static struct platform_driver mediatek_dwmac_driver = {
+ .probe = mediatek_dwmac_probe,
+- .remove = stmmac_pltfr_remove,
++ .remove = mediatek_dwmac_remove,
+ .driver = {
+ .name = "dwmac-mediatek",
+ .pm = &stmmac_pltfr_pm_ops,
+--
+2.35.1
+
--- /dev/null
+From e7395facd548e0afe40b3a3a5757c5a773537cd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:58 -0700
+Subject: tcp/dccp: Fix a data-race around sysctl_tcp_fwmark_accept.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 1a0008f9df59451d0a17806c1ee1a19857032fa8 ]
+
+While reading sysctl_tcp_fwmark_accept, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 84f39b08d786 ("net: support marking accepting TCP sockets")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_sock.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index 2f6b715acc15..d3cf5871289b 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -107,7 +107,8 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
+
+ static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
+ {
+- if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept)
++ if (!sk->sk_mark &&
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
+ return skb->mark;
+
+ return sk->sk_mark;
+--
+2.35.1
+
--- /dev/null
+From 9561fe5388053be876fedf8e9abcd382bfad46e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:52 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_abort_on_overflow.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 2d17d9c7382327d00aeaea35af44e9b26d53206e ]
+
+While reading sysctl_tcp_abort_on_overflow, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_minisocks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
+index 700ea548d125..cb95d88497ae 100644
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -781,7 +781,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
+ if (sk != req->rsk_listener)
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMIGRATEREQFAILURE);
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow) {
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow)) {
+ inet_rsk(req)->acked = 1;
+ return NULL;
+ }
+--
+2.35.1
+
--- /dev/null
+From 163df31a7022a2c55634d15fd683190fb8374df4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:45 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_early_retrans.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 52e65865deb6a36718a463030500f16530eaab74 ]
+
+While reading sysctl_tcp_early_retrans, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: eed530b6c676 ("tcp: early retransmit")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index be3e90b526d8..5cda762a43dd 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2739,7 +2739,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto)
+ if (rcu_access_pointer(tp->fastopen_rsk))
+ return false;
+
+- early_retrans = sock_net(sk)->ipv4.sysctl_tcp_early_retrans;
++ early_retrans = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_early_retrans);
+ /* Schedule a loss probe in 2*RTT for SACK capable connections
+ * not in loss recovery, that are either limited by cwnd or application.
+ */
+--
+2.35.1
+
--- /dev/null
+From dd3b74422f735a4b72b292b81e3916eb90db48bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:52:03 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_mtu_probe_floor.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 8e92d4423615a5257d0d871fc067aa561f597deb ]
+
+While reading sysctl_tcp_mtu_probe_floor, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: c04b79b6cfd7 ("tcp: add new tcp_mtu_probe_floor sysctl")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 39107bb730b0..4f3b9ab222b6 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -172,7 +172,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+ } else {
+ mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
+ mss = min(READ_ONCE(net->ipv4.sysctl_tcp_base_mss), mss);
+- mss = max(mss, net->ipv4.sysctl_tcp_mtu_probe_floor);
++ mss = max(mss, READ_ONCE(net->ipv4.sysctl_tcp_mtu_probe_floor));
+ mss = max(mss, READ_ONCE(net->ipv4.sysctl_tcp_min_snd_mss));
+ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
+ }
+--
+2.35.1
+
--- /dev/null
+From bf938270c9b57461d6bc81be60228dfdeb8ca369 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:51 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_notsent_lowat.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 55be873695ed8912eb77ff46d1d1cadf028bd0f3 ]
+
+While reading sysctl_tcp_notsent_lowat, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: c9bee3b7fdec ("tcp: TCP_NOTSENT_LOWAT socket option")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 815ea8f9b93f..8d02972e46cd 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -2045,7 +2045,7 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr);
+ static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+- return tp->notsent_lowat ?: net->ipv4.sysctl_tcp_notsent_lowat;
++ return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat);
+ }
+
+ bool tcp_stream_memory_free(const struct sock *sk, int wake);
+--
+2.35.1
+
--- /dev/null
+From 578f8f277352e650f4c9b2c917ba46139c834ef2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:52:05 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_probe_interval.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 2a85388f1d94a9f8b5a529118a2c5eaa0520d85c ]
+
+While reading sysctl_tcp_probe_interval, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 05cbc0db03e8 ("ipv4: Create probe timer for tcp PMTU as per RFC4821")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 4057da397087..99a2f4518e2e 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2281,7 +2281,7 @@ static inline void tcp_mtu_check_reprobe(struct sock *sk)
+ u32 interval;
+ s32 delta;
+
+- interval = net->ipv4.sysctl_tcp_probe_interval;
++ interval = READ_ONCE(net->ipv4.sysctl_tcp_probe_interval);
+ delta = tcp_jiffies32 - icsk->icsk_mtup.probe_timestamp;
+ if (unlikely(delta >= interval * HZ)) {
+ int mss = tcp_current_mss(sk);
+--
+2.35.1
+
--- /dev/null
+From 6736234aecb6e535c618c717b1cb8f4e834db44b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:52:04 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_probe_threshold.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 92c0aa4175474483d6cf373314343d4e624e882a ]
+
+While reading sysctl_tcp_probe_threshold, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 6b58e0a5f32d ("ipv4: Use binary search to choose tcp PMTU probe_size")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index da31119f9463..4057da397087 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2365,7 +2365,7 @@ static int tcp_mtu_probe(struct sock *sk)
+ * probing process by not resetting search range to its orignal.
+ */
+ if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high) ||
+- interval < net->ipv4.sysctl_tcp_probe_threshold) {
++ interval < READ_ONCE(net->ipv4.sysctl_tcp_probe_threshold)) {
+ /* Check whether enough time has elaplased for
+ * another round of probing.
+ */
+--
+2.35.1
+
--- /dev/null
+From 20febb70d923309f16f65001529d76e1db883b90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:49 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_retrans_collapse.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 1a63cb91f0c2fcdeced6d6edee8d1d886583d139 ]
+
+While reading sysctl_tcp_retrans_collapse, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 5bcd12a9d8ff..3554a4c1e1b8 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -3103,7 +3103,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
+ struct sk_buff *skb = to, *tmp;
+ bool first = true;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_retrans_collapse)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_retrans_collapse))
+ return;
+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)
+ return;
+--
+2.35.1
+
--- /dev/null
+From 78c8e1ad353e88755a9af044009514d14152ae1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:51 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_rfc1337.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 0b484c91911e758e53656d570de58c2ed81ec6f2 ]
+
+While reading sysctl_tcp_rfc1337, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_minisocks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
+index 6854bb1fb32b..700ea548d125 100644
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -173,7 +173,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
+ * Oh well... nobody has a sufficient solution to this
+ * protocol bug yet.
+ */
+- if (twsk_net(tw)->ipv4.sysctl_tcp_rfc1337 == 0) {
++ if (!READ_ONCE(twsk_net(tw)->ipv4.sysctl_tcp_rfc1337)) {
+ kill:
+ inet_twsk_deschedule_put(tw);
+ return TCP_TW_SUCCESS;
+--
+2.35.1
+
--- /dev/null
+From 04c4976733683e1a34425ff66373b2e38562453c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:50 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_stdurg.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 4e08ed41cb1194009fc1a916a59ce3ed4afd77cd ]
+
+While reading sysctl_tcp_stdurg, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 61f93f51adbb..f200dd654e05 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -5576,7 +5576,7 @@ static void tcp_check_urg(struct sock *sk, const struct tcphdr *th)
+ struct tcp_sock *tp = tcp_sk(sk);
+ u32 ptr = ntohs(th->urg_ptr);
+
+- if (ptr && !sock_net(sk)->ipv4.sysctl_tcp_stdurg)
++ if (ptr && !READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_stdurg))
+ ptr--;
+ ptr += ntohl(th->seq);
+
+--
+2.35.1
+
--- /dev/null
+From 7610d322b2b7b113aba50641c6548828e05142e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:47 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_thin_linear_timeouts.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 7c6f2a86ca590d5187a073d987e9599985fb1c7c ]
+
+While reading sysctl_tcp_thin_linear_timeouts, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 36e31b0af587 ("net: TCP thin linear timeouts")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index ec5277becc6a..50bba370486e 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -578,7 +578,7 @@ void tcp_retransmit_timer(struct sock *sk)
+ * linear-timeout retransmissions into a black hole
+ */
+ if (sk->sk_state == TCP_ESTABLISHED &&
+- (tp->thin_lto || net->ipv4.sysctl_tcp_thin_linear_timeouts) &&
++ (tp->thin_lto || READ_ONCE(net->ipv4.sysctl_tcp_thin_linear_timeouts)) &&
+ tcp_stream_is_thin(tp) &&
+ icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) {
+ icsk->icsk_backoff = 0;
+--
+2.35.1
+
--- /dev/null
+From 68d37ffbe0efb0e1ae9c52ea0b9a537b2604a62c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:52 -0700
+Subject: tcp: Fix a data-race around sysctl_tcp_tw_reuse.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit cbfc6495586a3f09f6f07d9fb3c7cafe807e3c55 ]
+
+While reading sysctl_tcp_tw_reuse, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_ipv4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index cd78b4fc334f..a57f96b86874 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -108,10 +108,10 @@ static u32 tcp_v4_init_ts_off(const struct net *net, const struct sk_buff *skb)
+
+ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
+ {
++ int reuse = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_tw_reuse);
+ const struct inet_timewait_sock *tw = inet_twsk(sktw);
+ const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
+ struct tcp_sock *tp = tcp_sk(sk);
+- int reuse = sock_net(sk)->ipv4.sysctl_tcp_tw_reuse;
+
+ if (reuse == 2) {
+ /* Still does not detect *everything* that goes through
+--
+2.35.1
+
--- /dev/null
+From 01ade211136e961e4a9f76e8f2ad898ce06a2f7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:45 -0700
+Subject: tcp: Fix data-races around keepalive sysctl knobs.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit f2f316e287e6c2e3a1c5bab8d9b77ee03daa0463 ]
+
+While reading sysctl_tcp_keepalive_(time|probes|intvl), they can be changed
+concurrently. Thus, we need to add READ_ONCE() to their readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h | 9 ++++++---
+ net/smc/smc_llc.c | 2 +-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 113ce516ce42..e6f9a02fa465 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1511,21 +1511,24 @@ static inline int keepalive_intvl_when(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+
+- return tp->keepalive_intvl ? : net->ipv4.sysctl_tcp_keepalive_intvl;
++ return tp->keepalive_intvl ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl);
+ }
+
+ static inline int keepalive_time_when(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+
+- return tp->keepalive_time ? : net->ipv4.sysctl_tcp_keepalive_time;
++ return tp->keepalive_time ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
+ }
+
+ static inline int keepalive_probes(const struct tcp_sock *tp)
+ {
+ struct net *net = sock_net((struct sock *)tp);
+
+- return tp->keepalive_probes ? : net->ipv4.sysctl_tcp_keepalive_probes;
++ return tp->keepalive_probes ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes);
+ }
+
+ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
+diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
+index c4d057b2941d..0bde36b56472 100644
+--- a/net/smc/smc_llc.c
++++ b/net/smc/smc_llc.c
+@@ -2122,7 +2122,7 @@ void smc_llc_lgr_init(struct smc_link_group *lgr, struct smc_sock *smc)
+ init_waitqueue_head(&lgr->llc_flow_waiter);
+ init_waitqueue_head(&lgr->llc_msg_waiter);
+ mutex_init(&lgr->llc_conf_mutex);
+- lgr->llc_testlink_time = net->ipv4.sysctl_tcp_keepalive_time;
++ lgr->llc_testlink_time = READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time);
+ }
+
+ /* called after lgr was removed from lgr_list */
+--
+2.35.1
+
--- /dev/null
+From 04604b7cfcc47da0f1629b6eb5b084e10eac7784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:50 -0700
+Subject: tcp: Fix data-races around some timeout sysctl knobs.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 39e24435a776e9de5c6dd188836cf2523547804b ]
+
+While reading these sysctl knobs, they can be changed concurrently.
+Thus, we need to add READ_ONCE() to their readers.
+
+ - tcp_retries1
+ - tcp_retries2
+ - tcp_orphan_retries
+ - tcp_fin_timeout
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h | 3 ++-
+ net/ipv4/tcp.c | 2 +-
+ net/ipv4/tcp_output.c | 2 +-
+ net/ipv4/tcp_timer.c | 10 +++++-----
+ 4 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index e6f9a02fa465..815ea8f9b93f 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1541,7 +1541,8 @@ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
+
+ static inline int tcp_fin_time(const struct sock *sk)
+ {
+- int fin_timeout = tcp_sk(sk)->linger2 ? : sock_net(sk)->ipv4.sysctl_tcp_fin_timeout;
++ int fin_timeout = tcp_sk(sk)->linger2 ? :
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fin_timeout);
+ const int rto = inet_csk(sk)->icsk_rto;
+
+ if (fin_timeout < (rto << 2) - (rto >> 1))
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 0e0ee9c58257..164603527399 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3994,7 +3994,7 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
+ case TCP_LINGER2:
+ val = tp->linger2;
+ if (val >= 0)
+- val = (val ? : net->ipv4.sysctl_tcp_fin_timeout) / HZ;
++ val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ;
+ break;
+ case TCP_DEFER_ACCEPT:
+ val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 99a2f4518e2e..3f20642c8171 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -4088,7 +4088,7 @@ void tcp_send_probe0(struct sock *sk)
+
+ icsk->icsk_probes_out++;
+ if (err <= 0) {
+- if (icsk->icsk_backoff < net->ipv4.sysctl_tcp_retries2)
++ if (icsk->icsk_backoff < READ_ONCE(net->ipv4.sysctl_tcp_retries2))
+ icsk->icsk_backoff++;
+ timeout = tcp_probe0_when(sk, TCP_RTO_MAX);
+ } else {
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index a234704e8163..ec5277becc6a 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -143,7 +143,7 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset)
+ */
+ static int tcp_orphan_retries(struct sock *sk, bool alive)
+ {
+- int retries = sock_net(sk)->ipv4.sysctl_tcp_orphan_retries; /* May be zero. */
++ int retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_orphan_retries); /* May be zero. */
+
+ /* We know from an ICMP that something is wrong. */
+ if (sk->sk_err_soft && !alive)
+@@ -243,14 +243,14 @@ static int tcp_write_timeout(struct sock *sk)
+ READ_ONCE(net->ipv4.sysctl_tcp_syn_retries);
+ expired = icsk->icsk_retransmits >= retry_until;
+ } else {
+- if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) {
++ if (retransmits_timed_out(sk, READ_ONCE(net->ipv4.sysctl_tcp_retries1), 0)) {
+ /* Black hole detection */
+ tcp_mtu_probing(icsk, sk);
+
+ __dst_negative_advice(sk);
+ }
+
+- retry_until = net->ipv4.sysctl_tcp_retries2;
++ retry_until = READ_ONCE(net->ipv4.sysctl_tcp_retries2);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ const bool alive = icsk->icsk_rto < TCP_RTO_MAX;
+
+@@ -381,7 +381,7 @@ static void tcp_probe_timer(struct sock *sk)
+ msecs_to_jiffies(icsk->icsk_user_timeout))
+ goto abort;
+
+- max_probes = sock_net(sk)->ipv4.sysctl_tcp_retries2;
++ max_probes = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_retries2);
+ if (sock_flag(sk, SOCK_DEAD)) {
+ const bool alive = inet_csk_rto_backoff(icsk, TCP_RTO_MAX) < TCP_RTO_MAX;
+
+@@ -589,7 +589,7 @@ void tcp_retransmit_timer(struct sock *sk)
+ }
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+ tcp_clamp_rto_to_user_timeout(sk), TCP_RTO_MAX);
+- if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0))
++ if (retransmits_timed_out(sk, READ_ONCE(net->ipv4.sysctl_tcp_retries1) + 1, 0))
+ __sk_dst_reset(sk);
+
+ out:;
+--
+2.35.1
+
--- /dev/null
+From ef1222cd7fddfab4690429ff345cda95774ef2d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:44 -0700
+Subject: tcp: Fix data-races around sysctl knobs related to SYN option.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 3666f666e99600518ab20982af04a078bbdad277 ]
+
+While reading these knobs, they can be changed concurrently.
+Thus, we need to add READ_ONCE() to their readers.
+
+ - tcp_sack
+ - tcp_window_scaling
+ - tcp_timestamps
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/chelsio/inline_crypto/chtls/chtls_cm.c | 6 +++---
+ net/core/secure_seq.c | 4 ++--
+ net/ipv4/syncookies.c | 6 +++---
+ net/ipv4/tcp_input.c | 6 +++---
+ net/ipv4/tcp_output.c | 10 +++++-----
+ 5 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+index 7c760aa65540..ddfe9208529a 100644
+--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
++++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+@@ -1236,8 +1236,8 @@ static struct sock *chtls_recv_sock(struct sock *lsk,
+ csk->sndbuf = newsk->sk_sndbuf;
+ csk->smac_idx = ((struct port_info *)netdev_priv(ndev))->smt_idx;
+ RCV_WSCALE(tp) = select_rcv_wscale(tcp_full_space(newsk),
+- sock_net(newsk)->
+- ipv4.sysctl_tcp_window_scaling,
++ READ_ONCE(sock_net(newsk)->
++ ipv4.sysctl_tcp_window_scaling),
+ tp->window_clamp);
+ neigh_release(n);
+ inet_inherit_port(&tcp_hashinfo, lsk, newsk);
+@@ -1384,7 +1384,7 @@ static void chtls_pass_accept_request(struct sock *sk,
+ #endif
+ }
+ if (req->tcpopt.wsf <= 14 &&
+- sock_net(sk)->ipv4.sysctl_tcp_window_scaling) {
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling)) {
+ inet_rsk(oreq)->wscale_ok = 1;
+ inet_rsk(oreq)->snd_wscale = req->tcpopt.wsf;
+ }
+diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
+index 5f85e01d4093..b0ff6153be62 100644
+--- a/net/core/secure_seq.c
++++ b/net/core/secure_seq.c
+@@ -64,7 +64,7 @@ u32 secure_tcpv6_ts_off(const struct net *net,
+ .daddr = *(struct in6_addr *)daddr,
+ };
+
+- if (net->ipv4.sysctl_tcp_timestamps != 1)
++ if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
+ return 0;
+
+ ts_secret_init();
+@@ -120,7 +120,7 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
+ #ifdef CONFIG_INET
+ u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr)
+ {
+- if (net->ipv4.sysctl_tcp_timestamps != 1)
++ if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
+ return 0;
+
+ ts_secret_init();
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 9b234b42021e..942d2dfa1115 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -247,12 +247,12 @@ bool cookie_timestamp_decode(const struct net *net,
+ return true;
+ }
+
+- if (!net->ipv4.sysctl_tcp_timestamps)
++ if (!READ_ONCE(net->ipv4.sysctl_tcp_timestamps))
+ return false;
+
+ tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0;
+
+- if (tcp_opt->sack_ok && !net->ipv4.sysctl_tcp_sack)
++ if (tcp_opt->sack_ok && !READ_ONCE(net->ipv4.sysctl_tcp_sack))
+ return false;
+
+ if ((options & TS_OPT_WSCALE_MASK) == TS_OPT_WSCALE_MASK)
+@@ -261,7 +261,7 @@ bool cookie_timestamp_decode(const struct net *net,
+ tcp_opt->wscale_ok = 1;
+ tcp_opt->snd_wscale = options & TS_OPT_WSCALE_MASK;
+
+- return net->ipv4.sysctl_tcp_window_scaling != 0;
++ return READ_ONCE(net->ipv4.sysctl_tcp_window_scaling) != 0;
+ }
+ EXPORT_SYMBOL(cookie_timestamp_decode);
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index d8d903ef61f7..c2431fe41b09 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -4060,7 +4060,7 @@ void tcp_parse_options(const struct net *net,
+ break;
+ case TCPOPT_WINDOW:
+ if (opsize == TCPOLEN_WINDOW && th->syn &&
+- !estab && net->ipv4.sysctl_tcp_window_scaling) {
++ !estab && READ_ONCE(net->ipv4.sysctl_tcp_window_scaling)) {
+ __u8 snd_wscale = *(__u8 *)ptr;
+ opt_rx->wscale_ok = 1;
+ if (snd_wscale > TCP_MAX_WSCALE) {
+@@ -4076,7 +4076,7 @@ void tcp_parse_options(const struct net *net,
+ case TCPOPT_TIMESTAMP:
+ if ((opsize == TCPOLEN_TIMESTAMP) &&
+ ((estab && opt_rx->tstamp_ok) ||
+- (!estab && net->ipv4.sysctl_tcp_timestamps))) {
++ (!estab && READ_ONCE(net->ipv4.sysctl_tcp_timestamps)))) {
+ opt_rx->saw_tstamp = 1;
+ opt_rx->rcv_tsval = get_unaligned_be32(ptr);
+ opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4);
+@@ -4084,7 +4084,7 @@ void tcp_parse_options(const struct net *net,
+ break;
+ case TCPOPT_SACK_PERM:
+ if (opsize == TCPOLEN_SACK_PERM && th->syn &&
+- !estab && net->ipv4.sysctl_tcp_sack) {
++ !estab && READ_ONCE(net->ipv4.sysctl_tcp_sack)) {
+ opt_rx->sack_ok = TCP_SACK_SEEN;
+ tcp_sack_reset(opt_rx);
+ }
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 3f20642c8171..be3e90b526d8 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -789,18 +789,18 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
+ opts->mss = tcp_advertise_mss(sk);
+ remaining -= TCPOLEN_MSS_ALIGNED;
+
+- if (likely(sock_net(sk)->ipv4.sysctl_tcp_timestamps && !*md5)) {
++ if (likely(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_timestamps) && !*md5)) {
+ opts->options |= OPTION_TS;
+ opts->tsval = tcp_skb_timestamp(skb) + tp->tsoffset;
+ opts->tsecr = tp->rx_opt.ts_recent;
+ remaining -= TCPOLEN_TSTAMP_ALIGNED;
+ }
+- if (likely(sock_net(sk)->ipv4.sysctl_tcp_window_scaling)) {
++ if (likely(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling))) {
+ opts->ws = tp->rx_opt.rcv_wscale;
+ opts->options |= OPTION_WSCALE;
+ remaining -= TCPOLEN_WSCALE_ALIGNED;
+ }
+- if (likely(sock_net(sk)->ipv4.sysctl_tcp_sack)) {
++ if (likely(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_sack))) {
+ opts->options |= OPTION_SACK_ADVERTISE;
+ if (unlikely(!(OPTION_TS & opts->options)))
+ remaining -= TCPOLEN_SACKPERM_ALIGNED;
+@@ -3645,7 +3645,7 @@ static void tcp_connect_init(struct sock *sk)
+ * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
+ */
+ tp->tcp_header_len = sizeof(struct tcphdr);
+- if (sock_net(sk)->ipv4.sysctl_tcp_timestamps)
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_timestamps))
+ tp->tcp_header_len += TCPOLEN_TSTAMP_ALIGNED;
+
+ #ifdef CONFIG_TCP_MD5SIG
+@@ -3681,7 +3681,7 @@ static void tcp_connect_init(struct sock *sk)
+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
+ &tp->rcv_wnd,
+ &tp->window_clamp,
+- sock_net(sk)->ipv4.sysctl_tcp_window_scaling,
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling),
+ &rcv_wscale,
+ rcv_wnd);
+
+--
+2.35.1
+
--- /dev/null
+From 22498384efc62c295487f2af8f071bcf23e08dcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:53 -0700
+Subject: tcp: Fix data-races around sysctl_max_syn_backlog.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 79539f34743d3e14cc1fa6577d326a82cc64d62f ]
+
+While reading sysctl_max_syn_backlog, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 391f4a3f10fd..d8d903ef61f7 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -6939,10 +6939,12 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
+ tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb);
+
+ if (!want_cookie && !isn) {
++ int max_syn_backlog = READ_ONCE(net->ipv4.sysctl_max_syn_backlog);
++
+ /* Kill the following clause, if you dislike this way. */
+ if (!syncookies &&
+- (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
+- (net->ipv4.sysctl_max_syn_backlog >> 2)) &&
++ (max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
++ (max_syn_backlog >> 2)) &&
+ !tcp_peer_is_proven(req, dst)) {
+ /* Without syncookies last quarter of
+ * backlog is filled with destinations,
+--
+2.35.1
+
--- /dev/null
+From 3cddbcda319fe0f422bf67a9e2e8bca9655060f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:52:01 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_base_mss.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 88d78bc097cd8ebc6541e93316c9d9bf651b13e8 ]
+
+While reading sysctl_tcp_base_mss, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 5d424d5a674f ("[TCP]: MTU probing")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 2 +-
+ net/ipv4/tcp_timer.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index f0f2e1aea8c7..66b35cb893c1 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1763,7 +1763,7 @@ void tcp_mtup_init(struct sock *sk)
+ icsk->icsk_mtup.enabled = READ_ONCE(net->ipv4.sysctl_tcp_mtu_probing) > 1;
+ icsk->icsk_mtup.search_high = tp->rx_opt.mss_clamp + sizeof(struct tcphdr) +
+ icsk->icsk_af_ops->net_header_len;
+- icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, net->ipv4.sysctl_tcp_base_mss);
++ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, READ_ONCE(net->ipv4.sysctl_tcp_base_mss));
+ icsk->icsk_mtup.probe_size = 0;
+ if (icsk->icsk_mtup.enabled)
+ icsk->icsk_mtup.probe_timestamp = tcp_jiffies32;
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 98bb00e29e1e..04063c7e33ba 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -171,7 +171,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+ icsk->icsk_mtup.probe_timestamp = tcp_jiffies32;
+ } else {
+ mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
+- mss = min(net->ipv4.sysctl_tcp_base_mss, mss);
++ mss = min(READ_ONCE(net->ipv4.sysctl_tcp_base_mss), mss);
+ mss = max(mss, net->ipv4.sysctl_tcp_mtu_probe_floor);
+ mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss);
+ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
+--
+2.35.1
+
--- /dev/null
+From 7538f341380dd1181da33fcb014b4a9675821a73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:54 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_fastopen.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 5a54213318c43f4009ae158347aa6016e3b9b55a ]
+
+While reading sysctl_tcp_fastopen, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 2100c8d2d9db ("net-tcp: Fast Open base")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Acked-by: Yuchung Cheng <ycheng@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/af_inet.c | 2 +-
+ net/ipv4/tcp.c | 6 ++++--
+ net/ipv4/tcp_fastopen.c | 4 ++--
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index f5d5911a8abd..5c207367b3b4 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -217,7 +217,7 @@ int inet_listen(struct socket *sock, int backlog)
+ * because the socket was in TCP_LISTEN state previously but
+ * was shutdown() rather than close().
+ */
+- tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
++ tcp_fastopen = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen);
+ if ((tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
+ (tcp_fastopen & TFO_SERVER_ENABLE) &&
+ !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) {
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 164603527399..28db838e604a 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1151,7 +1151,8 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
+ struct sockaddr *uaddr = msg->msg_name;
+ int err, flags;
+
+- if (!(sock_net(sk)->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) ||
++ if (!(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen) &
++ TFO_CLIENT_ENABLE) ||
+ (uaddr && msg->msg_namelen >= sizeof(uaddr->sa_family) &&
+ uaddr->sa_family == AF_UNSPEC))
+ return -EOPNOTSUPP;
+@@ -3638,7 +3639,8 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
+ case TCP_FASTOPEN_CONNECT:
+ if (val > 1 || val < 0) {
+ err = -EINVAL;
+- } else if (net->ipv4.sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) {
++ } else if (READ_ONCE(net->ipv4.sysctl_tcp_fastopen) &
++ TFO_CLIENT_ENABLE) {
+ if (sk->sk_state == TCP_CLOSE)
+ tp->fastopen_connect = val;
+ else
+diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
+index fdbcf2a6d08e..0acdb5473850 100644
+--- a/net/ipv4/tcp_fastopen.c
++++ b/net/ipv4/tcp_fastopen.c
+@@ -332,7 +332,7 @@ static bool tcp_fastopen_no_cookie(const struct sock *sk,
+ const struct dst_entry *dst,
+ int flag)
+ {
+- return (sock_net(sk)->ipv4.sysctl_tcp_fastopen & flag) ||
++ return (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen) & flag) ||
+ tcp_sk(sk)->fastopen_no_cookie ||
+ (dst && dst_metric(dst, RTAX_FASTOPEN_NO_COOKIE));
+ }
+@@ -347,7 +347,7 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
+ const struct dst_entry *dst)
+ {
+ bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1;
+- int tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
++ int tcp_fastopen = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen);
+ struct tcp_fastopen_cookie valid_foc = { .len = -1 };
+ struct sock *child;
+ int ret = 0;
+--
+2.35.1
+
--- /dev/null
+From f0c1be302ca6343d842b83169baffc35b23d7cec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:55 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_fastopen_blackhole_timeout.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 021266ec640c7a4527e6cd4b7349a512b351de1d ]
+
+While reading sysctl_tcp_fastopen_blackhole_timeout, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: cf1ef3f0719b ("net/tcp_fastopen: Disable active side TFO in certain scenarios")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_fastopen.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
+index 0acdb5473850..825b216d11f5 100644
+--- a/net/ipv4/tcp_fastopen.c
++++ b/net/ipv4/tcp_fastopen.c
+@@ -489,7 +489,7 @@ void tcp_fastopen_active_disable(struct sock *sk)
+ {
+ struct net *net = sock_net(sk);
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout))
+ return;
+
+ /* Paired with READ_ONCE() in tcp_fastopen_active_should_disable() */
+@@ -510,7 +510,8 @@ void tcp_fastopen_active_disable(struct sock *sk)
+ */
+ bool tcp_fastopen_active_should_disable(struct sock *sk)
+ {
+- unsigned int tfo_bh_timeout = sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout;
++ unsigned int tfo_bh_timeout =
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fastopen_blackhole_timeout);
+ unsigned long timeout;
+ int tfo_da_times;
+ int multiplier;
+--
+2.35.1
+
--- /dev/null
+From 97edb419b11768a565de071fc4c8f5d13331b510 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:51:59 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_l3mdev_accept.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 08a75f10679470552a3a443f9aefd1399604d31d ]
+
+While reading sysctl_tcp_l3mdev_accept, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 6dd9a14e92e5 ("net: Allow accepted sockets to be bound to l3mdev domain")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_hashtables.h | 2 +-
+ include/net/inet_sock.h | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 98e1ec1a14f0..749bb1e46087 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -207,7 +207,7 @@ static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+ {
+ #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+- return inet_bound_dev_eq(!!net->ipv4.sysctl_tcp_l3mdev_accept,
++ return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept),
+ bound_dev_if, dif, sdif);
+ #else
+ return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index b29108f0973a..6395f6b9a5d2 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -121,7 +121,7 @@ static inline int inet_request_bound_dev_if(const struct sock *sk,
+ #ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+- if (!bound_dev_if && net->ipv4.sysctl_tcp_l3mdev_accept)
++ if (!bound_dev_if && READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept))
+ return l3mdev_master_ifindex_by_index(net, skb->skb_iif);
+ #endif
+
+@@ -133,7 +133,7 @@ static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+ #ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+- if (!net->ipv4.sysctl_tcp_l3mdev_accept)
++ if (!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept))
+ return l3mdev_master_ifindex_by_index(net,
+ sk->sk_bound_dev_if);
+ #endif
+--
+2.35.1
+
--- /dev/null
+From b43f03537a9a637d65a4f231d0d01cc4e3b9d360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:53 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_max_reordering.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit a11e5b3e7a59fde1a90b0eaeaa82320495cf8cae ]
+
+While reading sysctl_tcp_max_reordering, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: dca145ffaa8d ("tcp: allow for bigger reordering level")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index f200dd654e05..19b186a4a8e8 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -1051,7 +1051,7 @@ static void tcp_check_sack_reordering(struct sock *sk, const u32 low_seq,
+ tp->undo_marker ? tp->undo_retrans : 0);
+ #endif
+ tp->reordering = min_t(u32, (metric + mss - 1) / mss,
+- sock_net(sk)->ipv4.sysctl_tcp_max_reordering);
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_max_reordering));
+ }
+
+ /* This exciting event is worth to be remembered. 8) */
+@@ -2030,7 +2030,7 @@ static void tcp_check_reno_reordering(struct sock *sk, const int addend)
+ return;
+
+ tp->reordering = min_t(u32, tp->packets_out + addend,
+- sock_net(sk)->ipv4.sysctl_tcp_max_reordering);
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_max_reordering));
+ tp->reord_seen++;
+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRENOREORDER);
+ }
+--
+2.35.1
+
--- /dev/null
+From 50ac59702f3e355d14cc1e2d9bd6c699ee2bed2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:48 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_migrate_req.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 4177f545895b1da08447a80692f30617154efa6e ]
+
+While reading sysctl_tcp_migrate_req, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: f9ac779f881c ("net: Introduce net.ipv4.tcp_migrate_req.")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_reuseport.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index 3f00a28fe762..5daa1fa54249 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -387,7 +387,7 @@ void reuseport_stop_listen_sock(struct sock *sk)
+ prog = rcu_dereference_protected(reuse->prog,
+ lockdep_is_held(&reuseport_lock));
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_migrate_req ||
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_migrate_req) ||
+ (prog && prog->expected_attach_type == BPF_SK_REUSEPORT_SELECT_OR_MIGRATE)) {
+ /* Migration capable, move sk from the listening section
+ * to the closed section.
+@@ -545,7 +545,7 @@ struct sock *reuseport_migrate_sock(struct sock *sk,
+ hash = migrating_sk->sk_hash;
+ prog = rcu_dereference(reuse->prog);
+ if (!prog || prog->expected_attach_type != BPF_SK_REUSEPORT_SELECT_OR_MIGRATE) {
+- if (sock_net(sk)->ipv4.sysctl_tcp_migrate_req)
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_migrate_req))
+ goto select_by_hash;
+ goto failure;
+ }
+--
+2.35.1
+
--- /dev/null
+From c5a91afae11d94287220b7220a5e4feb5d33e255 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:52:02 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_min_snd_mss.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 78eb166cdefcc3221c8c7c1e2d514e91a2eb5014 ]
+
+While reading sysctl_tcp_min_snd_mss, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 5f3e2bf008c2 ("tcp: add tcp_min_snd_mss sysctl")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 3 ++-
+ net/ipv4/tcp_timer.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 66b35cb893c1..da31119f9463 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1717,7 +1717,8 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)
+ mss_now -= icsk->icsk_ext_hdr_len;
+
+ /* Then reserve room for full set of TCP options and 8 bytes of data */
+- mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss);
++ mss_now = max(mss_now,
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss));
+ return mss_now;
+ }
+
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 04063c7e33ba..39107bb730b0 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -173,7 +173,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+ mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
+ mss = min(READ_ONCE(net->ipv4.sysctl_tcp_base_mss), mss);
+ mss = max(mss, net->ipv4.sysctl_tcp_mtu_probe_floor);
+- mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss);
++ mss = max(mss, READ_ONCE(net->ipv4.sysctl_tcp_min_snd_mss));
+ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
+ }
+ tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
+--
+2.35.1
+
--- /dev/null
+From e53ac159d8ba3e31b1d52800e6d9bd4b0264fe60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:52:00 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_mtu_probing.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit f47d00e077e7d61baf69e46dde3210c886360207 ]
+
+While reading sysctl_tcp_mtu_probing, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 5d424d5a674f ("[TCP]: MTU probing")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 2 +-
+ net/ipv4/tcp_timer.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 34249469e361..f0f2e1aea8c7 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1760,7 +1760,7 @@ void tcp_mtup_init(struct sock *sk)
+ struct inet_connection_sock *icsk = inet_csk(sk);
+ struct net *net = sock_net(sk);
+
+- icsk->icsk_mtup.enabled = net->ipv4.sysctl_tcp_mtu_probing > 1;
++ icsk->icsk_mtup.enabled = READ_ONCE(net->ipv4.sysctl_tcp_mtu_probing) > 1;
+ icsk->icsk_mtup.search_high = tp->rx_opt.mss_clamp + sizeof(struct tcphdr) +
+ icsk->icsk_af_ops->net_header_len;
+ icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, net->ipv4.sysctl_tcp_base_mss);
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 20cf4a98c69d..98bb00e29e1e 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -163,7 +163,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+ int mss;
+
+ /* Black hole detection */
+- if (!net->ipv4.sysctl_tcp_mtu_probing)
++ if (!READ_ONCE(net->ipv4.sysctl_tcp_mtu_probing))
+ return;
+
+ if (!icsk->icsk_mtup.enabled) {
+--
+2.35.1
+
--- /dev/null
+From 9db70d85588667d251e91c1340b408a4f527511d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:46 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_recovery.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit e7d2ef837e14a971a05f60ea08c47f3fed1a36e4 ]
+
+While reading sysctl_tcp_recovery, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 4f41b1c58a32 ("tcp: use RACK to detect losses")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 3 ++-
+ net/ipv4/tcp_recovery.c | 6 ++++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index c2431fe41b09..61f93f51adbb 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2095,7 +2095,8 @@ static inline void tcp_init_undo(struct tcp_sock *tp)
+
+ static bool tcp_is_rack(const struct sock *sk)
+ {
+- return sock_net(sk)->ipv4.sysctl_tcp_recovery & TCP_RACK_LOSS_DETECTION;
++ return READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_recovery) &
++ TCP_RACK_LOSS_DETECTION;
+ }
+
+ /* If we detect SACK reneging, forget all SACK information
+diff --git a/net/ipv4/tcp_recovery.c b/net/ipv4/tcp_recovery.c
+index fd113f6226ef..ac14216f6204 100644
+--- a/net/ipv4/tcp_recovery.c
++++ b/net/ipv4/tcp_recovery.c
+@@ -19,7 +19,8 @@ static u32 tcp_rack_reo_wnd(const struct sock *sk)
+ return 0;
+
+ if (tp->sacked_out >= tp->reordering &&
+- !(sock_net(sk)->ipv4.sysctl_tcp_recovery & TCP_RACK_NO_DUPTHRESH))
++ !(READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_recovery) &
++ TCP_RACK_NO_DUPTHRESH))
+ return 0;
+ }
+
+@@ -192,7 +193,8 @@ void tcp_rack_update_reo_wnd(struct sock *sk, struct rate_sample *rs)
+ {
+ struct tcp_sock *tp = tcp_sk(sk);
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_recovery & TCP_RACK_STATIC_REO_WND ||
++ if ((READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_recovery) &
++ TCP_RACK_STATIC_REO_WND) ||
+ !rs->prior_delivered)
+ return;
+
+--
+2.35.1
+
--- /dev/null
+From 248d1158bb14ccc69df909968485262036f0c7ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:49 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_reordering.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 46778cd16e6a5ad1b2e3a91f6c057c907379418e ]
+
+While reading sysctl_tcp_reordering, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp.c | 2 +-
+ net/ipv4/tcp_input.c | 10 +++++++---
+ net/ipv4/tcp_metrics.c | 3 ++-
+ 3 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index df3bf1a24c39..0e0ee9c58257 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -441,7 +441,7 @@ void tcp_init_sock(struct sock *sk)
+ tp->snd_cwnd_clamp = ~0;
+ tp->mss_cache = TCP_MSS_DEFAULT;
+
+- tp->reordering = sock_net(sk)->ipv4.sysctl_tcp_reordering;
++ tp->reordering = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reordering);
+ tcp_assign_congestion_control(sk);
+
+ tp->tsoffset = 0;
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index f5ca08dfa02d..391f4a3f10fd 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2139,6 +2139,7 @@ void tcp_enter_loss(struct sock *sk)
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct net *net = sock_net(sk);
+ bool new_recovery = icsk->icsk_ca_state < TCP_CA_Recovery;
++ u8 reordering;
+
+ tcp_timeout_mark_lost(sk);
+
+@@ -2159,10 +2160,12 @@ void tcp_enter_loss(struct sock *sk)
+ /* Timeout in disordered state after receiving substantial DUPACKs
+ * suggests that the degree of reordering is over-estimated.
+ */
++ reordering = READ_ONCE(net->ipv4.sysctl_tcp_reordering);
+ if (icsk->icsk_ca_state <= TCP_CA_Disorder &&
+- tp->sacked_out >= net->ipv4.sysctl_tcp_reordering)
++ tp->sacked_out >= reordering)
+ tp->reordering = min_t(unsigned int, tp->reordering,
+- net->ipv4.sysctl_tcp_reordering);
++ reordering);
++
+ tcp_set_ca_state(sk, TCP_CA_Loss);
+ tp->high_seq = tp->snd_nxt;
+ tcp_ecn_queue_cwr(tp);
+@@ -3464,7 +3467,8 @@ static inline bool tcp_may_raise_cwnd(const struct sock *sk, const int flag)
+ * new SACK or ECE mark may first advance cwnd here and later reduce
+ * cwnd in tcp_fastretrans_alert() based on more states.
+ */
+- if (tcp_sk(sk)->reordering > sock_net(sk)->ipv4.sysctl_tcp_reordering)
++ if (tcp_sk(sk)->reordering >
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reordering))
+ return flag & FLAG_FORWARD_PROGRESS;
+
+ return flag & FLAG_DATA_ACKED;
+diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
+index 7029b0e98edb..a501150deaa3 100644
+--- a/net/ipv4/tcp_metrics.c
++++ b/net/ipv4/tcp_metrics.c
+@@ -428,7 +428,8 @@ void tcp_update_metrics(struct sock *sk)
+ if (!tcp_metric_locked(tm, TCP_METRIC_REORDERING)) {
+ val = tcp_metric_get(tm, TCP_METRIC_REORDERING);
+ if (val < tp->reordering &&
+- tp->reordering != net->ipv4.sysctl_tcp_reordering)
++ tp->reordering !=
++ READ_ONCE(net->ipv4.sysctl_tcp_reordering))
+ tcp_metric_set(tm, TCP_METRIC_REORDERING,
+ tp->reordering);
+ }
+--
+2.35.1
+
--- /dev/null
+From 504f74efae6cdc49ba1a73972a048d4b7f300345 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:48 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_slow_start_after_idle.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 4845b5713ab18a1bb6e31d1fbb4d600240b8b691 ]
+
+While reading sysctl_tcp_slow_start_after_idle, it can be changed
+concurrently. Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 35089bb203f4 ("[TCP]: Add tcp_slow_start_after_idle sysctl.")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h | 4 ++--
+ net/ipv4/tcp_output.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 8d02972e46cd..4f5de382e192 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1421,8 +1421,8 @@ static inline void tcp_slow_start_after_idle_check(struct sock *sk)
+ struct tcp_sock *tp = tcp_sk(sk);
+ s32 delta;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle || tp->packets_out ||
+- ca_ops->cong_control)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle) ||
++ tp->packets_out || ca_ops->cong_control)
+ return;
+ delta = tcp_jiffies32 - tp->lsndtime;
+ if (delta > inet_csk(sk)->icsk_rto)
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 5cda762a43dd..5bcd12a9d8ff 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1896,7 +1896,7 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited)
+ if (tp->packets_out > tp->snd_cwnd_used)
+ tp->snd_cwnd_used = tp->packets_out;
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle &&
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_slow_start_after_idle) &&
+ (s32)(tcp_jiffies32 - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto &&
+ !ca_ops->cong_control)
+ tcp_cwnd_application_limited(sk);
+--
+2.35.1
+
--- /dev/null
+From f22ed0eb8aeaa4891c291debf693fe58bf4c2cff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:46 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_syn(ack)?_retries.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 20a3b1c0f603e8c55c3396abd12dfcfb523e4d3c ]
+
+While reading sysctl_tcp_syn(ack)?_retries, they can be changed
+concurrently. Thus, we need to add READ_ONCE() to their readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_connection_sock.c | 3 ++-
+ net/ipv4/tcp.c | 3 ++-
+ net/ipv4/tcp_timer.c | 10 +++++++---
+ 3 files changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index dfb5a2d7ad85..cdc750ced525 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -829,7 +829,8 @@ static void reqsk_timer_handler(struct timer_list *t)
+
+ icsk = inet_csk(sk_listener);
+ net = sock_net(sk_listener);
+- max_syn_ack_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries;
++ max_syn_ack_retries = icsk->icsk_syn_retries ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_synack_retries);
+ /* Normally all the openreqs are young and become mature
+ * (i.e. converted to established socket) for first timeout.
+ * If synack was not acknowledged for 1 second, it means
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index f2fd1779d925..df3bf1a24c39 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3988,7 +3988,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
+ val = keepalive_probes(tp);
+ break;
+ case TCP_SYNCNT:
+- val = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
++ val = icsk->icsk_syn_retries ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_syn_retries);
+ break;
+ case TCP_LINGER2:
+ val = tp->linger2;
+diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
+index 4f3b9ab222b6..a234704e8163 100644
+--- a/net/ipv4/tcp_timer.c
++++ b/net/ipv4/tcp_timer.c
+@@ -239,7 +239,8 @@ static int tcp_write_timeout(struct sock *sk)
+ if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
+ if (icsk->icsk_retransmits)
+ __dst_negative_advice(sk);
+- retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
++ retry_until = icsk->icsk_syn_retries ? :
++ READ_ONCE(net->ipv4.sysctl_tcp_syn_retries);
+ expired = icsk->icsk_retransmits >= retry_until;
+ } else {
+ if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) {
+@@ -406,12 +407,15 @@ abort: tcp_write_err(sk);
+ static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req)
+ {
+ struct inet_connection_sock *icsk = inet_csk(sk);
+- int max_retries = icsk->icsk_syn_retries ? :
+- sock_net(sk)->ipv4.sysctl_tcp_synack_retries + 1; /* add one more retry for fastopen */
+ struct tcp_sock *tp = tcp_sk(sk);
++ int max_retries;
+
+ req->rsk_ops->syn_ack_timeout(req);
+
++ /* add one more retry for fastopen */
++ max_retries = icsk->icsk_syn_retries ? :
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_synack_retries) + 1;
++
+ if (req->num_timeout >= max_retries) {
+ tcp_write_err(sk);
+ return;
+--
+2.35.1
+
--- /dev/null
+From 244b47c440a81aaf3275736b63143b2e6953415b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:17:47 -0700
+Subject: tcp: Fix data-races around sysctl_tcp_syncookies.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit f2e383b5bb6bbc60a0b94b87b3e49a2b1aefd11e ]
+
+While reading sysctl_tcp_syncookies, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its readers.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 4 ++--
+ net/ipv4/syncookies.c | 3 ++-
+ net/ipv4/tcp_input.c | 20 ++++++++++++--------
+ net/ipv6/syncookies.c | 3 ++-
+ 4 files changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 6391c1885bca..d0b0c163d3f3 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -7031,7 +7031,7 @@ BPF_CALL_5(bpf_tcp_check_syncookie, struct sock *, sk, void *, iph, u32, iph_len
+ if (sk->sk_protocol != IPPROTO_TCP || sk->sk_state != TCP_LISTEN)
+ return -EINVAL;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies))
+ return -EINVAL;
+
+ if (!th->ack || th->rst || th->syn)
+@@ -7106,7 +7106,7 @@ BPF_CALL_5(bpf_tcp_gen_syncookie, struct sock *, sk, void *, iph, u32, iph_len,
+ if (sk->sk_protocol != IPPROTO_TCP || sk->sk_state != TCP_LISTEN)
+ return -EINVAL;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies))
+ return -ENOENT;
+
+ if (!th->syn || th->ack || th->fin || th->rst)
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index b387c4835155..9b234b42021e 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -340,7 +340,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
+ struct flowi4 fl4;
+ u32 tsoff = 0;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
++ !th->ack || th->rst)
+ goto out;
+
+ if (tcp_synq_no_recent_overflow(sk))
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 2d71bcfcc759..f5ca08dfa02d 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -6780,11 +6780,14 @@ static bool tcp_syn_flood_action(const struct sock *sk, const char *proto)
+ {
+ struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
+ const char *msg = "Dropping request";
+- bool want_cookie = false;
+ struct net *net = sock_net(sk);
++ bool want_cookie = false;
++ u8 syncookies;
++
++ syncookies = READ_ONCE(net->ipv4.sysctl_tcp_syncookies);
+
+ #ifdef CONFIG_SYN_COOKIES
+- if (net->ipv4.sysctl_tcp_syncookies) {
++ if (syncookies) {
+ msg = "Sending cookies";
+ want_cookie = true;
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPREQQFULLDOCOOKIES);
+@@ -6792,8 +6795,7 @@ static bool tcp_syn_flood_action(const struct sock *sk, const char *proto)
+ #endif
+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPREQQFULLDROP);
+
+- if (!queue->synflood_warned &&
+- net->ipv4.sysctl_tcp_syncookies != 2 &&
++ if (!queue->synflood_warned && syncookies != 2 &&
+ xchg(&queue->synflood_warned, 1) == 0)
+ net_info_ratelimited("%s: Possible SYN flooding on port %d. %s. Check SNMP counters.\n",
+ proto, sk->sk_num, msg);
+@@ -6842,7 +6844,7 @@ u16 tcp_get_syncookie_mss(struct request_sock_ops *rsk_ops,
+ struct tcp_sock *tp = tcp_sk(sk);
+ u16 mss;
+
+- if (sock_net(sk)->ipv4.sysctl_tcp_syncookies != 2 &&
++ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) != 2 &&
+ !inet_csk_reqsk_queue_is_full(sk))
+ return 0;
+
+@@ -6876,13 +6878,15 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
+ bool want_cookie = false;
+ struct dst_entry *dst;
+ struct flowi fl;
++ u8 syncookies;
++
++ syncookies = READ_ONCE(net->ipv4.sysctl_tcp_syncookies);
+
+ /* TW buckets are converted to open requests without
+ * limitations, they conserve resources and peer is
+ * evidently real one.
+ */
+- if ((net->ipv4.sysctl_tcp_syncookies == 2 ||
+- inet_csk_reqsk_queue_is_full(sk)) && !isn) {
++ if ((syncookies == 2 || inet_csk_reqsk_queue_is_full(sk)) && !isn) {
+ want_cookie = tcp_syn_flood_action(sk, rsk_ops->slab_name);
+ if (!want_cookie)
+ goto drop;
+@@ -6932,7 +6936,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
+
+ if (!want_cookie && !isn) {
+ /* Kill the following clause, if you dislike this way. */
+- if (!net->ipv4.sysctl_tcp_syncookies &&
++ if (!syncookies &&
+ (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
+ (net->ipv4.sysctl_max_syn_backlog >> 2)) &&
+ !tcp_peer_is_proven(req, dst)) {
+diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
+index 9cc123f000fb..5014aa663452 100644
+--- a/net/ipv6/syncookies.c
++++ b/net/ipv6/syncookies.c
+@@ -141,7 +141,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
+ __u8 rcv_wscale;
+ u32 tsoff = 0;
+
+- if (!sock_net(sk)->ipv4.sysctl_tcp_syncookies || !th->ack || th->rst)
++ if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
++ !th->ack || th->rst)
+ goto out;
+
+ if (tcp_synq_no_recent_overflow(sk))
+--
+2.35.1
+
--- /dev/null
+From 7f8905fc5824cd3a22952b1b05f4b8cc279457a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 May 2022 11:55:43 -0700
+Subject: tcp: sk->sk_bound_dev_if once in inet_request_bound_dev_if()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit fdb5fd7f736ec7ae9fb36d2842ea6d9ebc4e7269 ]
+
+inet_request_bound_dev_if() reads sk->sk_bound_dev_if twice
+while listener socket is not locked.
+
+Another cpu could change this field under us.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_sock.h | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index d3cf5871289b..b29108f0973a 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -117,14 +117,15 @@ static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
+ static inline int inet_request_bound_dev_if(const struct sock *sk,
+ struct sk_buff *skb)
+ {
++ int bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ #ifdef CONFIG_NET_L3_MASTER_DEV
+ struct net *net = sock_net(sk);
+
+- if (!sk->sk_bound_dev_if && net->ipv4.sysctl_tcp_l3mdev_accept)
++ if (!bound_dev_if && net->ipv4.sysctl_tcp_l3mdev_accept)
+ return l3mdev_master_ifindex_by_index(net, skb->skb_iif);
+ #endif
+
+- return sk->sk_bound_dev_if;
++ return bound_dev_if;
+ }
+
+ static inline int inet_sk_bound_l3mdev(const struct sock *sk)
+--
+2.35.1
+
--- /dev/null
+From 4544a0e37c0ca33e0ecc340297503ffea13714ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 10:52:07 -0700
+Subject: tcp/udp: Make early_demux back namespacified.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 11052589cf5c0bab3b4884d423d5f60c38fcf25d ]
+
+Commit e21145a9871a ("ipv4: namespacify ip_early_demux sysctl knob") made
+it possible to enable/disable early_demux on a per-netns basis. Then, we
+introduced two knobs, tcp_early_demux and udp_early_demux, to switch it for
+TCP/UDP in commit dddb64bcb346 ("net: Add sysctl to toggle early demux for
+tcp and udp"). However, the .proc_handler() was wrong and actually
+disabled us from changing the behaviour in each netns.
+
+We can execute early_demux if net.ipv4.ip_early_demux is on and each proto
+.early_demux() handler is not NULL. When we toggle (tcp|udp)_early_demux,
+the change itself is saved in each netns variable, but the .early_demux()
+handler is a global variable, so the handler is switched based on the
+init_net's sysctl variable. Thus, netns (tcp|udp)_early_demux knobs have
+nothing to do with the logic. Whether we CAN execute proto .early_demux()
+is always decided by init_net's sysctl knob, and whether we DO it or not is
+by each netns ip_early_demux knob.
+
+This patch namespacifies (tcp|udp)_early_demux again. For now, the users
+of the .early_demux() handler are TCP and UDP only, and they are called
+directly to avoid retpoline. So, we can remove the .early_demux() handler
+from inet6?_protos and need not dereference them in ip6?_rcv_finish_core().
+If another proto needs .early_demux(), we can restore it at that time.
+
+Fixes: dddb64bcb346 ("net: Add sysctl to toggle early demux for tcp and udp")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/20220713175207.7727-1-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/protocol.h | 4 ---
+ include/net/tcp.h | 2 +-
+ include/net/udp.h | 2 +-
+ net/ipv4/af_inet.c | 14 ++-------
+ net/ipv4/ip_input.c | 37 ++++++++++++++----------
+ net/ipv4/sysctl_net_ipv4.c | 59 ++------------------------------------
+ net/ipv6/ip6_input.c | 23 ++++++++-------
+ net/ipv6/tcp_ipv6.c | 9 ++----
+ net/ipv6/udp.c | 9 ++----
+ 9 files changed, 45 insertions(+), 114 deletions(-)
+
+diff --git a/include/net/protocol.h b/include/net/protocol.h
+index f51c06ae365f..6aef8cb11cc8 100644
+--- a/include/net/protocol.h
++++ b/include/net/protocol.h
+@@ -35,8 +35,6 @@
+
+ /* This is used to register protocols. */
+ struct net_protocol {
+- int (*early_demux)(struct sk_buff *skb);
+- int (*early_demux_handler)(struct sk_buff *skb);
+ int (*handler)(struct sk_buff *skb);
+
+ /* This returns an error if we weren't able to handle the error. */
+@@ -52,8 +50,6 @@ struct net_protocol {
+
+ #if IS_ENABLED(CONFIG_IPV6)
+ struct inet6_protocol {
+- void (*early_demux)(struct sk_buff *skb);
+- void (*early_demux_handler)(struct sk_buff *skb);
+ int (*handler)(struct sk_buff *skb);
+
+ /* This returns an error if we weren't able to handle the error. */
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 2d9a78b3beaa..113ce516ce42 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -932,7 +932,7 @@ extern const struct inet_connection_sock_af_ops ipv6_specific;
+
+ INDIRECT_CALLABLE_DECLARE(void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb));
+ INDIRECT_CALLABLE_DECLARE(int tcp_v6_rcv(struct sk_buff *skb));
+-INDIRECT_CALLABLE_DECLARE(void tcp_v6_early_demux(struct sk_buff *skb));
++void tcp_v6_early_demux(struct sk_buff *skb);
+
+ #endif
+
+diff --git a/include/net/udp.h b/include/net/udp.h
+index f1c2a88c9005..07d0ceadcf6e 100644
+--- a/include/net/udp.h
++++ b/include/net/udp.h
+@@ -167,7 +167,7 @@ static inline void udp_csum_pull_header(struct sk_buff *skb)
+ typedef struct sock *(*udp_lookup_t)(const struct sk_buff *skb, __be16 sport,
+ __be16 dport);
+
+-INDIRECT_CALLABLE_DECLARE(void udp_v6_early_demux(struct sk_buff *));
++void udp_v6_early_demux(struct sk_buff *skb);
+ INDIRECT_CALLABLE_DECLARE(int udpv6_rcv(struct sk_buff *));
+
+ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 8c0a22a5b36c..f5d5911a8abd 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1711,24 +1711,14 @@ static const struct net_protocol igmp_protocol = {
+ };
+ #endif
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct net_protocol tcp_protocol = {
+- .early_demux = tcp_v4_early_demux,
+- .early_demux_handler = tcp_v4_early_demux,
++static const struct net_protocol tcp_protocol = {
+ .handler = tcp_v4_rcv,
+ .err_handler = tcp_v4_err,
+ .no_policy = 1,
+ .icmp_strict_tag_validation = 1,
+ };
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct net_protocol udp_protocol = {
+- .early_demux = udp_v4_early_demux,
+- .early_demux_handler = udp_v4_early_demux,
++static const struct net_protocol udp_protocol = {
+ .handler = udp_rcv,
+ .err_handler = udp_err,
+ .no_policy = 1,
+diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+index 95f7bb052784..f3fd6c398309 100644
+--- a/net/ipv4/ip_input.c
++++ b/net/ipv4/ip_input.c
+@@ -312,14 +312,13 @@ static bool ip_can_use_hint(const struct sk_buff *skb, const struct iphdr *iph,
+ ip_hdr(hint)->tos == iph->tos;
+ }
+
+-INDIRECT_CALLABLE_DECLARE(int udp_v4_early_demux(struct sk_buff *));
+-INDIRECT_CALLABLE_DECLARE(int tcp_v4_early_demux(struct sk_buff *));
++int tcp_v4_early_demux(struct sk_buff *skb);
++int udp_v4_early_demux(struct sk_buff *skb);
+ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ struct sk_buff *skb, struct net_device *dev,
+ const struct sk_buff *hint)
+ {
+ const struct iphdr *iph = ip_hdr(skb);
+- int (*edemux)(struct sk_buff *skb);
+ int err, drop_reason;
+ struct rtable *rt;
+
+@@ -332,21 +331,29 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ goto drop_error;
+ }
+
+- if (net->ipv4.sysctl_ip_early_demux &&
++ if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
+ !skb_dst(skb) &&
+ !skb->sk &&
+ !ip_is_fragment(iph)) {
+- const struct net_protocol *ipprot;
+- int protocol = iph->protocol;
+-
+- ipprot = rcu_dereference(inet_protos[protocol]);
+- if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) {
+- err = INDIRECT_CALL_2(edemux, tcp_v4_early_demux,
+- udp_v4_early_demux, skb);
+- if (unlikely(err))
+- goto drop_error;
+- /* must reload iph, skb->head might have changed */
+- iph = ip_hdr(skb);
++ switch (iph->protocol) {
++ case IPPROTO_TCP:
++ if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux)) {
++ tcp_v4_early_demux(skb);
++
++ /* must reload iph, skb->head might have changed */
++ iph = ip_hdr(skb);
++ }
++ break;
++ case IPPROTO_UDP:
++ if (READ_ONCE(net->ipv4.sysctl_udp_early_demux)) {
++ err = udp_v4_early_demux(skb);
++ if (unlikely(err))
++ goto drop_error;
++
++ /* must reload iph, skb->head might have changed */
++ iph = ip_hdr(skb);
++ }
++ break;
+ }
+ }
+
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index ffe0264a51b8..6b718688865e 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -354,61 +354,6 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
+ return ret;
+ }
+
+-static void proc_configure_early_demux(int enabled, int protocol)
+-{
+- struct net_protocol *ipprot;
+-#if IS_ENABLED(CONFIG_IPV6)
+- struct inet6_protocol *ip6prot;
+-#endif
+-
+- rcu_read_lock();
+-
+- ipprot = rcu_dereference(inet_protos[protocol]);
+- if (ipprot)
+- ipprot->early_demux = enabled ? ipprot->early_demux_handler :
+- NULL;
+-
+-#if IS_ENABLED(CONFIG_IPV6)
+- ip6prot = rcu_dereference(inet6_protos[protocol]);
+- if (ip6prot)
+- ip6prot->early_demux = enabled ? ip6prot->early_demux_handler :
+- NULL;
+-#endif
+- rcu_read_unlock();
+-}
+-
+-static int proc_tcp_early_demux(struct ctl_table *table, int write,
+- void *buffer, size_t *lenp, loff_t *ppos)
+-{
+- int ret = 0;
+-
+- ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
+-
+- if (write && !ret) {
+- int enabled = init_net.ipv4.sysctl_tcp_early_demux;
+-
+- proc_configure_early_demux(enabled, IPPROTO_TCP);
+- }
+-
+- return ret;
+-}
+-
+-static int proc_udp_early_demux(struct ctl_table *table, int write,
+- void *buffer, size_t *lenp, loff_t *ppos)
+-{
+- int ret = 0;
+-
+- ret = proc_dou8vec_minmax(table, write, buffer, lenp, ppos);
+-
+- if (write && !ret) {
+- int enabled = init_net.ipv4.sysctl_udp_early_demux;
+-
+- proc_configure_early_demux(enabled, IPPROTO_UDP);
+- }
+-
+- return ret;
+-}
+-
+ static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,
+ int write, void *buffer,
+ size_t *lenp, loff_t *ppos)
+@@ -711,14 +656,14 @@ static struct ctl_table ipv4_net_table[] = {
+ .data = &init_net.ipv4.sysctl_udp_early_demux,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+- .proc_handler = proc_udp_early_demux
++ .proc_handler = proc_dou8vec_minmax,
+ },
+ {
+ .procname = "tcp_early_demux",
+ .data = &init_net.ipv4.sysctl_tcp_early_demux,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+- .proc_handler = proc_tcp_early_demux
++ .proc_handler = proc_dou8vec_minmax,
+ },
+ {
+ .procname = "nexthop_compat_mode",
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index 5b5ea35635f9..caba03e551ef 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -45,20 +45,23 @@
+ #include <net/inet_ecn.h>
+ #include <net/dst_metadata.h>
+
+-INDIRECT_CALLABLE_DECLARE(void tcp_v6_early_demux(struct sk_buff *));
+ static void ip6_rcv_finish_core(struct net *net, struct sock *sk,
+ struct sk_buff *skb)
+ {
+- void (*edemux)(struct sk_buff *skb);
+-
+- if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
+- const struct inet6_protocol *ipprot;
+-
+- ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
+- if (ipprot && (edemux = READ_ONCE(ipprot->early_demux)))
+- INDIRECT_CALL_2(edemux, tcp_v6_early_demux,
+- udp_v6_early_demux, skb);
++ if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
++ !skb_dst(skb) && !skb->sk) {
++ switch (ipv6_hdr(skb)->nexthdr) {
++ case IPPROTO_TCP:
++ if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux))
++ tcp_v6_early_demux(skb);
++ break;
++ case IPPROTO_UDP:
++ if (READ_ONCE(net->ipv4.sysctl_udp_early_demux))
++ udp_v6_early_demux(skb);
++ break;
++ }
+ }
++
+ if (!skb_valid_dst(skb))
+ ip6_route_input(skb);
+ }
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index cbc5fff3d846..5185c11dc444 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1822,7 +1822,7 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
+ goto discard_it;
+ }
+
+-INDIRECT_CALLABLE_SCOPE void tcp_v6_early_demux(struct sk_buff *skb)
++void tcp_v6_early_demux(struct sk_buff *skb)
+ {
+ const struct ipv6hdr *hdr;
+ const struct tcphdr *th;
+@@ -2176,12 +2176,7 @@ struct proto tcpv6_prot = {
+ };
+ EXPORT_SYMBOL_GPL(tcpv6_prot);
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct inet6_protocol tcpv6_protocol = {
+- .early_demux = tcp_v6_early_demux,
+- .early_demux_handler = tcp_v6_early_demux,
++static const struct inet6_protocol tcpv6_protocol = {
+ .handler = tcp_v6_rcv,
+ .err_handler = tcp_v6_err,
+ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index a535c3f2e4af..aea28bf701be 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1052,7 +1052,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
+ return NULL;
+ }
+
+-INDIRECT_CALLABLE_SCOPE void udp_v6_early_demux(struct sk_buff *skb)
++void udp_v6_early_demux(struct sk_buff *skb)
+ {
+ struct net *net = dev_net(skb->dev);
+ const struct udphdr *uh;
+@@ -1660,12 +1660,7 @@ int udpv6_getsockopt(struct sock *sk, int level, int optname,
+ return ipv6_getsockopt(sk, level, optname, optval, optlen);
+ }
+
+-/* thinking of making this const? Don't.
+- * early_demux can change based on sysctl.
+- */
+-static struct inet6_protocol udpv6_protocol = {
+- .early_demux = udp_v6_early_demux,
+- .early_demux_handler = udp_v6_early_demux,
++static const struct inet6_protocol udpv6_protocol = {
+ .handler = udpv6_rcv,
+ .err_handler = udpv6_err,
+ .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+--
+2.35.1
+
--- /dev/null
+From 80b07dddfc6e5c510315c1955568371259e613b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 10:26:43 -0700
+Subject: udp: Fix a data-race around sysctl_udp_l3mdev_accept.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 3d72bb4188c708bb16758c60822fc4dda7a95174 ]
+
+While reading sysctl_udp_l3mdev_accept, it can be changed concurrently.
+Thus, we need to add READ_ONCE() to its reader.
+
+Fixes: 63a6fff353d0 ("net: Avoid receiving packets with an l3mdev on unbound UDP sockets")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/udp.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/udp.h b/include/net/udp.h
+index 07d0ceadcf6e..abe91ab9030d 100644
+--- a/include/net/udp.h
++++ b/include/net/udp.h
+@@ -238,7 +238,7 @@ static inline bool udp_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+ int dif, int sdif)
+ {
+ #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+- return inet_bound_dev_eq(!!net->ipv4.sysctl_udp_l3mdev_accept,
++ return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_udp_l3mdev_accept),
+ bound_dev_if, dif, sdif);
+ #else
+ return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+--
+2.35.1
+
--- /dev/null
+From 2286e083e407b0e178f167ab95278662bc761d78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 14:46:25 +0800
+Subject: xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in
+ xfrm_bundle_lookup()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit f85daf0e725358be78dfd208dea5fd665d8cb901 ]
+
+xfrm_policy_lookup() will call xfrm_pol_hold_rcu() to get a refcount of
+pols[0]. This refcount can be dropped in xfrm_expand_policies() when
+xfrm_expand_policies() return error. pols[0]'s refcount is balanced in
+here. But xfrm_bundle_lookup() will also call xfrm_pols_put() with
+num_pols == 1 to drop this refcount when xfrm_expand_policies() return
+error.
+
+This patch also fix an illegal address access. pols[0] will save a error
+point when xfrm_policy_lookup fails. This lead to xfrm_pols_put to resolve
+an illegal address in xfrm_bundle_lookup's error path.
+
+Fix these by setting num_pols = 0 in xfrm_expand_policies()'s error path.
+
+Fixes: 80c802f3073e ("xfrm: cache bundles instead of policies for outgoing flows")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_policy.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index f1876ea61fdc..f1a0bab920a5 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -2678,8 +2678,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
+ *num_xfrms = 0;
+ return 0;
+ }
+- if (IS_ERR(pols[0]))
++ if (IS_ERR(pols[0])) {
++ *num_pols = 0;
+ return PTR_ERR(pols[0]);
++ }
+
+ *num_xfrms = pols[0]->xfrm_nr;
+
+@@ -2694,6 +2696,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
+ if (pols[1]) {
+ if (IS_ERR(pols[1])) {
+ xfrm_pols_put(pols, *num_pols);
++ *num_pols = 0;
+ return PTR_ERR(pols[1]);
+ }
+ (*num_pols)++;
+--
+2.35.1
+