diff --git a/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch b/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch index 125dc12649..94102ff842 100644 --- a/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch +++ b/projects/ArchR/devices/RK3326/patches/mali-bifrost/003-midgard-refactor-power-init-and-fixed-unbalanced-run.patch @@ -1,199 +1,39 @@ -From 5b1c50b3e181a57f5ce0a7d8c50f0f0823ac1609 Mon Sep 17 00:00:00 2001 -From: Paul Reioux -Date: Wed, 12 Jun 2024 07:36:52 -0700 -Subject: [PATCH] midgard: refactor power init and fixed unbalanced runtime PM - calls +midgard: balance mali probe regulator refcount + drop regulator is_enabled guard -Signed-off-by: Paul Reioux ---- - .../gpu/arm/midgard/mali_kbase_core_linux.c | 124 ++++++++++++------ - .../platform/meson/mali_kbase_runtime_pm.c | 11 +- - 2 files changed, 88 insertions(+), 47 deletions(-) - -diff --git a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c -index 0ad8a70..8db0c13 100644 --- a/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +++ b/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c -@@ -4507,31 +4507,44 @@ int power_control_init(struct kbase_device *kbdev) - - pdev = to_platform_device(kbdev->dev); - --#if defined(CONFIG_REGULATOR) -- /* Since the error code EPROBE_DEFER causes the entire probing -- * procedure to be restarted from scratch at a later time, -- * all regulators will be released before returning. -- * -- * Any other error is ignored and the driver will continue -- * operating with a partial initialization of regulators. -- */ -- for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { -- kbdev->regulators[i] = regulator_get_optional(kbdev->dev, regulator_names[i]); -- if (IS_ERR(kbdev->regulators[i])) { -- err = PTR_ERR(kbdev->regulators[i]); -- kbdev->regulators[i] = NULL; -- break; -- } -- } -- if (err == -EPROBE_DEFER) { -- while (i > 0) -- regulator_put(kbdev->regulators[--i]); -- return err; -+// #if defined(CONFIG_REGULATOR) -+// /* Since the error code EPROBE_DEFER causes the entire probing -+// * procedure to be restarted from scratch at a later time, -+// * all regulators will be released before returning. -+// * -+// * Any other error is ignored and the driver will continue -+// * operating with a partial initialization of regulators. -+// */ -+// for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { -+// kbdev->regulators[i] = regulator_get_optional(kbdev->dev, regulator_names[i]); -+// if (IS_ERR(kbdev->regulators[i])) { -+// err = PTR_ERR(kbdev->regulators[i]); -+// kbdev->regulators[i] = NULL; -+// break; -+// } -+// } -+// if (err == -EPROBE_DEFER) { -+// while (i > 0) -+// regulator_put(kbdev->regulators[--i]); -+// return err; -+// } -+ kbdev->regulators[0] = devm_regulator_get_optional(kbdev->dev, regulator_names[0]); -+ -+ if (IS_ERR(kbdev->regulators[0])) { -+ err = PTR_ERR(kbdev->regulators[0]); -+ kbdev->regulators[0] = NULL; -+ kbdev->nr_regulators = 0; -+ } else { -+ kbdev->nr_regulators = 1; -+ -+ err = regulator_enable(kbdev->regulators[0]); -+ if (err) -+ dev_dbg(&pdev->dev, "regulator_enable failed\n"); - } - -- kbdev->nr_regulators = i; +@@ -4607,6 +4607,15 @@ + + kbdev->nr_regulators = i; dev_dbg(&pdev->dev, "Regulators probed: %u\n", kbdev->nr_regulators); --#endif + -+// #endif - ++ /* Enable regulators during probe to balance the first runtime suspend's ++ * regulator_disable() call — mirrors what clocks already do with ++ * clk_prepare_enable() below. ++ */ ++ for (i = 0; i < kbdev->nr_regulators; i++) { ++ if (kbdev->regulators[i]) ++ WARN_ON(regulator_enable(kbdev->regulators[i])); ++ } + #endif + /* Having more clocks than regulators is acceptable, while the - * opposite shall not happen. -@@ -4543,30 +4556,55 @@ int power_control_init(struct kbase_device *kbdev) - * Any other error is ignored and the driver will continue - * operating with a partial initialization of clocks. - */ -- for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { -- kbdev->clocks[i] = of_clk_get_by_name(kbdev->dev->of_node, "bus"); -- if (IS_ERR(kbdev->clocks[i])) { -- err = PTR_ERR(kbdev->clocks[i]); -- kbdev->clocks[i] = NULL; -- break; -- } - -- err = clk_prepare_enable(kbdev->clocks[i]); -- if (err) { -- dev_err(kbdev->dev, "Failed to prepare and enable clock (%d)\n", err); -- clk_put(kbdev->clocks[i]); -- break; -- } -- } -- if (err == -EPROBE_DEFER) { -- while (i > 0) { -- clk_disable_unprepare(kbdev->clocks[--i]); -- clk_put(kbdev->clocks[i]); -- } -- goto clocks_probe_defer; -+ kbdev->clocks[0] = devm_clk_get_optional(kbdev->dev, NULL); -+ if (!IS_ERR(kbdev->clocks[0])) -+ dev_dbg(kbdev->dev, "clk_get: %s\n", __clk_get_name(kbdev->clocks[0])); -+ else -+ dev_err(kbdev->dev, "clk_get: is NULL"); -+ -+ /* if platform device is enabled, disable it now */ -+ //if (__clk_is_enabled(kbdev->clocks[0])) { -+ // clk_disable(kbdev->clocks[0]); -+ //} -+ /* delete from clk tree */ -+ //clk_unprepare(kbdev->clocks[0]); -+ //clk_put(kbdev->clocks[0]); -+ -+ /* now grab the gpu clock node from device tree definition */ -+ //kbdev->clocks[0] = of_clk_get_by_name(kbdev->dev->of_node, "gpu"); -+ -+ /* we are kinda commited here.. if this fails, the system will lock up */ -+ err = clk_prepare_enable(kbdev->clocks[0]); -+ if (err) { -+ dev_err(kbdev->dev, "Failed to prepare and enable clock (%d)\n", err); -+ clk_put(kbdev->clocks[0]); - } - -- kbdev->nr_clocks = i; -+ // for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { -+ // kbdev->clocks[i] = of_clk_get(kbdev->dev->of_node, (int)i); -+ // if (IS_ERR(kbdev->clocks[i])) { -+ // err = PTR_ERR(kbdev->clocks[i]); -+ // kbdev->clocks[i] = NULL; -+ // break; -+ // } -+ -+ // err = clk_prepare_enable(kbdev->clocks[i]); -+ // if (err) { -+ // dev_err(kbdev->dev, "Failed to prepare and enable clock (%d)\n", err); -+ // clk_put(kbdev->clocks[i]); -+ // break; -+ // } -+ // } -+ // if (err == -EPROBE_DEFER) { -+ // while (i > 0) { -+ // clk_disable_unprepare(kbdev->clocks[--i]); -+ // clk_put(kbdev->clocks[i]); -+ // } -+ // goto clocks_probe_defer; -+ // } -+ -+ kbdev->nr_clocks = 1; - dev_dbg(&pdev->dev, "Clocks probed: %u\n", kbdev->nr_clocks); - - /* Any error in parsing the OPP table from the device file -diff --git a/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c b/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c -index bd3b4b5..33a24bb 100644 ---- a/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c -+++ b/product/kernel/drivers/gpu/arm/midgard/platform/meson/mali_kbase_runtime_pm.c -@@ -113,7 +113,8 @@ static void enable_gpu_power_control(struct kbase_device *kbdev) - if (WARN_ON(kbdev->clocks[i] == NULL)) - ; - else if (!__clk_is_enabled(kbdev->clocks[i])) -- WARN_ON(clk_prepare_enable(kbdev->clocks[i])); -+ //WARN_ON(clk_prepare_enable(kbdev->clocks[i])); -+ ; - } - } - -@@ -125,8 +126,9 @@ static void disable_gpu_power_control(struct kbase_device *kbdev) - if (WARN_ON(kbdev->clocks[i] == NULL)) - ; - else if (__clk_is_enabled(kbdev->clocks[i])) { -- clk_disable_unprepare(kbdev->clocks[i]); -- WARN_ON(__clk_is_enabled(kbdev->clocks[i])); -+ //clk_disable_unprepare(kbdev->clocks[i]); -+ //WARN_ON(__clk_is_enabled(kbdev->clocks[i])); -+ ; +@@ -4731,6 +4740,7 @@ + #if defined(CONFIG_OF) && defined(CONFIG_REGULATOR) + for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { + if (kbdev->regulators[i]) { ++ regulator_disable(kbdev->regulators[i]); + regulator_put(kbdev->regulators[i]); + kbdev->regulators[i] = NULL; } - } - -@@ -135,7 +137,8 @@ static void disable_gpu_power_control(struct kbase_device *kbdev) +--- a/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c ++++ b/product/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c +@@ -38,7 +38,7 @@ static void enable_gpu_power_control(struct kbase_device *kbdev) + for (i = 0; i < kbdev->nr_regulators; i++) { if (WARN_ON(kbdev->regulators[i] == NULL)) ; - else if (regulator_is_enabled(kbdev->regulators[i])) -- WARN_ON(regulator_disable(kbdev->regulators[i])); -+ //WARN_ON(regulator_disable(kbdev->regulators[i])); -+ ; +- else if (!regulator_is_enabled(kbdev->regulators[i])) ++ else + WARN_ON(regulator_enable(kbdev->regulators[i])); } #endif - } --- -2.34.1 - diff --git a/projects/ArchR/packages/linux/patches/6.12-LTS/0020-usb-gadget-u_ether-guard-NULL-gadget-in-eth_get_drvinfo.patch b/projects/ArchR/packages/linux/patches/6.12-LTS/0020-usb-gadget-u_ether-guard-NULL-gadget-in-eth_get_drvinfo.patch new file mode 100644 index 0000000000..69f442bce9 --- /dev/null +++ b/projects/ArchR/packages/linux/patches/6.12-LTS/0020-usb-gadget-u_ether-guard-NULL-gadget-in-eth_get_drvinfo.patch @@ -0,0 +1,51 @@ +From: Kuen-Han Tsai +Date: Mon, 16 Mar 2026 15:49:09 +0800 +Subject: [PATCH] usb: gadget: u_ether: Fix NULL pointer deref in eth_get_drvinfo + +Commit ec35c1969650 ("usb: gadget: f_ncm: Fix net_device lifecycle with +device_move") reparents the gadget device to /sys/devices/virtual during +unbind, clearing the gadget pointer. If the userspace tool queries on +the surviving interface during this detached window, this leads to a +NULL pointer dereference. + +Unable to handle kernel NULL pointer dereference +Call trace: + eth_get_drvinfo+0x50/0x90 + ethtool_get_drvinfo+0x5c/0x1f0 + __dev_ethtool+0xaec/0x1fe0 + dev_ethtool+0x134/0x2e0 + dev_ioctl+0x338/0x560 + +Add a NULL check for dev->gadget in eth_get_drvinfo(). When detached, +skip copying the fw_version and bus_info strings, which is natively +handled by ethtool_get_drvinfo for empty strings. + +Suggested-by: Val Packett +Reported-by: Val Packett +Closes: https://lore.kernel.org/linux-usb/10890524-cf83-4a71-b879-93e2b2cc1fcc@packett.cool/ +Fixes: ec35c1969650 ("usb: gadget: f_ncm: Fix net_device lifecycle with device_move") +Cc: stable@vger.kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/linux-usb/20260316-eth-null-deref-v1-1-07005f33be85@google.com/ + +--- + drivers/usb/gadget/function/u_ether.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c +index 1a9e7c495e2e..a653fae9c0cb 100644 +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -113,8 +113,10 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) + + strscpy(p->driver, "g_ether", sizeof(p->driver)); + strscpy(p->version, UETH__VERSION, sizeof(p->version)); +- strscpy(p->fw_version, dev->gadget->name, sizeof(p->fw_version)); +- strscpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof(p->bus_info)); ++ if (dev->gadget) { ++ strscpy(p->fw_version, dev->gadget->name, sizeof(p->fw_version)); ++ strscpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof(p->bus_info)); ++ } + } + + /* REVISIT can also support: diff --git a/projects/ArchR/packages/network/iwd/sources/main.conf b/projects/ArchR/packages/network/iwd/sources/main.conf index e57adc8b9c..73e5cf7937 100644 --- a/projects/ArchR/packages/network/iwd/sources/main.conf +++ b/projects/ArchR/packages/network/iwd/sources/main.conf @@ -1,7 +1,7 @@ # use built-in dhcp client [General] EnableNetworkConfiguration=true -ControlPortOverNL80211=false +ControlPortOverNL80211=true UseDefaultInterface=true AddressRandomization=disabled AddressRandomizationRange=full