--- /dev/null
+From 89fb8acc38852116d38d721ad394aad7f2871670 Mon Sep 17 00:00:00 2001
+From: Christian Eggers <ceggers@arri.de>
+Date: Fri, 27 Jun 2025 09:05:08 +0200
+Subject: Bluetooth: HCI: Set extended advertising data synchronously
+
+From: Christian Eggers <ceggers@arri.de>
+
+commit 89fb8acc38852116d38d721ad394aad7f2871670 upstream.
+
+Currently, for controllers with extended advertising, the advertising
+data is set in the asynchronous response handler for extended
+adverstising params. As most advertising settings are performed in a
+synchronous context, the (asynchronous) setting of the advertising data
+is done too late (after enabling the advertising).
+
+Move setting of adverstising data from asynchronous response handler
+into synchronous context to fix ordering of HCI commands.
+
+Signed-off-by: Christian Eggers <ceggers@arri.de>
+Fixes: a0fb3726ba55 ("Bluetooth: Use Set ext adv/scan rsp data if controller supports")
+Cc: stable@vger.kernel.org
+v2: https://lore.kernel.org/linux-bluetooth/20250626115209.17839-1-ceggers@arri.de/
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+[ This patch deviates from the upstream version because 3 functions in
+ hci_sync.c (hci_set_ext_adv_data_sync, hci_set_adv_data_sync and
+ hci_update_adv_data_sync) had to be moved up within the file. The
+ content of these functions differs between 6.6 and newer kernels. ]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hci_event.c | 36 -------
+ net/bluetooth/hci_sync.c | 213 ++++++++++++++++++++++++++++------------------
+ 2 files changed, 133 insertions(+), 116 deletions(-)
+
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2139,40 +2139,6 @@ static u8 hci_cc_set_adv_param(struct hc
+ return rp->status;
+ }
+
+-static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
+- struct sk_buff *skb)
+-{
+- struct hci_rp_le_set_ext_adv_params *rp = data;
+- struct hci_cp_le_set_ext_adv_params *cp;
+- struct adv_info *adv_instance;
+-
+- bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
+-
+- if (rp->status)
+- return rp->status;
+-
+- cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
+- if (!cp)
+- return rp->status;
+-
+- hci_dev_lock(hdev);
+- hdev->adv_addr_type = cp->own_addr_type;
+- if (!cp->handle) {
+- /* Store in hdev for instance 0 */
+- hdev->adv_tx_power = rp->tx_power;
+- } else {
+- adv_instance = hci_find_adv_instance(hdev, cp->handle);
+- if (adv_instance)
+- adv_instance->tx_power = rp->tx_power;
+- }
+- /* Update adv data as tx power is known now */
+- hci_update_adv_data(hdev, cp->handle);
+-
+- hci_dev_unlock(hdev);
+-
+- return rp->status;
+-}
+-
+ static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
+ struct sk_buff *skb)
+ {
+@@ -4153,8 +4119,6 @@ static const struct hci_cc {
+ HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
+ hci_cc_le_read_num_adv_sets,
+ sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
+- HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
+- sizeof(struct hci_rp_le_set_ext_adv_params)),
+ HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
+ hci_cc_le_set_ext_adv_enable),
+ HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -1224,9 +1224,129 @@ static int hci_set_adv_set_random_addr_s
+ sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ }
+
++static int
++hci_set_ext_adv_params_sync(struct hci_dev *hdev, struct adv_info *adv,
++ const struct hci_cp_le_set_ext_adv_params *cp,
++ struct hci_rp_le_set_ext_adv_params *rp)
++{
++ struct sk_buff *skb;
++
++ skb = __hci_cmd_sync(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS, sizeof(*cp),
++ cp, HCI_CMD_TIMEOUT);
++
++ /* If command return a status event, skb will be set to -ENODATA */
++ if (skb == ERR_PTR(-ENODATA))
++ return 0;
++
++ if (IS_ERR(skb)) {
++ bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld",
++ HCI_OP_LE_SET_EXT_ADV_PARAMS, PTR_ERR(skb));
++ return PTR_ERR(skb);
++ }
++
++ if (skb->len != sizeof(*rp)) {
++ bt_dev_err(hdev, "Invalid response length for 0x%4.4x: %u",
++ HCI_OP_LE_SET_EXT_ADV_PARAMS, skb->len);
++ kfree_skb(skb);
++ return -EIO;
++ }
++
++ memcpy(rp, skb->data, sizeof(*rp));
++ kfree_skb(skb);
++
++ if (!rp->status) {
++ hdev->adv_addr_type = cp->own_addr_type;
++ if (!cp->handle) {
++ /* Store in hdev for instance 0 */
++ hdev->adv_tx_power = rp->tx_power;
++ } else if (adv) {
++ adv->tx_power = rp->tx_power;
++ }
++ }
++
++ return rp->status;
++}
++
++static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
++{
++ struct {
++ struct hci_cp_le_set_ext_adv_data cp;
++ u8 data[HCI_MAX_EXT_AD_LENGTH];
++ } pdu;
++ u8 len;
++ struct adv_info *adv = NULL;
++ int err;
++
++ memset(&pdu, 0, sizeof(pdu));
++
++ if (instance) {
++ adv = hci_find_adv_instance(hdev, instance);
++ if (!adv || !adv->adv_data_changed)
++ return 0;
++ }
++
++ len = eir_create_adv_data(hdev, instance, pdu.data);
++
++ pdu.cp.length = len;
++ pdu.cp.handle = instance;
++ pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
++ pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
++
++ err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_DATA,
++ sizeof(pdu.cp) + len, &pdu.cp,
++ HCI_CMD_TIMEOUT);
++ if (err)
++ return err;
++
++ /* Update data if the command succeed */
++ if (adv) {
++ adv->adv_data_changed = false;
++ } else {
++ memcpy(hdev->adv_data, pdu.data, len);
++ hdev->adv_data_len = len;
++ }
++
++ return 0;
++}
++
++static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
++{
++ struct hci_cp_le_set_adv_data cp;
++ u8 len;
++
++ memset(&cp, 0, sizeof(cp));
++
++ len = eir_create_adv_data(hdev, instance, cp.data);
++
++ /* There's nothing to do if the data hasn't changed */
++ if (hdev->adv_data_len == len &&
++ memcmp(cp.data, hdev->adv_data, len) == 0)
++ return 0;
++
++ memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
++ hdev->adv_data_len = len;
++
++ cp.length = len;
++
++ return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_DATA,
++ sizeof(cp), &cp, HCI_CMD_TIMEOUT);
++}
++
++int hci_update_adv_data_sync(struct hci_dev *hdev, u8 instance)
++{
++ if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
++ return 0;
++
++ if (ext_adv_capable(hdev))
++ return hci_set_ext_adv_data_sync(hdev, instance);
++
++ return hci_set_adv_data_sync(hdev, instance);
++}
++
+ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
+ {
+ struct hci_cp_le_set_ext_adv_params cp;
++ struct hci_rp_le_set_ext_adv_params rp;
+ bool connectable;
+ u32 flags;
+ bdaddr_t random_addr;
+@@ -1333,8 +1453,12 @@ int hci_setup_ext_adv_instance_sync(stru
+ cp.secondary_phy = HCI_ADV_PHY_1M;
+ }
+
+- err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS,
+- sizeof(cp), &cp, HCI_CMD_TIMEOUT);
++ err = hci_set_ext_adv_params_sync(hdev, adv, &cp, &rp);
++ if (err)
++ return err;
++
++ /* Update adv data as tx power is known now */
++ err = hci_set_ext_adv_data_sync(hdev, cp.handle);
+ if (err)
+ return err;
+
+@@ -1859,82 +1983,6 @@ int hci_le_terminate_big_sync(struct hci
+ sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+ }
+
+-static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
+-{
+- struct {
+- struct hci_cp_le_set_ext_adv_data cp;
+- u8 data[HCI_MAX_EXT_AD_LENGTH];
+- } pdu;
+- u8 len;
+- struct adv_info *adv = NULL;
+- int err;
+-
+- memset(&pdu, 0, sizeof(pdu));
+-
+- if (instance) {
+- adv = hci_find_adv_instance(hdev, instance);
+- if (!adv || !adv->adv_data_changed)
+- return 0;
+- }
+-
+- len = eir_create_adv_data(hdev, instance, pdu.data);
+-
+- pdu.cp.length = len;
+- pdu.cp.handle = instance;
+- pdu.cp.operation = LE_SET_ADV_DATA_OP_COMPLETE;
+- pdu.cp.frag_pref = LE_SET_ADV_DATA_NO_FRAG;
+-
+- err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_DATA,
+- sizeof(pdu.cp) + len, &pdu.cp,
+- HCI_CMD_TIMEOUT);
+- if (err)
+- return err;
+-
+- /* Update data if the command succeed */
+- if (adv) {
+- adv->adv_data_changed = false;
+- } else {
+- memcpy(hdev->adv_data, pdu.data, len);
+- hdev->adv_data_len = len;
+- }
+-
+- return 0;
+-}
+-
+-static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
+-{
+- struct hci_cp_le_set_adv_data cp;
+- u8 len;
+-
+- memset(&cp, 0, sizeof(cp));
+-
+- len = eir_create_adv_data(hdev, instance, cp.data);
+-
+- /* There's nothing to do if the data hasn't changed */
+- if (hdev->adv_data_len == len &&
+- memcmp(cp.data, hdev->adv_data, len) == 0)
+- return 0;
+-
+- memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
+- hdev->adv_data_len = len;
+-
+- cp.length = len;
+-
+- return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_DATA,
+- sizeof(cp), &cp, HCI_CMD_TIMEOUT);
+-}
+-
+-int hci_update_adv_data_sync(struct hci_dev *hdev, u8 instance)
+-{
+- if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
+- return 0;
+-
+- if (ext_adv_capable(hdev))
+- return hci_set_ext_adv_data_sync(hdev, instance);
+-
+- return hci_set_adv_data_sync(hdev, instance);
+-}
+-
+ int hci_schedule_adv_instance_sync(struct hci_dev *hdev, u8 instance,
+ bool force)
+ {
+@@ -6253,6 +6301,7 @@ static int hci_le_ext_directed_advertisi
+ struct hci_conn *conn)
+ {
+ struct hci_cp_le_set_ext_adv_params cp;
++ struct hci_rp_le_set_ext_adv_params rp;
+ int err;
+ bdaddr_t random_addr;
+ u8 own_addr_type;
+@@ -6294,8 +6343,12 @@ static int hci_le_ext_directed_advertisi
+ if (err)
+ return err;
+
+- err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS,
+- sizeof(cp), &cp, HCI_CMD_TIMEOUT);
++ err = hci_set_ext_adv_params_sync(hdev, NULL, &cp, &rp);
++ if (err)
++ return err;
++
++ /* Update adv data as tx power is known now */
++ err = hci_set_ext_adv_data_sync(hdev, cp.handle);
+ if (err)
+ return err;
+
--- /dev/null
+From fba46a5d83ca8decb338722fb4899026d8d9ead2 Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Mon, 16 Jun 2025 14:45:20 -0400
+Subject: maple_tree: fix MA_STATE_PREALLOC flag in mas_preallocate()
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit fba46a5d83ca8decb338722fb4899026d8d9ead2 upstream.
+
+Temporarily clear the preallocation flag when explicitly requesting
+allocations. Pre-existing allocations are already counted against the
+request through mas_node_count_gfp(), but the allocations will not happen
+if the MA_STATE_PREALLOC flag is set. This flag is meant to avoid
+re-allocating in bulk allocation mode, and to detect issues with
+preallocation calculations.
+
+The MA_STATE_PREALLOC flag should also always be set on zero allocations
+so that detection of underflow allocations will print a WARN_ON() during
+consumption.
+
+User visible effect of this flaw is a WARN_ON() followed by a null pointer
+dereference when subsequent requests for larger number of nodes is
+ignored, such as the vma merge retry in mmap_region() caused by drivers
+altering the vma flags (which happens in v6.6, at least)
+
+Link: https://lkml.kernel.org/r/20250616184521.3382795-3-Liam.Howlett@oracle.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reported-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
+Reported-by: Hailong Liu <hailong.liu@oppo.com>
+Link: https://lore.kernel.org/all/1652f7eb-a51b-4fee-8058-c73af63bacd1@oppo.com/
+Link: https://lore.kernel.org/all/20250428184058.1416274-1-Liam.Howlett@oracle.com/
+Link: https://lore.kernel.org/all/20250429014754.1479118-1-Liam.Howlett@oracle.com/
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Hailong Liu <hailong.liu@oppo.com>
+Cc: zhangpeng.00@bytedance.com <zhangpeng.00@bytedance.com>
+Cc: Steve Kang <Steve.Kang@unisoc.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -5497,7 +5497,7 @@ int mas_preallocate(struct ma_state *mas
+ /* At this point, we are at the leaf node that needs to be altered. */
+ /* Exact fit, no nodes needed. */
+ if (wr_mas.r_min == mas->index && wr_mas.r_max == mas->last)
+- return 0;
++ goto set_flag;
+
+ mas_wr_end_piv(&wr_mas);
+ node_size = mas_wr_new_end(&wr_mas);
+@@ -5506,10 +5506,10 @@ int mas_preallocate(struct ma_state *mas
+ if (node_size == wr_mas.node_end) {
+ /* reuse node */
+ if (!mt_in_rcu(mas->tree))
+- return 0;
++ goto set_flag;
+ /* shifting boundary */
+ if (wr_mas.offset_end - mas->offset == 1)
+- return 0;
++ goto set_flag;
+ }
+
+ if (node_size >= mt_slots[wr_mas.type]) {
+@@ -5528,10 +5528,13 @@ int mas_preallocate(struct ma_state *mas
+
+ /* node store, slot store needs one node */
+ ask_now:
++ mas->mas_flags &= ~MA_STATE_PREALLOC;
+ mas_node_count_gfp(mas, request, gfp);
+- mas->mas_flags |= MA_STATE_PREALLOC;
+- if (likely(!mas_is_err(mas)))
++ if (likely(!mas_is_err(mas))) {
++set_flag:
++ mas->mas_flags |= MA_STATE_PREALLOC;
+ return 0;
++ }
+
+ mas_set_alloc_req(mas, 0);
+ ret = xa_err(mas->node);
--- /dev/null
+From 440cf77625e300e683ca0edc39fbc4b6f3175feb Mon Sep 17 00:00:00 2001
+From: Leo Yan <leo.yan@arm.com>
+Date: Wed, 17 Jul 2024 09:22:06 +0100
+Subject: perf: build: Setup PKG_CONFIG_LIBDIR for cross compilation
+
+From: Leo Yan <leo.yan@arm.com>
+
+commit 440cf77625e300e683ca0edc39fbc4b6f3175feb upstream.
+
+On recent Linux distros like Ubuntu Noble and Debian Bookworm, the
+'pkg-config-aarch64-linux-gnu' package is missing. As a result, the
+aarch64-linux-gnu-pkg-config command is not available, which causes
+build failures.
+
+When a build passes the environment variables PKG_CONFIG_LIBDIR or
+PKG_CONFIG_PATH, like a user uses make command or a build system
+(like Yocto, Buildroot, etc) prepares the variables and passes to the
+Perf's Makefile, the commit keeps these variables for package
+configuration. Otherwise, this commit sets the PKG_CONFIG_LIBDIR
+variable to use the Multiarch libs for the cross compilation.
+
+Signed-off-by: Leo Yan <leo.yan@arm.com>
+Tested-by: Ian Rogers <irogers@google.com>
+Cc: amadio@gentoo.org
+Cc: Thomas Richter <tmricht@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240717082211.524826-2-leo.yan@arm.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/build/feature/Makefile | 25 ++++++++++++++++++++++++-
+ tools/perf/Makefile.perf | 27 ++++++++++++++++++++++++++-
+ 2 files changed, 50 insertions(+), 2 deletions(-)
+
+--- a/tools/build/feature/Makefile
++++ b/tools/build/feature/Makefile
+@@ -80,7 +80,30 @@ FILES=
+
+ FILES := $(addprefix $(OUTPUT),$(FILES))
+
+-PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
++# Some distros provide the command $(CROSS_COMPILE)pkg-config for
++# searching packges installed with Multiarch. Use it for cross
++# compilation if it is existed.
++ifneq (, $(shell which $(CROSS_COMPILE)pkg-config))
++ PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
++else
++ PKG_CONFIG ?= pkg-config
++
++ # PKG_CONFIG_PATH or PKG_CONFIG_LIBDIR, alongside PKG_CONFIG_SYSROOT_DIR
++ # for modified system root, are required for the cross compilation.
++ # If these PKG_CONFIG environment variables are not set, Multiarch library
++ # paths are used instead.
++ ifdef CROSS_COMPILE
++ ifeq ($(PKG_CONFIG_LIBDIR)$(PKG_CONFIG_PATH)$(PKG_CONFIG_SYSROOT_DIR),)
++ CROSS_ARCH = $(shell $(CC) -dumpmachine)
++ PKG_CONFIG_LIBDIR := /usr/local/$(CROSS_ARCH)/lib/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/lib/$(CROSS_ARCH)/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/lib/$(CROSS_ARCH)/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/
++ export PKG_CONFIG_LIBDIR
++ endif
++ endif
++endif
+
+ all: $(FILES)
+
+--- a/tools/perf/Makefile.perf
++++ b/tools/perf/Makefile.perf
+@@ -188,7 +188,32 @@ HOSTLD ?= ld
+ HOSTAR ?= ar
+ CLANG ?= clang
+
+-PKG_CONFIG = $(CROSS_COMPILE)pkg-config
++# Some distros provide the command $(CROSS_COMPILE)pkg-config for
++# searching packges installed with Multiarch. Use it for cross
++# compilation if it is existed.
++ifneq (, $(shell which $(CROSS_COMPILE)pkg-config))
++ PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
++else
++ PKG_CONFIG ?= pkg-config
++
++ # PKG_CONFIG_PATH or PKG_CONFIG_LIBDIR, alongside PKG_CONFIG_SYSROOT_DIR
++ # for modified system root, is required for the cross compilation.
++ # If these PKG_CONFIG environment variables are not set, Multiarch library
++ # paths are used instead.
++ ifdef CROSS_COMPILE
++ ifeq ($(PKG_CONFIG_LIBDIR)$(PKG_CONFIG_PATH)$(PKG_CONFIG_SYSROOT_DIR),)
++ CROSS_ARCH = $(shell $(CC) -dumpmachine)
++ PKG_CONFIG_LIBDIR := /usr/local/$(CROSS_ARCH)/lib/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/lib/$(CROSS_ARCH)/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/lib/$(CROSS_ARCH)/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/
++ PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/
++ export PKG_CONFIG_LIBDIR
++ $(warning Missing PKG_CONFIG_LIBDIR, PKG_CONFIG_PATH and PKG_CONFIG_SYSROOT_DIR for cross compilation,)
++ $(warning set PKG_CONFIG_LIBDIR for using Multiarch libs.)
++ endif
++ endif
++endif
+
+ RM = rm -f
+ LN = ln -f