From: Iouri Tarassov <[email protected]> When D3DKMTQueryStatistics specifies a non-zero process ID, it needs to be translated to the host process handle before sending a message to the host.
Signed-off-by: Iouri Tarassov <[email protected]> [kms: forward port to 6.6 from 6.1. No code changes made.] Signed-off-by: Kelsey Steele <[email protected]> --- drivers/hv/dxgkrnl/dxgkrnl.h | 3 +- drivers/hv/dxgkrnl/dxgprocess.c | 2 + drivers/hv/dxgkrnl/dxgvmbus.c | 140 ++++++++++++++++---------------- drivers/hv/dxgkrnl/ioctl.c | 39 ++++++++- 4 files changed, 111 insertions(+), 73 deletions(-) diff --git a/drivers/hv/dxgkrnl/dxgkrnl.h b/drivers/hv/dxgkrnl/dxgkrnl.h index e7d8919b3c01..6af1e59b0a31 100644 --- a/drivers/hv/dxgkrnl/dxgkrnl.h +++ b/drivers/hv/dxgkrnl/dxgkrnl.h @@ -386,6 +386,7 @@ struct dxgprocess { struct list_head plistentry; pid_t pid; pid_t tgid; + pid_t vpid; /* pdi from the current namespace */ /* how many time the process was opened */ struct kref process_kref; /* protects the object memory */ @@ -981,7 +982,7 @@ int dxgvmb_send_get_stdalloc_data(struct dxgdevice *device, void *prive_alloc_data, u32 *res_priv_data_size, void *priv_res_data); -int dxgvmb_send_query_statistics(struct dxgprocess *process, +int dxgvmb_send_query_statistics(struct d3dkmthandle host_process_handle, struct dxgadapter *adapter, struct d3dkmt_querystatistics *args); int dxgvmb_send_async_msg(struct dxgvmbuschannel *channel, diff --git a/drivers/hv/dxgkrnl/dxgprocess.c b/drivers/hv/dxgkrnl/dxgprocess.c index fd51fd968049..5a4c4cb0c2e8 100644 --- a/drivers/hv/dxgkrnl/dxgprocess.c +++ b/drivers/hv/dxgkrnl/dxgprocess.c @@ -12,6 +12,7 @@ */ #include "dxgkrnl.h" +#include "linux/sched.h" #undef dev_fmt #define dev_fmt(fmt) "dxgk: " fmt @@ -31,6 +32,7 @@ struct dxgprocess *dxgprocess_create(void) DXG_TRACE("new dxgprocess created"); process->pid = current->pid; process->tgid = current->tgid; + process->vpid = task_pid_vnr(current); ret = dxgvmb_send_create_process(process); if (ret < 0) { DXG_TRACE("send_create_process failed"); diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c index 487804ca731a..916ed9071656 100644 --- a/drivers/hv/dxgkrnl/dxgvmbus.c +++ b/drivers/hv/dxgkrnl/dxgvmbus.c @@ -22,6 +22,8 @@ #include "dxgkrnl.h" #include "dxgvmbus.h" +#pragma GCC diagnostic ignored "-Warray-bounds" + #undef dev_fmt #define dev_fmt(fmt) "dxgk: " fmt @@ -113,7 +115,6 @@ static int init_message(struct dxgvmbusmsg *msg, struct dxgadapter *adapter, static int init_message_res(struct dxgvmbusmsgres *msg, struct dxgadapter *adapter, - struct dxgprocess *process, u32 size, u32 result_size) { @@ -146,7 +147,7 @@ static int init_message_res(struct dxgvmbusmsgres *msg, return 0; } -static void free_message(struct dxgvmbusmsg *msg, struct dxgprocess *process) +static void free_message(struct dxgvmbusmsg *msg) { if (msg->hdr && (char *)msg->hdr != msg->msg_on_stack) vfree(msg->hdr); @@ -646,7 +647,7 @@ int dxgvmb_send_set_iospace_region(u64 start, u64 len) dxgglobal_release_channel_lock(); cleanup: - free_message(&msg, NULL); + free_message(&msg); if (ret) DXG_TRACE("Error: %d", ret); return ret; @@ -699,7 +700,7 @@ int dxgvmb_send_create_process(struct dxgprocess *process) dxgglobal_release_channel_lock(); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -727,7 +728,7 @@ int dxgvmb_send_destroy_process(struct d3dkmthandle process) dxgglobal_release_channel_lock(); cleanup: - free_message(&msg, NULL); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -790,7 +791,7 @@ int dxgvmb_send_open_sync_object_nt(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -839,7 +840,7 @@ int dxgvmb_send_open_sync_object(struct dxgprocess *process, *syncobj = result.sync_object; cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -881,7 +882,7 @@ int dxgvmb_send_create_nt_shared_object(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -912,7 +913,7 @@ int dxgvmb_send_destroy_nt_shared_object(struct d3dkmthandle shared_handle) dxgglobal_release_channel_lock(); cleanup: - free_message(&msg, NULL); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -945,7 +946,7 @@ int dxgvmb_send_destroy_sync_object(struct dxgprocess *process, dxgglobal_release_channel_lock(); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -989,7 +990,7 @@ int dxgvmb_send_share_object_with_host(struct dxgprocess *process, args->object_vail_nt_handle = result.vail_nt_handle; cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_ERR("err: %d", ret); return ret; @@ -1026,7 +1027,7 @@ int dxgvmb_send_open_adapter(struct dxgadapter *adapter) adapter->host_handle = result.host_adapter_handle; cleanup: - free_message(&msg, NULL); + free_message(&msg); if (ret) DXG_ERR("Failed to open adapter: %d", ret); return ret; @@ -1048,7 +1049,7 @@ int dxgvmb_send_close_adapter(struct dxgadapter *adapter) ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, NULL, 0); - free_message(&msg, NULL); + free_message(&msg); if (ret) DXG_ERR("Failed to close adapter: %d", ret); return ret; @@ -1084,7 +1085,7 @@ int dxgvmb_send_get_internal_adapter_info(struct dxgadapter *adapter) sizeof(adapter->device_instance_id) / sizeof(u16)); dxgglobal->async_msg_enabled = result.async_msg_enabled != 0; } - free_message(&msg, NULL); + free_message(&msg); if (ret) DXG_ERR("Failed to get adapter info: %d", ret); return ret; @@ -1114,7 +1115,7 @@ struct d3dkmthandle dxgvmb_send_create_device(struct dxgadapter *adapter, &result, sizeof(result)); if (ret < 0) result.device.v = 0; - free_message(&msg, process); + free_message(&msg); cleanup: if (ret) DXG_TRACE("err: %d", ret); @@ -1140,7 +1141,7 @@ int dxgvmb_send_destroy_device(struct dxgadapter *adapter, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1167,7 +1168,7 @@ int dxgvmb_send_flush_device(struct dxgdevice *device, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1239,7 +1240,7 @@ dxgvmb_send_create_context(struct dxgadapter *adapter, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return context; @@ -1265,7 +1266,7 @@ int dxgvmb_send_destroy_context(struct dxgadapter *adapter, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1312,7 +1313,7 @@ int dxgvmb_send_create_paging_queue(struct dxgprocess *process, pqueue->handle = args->paging_queue; cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1339,7 +1340,7 @@ int dxgvmb_send_destroy_paging_queue(struct dxgprocess *process, ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, NULL, 0); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1550,7 +1551,7 @@ int create_existing_sysmem(struct dxgdevice *device, cleanup: if (kmem) vunmap(kmem); - free_message(&msg, device->process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1783,7 +1784,7 @@ create_local_allocations(struct dxgprocess *process, dxgdevice_release_alloc_list_lock(device); } - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1908,7 +1909,7 @@ int dxgvmb_send_create_allocation(struct dxgprocess *process, if (result) vfree(result); - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); @@ -1950,7 +1951,7 @@ int dxgvmb_send_destroy_allocation(struct dxgprocess *process, cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -1992,7 +1993,7 @@ int dxgvmb_send_query_clock_calibration(struct dxgprocess *process, ret = ntstatus2int(result.status); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2015,7 +2016,7 @@ int dxgvmb_send_flush_heap_transitions(struct dxgprocess *process, process->host_handle); ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2042,7 +2043,7 @@ int dxgvmb_send_invalidate_cache(struct dxgprocess *process, command->length = args->length; ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2078,7 +2079,7 @@ int dxgvmb_send_query_alloc_residency(struct dxgprocess *process, } result_size += result_allocation_size; - ret = init_message_res(&msg, adapter, process, cmd_size, result_size); + ret = init_message_res(&msg, adapter, cmd_size, result_size); if (ret) goto cleanup; command = (void *)msg.msg; @@ -2115,7 +2116,7 @@ int dxgvmb_send_query_alloc_residency(struct dxgprocess *process, } cleanup: - free_message((struct dxgvmbusmsg *)&msg, process); + free_message((struct dxgvmbusmsg *)&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2179,7 +2180,7 @@ int dxgvmb_send_escape(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2243,7 +2244,7 @@ int dxgvmb_send_query_vidmem_info(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2288,7 +2289,7 @@ int dxgvmb_send_get_device_state(struct dxgprocess *process, args->execution_state = result.args.execution_state; cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2312,8 +2313,7 @@ int dxgvmb_send_open_resource(struct dxgprocess *process, sizeof(*result); struct dxgvmbusmsgres msg = {.hdr = NULL}; - ret = init_message_res(&msg, adapter, process, sizeof(*command), - result_size); + ret = init_message_res(&msg, adapter, sizeof(*command), result_size); if (ret) goto cleanup; command = msg.msg; @@ -2342,7 +2342,7 @@ int dxgvmb_send_open_resource(struct dxgprocess *process, alloc_handles[i] = handles[i]; cleanup: - free_message((struct dxgvmbusmsg *)&msg, process); + free_message((struct dxgvmbusmsg *)&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2367,7 +2367,7 @@ int dxgvmb_send_get_stdalloc_data(struct dxgdevice *device, result_size += *alloc_priv_driver_size; if (priv_res_data) result_size += *res_priv_data_size; - ret = init_message_res(&msg, device->adapter, device->process, + ret = init_message_res(&msg, device->adapter, sizeof(*command), result_size); if (ret) goto cleanup; @@ -2427,7 +2427,7 @@ int dxgvmb_send_get_stdalloc_data(struct dxgdevice *device, cleanup: - free_message((struct dxgvmbusmsg *)&msg, device->process); + free_message((struct dxgvmbusmsg *)&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2479,7 +2479,7 @@ int dxgvmb_send_make_resident(struct dxgprocess *process, cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2525,7 +2525,7 @@ int dxgvmb_send_evict(struct dxgprocess *process, cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2580,7 +2580,7 @@ int dxgvmb_send_submit_command(struct dxgprocess *process, cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2617,7 +2617,7 @@ int dxgvmb_send_map_gpu_va(struct dxgprocess *process, cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2647,7 +2647,7 @@ int dxgvmb_send_reserve_gpu_va(struct dxgprocess *process, args->virtual_address = result.virtual_address; cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2674,7 +2674,7 @@ int dxgvmb_send_free_gpu_va(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2730,7 +2730,7 @@ int dxgvmb_send_update_gpu_va(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2816,7 +2816,7 @@ dxgvmb_send_create_sync_object(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2910,7 +2910,7 @@ int dxgvmb_send_signal_sync_object(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -2970,7 +2970,7 @@ int dxgvmb_send_wait_sync_object_cpu(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3023,7 +3023,7 @@ int dxgvmb_send_wait_sync_object_gpu(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3103,7 +3103,7 @@ int dxgvmb_send_lock2(struct dxgprocess *process, hmgrtable_unlock(&process->handle_table, DXGLOCK_EXCL); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3130,7 +3130,7 @@ int dxgvmb_send_unlock2(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3175,7 +3175,7 @@ int dxgvmb_send_update_alloc_property(struct dxgprocess *process, } } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3200,7 +3200,7 @@ int dxgvmb_send_mark_device_as_error(struct dxgprocess *process, command->args = *args; ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3270,7 +3270,7 @@ int dxgvmb_send_set_allocation_priority(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3312,7 +3312,7 @@ int dxgvmb_send_get_allocation_priority(struct dxgprocess *process, } result_size = sizeof(*result) + priority_size; - ret = init_message_res(&msg, adapter, process, cmd_size, result_size); + ret = init_message_res(&msg, adapter, cmd_size, result_size); if (ret) goto cleanup; command = (void *)msg.msg; @@ -3352,7 +3352,7 @@ int dxgvmb_send_get_allocation_priority(struct dxgprocess *process, } cleanup: - free_message((struct dxgvmbusmsg *)&msg, process); + free_message((struct dxgvmbusmsg *)&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3381,7 +3381,7 @@ int dxgvmb_send_set_context_sch_priority(struct dxgprocess *process, command->in_process = in_process; ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3415,7 +3415,7 @@ int dxgvmb_send_get_context_sch_priority(struct dxgprocess *process, *priority = result.priority; } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3461,7 +3461,7 @@ int dxgvmb_send_offer_allocations(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3486,7 +3486,7 @@ int dxgvmb_send_reclaim_allocations(struct dxgprocess *process, result_size += (args->allocation_count - 1) * sizeof(enum d3dddi_reclaim_result); - ret = init_message_res(&msg, adapter, process, cmd_size, result_size); + ret = init_message_res(&msg, adapter, cmd_size, result_size); if (ret) goto cleanup; command = (void *)msg.msg; @@ -3537,7 +3537,7 @@ int dxgvmb_send_reclaim_allocations(struct dxgprocess *process, } cleanup: - free_message((struct dxgvmbusmsg *)&msg, process); + free_message((struct dxgvmbusmsg *)&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3567,7 +3567,7 @@ int dxgvmb_send_change_vidmem_reservation(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3706,7 +3706,7 @@ int dxgvmb_send_create_hwqueue(struct dxgprocess *process, dxgvmb_send_destroy_hwqueue(process, adapter, command->hwqueue); } - free_message(&msg, process); + free_message(&msg); return ret; } @@ -3731,7 +3731,7 @@ int dxgvmb_send_destroy_hwqueue(struct dxgprocess *process, ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3815,7 +3815,7 @@ int dxgvmb_send_query_adapter_info(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; @@ -3873,13 +3873,13 @@ int dxgvmb_send_submit_command_hwqueue(struct dxgprocess *process, } cleanup: - free_message(&msg, process); + free_message(&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; } -int dxgvmb_send_query_statistics(struct dxgprocess *process, +int dxgvmb_send_query_statistics(struct d3dkmthandle host_process_handle, struct dxgadapter *adapter, struct d3dkmt_querystatistics *args) { @@ -3888,7 +3888,7 @@ int dxgvmb_send_query_statistics(struct dxgprocess *process, int ret; struct dxgvmbusmsgres msg = {.hdr = NULL}; - ret = init_message_res(&msg, adapter, process, sizeof(*command), + ret = init_message_res(&msg, adapter, sizeof(*command), sizeof(*result)); if (ret) goto cleanup; @@ -3897,7 +3897,7 @@ int dxgvmb_send_query_statistics(struct dxgprocess *process, command_vgpu_to_host_init2(&command->hdr, DXGK_VMBCOMMAND_QUERYSTATISTICS, - process->host_handle); + host_process_handle); command->args = *args; ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, @@ -3909,7 +3909,7 @@ int dxgvmb_send_query_statistics(struct dxgprocess *process, ret = ntstatus2int(result->status); cleanup: - free_message((struct dxgvmbusmsg *)&msg, process); + free_message((struct dxgvmbusmsg *)&msg); if (ret) DXG_TRACE("err: %d", ret); return ret; diff --git a/drivers/hv/dxgkrnl/ioctl.c b/drivers/hv/dxgkrnl/ioctl.c index 56b838a87f09..466bef6c14b3 100644 --- a/drivers/hv/dxgkrnl/ioctl.c +++ b/drivers/hv/dxgkrnl/ioctl.c @@ -147,6 +147,23 @@ static int dxgkio_open_adapter_from_luid(struct dxgprocess *process, return ret; } +static struct d3dkmthandle find_dxgprocess_handle(u64 pid) +{ + struct dxgglobal *dxgglobal = dxggbl(); + struct dxgprocess *entry; + struct d3dkmthandle host_handle = {}; + + mutex_lock(&dxgglobal->plistmutex); + list_for_each_entry(entry, &dxgglobal->plisthead, plistentry) { + if (entry->vpid == pid) { + host_handle.v = entry->host_handle.v; + break; + } + } + mutex_unlock(&dxgglobal->plistmutex); + return host_handle; +} + static int dxgkio_query_statistics(struct dxgprocess *process, void __user *inargs) { @@ -156,6 +173,8 @@ static int dxgkio_query_statistics(struct dxgprocess *process, struct dxgadapter *adapter = NULL; struct winluid tmp; struct dxgglobal *dxgglobal = dxggbl(); + struct d3dkmthandle host_process_handle = process->host_handle; + u64 pid; args = vzalloc(sizeof(struct d3dkmt_querystatistics)); if (args == NULL) { @@ -170,6 +189,18 @@ static int dxgkio_query_statistics(struct dxgprocess *process, goto cleanup; } + /* Find the host process handle when needed */ + pid = args->process; + if (pid) { + host_process_handle = find_dxgprocess_handle(pid); + if (host_process_handle.v == 0) { + DXG_ERR("Invalid process ID is specified: %lld", pid); + ret = -EINVAL; + goto cleanup; + } + args->process = 0; + } + dxgglobal_acquire_adapter_list_lock(DXGLOCK_SHARED); list_for_each_entry(entry, &dxgglobal->adapter_list_head, adapter_list_entry) { @@ -186,7 +217,8 @@ static int dxgkio_query_statistics(struct dxgprocess *process, if (adapter) { tmp = args->adapter_luid; args->adapter_luid = adapter->host_adapter_luid; - ret = dxgvmb_send_query_statistics(process, adapter, args); + ret = dxgvmb_send_query_statistics(host_process_handle, adapter, + args); if (ret >= 0) { args->adapter_luid = tmp; ret = copy_to_user(inargs, args, sizeof(*args)); @@ -280,7 +312,10 @@ dxgkp_enum_adapters(struct dxgprocess *process, dxgglobal_release_adapter_list_lock(DXGLOCK_SHARED); if (adapter_count > adapter_count_max) { - ret = STATUS_BUFFER_TOO_SMALL; + struct ntstatus status; + + status.v = STATUS_BUFFER_TOO_SMALL; + ret = ntstatus2int(status); DXG_TRACE("Too many adapters"); ret = copy_to_user(adapter_count_out, &dxgglobal->num_adapters, sizeof(u32));

