From 27600805e62f800bacf990354632eae4e487d34c Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Thu, 3 Sep 2026 10:43:25 -0500 Subject: x86/amd_node: Fix PCI device reference counting in amd_smn_init() The local "root" pointer is a temporary variable used during the device search. Therefore, refcount related to the search iterators should be cleaned up after the search is complete. Use the __free() cleanup macro to ensure the refcount is decremented when the temporary pointer goes out of scope. Additionally, increment the refcount when caching a root pointer. This ensures the in-use refcount is separate from the temporary search refcounting. Finally, drop the redundant "root = NULL" before the second search loop. The pci_get_class() iterator always decrements the refcount of its "from" argument, so the first loop can only fall through with "root" already NULL. Fixes: 0a4b61d9c2e4 ("x86/amd_node: Fix AMD root device caching") Closes: https://sashiko.dev/#/patchset/20260806160159.230453-1-jason.andryuk%40amd.com Reported-by: Sashiko Assisted-by: LLM Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Mario Limonciello (AMD) Cc: Link: https://patch.msgid.link/20260903154325.74343-1-yazen.ghannam@amd.com --- drivers/net/wireguard/allowedips.h | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 drivers/net/wireguard/allowedips.h (limited to 'drivers/net/wireguard/allowedips.h') diff --git a/drivers/net/wireguard/allowedips.h b/drivers/net/wireguard/allowedips.h new file mode 100644 index 000000000..931958cb6 --- /dev/null +++ b/drivers/net/wireguard/allowedips.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. + */ + +#ifndef _WG_ALLOWEDIPS_H +#define _WG_ALLOWEDIPS_H + +#include +#include +#include + +struct wg_peer; + +struct allowedips_node { + struct wg_peer __rcu *peer; + struct allowedips_node __rcu *bit[2]; + u8 cidr, bit_at_a, bit_at_b, bitlen; + u8 bits[16] __aligned(__alignof(u64)); + + /* Keep rarely used members at bottom to be beyond cache line. */ + unsigned long parent_bit_packed; + union { + struct list_head peer_list; + struct rcu_head rcu; + }; +}; + +struct allowedips { + struct allowedips_node __rcu *root4; + struct allowedips_node __rcu *root6; + u64 seq; +} __aligned(4); /* We pack the lower 2 bits of &root, but m68k only gives 16-bit alignment. */ + +void wg_allowedips_init(struct allowedips *table); +void wg_allowedips_free(struct allowedips *table, struct mutex *mutex); +int wg_allowedips_insert_v4(struct allowedips *table, const struct in_addr *ip, + u8 cidr, struct wg_peer *peer, struct mutex *lock); +int wg_allowedips_insert_v6(struct allowedips *table, const struct in6_addr *ip, + u8 cidr, struct wg_peer *peer, struct mutex *lock); +int wg_allowedips_remove_v4(struct allowedips *table, const struct in_addr *ip, + u8 cidr, struct wg_peer *peer, struct mutex *lock); +int wg_allowedips_remove_v6(struct allowedips *table, const struct in6_addr *ip, + u8 cidr, struct wg_peer *peer, struct mutex *lock); +void wg_allowedips_remove_by_peer(struct allowedips *table, + struct wg_peer *peer, struct mutex *lock); +/* The ip input pointer should be __aligned(__alignof(u64))) */ +int wg_allowedips_read_node(struct allowedips_node *node, u8 ip[16], u8 *cidr); + +/* These return a strong reference to a peer: */ +struct wg_peer *wg_allowedips_lookup_dst(struct allowedips *table, + struct sk_buff *skb); +struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table, + struct sk_buff *skb); + +#ifdef DEBUG +bool wg_allowedips_selftest(void); +#endif + +int wg_allowedips_slab_init(void); +void wg_allowedips_slab_uninit(void); + +#endif /* _WG_ALLOWEDIPS_H */ -- cgit v1.3.1