Skip to content

Commit 06e98fd

Browse files
Iouri Tarassovchessturo
authored andcommitted
drivers: hv: dxgkrnl: Implement the D3DKMTEnumProcesses API
D3DKMTEnumProcesses is used to enumerate PIDs for all processes, which opened the /dev/dxg device. Signed-off-by: Iouri Tarassov <iourit@linux.microsoft.com> [kms: forward port to 6.6 from 6.1. No code changes made.] Signed-off-by: Kelsey Steele <kelseysteele@microsoft.com>
1 parent 106d9aa commit 06e98fd

4 files changed

Lines changed: 96 additions & 0 deletions

File tree

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ struct dxgprocess {
387387
pid_t pid;
388388
pid_t tgid;
389389
pid_t vpid; /* pdi from the current namespace */
390+
struct pid_namespace *nspid; /* namespace id */
390391
/* how many time the process was opened */
391392
struct kref process_kref;
392393
/* protects the object memory */

drivers/hv/dxgkrnl/dxgprocess.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "dxgkrnl.h"
1515
#include "linux/sched.h"
16+
#include <linux/pid_namespace.h>
1617

1718
#undef dev_fmt
1819
#define dev_fmt(fmt) "dxgk: " fmt
@@ -33,6 +34,7 @@ struct dxgprocess *dxgprocess_create(void)
3334
process->pid = current->pid;
3435
process->tgid = current->tgid;
3536
process->vpid = task_pid_vnr(current);
37+
process->nspid = task_active_pid_ns(current);
3638
ret = dxgvmb_send_create_process(process);
3739
if (ret < 0) {
3840
DXG_TRACE("send_create_process failed");

drivers/hv/dxgkrnl/ioctl.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/fs.h>
1717
#include <linux/anon_inodes.h>
1818
#include <linux/mman.h>
19+
#include <linux/pid_namespace.h>
1920

2021
#include "dxgkrnl.h"
2122
#include "dxgvmbus.h"
@@ -5238,6 +5239,85 @@ dxgkio_share_object_with_host(struct dxgprocess *process, void *__user inargs)
52385239
return ret;
52395240
}
52405241

5242+
static int
5243+
dxgkio_enum_processes(struct dxgprocess *process, void *__user inargs)
5244+
{
5245+
struct d3dkmt_enumprocesses args;
5246+
struct d3dkmt_enumprocesses *__user input = inargs;
5247+
struct dxgadapter *adapter = NULL;
5248+
struct dxgadapter *entry;
5249+
struct dxgglobal *dxgglobal = dxggbl();
5250+
struct dxgprocess_adapter *pentry;
5251+
int nump = 0; /* Current number of processes*/
5252+
struct ntstatus status;
5253+
int ret;
5254+
5255+
ret = copy_from_user(&args, inargs, sizeof(args));
5256+
if (ret) {
5257+
DXG_ERR("failed to copy input args");
5258+
ret = -EFAULT;
5259+
goto cleanup;
5260+
}
5261+
5262+
if (args.buffer_count == 0) {
5263+
DXG_ERR("Invalid buffer count");
5264+
ret = -EINVAL;
5265+
goto cleanup;
5266+
}
5267+
5268+
dxgglobal_acquire_adapter_list_lock(DXGLOCK_SHARED);
5269+
dxgglobal_acquire_process_adapter_lock();
5270+
5271+
list_for_each_entry(entry, &dxgglobal->adapter_list_head,
5272+
adapter_list_entry) {
5273+
if (*(u64 *) &entry->luid == *(u64 *) &args.adapter_luid) {
5274+
adapter = entry;
5275+
break;
5276+
}
5277+
}
5278+
5279+
if (adapter == NULL) {
5280+
DXG_ERR("Failed to find dxgadapter");
5281+
ret = -EINVAL;
5282+
goto cleanup_locks;
5283+
}
5284+
5285+
list_for_each_entry(pentry, &adapter->adapter_process_list_head,
5286+
adapter_process_list_entry) {
5287+
if (pentry->process->nspid != task_active_pid_ns(current))
5288+
continue;
5289+
if (nump == args.buffer_count) {
5290+
status.v = STATUS_BUFFER_TOO_SMALL;
5291+
ret = ntstatus2int(status);
5292+
goto cleanup_locks;
5293+
}
5294+
ret = copy_to_user(&args.buffer[nump], &pentry->process->vpid,
5295+
sizeof(u32));
5296+
if (ret) {
5297+
DXG_ERR("failed to copy data to user");
5298+
ret = -EFAULT;
5299+
goto cleanup_locks;
5300+
}
5301+
nump++;
5302+
}
5303+
5304+
cleanup_locks:
5305+
5306+
dxgglobal_release_process_adapter_lock();
5307+
dxgglobal_release_adapter_list_lock(DXGLOCK_SHARED);
5308+
5309+
if (ret == 0) {
5310+
ret = copy_to_user(&input->buffer_count, &nump, sizeof(u32));
5311+
if (ret)
5312+
DXG_ERR("failed to copy buffer count to user");
5313+
}
5314+
5315+
cleanup:
5316+
5317+
DXG_TRACE_IOCTL_END(ret);
5318+
return ret;
5319+
}
5320+
52415321
static struct ioctl_desc ioctls[] = {
52425322
/* 0x00 */ {},
52435323
/* 0x01 */ {dxgkio_open_adapter_from_luid, LX_DXOPENADAPTERFROMLUID},
@@ -5325,6 +5405,7 @@ static struct ioctl_desc ioctls[] = {
53255405
/* 0x46 */ {dxgkio_wait_sync_file, LX_DXWAITSYNCFILE},
53265406
/* 0x47 */ {dxgkio_open_syncobj_from_syncfile,
53275407
LX_DXOPENSYNCOBJECTFROMSYNCFILE},
5408+
/* 0x48 */ {dxgkio_enum_processes, LX_DXENUMPROCESSES},
53285409
};
53295410

53305411
/*

include/uapi/misc/d3dkmthk.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,16 @@ struct d3dkmt_opensyncobjectfromsyncfile {
15801580
__u64 fence_value_gpu_va; /* out */
15811581
};
15821582

1583+
struct d3dkmt_enumprocesses {
1584+
struct winluid adapter_luid;
1585+
#ifdef __KERNEL__
1586+
__u32 *buffer;
1587+
#else
1588+
__u64 buffer;
1589+
#endif
1590+
__u64 buffer_count;
1591+
};
1592+
15831593
struct d3dkmt_invalidatecache {
15841594
struct d3dkmthandle device;
15851595
struct d3dkmthandle allocation;
@@ -1718,5 +1728,7 @@ struct d3dkmt_invalidatecache {
17181728
_IOWR(0x47, 0x46, struct d3dkmt_waitsyncfile)
17191729
#define LX_DXOPENSYNCOBJECTFROMSYNCFILE \
17201730
_IOWR(0x47, 0x47, struct d3dkmt_opensyncobjectfromsyncfile)
1731+
#define LX_DXENUMPROCESSES \
1732+
_IOWR(0x47, 0x48, struct d3dkmt_enumprocesses)
17211733

17221734
#endif /* _D3DKMTHK_H */

0 commit comments

Comments
 (0)