cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amdgpu_dm_hdcp.c (22539B)


      1/*
      2 * Copyright 2019 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include "amdgpu_dm_hdcp.h"
     27#include "amdgpu.h"
     28#include "amdgpu_dm.h"
     29#include "dm_helpers.h"
     30#include <drm/display/drm_hdcp_helper.h>
     31#include "hdcp_psp.h"
     32
     33/*
     34 * If the SRM version being loaded is less than or equal to the
     35 * currently loaded SRM, psp will return 0xFFFF as the version
     36 */
     37#define PSP_SRM_VERSION_MAX 0xFFFF
     38
     39static bool
     40lp_write_i2c(void *handle, uint32_t address, const uint8_t *data, uint32_t size)
     41{
     42
     43	struct dc_link *link = handle;
     44	struct i2c_payload i2c_payloads[] = {{true, address, size, (void *)data} };
     45	struct i2c_command cmd = {i2c_payloads, 1, I2C_COMMAND_ENGINE_HW, link->dc->caps.i2c_speed_in_khz};
     46
     47	return dm_helpers_submit_i2c(link->ctx, link, &cmd);
     48}
     49
     50static bool
     51lp_read_i2c(void *handle, uint32_t address, uint8_t offset, uint8_t *data, uint32_t size)
     52{
     53	struct dc_link *link = handle;
     54
     55	struct i2c_payload i2c_payloads[] = {{true, address, 1, &offset}, {false, address, size, data} };
     56	struct i2c_command cmd = {i2c_payloads, 2, I2C_COMMAND_ENGINE_HW, link->dc->caps.i2c_speed_in_khz};
     57
     58	return dm_helpers_submit_i2c(link->ctx, link, &cmd);
     59}
     60
     61static bool
     62lp_write_dpcd(void *handle, uint32_t address, const uint8_t *data, uint32_t size)
     63{
     64	struct dc_link *link = handle;
     65
     66	return dm_helpers_dp_write_dpcd(link->ctx, link, address, data, size);
     67}
     68
     69static bool
     70lp_read_dpcd(void *handle, uint32_t address, uint8_t *data, uint32_t size)
     71{
     72	struct dc_link *link = handle;
     73
     74	return dm_helpers_dp_read_dpcd(link->ctx, link, address, data, size);
     75}
     76
     77static uint8_t *psp_get_srm(struct psp_context *psp, uint32_t *srm_version, uint32_t *srm_size)
     78{
     79
     80	struct ta_hdcp_shared_memory *hdcp_cmd;
     81
     82	if (!psp->hdcp_context.context.initialized) {
     83		DRM_WARN("Failed to get hdcp srm. HDCP TA is not initialized.");
     84		return NULL;
     85	}
     86
     87	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
     88	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
     89
     90	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP_GET_SRM;
     91	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
     92
     93	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
     94		return NULL;
     95
     96	*srm_version = hdcp_cmd->out_msg.hdcp_get_srm.srm_version;
     97	*srm_size = hdcp_cmd->out_msg.hdcp_get_srm.srm_buf_size;
     98
     99
    100	return hdcp_cmd->out_msg.hdcp_get_srm.srm_buf;
    101}
    102
    103static int psp_set_srm(struct psp_context *psp, uint8_t *srm, uint32_t srm_size, uint32_t *srm_version)
    104{
    105
    106	struct ta_hdcp_shared_memory *hdcp_cmd;
    107
    108	if (!psp->hdcp_context.context.initialized) {
    109		DRM_WARN("Failed to get hdcp srm. HDCP TA is not initialized.");
    110		return -EINVAL;
    111	}
    112
    113	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
    114	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
    115
    116	memcpy(hdcp_cmd->in_msg.hdcp_set_srm.srm_buf, srm, srm_size);
    117	hdcp_cmd->in_msg.hdcp_set_srm.srm_buf_size = srm_size;
    118	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP_SET_SRM;
    119
    120	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
    121
    122	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS || hdcp_cmd->out_msg.hdcp_set_srm.valid_signature != 1 ||
    123	    hdcp_cmd->out_msg.hdcp_set_srm.srm_version == PSP_SRM_VERSION_MAX)
    124		return -EINVAL;
    125
    126	*srm_version = hdcp_cmd->out_msg.hdcp_set_srm.srm_version;
    127	return 0;
    128}
    129
    130static void process_output(struct hdcp_workqueue *hdcp_work)
    131{
    132	struct mod_hdcp_output output = hdcp_work->output;
    133
    134	if (output.callback_stop)
    135		cancel_delayed_work(&hdcp_work->callback_dwork);
    136
    137	if (output.callback_needed)
    138		schedule_delayed_work(&hdcp_work->callback_dwork,
    139				      msecs_to_jiffies(output.callback_delay));
    140
    141	if (output.watchdog_timer_stop)
    142		cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
    143
    144	if (output.watchdog_timer_needed)
    145		schedule_delayed_work(&hdcp_work->watchdog_timer_dwork,
    146				      msecs_to_jiffies(output.watchdog_timer_delay));
    147
    148	schedule_delayed_work(&hdcp_work->property_validate_dwork, msecs_to_jiffies(0));
    149}
    150
    151static void link_lock(struct hdcp_workqueue *work, bool lock)
    152{
    153
    154	int i = 0;
    155
    156	for (i = 0; i < work->max_link; i++) {
    157		if (lock)
    158			mutex_lock(&work[i].mutex);
    159		else
    160			mutex_unlock(&work[i].mutex);
    161	}
    162}
    163void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
    164			 unsigned int link_index,
    165			 struct amdgpu_dm_connector *aconnector,
    166			 uint8_t content_type,
    167			 bool enable_encryption)
    168{
    169	struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
    170	struct mod_hdcp_display *display = &hdcp_work[link_index].display;
    171	struct mod_hdcp_link *link = &hdcp_work[link_index].link;
    172	struct mod_hdcp_display_query query;
    173
    174	mutex_lock(&hdcp_w->mutex);
    175	hdcp_w->aconnector = aconnector;
    176
    177	query.display = NULL;
    178	mod_hdcp_query_display(&hdcp_w->hdcp, aconnector->base.index, &query);
    179
    180	if (query.display != NULL) {
    181		memcpy(display, query.display, sizeof(struct mod_hdcp_display));
    182		mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
    183
    184		hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
    185
    186		if (enable_encryption) {
    187			/* Explicitly set the saved SRM as sysfs call will be after we already enabled hdcp
    188			 * (s3 resume case)
    189			 */
    190			if (hdcp_work->srm_size > 0)
    191				psp_set_srm(hdcp_work->hdcp.config.psp.handle, hdcp_work->srm, hdcp_work->srm_size,
    192					    &hdcp_work->srm_version);
    193
    194			display->adjust.disable = MOD_HDCP_DISPLAY_NOT_DISABLE;
    195			if (content_type == DRM_MODE_HDCP_CONTENT_TYPE0) {
    196				hdcp_w->link.adjust.hdcp1.disable = 0;
    197				hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
    198			} else if (content_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
    199				hdcp_w->link.adjust.hdcp1.disable = 1;
    200				hdcp_w->link.adjust.hdcp2.force_type = MOD_HDCP_FORCE_TYPE_1;
    201			}
    202
    203			schedule_delayed_work(&hdcp_w->property_validate_dwork,
    204					      msecs_to_jiffies(DRM_HDCP_CHECK_PERIOD_MS));
    205		} else {
    206			display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
    207			hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
    208			cancel_delayed_work(&hdcp_w->property_validate_dwork);
    209		}
    210
    211		display->state = MOD_HDCP_DISPLAY_ACTIVE;
    212	}
    213
    214	mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
    215
    216	process_output(hdcp_w);
    217	mutex_unlock(&hdcp_w->mutex);
    218}
    219
    220static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
    221			 unsigned int link_index,
    222			 struct amdgpu_dm_connector *aconnector)
    223{
    224	struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
    225	struct drm_connector_state *conn_state = aconnector->base.state;
    226
    227	mutex_lock(&hdcp_w->mutex);
    228	hdcp_w->aconnector = aconnector;
    229
    230	/* the removal of display will invoke auth reset -> hdcp destroy and
    231	 * we'd expect the Content Protection (CP) property changed back to
    232	 * DESIRED if at the time ENABLED. CP property change should occur
    233	 * before the element removed from linked list.
    234	 */
    235	if (conn_state && conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
    236		conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
    237
    238		DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP 2 -> 1, type %u, DPMS %u\n",
    239			 aconnector->base.index, conn_state->hdcp_content_type, aconnector->base.dpms);
    240	}
    241
    242	mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
    243
    244	process_output(hdcp_w);
    245	mutex_unlock(&hdcp_w->mutex);
    246}
    247void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
    248{
    249	struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
    250
    251	mutex_lock(&hdcp_w->mutex);
    252
    253	mod_hdcp_reset_connection(&hdcp_w->hdcp,  &hdcp_w->output);
    254
    255	cancel_delayed_work(&hdcp_w->property_validate_dwork);
    256	hdcp_w->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
    257
    258	process_output(hdcp_w);
    259
    260	mutex_unlock(&hdcp_w->mutex);
    261}
    262
    263void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
    264{
    265	struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
    266
    267	schedule_work(&hdcp_w->cpirq_work);
    268}
    269
    270
    271
    272
    273static void event_callback(struct work_struct *work)
    274{
    275	struct hdcp_workqueue *hdcp_work;
    276
    277	hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue,
    278				      callback_dwork);
    279
    280	mutex_lock(&hdcp_work->mutex);
    281
    282	cancel_delayed_work(&hdcp_work->callback_dwork);
    283
    284	mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CALLBACK,
    285			       &hdcp_work->output);
    286
    287	process_output(hdcp_work);
    288
    289	mutex_unlock(&hdcp_work->mutex);
    290
    291
    292}
    293static void event_property_update(struct work_struct *work)
    294{
    295
    296	struct hdcp_workqueue *hdcp_work = container_of(work, struct hdcp_workqueue, property_update_work);
    297	struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector;
    298	struct drm_device *dev = hdcp_work->aconnector->base.dev;
    299	long ret;
    300
    301	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
    302	mutex_lock(&hdcp_work->mutex);
    303
    304
    305	if (aconnector->base.state->commit) {
    306		ret = wait_for_completion_interruptible_timeout(&aconnector->base.state->commit->hw_done, 10 * HZ);
    307
    308		if (ret == 0) {
    309			DRM_ERROR("HDCP state unknown! Setting it to DESIRED");
    310			hdcp_work->encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
    311		}
    312	}
    313
    314	if (hdcp_work->encryption_status != MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF) {
    315		if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE0 &&
    316		    hdcp_work->encryption_status <= MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE0_ON)
    317			drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
    318		else if (aconnector->base.state->hdcp_content_type == DRM_MODE_HDCP_CONTENT_TYPE1 &&
    319			 hdcp_work->encryption_status == MOD_HDCP_ENCRYPTION_STATUS_HDCP2_TYPE1_ON)
    320			drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_ENABLED);
    321	} else {
    322		drm_hdcp_update_content_protection(&aconnector->base, DRM_MODE_CONTENT_PROTECTION_DESIRED);
    323	}
    324
    325
    326	mutex_unlock(&hdcp_work->mutex);
    327	drm_modeset_unlock(&dev->mode_config.connection_mutex);
    328}
    329
    330static void event_property_validate(struct work_struct *work)
    331{
    332	struct hdcp_workqueue *hdcp_work =
    333		container_of(to_delayed_work(work), struct hdcp_workqueue, property_validate_dwork);
    334	struct mod_hdcp_display_query query;
    335	struct amdgpu_dm_connector *aconnector = hdcp_work->aconnector;
    336
    337	if (!aconnector)
    338		return;
    339
    340	mutex_lock(&hdcp_work->mutex);
    341
    342	query.encryption_status = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
    343	mod_hdcp_query_display(&hdcp_work->hdcp, aconnector->base.index, &query);
    344
    345	if (query.encryption_status != hdcp_work->encryption_status) {
    346		hdcp_work->encryption_status = query.encryption_status;
    347		schedule_work(&hdcp_work->property_update_work);
    348	}
    349
    350	mutex_unlock(&hdcp_work->mutex);
    351}
    352
    353static void event_watchdog_timer(struct work_struct *work)
    354{
    355	struct hdcp_workqueue *hdcp_work;
    356
    357	hdcp_work = container_of(to_delayed_work(work),
    358				      struct hdcp_workqueue,
    359				      watchdog_timer_dwork);
    360
    361	mutex_lock(&hdcp_work->mutex);
    362
    363	cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
    364
    365	mod_hdcp_process_event(&hdcp_work->hdcp,
    366			       MOD_HDCP_EVENT_WATCHDOG_TIMEOUT,
    367			       &hdcp_work->output);
    368
    369	process_output(hdcp_work);
    370
    371	mutex_unlock(&hdcp_work->mutex);
    372
    373}
    374
    375static void event_cpirq(struct work_struct *work)
    376{
    377	struct hdcp_workqueue *hdcp_work;
    378
    379	hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work);
    380
    381	mutex_lock(&hdcp_work->mutex);
    382
    383	mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output);
    384
    385	process_output(hdcp_work);
    386
    387	mutex_unlock(&hdcp_work->mutex);
    388
    389}
    390
    391
    392void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
    393{
    394	int i = 0;
    395
    396	for (i = 0; i < hdcp_work->max_link; i++) {
    397		cancel_delayed_work_sync(&hdcp_work[i].callback_dwork);
    398		cancel_delayed_work_sync(&hdcp_work[i].watchdog_timer_dwork);
    399	}
    400
    401	sysfs_remove_bin_file(kobj, &hdcp_work[0].attr);
    402	kfree(hdcp_work->srm);
    403	kfree(hdcp_work->srm_temp);
    404	kfree(hdcp_work);
    405}
    406
    407
    408static bool enable_assr(void *handle, struct dc_link *link)
    409{
    410
    411	struct hdcp_workqueue *hdcp_work = handle;
    412	struct mod_hdcp hdcp = hdcp_work->hdcp;
    413	struct psp_context *psp = hdcp.config.psp.handle;
    414	struct ta_dtm_shared_memory *dtm_cmd;
    415	bool res = true;
    416
    417	if (!psp->dtm_context.context.initialized) {
    418		DRM_INFO("Failed to enable ASSR, DTM TA is not initialized.");
    419		return false;
    420	}
    421
    422	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
    423
    424	mutex_lock(&psp->dtm_context.mutex);
    425	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
    426
    427	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE;
    428	dtm_cmd->dtm_in_message.topology_assr_enable.display_topology_dig_be_index = link->link_enc_hw_inst;
    429	dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
    430
    431	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
    432
    433	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
    434		DRM_INFO("Failed to enable ASSR");
    435		res = false;
    436	}
    437
    438	mutex_unlock(&psp->dtm_context.mutex);
    439
    440	return res;
    441}
    442
    443static void update_config(void *handle, struct cp_psp_stream_config *config)
    444{
    445	struct hdcp_workqueue *hdcp_work = handle;
    446	struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx;
    447	int link_index = aconnector->dc_link->link_index;
    448	struct mod_hdcp_display *display = &hdcp_work[link_index].display;
    449	struct mod_hdcp_link *link = &hdcp_work[link_index].link;
    450	struct drm_connector_state *conn_state;
    451	struct dc_sink *sink = NULL;
    452	bool link_is_hdcp14 = false;
    453
    454	if (config->dpms_off) {
    455		hdcp_remove_display(hdcp_work, link_index, aconnector);
    456		return;
    457	}
    458
    459	memset(display, 0, sizeof(*display));
    460	memset(link, 0, sizeof(*link));
    461
    462	display->index = aconnector->base.index;
    463	display->state = MOD_HDCP_DISPLAY_ACTIVE;
    464
    465	if (aconnector->dc_sink)
    466		sink = aconnector->dc_sink;
    467	else if (aconnector->dc_em_sink)
    468		sink = aconnector->dc_em_sink;
    469
    470	if (sink != NULL)
    471		link->mode = mod_hdcp_signal_type_to_operation_mode(sink->sink_signal);
    472
    473	display->controller = CONTROLLER_ID_D0 + config->otg_inst;
    474	display->dig_fe = config->dig_fe;
    475	link->dig_be = config->dig_be;
    476	link->ddc_line = aconnector->dc_link->ddc_hw_inst + 1;
    477	display->stream_enc_idx = config->stream_enc_idx;
    478	link->link_enc_idx = config->link_enc_idx;
    479	link->phy_idx = config->phy_idx;
    480	if (sink)
    481		link_is_hdcp14 = dc_link_is_hdcp14(aconnector->dc_link, sink->sink_signal);
    482	link->hdcp_supported_informational = link_is_hdcp14;
    483	link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw;
    484	link->dp.assr_enabled = config->assr_enabled;
    485	link->dp.mst_enabled = config->mst_enabled;
    486	display->adjust.disable = MOD_HDCP_DISPLAY_DISABLE_AUTHENTICATION;
    487	link->adjust.auth_delay = 3;
    488	link->adjust.hdcp1.disable = 0;
    489	conn_state = aconnector->base.state;
    490
    491	DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP %d, type %d\n", aconnector->base.index,
    492			(!!aconnector->base.state) ? aconnector->base.state->content_protection : -1,
    493			(!!aconnector->base.state) ? aconnector->base.state->hdcp_content_type : -1);
    494
    495	hdcp_update_display(hdcp_work, link_index, aconnector, conn_state->hdcp_content_type, false);
    496}
    497
    498
    499/* NOTE: From the usermodes prospective you only need to call write *ONCE*, the kernel
    500 *      will automatically call once or twice depending on the size
    501 *
    502 * call: "cat file > /sys/class/drm/card0/device/hdcp_srm" from usermode no matter what the size is
    503 *
    504 * The kernel can only send PAGE_SIZE at once and since MAX_SRM_FILE(5120) > PAGE_SIZE(4096),
    505 * srm_data_write can be called multiple times.
    506 *
    507 * sysfs interface doesn't tell us the size we will get so we are sending partial SRMs to psp and on
    508 * the last call we will send the full SRM. PSP will fail on every call before the last.
    509 *
    510 * This means we don't know if the SRM is good until the last call. And because of this limitation we
    511 * cannot throw errors early as it will stop the kernel from writing to sysfs
    512 *
    513 * Example 1:
    514 * 	Good SRM size = 5096
    515 * 	first call to write 4096 -> PSP fails
    516 * 	Second call to write 1000 -> PSP Pass -> SRM is set
    517 *
    518 * Example 2:
    519 * 	Bad SRM size = 4096
    520 * 	first call to write 4096 -> PSP fails (This is the same as above, but we don't know if this
    521 * 	is the last call)
    522 *
    523 * Solution?:
    524 * 	1: Parse the SRM? -> It is signed so we don't know the EOF
    525 * 	2: We can have another sysfs that passes the size before calling set. -> simpler solution
    526 * 	below
    527 *
    528 * Easy Solution:
    529 * Always call get after Set to verify if set was successful.
    530 * +----------------------+
    531 * |   Why it works:      |
    532 * +----------------------+
    533 * PSP will only update its srm if its older than the one we are trying to load.
    534 * Always do set first than get.
    535 * 	-if we try to "1. SET" a older version PSP will reject it and we can "2. GET" the newer
    536 * 	version and save it
    537 *
    538 * 	-if we try to "1. SET" a newer version PSP will accept it and we can "2. GET" the
    539 * 	same(newer) version back and save it
    540 *
    541 * 	-if we try to "1. SET" a newer version and PSP rejects it. That means the format is
    542 * 	incorrect/corrupted and we should correct our SRM by getting it from PSP
    543 */
    544static ssize_t srm_data_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer,
    545			      loff_t pos, size_t count)
    546{
    547	struct hdcp_workqueue *work;
    548	uint32_t srm_version = 0;
    549
    550	work = container_of(bin_attr, struct hdcp_workqueue, attr);
    551	link_lock(work, true);
    552
    553	memcpy(work->srm_temp + pos, buffer, count);
    554
    555	if (!psp_set_srm(work->hdcp.config.psp.handle, work->srm_temp, pos + count, &srm_version)) {
    556		DRM_DEBUG_DRIVER("HDCP SRM SET version 0x%X", srm_version);
    557		memcpy(work->srm, work->srm_temp, pos + count);
    558		work->srm_size = pos + count;
    559		work->srm_version = srm_version;
    560	}
    561
    562
    563	link_lock(work, false);
    564
    565	return count;
    566}
    567
    568static ssize_t srm_data_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buffer,
    569			     loff_t pos, size_t count)
    570{
    571	struct hdcp_workqueue *work;
    572	uint8_t *srm = NULL;
    573	uint32_t srm_version;
    574	uint32_t srm_size;
    575	size_t ret = count;
    576
    577	work = container_of(bin_attr, struct hdcp_workqueue, attr);
    578
    579	link_lock(work, true);
    580
    581	srm = psp_get_srm(work->hdcp.config.psp.handle, &srm_version, &srm_size);
    582
    583	if (!srm) {
    584		ret = -EINVAL;
    585		goto ret;
    586	}
    587
    588	if (pos >= srm_size)
    589		ret = 0;
    590
    591	if (srm_size - pos < count) {
    592		memcpy(buffer, srm + pos, srm_size - pos);
    593		ret = srm_size - pos;
    594		goto ret;
    595	}
    596
    597	memcpy(buffer, srm + pos, count);
    598
    599ret:
    600	link_lock(work, false);
    601	return ret;
    602}
    603
    604/* From the hdcp spec (5.Renewability) SRM needs to be stored in a non-volatile memory.
    605 *
    606 * For example,
    607 * 	if Application "A" sets the SRM (ver 2) and we reboot/suspend and later when Application "B"
    608 * 	needs to use HDCP, the version in PSP should be SRM(ver 2). So SRM should be persistent
    609 * 	across boot/reboots/suspend/resume/shutdown
    610 *
    611 * Currently when the system goes down (suspend/shutdown) the SRM is cleared from PSP. For HDCP we need
    612 * to make the SRM persistent.
    613 *
    614 * -PSP owns the checking of SRM but doesn't have the ability to store it in a non-volatile memory.
    615 * -The kernel cannot write to the file systems.
    616 * -So we need usermode to do this for us, which is why an interface for usermode is needed
    617 *
    618 *
    619 *
    620 * Usermode can read/write to/from PSP using the sysfs interface
    621 * For example:
    622 * 	to save SRM from PSP to storage : cat /sys/class/drm/card0/device/hdcp_srm > srmfile
    623 * 	to load from storage to PSP: cat srmfile > /sys/class/drm/card0/device/hdcp_srm
    624 */
    625static const struct bin_attribute data_attr = {
    626	.attr = {.name = "hdcp_srm", .mode = 0664},
    627	.size = PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, /* Limit SRM size */
    628	.write = srm_data_write,
    629	.read = srm_data_read,
    630};
    631
    632
    633struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, struct cp_psp *cp_psp, struct dc *dc)
    634{
    635
    636	int max_caps = dc->caps.max_links;
    637	struct hdcp_workqueue *hdcp_work;
    638	int i = 0;
    639
    640	hdcp_work = kcalloc(max_caps, sizeof(*hdcp_work), GFP_KERNEL);
    641	if (ZERO_OR_NULL_PTR(hdcp_work))
    642		return NULL;
    643
    644	hdcp_work->srm = kcalloc(PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, sizeof(*hdcp_work->srm), GFP_KERNEL);
    645
    646	if (hdcp_work->srm == NULL)
    647		goto fail_alloc_context;
    648
    649	hdcp_work->srm_temp = kcalloc(PSP_HDCP_SRM_FIRST_GEN_MAX_SIZE, sizeof(*hdcp_work->srm_temp), GFP_KERNEL);
    650
    651	if (hdcp_work->srm_temp == NULL)
    652		goto fail_alloc_context;
    653
    654	hdcp_work->max_link = max_caps;
    655
    656	for (i = 0; i < max_caps; i++) {
    657		mutex_init(&hdcp_work[i].mutex);
    658
    659		INIT_WORK(&hdcp_work[i].cpirq_work, event_cpirq);
    660		INIT_WORK(&hdcp_work[i].property_update_work, event_property_update);
    661		INIT_DELAYED_WORK(&hdcp_work[i].callback_dwork, event_callback);
    662		INIT_DELAYED_WORK(&hdcp_work[i].watchdog_timer_dwork, event_watchdog_timer);
    663		INIT_DELAYED_WORK(&hdcp_work[i].property_validate_dwork, event_property_validate);
    664
    665		hdcp_work[i].hdcp.config.psp.handle = &adev->psp;
    666		if (dc->ctx->dce_version == DCN_VERSION_3_1 ||
    667		    dc->ctx->dce_version == DCN_VERSION_3_15 ||
    668		    dc->ctx->dce_version == DCN_VERSION_3_16)
    669			hdcp_work[i].hdcp.config.psp.caps.dtm_v3_supported = 1;
    670		hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, i);
    671		hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c;
    672		hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c;
    673		hdcp_work[i].hdcp.config.ddc.funcs.write_dpcd = lp_write_dpcd;
    674		hdcp_work[i].hdcp.config.ddc.funcs.read_dpcd = lp_read_dpcd;
    675	}
    676
    677	cp_psp->funcs.update_stream_config = update_config;
    678	cp_psp->funcs.enable_assr = enable_assr;
    679	cp_psp->handle = hdcp_work;
    680
    681	/* File created at /sys/class/drm/card0/device/hdcp_srm*/
    682	hdcp_work[0].attr = data_attr;
    683	sysfs_bin_attr_init(&hdcp_work[0].attr);
    684
    685	if (sysfs_create_bin_file(&adev->dev->kobj, &hdcp_work[0].attr))
    686		DRM_WARN("Failed to create device file hdcp_srm");
    687
    688	return hdcp_work;
    689
    690fail_alloc_context:
    691	kfree(hdcp_work->srm);
    692	kfree(hdcp_work->srm_temp);
    693	kfree(hdcp_work);
    694
    695	return NULL;
    696
    697
    698
    699}
    700
    701
    702