Skip to content

Commit dc66c10

Browse files
Iouri Tarassovchessturo
authored andcommitted
drivers: hv: dxgkrnl: The escape ioctl
Implement the escape ioctl (LX_DXESCAPE). This ioctl is used to send/receive private data between user mode compute device driver (guest) and kernel mode compute device driver (host). It allows the user mode driver to extend the virtual compute device API. 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 2a7e8eb commit dc66c10

5 files changed

Lines changed: 167 additions & 6 deletions

File tree

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,9 @@ int dxgvmb_send_query_alloc_residency(struct dxgprocess *process,
894894
struct dxgadapter *adapter,
895895
struct d3dkmt_queryallocationresidency
896896
*args);
897+
int dxgvmb_send_escape(struct dxgprocess *process,
898+
struct dxgadapter *adapter,
899+
struct d3dkmt_escape *args);
897900
int dxgvmb_send_query_vidmem_info(struct dxgprocess *process,
898901
struct dxgadapter *adapter,
899902
struct d3dkmt_queryvideomemoryinfo *args,

drivers/hv/dxgkrnl/dxgvmbus.c

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,70 @@ int dxgvmb_send_query_alloc_residency(struct dxgprocess *process,
19251925
return ret;
19261926
}
19271927

1928+
int dxgvmb_send_escape(struct dxgprocess *process,
1929+
struct dxgadapter *adapter,
1930+
struct d3dkmt_escape *args)
1931+
{
1932+
int ret;
1933+
struct dxgkvmb_command_escape *command = NULL;
1934+
u32 cmd_size = sizeof(*command);
1935+
struct dxgvmbusmsg msg = {.hdr = NULL};
1936+
1937+
if (args->priv_drv_data_size > DXG_MAX_VM_BUS_PACKET_SIZE) {
1938+
ret = -EINVAL;
1939+
goto cleanup;
1940+
}
1941+
1942+
cmd_size = cmd_size - sizeof(args->priv_drv_data[0]) +
1943+
args->priv_drv_data_size;
1944+
1945+
ret = init_message(&msg, adapter, process, cmd_size);
1946+
if (ret)
1947+
goto cleanup;
1948+
command = (void *)msg.msg;
1949+
command_vgpu_to_host_init2(&command->hdr,
1950+
DXGK_VMBCOMMAND_ESCAPE,
1951+
process->host_handle);
1952+
command->adapter = args->adapter;
1953+
command->device = args->device;
1954+
command->type = args->type;
1955+
command->flags = args->flags;
1956+
command->priv_drv_data_size = args->priv_drv_data_size;
1957+
command->context = args->context;
1958+
if (args->priv_drv_data_size) {
1959+
ret = copy_from_user(command->priv_drv_data,
1960+
args->priv_drv_data,
1961+
args->priv_drv_data_size);
1962+
if (ret) {
1963+
DXG_ERR("failed to copy priv data");
1964+
ret = -EINVAL;
1965+
goto cleanup;
1966+
}
1967+
}
1968+
1969+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size,
1970+
command->priv_drv_data,
1971+
args->priv_drv_data_size);
1972+
if (ret < 0)
1973+
goto cleanup;
1974+
1975+
if (args->priv_drv_data_size) {
1976+
ret = copy_to_user(args->priv_drv_data,
1977+
command->priv_drv_data,
1978+
args->priv_drv_data_size);
1979+
if (ret) {
1980+
DXG_ERR("failed to copy priv data");
1981+
ret = -EINVAL;
1982+
}
1983+
}
1984+
1985+
cleanup:
1986+
free_message(&msg, process);
1987+
if (ret)
1988+
DXG_TRACE("err: %d", ret);
1989+
return ret;
1990+
}
1991+
19281992
int dxgvmb_send_query_vidmem_info(struct dxgprocess *process,
19291993
struct dxgadapter *adapter,
19301994
struct d3dkmt_queryvideomemoryinfo *args,
@@ -1955,37 +2019,37 @@ int dxgvmb_send_query_vidmem_info(struct dxgprocess *process,
19552019
ret = copy_to_user(&output->budget, &result.budget,
19562020
sizeof(output->budget));
19572021
if (ret) {
1958-
pr_err("%s failed to copy budget", __func__);
2022+
DXG_ERR("failed to copy budget");
19592023
ret = -EINVAL;
19602024
goto cleanup;
19612025
}
19622026
ret = copy_to_user(&output->current_usage, &result.current_usage,
19632027
sizeof(output->current_usage));
19642028
if (ret) {
1965-
pr_err("%s failed to copy current usage", __func__);
2029+
DXG_ERR("failed to copy current usage");
19662030
ret = -EINVAL;
19672031
goto cleanup;
19682032
}
19692033
ret = copy_to_user(&output->current_reservation,
19702034
&result.current_reservation,
19712035
sizeof(output->current_reservation));
19722036
if (ret) {
1973-
pr_err("%s failed to copy reservation", __func__);
2037+
DXG_ERR("failed to copy reservation");
19742038
ret = -EINVAL;
19752039
goto cleanup;
19762040
}
19772041
ret = copy_to_user(&output->available_for_reservation,
19782042
&result.available_for_reservation,
19792043
sizeof(output->available_for_reservation));
19802044
if (ret) {
1981-
pr_err("%s failed to copy avail reservation", __func__);
2045+
DXG_ERR("failed to copy avail reservation");
19822046
ret = -EINVAL;
19832047
}
19842048

19852049
cleanup:
19862050
free_message(&msg, process);
19872051
if (ret)
1988-
dev_dbg(DXGDEV, "err: %d", ret);
2052+
DXG_TRACE("err: %d", ret);
19892053
return ret;
19902054
}
19912055

@@ -3152,3 +3216,4 @@ int dxgvmb_send_submit_command_hwqueue(struct dxgprocess *process,
31523216
DXG_TRACE("err: %d", ret);
31533217
return ret;
31543218
}
3219+

drivers/hv/dxgkrnl/dxgvmbus.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,18 @@ struct dxgkvmb_command_queryallocationresidency_return {
664664
/* d3dkmt_allocationresidencystatus[NumAllocations] */
665665
};
666666

667+
/* Returns only private data */
668+
struct dxgkvmb_command_escape {
669+
struct dxgkvmb_command_vgpu_to_host hdr;
670+
struct d3dkmthandle adapter;
671+
struct d3dkmthandle device;
672+
enum d3dkmt_escapetype type;
673+
struct d3dddi_escapeflags flags;
674+
u32 priv_drv_data_size;
675+
struct d3dkmthandle context;
676+
u8 priv_drv_data[1];
677+
};
678+
667679
struct dxgkvmb_command_queryvideomemoryinfo {
668680
struct dxgkvmb_command_vgpu_to_host hdr;
669681
struct d3dkmthandle adapter;

drivers/hv/dxgkrnl/ioctl.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3547,6 +3547,46 @@ dxgkio_flush_heap_transitions(struct dxgprocess *process, void *__user inargs)
35473547
return ret;
35483548
}
35493549

3550+
static int
3551+
dxgkio_escape(struct dxgprocess *process, void *__user inargs)
3552+
{
3553+
struct d3dkmt_escape args;
3554+
int ret;
3555+
struct dxgadapter *adapter = NULL;
3556+
bool adapter_locked = false;
3557+
3558+
ret = copy_from_user(&args, inargs, sizeof(args));
3559+
if (ret) {
3560+
ret = -EINVAL;
3561+
goto cleanup;
3562+
}
3563+
3564+
adapter = dxgprocess_adapter_by_handle(process, args.adapter);
3565+
if (adapter == NULL) {
3566+
ret = -EINVAL;
3567+
goto cleanup;
3568+
}
3569+
3570+
ret = dxgadapter_acquire_lock_shared(adapter);
3571+
if (ret < 0) {
3572+
adapter = NULL;
3573+
goto cleanup;
3574+
}
3575+
adapter_locked = true;
3576+
3577+
args.adapter = adapter->host_handle;
3578+
ret = dxgvmb_send_escape(process, adapter, &args);
3579+
3580+
cleanup:
3581+
3582+
if (adapter_locked)
3583+
dxgadapter_release_lock_shared(adapter);
3584+
if (adapter)
3585+
kref_put(&adapter->adapter_kref, dxgadapter_release);
3586+
DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
3587+
return ret;
3588+
}
3589+
35503590
static int
35513591
dxgkio_query_vidmem_info(struct dxgprocess *process, void *__user inargs)
35523592
{
@@ -4338,7 +4378,7 @@ static struct ioctl_desc ioctls[] = {
43384378
/* 0x0a */ {dxgkio_query_vidmem_info, LX_DXQUERYVIDEOMEMORYINFO},
43394379
/* 0x0b */ {},
43404380
/* 0x0c */ {},
4341-
/* 0x0d */ {},
4381+
/* 0x0d */ {dxgkio_escape, LX_DXESCAPE},
43424382
/* 0x0e */ {dxgkio_get_device_state, LX_DXGETDEVICESTATE},
43434383
/* 0x0f */ {dxgkio_submit_command, LX_DXSUBMITCOMMAND},
43444384
/* 0x10 */ {dxgkio_create_sync_object, LX_DXCREATESYNCHRONIZATIONOBJECT},

include/uapi/misc/d3dkmthk.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,45 @@ struct d3dddi_destroypagingqueue {
236236
struct d3dkmthandle paging_queue;
237237
};
238238

239+
enum d3dkmt_escapetype {
240+
_D3DKMT_ESCAPE_DRIVERPRIVATE = 0,
241+
_D3DKMT_ESCAPE_VIDMM = 1,
242+
_D3DKMT_ESCAPE_VIDSCH = 3,
243+
_D3DKMT_ESCAPE_DEVICE = 4,
244+
_D3DKMT_ESCAPE_DRT_TEST = 8,
245+
};
246+
247+
struct d3dddi_escapeflags {
248+
union {
249+
struct {
250+
__u32 hardware_access:1;
251+
__u32 device_status_query:1;
252+
__u32 change_frame_latency:1;
253+
__u32 no_adapter_synchronization:1;
254+
__u32 reserved:1;
255+
__u32 virtual_machine_data:1;
256+
__u32 driver_known_escape:1;
257+
__u32 driver_common_escape:1;
258+
__u32 reserved2:24;
259+
};
260+
__u32 value;
261+
};
262+
};
263+
264+
struct d3dkmt_escape {
265+
struct d3dkmthandle adapter;
266+
struct d3dkmthandle device;
267+
enum d3dkmt_escapetype type;
268+
struct d3dddi_escapeflags flags;
269+
#ifdef __KERNEL__
270+
void *priv_drv_data;
271+
#else
272+
__u64 priv_drv_data;
273+
#endif
274+
__u32 priv_drv_data_size;
275+
struct d3dkmthandle context;
276+
};
277+
239278
enum dxgk_render_pipeline_stage {
240279
_DXGK_RENDER_PIPELINE_STAGE_UNKNOWN = 0,
241280
_DXGK_RENDER_PIPELINE_STAGE_INPUT_ASSEMBLER = 1,
@@ -1217,6 +1256,8 @@ struct d3dkmt_shareobjectwithhost {
12171256
_IOWR(0x47, 0x09, struct d3dkmt_queryadapterinfo)
12181257
#define LX_DXQUERYVIDEOMEMORYINFO \
12191258
_IOWR(0x47, 0x0a, struct d3dkmt_queryvideomemoryinfo)
1259+
#define LX_DXESCAPE \
1260+
_IOWR(0x47, 0x0d, struct d3dkmt_escape)
12201261
#define LX_DXGETDEVICESTATE \
12211262
_IOWR(0x47, 0x0e, struct d3dkmt_getdevicestate)
12221263
#define LX_DXSUBMITCOMMAND \

0 commit comments

Comments
 (0)