AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/14 09:37 flow patch-triage
14m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the `qcom_bam_dmux` driver, which is a platform driver for specific Qualcomm hardware. Since there is no software emulation for this hardware in virtualized environments like QEMU or GCE, the modified code paths are impossible to reach and cannot be fuzzed.",
  "WorthFuzzing": false
}

1/1 2026/07/14 09:37 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 72469a2e7040a3987ca46b95d1d1ec628d4d9cae\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Tue Jul 14 09:37:44 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml b/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml\nindex 33746c238513d7..27f0fdf285c17d 100644\n--- a/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml\n+++ b/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml\n@@ -22,7 +22,13 @@ description: |\n \n properties:\n   compatible:\n-    const: qcom,bam-dmux\n+    oneOf:\n+      - const: qcom,bam-dmux\n+      - items:\n+          - enum:\n+              # Shikra\n+              - qcom,shikra-bam-dmux\n+          - const: qcom,bam-dmux\n \n   interrupts:\n     description:\ndiff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig\nindex 958dbc7347fa84..1b133c56231615 100644\n--- a/drivers/net/wwan/Kconfig\n+++ b/drivers/net/wwan/Kconfig\n@@ -65,6 +65,7 @@ config MHI_WWAN_MBIM\n config QCOM_BAM_DMUX\n \ttristate \"Qualcomm BAM-DMUX WWAN network driver\"\n \tdepends on (DMA_ENGINE \u0026\u0026 PM \u0026\u0026 QCOM_SMEM_STATE) || COMPILE_TEST\n+\tselect QCOM_SCM\n \thelp\n \t  The BAM Data Multiplexer provides access to the network data channels\n \t  of modems integrated into many older Qualcomm SoCs, e.g. Qualcomm\ndiff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c\nindex cc6ace8d64371e..247230b720e601 100644\n--- a/drivers/net/wwan/qcom_bam_dmux.c\n+++ b/drivers/net/wwan/qcom_bam_dmux.c\n@@ -9,10 +9,12 @@\n #include \u003clinux/completion.h\u003e\n #include \u003clinux/dma-mapping.h\u003e\n #include \u003clinux/dmaengine.h\u003e\n+#include \u003clinux/firmware/qcom/qcom_scm.h\u003e\n #include \u003clinux/if_arp.h\u003e\n #include \u003clinux/interrupt.h\u003e\n #include \u003clinux/module.h\u003e\n #include \u003clinux/netdevice.h\u003e\n+#include \u003clinux/of.h\u003e\n #include \u003clinux/platform_device.h\u003e\n #include \u003clinux/pm_runtime.h\u003e\n #include \u003clinux/soc/qcom/smem_state.h\u003e\n@@ -62,6 +64,7 @@ struct bam_dmux_skb_dma {\n \tstruct bam_dmux *dmux;\n \tstruct sk_buff *skb;\n \tdma_addr_t addr;\n+\tvoid *rx_virt; /* non-NULL: slot in the coherent RX block */\n };\n \n struct bam_dmux {\n@@ -75,6 +78,10 @@ struct bam_dmux {\n \tstruct completion pc_ack_completion;\n \n \tstruct dma_chan *rx, *tx;\n+\t/* Single coherent block backing all RX buffers, NULL if unused */\n+\tvoid *rx_buf;\n+\tdma_addr_t rx_buf_dma;\n+\tu64 rx_buf_perms; /* SCM source-VMID bitmask of rx_buf */\n \tstruct bam_dmux_skb_dma rx_skbs[BAM_DMUX_NUM_SKB];\n \tstruct bam_dmux_skb_dma tx_skbs[BAM_DMUX_NUM_SKB];\n \tspinlock_t tx_lock; /* Protect tx_skbs, tx_next_skb */\n@@ -92,6 +99,10 @@ struct bam_dmux_netdev {\n \tu8 ch;\n };\n \n+struct bam_dmux_data {\n+\tu32 vmid;\n+};\n+\n static void bam_dmux_pc_vote(struct bam_dmux *dmux, bool enable)\n {\n \treinit_completion(\u0026dmux-\u003epc_ack_completion);\n@@ -111,6 +122,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,\n {\n \tstruct device *dev = skb_dma-\u003edmux-\u003edev;\n \n+\tif (skb_dma-\u003erx_virt) /* coherent RX slot: addr pre-assigned */\n+\t\treturn true;\n+\n \tskb_dma-\u003eaddr = dma_map_single(dev, skb_dma-\u003eskb-\u003edata, skb_dma-\u003eskb-\u003elen, dir);\n \tif (dma_mapping_error(dev, skb_dma-\u003eaddr)) {\n \t\tdev_err(dev, \"Failed to DMA map buffer\\n\");\n@@ -124,6 +138,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,\n static void bam_dmux_skb_dma_unmap(struct bam_dmux_skb_dma *skb_dma,\n \t\t\t\t   enum dma_data_direction dir)\n {\n+\tif (skb_dma-\u003erx_virt) /* coherent RX slot: nothing to unmap */\n+\t\treturn;\n+\n \tdma_unmap_single(skb_dma-\u003edmux-\u003edev, skb_dma-\u003eaddr, skb_dma-\u003eskb-\u003elen, dir);\n \tskb_dma-\u003eaddr = 0;\n }\n@@ -468,9 +485,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)\n {\n \tstruct bam_dmux *dmux = skb_dma-\u003edmux;\n \tstruct dma_async_tx_descriptor *desc;\n+\tsize_t len = skb_dma-\u003erx_virt ? BAM_DMUX_BUFFER_SIZE : skb_dma-\u003eskb-\u003elen;\n \n \tdesc = dmaengine_prep_slave_single(dmux-\u003erx, skb_dma-\u003eaddr,\n-\t\t\t\t\t   skb_dma-\u003eskb-\u003elen, DMA_DEV_TO_MEM,\n+\t\t\t\t\t   len, DMA_DEV_TO_MEM,\n \t\t\t\t\t   DMA_PREP_INTERRUPT);\n \tif (!desc) {\n \t\tdev_err(dmux-\u003edev, \"Failed to prepare RX DMA buffer\\n\");\n@@ -485,6 +503,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)\n \n static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gfp)\n {\n+\t/* Coherent RX slots have rx_virt and addr pre-assigned at probe. */\n+\tif (skb_dma-\u003erx_virt)\n+\t\treturn bam_dmux_skb_dma_submit_rx(skb_dma);\n+\n \tif (!skb_dma-\u003eskb) {\n \t\tskb_dma-\u003eskb = __netdev_alloc_skb(NULL, BAM_DMUX_BUFFER_SIZE, gfp);\n \t\tif (!skb_dma-\u003eskb)\n@@ -499,9 +521,10 @@ static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gf\n static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)\n {\n \tstruct bam_dmux *dmux = skb_dma-\u003edmux;\n-\tstruct sk_buff *skb = skb_dma-\u003eskb;\n-\tstruct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb-\u003edata;\n+\tstruct bam_dmux_hdr *hdr = skb_dma-\u003erx_virt ? skb_dma-\u003erx_virt :\n+\t\t\t\t   (struct bam_dmux_hdr *)skb_dma-\u003eskb-\u003edata;\n \tstruct net_device *netdev = dmux-\u003enetdevs[hdr-\u003ech];\n+\tstruct sk_buff *skb;\n \n \tif (!netdev || !netif_running(netdev)) {\n \t\tdev_warn(dmux-\u003edev, \"Data for inactive channel %u\\n\", hdr-\u003ech);\n@@ -514,10 +537,18 @@ static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)\n \t\treturn;\n \t}\n \n-\tskb_dma-\u003eskb = NULL; /* Hand over to network stack */\n-\n-\tskb_pull(skb, sizeof(*hdr));\n-\tskb_trim(skb, hdr-\u003elen);\n+\tif (skb_dma-\u003erx_virt) {\n+\t\t/* Coherent block is not page-backed: copy out to a real skb */\n+\t\tskb = netdev_alloc_skb(netdev, hdr-\u003elen);\n+\t\tif (!skb)\n+\t\t\treturn;\n+\t\tskb_put_data(skb, (u8 *)skb_dma-\u003erx_virt + sizeof(*hdr), hdr-\u003elen);\n+\t} else {\n+\t\tskb = skb_dma-\u003eskb;\n+\t\tskb_dma-\u003eskb = NULL; /* Hand over to network stack */\n+\t\tskb_pull(skb, sizeof(*hdr));\n+\t\tskb_trim(skb, hdr-\u003elen);\n+\t}\n \tskb-\u003edev = netdev;\n \n \t/* Only Raw-IP/QMAP is supported by this driver */\n@@ -574,10 +605,14 @@ static void bam_dmux_rx_callback(void *data)\n {\n \tstruct bam_dmux_skb_dma *skb_dma = data;\n \tstruct bam_dmux *dmux = skb_dma-\u003edmux;\n-\tstruct sk_buff *skb = skb_dma-\u003eskb;\n-\tstruct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb-\u003edata;\n+\tstruct bam_dmux_hdr *hdr;\n \n-\tbam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);\n+\tif (skb_dma-\u003erx_virt) {\n+\t\thdr = skb_dma-\u003erx_virt; /* coherent RX: no skb to unmap */\n+\t} else {\n+\t\tbam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);\n+\t\thdr = (struct bam_dmux_hdr *)skb_dma-\u003eskb-\u003edata;\n+\t}\n \n \tif (hdr-\u003emagic != BAM_DMUX_HDR_MAGIC) {\n \t\tdev_err(dmux-\u003edev, \"Invalid magic in header: %#x\\n\", hdr-\u003emagic);\n@@ -644,6 +679,9 @@ static void bam_dmux_free_skbs(struct bam_dmux_skb_dma skbs[],\n \tfor (i = 0; i \u003c BAM_DMUX_NUM_SKB; i++) {\n \t\tstruct bam_dmux_skb_dma *skb_dma = \u0026skbs[i];\n \n+\t\tif (skb_dma-\u003erx_virt) /* coherent block freed at remove */\n+\t\t\tcontinue;\n+\n \t\tif (skb_dma-\u003eaddr)\n \t\t\tbam_dmux_skb_dma_unmap(skb_dma, dir);\n \t\tif (skb_dma-\u003eskb) {\n@@ -762,6 +800,71 @@ static int __maybe_unused bam_dmux_runtime_resume(struct device *dev)\n \treturn 0;\n }\n \n+static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)\n+{\n+\tstruct device *dev = dmux-\u003edev;\n+\tconst struct bam_dmux_data *data = of_device_get_match_data(dev);\n+\tsize_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;\n+\tu64 src = BIT_ULL(QCOM_SCM_VMID_HLOS);\n+\tstruct qcom_scm_vmperm dst[2];\n+\tint i, ret;\n+\n+\tif (!data)\n+\t\treturn 0;\n+\n+\tif (!qcom_scm_is_available())\n+\t\treturn -EPROBE_DEFER;\n+\n+\tdst[0].vmid = QCOM_SCM_VMID_HLOS;\n+\tdst[0].perm = QCOM_SCM_PERM_RW;\n+\tdst[1].vmid = data-\u003evmid;\n+\tdst[1].perm = QCOM_SCM_PERM_RW;\n+\n+\tdmux-\u003erx_buf = dma_alloc_coherent(dev, size, \u0026dmux-\u003erx_buf_dma, GFP_KERNEL);\n+\tif (!dmux-\u003erx_buf)\n+\t\treturn -ENOMEM;\n+\n+\tfor (i = 0; i \u003c BAM_DMUX_NUM_SKB; i++) {\n+\t\tdmux-\u003erx_skbs[i].rx_virt = dmux-\u003erx_buf + i * BAM_DMUX_BUFFER_SIZE;\n+\t\tdmux-\u003erx_skbs[i].addr = dmux-\u003erx_buf_dma + i * BAM_DMUX_BUFFER_SIZE;\n+\t}\n+\n+\tret = qcom_scm_assign_mem(dmux-\u003erx_buf_dma, size, \u0026src, dst, ARRAY_SIZE(dst));\n+\tif (ret) {\n+\t\tdev_err(dev, \"SCM assign RX block failed: %d\\n\", ret);\n+\t\tdma_free_coherent(dev, size, dmux-\u003erx_buf, dmux-\u003erx_buf_dma);\n+\t\tdmux-\u003erx_buf = NULL;\n+\t\treturn ret;\n+\t}\n+\tdmux-\u003erx_buf_perms = src;\n+\n+\treturn 0;\n+}\n+\n+static void bam_dmux_free_coherent_rx(struct bam_dmux *dmux)\n+{\n+\tstruct qcom_scm_vmperm hlos = {\n+\t\t.vmid = QCOM_SCM_VMID_HLOS,\n+\t\t.perm = QCOM_SCM_PERM_RW,\n+\t};\n+\tsize_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;\n+\n+\tif (!dmux-\u003erx_buf)\n+\t\treturn;\n+\n+\tif (dmux-\u003erx_buf_perms) {\n+\t\tif (qcom_scm_assign_mem(dmux-\u003erx_buf_dma, size, \u0026dmux-\u003erx_buf_perms,\n+\t\t\t\t\t\u0026hlos, 1)) {\n+\t\t\tdev_err(dmux-\u003edev, \"SCM reclaim RX block failed; leaking\\n\");\n+\t\t\treturn;\n+\t\t}\n+\t\tdmux-\u003erx_buf_perms = 0;\n+\t}\n+\n+\tdma_free_coherent(dmux-\u003edev, size, dmux-\u003erx_buf, dmux-\u003erx_buf_dma);\n+\tdmux-\u003erx_buf = NULL;\n+}\n+\n static int bam_dmux_probe(struct platform_device *pdev)\n {\n \tstruct device *dev = \u0026pdev-\u003edev;\n@@ -809,6 +912,10 @@ static int bam_dmux_probe(struct platform_device *pdev)\n \t\tdmux-\u003etx_skbs[i].dmux = dmux;\n \t}\n \n+\tret = bam_dmux_alloc_coherent_rx(dmux);\n+\tif (ret)\n+\t\treturn ret;\n+\n \t/* Runtime PM manages our own power vote.\n \t * Note that the RX path may be active even if we are runtime suspended,\n \t * since it is controlled by the remote side.\n@@ -845,6 +952,7 @@ static int bam_dmux_probe(struct platform_device *pdev)\n err_disable_pm:\n \tpm_runtime_disable(dev);\n \tpm_runtime_dont_use_autosuspend(dev);\n+\tbam_dmux_free_coherent_rx(dmux);\n \treturn ret;\n }\n \n@@ -879,13 +987,19 @@ static void bam_dmux_remove(struct platform_device *pdev)\n \tdisable_irq(dmux-\u003epc_irq);\n \tbam_dmux_power_off(dmux);\n \tbam_dmux_free_skbs(dmux-\u003etx_skbs, DMA_TO_DEVICE);\n+\tbam_dmux_free_coherent_rx(dmux);\n }\n \n static const struct dev_pm_ops bam_dmux_pm_ops = {\n \tSET_RUNTIME_PM_OPS(bam_dmux_runtime_suspend, bam_dmux_runtime_resume, NULL)\n };\n \n+static const struct bam_dmux_data shikra_data = {\n+\t.vmid = QCOM_SCM_VMID_NAV,\n+};\n+\n static const struct of_device_id bam_dmux_of_match[] = {\n+\t{ .compatible = \"qcom,shikra-bam-dmux\", .data = \u0026shikra_data },\n \t{ .compatible = \"qcom,bam-dmux\" },\n \t{ /* sentinel */ }\n };\n"
}

2/1 2026/07/14 09:37 agent patch-evaluator
14m Model:
gemini-3.1-pro-preview

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the `qcom_bam_dmux` driver, which is a platform driver for specific Qualcomm hardware. Since there is no software emulation for this hardware in virtualized environments like QEMU or GCE, the modified code paths are impossible to reach and cannot be fuzzed.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Do not list too generic configs (we already have them enabled). Only list those that
   specifically cover the modified code. List them in the EnableConfigs output array,
   and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 72469a2e7040a3987ca46b95d1d1ec628d4d9cae
Author: syz-cluster <triage@syzkaller.com>
Date:   Tue Jul 14 09:37:44 2026 +0000

    syz-cluster: applied patch under review

diff --git a/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml b/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
index 33746c238513d7..27f0fdf285c17d 100644
--- a/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
@@ -22,7 +22,13 @@ description: |
 
 properties:
   compatible:
-    const: qcom,bam-dmux
+    oneOf:
+      - const: qcom,bam-dmux
+      - items:
+          - enum:
+              # Shikra
+              - qcom,shikra-bam-dmux
+          - const: qcom,bam-dmux
 
   interrupts:
     description:
diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig
index 958dbc7347fa84..1b133c56231615 100644
--- a/drivers/net/wwan/Kconfig
+++ b/drivers/net/wwan/Kconfig
@@ -65,6 +65,7 @@ config MHI_WWAN_MBIM
 config QCOM_BAM_DMUX
 	tristate "Qualcomm BAM-DMUX WWAN network driver"
 	depends on (DMA_ENGINE && PM && QCOM_SMEM_STATE) || COMPILE_TEST
+	select QCOM_SCM
 	help
 	  The BAM Data Multiplexer provides access to the network data channels
 	  of modems integrated into many older Qualcomm SoCs, e.g. Qualcomm
diff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c
index cc6ace8d64371e..247230b720e601 100644
--- a/drivers/net/wwan/qcom_bam_dmux.c
+++ b/drivers/net/wwan/qcom_bam_dmux.c
@@ -9,10 +9,12 @@
 #include <linux/completion.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
+#include <linux/firmware/qcom/qcom_scm.h>
 #include <linux/if_arp.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/qcom/smem_state.h>
@@ -62,6 +64,7 @@ struct bam_dmux_skb_dma {
 	struct bam_dmux *dmux;
 	struct sk_buff *skb;
 	dma_addr_t addr;
+	void *rx_virt; /* non-NULL: slot in the coherent RX block */
 };
 
 struct bam_dmux {
@@ -75,6 +78,10 @@ struct bam_dmux {
 	struct completion pc_ack_completion;
 
 	struct dma_chan *rx, *tx;
+	/* Single coherent block backing all RX buffers, NULL if unused */
+	void *rx_buf;
+	dma_addr_t rx_buf_dma;
+	u64 rx_buf_perms; /* SCM source-VMID bitmask of rx_buf */
 	struct bam_dmux_skb_dma rx_skbs[BAM_DMUX_NUM_SKB];
 	struct bam_dmux_skb_dma tx_skbs[BAM_DMUX_NUM_SKB];
 	spinlock_t tx_lock; /* Protect tx_skbs, tx_next_skb */
@@ -92,6 +99,10 @@ struct bam_dmux_netdev {
 	u8 ch;
 };
 
+struct bam_dmux_data {
+	u32 vmid;
+};
+
 static void bam_dmux_pc_vote(struct bam_dmux *dmux, bool enable)
 {
 	reinit_completion(&dmux->pc_ack_completion);
@@ -111,6 +122,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,
 {
 	struct device *dev = skb_dma->dmux->dev;
 
+	if (skb_dma->rx_virt) /* coherent RX slot: addr pre-assigned */
+		return true;
+
 	skb_dma->addr = dma_map_single(dev, skb_dma->skb->data, skb_dma->skb->len, dir);
 	if (dma_mapping_error(dev, skb_dma->addr)) {
 		dev_err(dev, "Failed to DMA map buffer\n");
@@ -124,6 +138,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,
 static void bam_dmux_skb_dma_unmap(struct bam_dmux_skb_dma *skb_dma,
 				   enum dma_data_direction dir)
 {
+	if (skb_dma->rx_virt) /* coherent RX slot: nothing to unmap */
+		return;
+
 	dma_unmap_single(skb_dma->dmux->dev, skb_dma->addr, skb_dma->skb->len, dir);
 	skb_dma->addr = 0;
 }
@@ -468,9 +485,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)
 {
 	struct bam_dmux *dmux = skb_dma->dmux;
 	struct dma_async_tx_descriptor *desc;
+	size_t len = skb_dma->rx_virt ? BAM_DMUX_BUFFER_SIZE : skb_dma->skb->len;
 
 	desc = dmaengine_prep_slave_single(dmux->rx, skb_dma->addr,
-					   skb_dma->skb->len, DMA_DEV_TO_MEM,
+					   len, DMA_DEV_TO_MEM,
 					   DMA_PREP_INTERRUPT);
 	if (!desc) {
 		dev_err(dmux->dev, "Failed to prepare RX DMA buffer\n");
@@ -485,6 +503,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)
 
 static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gfp)
 {
+	/* Coherent RX slots have rx_virt and addr pre-assigned at probe. */
+	if (skb_dma->rx_virt)
+		return bam_dmux_skb_dma_submit_rx(skb_dma);
+
 	if (!skb_dma->skb) {
 		skb_dma->skb = __netdev_alloc_skb(NULL, BAM_DMUX_BUFFER_SIZE, gfp);
 		if (!skb_dma->skb)
@@ -499,9 +521,10 @@ static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gf
 static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
 {
 	struct bam_dmux *dmux = skb_dma->dmux;
-	struct sk_buff *skb = skb_dma->skb;
-	struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
+	struct bam_dmux_hdr *hdr = skb_dma->rx_virt ? skb_dma->rx_virt :
+				   (struct bam_dmux_hdr *)skb_dma->skb->data;
 	struct net_device *netdev = dmux->netdevs[hdr->ch];
+	struct sk_buff *skb;
 
 	if (!netdev || !netif_running(netdev)) {
 		dev_warn(dmux->dev, "Data for inactive channel %u\n", hdr->ch);
@@ -514,10 +537,18 @@ static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
 		return;
 	}
 
-	skb_dma->skb = NULL; /* Hand over to network stack */
-
-	skb_pull(skb, sizeof(*hdr));
-	skb_trim(skb, hdr->len);
+	if (skb_dma->rx_virt) {
+		/* Coherent block is not page-backed: copy out to a real skb */
+		skb = netdev_alloc_skb(netdev, hdr->len);
+		if (!skb)
+			return;
+		skb_put_data(skb, (u8 *)skb_dma->rx_virt + sizeof(*hdr), hdr->len);
+	} else {
+		skb = skb_dma->skb;
+		skb_dma->skb = NULL; /* Hand over to network stack */
+		skb_pull(skb, sizeof(*hdr));
+		skb_trim(skb, hdr->len);
+	}
 	skb->dev = netdev;
 
 	/* Only Raw-IP/QMAP is supported by this driver */
@@ -574,10 +605,14 @@ static void bam_dmux_rx_callback(void *data)
 {
 	struct bam_dmux_skb_dma *skb_dma = data;
 	struct bam_dmux *dmux = skb_dma->dmux;
-	struct sk_buff *skb = skb_dma->skb;
-	struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
+	struct bam_dmux_hdr *hdr;
 
-	bam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);
+	if (skb_dma->rx_virt) {
+		hdr = skb_dma->rx_virt; /* coherent RX: no skb to unmap */
+	} else {
+		bam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);
+		hdr = (struct bam_dmux_hdr *)skb_dma->skb->data;
+	}
 
 	if (hdr->magic != BAM_DMUX_HDR_MAGIC) {
 		dev_err(dmux->dev, "Invalid magic in header: %#x\n", hdr->magic);
@@ -644,6 +679,9 @@ static void bam_dmux_free_skbs(struct bam_dmux_skb_dma skbs[],
 	for (i = 0; i < BAM_DMUX_NUM_SKB; i++) {
 		struct bam_dmux_skb_dma *skb_dma = &skbs[i];
 
+		if (skb_dma->rx_virt) /* coherent block freed at remove */
+			continue;
+
 		if (skb_dma->addr)
 			bam_dmux_skb_dma_unmap(skb_dma, dir);
 		if (skb_dma->skb) {
@@ -762,6 +800,71 @@ static int __maybe_unused bam_dmux_runtime_resume(struct device *dev)
 	return 0;
 }
 
+static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)
+{
+	struct device *dev = dmux->dev;
+	const struct bam_dmux_data *data = of_device_get_match_data(dev);
+	size_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;
+	u64 src = BIT_ULL(QCOM_SCM_VMID_HLOS);
+	struct qcom_scm_vmperm dst[2];
+	int i, ret;
+
+	if (!data)
+		return 0;
+
+	if (!qcom_scm_is_available())
+		return -EPROBE_DEFER;
+
+	dst[0].vmid = QCOM_SCM_VMID_HLOS;
+	dst[0].perm = QCOM_SCM_PERM_RW;
+	dst[1].vmid = data->vmid;
+	dst[1].perm = QCOM_SCM_PERM_RW;
+
+	dmux->rx_buf = dma_alloc_coherent(dev, size, &dmux->rx_buf_dma, GFP_KERNEL);
+	if (!dmux->rx_buf)
+		return -ENOMEM;
+
+	for (i = 0; i < BAM_DMUX_NUM_SKB; i++) {
+		dmux->rx_skbs[i].rx_virt = dmux->rx_buf + i * BAM_DMUX_BUFFER_SIZE;
+		dmux->rx_skbs[i].addr = dmux->rx_buf_dma + i * BAM_DMUX_BUFFER_SIZE;
+	}
+
+	ret = qcom_scm_assign_mem(dmux->rx_buf_dma, size, &src, dst, ARRAY_SIZE(dst));
+	if (ret) {
+		dev_err(dev, "SCM assign RX block failed: %d\n", ret);
+		dma_free_coherent(dev, size, dmux->rx_buf, dmux->rx_buf_dma);
+		dmux->rx_buf = NULL;
+		return ret;
+	}
+	dmux->rx_buf_perms = src;
+
+	return 0;
+}
+
+static void bam_dmux_free_coherent_rx(struct bam_dmux *dmux)
+{
+	struct qcom_scm_vmperm hlos = {
+		.vmid = QCOM_SCM_VMID_HLOS,
+		.perm = QCOM_SCM_PERM_RW,
+	};
+	size_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;
+
+	if (!dmux->rx_buf)
+		return;
+
+	if (dmux->rx_buf_perms) {
+		if (qcom_scm_assign_mem(dmux->rx_buf_dma, size, &dmux->rx_buf_perms,
+					&hlos, 1)) {
+			dev_err(dmux->dev, "SCM reclaim RX block failed; leaking\n");
+			return;
+		}
+		dmux->rx_buf_perms = 0;
+	}
+
+	dma_free_coherent(dmux->dev, size, dmux->rx_buf, dmux->rx_buf_dma);
+	dmux->rx_buf = NULL;
+}
+
 static int bam_dmux_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -809,6 +912,10 @@ static int bam_dmux_probe(struct platform_device *pdev)
 		dmux->tx_skbs[i].dmux = dmux;
 	}
 
+	ret = bam_dmux_alloc_coherent_rx(dmux);
+	if (ret)
+		return ret;
+
 	/* Runtime PM manages our own power vote.
 	 * Note that the RX path may be active even if we are runtime suspended,
 	 * since it is controlled by the remote side.
@@ -845,6 +952,7 @@ static int bam_dmux_probe(struct platform_device *pdev)
 err_disable_pm:
 	pm_runtime_disable(dev);
 	pm_runtime_dont_use_autosuspend(dev);
+	bam_dmux_free_coherent_rx(dmux);
 	return ret;
 }
 
@@ -879,13 +987,19 @@ static void bam_dmux_remove(struct platform_device *pdev)
 	disable_irq(dmux->pc_irq);
 	bam_dmux_power_off(dmux);
 	bam_dmux_free_skbs(dmux->tx_skbs, DMA_TO_DEVICE);
+	bam_dmux_free_coherent_rx(dmux);
 }
 
 static const struct dev_pm_ops bam_dmux_pm_ops = {
 	SET_RUNTIME_PM_OPS(bam_dmux_runtime_suspend, bam_dmux_runtime_resume, NULL)
 };
 
+static const struct bam_dmux_data shikra_data = {
+	.vmid = QCOM_SCM_VMID_NAV,
+};
+
 static const struct of_device_id bam_dmux_of_match[] = {
+	{ .compatible = "qcom,shikra-bam-dmux", .data = &shikra_data },
 	{ .compatible = "qcom,bam-dmux" },
 	{ /* sentinel */ }
 };

3/2 2026/07/14 09:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6171
							output: 22
							thoughts: 424
						

Thoughts:
**Analyzing the QCOM BAM DMUX Patch for Fuzzing Potential**

Okay, so I'm looking at this patch for `drivers/net/wwan/qcom_bam_dmux.c`, specifically the one that adds support for "qcom,shikra-bam-dmux."  The core of the change seems to be around how the driver handles RX buffers.  It's modifying `bam_dmux_probe` to call `bam_dmux_alloc_coherent_rx`, and that's the interesting bit because *that* function uses `qcom_scm_assign_mem`.  This suggests memory management with a specific VMID, like `QCOM_SCM_VMID_NAV`.  The RX path (`bam_dmux_skb_dma_submit_rx`, etc.) is also adjusted to deal with this coherent memory block. It’s no longer just standard skb allocation.

The question now is, can we actually *reach* this code, and is it a good target for fuzzing?  First, the driver itself, `qcom_bam_dmux.c`, is pretty straightforward.  The config is `QCOM_BAM_DMUX`, so that's simple enough to check.  The changes *are* functional, they’re messing with how the driver allocates and handles RX buffers, a classic fuzzing target.

But, can it be reached in a virtualized environment?  Is it something we can test with GCE or QEMU?  It's a platform driver, specifically for "qcom,bam-dmux" and "qcom,shikra-bam-dmux".  So, to test this, do we know the device tree structure well enough to instantiate the platform device?  If not, can syzkaller handle it, either through device injection, pseudo-devices, or modifying the device tree?  We need to look at how syzkaller can handle this.

Hold on a second... that `qcom_scm_assign_mem` call... I need to check something.  Is `qcom_scm_is_available()` actually called *before* `qcom_scm_assign_mem`? If it returns `false`, it returns `-EPROBE_DEFER`. So, `qcom_scm_is_available()` returning `false` could completely prevent us from even getting into this critical path. I have to look into this more closely and see what the conditions are for `qcom_scm_is_available()` to return `true` or `false` and then, if necessary, write some code to make sure that we reach it.



4/2 2026/07/14 09:37 tool grepper
0m Args:
{
  "Expression": "qcom_scm_is_available"
}

Results:
{
  "Output": "drivers/cpuidle/cpuidle-qcom-spm.c=130=static int spm_cpuidle_drv_probe(struct platform_device *pdev)\n--\ndrivers/cpuidle/cpuidle-qcom-spm.c-133-\ndrivers/cpuidle/cpuidle-qcom-spm.c:134:\tif (!qcom_scm_is_available())\ndrivers/cpuidle/cpuidle-qcom-spm.c-135-\t\treturn -EPROBE_DEFER;\n--\ndrivers/firmware/qcom/qcom_scm.c=230=struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)\ndrivers/firmware/qcom/qcom_scm.c-231-{\ndrivers/firmware/qcom/qcom_scm.c:232:\tif (!qcom_scm_is_available())\ndrivers/firmware/qcom/qcom_scm.c-233-\t\treturn NULL;\n--\ndrivers/firmware/qcom/qcom_scm.c=2532=static void qcom_scm_qtee_init(struct qcom_scm *scm)\n--\ndrivers/firmware/qcom/qcom_scm.c-2556-/**\ndrivers/firmware/qcom/qcom_scm.c:2557: * qcom_scm_is_available() - Checks if SCM is available\ndrivers/firmware/qcom/qcom_scm.c-2558- */\ndrivers/firmware/qcom/qcom_scm.c:2559:bool qcom_scm_is_available(void)\ndrivers/firmware/qcom/qcom_scm.c-2560-{\n--\ndrivers/firmware/qcom/qcom_scm.c-2563-}\ndrivers/firmware/qcom/qcom_scm.c:2564:EXPORT_SYMBOL_GPL(qcom_scm_is_available);\ndrivers/firmware/qcom/qcom_scm.c-2565-\n--\ndrivers/firmware/qcom/qcom_scm.c=2737=static int qcom_scm_probe(struct platform_device *pdev)\n--\ndrivers/firmware/qcom/qcom_scm.c-2829-\t/*\ndrivers/firmware/qcom/qcom_scm.c:2830:\t * Paired with smp_load_acquire() in qcom_scm_is_available().\ndrivers/firmware/qcom/qcom_scm.c-2831-\t *\n--\ndrivers/gpu/drm/msm/adreno/a6xx_gmu.c=1195=static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)\n--\ndrivers/gpu/drm/msm/adreno/a6xx_gmu.c-1214-\t\t */\ndrivers/gpu/drm/msm/adreno/a6xx_gmu.c:1215:\t\tif (!qcom_scm_is_available()) {\ndrivers/gpu/drm/msm/adreno/a6xx_gmu.c-1216-\t\t\tdev_warn_once(gpu-\u003edev-\u003edev,\n--\ndrivers/gpu/drm/msm/adreno/adreno_gpu.c=169=int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)\n--\ndrivers/gpu/drm/msm/adreno/adreno_gpu.c-178-\t/* We need SCM to be able to load the firmware */\ndrivers/gpu/drm/msm/adreno/adreno_gpu.c:179:\tif (!qcom_scm_is_available()) {\ndrivers/gpu/drm/msm/adreno/adreno_gpu.c-180-\t\tDRM_DEV_ERROR(\u0026pdev-\u003edev, \"SCM is not available\\n\");\n--\ndrivers/iommu/arm/arm-smmu/arm-smmu-qcom.c=664=static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,\n--\ndrivers/iommu/arm/arm-smmu/arm-smmu-qcom.c-682-\t/* Check to make sure qcom_scm has finished probing */\ndrivers/iommu/arm/arm-smmu/arm-smmu-qcom.c:683:\tif (!qcom_scm_is_available())\ndrivers/iommu/arm/arm-smmu/arm-smmu-qcom.c-684-\t\treturn ERR_PTR(dev_err_probe(smmu-\u003edev, -EPROBE_DEFER,\n--\ndrivers/media/platform/qcom/venus/firmware.c=211=int venus_boot(struct venus_core *core)\n--\ndrivers/media/platform/qcom/venus/firmware.c-220-\tif (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER) ||\ndrivers/media/platform/qcom/venus/firmware.c:221:\t    (core-\u003euse_tz \u0026\u0026 !qcom_scm_is_available()))\ndrivers/media/platform/qcom/venus/firmware.c-222-\t\treturn -EPROBE_DEFER;\n--\ndrivers/misc/fastrpc.c=2364=static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)\n--\ndrivers/misc/fastrpc.c-2395-\t\tvmcount = 0;\ndrivers/misc/fastrpc.c:2396:\telse if (!qcom_scm_is_available())\ndrivers/misc/fastrpc.c-2397-\t\treturn -EPROBE_DEFER;\n--\ndrivers/net/ipa/ipa_main.c=723=static enum ipa_firmware_loader ipa_firmware_loader(struct device *dev)\n--\ndrivers/net/ipa/ipa_main.c-760-\t/* We need Trust Zone to load firmware; make sure it's available */\ndrivers/net/ipa/ipa_main.c:761:\tif (qcom_scm_is_available())\ndrivers/net/ipa/ipa_main.c-762-\t\treturn IPA_LOADER_SELF;\n--\ndrivers/net/wwan/qcom_bam_dmux.c=803=static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-814-\ndrivers/net/wwan/qcom_bam_dmux.c:815:\tif (!qcom_scm_is_available())\ndrivers/net/wwan/qcom_bam_dmux.c-816-\t\treturn -EPROBE_DEFER;\n--\ndrivers/remoteproc/qcom_q6v5_mss.c=2067=static int q6v5_probe(struct platform_device *pdev)\n--\ndrivers/remoteproc/qcom_q6v5_mss.c-2079-\ndrivers/remoteproc/qcom_q6v5_mss.c:2080:\tif (desc-\u003eneed_mem_protection \u0026\u0026 !qcom_scm_is_available())\ndrivers/remoteproc/qcom_q6v5_mss.c-2081-\t\treturn -EPROBE_DEFER;\n--\ndrivers/remoteproc/qcom_q6v5_pas.c=733=static int qcom_pas_probe(struct platform_device *pdev)\n--\ndrivers/remoteproc/qcom_q6v5_pas.c-745-\ndrivers/remoteproc/qcom_q6v5_pas.c:746:\tif (!qcom_scm_is_available())\ndrivers/remoteproc/qcom_q6v5_pas.c-747-\t\treturn -EPROBE_DEFER;\n--\ndrivers/remoteproc/qcom_wcnss.c=549=static int wcnss_probe(struct platform_device *pdev)\n--\ndrivers/remoteproc/qcom_wcnss.c-559-\ndrivers/remoteproc/qcom_wcnss.c:560:\tif (!qcom_scm_is_available())\ndrivers/remoteproc/qcom_wcnss.c-561-\t\treturn -EPROBE_DEFER;\n--\ndrivers/soc/qcom/ice.c=563=static struct qcom_ice *qcom_ice_create(struct device *dev,\n--\ndrivers/soc/qcom/ice.c-567-\ndrivers/soc/qcom/ice.c:568:\tif (!qcom_scm_is_available())\ndrivers/soc/qcom/ice.c-569-\t\treturn ERR_PTR(-EPROBE_DEFER);\n--\ndrivers/soc/qcom/ocmem.c=293=static int ocmem_dev_probe(struct platform_device *pdev)\n--\ndrivers/soc/qcom/ocmem.c-299-\ndrivers/soc/qcom/ocmem.c:300:\tif (!qcom_scm_is_available())\ndrivers/soc/qcom/ocmem.c-301-\t\treturn -EPROBE_DEFER;\n--\ndrivers/soc/qcom/rmtfs_mem.c=171=static int qcom_rmtfs_mem_probe(struct platform_device *pdev)\n--\ndrivers/soc/qcom/rmtfs_mem.c-258-\t} else if (!ret) {\ndrivers/soc/qcom/rmtfs_mem.c:259:\t\tif (!qcom_scm_is_available()) {\ndrivers/soc/qcom/rmtfs_mem.c-260-\t\t\tret = -EPROBE_DEFER;\n--\ndrivers/thermal/qcom/lmh.c=97=static int lmh_probe(struct platform_device *pdev)\n--\ndrivers/thermal/qcom/lmh.c-106-\ndrivers/thermal/qcom/lmh.c:107:\tif (!qcom_scm_is_available())\ndrivers/thermal/qcom/lmh.c-108-\t\treturn -EPROBE_DEFER;\n--\ninclude/linux/firmware/qcom/qcom_scm.h=49=enum qcom_scm_ice_cipher {\n--\ninclude/linux/firmware/qcom/qcom_scm.h-61-\ninclude/linux/firmware/qcom/qcom_scm.h:62:bool qcom_scm_is_available(void);\ninclude/linux/firmware/qcom/qcom_scm.h-63-\n"
}

5/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9904
							output: 20
							thoughts: 94
						

Thoughts:
**SCM Availability: A Quick Check**

Okay, so I'm looking into the availability of the Secure Channel Manager (SCM) driver, specifically how we determine if it's been probed. The function `qcom_scm_is_available()` is the key. It's supposed to return `true` if the driver, located in `drivers/firmware/qcom/qcom_scm.c`, is initialized and ready to go. My immediate thought is, "Is this going to be available under emulation, like in QEMU, or on Google Compute Engine?" I need to confirm whether `qcom_scm` is even present and working in those environments. To get a better understanding of its detection process, I'll need to dive into the `qcom_scm_probe` function within the driver's code in `drivers/firmware/qcom/qcom_scm.c`. That should clarify how the driver determines its own availability.



6/2 2026/07/14 09:38 tool grepper
0m Args:
{
  "Expression": "qcom_scm_probe"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=2559=bool qcom_scm_is_available(void)\ndrivers/firmware/qcom/qcom_scm.c-2560-{\ndrivers/firmware/qcom/qcom_scm.c:2561:\t/* Paired with smp_store_release() in qcom_scm_probe */\ndrivers/firmware/qcom/qcom_scm.c-2562-\treturn !!smp_load_acquire(\u0026__scm);\n--\ndrivers/firmware/qcom/qcom_scm.c=2735=MODULE_PARM_DESC(download_mode, \"download mode: off/0/N for no dump mode, full/on/1/Y for full dump mode, mini for minidump mode and full,mini for both full and m...\ndrivers/firmware/qcom/qcom_scm.c-2736-\ndrivers/firmware/qcom/qcom_scm.c:2737:static int qcom_scm_probe(struct platform_device *pdev)\ndrivers/firmware/qcom/qcom_scm.c-2738-{\n--\ndrivers/firmware/qcom/qcom_scm.c=2895=static struct platform_driver qcom_scm_driver = {\n--\ndrivers/firmware/qcom/qcom_scm.c-2900-\t},\ndrivers/firmware/qcom/qcom_scm.c:2901:\t.probe = qcom_scm_probe,\ndrivers/firmware/qcom/qcom_scm.c-2902-\t.shutdown = qcom_scm_shutdown,\n"
}

7/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10645
							output: 22
							thoughts: 21
						

Thoughts:
Okay, let's dive into this. Here's my thought process on dissecting `qcom_scm_probe`:

**Analyzing `qcom_scm_probe`**

Alright, I'm going to start by getting a handle on what `qcom_scm_probe` actually *does*. My immediate instinct is to figure out its functionality. What's it designed to accomplish? What's the core purpose?

Beyond that, I need to understand the relationship. I'm especially keen to figure out what kind of device this probe function is ultimately going to bind to. Is it something specific, like a particular hardware block, or is it more generic? Understanding that binding is key to understanding the context of the function itself. The device is the critical context.



8/2 2026/07/14 09:38 tool grepper
0m Args:
{
  "Expression": "qcom_scm_dt_match"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=2875=static void qcom_scm_shutdown(struct platform_device *pdev)\n--\ndrivers/firmware/qcom/qcom_scm.c-2880-\ndrivers/firmware/qcom/qcom_scm.c:2881:static const struct of_device_id qcom_scm_dt_match[] = {\ndrivers/firmware/qcom/qcom_scm.c-2882-\t{ .compatible = \"qcom,scm\" },\n--\ndrivers/firmware/qcom/qcom_scm.c-2892-};\ndrivers/firmware/qcom/qcom_scm.c:2893:MODULE_DEVICE_TABLE(of, qcom_scm_dt_match);\ndrivers/firmware/qcom/qcom_scm.c-2894-\ndrivers/firmware/qcom/qcom_scm.c=2895=static struct platform_driver qcom_scm_driver = {\n--\ndrivers/firmware/qcom/qcom_scm.c-2897-\t\t.name\t= \"qcom_scm\",\ndrivers/firmware/qcom/qcom_scm.c:2898:\t\t.of_match_table = qcom_scm_dt_match,\ndrivers/firmware/qcom/qcom_scm.c-2899-\t\t.suppress_bind_attrs = true,\n"
}

9/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11217
							output: 21
							thoughts: 783
						

Thoughts:
**Analyzing Syzkaller's Potential for Triggering Qualcomm Driver Bugs**

Okay, so I'm thinking about how syzkaller can interact with this `qcom_scm` and the `qcom,shikra-bam-dmux` drivers. The core question is: can syzkaller actually *inject* these devices or trigger their probing?

First thought is, does syzkaller have mechanisms to add platform devices, like `syz_dev_create` or even a hypothetical `syz_platform_device_add`? Wait, no, there isn't a direct `syz_platform_device_add` call. But, syzkaller does have other system calls like `syz_init_net_socket`, `syz_mount`, or `syz_open` that *might* be used.

The catch is, syzkaller primarily uses QEMU or GCE virtual machines for testing. Is `qcom_scm` even *present* in those environments? Generally, syzkaller's standard setup uses generic x86_64 or arm64 VMs. If it's on an arm64 VM, the device tree might not include `qcom,scm`. So, can syzkaller get around this? Well, it *does* have this pseudo-device injector, and, again, maybe `syz_dev_create` could work. Wait, let me check, does `syzkaller` have `syz_platform_device_add`? No, that's not right. Hmm, more avenues, it uses calls like `syz_usb_connect` or `syz_80211_inject_frame`.

The key thing is whether syzkaller can trigger `bam_dmux_probe`. Without `qcom,shikra-bam-dmux` in the device tree, the driver won't probe unless it can instantiate platform devices. And again, no, syzkaller *doesn't* generally have a direct way to instantiate those, unless there's a specific pseudo-device.

But wait, there is `sysfs`! Syzkaller could potentially bind/unbind devices through `sysfs`, or even use `platform_device_register` if there's an appropriate interface. Hang on, no, I'm stuck on this idea, is there `syz_dev_create`? No.

Okay, let's back up a bit. Is `qcom_scm` *reachable*? If `qcom_scm_is_available()` returns false, then `bam_dmux_alloc_coherent_rx` returns `-EPROBE_DEFER`. This will lead to the probe being deferred and possibly never executed. Therefore, if `qcom_scm` *never* gets probed, `bam_dmux` will also fail to probe.

So, how does `qcom_scm` get probed? It needs `qcom,scm` in the device tree. If we're running syzkaller on a generic arm64 VM, that's likely *not* present. Importantly, syzkaller doesn't directly fuzz device tree parsing by injecting arbitrary nodes. But, maybe syzkaller *could* run on a board that *does* have `qcom,scm`? Hmm, no. Syzkaller's typical target is `qemu-system-aarch64 -machine virt`. Does the `virt` machine have `qcom,scm`? No.

Wait. Does syzkaller have a way to test *any* `qcom` drivers? Okay, let's focus on if there are syzkaller descriptions for `qcom_bam_dmux` and go from there.



10/2 2026/07/14 09:38 tool grepper
0m Args:
{
  "Expression": "qcom_bam_dmux"
}

Results:
{
  "Output": "MAINTAINERS=22101=F:\tDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml\nMAINTAINERS:22102:F:\tdrivers/net/wwan/qcom_bam_dmux.c\nMAINTAINERS-22103-\n--\ndrivers/net/wwan/Kconfig=65=config QCOM_BAM_DMUX\n--\ndrivers/net/wwan/Kconfig-76-\t  To compile this driver as a module, choose M here: the module will be\ndrivers/net/wwan/Kconfig:77:\t  called qcom_bam_dmux.\ndrivers/net/wwan/Kconfig-78-\n--\ndrivers/net/wwan/Makefile=12=obj-$(CONFIG_MHI_WWAN_MBIM) += mhi_wwan_mbim.o\ndrivers/net/wwan/Makefile:13:obj-$(CONFIG_QCOM_BAM_DMUX) += qcom_bam_dmux.o\ndrivers/net/wwan/Makefile-14-obj-$(CONFIG_RPMSG_WWAN_CTRL) += rpmsg_wwan_ctrl.o\n"
}

11/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13123
							output: 20
							thoughts: 414
						

Thoughts:
**Analyzing the Reachability of `qcom_bam_dmux` for Fuzzing**

Okay, so I'm looking at this patch and immediately, a question pops up: syzkaller doesn't have specific descriptions for `qcom_bam_dmux`. Interesting, but the author is listed as `syz-cluster <triage@syzkaller.com>`, which suggests this is a patch being tested *by* syzkaller. The task at hand is to determine if this code path is worth fuzzing. The instructions indicate I should return `WorthFuzzing=false` if the code involves unreachable sections within virtualized environments like QEMU or GCE, specifically when employing software-emulated hardware.

So, the key question is: is `qcom_bam_dmux` reachable in QEMU? It's a platform driver, right? Which means it typically attaches to devices described in the Device Tree or ACPI tables.  Unless there's a mechanism to instantiate `qcom,shikra-bam-dmux` and `qcom,scm` from user space, it's a dead end. Can I instantiate platform devices from userspace? Ah, yes, if `CONFIG_OF_OVERLAY` is enabled, and there’s a userspace interface for Device Tree Overlays (like configfs), then it's possible. Does syzkaller leverage DT overlays for this kind of testing? No, current syzkaller doesn't have that functionality.

Hang on, what about `qcom_scm`? If `qcom_scm_is_available()` returns false, `bam_dmux_alloc_coherent_rx` returns `-EPROBE_DEFER`. Crucial point! If `qcom_scm_is_available()` is false, there's no way to reach that section of the code. Now the question is, can `qcom_scm_is_available()` return true in QEMU? Only if `qcom_scm` probes successfully. Time to check `qcom_scm_probe`.



12/2 2026/07/14 09:38 tool grepper
0m Args:
{
  "Expression": "qcom_scm_probe"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=2559=bool qcom_scm_is_available(void)\ndrivers/firmware/qcom/qcom_scm.c-2560-{\ndrivers/firmware/qcom/qcom_scm.c:2561:\t/* Paired with smp_store_release() in qcom_scm_probe */\ndrivers/firmware/qcom/qcom_scm.c-2562-\treturn !!smp_load_acquire(\u0026__scm);\n--\ndrivers/firmware/qcom/qcom_scm.c=2735=MODULE_PARM_DESC(download_mode, \"download mode: off/0/N for no dump mode, full/on/1/Y for full dump mode, mini for minidump mode and full,mini for both full and m...\ndrivers/firmware/qcom/qcom_scm.c-2736-\ndrivers/firmware/qcom/qcom_scm.c:2737:static int qcom_scm_probe(struct platform_device *pdev)\ndrivers/firmware/qcom/qcom_scm.c-2738-{\n--\ndrivers/firmware/qcom/qcom_scm.c=2895=static struct platform_driver qcom_scm_driver = {\n--\ndrivers/firmware/qcom/qcom_scm.c-2900-\t},\ndrivers/firmware/qcom/qcom_scm.c:2901:\t.probe = qcom_scm_probe,\ndrivers/firmware/qcom/qcom_scm.c-2902-\t.shutdown = qcom_scm_shutdown,\n"
}

13/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14422
							output: 44
							thoughts: 21
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Analyzing `qcom_scm_probe` for Hardware-Independent Operation**

Okay, let's dive into the `qcom_scm_probe` function. The primary question on my mind right now is whether this driver is rigidly tied to specific hardware configurations during its probing phase. My goal is to determine if it can operate in an environment where the complete hardware setup might not be fully present or functional – perhaps in a virtualized or emulated context, or during early bring-up before the full system is validated.

Essentially, I need to understand if the probe function relies on direct hardware interactions or if it implements a more abstract or fallback mechanism that might succeed even without specific hardware detection being flawless. I'll need to dissect its logic, looking for dependencies on registers, memory maps, or device-specific identifiers that would be insurmountable roadblocks in a hardware-deficient scenario. Understanding the error paths and how the driver handles missing or misconfigured hardware will be crucial.



14/2 2026/07/14 09:38 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_scm.c",
  "FirstLine": 2737,
  "LineCount": 100
}

Results:
{
  "Contents": "2737:\tstatic int qcom_scm_probe(struct platform_device *pdev)\n2738:\t{\n2739:\t\tstruct qcom_tzmem_pool_config pool_config;\n2740:\t\tstruct qcom_scm *scm;\n2741:\t\tint irq, ret;\n2742:\t\tint i;\n2743:\t\n2744:\t\tscm = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*scm), GFP_KERNEL);\n2745:\t\tif (!scm)\n2746:\t\t\treturn -ENOMEM;\n2747:\t\n2748:\t\tscm-\u003edev = \u0026pdev-\u003edev;\n2749:\t\tret = qcom_scm_find_dload_address(\u0026pdev-\u003edev, \u0026scm-\u003edload_mode_addr);\n2750:\t\tif (ret \u003c 0)\n2751:\t\t\treturn ret;\n2752:\t\n2753:\t\tmutex_init(\u0026scm-\u003escm_bw_lock);\n2754:\t\n2755:\t\tscm-\u003epath = devm_of_icc_get(\u0026pdev-\u003edev, NULL);\n2756:\t\tif (IS_ERR(scm-\u003epath))\n2757:\t\t\treturn dev_err_probe(\u0026pdev-\u003edev, PTR_ERR(scm-\u003epath),\n2758:\t\t\t\t\t     \"failed to acquire interconnect path\\n\");\n2759:\t\n2760:\t\tscm-\u003ecore_clk = devm_clk_get_optional(\u0026pdev-\u003edev, \"core\");\n2761:\t\tif (IS_ERR(scm-\u003ecore_clk))\n2762:\t\t\treturn PTR_ERR(scm-\u003ecore_clk);\n2763:\t\n2764:\t\tscm-\u003eiface_clk = devm_clk_get_optional(\u0026pdev-\u003edev, \"iface\");\n2765:\t\tif (IS_ERR(scm-\u003eiface_clk))\n2766:\t\t\treturn PTR_ERR(scm-\u003eiface_clk);\n2767:\t\n2768:\t\tscm-\u003ebus_clk = devm_clk_get_optional(\u0026pdev-\u003edev, \"bus\");\n2769:\t\tif (IS_ERR(scm-\u003ebus_clk))\n2770:\t\t\treturn PTR_ERR(scm-\u003ebus_clk);\n2771:\t\n2772:\t\tscm-\u003ereset.ops = \u0026qcom_scm_pas_reset_ops;\n2773:\t\tscm-\u003ereset.nr_resets = 1;\n2774:\t\tscm-\u003ereset.of_node = pdev-\u003edev.of_node;\n2775:\t\tret = devm_reset_controller_register(\u0026pdev-\u003edev, \u0026scm-\u003ereset);\n2776:\t\tif (ret)\n2777:\t\t\treturn ret;\n2778:\t\n2779:\t\t/* vote for max clk rate for highest performance */\n2780:\t\tret = clk_set_rate(scm-\u003ecore_clk, INT_MAX);\n2781:\t\tif (ret)\n2782:\t\t\treturn ret;\n2783:\t\n2784:\t\tret = of_reserved_mem_device_init(scm-\u003edev);\n2785:\t\tif (ret \u0026\u0026 ret != -ENODEV)\n2786:\t\t\treturn dev_err_probe(scm-\u003edev, ret,\n2787:\t\t\t\t\t     \"Failed to setup the reserved memory region for TZ mem\\n\");\n2788:\t\n2789:\t\tret = qcom_tzmem_enable(scm-\u003edev);\n2790:\t\tif (ret)\n2791:\t\t\treturn dev_err_probe(scm-\u003edev, ret,\n2792:\t\t\t\t\t     \"Failed to enable the TrustZone memory allocator\\n\");\n2793:\t\n2794:\t\tmemset(\u0026pool_config, 0, sizeof(pool_config));\n2795:\t\tpool_config.initial_size = 0;\n2796:\t\tpool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;\n2797:\t\tpool_config.max_size = SZ_256K;\n2798:\t\n2799:\t\tscm-\u003emempool = devm_qcom_tzmem_pool_new(scm-\u003edev, \u0026pool_config);\n2800:\t\tif (IS_ERR(scm-\u003emempool))\n2801:\t\t\treturn dev_err_probe(scm-\u003edev, PTR_ERR(scm-\u003emempool),\n2802:\t\t\t\t\t     \"Failed to create the SCM memory pool\\n\");\n2803:\t\n2804:\t\tret = qcom_scm_query_waitq_count(scm);\n2805:\t\tscm-\u003ewq_cnt = ret \u003c 0 ? QCOM_SCM_DEFAULT_WAITQ_COUNT : ret;\n2806:\t\tscm-\u003ewaitq_comps = devm_kcalloc(\u0026pdev-\u003edev, scm-\u003ewq_cnt, sizeof(*scm-\u003ewaitq_comps),\n2807:\t\t\t\t\t\tGFP_KERNEL);\n2808:\t\tif (!scm-\u003ewaitq_comps)\n2809:\t\t\treturn -ENOMEM;\n2810:\t\n2811:\t\tfor (i = 0; i \u003c scm-\u003ewq_cnt; i++)\n2812:\t\t\tinit_completion(\u0026scm-\u003ewaitq_comps[i]);\n2813:\t\n2814:\t\tirq = qcom_scm_get_waitq_irq(scm);\n2815:\t\tif (irq \u003c 0)\n2816:\t\t\tirq = platform_get_irq_optional(pdev, 0);\n2817:\t\n2818:\t\tif (irq \u003c 0) {\n2819:\t\t\tif (irq != -ENXIO)\n2820:\t\t\t\treturn irq;\n2821:\t\t} else {\n2822:\t\t\tret = devm_request_threaded_irq(scm-\u003edev, irq, NULL, qcom_scm_irq_handler,\n2823:\t\t\t\t\t\t\tIRQF_ONESHOT, \"qcom-scm\", scm);\n2824:\t\t\tif (ret \u003c 0)\n2825:\t\t\t\treturn dev_err_probe(scm-\u003edev, ret,\n2826:\t\t\t\t\t\t     \"Failed to request qcom-scm irq\\n\");\n2827:\t\t}\n2828:\t\n2829:\t\t/*\n2830:\t\t * Paired with smp_load_acquire() in qcom_scm_is_available().\n2831:\t\t *\n2832:\t\t * This marks the SCM API as ready to accept user calls and can only\n2833:\t\t * be called after the TrustZone memory pool is initialized and the\n2834:\t\t * waitqueue interrupt requested.\n2835:\t\t */\n2836:\t\tsmp_store_release(\u0026__scm, scm);\n"
}

15/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16455
							output: 20
							thoughts: 106
						

Thoughts:
**Analyzing the Qualcomm Secure Compute Module (SCM) Driver**

Okay, so I'm looking at `qcom_scm` here, and it's pretty clear it's reliant on a few key functions: `qcom_tzmem_enable`, `qcom_scm_query_waitq_count`, and so on. My focus right now is on that `qcom_scm_query_waitq_count` function. Digging a bit deeper, I see it calls `qcom_scm_call`. Ah, that's the core. It's making Secure Monitor Calls (SMCs) directly to TrustZone. Makes sense; that's the expected interface.

However, a red flag is starting to appear. What happens if TrustZone isn't present? Thinking about situations like a QEMU generic virtual machine, where we might not have a hardware-backed TrustZone, `qcom_scm_call` is probably going to either flat-out fail, or worse, crash the whole thing. The SMC calls will hit a dead end, or try to access something that doesn't exist. We need to be able to handle this. So, my next step is clear. Let's dig into `qcom_scm_call` and see exactly what's happening under the hood and how it handles potential errors. Understanding this function is crucial to ensuring stability in environments without a full TrustZone implementation.



16/2 2026/07/14 09:38 tool grepper
0m Args:
{
  "Expression": "qcom_scm_call"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm-legacy.c=110=static void __scm_legacy_do(const struct arm_smccc_args *smc,\n--\ndrivers/firmware/qcom/qcom_scm-legacy.c-128- * Note that any buffers that are expected to be accessed by the secure world\ndrivers/firmware/qcom/qcom_scm-legacy.c:129: * must be flushed before invoking qcom_scm_call and invalidated in the cache\ndrivers/firmware/qcom/qcom_scm-legacy.c:130: * immediately after qcom_scm_call returns. Cache maintenance on the command\ndrivers/firmware/qcom/qcom_scm-legacy.c:131: * and response buffers is taken care of by qcom_scm_call; however, callers are\ndrivers/firmware/qcom/qcom_scm-legacy.c-132- * responsible for any other cached buffers passed over to the secure world.\n--\ndrivers/firmware/qcom/qcom_scm.c=238=static enum qcom_scm_convention __get_convention(void)\n--\ndrivers/firmware/qcom/qcom_scm.c-305-/**\ndrivers/firmware/qcom/qcom_scm.c:306: * qcom_scm_call() - Invoke a syscall in the secure world\ndrivers/firmware/qcom/qcom_scm.c-307- * @dev:\tdevice\n--\ndrivers/firmware/qcom/qcom_scm.c-313- */\ndrivers/firmware/qcom/qcom_scm.c:314:static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc,\ndrivers/firmware/qcom/qcom_scm.c-315-\t\t\t struct qcom_scm_res *res)\n--\ndrivers/firmware/qcom/qcom_scm.c-330-/**\ndrivers/firmware/qcom/qcom_scm.c:331: * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()\ndrivers/firmware/qcom/qcom_scm.c-332- * @dev:\tdevice\n--\ndrivers/firmware/qcom/qcom_scm.c-338- */\ndrivers/firmware/qcom/qcom_scm.c:339:static int qcom_scm_call_atomic(struct device *dev,\ndrivers/firmware/qcom/qcom_scm.c-340-\t\t\t\tconst struct qcom_scm_desc *desc,\n--\ndrivers/firmware/qcom/qcom_scm.c=355=static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id,\n--\ndrivers/firmware/qcom/qcom_scm.c-380-\ndrivers/firmware/qcom/qcom_scm.c:381:\tret = qcom_scm_call(dev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-382-\n--\ndrivers/firmware/qcom/qcom_scm.c=386=static int qcom_scm_set_boot_addr(void *entry, const u8 *cpu_bits)\n--\ndrivers/firmware/qcom/qcom_scm.c-405-\ndrivers/firmware/qcom/qcom_scm.c:406:\treturn qcom_scm_call_atomic(__scm ? __scm-\u003edev : NULL, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-407-}\n--\ndrivers/firmware/qcom/qcom_scm.c=409=static int qcom_scm_set_boot_addr_mc(void *entry, unsigned int flags)\n--\ndrivers/firmware/qcom/qcom_scm.c-427-\ndrivers/firmware/qcom/qcom_scm.c:428:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-429-}\n--\ndrivers/firmware/qcom/qcom_scm.c=468=void qcom_scm_cpu_power_down(u32 flags)\n--\ndrivers/firmware/qcom/qcom_scm.c-477-\ndrivers/firmware/qcom/qcom_scm.c:478:\tqcom_scm_call_atomic(__scm ? __scm-\u003edev : NULL, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-479-}\n--\ndrivers/firmware/qcom/qcom_scm.c=482=int qcom_scm_set_remote_state(u32 state, u32 id)\n--\ndrivers/firmware/qcom/qcom_scm.c-494-\ndrivers/firmware/qcom/qcom_scm.c:495:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-496-\n--\ndrivers/firmware/qcom/qcom_scm.c=501=static int qcom_scm_disable_sdi(void)\n--\ndrivers/firmware/qcom/qcom_scm.c-516-\t\treturn ret;\ndrivers/firmware/qcom/qcom_scm.c:517:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-518-\n--\ndrivers/firmware/qcom/qcom_scm.c=524=static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)\n--\ndrivers/firmware/qcom/qcom_scm.c-535-\ndrivers/firmware/qcom/qcom_scm.c:536:\treturn qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-537-}\n--\ndrivers/firmware/qcom/qcom_scm.c=607=static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys,\n--\ndrivers/firmware/qcom/qcom_scm.c-628-\ndrivers/firmware/qcom/qcom_scm.c:629:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, res);\ndrivers/firmware/qcom/qcom_scm.c-630-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=749=int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)\n--\ndrivers/firmware/qcom/qcom_scm.c-770-\ndrivers/firmware/qcom/qcom_scm.c:771:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-772-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=781=static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm,\n--\ndrivers/firmware/qcom/qcom_scm.c-815-\t */\ndrivers/firmware/qcom/qcom_scm.c:816:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-817-\tif (!ret \u0026\u0026 res.result[2] \u003e SZ_1G) {\n--\ndrivers/firmware/qcom/qcom_scm.c=955=int qcom_scm_pas_auth_and_reset(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-974-\ndrivers/firmware/qcom/qcom_scm.c:975:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-976-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=1038=int qcom_scm_pas_shutdown(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1057-\ndrivers/firmware/qcom/qcom_scm.c:1058:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1059-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=1075=bool qcom_scm_pas_supported(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1090-\ndrivers/firmware/qcom/qcom_scm.c:1091:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1092-\n--\ndrivers/firmware/qcom/qcom_scm.c=1097=static int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)\n--\ndrivers/firmware/qcom/qcom_scm.c-1109-\ndrivers/firmware/qcom/qcom_scm.c:1110:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1111-\n--\ndrivers/firmware/qcom/qcom_scm.c=1138=int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)\n--\ndrivers/firmware/qcom/qcom_scm.c-1150-\ndrivers/firmware/qcom/qcom_scm.c:1151:\tret = qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1152-\tif (ret \u003e= 0)\n--\ndrivers/firmware/qcom/qcom_scm.c=1159=int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)\n--\ndrivers/firmware/qcom/qcom_scm.c-1169-\ndrivers/firmware/qcom/qcom_scm.c:1170:\treturn qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1171-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1187=int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)\n--\ndrivers/firmware/qcom/qcom_scm.c-1199-\ndrivers/firmware/qcom/qcom_scm.c:1200:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1201-\n--\ndrivers/firmware/qcom/qcom_scm.c=1215=int qcom_scm_set_gpu_smmu_aperture(unsigned int context_bank)\n--\ndrivers/firmware/qcom/qcom_scm.c-1227-\ndrivers/firmware/qcom/qcom_scm.c:1228:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1229-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1232=int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1243-\ndrivers/firmware/qcom/qcom_scm.c:1244:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1245-\n--\ndrivers/firmware/qcom/qcom_scm.c=1253=int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)\n--\ndrivers/firmware/qcom/qcom_scm.c-1266-\ndrivers/firmware/qcom/qcom_scm.c:1267:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1268-\n--\ndrivers/firmware/qcom/qcom_scm.c=1277=int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1287-\ndrivers/firmware/qcom/qcom_scm.c:1288:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1289-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1292=int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1309-\ndrivers/firmware/qcom/qcom_scm.c:1310:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1311-\n--\ndrivers/firmware/qcom/qcom_scm.c=1316=static int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,\n--\ndrivers/firmware/qcom/qcom_scm.c-1337-\ndrivers/firmware/qcom/qcom_scm.c:1338:\tret = qcom_scm_call(dev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1339-\n--\ndrivers/firmware/qcom/qcom_scm.c=1445=int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1457-\ndrivers/firmware/qcom/qcom_scm.c:1458:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1459-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1470=int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1480-\ndrivers/firmware/qcom/qcom_scm.c:1481:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1482-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1512=int qcom_scm_ice_invalidate_key(u32 index)\n--\ndrivers/firmware/qcom/qcom_scm.c-1521-\ndrivers/firmware/qcom/qcom_scm.c:1522:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1523-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1547=int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1572-\ndrivers/firmware/qcom/qcom_scm.c:1573:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1574-\n--\ndrivers/firmware/qcom/qcom_scm.c=1610=int qcom_scm_derive_sw_secret(const u8 *eph_key, size_t eph_key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1639-\ndrivers/firmware/qcom/qcom_scm.c:1640:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1641-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1661=int qcom_scm_generate_ice_key(u8 *lt_key, size_t lt_key_size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1679-\ndrivers/firmware/qcom/qcom_scm.c:1680:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1681-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1702=int qcom_scm_prepare_ice_key(const u8 *lt_key, size_t lt_key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1731-\ndrivers/firmware/qcom/qcom_scm.c:1732:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1733-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1755=int qcom_scm_import_ice_key(const u8 *raw_key, size_t raw_key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1784-\ndrivers/firmware/qcom/qcom_scm.c:1785:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1786-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1825=int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)\n--\ndrivers/firmware/qcom/qcom_scm.c-1854-\ndrivers/firmware/qcom/qcom_scm.c:1855:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1856-\t*resp = res.result[0];\n--\ndrivers/firmware/qcom/qcom_scm.c=1864=int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt)\n--\ndrivers/firmware/qcom/qcom_scm.c-1875-\ndrivers/firmware/qcom/qcom_scm.c:1876:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1877-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1880=int qcom_scm_qsmmu500_wait_safe_toggle(bool en)\n--\ndrivers/firmware/qcom/qcom_scm.c-1891-\ndrivers/firmware/qcom/qcom_scm.c:1892:\treturn qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1893-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1908=int qcom_scm_shm_bridge_enable(struct device *scm_dev)\n--\ndrivers/firmware/qcom/qcom_scm.c-1923-\ndrivers/firmware/qcom/qcom_scm.c:1924:\tret = qcom_scm_call(scm_dev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1925-\n--\ndrivers/firmware/qcom/qcom_scm.c=1936=int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,\n--\ndrivers/firmware/qcom/qcom_scm.c-1954-\ndrivers/firmware/qcom/qcom_scm.c:1955:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1956-\n--\ndrivers/firmware/qcom/qcom_scm.c=1964=int qcom_scm_shm_bridge_delete(u64 handle)\n--\ndrivers/firmware/qcom/qcom_scm.c-1973-\ndrivers/firmware/qcom/qcom_scm.c:1974:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1975-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1978=int qcom_scm_lmh_profile_change(u32 profile_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1987-\ndrivers/firmware/qcom/qcom_scm.c:1988:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1989-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1992=int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,\n--\ndrivers/firmware/qcom/qcom_scm.c-2022-\ndrivers/firmware/qcom/qcom_scm.c:2023:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-2024-\n--\ndrivers/firmware/qcom/qcom_scm.c=2029=int qcom_scm_gpu_init_regs(u32 gpu_req)\n--\ndrivers/firmware/qcom/qcom_scm.c-2038-\ndrivers/firmware/qcom/qcom_scm.c:2039:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-2040-}\n--\ndrivers/firmware/qcom/qcom_scm.c=2074=static int __qcom_scm_qseecom_call(const struct qcom_scm_desc *desc,\n--\ndrivers/firmware/qcom/qcom_scm.c-2085-\ndrivers/firmware/qcom/qcom_scm.c:2086:\tstatus = qcom_scm_call(__scm-\u003edev, desc, \u0026scm_res);\ndrivers/firmware/qcom/qcom_scm.c-2087-\n--\ndrivers/firmware/qcom/qcom_scm.c=2404=int qcom_scm_qtee_invoke_smc(phys_addr_t inbuf, size_t inbuf_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-2421-\ndrivers/firmware/qcom/qcom_scm.c:2422:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2423-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=2447=int qcom_scm_qtee_callback_response(phys_addr_t buf, size_t buf_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-2460-\ndrivers/firmware/qcom/qcom_scm.c:2461:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2462-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=2585=static int qcom_scm_query_waitq_count(struct qcom_scm *scm)\n--\ndrivers/firmware/qcom/qcom_scm.c-2594-\ndrivers/firmware/qcom/qcom_scm.c:2595:\tret = qcom_scm_call_atomic(scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2596-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=2602=static int qcom_scm_get_waitq_irq(struct qcom_scm *scm)\n--\ndrivers/firmware/qcom/qcom_scm.c-2614-\ndrivers/firmware/qcom/qcom_scm.c:2615:\tret = qcom_scm_call_atomic(scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2616-\tif (ret)\n"
}

17/2 2026/07/14 09:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23606
							output: 25
							thoughts: 252
						

Thoughts:
**Analyzing the Potential Failure Points in `qcom_scm_probe`**

Okay, let's break this down. My initial thought was that `qcom_scm_probe` is calling `qcom_scm_query_waitq_count`, which in turn leads to `qcom_scm_call_atomic`. And, as an expert, I know that `qcom_scm_call_atomic` is making an SMC call. Now, if we're running this on a generic QEMU arm64 VM, this SMC call is going to get interesting. QEMU might handle it (potentially leading to an error or even a crash), or TF-A might be in control.

My concern was that a failure in this SMC call would trickle up and cause `qcom_scm_probe` to fail. But hold on, I missed something! `qcom_scm_query_waitq_count` returns `ret < 0 ? QCOM_SCM_DEFAULT_WAITQ_COUNT : ret;`. That means if the SMC call fails, it simply uses a default wait queue count. That's a clever fallback!

So, the next line of thought is that it calls `qcom_scm_get_waitq_irq`. If that fails, there's another fallback to `platform_get_irq_optional`. So, actually, `qcom_scm_probe` *might* still succeed even if the underlying SMC calls are failing. That's good to know. It's more resilient than I initially thought.

However, I need to check something now. Wait, before all this `qcom_scm_find_dload_address` is called. Let's see what that is doing.



18/2 2026/07/14 09:39 tool grepper
0m Args:
{
  "Expression": "qcom_scm_find_dload_address"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=2041=EXPORT_SYMBOL_GPL(qcom_scm_gpu_init_regs);\ndrivers/firmware/qcom/qcom_scm.c-2042-\ndrivers/firmware/qcom/qcom_scm.c:2043:static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)\ndrivers/firmware/qcom/qcom_scm.c-2044-{\n--\ndrivers/firmware/qcom/qcom_scm.c=2737=static int qcom_scm_probe(struct platform_device *pdev)\n--\ndrivers/firmware/qcom/qcom_scm.c-2748-\tscm-\u003edev = \u0026pdev-\u003edev;\ndrivers/firmware/qcom/qcom_scm.c:2749:\tret = qcom_scm_find_dload_address(\u0026pdev-\u003edev, \u0026scm-\u003edload_mode_addr);\ndrivers/firmware/qcom/qcom_scm.c-2750-\tif (ret \u003c 0)\n"
}

19/2 2026/07/14 09:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24549
							output: 43
							thoughts: 17
						

Thoughts:
Okay, let's dive into this. Here's my take on those thoughts, as if they're my own:

**Analyzing `qcom_scm_find_dload_address`**

Alright, let's take a look at `qcom_scm_find_dload_address`. I know this is likely a critical function related to the Qualcomm Secure Execution Environment (SEE) and specifically, the process of locating the download address for some component, probably for secure boot or a system update. Given the function name, my immediate expectation is that this involves some interaction with the Secure Configuration Management (SCM) or potentially a similar mechanism to fetch this critical address. It's probably responsible for securely determining where the bootloader or some other critical piece of firmware resides, so that the SEE can subsequently load and execute it. My guess is it involves some hardware-level interactions – reading from protected memory regions, possibly using SCM commands to query secure registers, or maybe even performing a cryptographic verification to validate the address. I'll need to look closely at the surrounding code to understand the context and the specific security mechanisms in play. I'm keen to see if this function uses any standard or custom communication protocols. Specifically, I'm interested in how it interacts with the hardware's internal memory. It's also possible that it incorporates some kind of fallback or error-handling mechanism in case the primary method of address discovery fails, or the location is compromised. Let's see... I'll start by tracing the function's call stack to understand its role in the overall boot sequence.



20/2 2026/07/14 09:39 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_scm.c",
  "FirstLine": 2043,
  "LineCount": 20
}

Results:
{
  "Contents": "2043:\tstatic int qcom_scm_find_dload_address(struct device *dev, u64 *addr)\n2044:\t{\n2045:\t\tstruct device_node *tcsr;\n2046:\t\tstruct device_node *np = dev-\u003eof_node;\n2047:\t\tstruct resource res;\n2048:\t\tu32 offset;\n2049:\t\tint ret;\n2050:\t\n2051:\t\ttcsr = of_parse_phandle(np, \"qcom,dload-mode\", 0);\n2052:\t\tif (!tcsr)\n2053:\t\t\treturn 0;\n2054:\t\n2055:\t\tret = of_address_to_resource(tcsr, 0, \u0026res);\n2056:\t\tof_node_put(tcsr);\n2057:\t\tif (ret)\n2058:\t\t\treturn ret;\n2059:\t\n2060:\t\tret = of_property_read_u32_index(np, \"qcom,dload-mode\", 1, \u0026offset);\n2061:\t\tif (ret \u003c 0)\n2062:\t\t\treturn ret;\n"
}

21/2 2026/07/14 09:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25262
							output: 21
							thoughts: 35
						

Thoughts:
Okay, here's my interpretation of those thoughts, presented as my own mental process, given my expertise:

**Checking Dload Mode and TZMem Enablement**

Alright, so the first thing I'm picking up on is the behavior of this code related to the `qcom,dload-mode` property. I see that if it's *missing*, the function is returning a 0. That's interesting, because a zero return often indicates success in this context. It seems like the absence of this property isn't treated as an error condition, which is something I'll need to remember for further analysis. This likely means some default behavior is employed when the dload mode configuration is not provided.

Now, my mind immediately jumps to `qcom_tzmem_enable`. I'm wondering how this relates to the `dload-mode` scenario. Is `tzmem_enable` also handled in a way that doesn't necessarily indicate failure if the configuration is absent? Does the presence or absence of one property affect the other? I need to understand if these two mechanisms are linked or independent. Knowing how the Trusted Execution Environment (TEE) memory enablement interacts with dload mode will be crucial for understanding the overall system behavior, and potential vulnerabilities. I need to dig deeper into the code to determine the relationship.



22/2 2026/07/14 09:39 tool grepper
0m Args:
{
  "Expression": "qcom_tzmem_enable"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=2737=static int qcom_scm_probe(struct platform_device *pdev)\n--\ndrivers/firmware/qcom/qcom_scm.c-2788-\ndrivers/firmware/qcom/qcom_scm.c:2789:\tret = qcom_tzmem_enable(scm-\u003edev);\ndrivers/firmware/qcom/qcom_scm.c-2790-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_tzmem.c=508=EXPORT_SYMBOL_GPL(qcom_tzmem_to_phys);\ndrivers/firmware/qcom/qcom_tzmem.c-509-\ndrivers/firmware/qcom/qcom_tzmem.c:510:int qcom_tzmem_enable(struct device *dev)\ndrivers/firmware/qcom/qcom_tzmem.c-511-{\n--\ndrivers/firmware/qcom/qcom_tzmem.c-518-}\ndrivers/firmware/qcom/qcom_tzmem.c:519:EXPORT_SYMBOL_GPL(qcom_tzmem_enable);\ndrivers/firmware/qcom/qcom_tzmem.c-520-\n--\ndrivers/firmware/qcom/qcom_tzmem.h=9=struct device;\ndrivers/firmware/qcom/qcom_tzmem.h-10-\ndrivers/firmware/qcom/qcom_tzmem.h:11:int qcom_tzmem_enable(struct device *dev);\ndrivers/firmware/qcom/qcom_tzmem.h-12-\n"
}

23/2 2026/07/14 09:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26025
							output: 43
							thoughts: 13
						

Thoughts:
Okay, let's dive into this. Here's my take on `qcom_tzmem_enable`:

**Deep Dive into `qcom_tzmem_enable`**

Alright, I'm going to get my hands dirty and start dissecting `qcom_tzmem_enable`. The name itself immediately suggests we're dealing with enabling something related to TrustZone memory. Given my background, I can already anticipate some of the potential challenges and considerations. We're likely talking about:

*   **Secure Memory Allocation:** This function probably orchestrates the allocation and configuration of memory regions that are accessible only to the TrustZone (or Secure World). It would be used to store secrets, keys, or security-sensitive data.
*   **Permissions and Access Control:** I bet this function deals with setting up the necessary Memory Management Unit (MMU) mappings, and access control registers to ensure that only authorized code (running within the Secure World) can read from or write to the allocated memory.
*   **Potential for Race Conditions:** Enabling and configuring secure memory regions is a classic place to look for race conditions between the Normal World (e.g., the main OS) and the Secure World. Concurrent access might need to be handled carefully.
*   **Integration with the TrustZone Architecture:** It's almost guaranteed to interact with Qualcomm's specific TrustZone implementation. I'll be looking for references to their secure OS or TrustZone drivers and APIs. I will investigate how it fits into the broader boot and secure execution flow.
*   **Error Handling and Security:** Good error handling is critical here. Any failures in secure memory allocation or configuration could create significant security vulnerabilities. I'll need to pay close attention to the error codes and any potential attack vectors.
*   **Possible Interactions:** How this function interacts with the device's boot process and other security features (like secure boot) is of great interest.

I'm ready to dive into the code and see if my assumptions hold true. I'll be focused on how this function ensures the integrity and confidentiality of secure memory regions within the target system. Time to get started!



24/2 2026/07/14 09:39 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_tzmem.c",
  "FirstLine": 510,
  "LineCount": 10
}

Results:
{
  "Contents": " 510:\tint qcom_tzmem_enable(struct device *dev)\n 511:\t{\n 512:\t\tif (qcom_tzmem_dev)\n 513:\t\t\treturn -EBUSY;\n 514:\t\n 515:\t\tqcom_tzmem_dev = dev;\n 516:\t\n 517:\t\treturn qcom_tzmem_init();\n 518:\t}\n 519:\tEXPORT_SYMBOL_GPL(qcom_tzmem_enable);\n"
}

25/2 2026/07/14 09:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26677
							output: 21
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:

**Investigating Memory Initialization within the Qualcomm TrustZone**

Right, so we're looking at memory initialization in the Qualcomm TrustZone. The standard initialization routines are, of course, familiar, but I'm thinking beyond the basics. Where do we begin when digging into a specific vendor's implementation of the Trusted Execution Environment (TEE)?

The question that is top of mind is how `qcom_tzmem_init` is implemented? I am specifically interested in how memory regions are allocated and configured within the context of the TrustZone. Are we dealing with static allocations, dynamic allocations, or some hybrid approach? What kind of memory attributes (e.g., Secure, Non-Secure, Cacheability) are being set? Understanding how this function orchestrates the initial setup is critical to mapping how the TZ is structured. What assumptions is the vendor making about the underlying hardware and boot process? This is definitely the function to delve into.



26/2 2026/07/14 09:39 tool grepper
0m Args:
{
  "Expression": "qcom_tzmem_init"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_tzmem.c=50=static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);\n--\ndrivers/firmware/qcom/qcom_tzmem.c-53-\ndrivers/firmware/qcom/qcom_tzmem.c:54:static int qcom_tzmem_init(void)\ndrivers/firmware/qcom/qcom_tzmem.c-55-{\n--\ndrivers/firmware/qcom/qcom_tzmem.c-58-\ndrivers/firmware/qcom/qcom_tzmem.c:59:static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)\ndrivers/firmware/qcom/qcom_tzmem.c-60-{\n--\ndrivers/firmware/qcom/qcom_tzmem.c=79=static const char *const qcom_tzmem_blacklist[] = {\n--\ndrivers/firmware/qcom/qcom_tzmem.c-88-\ndrivers/firmware/qcom/qcom_tzmem.c:89:static int qcom_tzmem_init(void)\ndrivers/firmware/qcom/qcom_tzmem.c-90-{\n--\ndrivers/firmware/qcom/qcom_tzmem.c=165=EXPORT_SYMBOL_GPL(qcom_tzmem_shm_bridge_delete);\ndrivers/firmware/qcom/qcom_tzmem.c-166-\ndrivers/firmware/qcom/qcom_tzmem.c:167:static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)\ndrivers/firmware/qcom/qcom_tzmem.c-168-{\n--\ndrivers/firmware/qcom/qcom_tzmem.c=194=static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,\n--\ndrivers/firmware/qcom/qcom_tzmem.c-210-\ndrivers/firmware/qcom/qcom_tzmem.c:211:\tret = qcom_tzmem_init_area(area);\ndrivers/firmware/qcom/qcom_tzmem.c-212-\tif (ret) {\n--\ndrivers/firmware/qcom/qcom_tzmem.c=510=int qcom_tzmem_enable(struct device *dev)\n--\ndrivers/firmware/qcom/qcom_tzmem.c-516-\ndrivers/firmware/qcom/qcom_tzmem.c:517:\treturn qcom_tzmem_init();\ndrivers/firmware/qcom/qcom_tzmem.c-518-}\n"
}

27/2 2026/07/14 09:39 llm patch-evaluator
5m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27626
							output: 42
							thoughts: 19
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into qcom_tzmem_init**

Okay, time to get my hands dirty. Let's zero in on `qcom_tzmem_init`, specifically around line 89. I need to refresh my understanding of how TrustZone memory is initialized on this Qualcomm platform. This function is the likely entry point, the starting point for memory region setup. I'm expecting to see calls to register memory regions, perhaps some security context initialization, and potentially some device-specific hardware setup for memory protection. I'm hoping to quickly identify the crucial sequence of operations performed, so I can understand the bigger picture of memory management. Let's see what secrets it holds.



28/2 2026/07/14 09:45 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_tzmem.c",
  "FirstLine": 89,
  "LineCount": 20
}

Results:
{
  "Contents": "  89:\tstatic int qcom_tzmem_init(void)\n  90:\t{\n  91:\t\tconst char *const *platform;\n  92:\t\tint ret;\n  93:\t\n  94:\t\tfor (platform = qcom_tzmem_blacklist; *platform; platform++) {\n  95:\t\t\tif (of_machine_is_compatible(*platform))\n  96:\t\t\t\tgoto notsupp;\n  97:\t\t}\n  98:\t\n  99:\t\tret = qcom_scm_shm_bridge_enable(qcom_tzmem_dev);\n 100:\t\tif (ret == -EOPNOTSUPP)\n 101:\t\t\tgoto notsupp;\n 102:\t\n 103:\t\tif (!ret)\n 104:\t\t\tqcom_tzmem_using_shm_bridge = true;\n 105:\t\n 106:\t\treturn ret;\n 107:\t\n 108:\tnotsupp:\n"
}

29/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28111
							output: 25
							thoughts: 97
						

Thoughts:
**Analyzing the Secure Memory Bridge Enablement**

Okay, so I'm looking at this `qcom_scm_shm_bridge_enable` function, and it's calling `qcom_scm_call`.  That's the standard secure call mechanism, which is expected.  But here's a crucial point: If `qcom_scm_call` returns `-EOPNOTSUPP`, meaning the SMC (Secure Monitor Call) isn't supported, the code *doesn't* fail immediately. It jumps to `notsupp` and just returns 0.

That's an important detail. It means the initialization of the trusted zone memory, presumably handled by `qcom_tzmem_init`, can potentially *succeed* even when the underlying secure calls are not operational. This is by design, of course!

But... I need to clarify something in my head. What precisely *does* `qcom_scm_shm_bridge_enable` return in the specific scenario where there is *no* SMC support? A return of 0 from `qcom_scm_shm_bridge_enable` might appear as a success, however, that might be misleading if the underlying SMC functionality is not available. I need to understand that edge case better. I need to make sure I fully understand the ramifications of that return value. This detail could impact how the system handles secure memory in the absence of a proper SMC infrastructure, and that's something that requires rigorous scrutiny. I need to make sure that the system reports its actual configuration so that I am able to correctly interpret its runtime behaviour.



30/2 2026/07/14 09:45 tool grepper
0m Args:
{
  "Expression": "qcom_scm_shm_bridge_enable"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=1900=EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);\n--\ndrivers/firmware/qcom/qcom_scm.c-1907- */\ndrivers/firmware/qcom/qcom_scm.c:1908:int qcom_scm_shm_bridge_enable(struct device *scm_dev)\ndrivers/firmware/qcom/qcom_scm.c-1909-{\n--\ndrivers/firmware/qcom/qcom_scm.c-1933-}\ndrivers/firmware/qcom/qcom_scm.c:1934:EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);\ndrivers/firmware/qcom/qcom_scm.c-1935-\n--\ndrivers/firmware/qcom/qcom_scm.h=85=struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);\ndrivers/firmware/qcom/qcom_scm.h:86:int qcom_scm_shm_bridge_enable(struct device *scm_dev);\ndrivers/firmware/qcom/qcom_scm.h-87-\n--\ndrivers/firmware/qcom/qcom_tzmem.c=89=static int qcom_tzmem_init(void)\n--\ndrivers/firmware/qcom/qcom_tzmem.c-98-\ndrivers/firmware/qcom/qcom_tzmem.c:99:\tret = qcom_scm_shm_bridge_enable(qcom_tzmem_dev);\ndrivers/firmware/qcom/qcom_tzmem.c-100-\tif (ret == -EOPNOTSUPP)\n"
}

31/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 29031
							output: 43
							thoughts: 17
						

Thoughts:
Okay, here's my interpretation of what's going through my mind as I approach this function, assuming I'm already well-versed in system-on-chip (SoC) architecture, shared memory, and Qualcomm's SCM (Secure Command Manager) context.

**Deconstructing `qcom_scm_shm_bridge_enable`**

Alright, let's dive into `qcom_scm_shm_bridge_enable`. Given the name, I immediately anticipate this function is responsible for enabling a bridge – likely a hardware bridge – that facilitates communication between the Qualcomm SCM and Shared Memory. The term "bridge" is key here. It implies a specific hardware construct designed for secure communication, given the SCM's role.

My initial questions are:

*   **What type of Shared Memory are we talking about?** Is this a dedicated physical region, a virtual memory region mapped into multiple contexts, or something more complex? The specific shared memory type will heavily influence the function's internal mechanisms.
*   **What are the security implications?** The SCM is almost certainly involved because we're crossing security domains. This is likely about controlling access, mediating communication, and enforcing security policies. How are the security attributes handled within the memory shared in this scenario? Are there specific access controls in place? What security contexts are involved? Are we talking about TrustZone, secure boot, or other security features?
*   **What's the hardware context?** I'm curious about the specific SoC architecture and the hardware blocks involved. Does this rely on a specific interconnect, a hardware memory controller feature, or something custom? Is there a designated hardware bridge, and if so, what's its role?
*   **What's the enabling procedure?** What steps are necessary? Is this a simple register write, a sequence of operations, or a complex initialization process? Does it involve enabling interrupts, configuring address mapping, or setting up memory protection units (MPUs)?
*   **Error handling?** Given the security aspects, I expect robust error handling. Are there checks for invalid parameters, security violations, or hardware failures? What are the failure modes, and how are they handled? Is this interrupt-driven or polled? What are the failure modes and recovery procedures?
*   **Which contexts does this involve?** Is this running within the TrustZone, or in the normal world? Does this operate from both? Does this impact other system drivers or services?
*   **What is the boot-up sequence?** Does this happen early in the boot-up, or later? How does this interact with other initialization procedures?

I'll be looking for clues in the code itself, starting with the function's arguments, internal data structures, and the sequence of operations. I'll be expecting to see a combination of hardware access, security checks, and memory management routines. Ultimately, I'm expecting this will lay the foundation for secure communication across a shared memory interface on a Qualcomm SoC. Let's dig in.



32/2 2026/07/14 09:45 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_scm.c",
  "FirstLine": 1908,
  "LineCount": 20
}

Results:
{
  "Contents": "1908:\tint qcom_scm_shm_bridge_enable(struct device *scm_dev)\n1909:\t{\n1910:\t\tint ret;\n1911:\t\n1912:\t\tstruct qcom_scm_desc desc = {\n1913:\t\t\t.svc = QCOM_SCM_SVC_MP,\n1914:\t\t\t.cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE,\n1915:\t\t\t.owner = ARM_SMCCC_OWNER_SIP\n1916:\t\t};\n1917:\t\n1918:\t\tstruct qcom_scm_res res;\n1919:\t\n1920:\t\tif (!__qcom_scm_is_call_available(scm_dev, QCOM_SCM_SVC_MP,\n1921:\t\t\t\t\t\t  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))\n1922:\t\t\treturn -EOPNOTSUPP;\n1923:\t\n1924:\t\tret = qcom_scm_call(scm_dev, \u0026desc, \u0026res);\n1925:\t\n1926:\t\tif (ret)\n1927:\t\t\treturn ret;\n"
}

33/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 30044
							output: 25
							thoughts: 44
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating a System Call Availability Issue**

Alright, so I'm looking at a situation where a function, specifically `__qcom_scm_is_call_available`, seems to be returning `-EOPNOTSUPP`. That's a clear signal that the underlying secure call, or at least the mechanism to check it, isn't supported in the current configuration. My immediate thought is, let's drill down into that `__qcom_scm_is_call_available` function itself. It's the key to understanding *why* we're hitting this "operation not supported" error. I need to understand its logic, the checks it performs, and what conditions are causing it to return false. Is it a hardware capability issue? A missing driver? Configuration flags? The code itself should provide the answers, so let's start there. This is likely the root cause of the problem.



34/2 2026/07/14 09:45 tool grepper
0m Args:
{
  "Expression": "__qcom_scm_is_call_available"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=339=static int qcom_scm_call_atomic(struct device *dev,\n--\ndrivers/firmware/qcom/qcom_scm.c-354-\ndrivers/firmware/qcom/qcom_scm.c:355:static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id,\ndrivers/firmware/qcom/qcom_scm.c-356-\t\t\t\t\t u32 cmd_id)\n--\ndrivers/firmware/qcom/qcom_scm.c=554=static void qcom_scm_set_download_mode(u32 dload_mode)\n--\ndrivers/firmware/qcom/qcom_scm.c-560-\t\t\t\t      FIELD_PREP(QCOM_DLOAD_MASK, dload_mode));\ndrivers/firmware/qcom/qcom_scm.c:561:\t} else if (__qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_BOOT,\ndrivers/firmware/qcom/qcom_scm.c-562-\t\t\t\t\t\tQCOM_SCM_BOOT_SET_DLOAD_MODE)) {\n--\ndrivers/firmware/qcom/qcom_scm.c=1075=bool qcom_scm_pas_supported(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1086-\ndrivers/firmware/qcom/qcom_scm.c:1087:\tif (!__qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_PIL,\ndrivers/firmware/qcom/qcom_scm.c-1088-\t\t\t\t\t  QCOM_SCM_PIL_PAS_IS_SUPPORTED))\n--\ndrivers/firmware/qcom/qcom_scm.c=1180=bool qcom_scm_restore_sec_cfg_available(void)\ndrivers/firmware/qcom/qcom_scm.c-1181-{\ndrivers/firmware/qcom/qcom_scm.c:1182:\treturn __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_MP,\ndrivers/firmware/qcom/qcom_scm.c-1183-\t\t\t\t\t    QCOM_SCM_MP_RESTORE_SEC_CFG);\n--\ndrivers/firmware/qcom/qcom_scm.c=1208=bool qcom_scm_set_gpu_smmu_aperture_is_available(void)\ndrivers/firmware/qcom/qcom_scm.c-1209-{\ndrivers/firmware/qcom/qcom_scm.c:1210:\treturn __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_MP,\ndrivers/firmware/qcom/qcom_scm.c-1211-\t\t\t\t\t    QCOM_SCM_MP_CP_SMMU_APERTURE_ID);\n--\ndrivers/firmware/qcom/qcom_scm.c=1429=bool qcom_scm_ocmem_lock_available(void)\ndrivers/firmware/qcom/qcom_scm.c-1430-{\ndrivers/firmware/qcom/qcom_scm.c:1431:\treturn __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_OCMEM,\ndrivers/firmware/qcom/qcom_scm.c-1432-\t\t\t\t\t    QCOM_SCM_OCMEM_LOCK_CMD);\n--\ndrivers/firmware/qcom/qcom_scm.c=1491=bool qcom_scm_ice_available(void)\ndrivers/firmware/qcom/qcom_scm.c-1492-{\ndrivers/firmware/qcom/qcom_scm.c:1493:\treturn __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_ES,\ndrivers/firmware/qcom/qcom_scm.c-1494-\t\t\t\t\t    QCOM_SCM_ES_INVALIDATE_ICE_KEY) \u0026\u0026\ndrivers/firmware/qcom/qcom_scm.c:1495:\t\t__qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_ES,\ndrivers/firmware/qcom/qcom_scm.c-1496-\t\t\t\t\t     QCOM_SCM_ES_CONFIG_SET_ICE_KEY);\n--\ndrivers/firmware/qcom/qcom_scm.c=1581=bool qcom_scm_has_wrapped_key_support(void)\ndrivers/firmware/qcom/qcom_scm.c-1582-{\ndrivers/firmware/qcom/qcom_scm.c:1583:\treturn __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_ES,\ndrivers/firmware/qcom/qcom_scm.c-1584-\t\t\t\t\t    QCOM_SCM_ES_DERIVE_SW_SECRET) \u0026\u0026\ndrivers/firmware/qcom/qcom_scm.c:1585:\t       __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_ES,\ndrivers/firmware/qcom/qcom_scm.c-1586-\t\t\t\t\t    QCOM_SCM_ES_GENERATE_ICE_KEY) \u0026\u0026\ndrivers/firmware/qcom/qcom_scm.c:1587:\t       __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_ES,\ndrivers/firmware/qcom/qcom_scm.c-1588-\t\t\t\t\t    QCOM_SCM_ES_PREPARE_ICE_KEY) \u0026\u0026\ndrivers/firmware/qcom/qcom_scm.c:1589:\t       __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_ES,\ndrivers/firmware/qcom/qcom_scm.c-1590-\t\t\t\t\t    QCOM_SCM_ES_IMPORT_ICE_KEY);\n--\ndrivers/firmware/qcom/qcom_scm.c=1800=bool qcom_scm_hdcp_available(void)\n--\ndrivers/firmware/qcom/qcom_scm.c-1807-\ndrivers/firmware/qcom/qcom_scm.c:1808:\tavail = __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_HDCP,\ndrivers/firmware/qcom/qcom_scm.c-1809-\t\t\t\t\t\tQCOM_SCM_HDCP_INVOKE);\n--\ndrivers/firmware/qcom/qcom_scm.c=1896=bool qcom_scm_lmh_dcvsh_available(void)\ndrivers/firmware/qcom/qcom_scm.c-1897-{\ndrivers/firmware/qcom/qcom_scm.c:1898:\treturn __qcom_scm_is_call_available(__scm-\u003edev, QCOM_SCM_SVC_LMH, QCOM_SCM_LMH_LIMIT_DCVSH);\ndrivers/firmware/qcom/qcom_scm.c-1899-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1908=int qcom_scm_shm_bridge_enable(struct device *scm_dev)\n--\ndrivers/firmware/qcom/qcom_scm.c-1919-\ndrivers/firmware/qcom/qcom_scm.c:1920:\tif (!__qcom_scm_is_call_available(scm_dev, QCOM_SCM_SVC_MP,\ndrivers/firmware/qcom/qcom_scm.c-1921-\t\t\t\t\t  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))\n"
}

35/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 32331
							output: 42
							thoughts: 17
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm deep in the weeds of Qualcomm SCM:

**Analyzing `__qcom_scm_is_call_available`**

Right, let's dive into this function. `__qcom_scm_is_call_available`. Immediately, I see it's a critical piece of the SCM (Secure Configuration Module) puzzle. I need to understand its role in determining whether a secure call, likely to the TrustZone or a similar secure environment, can be made. This usually involves checking for a variety of conditions, things like:

*   **Security Context:** Am I, the caller, running in a context where secure calls are even *allowed*? Are the necessary permissions, capabilities, or configurations set?
*   **SCM State:** Is the SCM itself initialized and functioning correctly? Are there any global errors, shutdowns, or states that would prevent a secure call?
*   **Call ID Validity:** Is the specific call ID passed to the function, for instance, `SCM_CALL_SOME_TRUSTZONE_FUNCTION_X`, actually a *valid* one for this system? Is it supported by the installed TrustZone image?
*   **Resource Availability:** Are the resources needed for this specific secure call, things like memory buffers, secure interrupts, and other necessary bits, actually available and in a usable state?
*   **Platform-Specific Constraints:** This is always a big one. Does the underlying hardware platform have any unique limitations or quirks that would make this call unavailable? Power state, clock gating, and hardware revision could all impact the outcome here.

My goal is to thoroughly understand how this function actually makes its decision. I'll need to examine the source code closely, paying attention to any dependencies on other SCM modules, hardware abstraction layers, or platform-specific drivers. It's a key function and critical to the overall security posture and function of the system.



36/2 2026/07/14 09:45 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_scm.c",
  "FirstLine": 355,
  "LineCount": 20
}

Results:
{
  "Contents": " 355:\tstatic bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id,\n 356:\t\t\t\t\t\t u32 cmd_id)\n 357:\t{\n 358:\t\tint ret;\n 359:\t\tstruct qcom_scm_desc desc = {\n 360:\t\t\t.svc = QCOM_SCM_SVC_INFO,\n 361:\t\t\t.cmd = QCOM_SCM_INFO_IS_CALL_AVAIL,\n 362:\t\t\t.owner = ARM_SMCCC_OWNER_SIP,\n 363:\t\t};\n 364:\t\tstruct qcom_scm_res res;\n 365:\t\n 366:\t\tdesc.arginfo = QCOM_SCM_ARGS(1);\n 367:\t\tswitch (__get_convention()) {\n 368:\t\tcase SMC_CONVENTION_ARM_32:\n 369:\t\tcase SMC_CONVENTION_ARM_64:\n 370:\t\t\tdesc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) |\n 371:\t\t\t\t\t(ARM_SMCCC_OWNER_SIP \u003c\u003c ARM_SMCCC_OWNER_SHIFT);\n 372:\t\t\tbreak;\n 373:\t\tcase SMC_CONVENTION_LEGACY:\n 374:\t\t\tdesc.args[0] = SCM_LEGACY_FNID(svc_id, cmd_id);\n"
}

37/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 33180
							output: 22
							thoughts: 383
						

Thoughts:
**My Analysis of the Initialization Flow**

Okay, let me break this down. It starts with a call to `qcom_scm_call`. If *that* fails, we're looking at a return of `false`, which then causes `qcom_scm_shm_bridge_enable` to cough up an `-EOPNOTSUPP` error. However, `qcom_tzmem_init` somehow *still* manages to return 0, and that cascades into `qcom_tzmem_enable` also returning 0. That’s already a bit odd, but let's keep going.

Now, `qcom_scm_probe` kicks in and ventures into `qcom_scm_query_waitq_count`. This is where it calls `qcom_scm_call_atomic`, and if *that* fails, it resorts to the `QCOM_SCM_DEFAULT_WAITQ_COUNT`, which is 1. Fine, makes sense as a fallback.  Then, it allocates `waitq_comps`.

Next, we see `qcom_scm_get_waitq_irq` being called, which, *again*, calls `qcom_scm_call_atomic`. If *that* bombs, it returns the error code. Now, the `irq` value becomes negative. Here's where it gets interesting: it falls back to using `platform_get_irq_optional(pdev, 0)`. If *that* doesn't find an IRQ, it'll return `-ENXIO`.

The key here is the following conditional: `if (irq < 0) { if (irq != -ENXIO) return irq; }`.  Essentially, if the IRQ is *negative* but NOT `-ENXIO`, it returns. However, if the IRQ is `-ENXIO`, *it continues!*  That’s the crucial observation.

Because if the IRQ is `-ENXIO`, it then sets `smp_store_release(&__scm, scm);` and returns 0! This is the surprising part: `qcom_scm_probe` can, and *will*, succeed even if there is absolutely *no* SMC support! This directly implies that `qcom_scm_is_available()` is going to return `true` even when it shouldn’t.

Finally, `bam_dmux_alloc_coherent_rx` is called. It will call `qcom_scm_assign_mem`.

So, the critical takeaway is that the probe's success is decoupled from the actual availability of SMC functionality, which has implications that I need to investigate in `bam_dmux_alloc_coherent_rx` and `qcom_scm_assign_mem`, as they will likely be operating under a false assumption.



38/2 2026/07/14 09:45 tool grepper
0m Args:
{
  "Expression": "qcom_scm_assign_mem"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm.c=1314=EXPORT_SYMBOL_GPL(qcom_scm_mem_protect_video_var);\ndrivers/firmware/qcom/qcom_scm.c-1315-\ndrivers/firmware/qcom/qcom_scm.c:1316:static int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,\ndrivers/firmware/qcom/qcom_scm.c-1317-\t\t\t\t size_t mem_sz, phys_addr_t src, size_t src_sz,\n--\ndrivers/firmware/qcom/qcom_scm.c-1343-/**\ndrivers/firmware/qcom/qcom_scm.c:1344: * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership\ndrivers/firmware/qcom/qcom_scm.c-1345- * @mem_addr: mem region whose ownership need to be reassigned\n--\ndrivers/firmware/qcom/qcom_scm.c-1354- */\ndrivers/firmware/qcom/qcom_scm.c:1355:int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,\ndrivers/firmware/qcom/qcom_scm.c-1356-\t\t\tu64 *srcvm,\n--\ndrivers/firmware/qcom/qcom_scm.c-1412-\ndrivers/firmware/qcom/qcom_scm.c:1413:\tret = __qcom_scm_assign_mem(__scm-\u003edev, mem_to_map_phys, mem_to_map_sz,\ndrivers/firmware/qcom/qcom_scm.c-1414-\t\t\t\t    ptr_phys, src_sz, dest_phys, dest_sz);\n--\ndrivers/firmware/qcom/qcom_scm.c-1423-}\ndrivers/firmware/qcom/qcom_scm.c:1424:EXPORT_SYMBOL_GPL(qcom_scm_assign_mem);\ndrivers/firmware/qcom/qcom_scm.c-1425-\n--\ndrivers/misc/fastrpc.c=335=static void fastrpc_free_map(struct kref *ref)\n--\ndrivers/misc/fastrpc.c-349-\t\t\tperm.perm = QCOM_SCM_PERM_RWX;\ndrivers/misc/fastrpc.c:350:\t\t\terr = qcom_scm_assign_mem(map-\u003edma_addr, map-\u003elen,\ndrivers/misc/fastrpc.c-351-\t\t\t\t\u0026src_perms, \u0026perm, 1);\n--\ndrivers/misc/fastrpc.c=834=static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,\n--\ndrivers/misc/fastrpc.c-900-\t\tmap-\u003eattr = attr;\ndrivers/misc/fastrpc.c:901:\t\terr = qcom_scm_assign_mem(map-\u003edma_addr, (u64)map-\u003elen, \u0026src_perms, dst_perms, 2);\ndrivers/misc/fastrpc.c-902-\t\tif (err) {\n--\ndrivers/misc/fastrpc.c=1338=static int fastrpc_init_create_static_process(struct fastrpc_user *fl,\n--\ndrivers/misc/fastrpc.c-1383-\ndrivers/misc/fastrpc.c:1384:\t\t\terr = qcom_scm_assign_mem(fl-\u003ecctx-\u003eremote_heap-\u003edma_addr,\ndrivers/misc/fastrpc.c-1385-\t\t\t\t\t\t\t(u64)fl-\u003ecctx-\u003eremote_heap-\u003esize,\n--\ndrivers/misc/fastrpc.c-1440-\t\tdst_perms.perm = QCOM_SCM_PERM_RWX;\ndrivers/misc/fastrpc.c:1441:\t\terr = qcom_scm_assign_mem(fl-\u003ecctx-\u003eremote_heap-\u003edma_addr,\ndrivers/misc/fastrpc.c-1442-\t\t\t\t\t\t(u64)fl-\u003ecctx-\u003eremote_heap-\u003esize,\n--\ndrivers/misc/fastrpc.c=1930=static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)\n--\ndrivers/misc/fastrpc.c-2001-\ndrivers/misc/fastrpc.c:2002:\t\terr = qcom_scm_assign_mem(buf-\u003edma_addr, (u64)buf-\u003esize,\ndrivers/misc/fastrpc.c-2003-\t\t\t\u0026src_perms, fl-\u003ecctx-\u003evmperms, fl-\u003ecctx-\u003evmcount);\n--\ndrivers/misc/fastrpc.c=2364=static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)\n--\ndrivers/misc/fastrpc.c-2418-\ndrivers/misc/fastrpc.c:2419:\t\t\terr = qcom_scm_assign_mem(res.start, resource_size(\u0026res), \u0026src_perms,\ndrivers/misc/fastrpc.c-2420-\t\t\t\t    data-\u003evmperms, data-\u003evmcount);\n--\ndrivers/net/wireless/ath/ath10k/qmi.c=32=static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi,\n--\ndrivers/net/wireless/ath/ath10k/qmi.c-55-\ndrivers/net/wireless/ath/ath10k/qmi.c:56:\tret = qcom_scm_assign_mem(mem_info-\u003eaddr, mem_info-\u003esize,\ndrivers/net/wireless/ath/ath10k/qmi.c-57-\t\t\t\t  \u0026src_perms, dst_perms, perm_count);\n--\ndrivers/net/wireless/ath/ath10k/qmi.c=64=static int ath10k_qmi_unmap_msa_permission(struct ath10k_qmi *qmi,\n--\ndrivers/net/wireless/ath/ath10k/qmi.c-79-\ndrivers/net/wireless/ath/ath10k/qmi.c:80:\tret = qcom_scm_assign_mem(mem_info-\u003eaddr, mem_info-\u003esize,\ndrivers/net/wireless/ath/ath10k/qmi.c-81-\t\t\t\t  \u0026src_perms, \u0026dst_perms, 1);\n--\ndrivers/net/wwan/qcom_bam_dmux.c=803=static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-831-\ndrivers/net/wwan/qcom_bam_dmux.c:832:\tret = qcom_scm_assign_mem(dmux-\u003erx_buf_dma, size, \u0026src, dst, ARRAY_SIZE(dst));\ndrivers/net/wwan/qcom_bam_dmux.c-833-\tif (ret) {\n--\ndrivers/net/wwan/qcom_bam_dmux.c=844=static void bam_dmux_free_coherent_rx(struct bam_dmux *dmux)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-855-\tif (dmux-\u003erx_buf_perms) {\ndrivers/net/wwan/qcom_bam_dmux.c:856:\t\tif (qcom_scm_assign_mem(dmux-\u003erx_buf_dma, size, \u0026dmux-\u003erx_buf_perms,\ndrivers/net/wwan/qcom_bam_dmux.c-857-\t\t\t\t\t\u0026hlos, 1)) {\n--\ndrivers/remoteproc/qcom_q6v5_mss.c=463=static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, u64 *current_perm,\n--\ndrivers/remoteproc/qcom_q6v5_mss.c-488-\ndrivers/remoteproc/qcom_q6v5_mss.c:489:\treturn qcom_scm_assign_mem(addr, ALIGN(size, SZ_4K),\ndrivers/remoteproc/qcom_q6v5_mss.c-490-\t\t\t\t   current_perm, next, perms);\n--\ndrivers/remoteproc/qcom_q6v5_pas.c=660=static int qcom_pas_assign_memory_region(struct qcom_pas *pas)\n--\ndrivers/remoteproc/qcom_q6v5_pas.c-697-\ndrivers/remoteproc/qcom_q6v5_pas.c:698:\t\tret = qcom_scm_assign_mem(pas-\u003eregion_assign_phys[offset],\ndrivers/remoteproc/qcom_q6v5_pas.c-699-\t\t\t\t\t  pas-\u003eregion_assign_size[offset],\n--\ndrivers/remoteproc/qcom_q6v5_pas.c=711=static void qcom_pas_unassign_memory_region(struct qcom_pas *pas)\n--\ndrivers/remoteproc/qcom_q6v5_pas.c-723-\ndrivers/remoteproc/qcom_q6v5_pas.c:724:\t\tret = qcom_scm_assign_mem(pas-\u003eregion_assign_phys[offset],\ndrivers/remoteproc/qcom_q6v5_pas.c-725-\t\t\t\t\t  pas-\u003eregion_assign_size[offset],\n--\ndrivers/soc/qcom/rmtfs_mem.c=171=static int qcom_rmtfs_mem_probe(struct platform_device *pdev)\n--\ndrivers/soc/qcom/rmtfs_mem.c-272-\t\trmtfs_mem-\u003eperms = BIT(QCOM_SCM_VMID_HLOS);\ndrivers/soc/qcom/rmtfs_mem.c:273:\t\tret = qcom_scm_assign_mem(rmtfs_mem-\u003eaddr, rmtfs_mem-\u003esize,\ndrivers/soc/qcom/rmtfs_mem.c-274-\t\t\t\t\t  \u0026rmtfs_mem-\u003eperms, perms, num_vmids + 1);\n--\ndrivers/soc/qcom/rmtfs_mem.c=293=static void qcom_rmtfs_mem_remove(struct platform_device *pdev)\n--\ndrivers/soc/qcom/rmtfs_mem.c-301-\ndrivers/soc/qcom/rmtfs_mem.c:302:\t\tqcom_scm_assign_mem(rmtfs_mem-\u003eaddr, rmtfs_mem-\u003esize,\ndrivers/soc/qcom/rmtfs_mem.c-303-\t\t\t\t    \u0026rmtfs_mem-\u003eperms, \u0026perm, 1);\n--\ninclude/linux/firmware/qcom/qcom_scm.h=107=int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,\ninclude/linux/firmware/qcom/qcom_scm.h-108-\t\t\t\t   u32 cp_nonpixel_start, u32 cp_nonpixel_size);\ninclude/linux/firmware/qcom/qcom_scm.h:109:int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, u64 *src,\ninclude/linux/firmware/qcom/qcom_scm.h-110-\t\t\tconst struct qcom_scm_vmperm *newvm,\n"
}

39/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 37134
							output: 43
							thoughts: 14
						

Thoughts:
Okay, let's dive into this. Here's my take on `qcom_scm_assign_mem`, putting myself in the thought process:

**Diving into `qcom_scm_assign_mem`**

Right, so I'm looking at `qcom_scm_assign_mem`. First instinct is to get a handle on what it's *supposed* to do. The name itself suggests a function related to memory assignment within the Qualcomm Secure Compute Module (SCM) context. Given my experience, I'm expecting this function will be responsible for securely allocating and/or mapping memory regions, likely for use by trusted applications or secure processing environments. It's probably called from the SCM side, or maybe a context that interacts with it, to setup the necessary memory for various secure operations. I'm already anticipating some interesting aspects:

*   **Security Context:** This is an SCM function, so it's critical to consider the security implications right away. Things like memory protection, access control, and potential vulnerabilities related to buffer overflows or incorrect memory boundaries are going to be key concerns to watch for.
*   **Platform Specifics:** Qualcomm platforms have their own intricacies with memory management. So I'm expecting this function will contain code specific to the particular SoC, memory controllers, and security features implemented on the platform. This may contain information specific to different hardware revisions or configurations, and I will be looking out for if this is handled correctly.
*   **Resource Management:** I anticipate it will be doing some bookkeeping on resource availability and constraints, with careful handling of potential allocation failures. I'm also ready to see some error handling.
*   **Interactions:** I'll be looking for any interactions this function might have with other SCM components, such as memory protection controllers, bootloaders, or other security modules. How it works with the SCM context and its associated security features is going to be central.
*   **Memory Mapping Details:** Memory mapping details are always important. What regions are being assigned? Are there special considerations for physical vs. virtual addresses, cache coherency, or memory attributes?
*   **Context:** What context does this function operate in? Is it an interrupt context, process context, or something else entirely? The context will be important to understand how the function is used and any associated locks or synchronization primitives it uses.

I'm mentally gearing up to look for all these aspects, and now I'll start digging in and seeing what this code actually does. Let's get to it!



40/2 2026/07/14 09:45 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_scm.c",
  "FirstLine": 1355,
  "LineCount": 20
}

Results:
{
  "Contents": "1355:\tint qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,\n1356:\t\t\t\tu64 *srcvm,\n1357:\t\t\t\tconst struct qcom_scm_vmperm *newvm,\n1358:\t\t\t\tunsigned int dest_cnt)\n1359:\t{\n1360:\t\tstruct qcom_scm_current_perm_info *destvm;\n1361:\t\tstruct qcom_scm_mem_map_info *mem_to_map;\n1362:\t\tphys_addr_t mem_to_map_phys;\n1363:\t\tphys_addr_t dest_phys;\n1364:\t\tphys_addr_t ptr_phys;\n1365:\t\tsize_t mem_to_map_sz;\n1366:\t\tsize_t dest_sz;\n1367:\t\tsize_t src_sz;\n1368:\t\tsize_t ptr_sz;\n1369:\t\tint next_vm;\n1370:\t\t__le32 *src;\n1371:\t\tint ret, i, b;\n1372:\t\tu64 srcvm_bits = *srcvm;\n1373:\t\n1374:\t\tsrc_sz = hweight64(srcvm_bits) * sizeof(*src);\n"
}

41/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 38076
							output: 43
							thoughts: 24
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating Memory Assignment in the Qualcomm SCM**

Alright, let's see... *qcom_scm_assign_mem*... that's ringing a bell. Ah, yes, it seems I remember that function. I need to refresh my knowledge here, so I will analyze this information thoroughly, rather than make assumptions. *qcom_scm_assign_mem*...it's definitely involved in assigning memory through the Secure Channel Manager (SCM), as the name would suggest. And if I recall correctly from my previous work, it would seem that `qcom_scm_assign_mem` calls `__qcom_scm_assign_mem` internally. It's a common pattern. Usually, that kind of structure suggests a level of abstraction or perhaps some pre-processing before the core memory assignment routine is engaged. I will need to look deeper.



42/2 2026/07/14 09:45 tool read-file
0m Args:
{
  "File": "drivers/firmware/qcom/qcom_scm.c",
  "FirstLine": 1316,
  "LineCount": 20
}

Results:
{
  "Contents": "1316:\tstatic int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,\n1317:\t\t\t\t\t size_t mem_sz, phys_addr_t src, size_t src_sz,\n1318:\t\t\t\t\t phys_addr_t dest, size_t dest_sz)\n1319:\t{\n1320:\t\tint ret;\n1321:\t\tstruct qcom_scm_desc desc = {\n1322:\t\t\t.svc = QCOM_SCM_SVC_MP,\n1323:\t\t\t.cmd = QCOM_SCM_MP_ASSIGN,\n1324:\t\t\t.arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL,\n1325:\t\t\t\t\t\t QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO,\n1326:\t\t\t\t\t\t QCOM_SCM_VAL, QCOM_SCM_VAL),\n1327:\t\t\t.args[0] = mem_region,\n1328:\t\t\t.args[1] = mem_sz,\n1329:\t\t\t.args[2] = src,\n1330:\t\t\t.args[3] = src_sz,\n1331:\t\t\t.args[4] = dest,\n1332:\t\t\t.args[5] = dest_sz,\n1333:\t\t\t.args[6] = 0,\n1334:\t\t\t.owner = ARM_SMCCC_OWNER_SIP,\n1335:\t\t};\n"
}

43/2 2026/07/14 09:45 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 38749
							output: 20
							thoughts: 411
						

Thoughts:
**My Analysis of the Code's Failure Path**

Okay, so I'm looking at this code and immediately see a potential point of failure. It's calling `qcom_scm_call`. If that function fails, which could happen if SMC isn't supported or the Secure Monitor returns an error, then things are going to unravel pretty quickly. I know this because, if `qcom_scm_call` does fail, then `qcom_scm_assign_mem` returns an error. The crucial part is that the failure of `qcom_scm_assign_mem` directly causes `bam_dmux_alloc_coherent_rx` to return an error, which, in turn, causes `bam_dmux_probe` to fail. Essentially, a failed SCM call sinks the whole probe. The code explicitly shows this error path, so it's simple to reason about this.

Now, my real question is, can `qcom_scm_assign_mem` actually succeed in a QEMU environment? I am concerned here because if we are running in a typical QEMU arm64 VM, `qcom_scm_call` is going to make an SMC call. I'm wondering what happens with SMC calls when no EL3 firmware, such as TF-A, is present. Then I remember that if QEMU is launched with `-machine virt,secure=off` which is the default, then SMC instructions become UNDEFINED and will generate an exception, that the kernel will likely handle. But, wait, that is if SMC is even supported. We should check what happens if it is not supported in `qcom_scm_call`. I should go look at `qcom_scm_call`.



44/2 2026/07/14 09:45 tool grepper
0m Args:
{
  "Expression": "qcom_scm_call"
}

Results:
{
  "Output": "drivers/firmware/qcom/qcom_scm-legacy.c=110=static void __scm_legacy_do(const struct arm_smccc_args *smc,\n--\ndrivers/firmware/qcom/qcom_scm-legacy.c-128- * Note that any buffers that are expected to be accessed by the secure world\ndrivers/firmware/qcom/qcom_scm-legacy.c:129: * must be flushed before invoking qcom_scm_call and invalidated in the cache\ndrivers/firmware/qcom/qcom_scm-legacy.c:130: * immediately after qcom_scm_call returns. Cache maintenance on the command\ndrivers/firmware/qcom/qcom_scm-legacy.c:131: * and response buffers is taken care of by qcom_scm_call; however, callers are\ndrivers/firmware/qcom/qcom_scm-legacy.c-132- * responsible for any other cached buffers passed over to the secure world.\n--\ndrivers/firmware/qcom/qcom_scm.c=238=static enum qcom_scm_convention __get_convention(void)\n--\ndrivers/firmware/qcom/qcom_scm.c-305-/**\ndrivers/firmware/qcom/qcom_scm.c:306: * qcom_scm_call() - Invoke a syscall in the secure world\ndrivers/firmware/qcom/qcom_scm.c-307- * @dev:\tdevice\n--\ndrivers/firmware/qcom/qcom_scm.c-313- */\ndrivers/firmware/qcom/qcom_scm.c:314:static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc,\ndrivers/firmware/qcom/qcom_scm.c-315-\t\t\t struct qcom_scm_res *res)\n--\ndrivers/firmware/qcom/qcom_scm.c-330-/**\ndrivers/firmware/qcom/qcom_scm.c:331: * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()\ndrivers/firmware/qcom/qcom_scm.c-332- * @dev:\tdevice\n--\ndrivers/firmware/qcom/qcom_scm.c-338- */\ndrivers/firmware/qcom/qcom_scm.c:339:static int qcom_scm_call_atomic(struct device *dev,\ndrivers/firmware/qcom/qcom_scm.c-340-\t\t\t\tconst struct qcom_scm_desc *desc,\n--\ndrivers/firmware/qcom/qcom_scm.c=355=static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id,\n--\ndrivers/firmware/qcom/qcom_scm.c-380-\ndrivers/firmware/qcom/qcom_scm.c:381:\tret = qcom_scm_call(dev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-382-\n--\ndrivers/firmware/qcom/qcom_scm.c=386=static int qcom_scm_set_boot_addr(void *entry, const u8 *cpu_bits)\n--\ndrivers/firmware/qcom/qcom_scm.c-405-\ndrivers/firmware/qcom/qcom_scm.c:406:\treturn qcom_scm_call_atomic(__scm ? __scm-\u003edev : NULL, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-407-}\n--\ndrivers/firmware/qcom/qcom_scm.c=409=static int qcom_scm_set_boot_addr_mc(void *entry, unsigned int flags)\n--\ndrivers/firmware/qcom/qcom_scm.c-427-\ndrivers/firmware/qcom/qcom_scm.c:428:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-429-}\n--\ndrivers/firmware/qcom/qcom_scm.c=468=void qcom_scm_cpu_power_down(u32 flags)\n--\ndrivers/firmware/qcom/qcom_scm.c-477-\ndrivers/firmware/qcom/qcom_scm.c:478:\tqcom_scm_call_atomic(__scm ? __scm-\u003edev : NULL, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-479-}\n--\ndrivers/firmware/qcom/qcom_scm.c=482=int qcom_scm_set_remote_state(u32 state, u32 id)\n--\ndrivers/firmware/qcom/qcom_scm.c-494-\ndrivers/firmware/qcom/qcom_scm.c:495:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-496-\n--\ndrivers/firmware/qcom/qcom_scm.c=501=static int qcom_scm_disable_sdi(void)\n--\ndrivers/firmware/qcom/qcom_scm.c-516-\t\treturn ret;\ndrivers/firmware/qcom/qcom_scm.c:517:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-518-\n--\ndrivers/firmware/qcom/qcom_scm.c=524=static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)\n--\ndrivers/firmware/qcom/qcom_scm.c-535-\ndrivers/firmware/qcom/qcom_scm.c:536:\treturn qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-537-}\n--\ndrivers/firmware/qcom/qcom_scm.c=607=static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys,\n--\ndrivers/firmware/qcom/qcom_scm.c-628-\ndrivers/firmware/qcom/qcom_scm.c:629:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, res);\ndrivers/firmware/qcom/qcom_scm.c-630-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=749=int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)\n--\ndrivers/firmware/qcom/qcom_scm.c-770-\ndrivers/firmware/qcom/qcom_scm.c:771:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-772-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=781=static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm,\n--\ndrivers/firmware/qcom/qcom_scm.c-815-\t */\ndrivers/firmware/qcom/qcom_scm.c:816:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-817-\tif (!ret \u0026\u0026 res.result[2] \u003e SZ_1G) {\n--\ndrivers/firmware/qcom/qcom_scm.c=955=int qcom_scm_pas_auth_and_reset(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-974-\ndrivers/firmware/qcom/qcom_scm.c:975:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-976-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=1038=int qcom_scm_pas_shutdown(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1057-\ndrivers/firmware/qcom/qcom_scm.c:1058:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1059-\tqcom_scm_bw_disable();\n--\ndrivers/firmware/qcom/qcom_scm.c=1075=bool qcom_scm_pas_supported(u32 pas_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1090-\ndrivers/firmware/qcom/qcom_scm.c:1091:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1092-\n--\ndrivers/firmware/qcom/qcom_scm.c=1097=static int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)\n--\ndrivers/firmware/qcom/qcom_scm.c-1109-\ndrivers/firmware/qcom/qcom_scm.c:1110:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1111-\n--\ndrivers/firmware/qcom/qcom_scm.c=1138=int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)\n--\ndrivers/firmware/qcom/qcom_scm.c-1150-\ndrivers/firmware/qcom/qcom_scm.c:1151:\tret = qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1152-\tif (ret \u003e= 0)\n--\ndrivers/firmware/qcom/qcom_scm.c=1159=int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)\n--\ndrivers/firmware/qcom/qcom_scm.c-1169-\ndrivers/firmware/qcom/qcom_scm.c:1170:\treturn qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1171-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1187=int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)\n--\ndrivers/firmware/qcom/qcom_scm.c-1199-\ndrivers/firmware/qcom/qcom_scm.c:1200:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1201-\n--\ndrivers/firmware/qcom/qcom_scm.c=1215=int qcom_scm_set_gpu_smmu_aperture(unsigned int context_bank)\n--\ndrivers/firmware/qcom/qcom_scm.c-1227-\ndrivers/firmware/qcom/qcom_scm.c:1228:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1229-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1232=int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1243-\ndrivers/firmware/qcom/qcom_scm.c:1244:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1245-\n--\ndrivers/firmware/qcom/qcom_scm.c=1253=int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)\n--\ndrivers/firmware/qcom/qcom_scm.c-1266-\ndrivers/firmware/qcom/qcom_scm.c:1267:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1268-\n--\ndrivers/firmware/qcom/qcom_scm.c=1277=int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1287-\ndrivers/firmware/qcom/qcom_scm.c:1288:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1289-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1292=int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1309-\ndrivers/firmware/qcom/qcom_scm.c:1310:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1311-\n--\ndrivers/firmware/qcom/qcom_scm.c=1316=static int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,\n--\ndrivers/firmware/qcom/qcom_scm.c-1337-\ndrivers/firmware/qcom/qcom_scm.c:1338:\tret = qcom_scm_call(dev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1339-\n--\ndrivers/firmware/qcom/qcom_scm.c=1445=int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1457-\ndrivers/firmware/qcom/qcom_scm.c:1458:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1459-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1470=int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1480-\ndrivers/firmware/qcom/qcom_scm.c:1481:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1482-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1512=int qcom_scm_ice_invalidate_key(u32 index)\n--\ndrivers/firmware/qcom/qcom_scm.c-1521-\ndrivers/firmware/qcom/qcom_scm.c:1522:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1523-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1547=int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1572-\ndrivers/firmware/qcom/qcom_scm.c:1573:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1574-\n--\ndrivers/firmware/qcom/qcom_scm.c=1610=int qcom_scm_derive_sw_secret(const u8 *eph_key, size_t eph_key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1639-\ndrivers/firmware/qcom/qcom_scm.c:1640:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1641-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1661=int qcom_scm_generate_ice_key(u8 *lt_key, size_t lt_key_size)\n--\ndrivers/firmware/qcom/qcom_scm.c-1679-\ndrivers/firmware/qcom/qcom_scm.c:1680:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1681-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1702=int qcom_scm_prepare_ice_key(const u8 *lt_key, size_t lt_key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1731-\ndrivers/firmware/qcom/qcom_scm.c:1732:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1733-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1755=int qcom_scm_import_ice_key(const u8 *raw_key, size_t raw_key_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-1784-\ndrivers/firmware/qcom/qcom_scm.c:1785:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1786-\tif (!ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=1825=int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)\n--\ndrivers/firmware/qcom/qcom_scm.c-1854-\ndrivers/firmware/qcom/qcom_scm.c:1855:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1856-\t*resp = res.result[0];\n--\ndrivers/firmware/qcom/qcom_scm.c=1864=int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt)\n--\ndrivers/firmware/qcom/qcom_scm.c-1875-\ndrivers/firmware/qcom/qcom_scm.c:1876:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1877-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1880=int qcom_scm_qsmmu500_wait_safe_toggle(bool en)\n--\ndrivers/firmware/qcom/qcom_scm.c-1891-\ndrivers/firmware/qcom/qcom_scm.c:1892:\treturn qcom_scm_call_atomic(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1893-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1908=int qcom_scm_shm_bridge_enable(struct device *scm_dev)\n--\ndrivers/firmware/qcom/qcom_scm.c-1923-\ndrivers/firmware/qcom/qcom_scm.c:1924:\tret = qcom_scm_call(scm_dev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1925-\n--\ndrivers/firmware/qcom/qcom_scm.c=1936=int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,\n--\ndrivers/firmware/qcom/qcom_scm.c-1954-\ndrivers/firmware/qcom/qcom_scm.c:1955:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-1956-\n--\ndrivers/firmware/qcom/qcom_scm.c=1964=int qcom_scm_shm_bridge_delete(u64 handle)\n--\ndrivers/firmware/qcom/qcom_scm.c-1973-\ndrivers/firmware/qcom/qcom_scm.c:1974:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1975-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1978=int qcom_scm_lmh_profile_change(u32 profile_id)\n--\ndrivers/firmware/qcom/qcom_scm.c-1987-\ndrivers/firmware/qcom/qcom_scm.c:1988:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-1989-}\n--\ndrivers/firmware/qcom/qcom_scm.c=1992=int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,\n--\ndrivers/firmware/qcom/qcom_scm.c-2022-\ndrivers/firmware/qcom/qcom_scm.c:2023:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-2024-\n--\ndrivers/firmware/qcom/qcom_scm.c=2029=int qcom_scm_gpu_init_regs(u32 gpu_req)\n--\ndrivers/firmware/qcom/qcom_scm.c-2038-\ndrivers/firmware/qcom/qcom_scm.c:2039:\treturn qcom_scm_call(__scm-\u003edev, \u0026desc, NULL);\ndrivers/firmware/qcom/qcom_scm.c-2040-}\n--\ndrivers/firmware/qcom/qcom_scm.c=2074=static int __qcom_scm_qseecom_call(const struct qcom_scm_desc *desc,\n--\ndrivers/firmware/qcom/qcom_scm.c-2085-\ndrivers/firmware/qcom/qcom_scm.c:2086:\tstatus = qcom_scm_call(__scm-\u003edev, desc, \u0026scm_res);\ndrivers/firmware/qcom/qcom_scm.c-2087-\n--\ndrivers/firmware/qcom/qcom_scm.c=2404=int qcom_scm_qtee_invoke_smc(phys_addr_t inbuf, size_t inbuf_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-2421-\ndrivers/firmware/qcom/qcom_scm.c:2422:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2423-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=2447=int qcom_scm_qtee_callback_response(phys_addr_t buf, size_t buf_size,\n--\ndrivers/firmware/qcom/qcom_scm.c-2460-\ndrivers/firmware/qcom/qcom_scm.c:2461:\tret = qcom_scm_call(__scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2462-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=2585=static int qcom_scm_query_waitq_count(struct qcom_scm *scm)\n--\ndrivers/firmware/qcom/qcom_scm.c-2594-\ndrivers/firmware/qcom/qcom_scm.c:2595:\tret = qcom_scm_call_atomic(scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2596-\tif (ret)\n--\ndrivers/firmware/qcom/qcom_scm.c=2602=static int qcom_scm_get_waitq_irq(struct qcom_scm *scm)\n--\ndrivers/firmware/qcom/qcom_scm.c-2614-\ndrivers/firmware/qcom/qcom_scm.c:2615:\tret = qcom_scm_call_atomic(scm-\u003edev, \u0026desc, \u0026res);\ndrivers/firmware/qcom/qcom_scm.c-2616-\tif (ret)\n"
}

45/2 2026/07/14 09:46 llm patch-evaluator
5m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46270
							output: 17
							thoughts: 783
						

Thoughts:
**Reaching the `qcom_bam_dmux` Code in a Virtualized Environment**

Okay, so I'm looking at this code and trying to figure out if it's fuzzable. The key is whether syzkaller can reach it. I started by thinking about how `qcom_scm_call` works. It can lead to an undefined instruction exception if SMC is not supported and the kernel is running in EL1, but that's checked during boot. The real question is whether `qcom_scm_probe` even *runs*. That's the entry point, and it's triggered by the presence of a `qcom,scm` node in the device tree. Syzkaller doesn't directly inject device tree nodes, so that's a dead end.

Then it hits me, this patch is *tested* by syzkaller. The author is `syz-cluster`, meaning it's a patch under test. If syzkaller is testing it, then it *can* reach the code path. That's the crucial point.

But *how*? `qcom_bam_dmux` is a platform driver. So, it *must* be reachable somehow. The prompt gives me the `WorthFuzzing=false` logic for unreachable code. But, syzkaller *tests* the patch, and syzkaller tests on the same infrastructure where the bug was found. If syzkaller found it, it is reachable.

Then I consider a different scenario: Maybe syzbot is just testing a developer's patch. In this case, if the code is unreachable, syzbot would simply report "OK" without fuzzing the new code. So that helps determine the likelihood of reachability. We need to determine if it is reachable or not.

Now, how about virtualized environments? Is there some software-emulated hardware involved? No. Is `bam_dmux_probe` reachable in QEMU? Only if the device tree has `qcom,bam-dmux`. Does the default `virt` machine in QEMU have that? No. Syzkaller typically uses `virt`. Could it be reachable via `syz_dev_create`? Nope, that's for `/dev/` nodes. Wait... does syzkaller have a `syz_platform_device_add` call that might do it? I should check the syzkaller pseudo-syscalls.



46/2 2026/07/14 09:51 tool grepper
0m Args:
{
  "Expression": "syz_"
}

Results:
{
  "Output": "drivers/iommu/iommufd/ioas.c=283=int iommufd_ioas_copy(struct iommufd_ucmd *ucmd)\n--\ndrivers/iommu/iommufd/ioas.c-292-\ndrivers/iommu/iommufd/ioas.c:293:\tiommufd_test_syz_conv_iova_id(ucmd, cmd-\u003esrc_ioas_id, \u0026cmd-\u003esrc_iova,\ndrivers/iommu/iommufd/ioas.c-294-\t\t\t\t      \u0026cmd-\u003eflags);\n--\ndrivers/iommu/iommufd/iommufd_private.h=712=extern size_t iommufd_test_memory_limit;\ndrivers/iommu/iommufd/iommufd_private.h:713:void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,\ndrivers/iommu/iommufd/iommufd_private.h-714-\t\t\t\t   unsigned int ioas_id, u64 *iova, u32 *flags);\n--\ndrivers/iommu/iommufd/iommufd_private.h=719=int iommufd_test_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,\n--\ndrivers/iommu/iommufd/iommufd_private.h-721-#else\ndrivers/iommu/iommufd/iommufd_private.h:722:static inline void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,\ndrivers/iommu/iommufd/iommufd_private.h-723-\t\t\t\t\t\t unsigned int ioas_id,\n--\ndrivers/iommu/iommufd/selftest.c=51=static void mock_dev_disable_iopf(struct device *dev, struct iommu_domain *domain);\n--\ndrivers/iommu/iommufd/selftest.c-58- */\ndrivers/iommu/iommufd/selftest.c:59:static unsigned long __iommufd_test_syz_conv_iova(struct io_pagetable *iopt,\ndrivers/iommu/iommufd/selftest.c-60-\t\t\t\t\t\t  u64 *iova)\ndrivers/iommu/iommufd/selftest.c-61-{\ndrivers/iommu/iommufd/selftest.c:62:\tstruct syz_layout {\ndrivers/iommu/iommufd/selftest.c-63-\t\t__u32 nth_area;\n--\ndrivers/iommu/iommufd/selftest.c-65-\t};\ndrivers/iommu/iommufd/selftest.c:66:\tstruct syz_layout *syz = (void *)iova;\ndrivers/iommu/iommufd/selftest.c-67-\tunsigned int nth = syz-\u003enth_area;\n--\ndrivers/iommu/iommufd/selftest.c-83-\ndrivers/iommu/iommufd/selftest.c:84:static unsigned long iommufd_test_syz_conv_iova(struct iommufd_access *access,\ndrivers/iommu/iommufd/selftest.c-85-\t\t\t\t\t\tu64 *iova)\n--\ndrivers/iommu/iommufd/selftest.c-93-\t}\ndrivers/iommu/iommufd/selftest.c:94:\tret = __iommufd_test_syz_conv_iova(\u0026access-\u003eioas-\u003eiopt, iova);\ndrivers/iommu/iommufd/selftest.c-95-\tmutex_unlock(\u0026access-\u003eioas_lock);\n--\ndrivers/iommu/iommufd/selftest.c-98-\ndrivers/iommu/iommufd/selftest.c:99:void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,\ndrivers/iommu/iommufd/selftest.c-100-\t\t\t\t   unsigned int ioas_id, u64 *iova, u32 *flags)\n--\ndrivers/iommu/iommufd/selftest.c-110-\t\treturn;\ndrivers/iommu/iommufd/selftest.c:111:\t*iova = __iommufd_test_syz_conv_iova(\u0026ioas-\u003eiopt, iova);\ndrivers/iommu/iommufd/selftest.c-112-\tiommufd_put_object(ucmd-\u003eictx, \u0026ioas-\u003eobj);\n--\ndrivers/iommu/iommufd/selftest.c=1529=static int iommufd_test_access_pages(struct iommufd_ucmd *ucmd,\n--\ndrivers/iommu/iommufd/selftest.c-1557-\tif (flags \u0026 MOCK_FLAGS_ACCESS_SYZ)\ndrivers/iommu/iommufd/selftest.c:1558:\t\tiova = iommufd_test_syz_conv_iova(staccess-\u003eaccess,\ndrivers/iommu/iommufd/selftest.c-1559-\t\t\t\t\t\t  \u0026cmd-\u003eaccess_pages.iova);\n--\ndrivers/iommu/iommufd/selftest.c=1624=static int iommufd_test_access_rw(struct iommufd_ucmd *ucmd,\n--\ndrivers/iommu/iommufd/selftest.c-1659-\tif (flags \u0026 MOCK_FLAGS_ACCESS_SYZ)\ndrivers/iommu/iommufd/selftest.c:1660:\t\tiova = iommufd_test_syz_conv_iova(staccess-\u003eaccess,\ndrivers/iommu/iommufd/selftest.c-1661-\t\t\t\t\t\t  \u0026cmd-\u003eaccess_rw.iova);\n"
}

47/2 2026/07/14 09:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49162
							output: 21
							thoughts: 161
						

Thoughts:
**Assessing the Fuzzing Strategy for `qcom_bam_dmux`**

Okay, so I'm thinking about how to approach fuzzing this `qcom_bam_dmux` driver. The first thing that pops into my head is that `syz_` prefixes are usually executor-side code, not kernel code. That's a good starting point. Now, I remember that syzkaller *does* have a mechanism for testing patches. However, if this patch specifically targets a driver, and that driver isn't actually accessible within the QEMU environment – meaning it's not reachable during testing – then fuzzing it is, realistically, a waste of time.

So, the key question becomes: is `qcom_bam_dmux` reachable in QEMU? Let me think... It's a platform driver, specifically designed for a Qualcomm hardware block called the BAM Data Multiplexer. Right, it's pretty platform-specific. Unless there's a QEMU machine specifically emulating that particular hardware, or unless there’s some kind of clever syzkaller pseudo-device or module in place to simulate it, the answer is probably no, it’s not accessible.

Therefore, the next step is to quickly check whether there is any evidence of a syzkaller pseudo-device or test module specifically crafted for `qcom_bam_dmux`. Let’s see what's out there.



48/2 2026/07/14 09:51 tool grepper
0m Args:
{
  "Expression": "qcom_bam_dmux"
}

Results:
{
  "Output": "MAINTAINERS=22101=F:\tDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml\nMAINTAINERS:22102:F:\tdrivers/net/wwan/qcom_bam_dmux.c\nMAINTAINERS-22103-\n--\ndrivers/net/wwan/Kconfig=65=config QCOM_BAM_DMUX\n--\ndrivers/net/wwan/Kconfig-76-\t  To compile this driver as a module, choose M here: the module will be\ndrivers/net/wwan/Kconfig:77:\t  called qcom_bam_dmux.\ndrivers/net/wwan/Kconfig-78-\n--\ndrivers/net/wwan/Makefile=12=obj-$(CONFIG_MHI_WWAN_MBIM) += mhi_wwan_mbim.o\ndrivers/net/wwan/Makefile:13:obj-$(CONFIG_QCOM_BAM_DMUX) += qcom_bam_dmux.o\ndrivers/net/wwan/Makefile-14-obj-$(CONFIG_RPMSG_WWAN_CTRL) += rpmsg_wwan_ctrl.o\n"
}

49/2 2026/07/14 09:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 49949
							output: 21
							thoughts: 510
						

Thoughts:
**Analyzing Syzkaller's Platform Device Capabilities**

Okay, so there's no dedicated test module for platform devices, that's clear. Hmm, can Syzkaller inject them via `syz_dev_create`? Nope, that only handles `/dev/` nodes. What about `syz_platform_device_add`? No luck there either. Does it have anything with network sockets that might relate, maybe `syz_init_net_socket`? Nope. There is `syz_usb_connect`, though, for USB devices. But nothing directly for platform devices.

So, it seems Syzkaller doesn't have a *generic* way to inject platform devices unless there's a specific pseudo-device driver involved – things like `mac80211_hwsim`, `vkms`, or `vhci`. If `qcom_bam_dmux` *is* a platform driver, then it will need a platform device to be registered first. The question is, how do you register such a device from userspace?

There are a few potential avenues: Device Tree Overlays (DTO) via configfs, writing to a sysfs file (like `new_device` for I2C/SPI, but I don't think it's for platform buses), or a kernel module that registers it. Does Syzkaller use DTO? Looks like there is some mention of it, but no, not currently supported.

Wait, if this code path is unreachable, why was Syzkaller even testing it? Ah, right, Syzkaller tests patches submitted through email or Gerrit. It's possible that the patch was sent to syzbot for testing. Syzbot might compile and run the patch, and if the code is unreachable, syzbot will report "OK" since it didn't crash.

But, the instructions say to set "WorthFuzzing=false" if the patch contains unreachable code in virtualized environments. Since `qcom_bam_dmux` is a platform driver specifically for Qualcomm hardware, there is no software-emulated hardware in environments like GCE or QEMU. That means it's impossible to reach it.

Alright, let me just double-check one more time, make sure I didn't miss something. Is there any other driver that registers `qcom,bam-dmux`? Better be thorough.



50/2 2026/07/14 09:51 tool grepper
0m Args:
{
  "Expression": "qcom,bam-dmux"
}

Results:
{
  "Output": "Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml-3----\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml:4:$id: http://devicetree.org/schemas/net/qcom,bam-dmux.yaml#\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-5-$schema: http://devicetree.org/meta-schemas/core.yaml#\n--\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml=23=properties:\n--\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-25-    oneOf:\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml:26:      - const: qcom,bam-dmux\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-27-      - items:\n--\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-30-              - qcom,shikra-bam-dmux\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml:31:          - const: qcom,bam-dmux\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-32-\n--\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml=92=examples:\n--\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-97-        bam-dmux {\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml:98:            compatible = \"qcom,bam-dmux\";\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-99-\n--\nDocumentation/devicetree/bindings/remoteproc/qcom,msm8916-mss-pil.yaml=16=properties:\n--\nDocumentation/devicetree/bindings/remoteproc/qcom,msm8916-mss-pil.yaml-154-  bam-dmux:\nDocumentation/devicetree/bindings/remoteproc/qcom,msm8916-mss-pil.yaml:155:    $ref: /schemas/net/qcom,bam-dmux.yaml#\nDocumentation/devicetree/bindings/remoteproc/qcom,msm8916-mss-pil.yaml-156-    description:\n--\nMAINTAINERS=22100=S:\tMaintained\nMAINTAINERS:22101:F:\tDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml\nMAINTAINERS-22102-F:\tdrivers/net/wwan/qcom_bam_dmux.c\n--\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi=975=\t\t\tbam_dmux: bam-dmux {\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi:976:\t\t\t\tcompatible = \"qcom,bam-dmux\";\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-977-\n--\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi=1588=\t\t\tbam_dmux: bam-dmux {\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi:1589:\t\t\t\tcompatible = \"qcom,bam-dmux\";\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1590-\n--\narch/arm64/boot/dts/qcom/msm8916.dtsi=1976=\t\t\tbam_dmux: bam-dmux {\narch/arm64/boot/dts/qcom/msm8916.dtsi:1977:\t\t\t\tcompatible = \"qcom,bam-dmux\";\narch/arm64/boot/dts/qcom/msm8916.dtsi-1978-\n--\narch/arm64/boot/dts/qcom/msm8939.dtsi=1755=\t\t\tbam_dmux: bam-dmux {\narch/arm64/boot/dts/qcom/msm8939.dtsi:1756:\t\t\t\tcompatible = \"qcom,bam-dmux\";\narch/arm64/boot/dts/qcom/msm8939.dtsi-1757-\n--\ndrivers/net/wwan/qcom_bam_dmux.c=1001=static const struct of_device_id bam_dmux_of_match[] = {\ndrivers/net/wwan/qcom_bam_dmux.c-1002-\t{ .compatible = \"qcom,shikra-bam-dmux\", .data = \u0026shikra_data },\ndrivers/net/wwan/qcom_bam_dmux.c:1003:\t{ .compatible = \"qcom,bam-dmux\" },\ndrivers/net/wwan/qcom_bam_dmux.c-1004-\t{ /* sentinel */ }\n--\ndrivers/remoteproc/qcom_q6v5_mss.c=2067=static int q6v5_probe(struct platform_device *pdev)\n--\ndrivers/remoteproc/qcom_q6v5_mss.c-2203-\ndrivers/remoteproc/qcom_q6v5_mss.c:2204:\tnode = of_get_compatible_child(pdev-\u003edev.of_node, \"qcom,bam-dmux\");\ndrivers/remoteproc/qcom_q6v5_mss.c-2205-\tqproc-\u003ebam_dmux = of_platform_device_create(node, NULL, \u0026pdev-\u003edev);\n"
}

51/2 2026/07/14 09:51 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 52527
							output: 18
							thoughts: 596
						

Thoughts:
**Unreachable Code Path Analysis**

Okay, so I'm looking at this `qcom_q6v5_mss.c` file and I see it's registering `qcom,bam-dmux`. That's interesting, but then I remember `qcom_q6v5_mss` is itself a platform driver, specifically for Qualcomm Hexagon DSPs. Right away, my expert brain kicks in and I know that means it relies on a device tree node for the remoteproc device.

My concern is whether or not this code is reachable from syzkaller. I know syzkaller doesn't run on actual Qualcomm hardware; it's using generic QEMU/GCE VMs. So, can we actually instantiate this `qcom_q6v5_mss` driver in our testing environment? The answer is a solid no, and my reasoning is as follows: There is no way we can achieve that.

Let me think it through: Is there any *other* way? Can syzkaller use `syz_dev_create` to create the platform device, or maybe `syz_mount`? No, that's not how syzkaller or the kernel works. Hmm, what about using configfs to load a device tree overlay? I quickly check my mental map of Linux kernel features and recall that there's no upstream configfs interface for device tree overlays. There was a proposal, but it never landed. This means DTO from userspace is a dead end. Platform devices, in general, need a real device tree entry to get started unless there's some special driver that emulates the hardware. In my experience, I do not see that happening for `qcom_bam_dmux`.

Now, let's confirm this logic. The prompt mentions returning `WorthFuzzing=false` if the code path is unreachable in virtualized environments. Since `qcom_bam_dmux` is a hardware-specific platform driver that requires a device tree, and there's no software emulation I know of, it's definitively impossible to reach in QEMU/GCE. Therefore, based on the prompt's criteria, the fuzzing is not worth it, and I should return false.



52/2 2026/07/14 09:52 tool grepper
0m Args:
{
  "Expression": "bam_dmux"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 598 lines.\nUse more precise expression if possible.\n\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml=92=examples:\n--\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-106-\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml:107:            dmas = \u003c\u0026bam_dmux_dma 4\u003e, \u003c\u0026bam_dmux_dma 5\u003e;\nDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml-108-            dma-names = \"tx\", \"rx\";\n--\nMAINTAINERS=22101=F:\tDocumentation/devicetree/bindings/net/qcom,bam-dmux.yaml\nMAINTAINERS:22102:F:\tdrivers/net/wwan/qcom_bam_dmux.c\nMAINTAINERS-22103-\n--\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi=904=\t\tspmi_bus: spmi@fc4cf000 {\n--\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-919-\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi:920:\t\tbam_dmux_dma: dma-controller@fc834000 {\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-921-\t\t\tcompatible = \"qcom,bam-v1.4.0\";\n--\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi=932=\t\tmodem: remoteproc@fc880000 {\n--\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-974-\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi:975:\t\t\tbam_dmux: bam-dmux {\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-976-\t\t\t\tcompatible = \"qcom,bam-dmux\";\n--\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-984-\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi:985:\t\t\t\tdmas = \u003c\u0026bam_dmux_dma 4\u003e, \u003c\u0026bam_dmux_dma 5\u003e;\narch/arm/boot/dts/qcom/qcom-msm8226.dtsi-986-\t\t\t\tdma-names = \"tx\", \"rx\";\n--\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi=1521=\t\tspmi_bus: spmi@fc4cf000 {\n--\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1536-\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi:1537:\t\tbam_dmux_dma: dma-controller@fc834000 {\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1538-\t\t\tcompatible = \"qcom,bam-v1.4.0\";\n--\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi=1584=\t\t\tmpss {\n--\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1587-\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi:1588:\t\t\tbam_dmux: bam-dmux {\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1589-\t\t\t\tcompatible = \"qcom,bam-dmux\";\n--\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1597-\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi:1598:\t\t\t\tdmas = \u003c\u0026bam_dmux_dma 4\u003e, \u003c\u0026bam_dmux_dma 5\u003e;\narch/arm/boot/dts/qcom/qcom-msm8974.dtsi-1599-\t\t\t\tdma-names = \"tx\", \"rx\";\n--\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi=12=\u0026apr {\n--\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi-15-\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi:16:\u0026bam_dmux {\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi-17-\tstatus = \"okay\";\n--\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi-19-\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi:20:\u0026bam_dmux_dma {\narch/arm64/boot/dts/qcom/msm8916-modem-qdsp6.dtsi-21-\tstatus = \"okay\";\n--\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi=58=\t\tled_b: led-b {\n--\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi-65-\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi:66:\u0026bam_dmux {\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi-67-\tstatus = \"okay\";\n--\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi-69-\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi:70:\u0026bam_dmux_dma {\narch/arm64/boot/dts/qcom/msm8916-ufi.dtsi-71-\tstatus = \"okay\";\n--\narch/arm64/boot/dts/qcom/msm8916.dtsi=1901=\t\tspmi_bus: spmi@200f000 {\n--\narch/arm64/boot/dts/qcom/msm8916.dtsi-1918-\narch/arm64/boot/dts/qcom/msm8916.dtsi:1919:\t\tbam_dmux_dma: dma-controller@4044000 {\narch/arm64/boot/dts/qcom/msm8916.dtsi-1920-\t\t\tcompatible = \"qcom,bam-v1.7.0\";\n--\narch/arm64/boot/dts/qcom/msm8916.dtsi=1972=\t\t\tmpss {\n--\narch/arm64/boot/dts/qcom/msm8916.dtsi-1975-\narch/arm64/boot/dts/qcom/msm8916.dtsi:1976:\t\t\tbam_dmux: bam-dmux {\narch/arm64/boot/dts/qcom/msm8916.dtsi-1977-\t\t\t\tcompatible = \"qcom,bam-dmux\";\n--\narch/arm64/boot/dts/qcom/msm8916.dtsi-1985-\narch/arm64/boot/dts/qcom/msm8916.dtsi:1986:\t\t\t\tdmas = \u003c\u0026bam_dmux_dma 4\u003e, \u003c\u0026bam_dmux_dma 5\u003e;\narch/arm64/boot/dts/qcom/msm8916.dtsi-1987-\t\t\t\tdma-names = \"tx\", \"rx\";\n--\narch/arm64/boot/dts/qcom/msm8917.dtsi=1239=\t\tspmi_bus: spmi@200f000 {\n--\narch/arm64/boot/dts/qcom/msm8917.dtsi-1260-\narch/arm64/boot/dts/qcom/msm8917.dtsi:1261:\t\tbam_dmux_dma: dma-controller@4044000 {\narch/arm64/boot/dts/qcom/msm8917.dtsi-1262-\t\t\tcompatible = \"qcom,bam-v1.7.0\";\n--\narch/arm64/boot/dts/qcom/msm8937.dtsi=1403=\t\tspmi_bus: spmi@200f000 {\n--\narch/arm64/boot/dts/qcom/msm8937.dtsi-1424-\narch/arm64/boot/dts/qcom/msm8937.dtsi:1425:\t\tbam_dmux_dma: dma-controller@4044000 {\narch/arm64/boot/dts/qcom/msm8937.dtsi-1426-\t\t\tcompatible = \"qcom,bam-v1.7.0\";\n--\narch/arm64/boot/dts/qcom/msm8939.dtsi=1691=\t\tspmi_bus: spmi@200f000 {\n--\narch/arm64/boot/dts/qcom/msm8939.dtsi-1708-\narch/arm64/boot/dts/qcom/msm8939.dtsi:1709:\t\tbam_dmux_dma: dma-controller@4044000 {\narch/arm64/boot/dts/qcom/msm8939.dtsi-1710-\t\t\tcompatible = \"qcom,bam-v1.7.0\";\n--\narch/arm64/boot/dts/qcom/msm8939.dtsi=1723=\t\tmpss: remoteproc@4080000 {\n--\narch/arm64/boot/dts/qcom/msm8939.dtsi-1754-\narch/arm64/boot/dts/qcom/msm8939.dtsi:1755:\t\t\tbam_dmux: bam-dmux {\narch/arm64/boot/dts/qcom/msm8939.dtsi-1756-\t\t\t\tcompatible = \"qcom,bam-dmux\";\n--\narch/arm64/boot/dts/qcom/msm8939.dtsi-1764-\narch/arm64/boot/dts/qcom/msm8939.dtsi:1765:\t\t\t\tdmas = \u003c\u0026bam_dmux_dma 4\u003e, \u003c\u0026bam_dmux_dma 5\u003e;\narch/arm64/boot/dts/qcom/msm8939.dtsi-1766-\t\t\t\tdma-names = \"tx\", \"rx\";\n--\ndrivers/net/wwan/Kconfig=65=config QCOM_BAM_DMUX\n--\ndrivers/net/wwan/Kconfig-76-\t  To compile this driver as a module, choose M here: the module will be\ndrivers/net/wwan/Kconfig:77:\t  called qcom_bam_dmux.\ndrivers/net/wwan/Kconfig-78-\n--\ndrivers/net/wwan/Makefile=12=obj-$(CONFIG_MHI_WWAN_MBIM) += mhi_wwan_mbim.o\ndrivers/net/wwan/Makefile:13:obj-$(CONFIG_QCOM_BAM_DMUX) += qcom_bam_dmux.o\ndrivers/net/wwan/Makefile-14-obj-$(CONFIG_RPMSG_WWAN_CTRL) += rpmsg_wwan_ctrl.o\n--\ndrivers/net/wwan/qcom_bam_dmux.c-26-#define BAM_DMUX_BUFFER_SIZE\t\tSZ_2K\ndrivers/net/wwan/qcom_bam_dmux.c:27:#define BAM_DMUX_HDR_SIZE\t\tsizeof(struct bam_dmux_hdr)\ndrivers/net/wwan/qcom_bam_dmux.c-28-#define BAM_DMUX_MAX_DATA_SIZE\t\t(BAM_DMUX_BUFFER_SIZE - BAM_DMUX_HDR_SIZE)\n--\ndrivers/net/wwan/qcom_bam_dmux.c=42=enum {\n--\ndrivers/net/wwan/qcom_bam_dmux.c-53-\ndrivers/net/wwan/qcom_bam_dmux.c:54:struct bam_dmux_hdr {\ndrivers/net/wwan/qcom_bam_dmux.c-55-\tu16 magic;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-62-\ndrivers/net/wwan/qcom_bam_dmux.c:63:struct bam_dmux_skb_dma {\ndrivers/net/wwan/qcom_bam_dmux.c:64:\tstruct bam_dmux *dmux;\ndrivers/net/wwan/qcom_bam_dmux.c-65-\tstruct sk_buff *skb;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-69-\ndrivers/net/wwan/qcom_bam_dmux.c:70:struct bam_dmux {\ndrivers/net/wwan/qcom_bam_dmux.c-71-\tstruct device *dev;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-84-\tu64 rx_buf_perms; /* SCM source-VMID bitmask of rx_buf */\ndrivers/net/wwan/qcom_bam_dmux.c:85:\tstruct bam_dmux_skb_dma rx_skbs[BAM_DMUX_NUM_SKB];\ndrivers/net/wwan/qcom_bam_dmux.c:86:\tstruct bam_dmux_skb_dma tx_skbs[BAM_DMUX_NUM_SKB];\ndrivers/net/wwan/qcom_bam_dmux.c-87-\tspinlock_t tx_lock; /* Protect tx_skbs, tx_next_skb */\n--\ndrivers/net/wwan/qcom_bam_dmux.c-96-\ndrivers/net/wwan/qcom_bam_dmux.c:97:struct bam_dmux_netdev {\ndrivers/net/wwan/qcom_bam_dmux.c:98:\tstruct bam_dmux *dmux;\ndrivers/net/wwan/qcom_bam_dmux.c-99-\tu8 ch;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-101-\ndrivers/net/wwan/qcom_bam_dmux.c:102:struct bam_dmux_data {\ndrivers/net/wwan/qcom_bam_dmux.c-103-\tu32 vmid;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-105-\ndrivers/net/wwan/qcom_bam_dmux.c:106:static void bam_dmux_pc_vote(struct bam_dmux *dmux, bool enable)\ndrivers/net/wwan/qcom_bam_dmux.c-107-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-112-\ndrivers/net/wwan/qcom_bam_dmux.c:113:static void bam_dmux_pc_ack(struct bam_dmux *dmux)\ndrivers/net/wwan/qcom_bam_dmux.c-114-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-119-\ndrivers/net/wwan/qcom_bam_dmux.c:120:static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,\ndrivers/net/wwan/qcom_bam_dmux.c-121-\t\t\t\t enum dma_data_direction dir)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-137-\ndrivers/net/wwan/qcom_bam_dmux.c:138:static void bam_dmux_skb_dma_unmap(struct bam_dmux_skb_dma *skb_dma,\ndrivers/net/wwan/qcom_bam_dmux.c-139-\t\t\t\t   enum dma_data_direction dir)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-147-\ndrivers/net/wwan/qcom_bam_dmux.c:148:static void bam_dmux_tx_wake_queues(struct bam_dmux *dmux)\ndrivers/net/wwan/qcom_bam_dmux.c-149-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-161-\ndrivers/net/wwan/qcom_bam_dmux.c:162:static void bam_dmux_tx_stop_queues(struct bam_dmux *dmux)\ndrivers/net/wwan/qcom_bam_dmux.c-163-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-175-\ndrivers/net/wwan/qcom_bam_dmux.c:176:static void bam_dmux_tx_done(struct bam_dmux_skb_dma *skb_dma)\ndrivers/net/wwan/qcom_bam_dmux.c-177-{\ndrivers/net/wwan/qcom_bam_dmux.c:178:\tstruct bam_dmux *dmux = skb_dma-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c-179-\tunsigned long flags;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-183-\tif (skb_dma-\u003eaddr)\ndrivers/net/wwan/qcom_bam_dmux.c:184:\t\tbam_dmux_skb_dma_unmap(skb_dma, DMA_TO_DEVICE);\ndrivers/net/wwan/qcom_bam_dmux.c-185-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-188-\tif (skb_dma == \u0026dmux-\u003etx_skbs[dmux-\u003etx_next_skb % BAM_DMUX_NUM_SKB])\ndrivers/net/wwan/qcom_bam_dmux.c:189:\t\tbam_dmux_tx_wake_queues(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c-190-\tspin_unlock_irqrestore(\u0026dmux-\u003etx_lock, flags);\n--\ndrivers/net/wwan/qcom_bam_dmux.c-192-\ndrivers/net/wwan/qcom_bam_dmux.c:193:static void bam_dmux_tx_callback(void *data)\ndrivers/net/wwan/qcom_bam_dmux.c-194-{\ndrivers/net/wwan/qcom_bam_dmux.c:195:\tstruct bam_dmux_skb_dma *skb_dma = data;\ndrivers/net/wwan/qcom_bam_dmux.c-196-\tstruct sk_buff *skb = skb_dma-\u003eskb;\ndrivers/net/wwan/qcom_bam_dmux.c-197-\ndrivers/net/wwan/qcom_bam_dmux.c:198:\tbam_dmux_tx_done(skb_dma);\ndrivers/net/wwan/qcom_bam_dmux.c-199-\tdev_consume_skb_any(skb);\n--\ndrivers/net/wwan/qcom_bam_dmux.c-201-\ndrivers/net/wwan/qcom_bam_dmux.c:202:static bool bam_dmux_skb_dma_submit_tx(struct bam_dmux_skb_dma *skb_dma)\ndrivers/net/wwan/qcom_bam_dmux.c-203-{\ndrivers/net/wwan/qcom_bam_dmux.c:204:\tstruct bam_dmux *dmux = skb_dma-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c-205-\tstruct dma_async_tx_descriptor *desc;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-214-\ndrivers/net/wwan/qcom_bam_dmux.c:215:\tdesc-\u003ecallback = bam_dmux_tx_callback;\ndrivers/net/wwan/qcom_bam_dmux.c-216-\tdesc-\u003ecallback_param = skb_dma;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-220-\ndrivers/net/wwan/qcom_bam_dmux.c:221:static struct bam_dmux_skb_dma *\ndrivers/net/wwan/qcom_bam_dmux.c:222:bam_dmux_tx_queue(struct bam_dmux *dmux, struct sk_buff *skb)\ndrivers/net/wwan/qcom_bam_dmux.c-223-{\ndrivers/net/wwan/qcom_bam_dmux.c:224:\tstruct bam_dmux_skb_dma *skb_dma;\ndrivers/net/wwan/qcom_bam_dmux.c-225-\tunsigned long flags;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-230-\tif (skb_dma-\u003eskb) {\ndrivers/net/wwan/qcom_bam_dmux.c:231:\t\tbam_dmux_tx_stop_queues(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c-232-\t\tspin_unlock_irqrestore(\u0026dmux-\u003etx_lock, flags);\n--\ndrivers/net/wwan/qcom_bam_dmux.c-238-\tif (dmux-\u003etx_skbs[dmux-\u003etx_next_skb % BAM_DMUX_NUM_SKB].skb)\ndrivers/net/wwan/qcom_bam_dmux.c:239:\t\tbam_dmux_tx_stop_queues(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c-240-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-244-\ndrivers/net/wwan/qcom_bam_dmux.c:245:static int bam_dmux_send_cmd(struct bam_dmux_netdev *bndev, u8 cmd)\ndrivers/net/wwan/qcom_bam_dmux.c-246-{\ndrivers/net/wwan/qcom_bam_dmux.c:247:\tstruct bam_dmux *dmux = bndev-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c:248:\tstruct bam_dmux_skb_dma *skb_dma;\ndrivers/net/wwan/qcom_bam_dmux.c:249:\tstruct bam_dmux_hdr *hdr;\ndrivers/net/wwan/qcom_bam_dmux.c-250-\tstruct sk_buff *skb;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-261-\ndrivers/net/wwan/qcom_bam_dmux.c:262:\tskb_dma = bam_dmux_tx_queue(dmux, skb);\ndrivers/net/wwan/qcom_bam_dmux.c-263-\tif (!skb_dma) {\n--\ndrivers/net/wwan/qcom_bam_dmux.c-271-\ndrivers/net/wwan/qcom_bam_dmux.c:272:\tif (!bam_dmux_skb_dma_map(skb_dma, DMA_TO_DEVICE)) {\ndrivers/net/wwan/qcom_bam_dmux.c-273-\t\tret = -ENOMEM;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-276-\ndrivers/net/wwan/qcom_bam_dmux.c:277:\tif (!bam_dmux_skb_dma_submit_tx(skb_dma)) {\ndrivers/net/wwan/qcom_bam_dmux.c-278-\t\tret = -EIO;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-285-tx_fail:\ndrivers/net/wwan/qcom_bam_dmux.c:286:\tbam_dmux_tx_done(skb_dma);\ndrivers/net/wwan/qcom_bam_dmux.c-287-free_skb:\n--\ndrivers/net/wwan/qcom_bam_dmux.c-291-\ndrivers/net/wwan/qcom_bam_dmux.c:292:static int bam_dmux_netdev_open(struct net_device *netdev)\ndrivers/net/wwan/qcom_bam_dmux.c-293-{\ndrivers/net/wwan/qcom_bam_dmux.c:294:\tstruct bam_dmux_netdev *bndev = netdev_priv(netdev);\ndrivers/net/wwan/qcom_bam_dmux.c-295-\tint ret;\ndrivers/net/wwan/qcom_bam_dmux.c-296-\ndrivers/net/wwan/qcom_bam_dmux.c:297:\tret = bam_dmux_send_cmd(bndev, BAM_DMUX_CMD_OPEN);\ndrivers/net/wwan/qcom_bam_dmux.c-298-\tif (ret)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-304-\ndrivers/net/wwan/qcom_bam_dmux.c:305:static int bam_dmux_netdev_stop(struct net_device *netdev)\ndrivers/net/wwan/qcom_bam_dmux.c-306-{\ndrivers/net/wwan/qcom_bam_dmux.c:307:\tstruct bam_dmux_netdev *bndev = netdev_priv(netdev);\ndrivers/net/wwan/qcom_bam_dmux.c-308-\ndrivers/net/wwan/qcom_bam_dmux.c-309-\tnetif_stop_queue(netdev);\ndrivers/net/wwan/qcom_bam_dmux.c:310:\tbam_dmux_send_cmd(bndev, BAM_DMUX_CMD_CLOSE);\ndrivers/net/wwan/qcom_bam_dmux.c-311-\treturn 0;\n--\ndrivers/net/wwan/qcom_bam_dmux.c=314=static unsigned int needed_room(unsigned int avail, unsigned int needed)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-320-\ndrivers/net/wwan/qcom_bam_dmux.c:321:static int bam_dmux_tx_prepare_skb(struct bam_dmux_netdev *bndev,\ndrivers/net/wwan/qcom_bam_dmux.c-322-\t\t\t\t   struct sk_buff *skb)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-326-\tunsigned int tail = needed_room(skb_tailroom(skb), pad);\ndrivers/net/wwan/qcom_bam_dmux.c:327:\tstruct bam_dmux_hdr *hdr;\ndrivers/net/wwan/qcom_bam_dmux.c-328-\tint ret;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-348-\ndrivers/net/wwan/qcom_bam_dmux.c:349:static netdev_tx_t bam_dmux_netdev_start_xmit(struct sk_buff *skb,\ndrivers/net/wwan/qcom_bam_dmux.c-350-\t\t\t\t\t      struct net_device *netdev)\ndrivers/net/wwan/qcom_bam_dmux.c-351-{\ndrivers/net/wwan/qcom_bam_dmux.c:352:\tstruct bam_dmux_netdev *bndev = netdev_priv(netdev);\ndrivers/net/wwan/qcom_bam_dmux.c:353:\tstruct bam_dmux *dmux = bndev-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c:354:\tstruct bam_dmux_skb_dma *skb_dma;\ndrivers/net/wwan/qcom_bam_dmux.c-355-\tint active, ret;\ndrivers/net/wwan/qcom_bam_dmux.c-356-\ndrivers/net/wwan/qcom_bam_dmux.c:357:\tskb_dma = bam_dmux_tx_queue(dmux, skb);\ndrivers/net/wwan/qcom_bam_dmux.c-358-\tif (!skb_dma)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-364-\ndrivers/net/wwan/qcom_bam_dmux.c:365:\tret = bam_dmux_tx_prepare_skb(bndev, skb);\ndrivers/net/wwan/qcom_bam_dmux.c-366-\tif (ret)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-368-\ndrivers/net/wwan/qcom_bam_dmux.c:369:\tif (!bam_dmux_skb_dma_map(skb_dma, DMA_TO_DEVICE))\ndrivers/net/wwan/qcom_bam_dmux.c-370-\t\tgoto drop;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-379-\ndrivers/net/wwan/qcom_bam_dmux.c:380:\tif (!bam_dmux_skb_dma_submit_tx(skb_dma))\ndrivers/net/wwan/qcom_bam_dmux.c-381-\t\tgoto drop;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-386-drop:\ndrivers/net/wwan/qcom_bam_dmux.c:387:\tbam_dmux_tx_done(skb_dma);\ndrivers/net/wwan/qcom_bam_dmux.c-388-\tdev_kfree_skb_any(skb);\n--\ndrivers/net/wwan/qcom_bam_dmux.c-391-\ndrivers/net/wwan/qcom_bam_dmux.c:392:static void bam_dmux_tx_wakeup_work(struct work_struct *work)\ndrivers/net/wwan/qcom_bam_dmux.c-393-{\ndrivers/net/wwan/qcom_bam_dmux.c:394:\tstruct bam_dmux *dmux = container_of(work, struct bam_dmux, tx_wakeup_work);\ndrivers/net/wwan/qcom_bam_dmux.c-395-\tunsigned long pending;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-409-\tfor_each_set_bit(i, \u0026pending, BAM_DMUX_NUM_SKB) {\ndrivers/net/wwan/qcom_bam_dmux.c:410:\t\tbam_dmux_skb_dma_submit_tx(\u0026dmux-\u003etx_skbs[i]);\ndrivers/net/wwan/qcom_bam_dmux.c-411-\t}\n--\ndrivers/net/wwan/qcom_bam_dmux.c-417-\ndrivers/net/wwan/qcom_bam_dmux.c:418:static const struct net_device_ops bam_dmux_ops = {\ndrivers/net/wwan/qcom_bam_dmux.c:419:\t.ndo_open\t= bam_dmux_netdev_open,\ndrivers/net/wwan/qcom_bam_dmux.c:420:\t.ndo_stop\t= bam_dmux_netdev_stop,\ndrivers/net/wwan/qcom_bam_dmux.c:421:\t.ndo_start_xmit\t= bam_dmux_netdev_start_xmit,\ndrivers/net/wwan/qcom_bam_dmux.c-422-};\n--\ndrivers/net/wwan/qcom_bam_dmux.c=424=static const struct device_type wwan_type = {\n--\ndrivers/net/wwan/qcom_bam_dmux.c-427-\ndrivers/net/wwan/qcom_bam_dmux.c:428:static void bam_dmux_netdev_setup(struct net_device *dev)\ndrivers/net/wwan/qcom_bam_dmux.c-429-{\ndrivers/net/wwan/qcom_bam_dmux.c:430:\tdev-\u003enetdev_ops = \u0026bam_dmux_ops;\ndrivers/net/wwan/qcom_bam_dmux.c-431-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-437-\tdev-\u003emax_mtu = BAM_DMUX_MAX_DATA_SIZE;\ndrivers/net/wwan/qcom_bam_dmux.c:438:\tdev-\u003eneeded_headroom = sizeof(struct bam_dmux_hdr);\ndrivers/net/wwan/qcom_bam_dmux.c-439-\tdev-\u003eneeded_tailroom = sizeof(u32); /* word-aligned */\n--\ndrivers/net/wwan/qcom_bam_dmux.c-446-\ndrivers/net/wwan/qcom_bam_dmux.c:447:static void bam_dmux_register_netdev_work(struct work_struct *work)\ndrivers/net/wwan/qcom_bam_dmux.c-448-{\ndrivers/net/wwan/qcom_bam_dmux.c:449:\tstruct bam_dmux *dmux = container_of(work, struct bam_dmux, register_netdev_work);\ndrivers/net/wwan/qcom_bam_dmux.c:450:\tstruct bam_dmux_netdev *bndev;\ndrivers/net/wwan/qcom_bam_dmux.c-451-\tstruct net_device *netdev;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-458-\t\tnetdev = alloc_netdev(sizeof(*bndev), \"wwan%d\", NET_NAME_ENUM,\ndrivers/net/wwan/qcom_bam_dmux.c:459:\t\t\t\t      bam_dmux_netdev_setup);\ndrivers/net/wwan/qcom_bam_dmux.c-460-\t\tif (!netdev)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-481-\ndrivers/net/wwan/qcom_bam_dmux.c:482:static void bam_dmux_rx_callback(void *data);\ndrivers/net/wwan/qcom_bam_dmux.c-483-\ndrivers/net/wwan/qcom_bam_dmux.c:484:static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)\ndrivers/net/wwan/qcom_bam_dmux.c-485-{\ndrivers/net/wwan/qcom_bam_dmux.c:486:\tstruct bam_dmux *dmux = skb_dma-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c-487-\tstruct dma_async_tx_descriptor *desc;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-497-\ndrivers/net/wwan/qcom_bam_dmux.c:498:\tdesc-\u003ecallback = bam_dmux_rx_callback;\ndrivers/net/wwan/qcom_bam_dmux.c-499-\tdesc-\u003ecallback_param = skb_dma;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-503-\ndrivers/net/wwan/qcom_bam_dmux.c:504:static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gfp)\ndrivers/net/wwan/qcom_bam_dmux.c-505-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-507-\tif (skb_dma-\u003erx_virt)\ndrivers/net/wwan/qcom_bam_dmux.c:508:\t\treturn bam_dmux_skb_dma_submit_rx(skb_dma);\ndrivers/net/wwan/qcom_bam_dmux.c-509-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-516-\ndrivers/net/wwan/qcom_bam_dmux.c:517:\treturn bam_dmux_skb_dma_map(skb_dma, DMA_FROM_DEVICE) \u0026\u0026\ndrivers/net/wwan/qcom_bam_dmux.c:518:\t       bam_dmux_skb_dma_submit_rx(skb_dma);\ndrivers/net/wwan/qcom_bam_dmux.c-519-}\ndrivers/net/wwan/qcom_bam_dmux.c-520-\ndrivers/net/wwan/qcom_bam_dmux.c:521:static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)\ndrivers/net/wwan/qcom_bam_dmux.c-522-{\ndrivers/net/wwan/qcom_bam_dmux.c:523:\tstruct bam_dmux *dmux = skb_dma-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c:524:\tstruct bam_dmux_hdr *hdr = skb_dma-\u003erx_virt ? skb_dma-\u003erx_virt :\ndrivers/net/wwan/qcom_bam_dmux.c:525:\t\t\t\t   (struct bam_dmux_hdr *)skb_dma-\u003eskb-\u003edata;\ndrivers/net/wwan/qcom_bam_dmux.c-526-\tstruct net_device *netdev = dmux-\u003enetdevs[hdr-\u003ech];\n--\ndrivers/net/wwan/qcom_bam_dmux.c-569-\ndrivers/net/wwan/qcom_bam_dmux.c:570:static void bam_dmux_cmd_open(struct bam_dmux *dmux, struct bam_dmux_hdr *hdr)\ndrivers/net/wwan/qcom_bam_dmux.c-571-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-588-\ndrivers/net/wwan/qcom_bam_dmux.c:589:static void bam_dmux_cmd_close(struct bam_dmux *dmux, struct bam_dmux_hdr *hdr)\ndrivers/net/wwan/qcom_bam_dmux.c-590-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-603-\ndrivers/net/wwan/qcom_bam_dmux.c:604:static void bam_dmux_rx_callback(void *data)\ndrivers/net/wwan/qcom_bam_dmux.c-605-{\ndrivers/net/wwan/qcom_bam_dmux.c:606:\tstruct bam_dmux_skb_dma *skb_dma = data;\ndrivers/net/wwan/qcom_bam_dmux.c:607:\tstruct bam_dmux *dmux = skb_dma-\u003edmux;\ndrivers/net/wwan/qcom_bam_dmux.c:608:\tstruct bam_dmux_hdr *hdr;\ndrivers/net/wwan/qcom_bam_dmux.c-609-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-612-\t} else {\ndrivers/net/wwan/qcom_bam_dmux.c:613:\t\tbam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);\ndrivers/net/wwan/qcom_bam_dmux.c:614:\t\thdr = (struct bam_dmux_hdr *)skb_dma-\u003eskb-\u003edata;\ndrivers/net/wwan/qcom_bam_dmux.c-615-\t}\n--\ndrivers/net/wwan/qcom_bam_dmux.c-628-\tcase BAM_DMUX_CMD_DATA:\ndrivers/net/wwan/qcom_bam_dmux.c:629:\t\tbam_dmux_cmd_data(skb_dma);\ndrivers/net/wwan/qcom_bam_dmux.c-630-\t\tbreak;\ndrivers/net/wwan/qcom_bam_dmux.c-631-\tcase BAM_DMUX_CMD_OPEN:\ndrivers/net/wwan/qcom_bam_dmux.c:632:\t\tbam_dmux_cmd_open(dmux, hdr);\ndrivers/net/wwan/qcom_bam_dmux.c-633-\t\tbreak;\ndrivers/net/wwan/qcom_bam_dmux.c-634-\tcase BAM_DMUX_CMD_CLOSE:\ndrivers/net/wwan/qcom_bam_dmux.c:635:\t\tbam_dmux_cmd_close(dmux, hdr);\ndrivers/net/wwan/qcom_bam_dmux.c-636-\t\tbreak;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-643-out:\ndrivers/net/wwan/qcom_bam_dmux.c:644:\tif (bam_dmux_skb_dma_queue_rx(skb_dma, GFP_ATOMIC))\ndrivers/net/wwan/qcom_bam_dmux.c-645-\t\tdma_async_issue_pending(dmux-\u003erx);\n--\ndrivers/net/wwan/qcom_bam_dmux.c-647-\ndrivers/net/wwan/qcom_bam_dmux.c:648:static bool bam_dmux_power_on(struct bam_dmux *dmux)\ndrivers/net/wwan/qcom_bam_dmux.c-649-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-665-\tfor (i = 0; i \u003c BAM_DMUX_NUM_SKB; i++) {\ndrivers/net/wwan/qcom_bam_dmux.c:666:\t\tif (!bam_dmux_skb_dma_queue_rx(\u0026dmux-\u003erx_skbs[i], GFP_KERNEL))\ndrivers/net/wwan/qcom_bam_dmux.c-667-\t\t\treturn false;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-673-\ndrivers/net/wwan/qcom_bam_dmux.c:674:static void bam_dmux_free_skbs(struct bam_dmux_skb_dma skbs[],\ndrivers/net/wwan/qcom_bam_dmux.c-675-\t\t\t       enum dma_data_direction dir)\n--\ndrivers/net/wwan/qcom_bam_dmux.c-679-\tfor (i = 0; i \u003c BAM_DMUX_NUM_SKB; i++) {\ndrivers/net/wwan/qcom_bam_dmux.c:680:\t\tstruct bam_dmux_skb_dma *skb_dma = \u0026skbs[i];\ndrivers/net/wwan/qcom_bam_dmux.c-681-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-685-\t\tif (skb_dma-\u003eaddr)\ndrivers/net/wwan/qcom_bam_dmux.c:686:\t\t\tbam_dmux_skb_dma_unmap(skb_dma, dir);\ndrivers/net/wwan/qcom_bam_dmux.c-687-\t\tif (skb_dma-\u003eskb) {\n--\ndrivers/net/wwan/qcom_bam_dmux.c-693-\ndrivers/net/wwan/qcom_bam_dmux.c:694:static void bam_dmux_power_off(struct bam_dmux *dmux)\ndrivers/net/wwan/qcom_bam_dmux.c-695-{\n--\ndrivers/net/wwan/qcom_bam_dmux.c-707-\ndrivers/net/wwan/qcom_bam_dmux.c:708:\tbam_dmux_free_skbs(dmux-\u003erx_skbs, DMA_FROM_DEVICE);\ndrivers/net/wwan/qcom_bam_dmux.c-709-}\ndrivers/net/wwan/qcom_bam_dmux.c-710-\ndrivers/net/wwan/qcom_bam_dmux.c:711:static irqreturn_t bam_dmux_pc_irq(int irq, void *data)\ndrivers/net/wwan/qcom_bam_dmux.c-712-{\ndrivers/net/wwan/qcom_bam_dmux.c:713:\tstruct bam_dmux *dmux = data;\ndrivers/net/wwan/qcom_bam_dmux.c-714-\tbool new_state = !dmux-\u003epc_state;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-718-\tif (new_state) {\ndrivers/net/wwan/qcom_bam_dmux.c:719:\t\tif (bam_dmux_power_on(dmux))\ndrivers/net/wwan/qcom_bam_dmux.c:720:\t\t\tbam_dmux_pc_ack(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c-721-\t\telse\ndrivers/net/wwan/qcom_bam_dmux.c:722:\t\t\tbam_dmux_power_off(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c-723-\t} else {\ndrivers/net/wwan/qcom_bam_dmux.c:724:\t\tbam_dmux_power_off(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c:725:\t\tbam_dmux_pc_ack(dmux);\ndrivers/net/wwan/qcom_bam_dmux.c-726-\t}\n--\ndrivers/net/wwan/qcom_bam_dmux.c-733-\ndrivers/net/wwan/qcom_bam_dmux.c:734:static irqreturn_t bam_dmux_pc_ack_irq(int irq, void *data)\ndrivers/net/wwan/qcom_bam_dmux.c-735-{\ndrivers/net/wwan/qcom_bam_dmux.c:736:\tstruct bam_dmux *dmux = data;\ndrivers/net/wwan/qcom_bam_dmux.c-737-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-743-\ndrivers/net/wwan/qcom_bam_dmux.c:744:static int bam_dmux_runtime_suspend(struct device *dev)\ndrivers/net/wwan/qcom_bam_dmux.c-745-{\ndrivers/net/wwan/qcom_bam_dmux.c:746:\tstruct bam_dmux *dmux = dev_get_drvdata(dev);\ndrivers/net/wwan/qcom_bam_dmux.c-747-\ndrivers/net/wwan/qcom_bam_dmux.c-748-\tdev_dbg(dev, \"runtime suspend\\n\");\ndrivers/net/wwan/qcom_bam_dmux.c:749:\tbam_dmux_pc_vote(dmux, false);\ndrivers/net/wwan/qcom_bam_dmux.c-750-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-753-\ndrivers/net/wwan/qcom_bam_dmux.c:754:static int __maybe_unused bam_dmux_runtime_resume(struct device *dev)\ndrivers/net/wwan/qcom_bam_dmux.c-755-{\ndrivers/net/wwan/qcom_bam_dmux.c:756:\tstruct bam_dmux *dmux = dev_get_drvdata(dev);\ndrivers/net/wwan/qcom_bam_dmux.c-757-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-765-\t/* Vote for power state */\ndrivers/net/wwan/qcom_bam_dmux.c:766:\tbam_dmux_pc_vote(dmux, true);\ndrivers/net/wwan/qcom_bam_dmux.c-767-\n--\ndrivers/net/wwan/qcom_bam_dmux.c-770-\t\t\t\t\t BAM_DMUX_REMOTE_TIMEOUT)) {\ndrivers/net/wwan/qcom_bam_dmux.c:771:\t\tbam_dmux_pc_vote(dmux, false);\ndrivers/net/wwan/qcom_bam_dmux.c-772-\t\treturn -ETIMEDOUT;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-777-\t\t\t\tBAM_DMUX_REMOTE_TIMEOUT)) {\ndrivers/net/wwan/qcom_bam_dmux.c:778:\t\tbam_dmux_pc_vote(dmux, false);\ndrivers/net/wwan/qcom_bam_dmux.c-779-\t\treturn -ETIMEDOUT;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-783-\tif (!dmux-\u003erx) {\ndrivers/net/wwan/qcom_bam_dmux.c:784:\t\tbam_dmux_pc_vote(dmux, false);\ndrivers/net/wwan/qcom_bam_dmux.c-785-\t\treturn -ENXIO;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-795-\t\tdmux-\u003etx = NULL;\ndrivers/net/wwan/qcom_bam_dmux.c:796:\t\tbam_dmux_runtime_suspend(dev);\ndrivers/net/wwan/qcom_bam_dmux.c-797-\t\treturn -ENXIO;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-802-\ndrivers/net/wwan/qcom_bam_dmux.c:803:static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)\ndrivers/net/wwan/qcom_bam_dmux.c-804-{\ndrivers/net/wwan/qcom_bam_dmux.c-805-\tstruct device *dev = dmux-\u003edev;\ndrivers/net/wwan/qcom_bam_dmux.c:806:\tconst struct bam_dmux_data *data = of_device_get_match_data(dev);\ndrivers/net/wwan/qcom_bam_dmux.c-807-\tsize_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;\n--\ndrivers/net/wwan/qcom_bam_dmux.c-843-\n\n"
}

53/2 2026/07/14 09:52 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 67304
							output: 92
							thoughts: 422
						

Thoughts:
**WorthFuzzing Assessment: The `qcom_bam_dmux` Driver**

Okay, so the question is whether this patch, which touches `qcom_bam_dmux`, is worth fuzzing. My immediate thought is, "No." There's no emulator, which means `qcom_bam_dmux` is a hardware-specific driver. I need to make sure I don't miss anything, but I'm pretty sure that makes it unreachable in QEMU, right?

Syzkaller tests patches, yes, and compiles the kernel, runs its corpus. But if the code's never actually *executed* because the underlying hardware isn't emulated, syzkaller will just report "OK" – a false positive. The prompt specifically says to return `WorthFuzzing=false` if the code paths are impossible to reach in virtualized environments. So, that's the threshold I need to meet.

Let me double-check. Is there *any* way to reach this code? A `qcom,bam-dmux` device in *any* of the QEMU machines? Nope. QEMU doesn't emulate Qualcomm BAM DMUX. And I'm not aware of any other driver that could somehow trigger it indirectly.

So, here's my reasoning, and it's pretty solid: The patch modifies the `qcom_bam_dmux` driver to support a new compatible string and allocates a coherent RX buffer using SCM calls. However, this is for a very specific Qualcomm hardware block – the BAM Data Multiplexer – and requires a corresponding device tree node to probe. Since there is no software emulation for this hardware in QEMU or GCE, the modified code is completely unreachable in those virtualized environments.

Therefore, the patch doesn't add value for fuzzing in the relevant environments. So here's the response I need to formulate:

WorthFuzzing: false
Reasoning: The patch modifies the `qcom_bam_dmux` driver, which is a platform driver for specific Qualcomm hardware. Since there is no software emulation for this hardware in virtualized environments like QEMU or GCE, the modified code paths are impossible to reach and cannot be fuzzed.
FocusSymbols: []
EnableConfigs: []



54/2 2026/07/14 09:52 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the `qcom_bam_dmux` driver, which is a platform driver for specific Qualcomm hardware. Since there is no software emulation for this hardware in virtualized environments like QEMU or GCE, the modified code paths are impossible to reach and cannot be fuzzed.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the `qcom_bam_dmux` driver, which is a platform driver for specific Qualcomm hardware. Since there is no software emulation for this hardware in virtualized environments like QEMU or GCE, the modified code paths are impossible to reach and cannot be fuzzed.",
  "WorthFuzzing": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)