mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 01:11:51 -04:00
drm/amd/display: Add KUnit tests for enable_assr
Expose enable_assr() for KUnit and cover the "DTM TA not initialized" path and the full command-build path, using the SR-IOV VF early-return to bypass psp_dtm_invoke()'s firmware submit. Reviewed-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
9b03693912
commit
354bfcbd05
@@ -570,7 +570,8 @@ void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
|
||||
}
|
||||
EXPORT_IF_KUNIT(hdcp_destroy);
|
||||
|
||||
static bool enable_assr(void *handle, struct dc_link *link)
|
||||
STATIC_IFN_KUNIT
|
||||
bool enable_assr(void *handle, struct dc_link *link)
|
||||
{
|
||||
struct hdcp_workqueue *hdcp_work = handle;
|
||||
struct mod_hdcp hdcp = hdcp_work->hdcp;
|
||||
@@ -603,6 +604,7 @@ static bool enable_assr(void *handle, struct dc_link *link)
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_IF_KUNIT(enable_assr);
|
||||
|
||||
static void update_config(void *handle, struct cp_psp_stream_config *config)
|
||||
{
|
||||
|
||||
@@ -123,6 +123,7 @@ void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, unsigned int link_ind
|
||||
struct amdgpu_dm_connector *aconnector);
|
||||
uint8_t *psp_get_srm(struct psp_context *psp, uint32_t *srm_version, uint32_t *srm_size);
|
||||
int psp_set_srm(struct psp_context *psp, u8 *srm, uint32_t srm_size, uint32_t *srm_version);
|
||||
bool enable_assr(void *handle, struct dc_link *link);
|
||||
#endif
|
||||
|
||||
#endif /* AMDGPU_DM_AMDGPU_DM_HDCP_H_ */
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_hdcp.h"
|
||||
#include "amdgpu_dm_kunit_test_helpers.h"
|
||||
#include "hdcp_psp.h"
|
||||
|
||||
static void dummy_work_fn(struct work_struct *work) {}
|
||||
|
||||
@@ -1446,6 +1448,138 @@ static void dm_test_hdcp_reset_display_clears_all_state(struct kunit *test)
|
||||
* hdcp_reset_display().
|
||||
*/
|
||||
|
||||
/* Tests for enable_assr() */
|
||||
|
||||
/**
|
||||
* alloc_test_workqueue_for_assr - workqueue wired to a psp for enable_assr()
|
||||
* @test: KUnit test context for managed allocation
|
||||
* @adev: amdgpu device whose drm_device backs psp->adev (for drm_info())
|
||||
*
|
||||
* Allocates a minimal hdcp_workqueue and a psp_context connected through
|
||||
* hdcp.config.psp.handle, matching the dereference chain enable_assr()
|
||||
* performs. The psp is left with dtm_context.context.initialized == false
|
||||
* (from kzalloc) so enable_assr() takes the "DTM TA not initialized" path.
|
||||
*/
|
||||
static struct hdcp_workqueue *alloc_test_workqueue_for_assr(struct kunit *test,
|
||||
struct amdgpu_device *adev)
|
||||
{
|
||||
struct hdcp_workqueue *work;
|
||||
struct psp_context *psp;
|
||||
|
||||
work = kunit_kzalloc(test, sizeof(*work), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, work);
|
||||
|
||||
psp = kunit_kzalloc(test, sizeof(*psp), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, psp);
|
||||
|
||||
psp->adev = adev;
|
||||
work->hdcp.config.psp.handle = psp;
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_enable_assr_uninitialized_dtm_returns_false - DTM TA not initialized
|
||||
* @test: KUnit test context
|
||||
*
|
||||
* When the DTM TA context is not initialized, enable_assr() must take the
|
||||
* early-return path, emit the informational message and return false
|
||||
* without invoking the (real) firmware path.
|
||||
*/
|
||||
static void dm_test_enable_assr_uninitialized_dtm_returns_false(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
struct hdcp_workqueue *work = alloc_test_workqueue_for_assr(test, adev);
|
||||
struct dc_link *link;
|
||||
bool ret;
|
||||
|
||||
link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, link);
|
||||
|
||||
/* kzalloc leaves dtm_context.context.initialized == false */
|
||||
ret = enable_assr(work, link);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_enable_assr_uninitialized_dtm_ignores_link - link untouched on failure
|
||||
* @test: KUnit test context
|
||||
*
|
||||
* On the "DTM TA not initialized" path enable_assr() returns before reading
|
||||
* any field of @link, so a NULL link must be tolerated and the call must
|
||||
* still return false.
|
||||
*/
|
||||
static void dm_test_enable_assr_uninitialized_dtm_ignores_link(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
struct hdcp_workqueue *work = alloc_test_workqueue_for_assr(test, adev);
|
||||
bool ret;
|
||||
|
||||
/* link is not dereferenced before the initialized check. */
|
||||
ret = enable_assr(work, NULL);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_enable_assr_initialized_builds_command_and_fails - full body, invoke bypassed
|
||||
* @test: KUnit test context
|
||||
*
|
||||
* With the DTM TA marked initialized and a valid shared buffer, enable_assr()
|
||||
* runs its full body: it acquires the DTM mutex, clears the shared command,
|
||||
* fills in the ASSR-enable command from @link and pre-sets the status to
|
||||
* GENERIC_FAILURE before invoking the TA.
|
||||
*
|
||||
* psp_dtm_invoke() is prevented from touching real firmware by marking the
|
||||
* device as an SR-IOV virtual function, which makes it return early without
|
||||
* modifying the shared status. The status therefore stays GENERIC_FAILURE, so
|
||||
* enable_assr() must return false. Inspecting the shared command afterwards
|
||||
* proves the body executed and consumed @link.
|
||||
*/
|
||||
static void dm_test_enable_assr_initialized_builds_command_and_fails(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
|
||||
struct hdcp_workqueue *work = alloc_test_workqueue_for_assr(test, adev);
|
||||
struct psp_context *psp = work->hdcp.config.psp.handle;
|
||||
struct ta_dtm_shared_memory *dtm_cmd;
|
||||
struct dc_link *link;
|
||||
bool ret;
|
||||
|
||||
dtm_cmd = kunit_kzalloc(test, sizeof(*dtm_cmd), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, dtm_cmd);
|
||||
|
||||
link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, link);
|
||||
link->link_enc_hw_inst = 3;
|
||||
|
||||
/* Wire up an "initialized" DTM TA with a real shared buffer. */
|
||||
psp->dtm_context.context.initialized = true;
|
||||
psp->dtm_context.context.mem_context.shared_buf = (uint8_t *)dtm_cmd;
|
||||
mutex_init(&psp->dtm_context.mutex);
|
||||
|
||||
/*
|
||||
* Force the SR-IOV VF early-return in psp_dtm_invoke() so no GPU
|
||||
* command is submitted; the shared status is left untouched.
|
||||
*/
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
|
||||
|
||||
ret = enable_assr(work, link);
|
||||
|
||||
/* Status was never advanced to SUCCESS, so the call must fail. */
|
||||
KUNIT_EXPECT_FALSE(test, ret);
|
||||
/* The command body must have populated the shared buffer. */
|
||||
KUNIT_EXPECT_EQ(test, dtm_cmd->cmd_id, TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE);
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
dtm_cmd->dtm_in_message.topology_assr_enable.display_topology_dig_be_index,
|
||||
link->link_enc_hw_inst);
|
||||
KUNIT_EXPECT_EQ(test, dtm_cmd->dtm_status, TA_DTM_STATUS__GENERIC_FAILURE);
|
||||
/* The DTM mutex must be released after the guard scope exits. */
|
||||
KUNIT_EXPECT_FALSE(test, mutex_is_locked(&psp->dtm_context.mutex));
|
||||
}
|
||||
|
||||
/* End of tests for enable_assr() */
|
||||
|
||||
static struct kunit_case dm_hdcp_test_cases[] = {
|
||||
/* hdcp_get_content_protection_from_status() */
|
||||
KUNIT_CASE(dm_test_hdcp_get_cp_disabled_returns_desired),
|
||||
@@ -1507,6 +1641,10 @@ static struct kunit_case dm_hdcp_test_cases[] = {
|
||||
KUNIT_CASE(dm_test_hdcp_remove_display_enabled_resets_cp),
|
||||
KUNIT_CASE(dm_test_hdcp_remove_display_null_state_clears_connector),
|
||||
KUNIT_CASE(dm_test_hdcp_reset_display_clears_all_state),
|
||||
/* enable_assr() */
|
||||
KUNIT_CASE(dm_test_enable_assr_uninitialized_dtm_returns_false),
|
||||
KUNIT_CASE(dm_test_enable_assr_uninitialized_dtm_ignores_link),
|
||||
KUNIT_CASE(dm_test_enable_assr_initialized_builds_command_and_fails),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user