mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
913 lines
26 KiB
Diff
913 lines
26 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Iouri Tarassov <iourit@linux.microsoft.com>
|
|
Date: Wed, 19 Jan 2022 11:14:22 -0800
|
|
Subject: drivers: hv: dxgkrnl: Manage device allocation properties
|
|
|
|
Implement ioctls to manage properties of a compute device allocation:
|
|
- LX_DXUPDATEALLOCPROPERTY,
|
|
- LX_DXSETALLOCATIONPRIORITY,
|
|
- LX_DXGETALLOCATIONPRIORITY,
|
|
- LX_DXQUERYALLOCATIONRESIDENCY.
|
|
- LX_DXCHANGEVIDEOMEMORYRESERVATION,
|
|
|
|
The LX_DXUPDATEALLOCPROPERTY ioctl requests the host to update
|
|
various properties of a compute devoce allocation.
|
|
|
|
The LX_DXSETALLOCATIONPRIORITY and LX_DXGETALLOCATIONPRIORITY ioctls
|
|
are used to set/get allocation priority, which defines the
|
|
importance of the allocation to be in the local device memory.
|
|
|
|
The LX_DXQUERYALLOCATIONRESIDENCY ioctl queries if the allocation
|
|
is located in the compute device accessible memory.
|
|
|
|
The LX_DXCHANGEVIDEOMEMORYRESERVATION ioctl changes compute device
|
|
memory reservation of an allocation.
|
|
|
|
Signed-off-by: Iouri Tarassov <iourit@linux.microsoft.com>
|
|
[kms: Forward port to v6.1]
|
|
Signed-off-by: Kelsey Steele <kelseysteele@microsoft.com>
|
|
---
|
|
drivers/hv/dxgkrnl/dxgkrnl.h | 21 +
|
|
drivers/hv/dxgkrnl/dxgvmbus.c | 300 ++++++++++
|
|
drivers/hv/dxgkrnl/dxgvmbus.h | 50 ++
|
|
drivers/hv/dxgkrnl/ioctl.c | 217 ++++++-
|
|
include/uapi/misc/d3dkmthk.h | 127 ++++
|
|
5 files changed, 708 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/drivers/hv/dxgkrnl/dxgkrnl.h b/drivers/hv/dxgkrnl/dxgkrnl.h
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/hv/dxgkrnl/dxgkrnl.h
|
|
+++ b/drivers/hv/dxgkrnl/dxgkrnl.h
|
|
@@ -851,6 +851,23 @@ int dxgvmb_send_lock2(struct dxgprocess *process,
|
|
int dxgvmb_send_unlock2(struct dxgprocess *process,
|
|
struct dxgadapter *adapter,
|
|
struct d3dkmt_unlock2 *args);
|
|
+int dxgvmb_send_update_alloc_property(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dddi_updateallocproperty *args,
|
|
+ struct d3dddi_updateallocproperty *__user
|
|
+ inargs);
|
|
+int dxgvmb_send_set_allocation_priority(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmt_setallocationpriority *a);
|
|
+int dxgvmb_send_get_allocation_priority(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmt_getallocationpriority *a);
|
|
+int dxgvmb_send_change_vidmem_reservation(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmthandle other_process,
|
|
+ struct
|
|
+ d3dkmt_changevideomemoryreservation
|
|
+ *args);
|
|
int dxgvmb_send_create_hwqueue(struct dxgprocess *process,
|
|
struct dxgadapter *adapter,
|
|
struct d3dkmt_createhwqueue *args,
|
|
@@ -870,6 +887,10 @@ int dxgvmb_send_open_sync_object_nt(struct dxgprocess *process,
|
|
struct d3dkmt_opensyncobjectfromnthandle2
|
|
*args,
|
|
struct dxgsyncobject *syncobj);
|
|
+int dxgvmb_send_query_alloc_residency(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmt_queryallocationresidency
|
|
+ *args);
|
|
int dxgvmb_send_get_device_state(struct dxgprocess *process,
|
|
struct dxgadapter *adapter,
|
|
struct d3dkmt_getdevicestate *args,
|
|
diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/hv/dxgkrnl/dxgvmbus.c
|
|
+++ b/drivers/hv/dxgkrnl/dxgvmbus.c
|
|
@@ -1829,6 +1829,79 @@ int dxgvmb_send_destroy_allocation(struct dxgprocess *process,
|
|
return ret;
|
|
}
|
|
|
|
+int dxgvmb_send_query_alloc_residency(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmt_queryallocationresidency
|
|
+ *args)
|
|
+{
|
|
+ int ret = -EINVAL;
|
|
+ struct dxgkvmb_command_queryallocationresidency *command = NULL;
|
|
+ u32 cmd_size = sizeof(*command);
|
|
+ u32 alloc_size = 0;
|
|
+ u32 result_allocation_size = 0;
|
|
+ struct dxgkvmb_command_queryallocationresidency_return *result = NULL;
|
|
+ u32 result_size = sizeof(*result);
|
|
+ struct dxgvmbusmsgres msg = {.hdr = NULL};
|
|
+
|
|
+ if (args->allocation_count > DXG_MAX_VM_BUS_PACKET_SIZE) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ if (args->allocation_count) {
|
|
+ alloc_size = args->allocation_count *
|
|
+ sizeof(struct d3dkmthandle);
|
|
+ cmd_size += alloc_size;
|
|
+ result_allocation_size = args->allocation_count *
|
|
+ sizeof(args->residency_status[0]);
|
|
+ } else {
|
|
+ result_allocation_size = sizeof(args->residency_status[0]);
|
|
+ }
|
|
+ result_size += result_allocation_size;
|
|
+
|
|
+ ret = init_message_res(&msg, adapter, process, cmd_size, result_size);
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+ command = (void *)msg.msg;
|
|
+ result = msg.res;
|
|
+
|
|
+ command_vgpu_to_host_init2(&command->hdr,
|
|
+ DXGK_VMBCOMMAND_QUERYALLOCATIONRESIDENCY,
|
|
+ process->host_handle);
|
|
+ command->args = *args;
|
|
+ if (alloc_size) {
|
|
+ ret = copy_from_user(&command[1], args->allocations,
|
|
+ alloc_size);
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy alloc handles");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size,
|
|
+ result, msg.res_size);
|
|
+ if (ret < 0)
|
|
+ goto cleanup;
|
|
+
|
|
+ ret = ntstatus2int(result->status);
|
|
+ if (ret < 0)
|
|
+ goto cleanup;
|
|
+
|
|
+ ret = copy_to_user(args->residency_status, &result[1],
|
|
+ result_allocation_size);
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy residency status");
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+
|
|
+cleanup:
|
|
+ free_message((struct dxgvmbusmsg *)&msg, process);
|
|
+ if (ret)
|
|
+ DXG_TRACE("err: %d", ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int dxgvmb_send_get_device_state(struct dxgprocess *process,
|
|
struct dxgadapter *adapter,
|
|
struct d3dkmt_getdevicestate *args,
|
|
@@ -2461,6 +2534,233 @@ int dxgvmb_send_unlock2(struct dxgprocess *process,
|
|
return ret;
|
|
}
|
|
|
|
+int dxgvmb_send_update_alloc_property(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dddi_updateallocproperty *args,
|
|
+ struct d3dddi_updateallocproperty *__user
|
|
+ inargs)
|
|
+{
|
|
+ int ret;
|
|
+ int ret1;
|
|
+ struct dxgkvmb_command_updateallocationproperty *command;
|
|
+ struct dxgkvmb_command_updateallocationproperty_return result = { };
|
|
+ struct dxgvmbusmsg msg = {.hdr = NULL};
|
|
+
|
|
+ ret = init_message(&msg, adapter, process, sizeof(*command));
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+ command = (void *)msg.msg;
|
|
+
|
|
+ command_vgpu_to_host_init2(&command->hdr,
|
|
+ DXGK_VMBCOMMAND_UPDATEALLOCATIONPROPERTY,
|
|
+ process->host_handle);
|
|
+ command->args = *args;
|
|
+
|
|
+ ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size,
|
|
+ &result, sizeof(result));
|
|
+
|
|
+ if (ret < 0)
|
|
+ goto cleanup;
|
|
+ ret = ntstatus2int(result.status);
|
|
+ /* STATUS_PENING is a success code > 0 */
|
|
+ if (ret == STATUS_PENDING) {
|
|
+ ret1 = copy_to_user(&inargs->paging_fence_value,
|
|
+ &result.paging_fence_value,
|
|
+ sizeof(u64));
|
|
+ if (ret1) {
|
|
+ DXG_ERR("failed to copy paging fence");
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+ }
|
|
+cleanup:
|
|
+ free_message(&msg, process);
|
|
+ if (ret)
|
|
+ DXG_TRACE("err: %d", ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int dxgvmb_send_set_allocation_priority(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmt_setallocationpriority *args)
|
|
+{
|
|
+ u32 cmd_size = sizeof(struct dxgkvmb_command_setallocationpriority);
|
|
+ u32 alloc_size = 0;
|
|
+ u32 priority_size = 0;
|
|
+ struct dxgkvmb_command_setallocationpriority *command;
|
|
+ int ret;
|
|
+ struct d3dkmthandle *allocations;
|
|
+ struct dxgvmbusmsg msg = {.hdr = NULL};
|
|
+
|
|
+ if (args->allocation_count > DXG_MAX_VM_BUS_PACKET_SIZE) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ if (args->resource.v) {
|
|
+ priority_size = sizeof(u32);
|
|
+ if (args->allocation_count != 0) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ } else {
|
|
+ if (args->allocation_count == 0) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ alloc_size = args->allocation_count *
|
|
+ sizeof(struct d3dkmthandle);
|
|
+ cmd_size += alloc_size;
|
|
+ priority_size = sizeof(u32) * args->allocation_count;
|
|
+ }
|
|
+ cmd_size += priority_size;
|
|
+
|
|
+ ret = init_message(&msg, adapter, process, cmd_size);
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+ command = (void *)msg.msg;
|
|
+
|
|
+ command_vgpu_to_host_init2(&command->hdr,
|
|
+ DXGK_VMBCOMMAND_SETALLOCATIONPRIORITY,
|
|
+ process->host_handle);
|
|
+ command->device = args->device;
|
|
+ command->allocation_count = args->allocation_count;
|
|
+ command->resource = args->resource;
|
|
+ allocations = (struct d3dkmthandle *) &command[1];
|
|
+ ret = copy_from_user(allocations, args->allocation_list,
|
|
+ alloc_size);
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy alloc handle");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ ret = copy_from_user((u8 *) allocations + alloc_size,
|
|
+ args->priorities, priority_size);
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy alloc priority");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
|
|
+
|
|
+cleanup:
|
|
+ free_message(&msg, process);
|
|
+ if (ret)
|
|
+ DXG_TRACE("err: %d", ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int dxgvmb_send_get_allocation_priority(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmt_getallocationpriority *args)
|
|
+{
|
|
+ u32 cmd_size = sizeof(struct dxgkvmb_command_getallocationpriority);
|
|
+ u32 result_size;
|
|
+ u32 alloc_size = 0;
|
|
+ u32 priority_size = 0;
|
|
+ struct dxgkvmb_command_getallocationpriority *command;
|
|
+ struct dxgkvmb_command_getallocationpriority_return *result;
|
|
+ int ret;
|
|
+ struct d3dkmthandle *allocations;
|
|
+ struct dxgvmbusmsgres msg = {.hdr = NULL};
|
|
+
|
|
+ if (args->allocation_count > DXG_MAX_VM_BUS_PACKET_SIZE) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ if (args->resource.v) {
|
|
+ priority_size = sizeof(u32);
|
|
+ if (args->allocation_count != 0) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ } else {
|
|
+ if (args->allocation_count == 0) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ alloc_size = args->allocation_count *
|
|
+ sizeof(struct d3dkmthandle);
|
|
+ cmd_size += alloc_size;
|
|
+ priority_size = sizeof(u32) * args->allocation_count;
|
|
+ }
|
|
+ result_size = sizeof(*result) + priority_size;
|
|
+
|
|
+ ret = init_message_res(&msg, adapter, process, cmd_size, result_size);
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+ command = (void *)msg.msg;
|
|
+ result = msg.res;
|
|
+
|
|
+ command_vgpu_to_host_init2(&command->hdr,
|
|
+ DXGK_VMBCOMMAND_GETALLOCATIONPRIORITY,
|
|
+ process->host_handle);
|
|
+ command->device = args->device;
|
|
+ command->allocation_count = args->allocation_count;
|
|
+ command->resource = args->resource;
|
|
+ allocations = (struct d3dkmthandle *) &command[1];
|
|
+ ret = copy_from_user(allocations, args->allocation_list,
|
|
+ alloc_size);
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy alloc handles");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr,
|
|
+ msg.size + msg.res_size,
|
|
+ result, msg.res_size);
|
|
+ if (ret < 0)
|
|
+ goto cleanup;
|
|
+
|
|
+ ret = ntstatus2int(result->status);
|
|
+ if (ret < 0)
|
|
+ goto cleanup;
|
|
+
|
|
+ ret = copy_to_user(args->priorities,
|
|
+ (u8 *) result + sizeof(*result),
|
|
+ priority_size);
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy priorities");
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+
|
|
+cleanup:
|
|
+ free_message((struct dxgvmbusmsg *)&msg, process);
|
|
+ if (ret)
|
|
+ DXG_TRACE("err: %d", ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int dxgvmb_send_change_vidmem_reservation(struct dxgprocess *process,
|
|
+ struct dxgadapter *adapter,
|
|
+ struct d3dkmthandle other_process,
|
|
+ struct
|
|
+ d3dkmt_changevideomemoryreservation
|
|
+ *args)
|
|
+{
|
|
+ struct dxgkvmb_command_changevideomemoryreservation *command;
|
|
+ int ret;
|
|
+ struct dxgvmbusmsg msg = {.hdr = NULL};
|
|
+
|
|
+ ret = init_message(&msg, adapter, process, sizeof(*command));
|
|
+ if (ret)
|
|
+ goto cleanup;
|
|
+ command = (void *)msg.msg;
|
|
+
|
|
+ command_vgpu_to_host_init2(&command->hdr,
|
|
+ DXGK_VMBCOMMAND_CHANGEVIDEOMEMORYRESERVATION,
|
|
+ process->host_handle);
|
|
+ command->args = *args;
|
|
+ command->args.process = other_process.v;
|
|
+
|
|
+ ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
|
|
+cleanup:
|
|
+ free_message(&msg, process);
|
|
+ if (ret)
|
|
+ DXG_TRACE("err: %d", ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int dxgvmb_send_create_hwqueue(struct dxgprocess *process,
|
|
struct dxgadapter *adapter,
|
|
struct d3dkmt_createhwqueue *args,
|
|
diff --git a/drivers/hv/dxgkrnl/dxgvmbus.h b/drivers/hv/dxgkrnl/dxgvmbus.h
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/hv/dxgkrnl/dxgvmbus.h
|
|
+++ b/drivers/hv/dxgkrnl/dxgvmbus.h
|
|
@@ -308,6 +308,29 @@ struct dxgkvmb_command_queryadapterinfo_return {
|
|
u8 private_data[1];
|
|
};
|
|
|
|
+/* Returns ntstatus */
|
|
+struct dxgkvmb_command_setallocationpriority {
|
|
+ struct dxgkvmb_command_vgpu_to_host hdr;
|
|
+ struct d3dkmthandle device;
|
|
+ struct d3dkmthandle resource;
|
|
+ u32 allocation_count;
|
|
+ /* struct d3dkmthandle allocations[allocation_count or 0]; */
|
|
+ /* u32 priorities[allocation_count or 1]; */
|
|
+};
|
|
+
|
|
+struct dxgkvmb_command_getallocationpriority {
|
|
+ struct dxgkvmb_command_vgpu_to_host hdr;
|
|
+ struct d3dkmthandle device;
|
|
+ struct d3dkmthandle resource;
|
|
+ u32 allocation_count;
|
|
+ /* struct d3dkmthandle allocations[allocation_count or 0]; */
|
|
+};
|
|
+
|
|
+struct dxgkvmb_command_getallocationpriority_return {
|
|
+ struct ntstatus status;
|
|
+ /* u32 priorities[allocation_count or 1]; */
|
|
+};
|
|
+
|
|
struct dxgkvmb_command_createdevice {
|
|
struct dxgkvmb_command_vgpu_to_host hdr;
|
|
struct d3dkmt_createdeviceflags flags;
|
|
@@ -589,6 +612,22 @@ struct dxgkvmb_command_unlock2 {
|
|
bool use_legacy_unlock;
|
|
};
|
|
|
|
+struct dxgkvmb_command_updateallocationproperty {
|
|
+ struct dxgkvmb_command_vgpu_to_host hdr;
|
|
+ struct d3dddi_updateallocproperty args;
|
|
+};
|
|
+
|
|
+struct dxgkvmb_command_updateallocationproperty_return {
|
|
+ u64 paging_fence_value;
|
|
+ struct ntstatus status;
|
|
+};
|
|
+
|
|
+/* Returns ntstatus */
|
|
+struct dxgkvmb_command_changevideomemoryreservation {
|
|
+ struct dxgkvmb_command_vgpu_to_host hdr;
|
|
+ struct d3dkmt_changevideomemoryreservation args;
|
|
+};
|
|
+
|
|
/* Returns the same structure */
|
|
struct dxgkvmb_command_createhwqueue {
|
|
struct dxgkvmb_command_vgpu_to_host hdr;
|
|
@@ -609,6 +648,17 @@ struct dxgkvmb_command_destroyhwqueue {
|
|
struct d3dkmthandle hwqueue;
|
|
};
|
|
|
|
+struct dxgkvmb_command_queryallocationresidency {
|
|
+ struct dxgkvmb_command_vgpu_to_host hdr;
|
|
+ struct d3dkmt_queryallocationresidency args;
|
|
+ /* struct d3dkmthandle allocations[0 or number of allocations] */
|
|
+};
|
|
+
|
|
+struct dxgkvmb_command_queryallocationresidency_return {
|
|
+ struct ntstatus status;
|
|
+ /* d3dkmt_allocationresidencystatus[NumAllocations] */
|
|
+};
|
|
+
|
|
struct dxgkvmb_command_getdevicestate {
|
|
struct dxgkvmb_command_vgpu_to_host hdr;
|
|
struct d3dkmt_getdevicestate args;
|
|
diff --git a/drivers/hv/dxgkrnl/ioctl.c b/drivers/hv/dxgkrnl/ioctl.c
|
|
index 111111111111..222222222222 100644
|
|
--- a/drivers/hv/dxgkrnl/ioctl.c
|
|
+++ b/drivers/hv/dxgkrnl/ioctl.c
|
|
@@ -3214,7 +3214,7 @@ dxgkio_lock2(struct dxgprocess *process, void *__user inargs)
|
|
kref_put(&device->device_kref, dxgdevice_release);
|
|
|
|
success:
|
|
- DXG_TRACE("ioctl:%s %s %d", errorstr(ret), __func__, ret);
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
return ret;
|
|
}
|
|
|
|
@@ -3294,7 +3294,209 @@ dxgkio_unlock2(struct dxgprocess *process, void *__user inargs)
|
|
kref_put(&device->device_kref, dxgdevice_release);
|
|
|
|
success:
|
|
- DXG_TRACE("ioctl:%s %s %d", errorstr(ret), __func__, ret);
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int
|
|
+dxgkio_update_alloc_property(struct dxgprocess *process, void *__user inargs)
|
|
+{
|
|
+ struct d3dddi_updateallocproperty args;
|
|
+ int ret;
|
|
+ struct dxgadapter *adapter = NULL;
|
|
+ struct dxgdevice *device = NULL;
|
|
+
|
|
+ ret = copy_from_user(&args, inargs, sizeof(args));
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy input args");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ device = dxgprocess_device_by_object_handle(process,
|
|
+ HMGRENTRY_TYPE_DXGPAGINGQUEUE,
|
|
+ args.paging_queue);
|
|
+ if (device == NULL) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ adapter = device->adapter;
|
|
+ ret = dxgadapter_acquire_lock_shared(adapter);
|
|
+ if (ret < 0) {
|
|
+ adapter = NULL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ ret = dxgvmb_send_update_alloc_property(process, adapter,
|
|
+ &args, inargs);
|
|
+
|
|
+cleanup:
|
|
+ if (adapter)
|
|
+ dxgadapter_release_lock_shared(adapter);
|
|
+
|
|
+ if (device)
|
|
+ kref_put(&device->device_kref, dxgdevice_release);
|
|
+
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int
|
|
+dxgkio_query_alloc_residency(struct dxgprocess *process, void *__user inargs)
|
|
+{
|
|
+ struct d3dkmt_queryallocationresidency args;
|
|
+ struct dxgadapter *adapter = NULL;
|
|
+ struct dxgdevice *device = NULL;
|
|
+ int ret;
|
|
+
|
|
+ ret = copy_from_user(&args, inargs, sizeof(args));
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy input args");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ if ((args.allocation_count == 0) == (args.resource.v == 0)) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ device = dxgprocess_device_by_handle(process, args.device);
|
|
+ if (device == NULL) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ adapter = device->adapter;
|
|
+ ret = dxgadapter_acquire_lock_shared(adapter);
|
|
+ if (ret < 0) {
|
|
+ adapter = NULL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ ret = dxgvmb_send_query_alloc_residency(process, adapter, &args);
|
|
+cleanup:
|
|
+ if (adapter)
|
|
+ dxgadapter_release_lock_shared(adapter);
|
|
+ if (device)
|
|
+ kref_put(&device->device_kref, dxgdevice_release);
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int
|
|
+dxgkio_set_allocation_priority(struct dxgprocess *process, void *__user inargs)
|
|
+{
|
|
+ struct d3dkmt_setallocationpriority args;
|
|
+ struct dxgadapter *adapter = NULL;
|
|
+ struct dxgdevice *device = NULL;
|
|
+ int ret;
|
|
+
|
|
+ ret = copy_from_user(&args, inargs, sizeof(args));
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy input args");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ device = dxgprocess_device_by_handle(process, args.device);
|
|
+ if (device == NULL) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ adapter = device->adapter;
|
|
+ ret = dxgadapter_acquire_lock_shared(adapter);
|
|
+ if (ret < 0) {
|
|
+ adapter = NULL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ ret = dxgvmb_send_set_allocation_priority(process, adapter, &args);
|
|
+cleanup:
|
|
+ if (adapter)
|
|
+ dxgadapter_release_lock_shared(adapter);
|
|
+ if (device)
|
|
+ kref_put(&device->device_kref, dxgdevice_release);
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int
|
|
+dxgkio_get_allocation_priority(struct dxgprocess *process, void *__user inargs)
|
|
+{
|
|
+ struct d3dkmt_getallocationpriority args;
|
|
+ struct dxgadapter *adapter = NULL;
|
|
+ struct dxgdevice *device = NULL;
|
|
+ int ret;
|
|
+
|
|
+ ret = copy_from_user(&args, inargs, sizeof(args));
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy input args");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ device = dxgprocess_device_by_handle(process, args.device);
|
|
+ if (device == NULL) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ adapter = device->adapter;
|
|
+ ret = dxgadapter_acquire_lock_shared(adapter);
|
|
+ if (ret < 0) {
|
|
+ adapter = NULL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ ret = dxgvmb_send_get_allocation_priority(process, adapter, &args);
|
|
+cleanup:
|
|
+ if (adapter)
|
|
+ dxgadapter_release_lock_shared(adapter);
|
|
+ if (device)
|
|
+ kref_put(&device->device_kref, dxgdevice_release);
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int
|
|
+dxgkio_change_vidmem_reservation(struct dxgprocess *process, void *__user inargs)
|
|
+{
|
|
+ struct d3dkmt_changevideomemoryreservation args;
|
|
+ int ret;
|
|
+ struct dxgadapter *adapter = NULL;
|
|
+ bool adapter_locked = false;
|
|
+
|
|
+ ret = copy_from_user(&args, inargs, sizeof(args));
|
|
+ if (ret) {
|
|
+ DXG_ERR("failed to copy input args");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ if (args.process != 0) {
|
|
+ DXG_ERR("setting memory reservation for other process");
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ adapter = dxgprocess_adapter_by_handle(process, args.adapter);
|
|
+ if (adapter == NULL) {
|
|
+ ret = -EINVAL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ ret = dxgadapter_acquire_lock_shared(adapter);
|
|
+ if (ret < 0) {
|
|
+ adapter = NULL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ adapter_locked = true;
|
|
+ args.adapter.v = 0;
|
|
+ ret = dxgvmb_send_change_vidmem_reservation(process, adapter,
|
|
+ zerohandle, &args);
|
|
+
|
|
+cleanup:
|
|
+
|
|
+ if (adapter_locked)
|
|
+ dxgadapter_release_lock_shared(adapter);
|
|
+ if (adapter)
|
|
+ kref_put(&adapter->adapter_kref, dxgadapter_release);
|
|
+
|
|
+ DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
|
|
return ret;
|
|
}
|
|
|
|
@@ -4050,7 +4252,8 @@ static struct ioctl_desc ioctls[] = {
|
|
/* 0x13 */ {dxgkio_destroy_allocation, LX_DXDESTROYALLOCATION2},
|
|
/* 0x14 */ {dxgkio_enum_adapters, LX_DXENUMADAPTERS2},
|
|
/* 0x15 */ {dxgkio_close_adapter, LX_DXCLOSEADAPTER},
|
|
-/* 0x16 */ {},
|
|
+/* 0x16 */ {dxgkio_change_vidmem_reservation,
|
|
+ LX_DXCHANGEVIDEOMEMORYRESERVATION},
|
|
/* 0x17 */ {},
|
|
/* 0x18 */ {dxgkio_create_hwqueue, LX_DXCREATEHWQUEUE},
|
|
/* 0x19 */ {dxgkio_destroy_device, LX_DXDESTROYDEVICE},
|
|
@@ -4070,11 +4273,11 @@ static struct ioctl_desc ioctls[] = {
|
|
/* 0x27 */ {},
|
|
/* 0x28 */ {},
|
|
/* 0x29 */ {},
|
|
-/* 0x2a */ {},
|
|
+/* 0x2a */ {dxgkio_query_alloc_residency, LX_DXQUERYALLOCATIONRESIDENCY},
|
|
/* 0x2b */ {},
|
|
/* 0x2c */ {},
|
|
/* 0x2d */ {},
|
|
-/* 0x2e */ {},
|
|
+/* 0x2e */ {dxgkio_set_allocation_priority, LX_DXSETALLOCATIONPRIORITY},
|
|
/* 0x2f */ {},
|
|
/* 0x30 */ {},
|
|
/* 0x31 */ {dxgkio_signal_sync_object_cpu,
|
|
@@ -4089,13 +4292,13 @@ static struct ioctl_desc ioctls[] = {
|
|
/* 0x36 */ {dxgkio_submit_wait_to_hwqueue,
|
|
LX_DXSUBMITWAITFORSYNCOBJECTSTOHWQUEUE},
|
|
/* 0x37 */ {dxgkio_unlock2, LX_DXUNLOCK2},
|
|
-/* 0x38 */ {},
|
|
+/* 0x38 */ {dxgkio_update_alloc_property, LX_DXUPDATEALLOCPROPERTY},
|
|
/* 0x39 */ {},
|
|
/* 0x3a */ {dxgkio_wait_sync_object_cpu,
|
|
LX_DXWAITFORSYNCHRONIZATIONOBJECTFROMCPU},
|
|
/* 0x3b */ {dxgkio_wait_sync_object_gpu,
|
|
LX_DXWAITFORSYNCHRONIZATIONOBJECTFROMGPU},
|
|
-/* 0x3c */ {},
|
|
+/* 0x3c */ {dxgkio_get_allocation_priority, LX_DXGETALLOCATIONPRIORITY},
|
|
/* 0x3d */ {},
|
|
/* 0x3e */ {dxgkio_enum_adapters3, LX_DXENUMADAPTERS3},
|
|
/* 0x3f */ {dxgkio_share_objects, LX_DXSHAREOBJECTS},
|
|
diff --git a/include/uapi/misc/d3dkmthk.h b/include/uapi/misc/d3dkmthk.h
|
|
index 111111111111..222222222222 100644
|
|
--- a/include/uapi/misc/d3dkmthk.h
|
|
+++ b/include/uapi/misc/d3dkmthk.h
|
|
@@ -668,6 +668,63 @@ struct d3dkmt_submitcommandtohwqueue {
|
|
#endif
|
|
};
|
|
|
|
+struct d3dkmt_setallocationpriority {
|
|
+ struct d3dkmthandle device;
|
|
+ struct d3dkmthandle resource;
|
|
+#ifdef __KERNEL__
|
|
+ const struct d3dkmthandle *allocation_list;
|
|
+#else
|
|
+ __u64 allocation_list;
|
|
+#endif
|
|
+ __u32 allocation_count;
|
|
+ __u32 reserved;
|
|
+#ifdef __KERNEL__
|
|
+ const __u32 *priorities;
|
|
+#else
|
|
+ __u64 priorities;
|
|
+#endif
|
|
+};
|
|
+
|
|
+struct d3dkmt_getallocationpriority {
|
|
+ struct d3dkmthandle device;
|
|
+ struct d3dkmthandle resource;
|
|
+#ifdef __KERNEL__
|
|
+ const struct d3dkmthandle *allocation_list;
|
|
+#else
|
|
+ __u64 allocation_list;
|
|
+#endif
|
|
+ __u32 allocation_count;
|
|
+ __u32 reserved;
|
|
+#ifdef __KERNEL__
|
|
+ __u32 *priorities;
|
|
+#else
|
|
+ __u64 priorities;
|
|
+#endif
|
|
+};
|
|
+
|
|
+enum d3dkmt_allocationresidencystatus {
|
|
+ _D3DKMT_ALLOCATIONRESIDENCYSTATUS_RESIDENTINGPUMEMORY = 1,
|
|
+ _D3DKMT_ALLOCATIONRESIDENCYSTATUS_RESIDENTINSHAREDMEMORY = 2,
|
|
+ _D3DKMT_ALLOCATIONRESIDENCYSTATUS_NOTRESIDENT = 3,
|
|
+};
|
|
+
|
|
+struct d3dkmt_queryallocationresidency {
|
|
+ struct d3dkmthandle device;
|
|
+ struct d3dkmthandle resource;
|
|
+#ifdef __KERNEL__
|
|
+ struct d3dkmthandle *allocations;
|
|
+#else
|
|
+ __u64 allocations;
|
|
+#endif
|
|
+ __u32 allocation_count;
|
|
+ __u32 reserved;
|
|
+#ifdef __KERNEL__
|
|
+ enum d3dkmt_allocationresidencystatus *residency_status;
|
|
+#else
|
|
+ __u64 residency_status;
|
|
+#endif
|
|
+};
|
|
+
|
|
struct d3dddicb_lock2flags {
|
|
union {
|
|
struct {
|
|
@@ -835,6 +892,11 @@ struct d3dkmt_destroyallocation2 {
|
|
struct d3dddicb_destroyallocation2flags flags;
|
|
};
|
|
|
|
+enum d3dkmt_memory_segment_group {
|
|
+ _D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL = 0,
|
|
+ _D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL = 1
|
|
+};
|
|
+
|
|
struct d3dkmt_adaptertype {
|
|
union {
|
|
struct {
|
|
@@ -886,6 +948,61 @@ struct d3dddi_openallocationinfo2 {
|
|
__u64 reserved[6];
|
|
};
|
|
|
|
+struct d3dddi_updateallocproperty_flags {
|
|
+ union {
|
|
+ struct {
|
|
+ __u32 accessed_physically:1;
|
|
+ __u32 reserved:31;
|
|
+ };
|
|
+ __u32 value;
|
|
+ };
|
|
+};
|
|
+
|
|
+struct d3dddi_segmentpreference {
|
|
+ union {
|
|
+ struct {
|
|
+ __u32 segment_id0:5;
|
|
+ __u32 direction0:1;
|
|
+ __u32 segment_id1:5;
|
|
+ __u32 direction1:1;
|
|
+ __u32 segment_id2:5;
|
|
+ __u32 direction2:1;
|
|
+ __u32 segment_id3:5;
|
|
+ __u32 direction3:1;
|
|
+ __u32 segment_id4:5;
|
|
+ __u32 direction4:1;
|
|
+ __u32 reserved:2;
|
|
+ };
|
|
+ __u32 value;
|
|
+ };
|
|
+};
|
|
+
|
|
+struct d3dddi_updateallocproperty {
|
|
+ struct d3dkmthandle paging_queue;
|
|
+ struct d3dkmthandle allocation;
|
|
+ __u32 supported_segment_set;
|
|
+ struct d3dddi_segmentpreference preferred_segment;
|
|
+ struct d3dddi_updateallocproperty_flags flags;
|
|
+ __u64 paging_fence_value;
|
|
+ union {
|
|
+ struct {
|
|
+ __u32 set_accessed_physically:1;
|
|
+ __u32 set_supported_segmentSet:1;
|
|
+ __u32 set_preferred_segment:1;
|
|
+ __u32 reserved:29;
|
|
+ };
|
|
+ __u32 property_mask_value;
|
|
+ };
|
|
+};
|
|
+
|
|
+struct d3dkmt_changevideomemoryreservation {
|
|
+ __u64 process;
|
|
+ struct d3dkmthandle adapter;
|
|
+ enum d3dkmt_memory_segment_group memory_segment_group;
|
|
+ __u64 reservation;
|
|
+ __u32 physical_adapter_index;
|
|
+};
|
|
+
|
|
struct d3dkmt_createhwqueue {
|
|
struct d3dkmthandle context;
|
|
struct d3dddi_createhwqueueflags flags;
|
|
@@ -1099,6 +1216,8 @@ struct d3dkmt_shareobjectwithhost {
|
|
_IOWR(0x47, 0x14, struct d3dkmt_enumadapters2)
|
|
#define LX_DXCLOSEADAPTER \
|
|
_IOWR(0x47, 0x15, struct d3dkmt_closeadapter)
|
|
+#define LX_DXCHANGEVIDEOMEMORYRESERVATION \
|
|
+ _IOWR(0x47, 0x16, struct d3dkmt_changevideomemoryreservation)
|
|
#define LX_DXCREATEHWQUEUE \
|
|
_IOWR(0x47, 0x18, struct d3dkmt_createhwqueue)
|
|
#define LX_DXDESTROYHWQUEUE \
|
|
@@ -1111,6 +1230,10 @@ struct d3dkmt_shareobjectwithhost {
|
|
_IOWR(0x47, 0x1d, struct d3dkmt_destroysynchronizationobject)
|
|
#define LX_DXLOCK2 \
|
|
_IOWR(0x47, 0x25, struct d3dkmt_lock2)
|
|
+#define LX_DXQUERYALLOCATIONRESIDENCY \
|
|
+ _IOWR(0x47, 0x2a, struct d3dkmt_queryallocationresidency)
|
|
+#define LX_DXSETALLOCATIONPRIORITY \
|
|
+ _IOWR(0x47, 0x2e, struct d3dkmt_setallocationpriority)
|
|
#define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMCPU \
|
|
_IOWR(0x47, 0x31, struct d3dkmt_signalsynchronizationobjectfromcpu)
|
|
#define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMGPU \
|
|
@@ -1125,10 +1248,14 @@ struct d3dkmt_shareobjectwithhost {
|
|
_IOWR(0x47, 0x36, struct d3dkmt_submitwaitforsyncobjectstohwqueue)
|
|
#define LX_DXUNLOCK2 \
|
|
_IOWR(0x47, 0x37, struct d3dkmt_unlock2)
|
|
+#define LX_DXUPDATEALLOCPROPERTY \
|
|
+ _IOWR(0x47, 0x38, struct d3dddi_updateallocproperty)
|
|
#define LX_DXWAITFORSYNCHRONIZATIONOBJECTFROMCPU \
|
|
_IOWR(0x47, 0x3a, struct d3dkmt_waitforsynchronizationobjectfromcpu)
|
|
#define LX_DXWAITFORSYNCHRONIZATIONOBJECTFROMGPU \
|
|
_IOWR(0x47, 0x3b, struct d3dkmt_waitforsynchronizationobjectfromgpu)
|
|
+#define LX_DXGETALLOCATIONPRIORITY \
|
|
+ _IOWR(0x47, 0x3c, struct d3dkmt_getallocationpriority)
|
|
#define LX_DXENUMADAPTERS3 \
|
|
_IOWR(0x47, 0x3e, struct d3dkmt_enumadapters3)
|
|
#define LX_DXSHAREOBJECTS \
|
|
--
|
|
Armbian
|
|
|