[PATCH 41/55] drivers: hv: dxgkrnl: Handle process ID in D3DKMTQueryStatistics

Eric Curtin posted 55 patches 2 weeks, 3 days ago
[PATCH 41/55] drivers: hv: dxgkrnl: Handle process ID in D3DKMTQueryStatistics
Posted by Eric Curtin 2 weeks, 3 days ago
From: Iouri Tarassov <iourit@linux.microsoft.com>

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 <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>
---
 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));