From nobody Sat Sep 26 22:02:22 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F02C13D9DCD for ; Fri, 28 Aug 2026 21:37:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953081; cv=none; b=uliW8VPjm03t2Z242HOyEYVRQrU33y9CRInP32Ix0jHwKDkdi9uEbhgHT7MSYWxg6KhjY8gw9E3JY+S9h8JyNoYDwmGDvBxr6Fpt6YCfyKLouR9g6k+K9ndBJO29vZXeAkxMtkepAZCzl23m3Ka1MckSAabyxRtIzmUl4Kkk39E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953081; c=relaxed/simple; bh=6k3p0ySqBDsyF/vFgmLfucoHCiVzOtKxA6qYkh5DRN0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZGz8Fc2j4jJQ1LU0xncxvmE045MzLAizE8cYH7TyN89Ri0XmWsWyAhz7EzgR6Ug7awgWBL71z5Ypcry+792Zv3shuzBiHVvbEPkZp+zzqlShft10gcYZEek4PqIlOtzQw3ObOKWNURFRLawUVTza4R+Jt9H0jLejvoJKU39TQ94= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=b3OlHNtQ; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=NEt44Klp; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="b3OlHNtQ"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="NEt44Klp" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67SKZj2u4122162 for ; Fri, 28 Aug 2026 21:37:59 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 6yZymeJtaZo5lERvmK0bkufR21pmFncW0lW87uQacK4=; b=b3OlHNtQDLxxWgkH vZlP6F9g/Yib2f3oKfIWTJex3sp5cnOeiBe7vG0+Bu8171znXyzSz5UFagBcefBQ dRZqPCUqNuU34WjVHP3QSHZFBg4xlw4545qoRVdPcp77Yx6M3r7b/dlcXbMorA5W 753v2QuVEkgCr7ApykfewqtkSWPIlHW5zZpsbx/Y+6ZhwGujgxLqhpI62yBFkmr9 thDvRPf7M1K3zdAPrx4R5DHTN6lcWU4XwWf9gFqR+3xly7RAgiumMRmWPuxxz6Nd GiKbl4ferOpecVHGyogmADW/BVzwbCQbSL5SqAZqgc2DR2/hWZaiC5pDL+u+yAnr Gi8oYA== Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gbhgq8599-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 28 Aug 2026 21:37:58 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-38e1118e4abso2474484a91.0 for ; Fri, 28 Aug 2026 14:37:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787953078; x=1788557878; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=6yZymeJtaZo5lERvmK0bkufR21pmFncW0lW87uQacK4=; b=NEt44KlpXlwDgNnmUE3bsh71d84a8h8mLRU9KPcrJM9RWwkPiaH7dd2+qL5GauQ/x8 6HSyC5z0LR2lNHMJCdw5JVgOJ+Rb7ezTK2nyab+xQEYPvNYUtIc7qIDqVYf/0vdQ6/+q 1ZRI8QPRdRkNGD/DTSU4Z55y+rG7IbYONuPYRh2IqEt81738btN+gUDpwIpAxNzeUoSe jYD3WcNBT6ADHZumFGvTmrav2IEv5az8wrEjr0YvFvxZHB0gMpa0RzBs23G7xIvQmfJD eU3heMXBukUDxrbm7423bPbtJnvnvoD/t6u7cgNbjtecVIxfAEhVUbTwdKFusGcIYW/Y LMzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787953078; x=1788557878; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=6yZymeJtaZo5lERvmK0bkufR21pmFncW0lW87uQacK4=; b=E2NRtuD0QCjAKeuy40wx3q1D1lhuFbQ6AMdCVwvII8UN3SEvQ0B3LH5reT1Y+VFsGe TFx+iZdhO1sfUNYIA9YLocmNYCgVzEbHiKt2xcs3nMK8YXEjtoJUQLbJm1yce2sD1lLA lFLI+LZ8Iq+FGh/US4W8eJ7fjEXz8DklguE/G3xRXuHnkx8KKg1N+VWuroyiz1Lc8Or3 aj/iz0aI/g7IEwky7M0/ZgSmaOnwKXFq9qB3mJScB1UxxAsBMguvGFzWkpo/WFcbxOMH ymsutPLOI6jcg4nitdBz6mIYmm2W/jrKmYRAxCyPK0pZlfuHY9BfPmYzhC7UdtmeFBr9 ZXGw== X-Forwarded-Encrypted: i=1; AKwUvBy0eBDxku+R85QKOJofZAAKnrbrf/STFbN61kO6b/N67wXECVhdAZbFG4Iv5HL4gVTzjIKyy/pyhx0JQxU=@vger.kernel.org X-Gm-Message-State: AFuF++lby3oDiIWIXmYiGkE7FJqoeXU0lDrUZK8OM1MSEztwXVFq8Vm8 Mr49zaBh8KrGmcLzpE2eyFMLGdwZDN/iUQjZssNs0A762Uq9E5a1zhWPuLT7zgflY2/PLtgFVfL FVX56zpl0LAieQllWebm4DBHh0Pjgen1w/mxAVQCMYa4+K0rkm6AIC4qNPYh6fXam+LQ= X-Gm-Gg: AYBFou2qA+q1R8f92jJPgpQ8TzdIFoylVL+vmVR2IGQqH6kaR1rHawPYg3+pHwOcE3c Nzdxvcag9vJXaMQ+4y1Yh2iUwFczGIRlNVlBgmG0JCEsMRCG5HLkUxOGk6aIBRWbz32Ba6rCGaD EHOzfx7LHa3j/eN3UfyhigUiO/JwGqLn7nuExV5D0KU3/cUSYAyp6gIYQX+zi1Bad9xtjbb83rf as6Ayh56noiBREkv/Q4hjXjjHjqcwI87ex06I4t+A/E+A9pXRViME7NGyp30DCGV4fec4hmt5Do X4F01tqlZ8PMdtIrjlkYN2rFu//nyqe1DQA2TuQdNoodVnuw7TNNT3ZEwv9CLQ1cM8WmU6QHXwH xzqpN0GJ0zQLpOSqubchH4ncf/VsVwnYOGhn7XFs68O3RZhg3OuXc X-Received: by 2002:a17:90b:3a45:b0:396:5785:843 with SMTP id 98e67ed59e1d1-396d0f09a46mr18686543a91.8.1787953077855; Fri, 28 Aug 2026 14:37:57 -0700 (PDT) X-Received: by 2002:a17:90b:3a45:b0:396:5785:843 with SMTP id 98e67ed59e1d1-396d0f09a46mr18686481a91.8.1787953077320; Fri, 28 Aug 2026 14:37:57 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e41837c6sm5892112c88.11.2026.08.28.14.37.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2026 14:37:56 -0700 (PDT) From: Wesley Cheng Date: Fri, 28 Aug 2026 14:37:53 -0700 Subject: [PATCH v2 1/4] xhci: sideband: fix ring sg table for sub-page TRB segments Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260828-16k_offload_v1_b4-v2-1-8a46369ebbb6@oss.qualcomm.com> References: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> In-Reply-To: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> To: Mathias Nyman , Greg Kroah-Hartman , Jaroslav Kysela , Takashi Iwai , Michal Pecio Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, Wesley Cheng X-Mailer: b4 0.15.2 X-Proofpoint-GUID: nELAIKCRLALj0c2_fUgmQz7jzSamdYPq X-Proofpoint-Spam-Info: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfXylYFL1hWfFg/ uEcXb4O7mnrplywNpml8KkISNM4cA/STytZqoC/Jz/V8GQdzlN5JfgCv6XbFK0wk8KWy8s1lr4g ptrbRXIWM4NuHQZsr/Bm8xfNYJq1utg= X-Proofpoint-ORIG-GUID: nELAIKCRLALj0c2_fUgmQz7jzSamdYPq X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfX4mHwALculn/5 Gyn7UiZv8vDvl/S8r0gHodsb4miv7Tv+BhT7qB+zjUkB9/Y7KovWKvFx3evJKWXmiTm/WrLDRSW 6Mw7kGADaJ50TJqq+U9Y83JtcujCMShooBoUJRb7ODlODaJfGFZpojYCDecMnZLDWpN0q1xV5iZ i12o0l/vvOcqA0qlKGtyiDopy8iCQlvDA7K5y/NU51fBuhp5kCKklslJOIvp2I6Puutwt64ULYL IO4LO1eDEB4J7qDhu45ABmPySrCeo72ug7GAOgnt4fZ0+3ucP8Br+TR8KtjX62xHl3WuHl00c7m VoAHRtnfRWV237gm/AdReAUKdU7VzWi5Legmm+WiT/oberdwmlaHDwx9ptbmi4EASZhq5seMkJO ZlIUHgSObP5M2jCUTSMeOgwFp+ZvyWxxL5L2yeSltNmYxnI4g0XSOu04KdfK/n8+h9jnEBwfUy6 wDOdHH8fWKvaLNHLVkQ== X-Authority-Analysis: v=2.4 cv=CsGPtH4D c=1 sm=1 tr=0 ts=6a91ffb6 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=aXGjAn6Wb1zARzc8srgA:9 a=QEXdDO2ut3YA:10 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-28_06,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 suspectscore=0 bulkscore=0 spamscore=0 malwarescore=0 impostorscore=0 adultscore=0 clxscore=1015 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608280188 xhci_ring_to_sgtable() sized its pages[] array from PAGE_ALIGN(sz) >> PAGE_SHIFT and always passed offset 0 to sg_alloc_table_from_pages(). Since TRB_SEGMENT_SIZE (4096) can be smaller than PAGE_SIZE, multiple ring segments can be packed into the same physical page, and the first segment can start at a nonzero offset within its page - PAGE_ALIGN(sz) undercounts the number of distinct pages actually needed in that case, and a hardcoded offset of 0 silently drops the first segment's true offset. Take max_t() against ring->num_segs so there's always at least one pages[] entry per segment, and capture the first segment's page offset from dma_get_sgtable() to pass to sg_alloc_table_from_pages() instead of assuming it's zero. Assisted-by: Claude:claude-sonnet-5Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Wesley Cheng --- drivers/usb/host/xhci-sideband.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideb= and.c index a5deeee4d5dc..1585c47720e0 100644 --- a/drivers/usb/host/xhci-sideband.c +++ b/drivers/usb/host/xhci-sideband.c @@ -24,10 +24,14 @@ xhci_ring_to_sgtable(struct xhci_sideband *sb, struct x= hci_ring *ring) struct device *dev; size_t sz; int i; + unsigned int first_seg_offset =3D 0; =20 dev =3D xhci_to_hcd(sb->xhci)->self.sysdev; sz =3D ring->num_segs * TRB_SEGMENT_SIZE; n_pages =3D PAGE_ALIGN(sz) >> PAGE_SHIFT; + + /* TRB_SEGMENT_SIZE may be smaller than PAGE_SIZE; need one entry per seg= ment */ + n_pages =3D max_t(unsigned int, n_pages, ring->num_segs); pages =3D kvmalloc_objs(struct page *, n_pages); if (!pages) return NULL; @@ -51,11 +55,13 @@ xhci_ring_to_sgtable(struct xhci_sideband *sb, struct x= hci_ring *ring) dma_get_sgtable(dev, sgt, seg->trbs, seg->dma, TRB_SEGMENT_SIZE); pages[i] =3D sg_page(sgt->sgl); + if (i =3D=3D 0) + first_seg_offset =3D sgt->sgl->offset; sg_free_table(sgt); seg =3D seg->next; } =20 - if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL)) + if (sg_alloc_table_from_pages(sgt, pages, n_pages, first_seg_offset, sz, = GFP_KERNEL)) goto err; =20 kvfree(pages); --=20 2.34.1 From nobody Sat Sep 26 22:02:22 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFAF6478E56 for ; Fri, 28 Aug 2026 21:38:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953085; cv=none; b=M3viZ7WWdblA5+zYHa3sYOgqCIOh5OLdWiqTgKbEnAOj8ho9fKZOHFz1c7BhsGTzmnMEnVC+67zFOhoDtjXvUprdrjB6D6HhASP+kiKwO6R3ynmzfx7hSDPgpnY6KAu9vR3j1s6LZr3m0eqQW/r7oPjZTEmK2Gh5i3LKecQkQ4w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953085; c=relaxed/simple; bh=3oWb2ED0DUimXzrvzTFETa03tehzQ1fBvx/hdYY/Hnw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lIos4/B7s6WEH4QZ5ynbN/Ck03LhHD4wBxEkShJtqdXkBDqRtN6+IWo8ovF9EJ1OQLyP5uQ93xhcbRlNF8UJsuWJYNnp1W1x9PkOh/fRc6OickoYNPODtPIWXkZiuUUHLaoLlTHpEEiG+uWotlYZncFTh9irUaQF6AhF/KvLr8s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=cYwm80qi; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=TvcXuUvb; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="cYwm80qi"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="TvcXuUvb" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67SJ71KM3674258 for ; Fri, 28 Aug 2026 21:38:00 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= edwmVF0kuFN7eYt2lxNi6cf3g1PHD1yZadeiuBsRrqE=; b=cYwm80qi8KCLUfNf 5m2MZqR7gdlY82qnBwno5eBNPIzPc/E24eJATmxQH6OU0zlQBoDGW4L9vdet20Za wgaKDDrwI0L/NTx6NWGafja2AnwL1knszWdQZ8AUb8RDf4B4jMRZpvkuiN2WwxnH iJXzDaL+IZNlg0qbGiHyvoBm590051XsCZsW8cfLgafjLm0MGnChZgr4GgjQD1xh BvL41VOIieZOOKWZS59Wyhv49yzpc8B19VkgnU+IQlB96y18ZIoa6zGh7apBP3QL uDyAet9q1bWgUiCAUNpwGKWtkhZKd0zrWA4QAsVj8qTyXAshDqKm6J0DGhmxPng3 Cs+/Ug== Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gb3hs3q7a-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 28 Aug 2026 21:38:00 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-38e475f83a2so2707573a91.1 for ; Fri, 28 Aug 2026 14:37:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787953079; x=1788557879; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=edwmVF0kuFN7eYt2lxNi6cf3g1PHD1yZadeiuBsRrqE=; b=TvcXuUvb1wFD48HLxhpdaKKpGWgFuerxAmJ2PtGotP3VAcUpu9ChfEgnZVwWusWMEn coeD0Q8CAZOBrR2kl8fRUwkEhGd2FM49icxpH+XUhMPEUsiiSN6P5ldQQAuliaQ6StEE YKL1nVZoZBG8/K1/OaC+NuYohn8wlqU+FJR7YX2TfqLilfwVKsQLO10APneWFJ1txOTc 9xDdEq/4Naxo5sTJS2LoApyqMaGN86ygaOpGIA6Lee3F5gJx95XUQ3fLwtCz4OaBDCle c3DUOs56AVb5GLIUjj/OaOBJVN5+6754Ef0BRoIjYoukhme0RftEq8XexUUFfQZls5sW jbQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787953079; x=1788557879; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=edwmVF0kuFN7eYt2lxNi6cf3g1PHD1yZadeiuBsRrqE=; b=Hh6F6ndl3m6/0ngIeeXEFuzJnmEdLZF+diP8SoeXof35crMGHKX8Pc19KDrWQwA/fC SkQ9bRJ4TtCc5N6B7uAMacoTaih5DqulieXezLu1TulpJqPL71wgvOGs6fPBmHLLFl/3 ldbOWwqzoLzkx6B3sLprIb+sCX6ziHSlNiorKxS594D8jVdiXRzILFQkoZ8MwMpBHy9c EcLe7jeFf4+OPmCmshY7jyaL/AVac9GK+KZgBhNNcZ0cB0+2XAhouPZr1ibYPQu3E6q+ GozSdmKiHpL0+4SRBpGN7RdC6c1+elGL9rGW7bx29L5mtdGCndhh6fq3mizyZDkjzFTm 4pHQ== X-Forwarded-Encrypted: i=1; AKwUvByNXSywlYXEXbgj36T2blFBy/Hd1hi5xooqwHg8GN2GmQxvj9aQLhbMc/gDAvZp+iVbY4WvABffscRsfU0=@vger.kernel.org X-Gm-Message-State: AFuF++kZAKQ7ANveNTFsapHhxXr4vC2BszNzJz1M5kTTlzWCbU0qFfnr Uvp9Yr2bp8Ro103mBWTHYUM6ykEwY2corimkFqwr10t0xAIo+Gd4xEdylCf0rd5uwhqpkjZCXV1 gFhvieH1Nt9r43NcOx539rkfzTsa5gngM18FtG8UUuBF7tdzJUEYH5tNDECd5qvyEQwQ= X-Gm-Gg: AYBFou0rjJFlJH6yU3/R7J53UMKQVPRhrbg3FuzpTd4i6GXqxg6lN57nS6GInFe4zlL nQ4VscSdxBZeQbMxecvSkdcKL5ScC/zggGtlcmCUHCKzsdJDxDCkqaPHGzAiXGn7IafQlGE2cfk oQ/C0v6uf5kNTQiZP9ks84aTeGwmP7knpV8hDkeyxXb3kTUifZK6cGPUp8abE5Z568JYOCCcrty d4e+KtzbS1RV5hAoIOibvPP85ALtq+wkJiW4TqIfsxUMAdV4H/FBYjZ1Mo3kGJHUudilhsrtszT WZmaiP6XS7CRSlq4Tl6fAHZ0YVNEAer9PDBLwPpeePFrJm9FRBkOhNTswFwMz2ndVzv2TnwokUl PcQZJG7TmSMrmyeFmxzfwf9H64pbefODBRC57C7DwZ7v0dDApyNpO X-Received: by 2002:a17:90b:4cd1:b0:398:9bd4:d12 with SMTP id 98e67ed59e1d1-3989bd40da3mr4340687a91.17.1787953078892; Fri, 28 Aug 2026 14:37:58 -0700 (PDT) X-Received: by 2002:a17:90b:4cd1:b0:398:9bd4:d12 with SMTP id 98e67ed59e1d1-3989bd40da3mr4340617a91.17.1787953078337; Fri, 28 Aug 2026 14:37:58 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e41837c6sm5892112c88.11.2026.08.28.14.37.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2026 14:37:57 -0700 (PDT) From: Wesley Cheng Date: Fri, 28 Aug 2026 14:37:54 -0700 Subject: [PATCH v2 2/4] usb: xhci: sideband: allocate sideband ring segments from a dedicated pool Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260828-16k_offload_v1_b4-v2-2-8a46369ebbb6@oss.qualcomm.com> References: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> In-Reply-To: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> To: Mathias Nyman , Greg Kroah-Hartman , Jaroslav Kysela , Takashi Iwai , Michal Pecio Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, Wesley Cheng X-Mailer: b4 0.15.2 X-Authority-Analysis: v=2.4 cv=XKYAjwhE c=1 sm=1 tr=0 ts=6a91ffb8 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=n6KXtLIYvygRVsXyBwEA:9 a=QEXdDO2ut3YA:10 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfX2tJQrr9xqZ8m VTSD9z11/14JIVRJvP26wfyRavFgbTYABvfumqrM9Es56HUV0e/4tOycrUJVdj9s6TKmRXHgh05 2sEBVLhc4ozfWfLU7zKAFajKc0mW5fKysNoYj24g/aeYYqJlecxEi4TEwW8nxOVy/v3MA/gsapN AjQ2trhjqnlEnBFrvt1qmG1wksBFAEusvkqEqjLsPQsQ8SdhxUeemre74KcyKUAAOLojJHkH3rH JwGPdhFmvxsMsCw85YtjgPYD9E4DNYXA10jh/RN8ewhlxbBItKRd6Pzkqb1xQUY5yPJMFwAg/wy bT/EMchndE6+tCw+8vBlxA17fOfWcQ2PLs5/SKroLGxHFykke/IqvZaFsgg8krMNIUVcwfiYr0h Zf3hgxk6hx+9elZdeU7AockE5AHIhbHvIe81BXHxT5FgrFBxzB3fxK2mt2Qvt6hzW1QQ+Wn1IIy DECLw9ZkOAr8/qjcU9Q== X-Proofpoint-Spam-Info: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfX7R36FlMcR6WA pB+fpbO9Q9BdKcoJQI9UBUL5Agp9A9ULPZ+X8gr9AN4TRTvLCE4nIWPO2xgLKG5I8GaMqYgPC+L 48xedlGHUJCJikaumi3RvSv2EgvvtlI= X-Proofpoint-GUID: OZI09DLQ_ucVJk-JAG-PExhqHw1bPlf8 X-Proofpoint-ORIG-GUID: OZI09DLQ_ucVJk-JAG-PExhqHw1bPlf8 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-28_06,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 lowpriorityscore=0 clxscore=1015 priorityscore=1501 bulkscore=0 adultscore=0 phishscore=0 suspectscore=0 impostorscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608280188 Ring segments are normally allocated from a shared DMA pool sized and aligned to TRB_SEGMENT_SIZE (4096 bytes). On kernels built with a larger PAGE_SIZE (e.g. 16K or 64K page arches), a segment can end up at a non-page-aligned offset within its enclosing CPU page, and multiple segments can share the same physical page. A sideband client that maps a ring buffer directly via the IOMMU (which operates at page granularity) needs to know exactly which page(s) back the ring, and only pages that are actually intended to be exposed to that client should ever be mapped this way. Give each xhci_sideband instance its own segment_pool, allocated separately from the core xhci->segment_pool, so every segment backing a sideband-tagged endpoint always comes from a page that is meant to be ADSP-visible. Normal (non-offloaded) endpoints are unaffected, as they keep allocating from xhci->segment_pool. Thread the pool to use through xhci_ring_alloc_from_pool(), xhci_alloc_interrupter() and xhci_create_secondary_interrupter(), and have xhci_endpoint_init() pick virt_dev->eps[ep_index].sideband's pool over xhci->segment_pool when the endpoint has already been tagged by xhci_sideband_add_endpoint(). Endpoint tagging always precedes ring allocation, since UAC streaming endpoints aren't allocated a ring until usb_set_interface() activates the streaming altsetting, well after the sideband client has already tagged them. Move EP_CTX_PER_DEV, TRBS_PER_SEGMENT and TRB_SEGMENT_SIZE into xhci-sideband.h as the shared canonical definitions, replacing the "FIXME defined twice" duplicate in xhci.h. Have xhci_sideband_register() take the segment pool as an argument instead of creating it internally, so the sideband client that actually consumes the pool (qc_audio_offload.c) owns its full lifetime: create it before xhci_sideband_register(), destroy it after xhci_sideband_unregister() or a failed register call. The client picks the DMA device the same way it already does elsewhere in that file (interface_to_usbdev(intf)->bus->sysdev) without needing an xhci-internal accessor for xhci->page_size. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Wesley Cheng --- drivers/usb/host/xhci-mem.c | 64 +++++++++++++++++++++++++----------= ---- drivers/usb/host/xhci-sideband.c | 14 +++++++-- drivers/usb/host/xhci.h | 14 ++++----- include/linux/usb/xhci-sideband.h | 22 +++++++++++++- sound/usb/qcom/qc_audio_offload.c | 21 +++++++++++-- 5 files changed, 100 insertions(+), 35 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 7a21ac81f9c8..bf7eb53abab9 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -15,6 +15,7 @@ #include #include #include +#include =20 #include "xhci.h" #include "xhci-trace.h" @@ -28,6 +29,7 @@ * "All components of all Command and Transfer TRBs shall be initialized t= o '0'" */ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci, + struct dma_pool *pool, unsigned int max_packet, unsigned int num, gfp_t flags) @@ -40,7 +42,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhc= i_hcd *xhci, if (!seg) return NULL; =20 - seg->trbs =3D dma_pool_zalloc(xhci->segment_pool, flags, &dma); + seg->trbs =3D dma_pool_zalloc(pool, flags, &dma); if (!seg->trbs) { kfree(seg); return NULL; @@ -50,7 +52,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhc= i_hcd *xhci, seg->bounce_buf =3D kzalloc_node(max_packet, flags, dev_to_node(dev)); if (!seg->bounce_buf) { - dma_pool_free(xhci->segment_pool, seg->trbs, dma); + dma_pool_free(pool, seg->trbs, dma); kfree(seg); return NULL; } @@ -62,10 +64,11 @@ static struct xhci_segment *xhci_segment_alloc(struct x= hci_hcd *xhci, return seg; } =20 -static void xhci_segment_free(struct xhci_hcd *xhci, struct xhci_segment *= seg) +static void xhci_segment_free(struct xhci_hcd *xhci, struct dma_pool *pool, + struct xhci_segment *seg) { if (seg->trbs) { - dma_pool_free(xhci->segment_pool, seg->trbs, seg->dma); + dma_pool_free(pool, seg->trbs, seg->dma); seg->trbs =3D NULL; } kfree(seg->bounce_buf); @@ -81,7 +84,7 @@ static void xhci_ring_segments_free(struct xhci_hcd *xhci= , struct xhci_ring *rin =20 while (seg) { next =3D seg->next; - xhci_segment_free(xhci, seg); + xhci_segment_free(xhci, ring->segment_pool, seg); seg =3D next; } } @@ -334,7 +337,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd= *xhci, struct xhci_ring struct xhci_segment *prev; unsigned int num =3D 0; =20 - prev =3D xhci_segment_alloc(xhci, ring->bounce_buf_len, num, flags); + prev =3D xhci_segment_alloc(xhci, ring->segment_pool, ring->bounce_buf_le= n, num, flags); if (!prev) return -ENOMEM; num++; @@ -343,7 +346,8 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd= *xhci, struct xhci_ring while (num < ring->num_segs) { struct xhci_segment *next; =20 - next =3D xhci_segment_alloc(xhci, ring->bounce_buf_len, num, flags); + next =3D xhci_segment_alloc(xhci, ring->segment_pool, ring->bounce_buf_l= en, + num, flags); if (!next) goto free_segments; =20 @@ -362,15 +366,10 @@ static int xhci_alloc_segments_for_ring(struct xhci_h= cd *xhci, struct xhci_ring return -ENOMEM; } =20 -/* - * Create a new ring with zero or more segments. - * - * Link each segment together into a ring. - * Set the end flag and the cycle toggle bit on the last segment. - * See section 4.9.1 and figures 15 and 16. - */ -struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_= segs, - enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) +static struct xhci_ring * +xhci_ring_alloc_from_pool(struct xhci_hcd *xhci, unsigned int num_segs, + enum xhci_ring_type type, unsigned int max_packet, + struct dma_pool *pool, gfp_t flags) { struct xhci_ring *ring; int ret; @@ -382,6 +381,7 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci= , unsigned int num_segs, =20 ring->num_segs =3D num_segs; ring->bounce_buf_len =3D max_packet; + ring->segment_pool =3D pool; INIT_LIST_HEAD(&ring->td_list); ring->type =3D type; if (num_segs =3D=3D 0) @@ -398,6 +398,20 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhc= i, unsigned int num_segs, return NULL; } =20 +/* + * Create a new ring with zero or more segments. + * + * Link each segment together into a ring. + * Set the end flag and the cycle toggle bit on the last segment. + * See section 4.9.1 and figures 15 and 16. + */ +struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, unsigned int num_= segs, + enum xhci_ring_type type, unsigned int max_packet, gfp_t flags) +{ + return xhci_ring_alloc_from_pool(xhci, num_segs, type, max_packet, + xhci->segment_pool, flags); +} + void xhci_free_endpoint_ring(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, unsigned int ep_index) @@ -422,6 +436,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct x= hci_ring *ring, new_ring.num_segs =3D num_new_segs; new_ring.bounce_buf_len =3D ring->bounce_buf_len; new_ring.type =3D ring->type; + new_ring.segment_pool =3D ring->segment_pool; ret =3D xhci_alloc_segments_for_ring(xhci, &new_ring, flags); if (ret) return -ENOMEM; @@ -1424,6 +1439,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, unsigned int mult; unsigned int avg_trb_len; unsigned int err_count =3D 0; + struct dma_pool *pool; =20 ep_index =3D xhci_get_endpoint_index(&ep->desc); ep_ctx =3D xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); @@ -1487,8 +1503,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, avg_trb_len =3D 8; =20 /* Set up the endpoint ring */ + pool =3D virt_dev->eps[ep_index].sideband ? + virt_dev->eps[ep_index].sideband->segment_pool : xhci->segment_poo= l; virt_dev->eps[ep_index].new_ring =3D - xhci_ring_alloc(xhci, 2, ring_type, max_packet, mem_flags); + xhci_ring_alloc_from_pool(xhci, 2, ring_type, max_packet, pool, mem_flag= s); if (!virt_dev->eps[ep_index].new_ring) return -ENOMEM; =20 @@ -2291,7 +2309,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xh= ci, gfp_t flags) } =20 static struct xhci_interrupter * -xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t fla= gs) +xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, + struct dma_pool *pool, gfp_t flags) { struct device *dev =3D xhci_to_hcd(xhci)->self.sysdev; struct xhci_interrupter *ir; @@ -2308,7 +2327,7 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigne= d int segs, gfp_t flags) if (!ir) return NULL; =20 - ir->event_ring =3D xhci_ring_alloc(xhci, segs, TYPE_EVENT, 0, flags); + ir->event_ring =3D xhci_ring_alloc_from_pool(xhci, segs, TYPE_EVENT, 0, p= ool, flags); if (!ir->event_ring) { xhci_warn(xhci, "Failed to allocate interrupter event ring\n"); kfree(ir); @@ -2356,7 +2375,8 @@ void xhci_add_interrupter(struct xhci_hcd *xhci, unsi= gned int intr_num) =20 struct xhci_interrupter * xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs, - u32 imod_interval, unsigned int intr_num) + struct dma_pool *pool, u32 imod_interval, + unsigned int intr_num) { struct xhci_hcd *xhci =3D hcd_to_xhci(hcd); struct xhci_interrupter *ir; @@ -2367,7 +2387,7 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd= , unsigned int segs, intr_num >=3D xhci->max_interrupters) return NULL; =20 - ir =3D xhci_alloc_interrupter(xhci, segs, GFP_KERNEL); + ir =3D xhci_alloc_interrupter(xhci, segs, pool, GFP_KERNEL); if (!ir) return NULL; =20 @@ -2498,7 +2518,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) if (!xhci->interrupters) goto fail; =20 - xhci->interrupters[0] =3D xhci_alloc_interrupter(xhci, 0, flags); + xhci->interrupters[0] =3D xhci_alloc_interrupter(xhci, 0, xhci->segment_p= ool, flags); if (!xhci->interrupters[0]) goto fail; =20 diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideb= and.c index 1585c47720e0..ec7d3859771c 100644 --- a/drivers/usb/host/xhci-sideband.c +++ b/drivers/usb/host/xhci-sideband.c @@ -10,6 +10,7 @@ =20 #include #include +#include =20 #include "xhci.h" =20 @@ -342,8 +343,8 @@ xhci_sideband_create_interrupter(struct xhci_sideband *= sb, int num_seg, return -EBUSY; =20 sb->ir =3D xhci_create_secondary_interrupter(xhci_to_hcd(sb->xhci), - num_seg, imod_interval, - intr_num); + num_seg, sb->segment_pool, + imod_interval, intr_num); if (!sb->ir) return -ENOMEM; =20 @@ -397,6 +398,11 @@ EXPORT_SYMBOL_GPL(xhci_sideband_interrupter_id); /** * xhci_sideband_register - register a sideband for a usb device * @intf: usb interface associated with the sideband device + * @type: xHCI sideband type + * @segment_pool: dma pool for sideband ring segments, created and owned by + * the caller. The caller must destroy it after calling + * xhci_sideband_unregister(). + * @notify_client: callback for xHCI sideband sequences * * Allows for clients to utilize XHCI interrupters and fetch transfer and = event * ring parameters for executing data transfers. @@ -405,6 +411,7 @@ EXPORT_SYMBOL_GPL(xhci_sideband_interrupter_id); */ struct xhci_sideband * xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type= type, + struct dma_pool *segment_pool, int (*notify_client)(struct usb_interface *intf, struct xhci_sideband_event *evt)) { @@ -426,6 +433,8 @@ xhci_sideband_register(struct usb_interface *intf, enum= xhci_sideband_type type, if (!sb) return NULL; =20 + sb->segment_pool =3D segment_pool; + mutex_init(&sb->mutex); =20 /* check this device isn't already controlled via sideband */ @@ -450,6 +459,7 @@ xhci_sideband_register(struct usb_interface *intf, enum= xhci_sideband_type type, =20 spin_unlock_irq(&xhci->lock); =20 + return sb; } EXPORT_SYMBOL_GPL(xhci_sideband_register); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c7bfa7f028d3..c91cba16abea 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -19,6 +19,7 @@ #include #include #include +#include =20 /* Code sharing between pci-quirks and xhci hcd */ #include "xhci-ext-caps.h" @@ -738,8 +739,6 @@ struct xhci_interval_bw_table { unsigned int ss_bw_out; }; =20 -#define EP_CTX_PER_DEV 31 - struct xhci_virt_device { int slot_id; struct usb_device *udev; @@ -1253,14 +1252,11 @@ static inline const char *xhci_trb_type_string(u8 t= ype) #define NEC_FW_MAJOR(p) (((p) >> 8) & 0xff) =20 /* - * TRBS_PER_SEGMENT must be a multiple of 4, - * since the command ring is 64-byte aligned. - * It must also be greater than 16. + * TRBS_PER_SEGMENT and TRB_SEGMENT_SIZE are defined in + * , shared with sideband client drivers. */ -#define TRBS_PER_SEGMENT 256 /* Allow two commands + a link TRB, along with any reserved command TRBs */ #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) -#define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) #define TRB_SEGMENT_SHIFT (ilog2(TRB_SEGMENT_SIZE)) /* TRB buffer pointers can't cross 64KB boundaries */ #define TRB_MAX_BUFF_SHIFT 16 @@ -1380,6 +1376,7 @@ struct xhci_ring { enum xhci_ring_type type; u32 old_trb_comp_code; struct radix_tree_root *trb_address_map; + struct dma_pool *segment_pool; }; =20 struct xhci_erst_entry { @@ -1865,7 +1862,8 @@ void xhci_free_port_bw_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_interrupter * xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs, - u32 imod_interval, unsigned int intr_num); + struct dma_pool *pool, u32 imod_interval, + unsigned int intr_num); void xhci_remove_secondary_interrupter(struct usb_hcd *hcd, struct xhci_interrupter *ir); void xhci_skip_sec_intr_events(struct xhci_hcd *xhci, diff --git a/include/linux/usb/xhci-sideband.h b/include/linux/usb/xhci-sid= eband.h index 005257085dcb..338146674a88 100644 --- a/include/linux/usb/xhci-sideband.h +++ b/include/linux/usb/xhci-sideband.h @@ -13,7 +13,19 @@ #include #include =20 -#define EP_CTX_PER_DEV 31 /* FIXME defined twice, from xhci.h */ +/* + * Constants shared with the xHCI host driver (drivers/usb/host/xhci.h), + * which includes this header for its canonical definitions. + */ +#define EP_CTX_PER_DEV 31 + +/* + * TRBS_PER_SEGMENT must be a multiple of 4, + * since the command ring is 64-byte aligned. + * It must also be greater than 16. + */ +#define TRBS_PER_SEGMENT 256 +#define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT * 16) =20 struct xhci_sideband; =20 @@ -59,6 +71,13 @@ struct xhci_sideband { /* Synchronizing xHCI sideband operations with client drivers operations = */ struct mutex mutex; =20 + /* + * Separate sideband segment pool for sideband rings, supplied by and + * owned by the sideband client: created before xhci_sideband_register() + * and destroyed after xhci_sideband_unregister(). + */ + struct dma_pool *segment_pool; + struct usb_interface *intf; int (*notify_client)(struct usb_interface *intf, struct xhci_sideband_event *evt); @@ -66,6 +85,7 @@ struct xhci_sideband { =20 struct xhci_sideband * xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type= type, + struct dma_pool *segment_pool, int (*notify_client)(struct usb_interface *intf, struct xhci_sideband_event *evt)); void diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_of= fload.c index e4bfd43a2488..1b8877b8ee62 100644 --- a/sound/usb/qcom/qc_audio_offload.c +++ b/sound/usb/qcom/qc_audio_offload.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -1786,6 +1787,7 @@ static void qc_usb_audio_offload_probe(struct snd_usb= _audio *chip) struct usb_interface_descriptor *altsd; struct usb_host_interface *alts; struct snd_soc_usb_device *sdev; + struct dma_pool *segment_pool; struct xhci_sideband *sb; =20 /* @@ -1804,10 +1806,19 @@ static void qc_usb_audio_offload_probe(struct snd_u= sb_audio *chip) if (!sdev) return; =20 - sb =3D xhci_sideband_register(intf, XHCI_SIDEBAND_VENDOR, + segment_pool =3D dma_pool_create("xHCI sideband ring segments", + interface_to_usbdev(intf)->bus->sysdev, + TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, + TRB_SEGMENT_SIZE); + if (!segment_pool) + goto free_sdev; + + sb =3D xhci_sideband_register(intf, XHCI_SIDEBAND_VENDOR, segment_pool, uaudio_sideband_notifier); - if (!sb) + if (!sb) { + dma_pool_destroy(segment_pool); goto free_sdev; + } } else { sb =3D uadev[chip->card->number].sb; sdev =3D uadev[chip->card->number].sdev; @@ -1844,7 +1855,9 @@ static void qc_usb_audio_offload_probe(struct snd_usb= _audio *chip) return; =20 unreg_xhci: + segment_pool =3D sb->segment_pool; xhci_sideband_unregister(sb); + dma_pool_destroy(segment_pool); uadev[chip->card->number].sb =3D NULL; free_sdev: kfree(sdev); @@ -1905,8 +1918,12 @@ static void qc_usb_audio_offload_disconnect(struct s= nd_usb_audio *chip) * This is to accommodate for devices w/ multiple UAC functions. */ if (chip->num_interfaces =3D=3D 1) { + struct dma_pool *segment_pool =3D dev->sb->segment_pool; + snd_soc_usb_disconnect(uaudio_qdev->auxdev->dev.parent, dev->sdev); xhci_sideband_unregister(dev->sb); + dma_pool_destroy(segment_pool); + dev->sb =3D NULL; dev->chip =3D NULL; kfree(dev->sdev->ppcm_idx); kfree(dev->sdev); --=20 2.34.1 From nobody Sat Sep 26 22:02:22 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9002478E49 for ; Fri, 28 Aug 2026 21:38:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953084; cv=none; b=JiuhIrgiWoS1YE3A4ruBbaiDIeOj5R7OBXiR24rYcVKMlIUZx1U8eSZXEwy6vD0wJS3NjdpCnPtlXuvl7K3HY4D64lJ6Bey6tYJAC2OVtONeSFcwIw4JUGIFLai/7MRIeJZg0sdaIsmva6Jctwzqp868yz/UOSHRFbJ1Yi4SkYI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953084; c=relaxed/simple; bh=uIuRToF6+GYeUp9B7mtrYh1Ht28jMpvmqqD4otUBEic=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pzYZbCfBeIf6dnx0ShxhjmASnooa2HcqN3QlTN4fAnzwCpjF7EflkUj7xYmGSAqm+bDvlVQ2jc5PMaaRz648ua/zIFcDmlOMo9HbwOYr+botMf6ud6UfAd9IjiEg+pVbf+dgdDW2Lq+3hyftaLDRYoVfibIYNiARz0lxm3Ylmi8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=LfscWWmg; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=T95E4Hk3; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="LfscWWmg"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="T95E4Hk3" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67SKZiB84122120 for ; Fri, 28 Aug 2026 21:38:01 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= abItBtmIQwjb67EQFY51LZAO+X7YMVVSbxtZU8hrtr0=; b=LfscWWmgywmJ+L06 quLxcxKpGSHQwY1IWXYpbR3YL4uBQqz79EPOUlAhBmzgYr5xXz3tZV2ZxsQtVNOX 0OBf5hrQ84mtDgf2yO/cJ4zJHS7+qpm+hhFvcFC68UCG+eIuy8eDx7d9HmhSlow6 q0xyITthKr62YKbVD55ATopXV0Ya9SxZ73YIzV9j1c2Ot+Jw30YAr+hHEhK59Izq tOqQ85/1jZgFXQHW3lHasEOOR42skokucqmDzkAjUhLeeAbd9zKDPcbGSBHyvxz2 JIzXSdngaeAM25obE0HQ3JPcrQBTR2fDiyPjAMLqBATrbn0jMXqNdbUdb0MVpia0 1YdNFw== Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gbhgq859e-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 28 Aug 2026 21:38:00 +0000 (GMT) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-38e11baa66eso2824281a91.2 for ; Fri, 28 Aug 2026 14:38:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787953080; x=1788557880; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=abItBtmIQwjb67EQFY51LZAO+X7YMVVSbxtZU8hrtr0=; b=T95E4Hk3q0AQDGiKD+su7DDaRI4MCQunnxyXoc207aVED609XA8C86pZugpIUdCEgy 49Hxna5P3WDkwltP3XM3EupfK9QiXLubnczX5+iFGLWXaych/Wlvt8QJbcrdtd/Jdpq8 ciL92nQvZzPLUTkQ6Ctgn5vfKUCPW1lSGt8P/wCR0VRf7YYly6hFOC1vvfeVoN7a66WA MhXIzA+mVVtxNi0jAx/S6/HaMximBV0XtvIAPkjCydSMT2jp3NEkBZ0e1qiKJgDrzOhy OgrM5tUZ7S86e8vDt4gBdnGYWDpFYyoyUhzR+PISoY8x75zUH2Q+nmxZWHzE3a5GYAkS ZEZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787953080; x=1788557880; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=abItBtmIQwjb67EQFY51LZAO+X7YMVVSbxtZU8hrtr0=; b=bZgfLQw18JZn5rThDz23jPMlXO/uQAIFlaD2MitZ219KX0VGsKihPaRbo6lT4QfNd1 pbkd6cc/MIu4fKZxIpuCMhQcPJzS5R+aYS87mnbWaCCV6hGIi84WF9oixW1zYrxFXZ9A 26Za/XnqmD59okpuZV/mk7oC2cwrM+5Ugn5qYfQuF0rmXLcWHwaj5yuvA+vXTuYy5mxD Jq08OKv+2uOmvbdsIlAgmgJvAdWWgkMxZUq63PYg0tXhh60OCN5Sc+Ue/q7qrcpoij9j nGCp1xoNcm+X4wp3YQnhU4J8cSZ7dBkrrdpc6upVKP6XrF4kgRznBEENoyl/a/ySa3wU /AWg== X-Forwarded-Encrypted: i=1; AKwUvBzJslWpxK1ecSPJ86+p5mI/gIROHdss+RGoZJujw0Gb0g7PIZXDYykEDNNfhE9sEWkwDdmTm0ca5SdEo7Y=@vger.kernel.org X-Gm-Message-State: AFuF++lTroCIJFQj8Xpc2CAfMk48NcefE4MoDZbS9oe/uHohFsCWcT15 IAz8FiYhILJNKPXUdM5fuCNgoFwaUwdv2zcwntaA0ROplm12gXLKvTA12E2ax1cDwppXkkGyWM/ kKmHfeBf4YQziyb3zS0XX+sRpfeq9GkGTFz1a7j/kJovUrf9YgYq/nFKo4SR1fkVO7os= X-Gm-Gg: AYBFou1cQDAr62LKx5lkQR9lxpmF01ToiVv2tlPxKQI1dhlftB9BXLfsJdUyxU1y7s2 32JUvCwUxsrtEJGlrzX/Nrxc458x+GF4q8hNhiGY1bLMEHwqLyiksA1kZ3PutuZT4n+W812lqqp zjuCYh4vq7MzjBaJTfvR+0jWhO0nhKT5UuV2EFZFjFqhoHV51GSso+L8+rCC2i91UikpHElbV1g rEUw7VctjYtAfVqdmtoOPhNEP7sS/G1MmL36Ilb3aOEU7DUHTQ/JBbbgpIUxF9UhmyH+GrntHZU /inHXCciZsHTkc6eVr+ji2p7vv71mIp3s1qeAHjoUBtUovA80Nv7x3zeB9klzp08MFzWWKZfa5j liYmRs3CoNPkl08TDZRjrEQ8DCmd1uleWOmac3anHhXREmQoQWRB7 X-Received: by 2002:a17:90b:2c88:b0:396:b98b:a3c2 with SMTP id 98e67ed59e1d1-396d0f52a0amr18763173a91.8.1787953079760; Fri, 28 Aug 2026 14:37:59 -0700 (PDT) X-Received: by 2002:a17:90b:2c88:b0:396:b98b:a3c2 with SMTP id 98e67ed59e1d1-396d0f52a0amr18763126a91.8.1787953079236; Fri, 28 Aug 2026 14:37:59 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e41837c6sm5892112c88.11.2026.08.28.14.37.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2026 14:37:58 -0700 (PDT) From: Wesley Cheng Date: Fri, 28 Aug 2026 14:37:55 -0700 Subject: [PATCH v2 3/4] ALSA: usb-audio: qcom: tag sideband endpoints before ring allocation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260828-16k_offload_v1_b4-v2-3-8a46369ebbb6@oss.qualcomm.com> References: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> In-Reply-To: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> To: Mathias Nyman , Greg Kroah-Hartman , Jaroslav Kysela , Takashi Iwai , Michal Pecio Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, Wesley Cheng X-Mailer: b4 0.15.2 X-Proofpoint-GUID: Btu75yIeGCiKM8UXVVnkQiHD5aNlFOgk X-Proofpoint-Spam-Info: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfX58O7/pCyGSUp T8iDyg149jS3h/1kfbM5zxQM8XjU6Tw3gwne5fyk1D+muCblcPUt8+eRXMgw6n/MugY2g55NZPd OErxmc/h5hbh9fw3OHQAVrOFtX8qhd8= X-Proofpoint-ORIG-GUID: Btu75yIeGCiKM8UXVVnkQiHD5aNlFOgk X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfXxbY/7tCR98tB KkRye2EKSYkieB/qjnnBj7rXzFnkkJ2nkcupcnVts0eNkRb7JolR0wOR99Q7gJ704tVUZLT/U+K a4FYXMqjVEoIai0GU8kc08R0XYRMwYh7oeMqC1Y4c7D/dMxrQiJcql2Zbo7hARZIAM2jQi0OPsj mJWegmpwExkL990Vp6+Tq17BbfEj2lVWs4RbWH9SMhaqyw2tAszImYZNbkbAyEIGGUWTYrul1ES M+wOvc+LXxHC0qEeII6ZwcmpmUfEf+/fcXVQFJxFL5h07NLw5TDqn8HnwagfL+yip21L/d4JAIS iLy3lgHjGUlmbkuHKT0M2ZZ3sLjDGXhYB5ct8WMBsuiN8P4S4bWBW36v1PuPyHRnUu0N6fmeOTu 5hptCoa3dxNaq9xSWniMHzco8/EvK5QI1D00Dvn7ur3yc/5La1GrbVarcX6wjQAWMq0+clzr643 iSrRe18TsmadFwUQ7Hw== X-Authority-Analysis: v=2.4 cv=CsGPtH4D c=1 sm=1 tr=0 ts=6a91ffb8 cx=c_pps a=vVfyC5vLCtgYJKYeQD43oA==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=CbMfP9IJxQ5wjS32uxIA:9 a=QEXdDO2ut3YA:10 a=rl5im9kqc5Lf4LNbBjHf:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-28_06,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 suspectscore=0 bulkscore=0 spamscore=0 malwarescore=0 impostorscore=0 adultscore=0 clxscore=1015 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608280188 xhci_endpoint_init() picks the ring's segment pool based on whether the endpoint has already been tagged via xhci_sideband_add_endpoint(): sideband-tagged endpoints get their ring allocated from the sideband's own segment_pool instead of the shared xhci->segment_pool, so the buffer reported to the ADSP over QMI is guaranteed to come from a page meant to be ADSP-visible. xhci_sideband_add_endpoint() must therefore run before the endpoint's transfer ring is first allocated (i.e. before snd_usb_endpoint_prepare() triggers xhci_endpoint_init()) for that pool selection to apply to the first allocation. Move the xhci_sideband_add_endpoint() calls out of uaudio_endpoint_setup() and into enable_audio_stream(), before snd_usb_endpoint_prepare() is called for the data and sync endpoints, and unwind them on the new error paths. At that point in the setup sequence dev->ep_in[]/ep_out[] are not yet populated, since the endpoint's altsetting has not been activated, so usb_pipe_endpoint() cannot be used to find the usb_host_endpoint. Add uaudio_find_host_endpoint(), which resolves it directly from the interface's altsetting descriptor table instead. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Wesley Cheng --- sound/usb/qcom/qc_audio_offload.c | 93 +++++++++++++++++++++++++++++++++--= ---- 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_of= fload.c index 1b8877b8ee62..bd3f84a3652b 100644 --- a/sound/usb/qcom/qc_audio_offload.c +++ b/sound/usb/qcom/qc_audio_offload.c @@ -942,6 +942,45 @@ static void uaudio_dev_release(struct kref *kref) wake_up(&dev->disconnect_wq); } =20 +/** + * uaudio_find_host_endpoint() - look up usb_host_endpoint for a snd_usb_e= ndpoint + * @subs: usb substream owning the target snd_usb_endpoint + * @endpoint: sync or data snd_usb_endpoint to resolve + * + * usb_pipe_endpoint() resolves via dev->ep_in[]/ep_out[], which are only + * populated once usb_set_interface() has activated the endpoint's altsett= ing + * (i.e. after snd_usb_endpoint_prepare() has run for it). Looking that up + * beforehand returns NULL. + * + * Instead, look the endpoint up directly in the interface's altsetting + * descriptor table, which is populated once at enumeration time and stays + * valid regardless of which altsetting is currently active. + * + * Return: matching usb_host_endpoint, or NULL if not found. + */ +static struct usb_host_endpoint * +uaudio_find_host_endpoint(struct snd_usb_substream *subs, + struct snd_usb_endpoint *endpoint) +{ + struct usb_host_interface *alt; + struct usb_interface *iface; + int i; + + iface =3D usb_ifnum_to_if(subs->dev, endpoint->iface); + if (!iface) + return NULL; + + alt =3D usb_altnum_to_altsetting(iface, endpoint->altsetting); + if (!alt) + return NULL; + + for (i =3D 0; i < alt->desc.bNumEndpoints; i++) + if (alt->endpoint[i].desc.bEndpointAddress =3D=3D endpoint->ep_num) + return &alt->endpoint[i]; + + return NULL; +} + /** * enable_audio_stream() - enable usb snd endpoints * @subs: usb substream @@ -959,8 +998,9 @@ static void uaudio_dev_release(struct kref *kref) static int enable_audio_stream(struct snd_usb_substream *subs, snd_pcm_format_t pcm_format, unsigned int channels, unsigned int cur_rate, - int datainterval) + int datainterval, unsigned int card_num) { + struct usb_host_endpoint *data_ep =3D NULL, *sync_ep =3D NULL; struct snd_pcm_hw_params params; struct snd_usb_audio *chip; struct snd_interval *i; @@ -998,17 +1038,47 @@ static int enable_audio_stream(struct snd_usb_substr= eam *subs, goto detach_ep; } =20 + data_ep =3D uaudio_find_host_endpoint(subs, subs->data_endpoint); + if (!data_ep) { + dev_err(&subs->dev->dev, "data ep # %d not found\n", + subs->data_endpoint->ep_num); + ret =3D -ENODEV; + goto detach_ep; + } + + ret =3D xhci_sideband_add_endpoint(uadev[card_num].sb, data_ep); + if (ret < 0) { + dev_err(&subs->dev->dev, + "failed to add data ep to sec intr: %d\n", ret); + goto detach_ep; + } + if (subs->sync_endpoint) { + sync_ep =3D uaudio_find_host_endpoint(subs, subs->sync_endpoint); + if (!sync_ep) { + dev_err(&subs->dev->dev, "sync ep # %d not found\n", + subs->sync_endpoint->ep_num); + ret =3D -ENODEV; + goto remove_data_ep; + } + + ret =3D xhci_sideband_add_endpoint(uadev[card_num].sb, sync_ep); + if (ret < 0) { + dev_err(&subs->dev->dev, + "failed to add sync ep to sec intr: %d\n", ret); + goto remove_data_ep; + } + ret =3D snd_usb_endpoint_prepare(chip, subs->sync_endpoint); if (ret < 0) - goto detach_ep; + goto remove_sync_ep; } =20 ret =3D snd_usb_endpoint_prepare(chip, subs->data_endpoint); if (ret < 0) - goto detach_ep; + goto remove_sync_ep; =20 - dev_dbg(uaudio_qdev->data->dev, + dev_dbg(&subs->dev->dev, "selected %s iface:%d altsetting:%d datainterval:%dus\n", subs->direction ? "capture" : "playback", subs->cur_audiofmt->iface, subs->cur_audiofmt->altsetting, @@ -1020,6 +1090,11 @@ static int enable_audio_stream(struct snd_usb_substr= eam *subs, =20 return 0; =20 +remove_sync_ep: + if (sync_ep) + xhci_sideband_remove_endpoint(uadev[card_num].sb, sync_ep); +remove_data_ep: + xhci_sideband_remove_endpoint(uadev[card_num].sb, data_ep); detach_ep: snd_usb_hw_free(subs); =20 @@ -1141,14 +1216,6 @@ uaudio_endpoint_setup(struct snd_usb_substream *subs, =20 memcpy(ep_desc, &ep->desc, sizeof(ep->desc)); =20 - ret =3D xhci_sideband_add_endpoint(uadev[card_num].sb, ep); - if (ret < 0) { - dev_err(&subs->dev->dev, - "failed to add data ep to sec intr: %d\n", ret); - ret =3D -ENODEV; - goto exit; - } - sgt =3D xhci_sideband_get_endpoint_buffer(uadev[card_num].sb, ep); if (!sgt) { dev_err(&subs->dev->dev, @@ -1638,7 +1705,7 @@ static void handle_uaudio_stream_req(struct qmi_handl= e *handle, ret =3D enable_audio_stream(subs, map_pcm_format(req_msg->audio_format), req_msg->number_of_ch, req_msg->bit_rate, - datainterval); + datainterval, pcm_card_num); =20 if (!ret) ret =3D prepare_qmi_response(subs, req_msg, &resp, --=20 2.34.1 From nobody Sat Sep 26 22:02:22 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4302A3C870E for ; Fri, 28 Aug 2026 21:38:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953085; cv=none; b=cD1o22g9f9ecknURWe2ONSSj/Iv26WtHeTizifvyoxziECZuS46kVtCMZMwK2qi3fgiDKciexNwBPICO9hQvAcVPMAdKRFO3AoSDEd0cLFQXHLnIdkNgqZbu97Vbp6jpXgLHHYt2DyS6fESLdwQlNsBrSnr0267tkUJyXorm+38= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787953085; c=relaxed/simple; bh=FNQrozwGe9BoZpI4GBh5WAtDpvMJBU/Pn6W9l/5qiAw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rr0Zl4OovGnTlewcFBs5c3fwytT7HDV2R8D5vgkG6BDXPDtB+87pmb6bLHfiraObFElMIDE5FdW3fCaoCZ5Y4oxOa20OqyV+sNTnXjBMMUIVjRsXBCOyot3ViuKYoaIgBg7OpWxtlm2zFkWq1tZGeOyLupBdqNx+uPNtQ8HsDQs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=d/XmdU09; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=i9zoPMhV; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="d/XmdU09"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="i9zoPMhV" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67SJqcOU3878222 for ; Fri, 28 Aug 2026 21:38:02 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 0Rz0iVeAXXDDxoPKkN9pDDWOnBof2/EJ5U0hjC8lqJM=; b=d/XmdU09pZ8yo+nc TzCjIY/b0FiYQ2jWxVcxxDyNwp4eQQqWHZFiySbnE+lQnwOTRv21/WRjWMJngE0w DOb6AzTk8Q7GNX5blHDqBzMYNHHwGbiUnHAu5ghKiw2VdHM6LRS5mQQkPxAf5W6t ICd08KNVa7ez5tXLhHU2pPbSZEazlucx4/gwdKuNpn2jsxlPZR9a3hUL/x/tcgIQ 0gcQw7ruUahoA8T62r+RWZ3UBOw/7ncQxN3chHupUtHTZVC1A+Acj5p+k0mSUHLx 3qzBlDFezDSyxFrHPmyRmfqiEK/DbNOWkl0QsLmwYtZddHR8V5yYr4YGKPb903SV 9OqXeQ== Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gbgvfg8eb-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 28 Aug 2026 21:38:02 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-396901263b6so2322986a91.2 for ; Fri, 28 Aug 2026 14:38:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1787953081; x=1788557881; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=0Rz0iVeAXXDDxoPKkN9pDDWOnBof2/EJ5U0hjC8lqJM=; b=i9zoPMhV06IBzHtgqjABBfgEZcVbK/U762KKDEpZqa+YPJJGWxJeok4I0udrfaOc2q bkvhNQRSPd+wbGgnWKyFq2EdgeZwMSWl7Xy23juzhj3ljqjgwGHq8lcoqjklkKRHqRqI Ayj+HYvxYpBbSzUnLw4jjT9QG3mIv7PADmxsRBY4LLfslErdUW1BqxwxkfeTUeCooSyn 9fID19NlR1ZdgKQB+fPaN3eW/olqmPmv2Qon9Baabo3pAxa8MCdeQtxcDTwVqV34wx9h CXgHzF8Ch6vqeEm9m4Vc3eRmSwe27UEe6WNhg9o9cCvFFiDSrUG16gIaZ0kgRTQfQcqO 7D2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787953081; x=1788557881; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=0Rz0iVeAXXDDxoPKkN9pDDWOnBof2/EJ5U0hjC8lqJM=; b=ThBEJRmnKZEqpFS2KDqtUEHPAcGjfl8EFrsUWCJRgAbGLdfm9xR6QXOLxGGQo2hrGL Q5nrAwpm84GZRptqGZIeyhRqmB00bHehufnsAG26ojuUQY4QBSNSuV+snldqtug+jJ8F /7AI3bLt8a2braTylF2fC5x8/U7BgotD2T4NmEcdYjxffmhs4BHyJMJMUSkS/yA9EsWC cN5jY4ESplB3ayzuy96yidrmmBDUcrtL+7B6DUXqMNJpr3ChHgUKoPBe6KzX8mpcd225 tmUlcX3H23SwLJjWCDvqTd1Jitt2hwLLRpSYSf8esLEYdmqortsyvl9EVB3oWkSAvz0X zggg== X-Forwarded-Encrypted: i=1; AKwUvBxK+W3ETo4o/xd07ZuXLjNbnqGSeTRsRwJCNPaMIBUJUkGykptXqtNfIMuwACGw/Z35jspvNc/he94r9mE=@vger.kernel.org X-Gm-Message-State: AFuF++kkBRGmqs15Rvh/pgRShZNbXiFg4JKAzhMRYpE0XX439yX+xq6o O+EIb8xVvSrKns+yRqSUZJytmqZU6W+FPDMEpvl5YcAdzkFD7YRWBUi775T7GI5giLwKGNNjBhT kAIADNYvl7H/6AD1RN9kr9ry45O7Ilox1vwkgPKoYev7uqzNOHrwn5QaOEZfLohS450w= X-Gm-Gg: AYBFou3J6q1TOYQviIyibTg6+Xpwab9j0kIudGmEJllaNTnb9rIX2uWk9i7AcsKvLP/ PHFx1cuo2u27y1C2QZSBQ6obqBb7JmaRbS8rfEwpzmkytcxj6eXWk7Nbmo4L467JYwDoK64GbO3 /12mt3zCognKBq/5qgiZVUTItXbD6I9HvONg8Qn4E19Dgy/wFuEgThmooIcsqDlxIY7mdUXMRmx Im2bZF5/Qs6nwKoL0CAV53s6N79ApJLkzu+YAVfmuB2OolKT6nS8pHhSGuccRSnfjEP3xhACrPR mnMRMsecdBnMPG1c7Qp+ZH6HUZLx2yfM7KLf0EDbjNucNkJlzJsKPDMEMjU6b/rb6E4mr+Rn5rP TuLO8dtp1KTUzjLhM667Yndyn8TLE9uj0Fjc4DDJUI4i2GYzXdDyN X-Received: by 2002:a17:90b:3a05:b0:398:9be8:ea69 with SMTP id 98e67ed59e1d1-3989be8ead8mr4014475a91.22.1787953081159; Fri, 28 Aug 2026 14:38:01 -0700 (PDT) X-Received: by 2002:a17:90b:3a05:b0:398:9be8:ea69 with SMTP id 98e67ed59e1d1-3989be8ead8mr4014412a91.22.1787953080676; Fri, 28 Aug 2026 14:38:00 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-142e41837c6sm5892112c88.11.2026.08.28.14.37.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2026 14:37:59 -0700 (PDT) From: Wesley Cheng Date: Fri, 28 Aug 2026 14:37:56 -0700 Subject: [PATCH v2 4/4] ALSA: usb-audio: qcom: fix xfer ring IOMMU unmap on 16K+ page kernels Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260828-16k_offload_v1_b4-v2-4-8a46369ebbb6@oss.qualcomm.com> References: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> In-Reply-To: <20260828-16k_offload_v1_b4-v2-0-8a46369ebbb6@oss.qualcomm.com> To: Mathias Nyman , Greg Kroah-Hartman , Jaroslav Kysela , Takashi Iwai , Michal Pecio Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, Wesley Cheng X-Mailer: b4 0.15.2 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfX2lavZsACly0f bHeKp/itb3N7mEcs9Diqjz5HKbXqAhJFPsQ5+9/oBSq9xM9GoVjIJ4z4VTMdCvSQYKbBLXbn8Jl KyOZteoN5tV9VY653b7ZaQAeHB+GR5hHNq9I/OEUKafTI/f9A6kSK2GnGKa/4EMbgFF3kqR5KdU cTXq8nGtZxBAeATZVuVQhg47QJ1fC7vb/xJHIWrp7N4swEg3S+ql9goeXI6IWMdEuWWA3AQVKUk LbFmxajBD7HgtqdteW8111+UR0SMQbHA/xmpzGyg0I8GXev+lHFfwydUA2S/2tK2aX0oPN8jEKh 8wIhhGkZXyLx/sUUJqxvqbJTl2e8tmkARFr1aRtMV+wEvYt0Tki5kmCr1UaXnqcbXY5DF8Vni+6 sVIcbMWYcQscDJoT0RttpyMn9ZdI+P4HmOO10AqCUgdShkilbyPhhd51pVN4DmSwQvJ3SITwQLH O2DfL8DdqevxT2JrJTQ== X-Proofpoint-ORIG-GUID: bj5i2oszPMximBj31V4GWGf-9hdZxx4A X-Authority-Analysis: v=2.4 cv=UcthjqSN c=1 sm=1 tr=0 ts=6a91ffba cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=4X7XonqLFEBPzPt-dYYA:9 a=QEXdDO2ut3YA:10 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODI4MDE4OCBTYWx0ZWRfX4+6m03zVcBqd e4wrA5Fpoe3zlJUykKemQpgfuSLlv7gnSGP+wpLo61v3SUHoifbFfQ3bgPheh+DYfxZ2B0Aq8oy ePnUNgewuhO5iTSBVAp7/LzDd9TksBU= X-Proofpoint-GUID: bj5i2oszPMximBj31V4GWGf-9hdZxx4A X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-28_06,2026-08-27_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 lowpriorityscore=0 bulkscore=0 adultscore=0 clxscore=1015 priorityscore=1501 impostorscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608280188 TRB_SEGMENT_SIZE is hardcoded to 4096 bytes, but on kernels built with a larger PAGE_SIZE (e.g. 16K or 64K page arches) the IOMMU still maps and unmaps in units of PAGE_SIZE. A ring segment's physical page can therefore start at a non-page-aligned offset relative to the segment itself, and the DMA address handed back for the ring (sg_dma_address()) carries that same intra-page offset. Add that offset back onto the mapped iova before sending it to the ADSP over QMI, so the reported address resolves to the start of the segment rather than the start of its containing page, and report the true TRB_SEGMENT_SIZE instead of PAGE_SIZE as the ring size. This broke the reverse direction: recovering the raw, page-aligned iova for iommu_unmap() by masking off the low PAGE_SIZE bits of the QMI-reported iova only works if that iova happens to already be page-aligned before the offset was added, which is not guaranteed. Add RING_IOVA_BASE(), which instead subtracts the exact offset that was added at setup time, and use it for both the cached data/sync_xfer_ring_va and the drop_sync_ep/drop_data_ep unmap error paths. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Wesley Cheng --- sound/usb/qcom/qc_audio_offload.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_of= fload.c index bd3f84a3652b..d6e4bcaa7239 100644 --- a/sound/usb/qcom/qc_audio_offload.c +++ b/sound/usb/qcom/qc_audio_offload.c @@ -58,6 +58,8 @@ #define PREPEND_SID_TO_IOVA(iova, sid) ((u64)(((u64)(iova)) | \ (((u64)sid) << 32))) #define IOVA_MASK(iova) (((u64)(iova)) & 0xFFFFFFFF) +/* recover the raw xfer ring iova by subtracting the intra-page offset add= ed at setup */ +#define RING_IOVA_BASE(mem) (IOVA_MASK((mem).iova) - ((mem).dma & ~PAGE_MA= SK)) #define IOVA_BASE 0x1000 #define IOVA_XFER_RING_BASE (IOVA_BASE + PAGE_SIZE * (SNDRV_CARDS + 1)) #define IOVA_XFER_BUF_BASE (IOVA_XFER_RING_BASE + PAGE_SIZE * SNDRV_CARDS = * 32) @@ -1238,8 +1240,10 @@ uaudio_endpoint_setup(struct snd_usb_substream *subs, goto clear_pa; } =20 - mem_info->iova =3D PREPEND_SID_TO_IOVA(iova, uaudio_qdev->data->sid); - mem_info->size =3D PAGE_SIZE; + /* add intra-page offset so DSP IOVA resolves to the correct 4K slot */ + mem_info->iova =3D PREPEND_SID_TO_IOVA(iova + (mem_info->dma & ~PAGE_MASK= ), + uaudio_qdev->data->sid); + mem_info->size =3D TRB_SEGMENT_SIZE; =20 return 0; =20 @@ -1307,8 +1311,10 @@ static int uaudio_event_ring_setup(struct snd_usb_su= bstream *subs, goto clear_pa; } =20 - mem_info->iova =3D PREPEND_SID_TO_IOVA(iova, uaudio_qdev->data->sid); - mem_info->size =3D PAGE_SIZE; + /* add intra-page offset so DSP IOVA resolves to the correct 4K slot */ + mem_info->iova =3D PREPEND_SID_TO_IOVA(iova + (mem_info->dma & ~PAGE_MASK= ), + uaudio_qdev->data->sid); + mem_info->size =3D TRB_SEGMENT_SIZE; =20 return 0; =20 @@ -1547,10 +1553,10 @@ static int prepare_qmi_response(struct snd_usb_subs= tream *subs, =20 /* cache intf specific info to use it for unmap and free xfer buf */ uadev[card_num].info[info_idx].data_xfer_ring_va =3D - IOVA_MASK(resp->xhci_mem_info.tr_data.iova); + RING_IOVA_BASE(resp->xhci_mem_info.tr_data); uadev[card_num].info[info_idx].data_xfer_ring_size =3D PAGE_SIZE; uadev[card_num].info[info_idx].sync_xfer_ring_va =3D - IOVA_MASK(resp->xhci_mem_info.tr_sync.iova); + RING_IOVA_BASE(resp->xhci_mem_info.tr_sync); uadev[card_num].info[info_idx].sync_xfer_ring_size =3D PAGE_SIZE; uadev[card_num].info[info_idx].xfer_buf_iova =3D IOVA_MASK(resp->xhci_mem_info.xfer_buff.iova); @@ -1585,13 +1591,14 @@ static int prepare_qmi_response(struct snd_usb_subs= tream *subs, drop_sync_ep: if (subs->sync_endpoint) { uaudio_iommu_unmap(MEM_XFER_RING, - IOVA_MASK(resp->xhci_mem_info.tr_sync.iova), + RING_IOVA_BASE(resp->xhci_mem_info.tr_sync), PAGE_SIZE, PAGE_SIZE); xhci_sideband_remove_endpoint(uadev[card_num].sb, usb_pipe_endpoint(subs->dev, subs->sync_endpoint->pipe)); } drop_data_ep: - uaudio_iommu_unmap(MEM_XFER_RING, IOVA_MASK(resp->xhci_mem_info.tr_data.i= ova), + uaudio_iommu_unmap(MEM_XFER_RING, + RING_IOVA_BASE(resp->xhci_mem_info.tr_data), PAGE_SIZE, PAGE_SIZE); xhci_sideband_remove_endpoint(uadev[card_num].sb, usb_pipe_endpoint(subs->dev, subs->data_endpoint->pipe)); --=20 2.34.1