From nobody Sat Sep 26 06:32:32 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 DC1EE35839C for ; Fri, 4 Sep 2026 06:58:07 +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=1788505089; cv=none; b=JUYqIKZiPsLvdkNdP7vzEHMrpVe5ndaty8S43MdFyVro6TnJTQQPkwq/3y2TM2CGb3TJK/XnFQy+kTvoiyU3cQQn02ZpnxmZfeUjr7peyVUfPJAbTtgA/YVXkoobewddf4EODf7IMpLELulj6L9fjjwT0Xs1xE/RuqoztBoZWwE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788505089; c=relaxed/simple; bh=MC8RF8exbnRdyxfzrjSNLOlOV7Cnba1woExTrACXBa8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=i5hzYCJybTgq5OPJV+QQZzV4J9NppB7nqs7uHUxFgULatIMc7uE1b2D0Nix49sB7IvyMivQQdW50fbVgA2NYr/2wWHiuWX6uMrD9Ht78y8w2XdeFnEeVPS2IaP6ZCXkkeTv3DjhFn9qWECbKBD2XluZkFVhYnH4KplWze79K/SA= 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=JPF64rvP; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=WgZziDPq; 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="JPF64rvP"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="WgZziDPq" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68462gi02125272 for ; Fri, 4 Sep 2026 06:58:07 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= qLcKeVUAGDAqIIR+NcT+dw/2isBatO7SL2E+KRjKb9M=; b=JPF64rvP1YU48bat gpLVWml1fLZ03YMZhx7M+tEUF/S9QB7lrPYtK/oyiKTGOfzWDg3Wux5evgFHPNA4 JbkozSRW3FyJ9ramd4hH8AMBNRyH7XMOUGQ92BwIgrGTKt3o4tfOeYY38aosMBhq 9u4ahSd/YSmvHKAsMMhJKvj8khnaVPg1RXlLAX4MC690jv+3ikp+39YYqbvzJinU 6j0iL+IHz3UNACEip0mENQT6DVPz5e2zcMam4BsoB0lCe4YURTQ1187/LAqb+dJP 3UIVCOHVC+d7R95QVIkDcg8DRsDjH6akkQYH7jWmSN1CqaprF9fk/j8RUojzs8GG 6sSvSQ== Received: from mail-pg1-f200.google.com (mail-pg1-f200.google.com [209.85.215.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gfp1fgm73-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 04 Sep 2026 06:58:06 +0000 (GMT) Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-cbb467e56aaso714742a12.1 for ; Thu, 03 Sep 2026 23:58:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1788505086; x=1789109886; 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=qLcKeVUAGDAqIIR+NcT+dw/2isBatO7SL2E+KRjKb9M=; b=WgZziDPqTZPQZYRF3UZY8XNxWTbI5yVu/dHuS5u85ibe/st6qp9v4H3rtnfMAp0umy 3EiHIcplqSGgxU6zA01MTrgHxIo8Tg7R/Y3C0XCRasWOu6R+wd2lIbWsqzPkztqBH/uq KYh1/V6z2fg0EhHcwWjgSEgW1V25SdH30/dI1FapwTF4QfI90XNuFTvMrf5QxgPWT4+3 XIv5F25mFDWASA6RkaKWIX7ZdLk7YXs5HFKflj+heUug0SaYwQW+LPYxrAkqlThK5PG5 AEQeObO+FI/5s/C9KysC8EPxviriDkieHbWiEXIyhIauQHRfny2EKO5Mpgl3KxOICNaP hddg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788505086; x=1789109886; 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=qLcKeVUAGDAqIIR+NcT+dw/2isBatO7SL2E+KRjKb9M=; b=Jpgx7dvogxQfIictPgsExTw07ssTZULLdVeYNShjrLB1k/+clQPbbfxJb/75Urku0l aUF9U2KWkZYJSLR3L+n7HWS1RuJRLdybJZQBJnHAUC/VbZFQGatt3ecVVjFYwJqY3ZGF B2qk2BHVyBU2b2tdlof1dxsy//Ro939NAOjd7DkqLuRuSttaCO9V/rTY3sAvakmcCej0 ooj1gKKM2NsUxC5s2XSw0K+D4xS0C8UKRNoDGAstNaplCgqGsD9eKOPWEKlHgdx4DLr/ fnimpyR3KsK9Dg83fYeuOtZREl6GowgnntxQMXS0/vhO79ykTr3RhnyMs48ERSyM5w5C 8UrQ== X-Forwarded-Encrypted: i=1; AKwUvByprYkkO712h68jMR89E0/JhQ7436KvoHfu1kgY6C873sY1lM5FQ/MTTjzH9+kA4SbT1FYwfNcnyuy8z9w=@vger.kernel.org X-Gm-Message-State: AFuF++mxXOz3OesvyweTmneIO9mCvgrGcc+9CvMRveJdysqWFK0ZERTX LmdqrTXx0eXab6f7zzx15u36YRpnqBtRpVoKqBImSnI/HsFyKGO9vKLHxQoA0FfwSVIGkFpbZWX aAtgTRK+QfajCbibOY+oKIQxtB/qXoUWh2M/vrFbg+Jy7qWuZbFUpLBlqudBdQyZ036o= X-Gm-Gg: AYBFou0wTvKtmjPRsRxt4z2WIzze2mbDC02hK7nVRuwyV307ESZIZcK/ec9fLy4uTSk i+nPvaHzGVJ8pR/M6YYkxwYsnoUql2MTYGp1f82DNLoJGo+v8r3BOdFAVjI8pPp3bI6n9UnCYmT r/hLukHTij66sHa6uLUtQLRcoQLsPWgV7DlkfjIC6HT9WQG53sXa78TjlohqxSiQOarkrrJPD9w D6yMoEu/f/y8MRL0AomlZisqyKCiizhqHUeUWe1xEp+HcWPNsV8xitCDwZzyXvCLFQHnpjaa3pK s2WtgVcAoQzPnSsIGwJbhYcSAB3aCQi+wOiqL/A9hO4VQG9THXmqd9dJ++92/T3CkgNdNje/XP9 ypdxiXchJZzBDvnXiP4NL6VOd3mNqDpsoygWcH/5ih+Q6KtL+X5ge X-Received: by 2002:a05:6a20:9151:b0:3d3:af44:ee12 with SMTP id adf61e73a8af0-3da3a2067e9mr5515704637.27.1788505085785; Thu, 03 Sep 2026 23:58:05 -0700 (PDT) X-Received: by 2002:a05:6a20:9151:b0:3d3:af44:ee12 with SMTP id adf61e73a8af0-3da3a2067e9mr5515661637.27.1788505085365; Thu, 03 Sep 2026 23:58:05 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3339885d29esm4760900eec.2.2026.09.03.23.58.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 23:58:04 -0700 (PDT) From: Wesley Cheng Date: Thu, 03 Sep 2026 23:57:50 -0700 Subject: [PATCH v3 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: <20260903-16k_offload_v1_b4-v3-1-135928dc2408@oss.qualcomm.com> References: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@oss.qualcomm.com> In-Reply-To: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@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=F+xnsKhN c=1 sm=1 tr=0 ts=6a9a6bfe cx=c_pps a=oF/VQ+ItUULfLr/lQ2/icg==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=aTe8jcWzyPiXfLMz6F4A:9 a=QEXdDO2ut3YA:10 a=3WC7DwWrALyhR5TkjVHa:22 X-Proofpoint-ORIG-GUID: 9IEt0F4Yn1jKPWm9oC3QAEYJfNVtYEKO X-Proofpoint-Spam-Info: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfXzEJJm1RsYXFm Ig32gFjP2mX988fdz6gFW/Q7U5IMUwmikhjC5gcpP2aETF2YeWY+JMg5AG1rNE47F8tpl+Epalo xFvc5FnMoD8tWDc5PVDQJUBYAUpYGC4= X-Proofpoint-GUID: 9IEt0F4Yn1jKPWm9oC3QAEYJfNVtYEKO X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX7qObtGaeFan+ iDNQzCf1yGQ9nLHqp5R8RrVN6DgFvzhks1ia1KDrHZ0lXxuylosFFJN/D6B4woceomezIQGzC0X R+yAJyEZ7WXmB7/wwiOsZC6GbopxJj807UffM0aUV1VZGmOQsB4MuXK9sVFjgr8D5WaiYbJ8rl6 OPQKWZKEQIh+uYSxDmNj8284Wan9GHgoaqFyLDWNsQtYB/MpUnja+TZlQla4y7PR5SYtOwZJZT6 vK7WXXarPa5V9zTgY7Phf0xqliuhgQkpnj2WvQoRDB0qMLe1xXf5ix7bQkwEwNzkY92jxEbB6HB 9Kg1WzndOzzO1wGpp5OeWJ6cz+IDoNCgYaNYaY3iVU5yktyT9OOXwOktZynTMG4oAmFA/weRHaN GQ60MGj3PJixK8fF8HmAH+lL+kO+HVF/4M1AvBv/hZO0WR+dxtd5fengFpy47o0OIKNgRKTitxD sOTXgdXcFUt3dPLjdEQ== 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-09-04_02,2026-09-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 phishscore=0 adultscore=0 spamscore=0 suspectscore=0 lowpriorityscore=0 priorityscore=1501 malwarescore=0 impostorscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2609040063 xhci_ring_to_sgtable() populated its sg_table via dma_get_sgtable() per segment and sg_alloc_table_from_pages(), both of which only operate at whole PAGE_SIZE granularity. Since TRB_SEGMENT_SIZE (4096) can be smaller than PAGE_SIZE, multiple ring segments can share the same physical page on larger-PAGE_SIZE kernels (16K/64K), which these helpers cannot correctly represent. Build the sg_table directly instead: allocate one sg entry per ring segment with sg_alloc_table(), and fill each entry explicitly with sg_set_page() using the segment's own page (resolved via is_vmalloc_addr()/vmalloc_to_page() or virt_to_page()), TRB_SEGMENT_SIZE as the length, and offset_in_page() for the exact intra-page offset. This guarantees each segment gets its own sg entry regardless of page sharing. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Wesley Cheng --- drivers/usb/host/xhci-sideband.c | 57 +++++++++++++-----------------------= ---- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideb= and.c index a5deeee4d5dc..beb637407e47 100644 --- a/drivers/usb/host/xhci-sideband.c +++ b/drivers/usb/host/xhci-sideband.c @@ -9,57 +9,42 @@ */ =20 #include -#include =20 #include "xhci.h" =20 /* sideband internal helpers */ static struct sg_table * -xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring) +xhci_ring_to_sgtable(struct xhci_ring *ring) { struct xhci_segment *seg; struct sg_table *sgt; - unsigned int n_pages; - struct page **pages; - struct device *dev; - size_t sz; + struct page *page; int i; =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; - pages =3D kvmalloc_objs(struct page *, n_pages); - if (!pages) + seg =3D ring->first_seg; + if (!seg) return NULL; =20 sgt =3D kzalloc_obj(*sgt); - if (!sgt) { - kvfree(pages); + if (!sgt) + return NULL; + + if (sg_alloc_table(sgt, ring->num_segs, GFP_KERNEL)) { + kfree(sgt); return NULL; } =20 - seg =3D ring->first_seg; - if (!seg) - goto err; - /* - * Rings can potentially have multiple segments, create an array that - * carries page references to allocated segments. Utilize the - * sg_alloc_table_from_pages() to create the sg table, and to ensure - * that page links are created. - */ for (i =3D 0; i < ring->num_segs; i++) { - dma_get_sgtable(dev, sgt, seg->trbs, seg->dma, - TRB_SEGMENT_SIZE); - pages[i] =3D sg_page(sgt->sgl); - sg_free_table(sgt); + if (is_vmalloc_addr(seg->trbs)) + page =3D vmalloc_to_page(seg->trbs); + else + page =3D virt_to_page(seg->trbs); + + sg_set_page(&sgt->sgl[i], page, TRB_SEGMENT_SIZE, + offset_in_page(seg->trbs)); seg =3D seg->next; } =20 - if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL)) - goto err; - - kvfree(pages); - /* * Save first segment dma address to sg dma_address field for the sideband * client to have access to the IOVA of the ring. @@ -67,12 +52,6 @@ xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xh= ci_ring *ring) sg_dma_address(sgt->sgl) =3D ring->first_seg->dma; =20 return sgt; - -err: - kvfree(pages); - kfree(sgt); - - return NULL; } =20 /* Caller must hold sb->mutex */ @@ -254,7 +233,7 @@ xhci_sideband_get_endpoint_buffer(struct xhci_sideband = *sb, if (!ep || !ep->ring || !ep->sideband || ep->sideband !=3D sb) return NULL; =20 - return xhci_ring_to_sgtable(sb, ep->ring); + return xhci_ring_to_sgtable(ep->ring); } EXPORT_SYMBOL_GPL(xhci_sideband_get_endpoint_buffer); =20 @@ -276,7 +255,7 @@ xhci_sideband_get_event_buffer(struct xhci_sideband *sb) if (!sb || !sb->ir) return NULL; =20 - return xhci_ring_to_sgtable(sb, sb->ir->event_ring); + return xhci_ring_to_sgtable(sb->ir->event_ring); } EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer); =20 --=20 2.34.1 From nobody Sat Sep 26 06:32:32 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 D177D42376F for ; Fri, 4 Sep 2026 06:58:11 +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=1788505095; cv=none; b=c8NXKbdc39d5c8dNppz7fJRrRnwm4ieyf5hqaQwb4FoEMoBDCiu9B1Sob3a9d0R1aAclXVExJGrTohhs10vqqQrBB8+vcCUkwWgQk4+JalrOXOUR8mKhViilYeO2e7Np7hNMfGtdg4XUZ4lsCQfhjR7J+U73CzWKkmWPj1HNLlE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788505095; c=relaxed/simple; bh=qk2H2kpP5eCkGJQc3YwLpJnOJ4Ld+X7USeS5LpzMJyw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Uk88NtFWCACbhy+JHTRX1HK79Yy0Uu16jS3BOFjhWXaVwRmrAorbfXfuKiA7pQ0kBnruAhz57M/ArKa6VpUlq09wefcYb+yWcKS7SQOFz3bRn+X0JMFV4lwoG+CnH1KEnHoJ+feNuYJO2UJ1cGah/IcF3yeoNoFtuvvWU+CPH6M= 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=ahmQqfvy; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=bmfPmafX; 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="ahmQqfvy"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="bmfPmafX" 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 684633Ai2719347 for ; Fri, 4 Sep 2026 06:58:10 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= cqNAQpz3CKiCXLDTkHcOYdwhCHLF31sQozeDDZ/5UWM=; b=ahmQqfvy/afZU4II 0Dg04lGlj6UX8wOIIH69WCumI5ahnB2Lwvk7SNzOqeeKuf1xgqgZxfVM0P6IQPx/ Qq3rNAiNJ8Zti588TxMPmrtn9UZ4Gfi7SZU9br3iqUV7ZmUESR+H8OJG8OOjDUQ/ hL+658zjXtuUrclegLk6DsW/TSvMhUCQ/Fsj1j0Rbbb2p6x2drmkRcBljGuqu93h V0OCjlty0rlP8F7oMEep4zVLdN4+MYYr3T5VtvTEtAfbDhEFBMcnSUlr8dxXaPKD 8cWBL6a2pfG1ojwoaq7YPMLN+7zW/nC+h6oIG6heZMfdXiQLQeaHEkqGSb32HxLh JRrZMg== Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gfqqd0b3h-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 04 Sep 2026 06:58:10 +0000 (GMT) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-cc435388657so1164181a12.3 for ; Thu, 03 Sep 2026 23:58:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1788505089; x=1789109889; 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=cqNAQpz3CKiCXLDTkHcOYdwhCHLF31sQozeDDZ/5UWM=; b=bmfPmafXXCy2DKhaXKqlvCOpR/xdiZOleSM9c2GYjzo7BZNjPcQ59YTDMuHNao7o3I jF4UYwgjIACf/hnSmhFg5wSHIYJEuRZanBJ0tp428Zq4OUxyBofIHQraLkhHaYidj0fy KEqWafVgDcx/nxzySAhWFL70RZCUxCDGr/d3WYT1VuvqeqLxS6HHd4QOofSW7Yi41ffB HPAhJI4Vx0vv6zWhc95v3+qVxLyAhKCqxAK3as1xQKlQ86ARnffW1V7P98vcziHwBjy9 H2KMyaChlaLhAOitXS31vnb8vxMer6fBENnUg2zLrKs9duyYMB23i3lRX8a2OGASm6wx ttsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788505089; x=1789109889; 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=cqNAQpz3CKiCXLDTkHcOYdwhCHLF31sQozeDDZ/5UWM=; b=Olr34jLbfqzgcfVOqoWBzItMgIFTVgZI9NogC37qLhgLqSDmmf/IgS8nHIRUZoewJr wHoim2Hc4ylCD5pbWXYpidrltQsCWtfPjE32qroJaFs5BvHa7Ecg3EQVTiqRZ1QdK6TC DQN7fnhTArpnvtb5PVfzIRr4+vT0kuANjMx8F7cRRmMv/FBuoFhQKLlUFGiMkxL4wOYZ pV1NAPRAd3PWIeqpYl98jh/4ZHi5O3Of5yc7/4c5FzwIiI+nO7wPM+lnOxb1AHs2HkUF oMiRAQkgvSOKWOEMBXYXHOF179BVAvcbawRuUstmE2sHzrEM4C4neqkbKZTDO+rKc5i6 WDKg== X-Forwarded-Encrypted: i=1; AKwUvByodZUAOXCXA2ii7qgwsol1Dk6ztzwPWEmPUvg0WMuuurdYIDED2eTv2TvazA/Mw/ROg70cQcLc5VHwhPA=@vger.kernel.org X-Gm-Message-State: AFuF++nYO3Dod8daGb2lNwevpWkCPyP/wXZ75zsX8zdKoeGuooZR/XlE ZUBaAzXpKia2CVOKr+gcDPwE4Ho/Rs82JTK5KuKyp1kSX15WiwtM/08mp1nSNQNAnUNcq/j1S9m R3GMeus8YWS/eNNqPLvgEc2ri4uuXn44lKimWasx/gjmUoTdgOZTI46pnbzi+K97uc/I= X-Gm-Gg: AYBFou2OYNr9FanqFU9Uu9lsgwlx7G8CG2pdjMoedzGJX7qcLfabiz9Igj3Q/SObVr7 LeVeN0BoOHO9E1luPpNmQpkmz/+9e4Hj8fuqniqYk5MuG0NuEEkFuufK3747W9Nx0SzWFoQRkdw H6BlI3a4dsGUL1jQNjA6PzdZ7Dx+Ac70MpMKWxLDwOTD7RKJcbieTX6rCgB3ZeyGwkrb8gwaEcJ lPL2wwvmyAt04A4RRy688llV37fs66rt3ab2wEvhOrl90QhHAiGrK/vSb2aLNHZkXb+jTWOvZVH CGucDJ2UcaqzEhyP6V01t7CsBM2LHjgcOgbNcsC2avjIZgTUJlkgyK88IKEYCs1y66LIJZPTTqt xLWl5J2zeQzTImFRw8lzTnSBDUY/pxKM4duJz4bANTJeDetdJKtXl X-Received: by 2002:a17:90b:3ec5:b0:398:9c00:29ed with SMTP id 98e67ed59e1d1-39b26277673mr6247859a91.21.1788505088645; Thu, 03 Sep 2026 23:58:08 -0700 (PDT) X-Received: by 2002:a17:90b:3ec5:b0:398:9c00:29ed with SMTP id 98e67ed59e1d1-39b26277673mr6247568a91.21.1788505086569; Thu, 03 Sep 2026 23:58:06 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3339885d29esm4760900eec.2.2026.09.03.23.58.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 23:58:05 -0700 (PDT) From: Wesley Cheng Date: Thu, 03 Sep 2026 23:57:51 -0700 Subject: [PATCH v3 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: <20260903-16k_offload_v1_b4-v3-2-135928dc2408@oss.qualcomm.com> References: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@oss.qualcomm.com> In-Reply-To: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@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: 4P9hA6kQCBJqrCiwOoLjUG_RhlhGu95w X-Proofpoint-ORIG-GUID: 4P9hA6kQCBJqrCiwOoLjUG_RhlhGu95w X-Proofpoint-Spam-Info: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX9oU/utFSbJpR 1BRExtb8ZvYbT+aj49Onl00aZpkanEtrOPlMYNZhQqFjFSExxS7J9Mhw//XpZbdf8hqec5PUnYB 5RIOlqOlk8JPhmvCOrNRzn6JxwcVr0g= X-Authority-Analysis: v=2.4 cv=XtnK/1F9 c=1 sm=1 tr=0 ts=6a9a6c02 cx=c_pps a=rz3CxIlbcmazkYymdCej/Q==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=fiA0ds54v2HOqp6UKg4A:9 a=QEXdDO2ut3YA:10 a=bFCP_H2QrGi7Okbo017w:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX70oSTZHqotOm ju7BvgpIaLNU1Fp05TUVKpvB6sMe6XwkRvOQip6O5o/1oeahiiC55Xu8QZvx8by25MqVPVWuRc4 0sQiFZ2tmb47qlGEr1B5V+1pCjog6STB8oQVlaRzBa3O0E7Zc+Xk77L1QAHuVdazy5WjTjMTxj7 Hz9JUtWtayjBCOMUpLMPVtElgqAMbhn1bwBQVwqGTLoihM6sEzFgHUv4qz8neXiMJW/yz6V0UKK 8dE4D2zBNtOXNvCvc7VZdiRhlqppChomwvY61c9bMWanW5Nv19DbDhgCi7mHfOFZ3v3tUry7Oa0 1uTKzspXVRItAloKB+HKkj6jCHqWaGwhBPC/V0VqOsgEKifAc8TVHN+GL45+qEJeEV0hnJeIktz 4p9YB4RcIXMaXn8U5UgcakX6mE65ZfHJXItyrWSAyf6pY/ro50wDnRyWk3bgkJ6PQbGgtelJoQR aD4kU4iOrvtgqKM2Sdg== 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-09-04_02,2026-09-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 malwarescore=0 spamscore=0 clxscore=1015 impostorscore=0 bulkscore=0 adultscore=0 lowpriorityscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2609040063 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. Allow each xhci_sideband endpoint to pass 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 visible by the entity handling the offloaded endpoints. Normal (non-offloaded) endpoints are unaffected, as they keep allocating from xhci->segment_pool. The offload client owns the pool's full lifetime, and since that lifetime is no longer tied to the sideband instance itself, xhci_sideband_unregister() must free any ring still backed by a client-supplied pool before returning, rather than leaving it for xhci to free later when the client and its pool may already be gone. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Wesley Cheng --- drivers/usb/host/xhci-mem.c | 63 +++++++++++++++++++++++++----------= ---- drivers/usb/host/xhci-sideband.c | 40 ++++++++++++++++++++++--- drivers/usb/host/xhci.h | 16 +++++----- include/linux/usb/xhci-sideband.h | 20 +++++++++++-- sound/usb/qcom/qc_audio_offload.c | 21 +++++++++++-- 5 files changed, 121 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 7a21ac81f9c8..a041a35fcd4f 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -28,6 +28,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 +41,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 +51,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 +63,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 +83,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 +336,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 +345,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 +365,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 +380,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 +397,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 +435,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 +1438,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 +1502,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].priv_seg_pool ? + virt_dev->eps[ep_index].priv_seg_pool : xhci->segment_pool; 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 +2308,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 +2326,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 +2374,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 +2386,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 +2517,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 beb637407e47..1bb6e5034b58 100644 --- a/drivers/usb/host/xhci-sideband.c +++ b/drivers/usb/host/xhci-sideband.c @@ -9,6 +9,7 @@ */ =20 #include +#include =20 #include "xhci.h" =20 @@ -67,6 +68,7 @@ __xhci_sideband_remove_endpoint(struct xhci_sideband *sb,= struct xhci_virt_ep *e xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL); =20 ep->sideband =3D NULL; + ep->priv_seg_pool =3D NULL; sb->eps[ep->ep_index] =3D NULL; } =20 @@ -113,6 +115,8 @@ EXPORT_SYMBOL_GPL(xhci_sideband_notify_ep_ring_free); * xhci_sideband_add_endpoint - add endpoint to sideband access list * @sb: sideband instance for this usb device * @host_ep: usb host endpoint + * @pool: dma pool to allocate this endpoint's ring segments from, or NULL + * to leave the endpoint's current pool selection untouched * * Adds an endpoint to the list of sideband accessed endpoints for this usb * device. @@ -123,7 +127,8 @@ EXPORT_SYMBOL_GPL(xhci_sideband_notify_ep_ring_free); */ int xhci_sideband_add_endpoint(struct xhci_sideband *sb, - struct usb_host_endpoint *host_ep) + struct usb_host_endpoint *host_ep, + struct dma_pool *pool) { struct xhci_virt_ep *ep; unsigned int ep_index; @@ -153,6 +158,9 @@ xhci_sideband_add_endpoint(struct xhci_sideband *sb, ep->sideband =3D sb; sb->eps[ep_index] =3D ep; =20 + if (pool) + ep->priv_seg_pool =3D pool; + return 0; } EXPORT_SYMBOL_GPL(xhci_sideband_add_endpoint); @@ -288,6 +296,7 @@ EXPORT_SYMBOL_GPL(xhci_sideband_check); * xhci_sideband_create_interrupter - creates a new interrupter for this s= ideband * @sb: sideband instance for this usb device * @num_seg: number of event ring segments to allocate + * @pool: dma pool to allocate the interrupter's event ring segments from * @ip_autoclear: IP autoclearing support such as MSI implemented * * Sets up a xhci interrupter that can be used for this sideband accessed = usb @@ -301,7 +310,8 @@ EXPORT_SYMBOL_GPL(xhci_sideband_check); */ int xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg, - bool ip_autoclear, u32 imod_interval, int intr_num) + struct dma_pool *pool, bool ip_autoclear, + u32 imod_interval, int intr_num) { if (!sb || !sb->xhci) return -ENODEV; @@ -315,8 +325,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, pool, + imod_interval, intr_num); if (!sb->ir) return -ENOMEM; =20 @@ -370,6 +380,8 @@ 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 + * @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. @@ -436,6 +448,15 @@ EXPORT_SYMBOL_GPL(xhci_sideband_register); * After this the endpoint and interrupter event buffers should no longer * be accessed via sideband. The xhci driver can now take over handling * the buffers. + * Any transfer ring allocated from a client supplied dma pool is freed he= re + * as well, as the client is not expected to keep that pool alive any long= er + * than this call. This includes rings of endpoints already removed with + * xhci_sideband_remove_endpoint(), which xhci would otherwise only free o= nce + * the device is reconfigured or torn down, i.e. after the client is gone. + * + * The caller must ensure the usb device is no longer streaming through the + * normal, non-sideband path when calling this, as the freed rings are sti= ll + * referenced by the endpoint contexts until xhci reconfigures the device. */ void xhci_sideband_unregister(struct xhci_sideband *sb) @@ -458,6 +479,17 @@ xhci_sideband_unregister(struct xhci_sideband *sb) if (sb->eps[i]) __xhci_sideband_remove_endpoint(sb, sb->eps[i]); =20 + spin_lock_irq(&xhci->lock); + for (i =3D 0; i < EP_CTX_PER_DEV; i++) { + struct xhci_ring *ring =3D vdev->eps[i].ring; + + if (ring && ring->segment_pool !=3D xhci->segment_pool) { + xhci_ring_free(xhci, ring); + vdev->eps[i].ring =3D NULL; + } + } + spin_unlock_irq(&xhci->lock); + __xhci_sideband_remove_interrupter(sb); =20 sb->vdev =3D NULL; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c7bfa7f028d3..1353d6fa2776 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" @@ -709,6 +710,8 @@ struct xhci_virt_ep { bool use_extended_tbc; /* set if this endpoint is controlled via sideband access*/ struct xhci_sideband *sideband; + /* dma pool to allocate this endpoint's ring segments from, if set */ + struct dma_pool *priv_seg_pool; }; =20 enum xhci_overhead_type { @@ -738,8 +741,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 +1254,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 +1378,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 +1864,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..6d318e6a3bf6 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 @@ -72,7 +84,8 @@ void xhci_sideband_unregister(struct xhci_sideband *sb); int xhci_sideband_add_endpoint(struct xhci_sideband *sb, - struct usb_host_endpoint *host_ep); + struct usb_host_endpoint *host_ep, + struct dma_pool *pool); int xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct usb_host_endpoint *host_ep); @@ -94,7 +107,8 @@ static inline bool xhci_sideband_check(struct usb_hcd *h= cd) =20 int xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg, - bool ip_autoclear, u32 imod_interval, int intr_num); + struct dma_pool *pool, bool ip_autoclear, + u32 imod_interval, int intr_num); void xhci_sideband_remove_interrupter(struct xhci_sideband *sb); int 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 06:32:32 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.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 4B262425892 for ; Fri, 4 Sep 2026 06:58:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788505094; cv=none; b=KnFYHzdSJLpAGNmrWDjwX8UNfvCKV3sACGED10a75kOo55sB7FhtskFxVCZMH4YsP18Yec/oO1PdQE5ryZYWXU2uoTRwh3R9Ef6E2Ic3Qug3OirAO5b1zVXVuD3QKxYgkeoXhqPGhAJynZnGbqXeFw+g6Xqes3nZPAtMwi6Dbr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788505094; c=relaxed/simple; bh=lve08jujf/eMvpsshRzTzwRftklUvvZDXztfOjmPd1k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mpKoWPo7N9icrSoOZm0/7oW1usoqUH2/lgDj20NNb6ZuZPbB2v5LVzmpePoVQfELd6z4Jvj05NcK6SYhtmx4wonZXdp9Y9ClTCPSU8L5ZMKprOCcKKSqs/MXxw5KbnpA6CEZm9lEzvxvFjX9enQ3SbhN1Mi9erx9aYgaevIi9+I= 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=AdB0ukcj; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=SFQc6xLh; arc=none smtp.client-ip=205.220.168.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="AdB0ukcj"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="SFQc6xLh" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 684635oi2751977 for ; Fri, 4 Sep 2026 06:58:10 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= Iq+pltkssLijjF8JMOOy4XYsugaeaREAGo7D2xyU9U8=; b=AdB0ukcjGmd2XZ2J d97weZ9NSHUUCiC9J+SBv3cs3O1DA6I9rCAnsNQkiDi1HmZutTzytvCt2TvoV6i6 r8uGiQHMfuvhhqa8JCkqXUi2GGvBe5OZeHjI9MOjHVP4QQsGF6xOx1sz/5fz+hSE M9BrnTyZ38/b4Rohr/vCqqvQw0s47y4cmwfjds/DCUbdTEk+XxOgpjD5aTWJKQZG K1zB/+6LUAuv+4Io4p8RbCfCYh1TfvRymPreDPJ14dnQJW4pGTVEO9kOgznr/8ts tTtS7Xm81xCuXDMs2VMl5xZe8hsmAjwHMyvx4NiMvS6+uNdi3QVbH8sHnq7h1Wes 0RJV+A== Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gfdyxjeta-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 04 Sep 2026 06:58:10 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-39af92138f9so1145158a91.0 for ; Thu, 03 Sep 2026 23:58:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1788505089; x=1789109889; 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=Iq+pltkssLijjF8JMOOy4XYsugaeaREAGo7D2xyU9U8=; b=SFQc6xLhJUis+kr+Qr5xvv7sTyrCEIiUG7Pjsla/GBWIvvP3qTLyPpTxb8PwRFC5Ca 7rKBODDcVUrsXyFVVFIKjGYXc11ziExHgbu0BzdiwLMYpCqgNGJe3W3ywucX4JX88i5p 1gu6c0r2CvdQRV5CMeeYgirfo2zrmaceeo9k24LqGxq6j7P1El8U+800yQJ9SJk6qyXm cjJW4bD00RRr2Z2JGsPpYuAuI5NwelpjmLrgVjNF2KdNbhLmlOCHWBltP3UIcZ3EHBuK 8aSZbufE7YHpvRTpjsGcmzp4f/g64i/cQ7kFEqJBuHo8n/P7VNly4KyCQPEjQvBxYmE0 Ra8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788505089; x=1789109889; 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=Iq+pltkssLijjF8JMOOy4XYsugaeaREAGo7D2xyU9U8=; b=WUrpU24XHOVzNkaP6Zdd6HDqFpMQbKS/+BMBdjG6OoOkeof1ekzLCnLk6Qkft7UjXt SC96j3LOVT9+wBLLe/MxFXjVNGTQKA9aF3OJml6ONWE2PqQp6GeEExf+pCoBtpRkOu8f 0ydWNXt1nJx/e/WjvtgdUWIYxlANu3RhcPD8aKMTz8N4ulfFUtLvKSs0C3lUlmCmMCHb BT+wXSkj7lR+xXsI6oonUq78DfGe/VaMxHEzfEsNkdqe74rHt2sldcX9RYU5geatE6// NnfyrsVaW3y/eISUfnEzi2Tsbf5rZU8xCYUaFSD0f3weBmnXNyqc+Ygah49nvUSc4GPE jmqQ== X-Forwarded-Encrypted: i=1; AKwUvBwLYeDRWITnyqjrF5mTLCZ3CSmStBDX0kdA6RNR3rT9QvRiXYWAleqrNCXFGU+c6SSpwcTjUCajcZBR4Ns=@vger.kernel.org X-Gm-Message-State: AFuF++nILdyYEGRCZoI5Y8HEr5f7UVkeoFrXpTnzB9gdbNUWd5U8M9rL VEl1CnGPuZWCiVQ5SojAUwVo3KLKrIPmnaZqELknO0hS/KHgLeiWRNc6YBJBtrn72FhoWE0MKL7 dvZ+7fmOwdjHJXO5y19TkXShPsyop/3K4s6roBixGGjnIOuYCUVu/ZrC0xmH+cK4I0s4= X-Gm-Gg: AYBFou2So2zFtzvP/luArFZy+nIO1P/Suz1YOzn01JfFjvVpy9E9b4Oq/OxDg/YeWTc 4yWZ1Ixsw2UV0tbcN1nUNi85P8t02frZ5k+jtf9nZuYKLkiNZ11YbH26GQqUxqtOWv4xjeMpQHD SXXvcbqpiM+Ex/coaBq/3VSlUV9fiAjWySQBQR+g0x2s3OaUrlDCrsVa3xT24NvVYY+reJI2Xxz FxlM0vHMcvjQfT6RZ4wPn6P2AukGwgeLV1koQoih6IczkF9nlx4aIlNUIOkHEkr952FRcDKF9mX yqBcz/9AZTYHEKRTjGy2tEYegXbgOnwFvUj2FN5FVu189U+RvAMU8bSGrWhrqrEh5SXFBMpmhjA g13GLtY5rUNZwbDCtkaeQdgo8Ousn7vgmZWu1H6zU8opPzeYUEg9X X-Received: by 2002:a17:90b:4b04:b0:396:4ce0:6400 with SMTP id 98e67ed59e1d1-39b07f33963mr13166063a91.2.1788505088227; Thu, 03 Sep 2026 23:58:08 -0700 (PDT) X-Received: by 2002:a17:90b:4b04:b0:396:4ce0:6400 with SMTP id 98e67ed59e1d1-39b07f33963mr13166028a91.2.1788505087695; Thu, 03 Sep 2026 23:58:07 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3339885d29esm4760900eec.2.2026.09.03.23.58.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 23:58:07 -0700 (PDT) From: Wesley Cheng Date: Thu, 03 Sep 2026 23:57:52 -0700 Subject: [PATCH v3 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: <20260903-16k_offload_v1_b4-v3-3-135928dc2408@oss.qualcomm.com> References: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@oss.qualcomm.com> In-Reply-To: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@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-ORIG-GUID: 1McBCqWnXDc7ILQhG2T0cB-fRHwyJUyN X-Proofpoint-Spam-Info: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX+KR3e4FfffFy fy7EA1d2JxlK07mSGWcMJQvUcuqjJ1hnIZaBMDPWeIFUzXzfDRov8htK4BiBEyvIpbVjBJ3vd7G dd3+Fl3D/yiAi2xlIfGBe8r6rY2ErFk= X-Proofpoint-GUID: 1McBCqWnXDc7ILQhG2T0cB-fRHwyJUyN X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX/LiMc2FiJZwA SEy2cEEfOlSdvyrzxXwy/u1T16VeQvcPGxKtcKgvek0ZVczzJJvnRK6EC5MaIGe6PEdut6cl2Ox FMfCsTUNEfEgsrr/TPACbosKq+s2/BPKtXZQ2LGoAggZGyXAaw/GHwrt0a02drl3IAAPhrIDwJe NcabUFiCja5mvbnlEcKE4A8HxAmeXV73oDvka7EV4D2ebhFbaRWD4QRYaqbG7sSjElxEjPVDSTD MJx1A77xCs5kaFbAM9sSVRahRQX6hQpXVxCHK+mFjQJurjMULIGt3or4KBcLcVFSrpikhhB9Iig EZCMsvAFccerLWVS8PkOz4gGZT041TpxwkPrEi5Ci1/pJ7cb287Cj/SA+B0dG08MASC095Xzafg BAL8OMLNkDOT4bgdwvmSu4evBFtwXc1GeSu0r3B95CheHaaGLdH/1rYXioIIEmkeOzmtsNWLlIW sY6AwuisEi2sMGbPzgQ== X-Authority-Analysis: v=2.4 cv=X9Zi7mTe c=1 sm=1 tr=0 ts=6a9a6c02 cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=mfbS_Oyj0OiJrwsacs8A:9 a=QEXdDO2ut3YA:10 a=iS9zxrgQBfv6-_F4QbHw: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-09-04_02,2026-09-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 malwarescore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 suspectscore=0 priorityscore=1501 spamscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2609040063 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 offload client'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 | 111 +++++++++++++++++++++++++++++++---= ---- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_of= fload.c index 1b8877b8ee62..f09dae8334d0 100644 --- a/sound/usb/qcom/qc_audio_offload.c +++ b/sound/usb/qcom/qc_audio_offload.c @@ -132,6 +132,7 @@ struct uaudio_dev { =20 /* xhci sideband */ struct xhci_sideband *sb; + struct dma_pool *segment_pool; =20 /* SoC USB device */ struct snd_soc_usb_device *sdev; @@ -942,6 +943,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 +999,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 +1039,49 @@ 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, + uadev[card_num].segment_pool); + 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, + uadev[card_num].segment_pool); + 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 +1093,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 +1219,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, @@ -1212,8 +1282,9 @@ static int uaudio_event_ring_setup(struct snd_usb_sub= stream *subs, goto exit; =20 /* event ring */ - ret =3D xhci_sideband_create_interrupter(uadev[card_num].sb, 1, false, - 0, uaudio_qdev->data->intr_num); + ret =3D xhci_sideband_create_interrupter(uadev[card_num].sb, 1, + uadev[card_num].segment_pool, + false, 0, uaudio_qdev->data->intr_num); if (ret < 0) { dev_err(&subs->dev->dev, "failed to fetch interrupter\n"); goto put_offload; @@ -1638,7 +1709,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, @@ -1813,12 +1884,14 @@ static void qc_usb_audio_offload_probe(struct snd_u= sb_audio *chip) if (!segment_pool) goto free_sdev; =20 - sb =3D xhci_sideband_register(intf, XHCI_SIDEBAND_VENDOR, segment_pool, + sb =3D xhci_sideband_register(intf, XHCI_SIDEBAND_VENDOR, uaudio_sideband_notifier); if (!sb) { dma_pool_destroy(segment_pool); goto free_sdev; } + + uadev[chip->card->number].segment_pool =3D segment_pool; } else { sb =3D uadev[chip->card->number].sb; sdev =3D uadev[chip->card->number].sdev; @@ -1855,10 +1928,11 @@ static void qc_usb_audio_offload_probe(struct snd_u= sb_audio *chip) return; =20 unreg_xhci: - segment_pool =3D sb->segment_pool; + segment_pool =3D uadev[chip->card->number].segment_pool; xhci_sideband_unregister(sb); dma_pool_destroy(segment_pool); uadev[chip->card->number].sb =3D NULL; + uadev[chip->card->number].segment_pool =3D NULL; free_sdev: kfree(sdev); uadev[chip->card->number].sdev =3D NULL; @@ -1918,12 +1992,13 @@ static void qc_usb_audio_offload_disconnect(struct = snd_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; + struct dma_pool *segment_pool =3D dev->segment_pool; =20 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->segment_pool =3D NULL; dev->chip =3D NULL; kfree(dev->sdev->ppcm_idx); kfree(dev->sdev); --=20 2.34.1 From nobody Sat Sep 26 06:32:32 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 3E1DDC2EA for ; Fri, 4 Sep 2026 06:58:11 +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=1788505095; cv=none; b=IQCGVYvSUBLlNCE6C0wKjY/waMuiy8/4aIvLs4xGu5JWgETctJsbtRWL/labTJe6yU3fOD3DRvTRkBgJt7enaEtPsq3XGSPOyJ29S9uGapGdo1gXq6E5ZXsHurGHT/Q2fXLGrUAGl4aqpfKnyyC64S/jONpWaQb4rN6IIJOUk+8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788505095; c=relaxed/simple; bh=ZFeil9OwyvB+ttevEGeLJHHBev8PjDjG10AnscfM4Ow=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tjeyPLwmmtx2zHM5hXqApnf6GHFhmPCVhkKh1TUnTAlz99QxlA+XM0JH/lQNW7g8CwsT6sDBZyspM1kuurPK3p00JpYsSm+YGnIdK0IJOfCNRmooZd9N08yrbpnMtZDPSpRZgikgHkIpjFETMmPhe25i1WwDvRA9L07iNffislo= 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=il67v3Ue; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=TqP7ATi9; 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="il67v3Ue"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="TqP7ATi9" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 684635wu3227511 for ; Fri, 4 Sep 2026 06:58:10 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= NLwSipIlwt4Uh35Xbe9B2buRpk0lXStHU+U69Bwrflg=; b=il67v3Ue4qQ5DvXi hNWbTorQL6HNxFFZRiBkUyztCfJmfLGiYoLHTHZAHPwk7yJeaVfdbuDjkmrjBf5x qoeQYgpCfE5zEBqMxZ4qWk+5QU42faVpl9DuEIOsCX73q+zbgIFqogC1zXrHBtjW /qqH3ceNPBsSpjoVcEiLJ3B1UuX9TyZw0A1o6iKuUu77TLEMw/xpb8Vb3GSCEzmj gA9WnXkxQvw4VH3E2JP/xbT2Hb9g2xQazdMAY2+3W3pPzRX3uqRSp2bNnx5LBmY9 sXTxtU3UXvq7YKyKgll6Jg/2lN2jZ/O85Ghq4FWHE56Lz+BCga7j6As2gdhU2m2a ck/ZlQ== Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gfhc9sjnf-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 04 Sep 2026 06:58:10 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2ce7dff6253so20903175ad.1 for ; Thu, 03 Sep 2026 23:58:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1788505089; x=1789109889; 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=NLwSipIlwt4Uh35Xbe9B2buRpk0lXStHU+U69Bwrflg=; b=TqP7ATi95xRKdqn6Bb+x64j5JWXxk6v7LuhoYSDqf2oCh4GMPzqLCZxX0NoHhBJl+Z oYMMQDWYyWgsxMkRstsTDPLNiDxwFlnNDnieESqEKhJF4k4U6yCYpW6fSw0GJbCQVsZJ n5kGG2MruW1zOXnMTJ+Dlkeil4fmSRDuxf3BvFqnAk8Hn3S13afXZq+sNPSay5C93u0I tegT0ei8axmBWM+jzHc/3FTTT4qxAEmJ+n+X+pyheKbcHbos+WF4hommZQ/e46/pD2pH UflIlcXDO79EvwTIWuN4sSOitCBzA4O1QbtWgmR3UthiQE/uUvBB6FhDmZ2ybeWTUlg2 wkbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788505089; x=1789109889; 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=NLwSipIlwt4Uh35Xbe9B2buRpk0lXStHU+U69Bwrflg=; b=G4K6vYPUMO8jm6clLi7OCwDK0thGIr+rjKua7nAk6RybHGW/oafFwb0l1O9P4XQ3qc cg83cKAZFxtxAaBk+xZImhW//flA3RSmG8JWY/dOaW9vpoIgleW7YaoodlEA2ZLfZNAT L2DjwSxvF2LFb9TBX5GbqZYGrL/UbbEcGzrPTdPQQLNY86rPKI3jJwvH0dOiVyRe6evw bTlfEm2gpwx4NJoCEf4/dqw8kF70xANm3zNTdTIjJidwAEYM6c7myWxQr3k57+V9kKN7 Cx/ByLzN2iZ/opdVhlHUcDzW8Mk0XoF5NkhkCOOdikWnXhqgSfiV1EuU1oHb/rmxrwmN 9VMw== X-Forwarded-Encrypted: i=1; AKwUvBzzdpyBbil82f9DjjLAByC62Vh3IIS3gElCOYTypba7knmbMhEhhUUqxT4URdgcLHhldiA7i9fctGvx9Ds=@vger.kernel.org X-Gm-Message-State: AFuF++nEq4Cr6iY4B/jZGWOV5vWXZtT0ghSJ2RQj2BRTkAzicxskX5jW PqlW0Cyb9ThJ+PYsT2clCFAAeSnW3+89yhDs5JJBEO4QN+7NJruoqtlb6Jpl4wAb/vODlU6v77h RLizF2dnge00W47EAnBZsL6vgZ4IEl8Ybi+sOmpJ1Bbt4S5fJo/iJdmNnS34UiwSqSAP4KLX8VD 0= X-Gm-Gg: AYBFou3VtiesIAqOZhTiGPdIVCfzdG/VW85FrVYX/TFRwnbqh2VljPfyFQvkf8a6qsu 8nm8QSGis5igXtmSHj8rRsKkgKw3nQMsc8vQJKyJPnGyGDdvLv/rTpt+ocels6W846het2cDnxO 5vrufz73Gkk+XDj5Ql2LXr2wJ67LXuc0d+jYCVqLyORWEwtA0eb16xMm+uyBftrlTVWYnAY79eT YO9wg5uB/0F36x+shubLPuSKg3L9qFbJexKj3igEWTxDSBrzhGkQBuNvRUS7jmwjmwy4cVTbg6B qNDJb7h032ROvlyE4QgpHtxY7lbG9fnl9SCLXTCEbGrfTmOTMhMHG41ud9LfjgkC4tJovR/4geg wIEh7BZfhtCSIDhd71mANLyPWFaDlm3YAAMPNpSWyLSQ4DKnfeDHu X-Received: by 2002:a17:90b:2249:b0:396:d28e:b53 with SMTP id 98e67ed59e1d1-39b0865350amr12594500a91.20.1788505089276; Thu, 03 Sep 2026 23:58:09 -0700 (PDT) X-Received: by 2002:a17:90b:2249:b0:396:d28e:b53 with SMTP id 98e67ed59e1d1-39b0865350amr12594444a91.20.1788505088769; Thu, 03 Sep 2026 23:58:08 -0700 (PDT) Received: from hu-wcheng-lv.qualcomm.com (Global_NAT1.qualcomm.com. [129.46.96.20]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3339885d29esm4760900eec.2.2026.09.03.23.58.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 23:58:08 -0700 (PDT) From: Wesley Cheng Date: Thu, 03 Sep 2026 23:57:53 -0700 Subject: [PATCH v3 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: <20260903-16k_offload_v1_b4-v3-4-135928dc2408@oss.qualcomm.com> References: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@oss.qualcomm.com> In-Reply-To: <20260903-16k_offload_v1_b4-v3-0-135928dc2408@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=afdRWxot c=1 sm=1 tr=0 ts=6a9a6c02 cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=ouPCqIW2jiPt+lZRy3xVPw==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=4X7XonqLFEBPzPt-dYYA:9 a=QEXdDO2ut3YA:10 a=uG9DUKGECoFWVXl0Dc02:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX7QutEpZ3uVKC HCC7FokS8Hdpx0+VIPI+S0vDzKu0qA5eFlQuad2qIFgG6QWlprCGS0BWo7SJ9V+QS5fQ5xweNqL lnsreO0L3PlSmnlg6WYw1cvs0JPdQ1brSPSYpVfIPX72zZ7uIkXi1CjcvXMWMhUvHGAYkhMq/bI P1Ibbo/hcgEe3WDZtpAdJBUNNBIJ+odSJIF3NMJfn89tduGuTLATNC3D93mWyWWM2hzEKp+E6FF h7U7CUTJk8JOg50qw5U4owFYaGaU7iy6jVJ4QG37dfGc9sQ9pHpQHgJ88hFQ/U7Ki6ltNaY0tFE we9ebswmDrGIkkz2RW3HGAJ42+tD7mfvTt6WdUO1fXSsxOTtfDxNRzTJnVG9KHJ+PTjuX+VdFFz IorFRDTtU6eNbOjkWska9SM4g2TFlSbwTmbukVPuKldJsfoVtk632Lk7qN1P0WL1QKhWSe9Ifb8 N7rUU3iNhE4Kr8G7VGg== X-Proofpoint-Spam-Info: AW1haW4tMjYwOTA0MDA2MyBTYWx0ZWRfX9zdy9AQCLlsJ gTISixObu/TGbPfi8B5tq6GN5fPMFSaVgU9wyojM90cpfyABjbqVqPwqYNwsrvTBcNjFk1XL/5j pIpx/LHWNNLIzTTCTn4KfFIH1Fx1wwo= X-Proofpoint-ORIG-GUID: ldTVLevlezW0GYDOsBb6QgiFjAHgzLFu X-Proofpoint-GUID: ldTVLevlezW0GYDOsBb6QgiFjAHgzLFu 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-09-04_02,2026-09-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 adultscore=0 malwarescore=0 bulkscore=0 spamscore=0 priorityscore=1501 suspectscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2609040063 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 f09dae8334d0..515f4271a58c 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) @@ -1241,8 +1243,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 @@ -1311,8 +1315,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 @@ -1551,10 +1557,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); @@ -1589,13 +1595,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