On Thu, Jan 22, 2026 at 5:52 AM Lijo Lazar <[email protected]> wrote: > > Add user save area parameters to mqd properties for queue creation. > Validate the parameters before using for mqd initialization. > > Signed-off-by: Lijo Lazar <[email protected]>
Reviewed-by: Alex Deucher <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 ++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 24 ++++++++++++++++++++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 5 +++++ > drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 14 +++++++++++++ > drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 16 +++++++++++++++ > 5 files changed, 63 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 218d8030a07c..26b757c95579 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -814,6 +814,10 @@ struct amdgpu_mqd_prop { > uint64_t fence_address; > bool tmz_queue; > bool kernel_queue; > + /* cwsr params*/ > + uint64_t ctx_save_area_addr; > + uint32_t ctx_save_area_size; > + uint32_t ctl_stack_size; > }; > > struct amdgpu_mqd { > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > index 37a526a1085f..119b84a0703e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > @@ -33,6 +33,7 @@ > #include "amdgpu_userq.h" > #include "amdgpu_hmm.h" > #include "amdgpu_userq_fence.h" > +#include "amdgpu_cwsr.h" > > u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev) > { > @@ -265,6 +266,29 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device > *adev, > return r; > } > > +int amdgpu_userq_input_cwsr_params_validate( > + struct amdgpu_usermode_queue *queue, > + struct amdgpu_cwsr_params *cwsr_params) > +{ > + struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(queue->userq_mgr); > + struct amdgpu_device *adev = queue->userq_mgr->adev; > + uint32_t cwsr_size; > + int num_xcc; > + int r; > + > + num_xcc = amdgpu_xcp_get_num_xcc(adev->xcp_mgr, fpriv->xcp_id); > + r = amdgpu_cwsr_validate_params(queue->userq_mgr->adev, cwsr_params, > + num_xcc); > + if (r) > + return r; > + cwsr_size = amdgpu_cwsr_size_needed(queue->userq_mgr->adev, num_xcc); > + if (!cwsr_size) > + return -EOPNOTSUPP; > + > + return amdgpu_userq_input_va_validate( > + adev, queue, cwsr_params->ctx_save_area_address, cwsr_size); > +} > + > static bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr) > { > struct amdgpu_bo_va_mapping *mapping; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > index 5845d8959034..a64292bc24dd 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > @@ -41,6 +41,7 @@ enum amdgpu_userq_state { > }; > > struct amdgpu_mqd_prop; > +struct amdgpu_cwsr_params; > > struct amdgpu_userq_obj { > void *cpu_ptr; > @@ -157,4 +158,8 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device > *adev, > int amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev, > struct amdgpu_bo_va_mapping *mapping, > uint64_t saddr); > +int amdgpu_userq_input_cwsr_params_validate( > + struct amdgpu_usermode_queue *queue, > + struct amdgpu_cwsr_params *cwsr_params); > + > #endif > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c > index 40660b05f979..5f6a6f630495 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c > @@ -3243,6 +3243,20 @@ static int gfx_v12_0_compute_mqd_init(struct > amdgpu_device *adev, void *m, > mqd->fence_address_lo = lower_32_bits(prop->fence_address); > mqd->fence_address_hi = upper_32_bits(prop->fence_address); > > + /* If non-zero, assume cwsr is enabled */ > + if (prop->ctx_save_area_addr) { > + mqd->cp_hqd_persistent_state |= > + (1 << CP_HQD_PERSISTENT_STATE__QSWITCH_MODE__SHIFT); > + mqd->cp_hqd_ctx_save_base_addr_lo = > + lower_32_bits(prop->ctx_save_area_addr); > + mqd->cp_hqd_ctx_save_base_addr_hi = > + upper_32_bits(prop->ctx_save_area_addr); > + mqd->cp_hqd_ctx_save_size = prop->ctx_save_area_size; > + mqd->cp_hqd_cntl_stack_size = prop->ctl_stack_size; > + mqd->cp_hqd_cntl_stack_offset = prop->ctl_stack_size; > + mqd->cp_hqd_wg_state_offset = prop->ctl_stack_size; > + } > + > return 0; > } > > diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > index 27917614b1a8..7ad8297eb0d8 100644 > --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > @@ -314,6 +314,7 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > > if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { > struct drm_amdgpu_userq_mqd_compute_gfx11 *compute_mqd; > + struct amdgpu_cwsr_params cwsr_params; > > if (mqd_user->mqd_size != sizeof(*compute_mqd)) { > DRM_ERROR("Invalid compute IP MQD size\n"); > @@ -339,6 +340,21 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > userq_props->hqd_active = false; > userq_props->tmz_queue = > mqd_user->flags & > AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; > + > + if (amdgpu_cwsr_is_enabled(adev)) { > + cwsr_params.ctx_save_area_address = > + userq_props->ctx_save_area_addr; > + cwsr_params.cwsr_sz = userq_props->ctx_save_area_size; > + cwsr_params.ctl_stack_sz = > userq_props->ctl_stack_size; > + > + r = amdgpu_userq_input_cwsr_params_validate( > + queue, &cwsr_params); > + if (r) { > + kfree(compute_mqd); > + goto free_mqd; > + } > + } > + > kfree(compute_mqd); > } else if (queue->queue_type == AMDGPU_HW_IP_GFX) { > struct drm_amdgpu_userq_mqd_gfx11 *mqd_gfx_v11; > -- > 2.49.0 >
