From nobody Mon Apr 6 10:42:01 2026 Received: from mail-wr1-f47.google.com (mail-wr1-f47.google.com [209.85.221.47]) (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 D3EA13FCB1C for ; Thu, 19 Mar 2026 20:25:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773951955; cv=none; b=AIPz8Rl22OxBQ8+F8BgiZ0xE758yMmefJkGRXBGBsRK6uJBl2aWobfBQrk6ghDjtx2hzYSBfSW76/X/j8iQIVYMSUHympdjJ7FGMEC9/7OTI6lBJUdLyJ1DjTlHVyO6BPaJXYLCdIIvt9gWlPwi/A9B2cRUjJAJz7YluTAh0UZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773951955; c=relaxed/simple; bh=lbJJqathQ0RsrVpKR+Bj4fX/ytc5wlKUMv0nb6CZSto=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HznOQQ0lmhQjE9UKvjwGiJ1zGct6gH2S+lYhi7mjFnnBHsaX3DKyP6HpBX19K2HPMYD8pV6GSWx7d+H3A7Dr1+SAwPRp/A5t66mtB+1lbToKnnhgs/xBBRPViE41JRRr8SYbiYPFPEsMtXNpjtHG6QVzARbxy8Q3C7dL/8pAVnQ= 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=gQCLFGJh; arc=none smtp.client-ip=209.85.221.47 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="gQCLFGJh" Received: by mail-wr1-f47.google.com with SMTP id ffacd0b85a97d-439cd6b0aedso839077f8f.1 for ; Thu, 19 Mar 2026 13:25:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773951949; x=1774556749; 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=yfPgBA+Pl94DE98AaTxzZlc8zjDbPiM5ZxN+Lw61xBc=; b=gQCLFGJhUnFinELTygYYEzWUR+/WXM5Kz28y76QDI0MCPbKQd8fJCuLDKum6b7KvQf bL93M/B2C519lWOr5ehriWuYbPGwRwUObN80JE0WM4s9VtPYIpW23VUNVESmIShBwJAd N93bpGYT8iehtNGN/dJkMi/5W0q0SQk4TqyPWKlBkJF5mwfMYLv+lHB/xMWm6LCySIg9 3m7iwtw7NMdYzDZJpmfOFMRTleuJiOB3lpnk/p86x820hFTIk6DLY44gXJ4yP6QL4g08 98jO26vtonKsQcyyskIuNtZznzTI+MNkznhWl8n9tpF6JmDnuqKAihqFxhQN6HPiqV+h bWNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773951949; x=1774556749; 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=yfPgBA+Pl94DE98AaTxzZlc8zjDbPiM5ZxN+Lw61xBc=; b=h/NX7HhQPaDh9Foc7GeA/nz7IDm04oa0NQjlnH4WYEVFVaATmK2EohsXpZ5VRpkIVl XjJFNUpIxyNZbB+mcyzuubjSA45fBbfjFvTVTQhFC5+MtSlFtIHcffM//NbQMkB/ovN9 4wbmSjeebTNz+EJXcPQGfcnqw6hDkbPPFn6XpoDTgYSyjGVCe58Ki6oUm6WILZNL+/u2 flS3rjMR3050nSepbJpBrhTibusBSc84XWGmAgRoV6h+FWZKt3v8CIjZ6T/cn1PWPJeW eh6u7v25ydj6PPJ2b3gvCZ3ZZnfxM2lfiWhnQoZxJ2p4cEqrLS4R3nO1i0rWt3g6PzlY VH3A== X-Gm-Message-State: AOJu0YzT8dD3qLW9CpAOw0CpPT561nAOF9BNbEV7tjgtDpXEyACxfcMM s2DS5JC0JuKnq5PwOmrobCmJJhatz091X3ReYsAWMEsH0CaXoh0lT9XC X-Gm-Gg: ATEYQzyy0S0jPgqRtzNx7BUf+I5VQKDdZj3NCc/ruowv4AYM1nvZrs7y7uVBv0Sm6zA yEK8thZLMDJZysveaocBGcMH2pCRVgZTrhpvUOv8leY89Z2vFOPtU40p797VS0PTmcRsTKg0E9U NbCYn8GFOxUiMROBucOHLCcPSU+phfnImYF5+lmvF5JAwDCSAPPUDbuLHgz+oC4OZ8ncvHGP8Cz XWgBy6jItHsGG8Ykdpg76l9Ubo3iVMCwmod05JBeGQUEiIeMdU8BgGGiHByv/mlcaRtOhAi3Erk coaEEwP1SdH1loZIPLOddAmDIdv7jFL0qGatHjnRnUvIld0oCYLE6t6nyISQIn9ZiPPU80zNVaN vxNJb7Jiy8sfULMSwNmD+HJPFcZv22QDINVAsMsH28xbhIt9iXvXb+qRAjyBJNAHIRvrg6IjWbK rzJddwOuuAkGDGj5mrl2pbIpEe80Oyfn6SkaWtzp/V0FN4wmQV X-Received: by 2002:a05:6000:420c:b0:43b:460a:b13 with SMTP id ffacd0b85a97d-43b64281506mr1176416f8f.44.1773951948875; Thu, 19 Mar 2026 13:25:48 -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.47 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 19 Mar 2026 13:25:48 -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 31/55] drivers: hv: dxgkrnl: Creation of dxgsyncfile objects Date: Thu, 19 Mar 2026 20:24:45 +0000 Message-ID: <20260319202509.63802-32-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 ioctl to create a dxgsyncfile object (LX_DXCREATESYNCFILE). This object is a wrapper around a monitored fence sync object and a fence value. dxgsyncfile is built on top of the Linux sync_file object and provides a way for the user mode to synchronize with the execution of the device DMA packets. The ioctl creates a dxgsyncfile object for the given GPU synchronization object and a fence value. A file descriptor of the sync_file object is returned to the caller. The caller could wait for the object by using poll(). When the underlying GPU synchronization object is signaled on the host, the host sends a message to the virtual machine and the sync_file object is signaled. 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/Kconfig | 2 + drivers/hv/dxgkrnl/Makefile | 2 +- drivers/hv/dxgkrnl/dxgkrnl.h | 2 + drivers/hv/dxgkrnl/dxgmodule.c | 12 ++ drivers/hv/dxgkrnl/dxgsyncfile.c | 215 +++++++++++++++++++++++++++++++ drivers/hv/dxgkrnl/dxgsyncfile.h | 30 +++++ drivers/hv/dxgkrnl/dxgvmbus.c | 33 +++-- drivers/hv/dxgkrnl/ioctl.c | 5 +- include/uapi/misc/d3dkmthk.h | 9 ++ 9 files changed, 294 insertions(+), 16 deletions(-) create mode 100644 drivers/hv/dxgkrnl/dxgsyncfile.c create mode 100644 drivers/hv/dxgkrnl/dxgsyncfile.h diff --git a/drivers/hv/dxgkrnl/Kconfig b/drivers/hv/dxgkrnl/Kconfig index bcd92bbff939..782692610887 100644 --- a/drivers/hv/dxgkrnl/Kconfig +++ b/drivers/hv/dxgkrnl/Kconfig @@ -6,6 +6,8 @@ config DXGKRNL tristate "Microsoft Paravirtualized GPU support" depends on HYPERV depends on 64BIT || COMPILE_TEST + select DMA_SHARED_BUFFER + select SYNC_FILE help This driver supports paravirtualized virtual compute devices, exposed by Microsoft Hyper-V when Linux is running inside of a virtual machine diff --git a/drivers/hv/dxgkrnl/Makefile b/drivers/hv/dxgkrnl/Makefile index fc85a47a6ad5..89824cda670a 100644 --- a/drivers/hv/dxgkrnl/Makefile +++ b/drivers/hv/dxgkrnl/Makefile @@ -2,4 +2,4 @@ # Makefile for the hyper-v compute device driver (dxgkrnl). =20 obj-$(CONFIG_DXGKRNL) +=3D dxgkrnl.o -dxgkrnl-y :=3D dxgmodule.o hmgr.o misc.o dxgadapter.o ioctl.o dxgvmbus.o d= xgprocess.o +dxgkrnl-y :=3D dxgmodule.o hmgr.o misc.o dxgadapter.o ioctl.o dxgvmbus.o d= xgprocess.o dxgsyncfile.o diff --git a/drivers/hv/dxgkrnl/dxgkrnl.h b/drivers/hv/dxgkrnl/dxgkrnl.h index 091dbe999d33..3a69e3b34e1c 100644 --- a/drivers/hv/dxgkrnl/dxgkrnl.h +++ b/drivers/hv/dxgkrnl/dxgkrnl.h @@ -120,6 +120,7 @@ struct dxgpagingqueue { */ enum dxghosteventtype { dxghostevent_cpu_event =3D 1, + dxghostevent_dma_fence =3D 2, }; =20 struct dxghostevent { @@ -858,6 +859,7 @@ int dxgvmb_send_wait_sync_object_cpu(struct dxgprocess = *process, struct d3dkmt_waitforsynchronizationobjectfromcpu *args, + bool user_address, u64 cpu_event); int dxgvmb_send_lock2(struct dxgprocess *process, struct dxgadapter *adapter, diff --git a/drivers/hv/dxgkrnl/dxgmodule.c b/drivers/hv/dxgkrnl/dxgmodule.c index f1245a9d8826..af51fcd35697 100644 --- a/drivers/hv/dxgkrnl/dxgmodule.c +++ b/drivers/hv/dxgkrnl/dxgmodule.c @@ -16,6 +16,7 @@ #include #include #include "dxgkrnl.h" +#include "dxgsyncfile.h" =20 #define PCI_VENDOR_ID_MICROSOFT 0x1414 #define PCI_DEVICE_ID_VIRTUAL_RENDER 0x008E @@ -145,6 +146,15 @@ void dxgglobal_remove_host_event(struct dxghostevent *= event) spin_unlock_irq(&dxgglobal->host_event_list_mutex); } =20 +static void signal_dma_fence(struct dxghostevent *eventhdr) +{ + struct dxgsyncpoint *event =3D (struct dxgsyncpoint *)eventhdr; + + event->fence_value++; + list_del(&eventhdr->host_event_list_entry); + dma_fence_signal(&event->base); +} + void signal_host_cpu_event(struct dxghostevent *eventhdr) { struct dxghosteventcpu *event =3D (struct dxghosteventcpu *)eventhdr; @@ -184,6 +194,8 @@ void dxgglobal_signal_host_event(u64 event_id) DXG_TRACE("found event to signal"); if (event->event_type =3D=3D dxghostevent_cpu_event) signal_host_cpu_event(event); + else if (event->event_type =3D=3D dxghostevent_dma_fence) + signal_dma_fence(event); else DXG_ERR("Unknown host event type"); break; diff --git a/drivers/hv/dxgkrnl/dxgsyncfile.c b/drivers/hv/dxgkrnl/dxgsyncf= ile.c new file mode 100644 index 000000000000..88fd78f08fbe --- /dev/null +++ b/drivers/hv/dxgkrnl/dxgsyncfile.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright (c) 2022, Microsoft Corporation. + * + * Author: + * Iouri Tarassov + * + * Dxgkrnl Graphics Driver + * Ioctl implementation + * + */ + +#include +#include +#include +#include +#include + +#include "dxgkrnl.h" +#include "dxgvmbus.h" +#include "dxgsyncfile.h" + +#undef dev_fmt +#define dev_fmt(fmt) "dxgk: " fmt + +#ifdef DEBUG +static char *errorstr(int ret) +{ + return ret < 0 ? "err" : ""; +} +#endif + +static const struct dma_fence_ops dxgdmafence_ops; + +static struct dxgsyncpoint *to_syncpoint(struct dma_fence *fence) +{ + if (fence->ops !=3D &dxgdmafence_ops) + return NULL; + return container_of(fence, struct dxgsyncpoint, base); +} + +int dxgkio_create_sync_file(struct dxgprocess *process, void *__user inarg= s) +{ + struct d3dkmt_createsyncfile args; + struct dxgsyncpoint *pt =3D NULL; + int ret =3D 0; + int fd =3D get_unused_fd_flags(O_CLOEXEC); + struct sync_file *sync_file =3D NULL; + struct dxgdevice *device =3D NULL; + struct dxgadapter *adapter =3D NULL; + struct d3dkmt_waitforsynchronizationobjectfromcpu waitargs =3D {}; + + if (fd < 0) { + DXG_ERR("get_unused_fd_flags failed: %d", fd); + ret =3D fd; + goto cleanup; + } + + ret =3D copy_from_user(&args, inargs, sizeof(args)); + if (ret) { + DXG_ERR("failed to copy input args"); + ret =3D -EFAULT; + goto cleanup; + } + + device =3D dxgprocess_device_by_handle(process, args.device); + if (device =3D=3D NULL) { + DXG_ERR("dxgprocess_device_by_handle failed"); + ret =3D -EINVAL; + goto cleanup; + } + + ret =3D dxgdevice_acquire_lock_shared(device); + if (ret < 0) { + DXG_ERR("dxgdevice_acquire_lock_shared failed"); + device =3D NULL; + goto cleanup; + } + + adapter =3D device->adapter; + ret =3D dxgadapter_acquire_lock_shared(adapter); + if (ret < 0) { + DXG_ERR("dxgadapter_acquire_lock_shared failed"); + adapter =3D NULL; + goto cleanup; + } + + pt =3D kzalloc(sizeof(*pt), GFP_KERNEL); + if (!pt) { + ret =3D -ENOMEM; + goto cleanup; + } + spin_lock_init(&pt->lock); + pt->fence_value =3D args.fence_value; + pt->context =3D dma_fence_context_alloc(1); + pt->hdr.event_id =3D dxgglobal_new_host_event_id(); + pt->hdr.event_type =3D dxghostevent_dma_fence; + dxgglobal_add_host_event(&pt->hdr); + + dma_fence_init(&pt->base, &dxgdmafence_ops, &pt->lock, + pt->context, args.fence_value); + + sync_file =3D sync_file_create(&pt->base); + if (sync_file =3D=3D NULL) { + DXG_ERR("sync_file_create failed"); + ret =3D -ENOMEM; + goto cleanup; + } + dma_fence_put(&pt->base); + + waitargs.device =3D args.device; + waitargs.object_count =3D 1; + waitargs.objects =3D &args.monitored_fence; + waitargs.fence_values =3D &args.fence_value; + ret =3D dxgvmb_send_wait_sync_object_cpu(process, adapter, + &waitargs, false, + pt->hdr.event_id); + if (ret < 0) { + DXG_ERR("dxgvmb_send_wait_sync_object_cpu failed"); + goto cleanup; + } + + args.sync_file_handle =3D (u64)fd; + ret =3D copy_to_user(inargs, &args, sizeof(args)); + if (ret) { + DXG_ERR("failed to copy output args"); + ret =3D -EFAULT; + goto cleanup; + } + + fd_install(fd, sync_file->file); + +cleanup: + if (adapter) + dxgadapter_release_lock_shared(adapter); + if (device) + dxgdevice_release_lock_shared(device); + if (ret) { + if (sync_file) { + fput(sync_file->file); + /* sync_file_release will destroy dma_fence */ + pt =3D NULL; + } + if (pt) + dma_fence_put(&pt->base); + if (fd >=3D 0) + put_unused_fd(fd); + } + DXG_TRACE("ioctl:%s %d", errorstr(ret), ret); + return ret; +} + +static const char *dxgdmafence_get_driver_name(struct dma_fence *fence) +{ + return "dxgkrnl"; +} + +static const char *dxgdmafence_get_timeline_name(struct dma_fence *fence) +{ + return "no_timeline"; +} + +static void dxgdmafence_release(struct dma_fence *fence) +{ + struct dxgsyncpoint *syncpoint; + + syncpoint =3D to_syncpoint(fence); + if (syncpoint) { + if (syncpoint->hdr.event_id) + dxgglobal_get_host_event(syncpoint->hdr.event_id); + kfree(syncpoint); + } +} + +static bool dxgdmafence_signaled(struct dma_fence *fence) +{ + struct dxgsyncpoint *syncpoint; + + syncpoint =3D to_syncpoint(fence); + if (syncpoint =3D=3D 0) + return true; + return __dma_fence_is_later(syncpoint->fence_value, fence->seqno, + fence->ops); +} + +static bool dxgdmafence_enable_signaling(struct dma_fence *fence) +{ + return true; +} + +static void dxgdmafence_value_str(struct dma_fence *fence, + char *str, int size) +{ + snprintf(str, size, "%lld", fence->seqno); +} + +static void dxgdmafence_timeline_value_str(struct dma_fence *fence, + char *str, int size) +{ + struct dxgsyncpoint *syncpoint; + + syncpoint =3D to_syncpoint(fence); + snprintf(str, size, "%lld", syncpoint->fence_value); +} + +static const struct dma_fence_ops dxgdmafence_ops =3D { + .get_driver_name =3D dxgdmafence_get_driver_name, + .get_timeline_name =3D dxgdmafence_get_timeline_name, + .enable_signaling =3D dxgdmafence_enable_signaling, + .signaled =3D dxgdmafence_signaled, + .release =3D dxgdmafence_release, + .fence_value_str =3D dxgdmafence_value_str, + .timeline_value_str =3D dxgdmafence_timeline_value_str, +}; diff --git a/drivers/hv/dxgkrnl/dxgsyncfile.h b/drivers/hv/dxgkrnl/dxgsyncf= ile.h new file mode 100644 index 000000000000..207ef9b30f67 --- /dev/null +++ b/drivers/hv/dxgkrnl/dxgsyncfile.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (c) 2022, Microsoft Corporation. + * + * Author: + * Iouri Tarassov + * + * Dxgkrnl Graphics Driver + * Headers for sync file objects + * + */ + +#ifndef _DXGSYNCFILE_H +#define _DXGSYNCFILE_H + +#include + +int dxgkio_create_sync_file(struct dxgprocess *process, void *__user inarg= s); + +struct dxgsyncpoint { + struct dxghostevent hdr; + struct dma_fence base; + u64 fence_value; + u64 context; + spinlock_t lock; + u64 u64; +}; + +#endif /* _DXGSYNCFILE_H */ diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c index 4d7807909284..913ea3cabb31 100644 --- a/drivers/hv/dxgkrnl/dxgvmbus.c +++ b/drivers/hv/dxgkrnl/dxgvmbus.c @@ -2820,6 +2820,7 @@ int dxgvmb_send_wait_sync_object_cpu(struct dxgproces= s *process, struct d3dkmt_waitforsynchronizationobjectfromcpu *args, + bool user_address, u64 cpu_event) { int ret =3D -EINVAL; @@ -2844,19 +2845,25 @@ int dxgvmb_send_wait_sync_object_cpu(struct dxgproc= ess *process, command->guest_event_pointer =3D (u64) cpu_event; current_pos =3D (u8 *) &command[1]; =20 - ret =3D copy_from_user(current_pos, args->objects, object_size); - if (ret) { - DXG_ERR("failed to copy objects"); - ret =3D -EINVAL; - goto cleanup; - } - current_pos +=3D object_size; - ret =3D copy_from_user(current_pos, args->fence_values, - fence_size); - if (ret) { - DXG_ERR("failed to copy fences"); - ret =3D -EINVAL; - goto cleanup; + if (user_address) { + ret =3D copy_from_user(current_pos, args->objects, object_size); + if (ret) { + DXG_ERR("failed to copy objects"); + ret =3D -EINVAL; + goto cleanup; + } + current_pos +=3D object_size; + ret =3D copy_from_user(current_pos, args->fence_values, + fence_size); + if (ret) { + DXG_ERR("failed to copy fences"); + ret =3D -EINVAL; + goto cleanup; + } + } else { + memcpy(current_pos, args->objects, object_size); + current_pos +=3D object_size; + memcpy(current_pos, args->fence_values, fence_size); } =20 ret =3D dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); diff --git a/drivers/hv/dxgkrnl/ioctl.c b/drivers/hv/dxgkrnl/ioctl.c index 8732a66040a0..6c26aafb0619 100644 --- a/drivers/hv/dxgkrnl/ioctl.c +++ b/drivers/hv/dxgkrnl/ioctl.c @@ -19,6 +19,7 @@ =20 #include "dxgkrnl.h" #include "dxgvmbus.h" +#include "dxgsyncfile.h" =20 #undef pr_fmt #define pr_fmt(fmt) "dxgk: " fmt @@ -3488,7 +3489,7 @@ dxgkio_wait_sync_object_cpu(struct dxgprocess *proces= s, void *__user inargs) } =20 ret =3D dxgvmb_send_wait_sync_object_cpu(process, adapter, - &args, event_id); + &args, true, event_id); if (ret < 0) goto cleanup; =20 @@ -5224,7 +5225,7 @@ static struct ioctl_desc ioctls[] =3D { /* 0x42 */ {dxgkio_open_resource_nt, LX_DXOPENRESOURCEFROMNTHANDLE}, /* 0x43 */ {dxgkio_query_statistics, LX_DXQUERYSTATISTICS}, /* 0x44 */ {dxgkio_share_object_with_host, LX_DXSHAREOBJECTWITHHOST}, -/* 0x45 */ {}, +/* 0x45 */ {dxgkio_create_sync_file, LX_DXCREATESYNCFILE}, }; =20 /* diff --git a/include/uapi/misc/d3dkmthk.h b/include/uapi/misc/d3dkmthk.h index 1f60f5120e1d..c7f168425dc7 100644 --- a/include/uapi/misc/d3dkmthk.h +++ b/include/uapi/misc/d3dkmthk.h @@ -1554,6 +1554,13 @@ struct d3dkmt_shareobjectwithhost { __u64 object_vail_nt_handle; }; =20 +struct d3dkmt_createsyncfile { + struct d3dkmthandle device; + struct d3dkmthandle monitored_fence; + __u64 fence_value; + __u64 sync_file_handle; /* out */ +}; + /* * Dxgkrnl Graphics Port Driver ioctl definitions * @@ -1677,5 +1684,7 @@ struct d3dkmt_shareobjectwithhost { _IOWR(0x47, 0x43, struct d3dkmt_querystatistics) #define LX_DXSHAREOBJECTWITHHOST \ _IOWR(0x47, 0x44, struct d3dkmt_shareobjectwithhost) +#define LX_DXCREATESYNCFILE \ + _IOWR(0x47, 0x45, struct d3dkmt_createsyncfile) =20 #endif /* _D3DKMTHK_H */