diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 14:40:01 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 14:40:01 -0400 |
| commit | 8353a1344c78a3f29274f3c7b6e0984b81464346 (patch) | |
| tree | fe2baceb7e746e8a783afa41b31f348b721ed706 /kernel/gsp_rm_emulation.c | |
| parent | d52a6425ba2e0a46f2cf5c66219d34fcdc49c2d7 (diff) | |
| download | open-iov-8353a1344c78a3f29274f3c7b6e0984b81464346.tar.gz open-iov-8353a1344c78a3f29274f3c7b6e0984b81464346.zip | |
GSPRM CLK legacy controls: populate the domain queries the runtime clock helper gates on
The static CUDA runtime's device init failed with cudaErrorInitializationError
even though every kernel ioctl returned 0: cuInit succeeded and then
cuDeviceGetAttribute(ECC_ENABLED=36) returned CUDA_ERROR_NOT_FOUND (500).
Tracing libcuda's clock-domain helper (libcuda+0xe8c410) shows it issues the
CLK legacy controls 0x20809009/0x20809064/0x20809001 and bails with 500 when
the replies do not carry the expected domain bits/entries; the dependent
attribute getters (ECC_ENABLED, TOTAL_CONSTANT_MEMORY) then abort init.
Reply to the three queries with the minimal fields the helper checks: bits
32|34 present in 0x20809009, non-zero domain entries at offsets 12/20/28/36
of 0x20809064, and a matching selector in 0x20809001. No frequencies are
fabricated (all other fields stay zero).
Verified in the guest with the stock 570.144 static-cudart vectorAdd client:
cudaGetDeviceCount -> rc=0 (ndev=1), cudaSetDevice, cudaFree, three
cudaMallocs and both HtoD copies all return rc=0; the client then parks in
cudaDeviceSynchronize waiting for the (not yet forwarded) kernel launch.
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index ff65275..d6aef9e 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -2031,6 +2031,60 @@ static void gsp_rm_handle_fb_get_info_v2(struct gsp_emu_context *ctx, } /* + * CLK legacy domain queries (0x20809001 / 0x20809009 / 0x20809064) + * + * libcuda's clock-domain helper (libcuda+0xe8c410) walks these three queries + * before it will report clock/ECC/perf data. It requires: + * - 0x20809009: bits 32 and 34 set in the 8-byte reply (domain presence); + * - 0x20809064: non-zero domain entries at reply offsets 12, 20, 28, 36; + * - 0x20809001: a selector mask overlapping those entries. + * With the generic zero reply the helper returns CUDA_ERROR_NOT_FOUND, which + * makes the dependent device-attribute queries (ECC_ENABLED = attr 36, + * TOTAL_CONSTANT_MEMORY = attr 13) abort device initialization with + * cudaErrorInitializationError. Populate only the fields the checks read; + * clock rates stay zero (no fabricated frequencies). + */ +static void gsp_rm_handle_clk_domain_info(struct gsp_emu_context *ctx, u32 cmd, + u32 req_size, + u32 *out_status, + u8 *out_params, + u32 *out_params_size) +{ + u32 n = req_size ? req_size : 8; + u32 one = 1; + + if (n > 4096) + n = 4096; + memset(out_params, 0, n); + + if (cmd == TU104_CTRL_CLK_DOMAIN_MASK) { + u64 mask = (1ULL << 32) | (1ULL << 34); + + if (n >= sizeof(mask)) + memcpy(out_params, &mask, sizeof(mask)); + } else if (cmd == TU104_CTRL_CLK_DOMAIN_DATA) { + if (n >= 16) + memcpy(out_params + 12, &one, sizeof(one)); + if (n >= 24) + memcpy(out_params + 20, &one, sizeof(one)); + if (n >= 32) + memcpy(out_params + 28, &one, sizeof(one)); + if (n >= 40) + memcpy(out_params + 36, &one, sizeof(one)); + } else { /* TU104_CTRL_CLK_DOMAIN_SEL */ + if (n >= sizeof(one)) + memcpy(out_params, &one, sizeof(one)); + } + + *out_params_size = n; + *out_status = 0; + + if (gsp_sema_dbg) + nv_vgpu_info(ctx->vgpu, "GSPRM: CLK domain info cmd=0x%x size=%u", + cmd, n); +} + +/* * BUS_GET_INFO_V2 (0x20801823) * * Same flat index/data list pattern as FB_GET_INFO_V2. UVM's @@ -2641,6 +2695,14 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size); break; + case TU104_CTRL_CLK_DOMAIN_MASK: + case TU104_CTRL_CLK_DOMAIN_DATA: + case TU104_CTRL_CLK_DOMAIN_SEL: + gsp_rm_handle_clk_domain_info(ctx, req.cmd, req.paramsSize, + &out_status, + reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size); + break; + case TU104_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO: gsp_rm_handle_display_get_static_info(ctx, sequence, &out_status, |
