diff options
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index bb74767..3157a24 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -4401,11 +4401,28 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, const u8 *pp = req_data + GSP_RM_CTRL_HDR_SIZE; u8 *rp = reply + GSP_RM_CTRL_HDR_SIZE; - if (req.paramsSize >= 52 && + /* + * The real struct (NV2080_CTRL_INTERNAL_DISPLAY_CHANNEL_ + * PUSHBUFFER_PARAMS) is 56 bytes: addressSpace@0, + * physicalAddr@8, limit@16, cacheSnoop@24, hclass@28, + * channelInstance@32, valid@36 (NvBool = 1 byte!), + * pbTargetAperture@40, channelPBSize@44, subDeviceId@48. + * Read valid as a byte: the 3 padding bytes after it are not + * guaranteed zero, so a u32 load can turn valid=0 (PIO + * cursor channel) into a false positive. + */ + pr_info("rm-ctl: display channel pushbuffer hObject=0x%x size=%u pa=0x%llx limit=0x%llx class=0x%x inst=%u valid=%u\n", + req.hObject, req.paramsSize, + req.paramsSize >= 24 ? *(const u64 *)(pp + 8) : 0, + req.paramsSize >= 24 ? *(const u64 *)(pp + 16) : 0, + req.paramsSize >= 32 ? *(const u32 *)(pp + 28) : 0, + req.paramsSize >= 36 ? *(const u32 *)(pp + 32) : 0, + req.paramsSize >= 37 ? pp[36] : 0); + if (req.paramsSize >= 40 && req.paramsSize + GSP_RM_CTRL_HDR_SIZE <= GSPRM_MAX_SINGLE_ELEM_DATA) { u32 address_space = 0, hclass = 0, instance = 0; - u32 valid = 0; + u8 valid = 0; u64 pa = 0, limit = 0; memcpy(&address_space, pp + 0, 4); @@ -4413,7 +4430,7 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, memcpy(&limit, pp + 16, 8); memcpy(&hclass, pp + 28, 4); memcpy(&instance, pp + 32, 4); - memcpy(&valid, pp + 36, 4); + valid = pp[36]; memcpy(rp, pp, req.paramsSize); gsp_disp_engine_channel_add(ctx->vgpu, hclass, instance, pa, limit, address_space, |
