From nobody Thu Sep 24 18:40:56 2026 Received: from PH8PR06CU001.outbound.protection.outlook.com (mail-westus3azon11012054.outbound.protection.outlook.com [40.107.209.54]) (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 5CEC550B41B for ; Mon, 21 Sep 2026 21:15:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.209.54 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790025309; cv=fail; b=ZZx8ec4Cvh3nZsbhdLI0ZpVi9oNn+xihZLbfs1sf3P8kbrIYv68aXkIK2jPRZBUPulj8KnTZ9qouzszvtRZQP/rIedvIzjMcVN4brU8PzV8dyFUcObyMq7qgPyyekYatXoSRwD4bnc29vA6/+6/bv27jnWOBFTjiVzEpQyjIN18= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790025309; c=relaxed/simple; bh=CugRMuNeqwcm/XF8gKqrKtceK9zeDjMClWMCxfqciFQ=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=p3m+SC7vlzSIpDfCojeXvOlRh50OJ/+dPjYhxOvWYkWH/kxLk7HwguTdixKo7xTxzrWTODYWAJeitQoPCNlfXhz+pgn+CuENzIvRRaSFMZNKDlrabxAqtvPsIpbeFl6LBOgJJ1WLGYatdoRzPYcNR1DIueoEu6B26K9Rku9Qc8U= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=Fb53roo5; arc=fail smtp.client-ip=40.107.209.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="Fb53roo5" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=rMOqHAlVIRMGKOpoXRthhxnlXNPu0gWOSLC/2w/eyERdYjv5MbmtOxI9BlQpGbPtrc+cVObxNF1tN3W1cpbEK23NlkeWvEbwwTwuf+rzxOVyzGf/LkTLZ1qc2gC3gq49qZO86s2al151RTiD197huHR5NVKH5EGc2XLh8b0YjdbbLBAAJfyQlxW/2DDkyPyvK307UVOxlDHumBI7rAZ2W58i36Z8wDM6FZctto+buZHW/FsuTo3rYJhDwcQusr5C4xYX0olmQwrBGQs9xmP6lJiaXokFu7W/PEmSEw197knrgdbvZzaOjJHPcACggNKdawoDlk6VRIveRRQA9Qe8Kg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=xuRL8IEFg8FVqyy91hI4WdLAA/vCjzVMHv7IURFZyLA=; b=cHodxQBEVU9pL+PLHGLTbjEhsjwk1ZCkgwOi47hFP1aPjwQ3ri1q2s9CmsXKcV6a/PTonCL3XquyD83n/3KiMy6ND+gSRzS/6ihVOYN2gBBgD4uqZUfan3Do0CCUQPeQX/GkaeoD6CbpeWsvtX+5lziTf+u6BzO76nkX79m1O/ld4hLHTruQSo132QRTdee2Lio1g9b+gXRgrHoNGjBR4MUPnshP5nl3d1S8iQ099YVzoex5V8HpVIjh9b/CSEO8CXcHEhstSD1ms7BOilycFar8raBiUh/wRF2yjA2CADya1dEe1PLhoM1aGzAbBwFFq5wCi5UX9F288wEVI4hpXA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=xuRL8IEFg8FVqyy91hI4WdLAA/vCjzVMHv7IURFZyLA=; b=Fb53roo5QuX9A1Lux8OOPXY5JKDeaZv/n5ILByBlA3PFB0e+AvadOU5OflIDHeorM8+7YZGWxLPJOPXXCvChyyAnY8fyC2FH+bGUTxU/xvXHmtQd+9XnXJADKzfhNmFR7eu+pzDiPxxdr8K4guSB7fi9pj3/AfASLl0mGWEXFt4= Received: from BYAPR21CA0017.namprd21.prod.outlook.com (2603:10b6:a03:114::27) by PH8PR12MB6843.namprd12.prod.outlook.com (2603:10b6:510:1ca::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.428.16; Mon, 21 Sep 2026 21:14:56 +0000 Received: from SJ1PEPF00002321.namprd03.prod.outlook.com (2603:10b6:a03:114:cafe::17) by BYAPR21CA0017.outlook.office365.com (2603:10b6:a03:114::27) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.451.13 via Frontend Transport; Mon, 21 Sep 2026 21:14:55 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by SJ1PEPF00002321.mail.protection.outlook.com (10.167.242.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.451.8 via Frontend Transport; Mon, 21 Sep 2026 21:14:55 +0000 Received: from satlexmb08.amd.com (10.181.42.217) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.49; Mon, 21 Sep 2026 16:14:54 -0500 Received: from xsjlizhih51.xilinx.com (10.180.168.240) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server id 15.2.2562.49 via Frontend Transport; Mon, 21 Sep 2026 16:14:53 -0500 From: Lizhi Hou To: , , , , , , , CC: Lizhi Hou , , , Subject: [PATCH V2] accel/amdxdna: Drop dma-buf wrapping for ubuf Date: Mon, 21 Sep 2026 14:14:48 -0700 Message-ID: <20260921211448.39832-1-lizhi.hou@amd.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF00002321:EE_|PH8PR12MB6843:EE_ X-MS-Office365-Filtering-Correlation-Id: fdea2e81-fae9-466f-5735-08df18256287 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|23010399003|82310400026|1800799024|36860700016|18002099003|56012099006|11063799006|5023799004|10067099003; X-Microsoft-Antispam-Message-Info: p13sFjIKQF4kj154QQsbBYcmu6Ch2oDOLvkMtxU0nbpC+Jb56+dWMBOoR3UWjxDXZFehw1ZCtMq0lpeZ25HtuBeggD0VXtDo0W9z/63dECcviXRQDK79WV0uPiDFYvrgjqKSrQ/icowFkN+U1ldOw8k06KJMr+E1W6NGfX/5WC9+T6HjfFGAW+7uqXH1MQp4l3Ln0L3f3P7hQNb++0Rk0rtFQnxHQEvaJYkqUELUhMd7Y0QEx1maHdpw+4anPSLxcRww/jaCYsIaHATQha5CR5pPViAQXt+23bolK/yqiphsYAh6YG0IAYQTSjrUDrjrpWBx1E7etNNAs06kk0sttKym/PQGopLr47qn8Ys/HEddP3jCCLg7tfJM29AhuMlffNuh2d04sclxr5BUTnj6xO5klXxEF1d4LQwXALZ/7CQqZ2vyvm/Z2Uk9RBFilN+fLVeTvDXg2jRXBDfwwY6NQq9zTnaggFqo/yHdp+jhUbnkyaLcVngMOMROgZpMzpu2k/qCgIrOzMLr3ruuDAoO3VI6kSzPH5GrxBLRRGulR1E6EjP/i8h7kywc4uFygsF0BtJTA02TydfkIfLwF4osHSd6VujNSutbv5ylR6qqjuhsbKOCnyMvecEBgxMR24GVzMZTgospPqXsdxiXAkPH+mkxzKdWz4vQEvBS69VBnNTK8i+lykM9L+mH1piOPHmh/8LKvfolWznpjYEbAkCeCg== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(23010399003)(82310400026)(1800799024)(36860700016)(18002099003)(56012099006)(11063799006)(5023799004)(10067099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: l9R/nNXw03nlh9eXCd1XtpZac+IgtU44rtyrwHhD6aI6OehMAGyfNMzwKwJpxaSYqXv6gBugkso2QRNegdftiiCSbnEnsqN69EgSXaBRDvUv5WjBK6htbkMqXktYRXjfLNPGR5SHynCVXVPWWxMHdPlkiY0yjFJoyAtOhff21OK9ZeIEfHzX2i2aG1Zb/Q2bSKWL4VH06M9KBRxW1DoHuXmK1YNNBk76AQSkQtJWLjvn+FV843wFsBa3udj/Qkiv1WCOypDoKMo5FcM9aM+52fLdDN6FeU56QKEgZyu8hhUXOHC7QYXVfxP2u8Ak7xyJcPnEcOAqJZJrM9FlZ0EglrITViINNAPJeregortF06nQu2o9BpyUISIHBg8UCOP+qlMM0dTiEDZY/DuzTY210z/pzi5P4/B3qiHLd23q9bV7qCNxNi4ocIi4aAsDBgAx X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2026 21:14:55.5121 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fdea2e81-fae9-466f-5735-08df18256287 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ1PEPF00002321.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR12MB6843 Content-Type: text/plain; charset="utf-8" A ubuf buffer is a range of existing userspace memory passed in through CREATE_BO. The driver currently wraps those pages in a dma-buf, then imports that dma-buf as a GEM object. The extra layer does not add a sharing path: ubuf is not exportable, and the pages never belonged to the driver in the first place. Make ubuf a DRM GEM private object and tracks the user VA with HMM instead of a long-term pin. - Create the BO directly from the VA table without going through dma-buf. Export stays unsupported. - Drop pin_user_pages(FOLL_LONGTERM). Create registers an MMU interval notifier over the user range and marks it invalid. Command submit faults the range in if it is still invalid. That only works with PASID, which is the only mode where ubuf is supported. Signed-off-by: Lizhi Hou --- V2: Fix sashiko comment: remove holding process's virtual address space. drivers/accel/amdxdna/amdxdna_gem.c | 85 ++++++----- drivers/accel/amdxdna/amdxdna_gem.h | 12 ++ drivers/accel/amdxdna/amdxdna_ubuf.c | 207 ++++++++++----------------- drivers/accel/amdxdna/amdxdna_ubuf.h | 8 +- 4 files changed, 138 insertions(+), 174 deletions(-) diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/am= dxdna_gem.c index f4832337ec31..a3d9a54c6563 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.c +++ b/drivers/accel/amdxdna/amdxdna_gem.c @@ -164,8 +164,7 @@ void amdxdna_gem_heap_free(struct amdxdna_client *clien= t, struct amdxdna_gem_obj mutex_unlock(&client->mm_lock); } =20 -static void -amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo) +void amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo) { mutex_destroy(&abo->lock); kfree(abo); @@ -190,7 +189,9 @@ void *amdxdna_gem_vmap(struct amdxdna_gem_obj *abo) =20 if (!abo->mem.kva) { ret =3D drm_gem_vmap(to_gobj(abo), &map); - if (ret) + if (ret =3D=3D -EOPNOTSUPP) + XDNA_DBG(xdna, "Vmap bo is not supported"); + else if (ret) XDNA_ERR(xdna, "Vmap bo failed, ret %d", ret); else abo->mem.kva =3D map.vaddr; @@ -291,7 +292,7 @@ static void amdxdna_hmm_unregister(struct amdxdna_gem_o= bj *abo, up_write(&xdna->notifier_lock); } =20 -static void amdxdna_hmm_unreg_umaps(struct amdxdna_gem_obj *abo, bool forc= e) +void amdxdna_hmm_unreg_umaps(struct amdxdna_gem_obj *abo, bool force) { struct amdxdna_dev *xdna =3D to_xdna_dev(to_gobj(abo)->dev); struct amdxdna_umap *mapp, *tmp; @@ -335,12 +336,11 @@ static void amdxdna_hmm_unreg_work(struct work_struct= *work) amdxdna_hmm_unreg_umaps(abo, false); } =20 -static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, - struct vm_area_struct *vma) +int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, struct vm_area_struc= t *vma, + size_t offset, size_t len) { struct amdxdna_dev *xdna =3D to_xdna_dev(to_gobj(abo)->dev); - unsigned long len =3D vma->vm_end - vma->vm_start; - unsigned long addr =3D vma->vm_start; + unsigned long addr =3D vma->vm_start + offset; struct amdxdna_umap *mapp; unsigned long nr_pages; int ret; @@ -359,7 +359,7 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj = *abo, =20 down_read(&xdna->notifier_lock); list_for_each_entry(mapp, &abo->mem.umap_list, node) { - if (compare_range(mapp, current->mm, addr, addr + len)) { + if (compare_range(mapp, vma->vm_mm, addr, addr + len)) { up_read(&xdna->notifier_lock); return 0; } @@ -371,15 +371,15 @@ static int amdxdna_hmm_register(struct amdxdna_gem_ob= j *abo, return -ENOMEM; =20 nr_pages =3D (PAGE_ALIGN(addr + len) - (addr & PAGE_MASK)) >> PAGE_SHIFT; - mapp->range.hmm_pfns =3D kvzalloc_objs(*mapp->range.hmm_pfns, nr_pages); + mapp->range.hmm_pfns =3D kvzalloc_objs(*mapp->range.hmm_pfns, nr_pages, G= FP_KERNEL_ACCOUNT); if (!mapp->range.hmm_pfns) { ret =3D -ENOMEM; goto free_map; } =20 mapp->range.notifier =3D &mapp->notifier; - mapp->range.start =3D vma->vm_start; - mapp->range.end =3D vma->vm_end; + mapp->range.start =3D addr; + mapp->range.end =3D addr + len; /* * Access permissions are fixed at mmap() time. Changing them later * with mprotect() is not supported: the range keeps requesting the @@ -393,7 +393,7 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj = *abo, kref_init(&mapp->refcnt); =20 ret =3D mmu_interval_notifier_insert_locked(&mapp->notifier, - current->mm, + vma->vm_mm, addr, len, &amdxdna_hmm_ops); @@ -417,7 +417,7 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj = *abo, return ret; } =20 -static struct amdxdna_gem_obj * +struct amdxdna_gem_obj * amdxdna_gem_create_obj(struct drm_device *dev, size_t size) { struct amdxdna_gem_obj *abo; @@ -462,8 +462,9 @@ static void amdxdna_gem_dev_obj_free(struct drm_gem_obj= ect *gobj) amdxdna_gem_destroy_obj(abo); } =20 -static void amdxdna_mark_mapp_invalid(struct amdxdna_gem_obj *abo, - struct vm_area_struct *vma) +void amdxdna_mark_mapp_invalid(struct amdxdna_gem_obj *abo, + struct mm_struct *mm, + unsigned long start, unsigned long end) { struct amdxdna_dev *xdna =3D to_xdna_dev(to_gobj(abo)->dev); struct amdxdna_umap *mapp; @@ -471,7 +472,7 @@ static void amdxdna_mark_mapp_invalid(struct amdxdna_ge= m_obj *abo, down_write(&xdna->notifier_lock); abo->mem.map_invalid =3D true; list_for_each_entry(mapp, &abo->mem.umap_list, node) { - if (compare_range(mapp, vma->vm_mm, vma->vm_start, vma->vm_end)) { + if (compare_range(mapp, mm, start, end)) { mapp->invalid =3D true; break; } @@ -502,7 +503,7 @@ static int amdxdna_insert_pages(struct amdxdna_gem_obj = *abo, return ret; } =20 - amdxdna_mark_mapp_invalid(abo, vma); + amdxdna_mark_mapp_invalid(abo, vma->vm_mm, vma->vm_start, vma->vm_end); =20 /* Drop the reference drm_gem_mmap_obj() acquired.*/ drm_gem_object_put(to_gobj(abo)); @@ -539,7 +540,7 @@ static int amdxdna_gem_obj_mmap(struct drm_gem_object *= gobj, drm_vma_node_offset_addr(&gobj->vma_node), abo->type, vma->vm_start, gobj->size); =20 - ret =3D amdxdna_hmm_register(abo, vma); + ret =3D amdxdna_hmm_register(abo, vma, 0, vma->vm_end - vma->vm_start); if (ret) return ret; =20 @@ -682,7 +683,7 @@ static struct dma_buf *amdxdna_gem_prime_export(struct = drm_gem_object *gobj, int struct amdxdna_gem_obj *abo =3D to_xdna_obj(gobj); DEFINE_DMA_BUF_EXPORT_INFO(exp_info); =20 - if (abo->private_buffer) + if (is_private_bo(abo)) return ERR_PTR(-EOPNOTSUPP); =20 if (abo->dma_buf) { @@ -766,7 +767,7 @@ static void amdxdna_gem_obj_free(struct drm_gem_object = *gobj) drm_gem_shmem_free(&abo->base); } =20 -static int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_fi= le *filp) +int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *fil= p) { struct amdxdna_dev *xdna =3D to_xdna_dev(gobj->dev); struct amdxdna_gem_obj *abo =3D to_xdna_obj(gobj); @@ -805,7 +806,7 @@ static int amdxdna_gem_obj_open(struct drm_gem_object *= gobj, struct drm_file *fi return 0; } =20 -static void amdxdna_gem_obj_close(struct drm_gem_object *gobj, struct drm_= file *filp) +void amdxdna_gem_obj_close(struct drm_gem_object *gobj, struct drm_file *f= ilp) { struct amdxdna_gem_obj *abo =3D to_xdna_obj(gobj); struct amdxdna_client *client =3D NULL; @@ -991,40 +992,46 @@ amdxdna_gem_create_shmem_object(struct drm_device *de= v, struct amdxdna_drm_creat } =20 static struct amdxdna_gem_obj * -amdxdna_gem_create_ubuf_object(struct drm_device *dev, struct amdxdna_drm_= create_bo *args) +amdxdna_gem_create_ubuf_object(struct drm_device *dev, + struct amdxdna_drm_create_bo *args, + struct drm_file *filp) { + struct amdxdna_client *client =3D filp->driver_priv; struct amdxdna_dev *xdna =3D to_xdna_dev(dev); struct amdxdna_drm_va_tbl va_tbl; struct amdxdna_gem_obj *abo; struct drm_gem_object *gobj; struct dma_buf *dma_buf; =20 + if (args->type =3D=3D AMDXDNA_BO_DEV_HEAP || args->type =3D=3D AMDXDNA_BO= _CMD) + return ERR_PTR(-EOPNOTSUPP); + if (copy_from_user(&va_tbl, u64_to_user_ptr(args->vaddr), sizeof(va_tbl))= ) { XDNA_DBG(xdna, "Access va table failed"); return ERR_PTR(-EINVAL); } =20 if (va_tbl.num_entries) { - dma_buf =3D amdxdna_get_ubuf(dev, va_tbl.num_entries, - u64_to_user_ptr(args->vaddr + sizeof(va_tbl))); + abo =3D amdxdna_alloc_ubuf_bo(client, va_tbl.num_entries, + u64_to_user_ptr(args->vaddr + sizeof(va_tbl))); + if (IS_ERR(abo)) + return abo; } else { dma_buf =3D dma_buf_get(va_tbl.dmabuf_fd); - } + if (IS_ERR(dma_buf)) + return ERR_CAST(dma_buf); =20 - if (IS_ERR(dma_buf)) - return ERR_CAST(dma_buf); + gobj =3D amdxdna_gem_prime_import(dev, dma_buf); + if (IS_ERR(gobj)) { + dma_buf_put(dma_buf); + return ERR_CAST(gobj); + } =20 - gobj =3D amdxdna_gem_prime_import(dev, dma_buf); - if (IS_ERR(gobj)) { dma_buf_put(dma_buf); - return ERR_CAST(gobj); + abo =3D to_xdna_obj(gobj); } =20 - dma_buf_put(dma_buf); - - abo =3D to_xdna_obj(gobj); abo->private_buffer =3D true; - return abo; } =20 @@ -1112,7 +1119,7 @@ amdxdna_drm_create_share_bo(struct drm_device *dev, struct amdxdna_gem_obj *abo; =20 if (args->vaddr) - abo =3D amdxdna_gem_create_ubuf_object(dev, args); + abo =3D amdxdna_gem_create_ubuf_object(dev, args, filp); else if (amdxdna_use_carveout(to_xdna_dev(dev))) abo =3D amdxdna_gem_create_cbuf_object(dev, args); else @@ -1293,7 +1300,7 @@ static int amdxdna_bo_pin(struct amdxdna_gem_obj *abo) struct amdxdna_dev *xdna =3D to_xdna_dev(to_gobj(abo)->dev); int ret; =20 - if (is_import_bo(abo)) + if (is_import_bo(abo) || is_private_bo(abo)) return 0; =20 ret =3D drm_gem_shmem_pin(&abo->base); @@ -1306,7 +1313,7 @@ static void amdxdna_bo_unpin(struct amdxdna_gem_obj *= abo) { struct amdxdna_dev *xdna =3D to_xdna_dev(to_gobj(abo)->dev); =20 - if (is_import_bo(abo)) + if (is_import_bo(abo) || is_private_bo(abo)) return; =20 drm_gem_shmem_unpin(&abo->base); @@ -1406,7 +1413,7 @@ int amdxdna_drm_get_bo_info_ioctl(struct drm_device *= dev, void *data, struct drm args->vaddr =3D amdxdna_gem_uva(abo); args->xdna_addr =3D amdxdna_gem_dev_addr(abo); =20 - if (abo->type !=3D AMDXDNA_BO_DEV) + if (abo->type !=3D AMDXDNA_BO_DEV && !is_private_bo(abo)) args->map_offset =3D drm_vma_node_offset_addr(&gobj->vma_node); else args->map_offset =3D AMDXDNA_INVALID_ADDR; diff --git a/drivers/accel/amdxdna/amdxdna_gem.h b/drivers/accel/amdxdna/am= dxdna_gem.h index 9b4aa21a37c9..815348a3c429 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.h +++ b/drivers/accel/amdxdna/amdxdna_gem.h @@ -60,6 +60,7 @@ struct amdxdna_gem_obj { =20 #define to_gobj(obj) (&(obj)->base.base) #define is_import_bo(obj) ((obj)->attach) +#define is_private_bo(obj) ((obj)->private_buffer) =20 static inline struct amdxdna_gem_obj *to_xdna_obj(struct drm_gem_object *g= obj) { @@ -112,10 +113,21 @@ amdxdna_gem_prime_import(struct drm_device *dev, stru= ct dma_buf *dma_buf); struct amdxdna_gem_obj * amdxdna_drm_create_dev_bo(struct drm_device *dev, struct amdxdna_drm_create_bo *args, struct drm_file *filp); +struct amdxdna_gem_obj * +amdxdna_gem_create_obj(struct drm_device *dev, size_t size); +void amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo); +void amdxdna_hmm_unreg_umaps(struct amdxdna_gem_obj *abo, bool force); =20 int amdxdna_gem_pin_nolock(struct amdxdna_gem_obj *abo); int amdxdna_gem_pin(struct amdxdna_gem_obj *abo); void amdxdna_gem_unpin(struct amdxdna_gem_obj *abo); +int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *fil= p); +void amdxdna_gem_obj_close(struct drm_gem_object *gobj, struct drm_file *f= ilp); +int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, struct vm_area_struc= t *vma, + size_t offset, size_t len); +void amdxdna_mark_mapp_invalid(struct amdxdna_gem_obj *abo, + struct mm_struct *mm, + unsigned long start, unsigned long end); =20 int amdxdna_drm_create_bo_ioctl(struct drm_device *dev, void *data, struct= drm_file *filp); int amdxdna_drm_get_bo_info_ioctl(struct drm_device *dev, void *data, stru= ct drm_file *filp); diff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/a= mdxdna_ubuf.c index 0e0cd69cd1fb..5c291786d981 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -6,182 +6,127 @@ #include #include #include -#include #include #include #include =20 +#include "amdxdna_gem.h" #include "amdxdna_pci_drv.h" #include "amdxdna_ubuf.h" =20 -struct amdxdna_ubuf_priv { - struct page **pages; - u64 nr_pages; - struct mm_struct *mm; -}; - -static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, - enum dma_data_direction direction) +static int amdxdna_ubuf_hmm_register(struct amdxdna_client *client, + struct amdxdna_gem_obj *abo, + struct amdxdna_drm_va_entry *va_ent) { - struct amdxdna_ubuf_priv *ubuf =3D attach->dmabuf->priv; - struct sg_table *sg; + struct vm_area_struct *vma; int ret; =20 - sg =3D kzalloc_obj(*sg); - if (!sg) - return ERR_PTR(-ENOMEM); - - ret =3D sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->nr_pages, 0, - ubuf->nr_pages << PAGE_SHIFT, GFP_KERNEL); - if (ret) - goto err_free_sg; + mmap_write_lock(client->mm); + vma =3D find_vma(client->mm, va_ent->vaddr); + if (!vma || vma->vm_start > va_ent->vaddr || + vma->vm_end - va_ent->vaddr < va_ent->len) { + ret =3D -EINVAL; + goto unlock; + } =20 - ret =3D dma_map_sgtable(attach->dev, sg, direction, 0); - if (ret) - goto err_free_table; + ret =3D amdxdna_hmm_register(abo, vma, va_ent->vaddr - vma->vm_start, va_= ent->len); =20 - return sg; +unlock: + mmap_write_unlock(client->mm); =20 -err_free_table: - sg_free_table(sg); -err_free_sg: - kfree(sg); - return ERR_PTR(ret); + return ret; } =20 -static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach, - struct sg_table *sg, - enum dma_data_direction direction) +static void amdxdna_gem_ubuf_obj_free(struct drm_gem_object *gobj) { - dma_unmap_sgtable(attach->dev, sg, direction, 0); - sg_free_table(sg); - kfree(sg); + struct amdxdna_gem_obj *abo =3D to_xdna_obj(gobj); + + amdxdna_hmm_unreg_umaps(abo, true); + cancel_work_sync(&abo->hmm_unreg_work); + + drm_gem_object_release(gobj); + amdxdna_gem_destroy_obj(abo); } =20 -static void amdxdna_ubuf_release(struct dma_buf *dbuf) +static struct dma_buf *amdxdna_gem_ubuf_obj_export(struct drm_gem_object *= gobj, int flags) { - struct amdxdna_ubuf_priv *ubuf =3D dbuf->priv; - - unpin_user_pages(ubuf->pages, ubuf->nr_pages); - kvfree(ubuf->pages); - atomic64_sub(ubuf->nr_pages, &ubuf->mm->pinned_vm); - mmdrop(ubuf->mm); - kfree(ubuf); + return ERR_PTR(-EOPNOTSUPP); } =20 -static const struct dma_buf_ops amdxdna_ubuf_dmabuf_ops =3D { - .map_dma_buf =3D amdxdna_ubuf_map, - .unmap_dma_buf =3D amdxdna_ubuf_unmap, - .release =3D amdxdna_ubuf_release, +static const struct drm_gem_object_funcs amdxdna_gem_ubuf_obj_funcs =3D { + .free =3D amdxdna_gem_ubuf_obj_free, + .open =3D amdxdna_gem_obj_open, + .close =3D amdxdna_gem_obj_close, + .export =3D amdxdna_gem_ubuf_obj_export, }; =20 -struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev, - u32 num_entries, void __user *va_entries) +struct amdxdna_gem_obj *amdxdna_alloc_ubuf_bo(struct amdxdna_client *clien= t, + u32 num_entries, void __user *va_entries) { - struct amdxdna_dev *xdna =3D to_xdna_dev(dev); - unsigned long lock_limit, new_pinned; + struct amdxdna_dev *xdna =3D client->xdna; struct amdxdna_drm_va_entry *va_ent; - struct amdxdna_ubuf_priv *ubuf; - u32 npages, start =3D 0; - struct dma_buf *dbuf; - int i, ret; - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct amdxdna_gem_obj *abo; + size_t bufsize; + long ret; =20 - if (!can_do_mlock()) - return ERR_PTR(-EPERM); + if (!amdxdna_pasid_on(client)) + return ERR_PTR(-EOPNOTSUPP); =20 - ubuf =3D kzalloc_obj(*ubuf); - if (!ubuf) - return ERR_PTR(-ENOMEM); + /* + * There is not any valid case to use more than 1 entry. + * Hardcode maximum entries to 1. + */ + if (num_entries > 1) + return ERR_PTR(-EINVAL); =20 - ubuf->mm =3D current->mm; - mmgrab(ubuf->mm); + if (current->mm !=3D client->mm) + return ERR_PTR(-EINVAL); =20 - va_ent =3D kvzalloc_objs(*va_ent, num_entries); - if (!va_ent) { - ret =3D -ENOMEM; - goto free_ubuf; - } + va_ent =3D kvzalloc_obj(*va_ent); + if (!va_ent) + return ERR_PTR(-ENOMEM); =20 - if (copy_from_user(va_ent, va_entries, sizeof(*va_ent) * num_entries)) { + if (copy_from_user(va_ent, va_entries, sizeof(*va_ent))) { XDNA_DBG(xdna, "Access va entries failed"); ret =3D -EINVAL; goto free_ent; } =20 - for (i =3D 0, exp_info.size =3D 0; i < num_entries; i++) { - if (!IS_ALIGNED(va_ent[i].vaddr, PAGE_SIZE) || - !IS_ALIGNED(va_ent[i].len, PAGE_SIZE)) { - XDNA_ERR(xdna, "Invalid address or len %llx, %llx", - va_ent[i].vaddr, va_ent[i].len); - ret =3D -EINVAL; - goto free_ent; - } - - if (check_add_overflow(exp_info.size, va_ent[i].len, &exp_info.size)) { - ret =3D -EINVAL; - goto free_ent; - } - } - - ubuf->nr_pages =3D exp_info.size >> PAGE_SHIFT; - lock_limit =3D rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - new_pinned =3D atomic64_add_return(ubuf->nr_pages, &ubuf->mm->pinned_vm); - if (new_pinned > lock_limit && !capable(CAP_IPC_LOCK)) { - XDNA_DBG(xdna, "New pin %ld, limit %ld, cap %d", - new_pinned, lock_limit, capable(CAP_IPC_LOCK)); - ret =3D -ENOMEM; - goto sub_pin_cnt; + if (!IS_ALIGNED(va_ent->vaddr, PAGE_SIZE) || + !IS_ALIGNED(va_ent->len, PAGE_SIZE) || + !va_ent->len || + check_add_overflow(va_ent->vaddr, va_ent->len, &bufsize)) { + XDNA_DBG(xdna, "Invalid address or len %llx, %llx", + va_ent->vaddr, va_ent->len); + ret =3D -EINVAL; + goto free_ent; } =20 - ubuf->pages =3D kvmalloc_objs(*ubuf->pages, ubuf->nr_pages); - if (!ubuf->pages) { - ret =3D -ENOMEM; - goto sub_pin_cnt; + bufsize =3D va_ent->len; + abo =3D amdxdna_gem_create_obj(&xdna->ddev, bufsize); + if (IS_ERR(abo)) { + ret =3D PTR_ERR(abo); + goto free_ent; } =20 - for (i =3D 0; i < num_entries; i++) { - npages =3D va_ent[i].len >> PAGE_SHIFT; - - ret =3D pin_user_pages_fast(va_ent[i].vaddr, npages, - FOLL_WRITE | FOLL_LONGTERM, - &ubuf->pages[start]); - if (ret >=3D 0) { - start +=3D ret; - if (ret !=3D npages) { - XDNA_ERR(xdna, "Partially pinned pages %d/%u", ret, npages); - ret =3D -ENOMEM; - goto destroy_pages; - } - } else { - XDNA_ERR(xdna, "Failed to pin pages ret %d", ret); - goto destroy_pages; - } - } + abo->type =3D AMDXDNA_BO_SHARE; + abo->mem.uva =3D va_ent->vaddr; + to_gobj(abo)->funcs =3D &amdxdna_gem_ubuf_obj_funcs; + drm_gem_private_object_init(&xdna->ddev, to_gobj(abo), bufsize); =20 - exp_info.ops =3D &amdxdna_ubuf_dmabuf_ops; - exp_info.priv =3D ubuf; - exp_info.flags =3D O_RDWR | O_CLOEXEC; + ret =3D amdxdna_ubuf_hmm_register(client, abo, va_ent); + if (ret) + goto put_obj; =20 - dbuf =3D dma_buf_export(&exp_info); - if (IS_ERR(dbuf)) { - ret =3D PTR_ERR(dbuf); - goto destroy_pages; - } + amdxdna_mark_mapp_invalid(abo, client->mm, va_ent->vaddr, + va_ent->vaddr + va_ent->len); kvfree(va_ent); =20 - return dbuf; + return abo; =20 -destroy_pages: - if (start) - unpin_user_pages(ubuf->pages, start); - kvfree(ubuf->pages); -sub_pin_cnt: - atomic64_sub(ubuf->nr_pages, &ubuf->mm->pinned_vm); +put_obj: + drm_gem_object_put(to_gobj(abo)); free_ent: kvfree(va_ent); -free_ubuf: - mmdrop(ubuf->mm); - kfree(ubuf); return ERR_PTR(ret); } diff --git a/drivers/accel/amdxdna/amdxdna_ubuf.h b/drivers/accel/amdxdna/a= mdxdna_ubuf.h index 8900a6dc4371..f6335603da34 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.h +++ b/drivers/accel/amdxdna/amdxdna_ubuf.h @@ -5,10 +5,10 @@ #ifndef _AMDXDNA_UBUF_H_ #define _AMDXDNA_UBUF_H_ =20 -#include -#include +#include "amdxdna_gem.h" +#include "amdxdna_pci_drv.h" =20 -struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev, - u32 num_entries, void __user *va_entries); +struct amdxdna_gem_obj *amdxdna_alloc_ubuf_bo(struct amdxdna_client *clien= t, + u32 num_entries, void __user *va_entries); =20 #endif /* _AMDXDNA_UBUF_H_ */ --=20 2.34.1