Skip to content

Commit fcb44b5

Browse files
Iouri Tarassovchessturo
authored andcommitted
drivers: hv: dxgkrnl: Manage compute device virtual addresses
Implement ioctls to manage compute device virtual addresses (VA): - LX_DXRESERVEGPUVIRTUALADDRESS, - LX_DXFREEGPUVIRTUALADDRESS, - LX_DXMAPGPUVIRTUALADDRESS, - LX_DXUPDATEGPUVIRTUALADDRESS. Compute devices access memory by using virtual addressses. Each process has a dedicated VA space. The video memory manager on the host is responsible with updating device page tables before submitting a DMA buffer for execution. The LX_DXRESERVEGPUVIRTUALADDRESS ioctl reserves a portion of the process compute device VA space. The LX_DXMAPGPUVIRTUALADDRESS ioctl reserves a portion of the process compute device VA space and maps it to the given compute device allocation. The LX_DXFREEGPUVIRTUALADDRESS frees the previously reserved portion of the compute device VA space. The LX_DXUPDATEGPUVIRTUALADDRESS ioctl adds operations to modify the compute device VA space to a compute device execution context. It allows the operations to be queued and synchronized with execution of other compute device DMA buffers.. 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 6ddd3ce commit fcb44b5

5 files changed

Lines changed: 548 additions & 4 deletions

File tree

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,16 @@ int dxgvmb_send_evict(struct dxgprocess *pr, struct dxgadapter *adapter,
817817
int dxgvmb_send_submit_command(struct dxgprocess *pr,
818818
struct dxgadapter *adapter,
819819
struct d3dkmt_submitcommand *args);
820+
int dxgvmb_send_map_gpu_va(struct dxgprocess *pr, struct d3dkmthandle h,
821+
struct dxgadapter *adapter,
822+
struct d3dddi_mapgpuvirtualaddress *args);
823+
int dxgvmb_send_reserve_gpu_va(struct dxgprocess *pr,
824+
struct dxgadapter *adapter,
825+
struct d3dddi_reservegpuvirtualaddress *args);
826+
int dxgvmb_send_free_gpu_va(struct dxgprocess *pr, struct dxgadapter *adapter,
827+
struct d3dkmt_freegpuvirtualaddress *args);
828+
int dxgvmb_send_update_gpu_va(struct dxgprocess *pr, struct dxgadapter *adapter,
829+
struct d3dkmt_updategpuvirtualaddress *args);
820830
int dxgvmb_send_create_sync_object(struct dxgprocess *pr,
821831
struct dxgadapter *adapter,
822832
struct d3dkmt_createsynchronizationobject2

drivers/hv/dxgkrnl/dxgvmbus.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,156 @@ int dxgvmb_send_submit_command(struct dxgprocess *process,
24322432
return ret;
24332433
}
24342434

2435+
int dxgvmb_send_map_gpu_va(struct dxgprocess *process,
2436+
struct d3dkmthandle device,
2437+
struct dxgadapter *adapter,
2438+
struct d3dddi_mapgpuvirtualaddress *args)
2439+
{
2440+
struct dxgkvmb_command_mapgpuvirtualaddress *command;
2441+
struct dxgkvmb_command_mapgpuvirtualaddress_return result;
2442+
int ret;
2443+
struct dxgvmbusmsg msg = {.hdr = NULL};
2444+
2445+
ret = init_message(&msg, adapter, process, sizeof(*command));
2446+
if (ret)
2447+
goto cleanup;
2448+
command = (void *)msg.msg;
2449+
2450+
command_vgpu_to_host_init2(&command->hdr,
2451+
DXGK_VMBCOMMAND_MAPGPUVIRTUALADDRESS,
2452+
process->host_handle);
2453+
command->args = *args;
2454+
command->device = device;
2455+
2456+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, &result,
2457+
sizeof(result));
2458+
if (ret < 0)
2459+
goto cleanup;
2460+
args->virtual_address = result.virtual_address;
2461+
args->paging_fence_value = result.paging_fence_value;
2462+
ret = ntstatus2int(result.status);
2463+
2464+
cleanup:
2465+
2466+
free_message(&msg, process);
2467+
if (ret)
2468+
DXG_TRACE("err: %d", ret);
2469+
return ret;
2470+
}
2471+
2472+
int dxgvmb_send_reserve_gpu_va(struct dxgprocess *process,
2473+
struct dxgadapter *adapter,
2474+
struct d3dddi_reservegpuvirtualaddress *args)
2475+
{
2476+
struct dxgkvmb_command_reservegpuvirtualaddress *command;
2477+
struct dxgkvmb_command_reservegpuvirtualaddress_return result;
2478+
int ret;
2479+
struct dxgvmbusmsg msg = {.hdr = NULL};
2480+
2481+
ret = init_message(&msg, adapter, process, sizeof(*command));
2482+
if (ret)
2483+
goto cleanup;
2484+
command = (void *)msg.msg;
2485+
2486+
command_vgpu_to_host_init2(&command->hdr,
2487+
DXGK_VMBCOMMAND_RESERVEGPUVIRTUALADDRESS,
2488+
process->host_handle);
2489+
command->args = *args;
2490+
2491+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, &result,
2492+
sizeof(result));
2493+
args->virtual_address = result.virtual_address;
2494+
2495+
cleanup:
2496+
free_message(&msg, process);
2497+
if (ret)
2498+
DXG_TRACE("err: %d", ret);
2499+
return ret;
2500+
}
2501+
2502+
int dxgvmb_send_free_gpu_va(struct dxgprocess *process,
2503+
struct dxgadapter *adapter,
2504+
struct d3dkmt_freegpuvirtualaddress *args)
2505+
{
2506+
struct dxgkvmb_command_freegpuvirtualaddress *command;
2507+
int ret;
2508+
struct dxgvmbusmsg msg = {.hdr = NULL};
2509+
2510+
ret = init_message(&msg, adapter, process, sizeof(*command));
2511+
if (ret)
2512+
goto cleanup;
2513+
command = (void *)msg.msg;
2514+
2515+
command_vgpu_to_host_init2(&command->hdr,
2516+
DXGK_VMBCOMMAND_FREEGPUVIRTUALADDRESS,
2517+
process->host_handle);
2518+
command->args = *args;
2519+
2520+
ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
2521+
2522+
cleanup:
2523+
free_message(&msg, process);
2524+
if (ret)
2525+
DXG_TRACE("err: %d", ret);
2526+
return ret;
2527+
}
2528+
2529+
int dxgvmb_send_update_gpu_va(struct dxgprocess *process,
2530+
struct dxgadapter *adapter,
2531+
struct d3dkmt_updategpuvirtualaddress *args)
2532+
{
2533+
struct dxgkvmb_command_updategpuvirtualaddress *command;
2534+
u32 cmd_size;
2535+
u32 op_size;
2536+
int ret;
2537+
struct dxgvmbusmsg msg = {.hdr = NULL};
2538+
2539+
if (args->num_operations == 0 ||
2540+
(DXG_MAX_VM_BUS_PACKET_SIZE /
2541+
sizeof(struct d3dddi_updategpuvirtualaddress_operation)) <
2542+
args->num_operations) {
2543+
ret = -EINVAL;
2544+
DXG_ERR("Invalid number of operations: %d",
2545+
args->num_operations);
2546+
goto cleanup;
2547+
}
2548+
2549+
op_size = args->num_operations *
2550+
sizeof(struct d3dddi_updategpuvirtualaddress_operation);
2551+
cmd_size = sizeof(struct dxgkvmb_command_updategpuvirtualaddress) +
2552+
op_size - sizeof(args->operations[0]);
2553+
2554+
ret = init_message(&msg, adapter, process, cmd_size);
2555+
if (ret)
2556+
goto cleanup;
2557+
command = (void *)msg.msg;
2558+
2559+
command_vgpu_to_host_init2(&command->hdr,
2560+
DXGK_VMBCOMMAND_UPDATEGPUVIRTUALADDRESS,
2561+
process->host_handle);
2562+
command->fence_value = args->fence_value;
2563+
command->device = args->device;
2564+
command->context = args->context;
2565+
command->fence_object = args->fence_object;
2566+
command->num_operations = args->num_operations;
2567+
command->flags = args->flags.value;
2568+
ret = copy_from_user(command->operations, args->operations,
2569+
op_size);
2570+
if (ret) {
2571+
DXG_ERR("failed to copy operations");
2572+
ret = -EINVAL;
2573+
goto cleanup;
2574+
}
2575+
2576+
ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
2577+
2578+
cleanup:
2579+
free_message(&msg, process);
2580+
if (ret)
2581+
DXG_TRACE("err: %d", ret);
2582+
return ret;
2583+
}
2584+
24352585
static void set_result(struct d3dkmt_createsynchronizationobject2 *args,
24362586
u64 fence_gpu_va, u8 *va)
24372587
{

drivers/hv/dxgkrnl/dxgvmbus.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,44 @@ struct dxgkvmb_command_flushheaptransitions {
418418
struct dxgkvmb_command_vgpu_to_host hdr;
419419
};
420420

421+
struct dxgkvmb_command_freegpuvirtualaddress {
422+
struct dxgkvmb_command_vgpu_to_host hdr;
423+
struct d3dkmt_freegpuvirtualaddress args;
424+
};
425+
426+
struct dxgkvmb_command_mapgpuvirtualaddress {
427+
struct dxgkvmb_command_vgpu_to_host hdr;
428+
struct d3dddi_mapgpuvirtualaddress args;
429+
struct d3dkmthandle device;
430+
};
431+
432+
struct dxgkvmb_command_mapgpuvirtualaddress_return {
433+
u64 virtual_address;
434+
u64 paging_fence_value;
435+
struct ntstatus status;
436+
};
437+
438+
struct dxgkvmb_command_reservegpuvirtualaddress {
439+
struct dxgkvmb_command_vgpu_to_host hdr;
440+
struct d3dddi_reservegpuvirtualaddress args;
441+
};
442+
443+
struct dxgkvmb_command_reservegpuvirtualaddress_return {
444+
u64 virtual_address;
445+
u64 paging_fence_value;
446+
};
447+
448+
struct dxgkvmb_command_updategpuvirtualaddress {
449+
struct dxgkvmb_command_vgpu_to_host hdr;
450+
u64 fence_value;
451+
struct d3dkmthandle device;
452+
struct d3dkmthandle context;
453+
struct d3dkmthandle fence_object;
454+
u32 num_operations;
455+
u32 flags;
456+
struct d3dddi_updategpuvirtualaddress_operation operations[1];
457+
};
458+
421459
struct dxgkvmb_command_queryclockcalibration {
422460
struct dxgkvmb_command_vgpu_to_host hdr;
423461
struct d3dkmt_queryclockcalibration args;

0 commit comments

Comments
 (0)