From nobody Mon Apr 6 10:42:00 2026 Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B7D03F99F3 for ; Thu, 19 Mar 2026 20:25:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773951936; cv=none; b=CdURbpi4cMIaSuplqMrt1zvLSt/ttjU0f/NNVUUmbMS+GO5MXA6YXgoRnFkcl6/aKTYOBjNJTgrDcdSaAeXbraBqWBba/ASlY5phXVBdFyvoXR12RQFib+eqkH7wwqcMSkGbWgznWqVOUHftmreiZErtFqRr8RSwt6TyYobRiao= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773951936; c=relaxed/simple; bh=XYXh9hWNCjjaYxIFWsgzSpcYNdUPkATphGgllc+kOiE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JFImNmiAgcMZ84hf8Ia+PkE8WrzWjY5bTEXS93nidUlGVIPNeAD3P4QNO/imQoIxkVHhLx5im4ApfWCjc22LGetXMC7t3jOUZXC9HQtJntq0qGATteabDTGThxYT4kzsO3WXtNzpbGBXTUX5OP2t6aP9mTVBfg+1JGSRNuV+D3U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lFiZAwEV; arc=none smtp.client-ip=209.85.221.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lFiZAwEV" Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-439b611274bso598432f8f.3 for ; Thu, 19 Mar 2026 13:25:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773951931; x=1774556731; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IfwWxdi0huZ+o5QErDeADcsmeHgqSR0aJcBxkGUgmUc=; b=lFiZAwEV2mQH2cRU2fS6EmzCi6rISVLe6QcO7cLDyubLtp1uaUNqR3ZuuGssjsI6vJ GyR1stFWt12C8tVR2x6V2AOkge+n/ufNtkqOb8o3AxduGD3Fzx/kTw2P+Svemfl4kn5V dDhN7tfMCpzJFc3VLcXAvhw+Li1WRFOD+l+M6Yca43DnNjbsQ8jCCXrWtuQ8ISM349/7 qTHIHBF15VxmfJdjMeAO8zW8kXUt2hhPeDVm/NDEVBvmJn73w1x3rj5ud2MdGMQcx/Nc Tse8cZrYhlpy1GAGW3Xolel6/2OjSYk4IiQU5BuW8AGTJVurCf0qOZPCafEsGcyISZGv HYlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773951931; x=1774556731; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=IfwWxdi0huZ+o5QErDeADcsmeHgqSR0aJcBxkGUgmUc=; b=Wwpavc0lHOZdB83YGBHIdBsvJIIf7L63Xeb3qvROXNqirjLWRdGfMWWcIHT9w+SFAW 3yBDsixdNJg+UQmENq+Edvme0x5tgSE+1tcyKyr5nKzipYY7//4bImp8pkWMojcPGqCo moC1iJmnFQXcDpGMVDqVjTjAGom7u2H4nQuB6NJJJ4hN4FycOadgxgbQUNrcR3PzZ1ss ++TJ6l63LZFyB6tUjUlGlFhKj131QEEAa0sG4TOQWVQHYw0YzT5GDXpQEZonaTwakyO+ gsAH/7YsfFraUpI6u/PHKjoUwwGNZox6bSJ33I1FxVNdzsfn3VFzjyFulCcEFHjOcaga 1wCw== X-Gm-Message-State: AOJu0YxI61o0Paa95IVFRs+a0hX5lEMysGlAMrB/fLv1yvb0LjSsYI1m rWyJt4wmC7iIKhubi97k1QLfh1u++KrCgNqiYeVk59KhENpSQo0AvnUu X-Gm-Gg: ATEYQzx0FpI5gQzQx3tmRHU0qcLPlgGANWzKcSOJIGC57b4lGPrkX4bxJ0dsNwPczBv YMwFp1XplsO8jyfYfwwGV0amcBu8IL4jvlPmlk0A1+uL5vUaQAR/bMiJrqxgVUNw4JoEGK/Mcph gH+4Q3EFuR/Chh0sqi8ysVM5l3M7YKiC4LTHYGJBa0IPm3+/RF3lc0YIUKmyhHiIFLXaFdF+3rm sOMeJQaxM5h2YhpBnsana162HuCIypS/kzRbxwDfepU+d4rMk0zIpe0CdTxg5Y+Sh3VY4M7Hfui KeX4UeXndB/b6Ry+MPykJfmg1poMe2iNMmrItk7bTp1BGY73+/gboaFN5n+eHsOwasH1dgs1np4 KfUb0jt2pOQuTWH6cKS+oUhIy8aSjMIkAmOURMfLghUp4CU1lX/I7wgJSf7zrFMt8OYl2R03KJ+ uGMzFebuWq+CpaDUWAmc4go5kcrMz3Zuo4Ruv5fZuqsEkhMe79 X-Received: by 2002:a05:6000:2012:b0:43b:3c49:c393 with SMTP id ffacd0b85a97d-43b6424432dmr1211203f8f.18.1773951931428; Thu, 19 Mar 2026 13:25:31 -0700 (PDT) Received: from LQ5W56KC4T ([2001:8a0:672f:7800:e0e1:55cd:f0b:b1e5]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43b644ae16fsm1347544f8f.8.2026.03.19.13.25.30 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 19 Mar 2026 13:25:30 -0700 (PDT) From: Eric Curtin X-Google-Original-From: Eric Curtin To: linux-hyperv@vger.kernel.org Cc: linux-kernel@vger.kernel.org, iourit@linux.microsoft.com, wei.liu@kernel.org, decui@microsoft.com, haiyangz@microsoft.com Subject: [PATCH 15/55] drivers: hv: dxgkrnl: Share objects with the host Date: Thu, 19 Mar 2026 20:24:29 +0000 Message-ID: <20260319202509.63802-16-eric.curtin@docker.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260319202509.63802-1-eric.curtin@docker.com> References: <20260319202509.63802-1-eric.curtin@docker.com> 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 Content-Type: text/plain; charset="utf-8" From: Iouri Tarassov Implement the LX_DXSHAREOBJECTWITHHOST ioctl. This ioctl is used to create a Windows NT handle on the host for the given shared object (resource or sync object). The NT handle is returned to the caller. The caller could share the NT handle with a host application, which needs to access the object. The host application can open the shared resource using the NT handle. This way the guest and the host have access to the same object. Fix incorrect handling of error results from copy_from_user(). Signed-off-by: Iouri Tarassov [kms: forward port to 6.6 from 6.1. No code changes made.] Signed-off-by: Kelsey Steele --- drivers/hv/dxgkrnl/dxgkrnl.h | 2 ++ drivers/hv/dxgkrnl/dxgvmbus.c | 60 ++++++++++++++++++++++++++++++++--- drivers/hv/dxgkrnl/dxgvmbus.h | 18 +++++++++++ drivers/hv/dxgkrnl/ioctl.c | 38 ++++++++++++++++++++-- include/uapi/misc/d3dkmthk.h | 9 ++++++ 5 files changed, 120 insertions(+), 7 deletions(-) diff --git a/drivers/hv/dxgkrnl/dxgkrnl.h b/drivers/hv/dxgkrnl/dxgkrnl.h index ab97bc53b124..a39d11d76e41 100644 --- a/drivers/hv/dxgkrnl/dxgkrnl.h +++ b/drivers/hv/dxgkrnl/dxgkrnl.h @@ -872,6 +872,8 @@ int dxgvmb_send_get_stdalloc_data(struct dxgdevice *dev= ice, int dxgvmb_send_async_msg(struct dxgvmbuschannel *channel, void *command, u32 cmd_size); +int dxgvmb_send_share_object_with_host(struct dxgprocess *process, + struct d3dkmt_shareobjectwithhost *args); =20 void signal_host_cpu_event(struct dxghostevent *eventhdr); int ntstatus2int(struct ntstatus status); diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c index 7cb04fec217e..67a16de622e0 100644 --- a/drivers/hv/dxgkrnl/dxgvmbus.c +++ b/drivers/hv/dxgkrnl/dxgvmbus.c @@ -881,6 +881,50 @@ int dxgvmb_send_destroy_sync_object(struct dxgprocess = *process, return ret; } =20 +int dxgvmb_send_share_object_with_host(struct dxgprocess *process, + struct d3dkmt_shareobjectwithhost *args) +{ + struct dxgkvmb_command_shareobjectwithhost *command; + struct dxgkvmb_command_shareobjectwithhost_return result =3D {}; + int ret; + struct dxgvmbusmsg msg =3D {.hdr =3D NULL}; + + ret =3D init_message(&msg, NULL, process, sizeof(*command)); + if (ret) + return ret; + command =3D (void *)msg.msg; + + ret =3D dxgglobal_acquire_channel_lock(); + if (ret < 0) + goto cleanup; + + command_vm_to_host_init2(&command->hdr, + DXGK_VMBCOMMAND_SHAREOBJECTWITHHOST, + process->host_handle); + command->device_handle =3D args->device_handle; + command->object_handle =3D args->object_handle; + + ret =3D dxgvmb_send_sync_msg(dxgglobal_get_dxgvmbuschannel(), + msg.hdr, msg.size, &result, sizeof(result)); + + dxgglobal_release_channel_lock(); + + if (ret || !NT_SUCCESS(result.status)) { + if (ret =3D=3D 0) + ret =3D ntstatus2int(result.status); + DXG_ERR("Host failed to share object with host: %d %x", + ret, result.status.v); + goto cleanup; + } + args->object_vail_nt_handle =3D result.vail_nt_handle; + +cleanup: + free_message(&msg, process); + if (ret) + DXG_ERR("err: %d", ret); + return ret; +} + /* * Virtual GPU messages to the host */ @@ -2323,37 +2367,43 @@ int dxgvmb_send_create_hwqueue(struct dxgprocess *p= rocess, =20 ret =3D copy_to_user(&inargs->queue, &command->hwqueue, sizeof(struct d3dkmthandle)); - if (ret < 0) { + if (ret) { DXG_ERR("failed to copy hwqueue handle"); + ret =3D -EINVAL; goto cleanup; } ret =3D copy_to_user(&inargs->queue_progress_fence, &command->hwqueue_progress_fence, sizeof(struct d3dkmthandle)); - if (ret < 0) { + if (ret) { DXG_ERR("failed to progress fence"); + ret =3D -EINVAL; goto cleanup; } ret =3D copy_to_user(&inargs->queue_progress_fence_cpu_va, &hwqueue->progress_fence_mapped_address, sizeof(inargs->queue_progress_fence_cpu_va)); - if (ret < 0) { + if (ret) { DXG_ERR("failed to copy fence cpu va"); + ret =3D -EINVAL; goto cleanup; } ret =3D copy_to_user(&inargs->queue_progress_fence_gpu_va, &command->hwqueue_progress_fence_gpuva, sizeof(u64)); - if (ret < 0) { + if (ret) { DXG_ERR("failed to copy fence gpu va"); + ret =3D -EINVAL; goto cleanup; } if (args->priv_drv_data_size) { ret =3D copy_to_user(args->priv_drv_data, command->priv_drv_data, args->priv_drv_data_size); - if (ret < 0) + if (ret) { DXG_ERR("failed to copy private data"); + ret =3D -EINVAL; + } } =20 cleanup: diff --git a/drivers/hv/dxgkrnl/dxgvmbus.h b/drivers/hv/dxgkrnl/dxgvmbus.h index acfdbde09e82..c1f693917d99 100644 --- a/drivers/hv/dxgkrnl/dxgvmbus.h +++ b/drivers/hv/dxgkrnl/dxgvmbus.h @@ -574,4 +574,22 @@ struct dxgkvmb_command_destroyhwqueue { struct d3dkmthandle hwqueue; }; =20 +struct dxgkvmb_command_shareobjectwithhost { + struct dxgkvmb_command_vm_to_host hdr; + struct d3dkmthandle device_handle; + struct d3dkmthandle object_handle; + u64 reserved; +}; + +struct dxgkvmb_command_shareobjectwithhost_return { + struct ntstatus status; + u32 alignment; + u64 vail_nt_handle; +}; + +int +dxgvmb_send_sync_msg(struct dxgvmbuschannel *channel, + void *command, u32 command_size, void *result, + u32 result_size); + #endif /* _DXGVMBUS_H */ diff --git a/drivers/hv/dxgkrnl/ioctl.c b/drivers/hv/dxgkrnl/ioctl.c index 9128694c8e78..ac052836ce27 100644 --- a/drivers/hv/dxgkrnl/ioctl.c +++ b/drivers/hv/dxgkrnl/ioctl.c @@ -2460,6 +2460,7 @@ dxgkio_open_sync_object_nt(struct dxgprocess *process= , void *__user inargs) if (ret =3D=3D 0) goto success; DXG_ERR("failed to copy output args"); + ret =3D -EINVAL; =20 cleanup: =20 @@ -3364,8 +3365,10 @@ dxgkio_share_objects(struct dxgprocess *process, voi= d *__user inargs) tmp =3D (u64) object_fd; =20 ret =3D copy_to_user(args.shared_handle, &tmp, sizeof(u64)); - if (ret < 0) + if (ret) { DXG_ERR("failed to copy shared handle"); + ret =3D -EINVAL; + } =20 cleanup: if (ret < 0) { @@ -3773,6 +3776,37 @@ dxgkio_open_resource_nt(struct dxgprocess *process, return ret; } =20 +static int +dxgkio_share_object_with_host(struct dxgprocess *process, void *__user ina= rgs) +{ + struct d3dkmt_shareobjectwithhost args; + int ret; + + ret =3D copy_from_user(&args, inargs, sizeof(args)); + if (ret) { + DXG_ERR("failed to copy input args"); + ret =3D -EINVAL; + goto cleanup; + } + + ret =3D dxgvmb_send_share_object_with_host(process, &args); + if (ret) { + DXG_ERR("dxgvmb_send_share_object_with_host dailed"); + goto cleanup; + } + + ret =3D copy_to_user(inargs, &args, sizeof(args)); + if (ret) { + DXG_ERR("failed to copy data to user"); + ret =3D -EINVAL; + } + +cleanup: + + DXG_TRACE("ioctl:%s %d", errorstr(ret), ret); + return ret; +} + static struct ioctl_desc ioctls[] =3D { /* 0x00 */ {}, /* 0x01 */ {dxgkio_open_adapter_from_luid, LX_DXOPENADAPTERFROMLUID}, @@ -3850,7 +3884,7 @@ static struct ioctl_desc ioctls[] =3D { LX_DXQUERYRESOURCEINFOFROMNTHANDLE}, /* 0x42 */ {dxgkio_open_resource_nt, LX_DXOPENRESOURCEFROMNTHANDLE}, /* 0x43 */ {}, -/* 0x44 */ {}, +/* 0x44 */ {dxgkio_share_object_with_host, LX_DXSHAREOBJECTWITHHOST}, /* 0x45 */ {}, }; =20 diff --git a/include/uapi/misc/d3dkmthk.h b/include/uapi/misc/d3dkmthk.h index 9238115d165d..895861505e6e 100644 --- a/include/uapi/misc/d3dkmthk.h +++ b/include/uapi/misc/d3dkmthk.h @@ -952,6 +952,13 @@ struct d3dkmt_enumadapters3 { #endif }; =20 +struct d3dkmt_shareobjectwithhost { + struct d3dkmthandle device_handle; + struct d3dkmthandle object_handle; + __u64 reserved; + __u64 object_vail_nt_handle; +}; + /* * Dxgkrnl Graphics Port Driver ioctl definitions * @@ -1021,5 +1028,7 @@ struct d3dkmt_enumadapters3 { _IOWR(0x47, 0x41, struct d3dkmt_queryresourceinfofromnthandle) #define LX_DXOPENRESOURCEFROMNTHANDLE \ _IOWR(0x47, 0x42, struct d3dkmt_openresourcefromnthandle) +#define LX_DXSHAREOBJECTWITHHOST \ + _IOWR(0x47, 0x44, struct d3dkmt_shareobjectwithhost) =20 #endif /* _D3DKMTHK_H */