From 8ea5a9f933baceb15fcaf0ebacfe07cd0fee9d42 Mon Sep 17 00:00:00 2001 From: "hongyu.chen" Date: Fri, 25 Aug 2023 19:38:43 +0800 Subject: [PATCH] demux: fix dump input and dvr data fail in secure mode. [1/1] PD#SWPL-137791 Problem: dump input and dvr data fail in secure mode. Solution: use ioremap_wc map secure memory to virtual address space. Verify: S905X4/AH212 Change-Id: I349753e2ce6432cf70a09ee6df70e8867a71fecf Signed-off-by: hongyu.chen --- drivers/dvb/demux/aml_dmx.c | 2 +- drivers/dvb/demux/sc2_demux/mem_desc.c | 45 +++++++++++++++++++++++ drivers/dvb/demux/sc2_demux/ts_output.c | 47 ++++++++++++++++++++++--- 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/drivers/dvb/demux/aml_dmx.c b/drivers/dvb/demux/aml_dmx.c index 266fd912a..64da0bf98 100644 --- a/drivers/dvb/demux/aml_dmx.c +++ b/drivers/dvb/demux/aml_dmx.c @@ -771,7 +771,7 @@ static int _dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, if (pes_type == DMX_PES_OTHER && dump_type >= DMX_DUMP_DVR_TYPE && dump_type <= DMX_DUMP_INPUT_TYPE) { dump_sid = ((filter->params.pes.flags >> 24) & 0xff); - filter->params.pes.flags = 0; + filter->params.pes.flags &= 0x0000ffff; if (dump_type == DMX_DUMP_TS_TYPE) { /* nothing to do */ } else { diff --git a/drivers/dvb/demux/sc2_demux/mem_desc.c b/drivers/dvb/demux/sc2_demux/mem_desc.c index e63a0d68e..50050e927 100644 --- a/drivers/dvb/demux/sc2_demux/mem_desc.c +++ b/drivers/dvb/demux/sc2_demux/mem_desc.c @@ -13,6 +13,8 @@ #include #include +#include + //#define CHECK_PACKET_ALIGNM #ifdef CHECK_PACKET_ALIGNM #include @@ -1324,6 +1326,11 @@ int SC2_bufferid_write(struct chan_id *pchan, const char *buf, char *buf_phys, int total = count; s64 prev_time_nsec; s64 max_timeout_nsec; + unsigned char *vaddr = 0; + unsigned long reg = 0; + unsigned long length = 0; + struct page *page = NULL; + int alignment = sizeof(unsigned long); pr_dbg("%s start w:%d id:%d, addr:0x%0x\n", __func__, count, pchan->id, (u32)(long)buf_phys); @@ -1347,6 +1354,44 @@ int SC2_bufferid_write(struct chan_id *pchan, const char *buf, char *buf_phys, pchan->memdescs->bits.byte_length = ts_data->buf_end - ts_data->buf_start; + if (dump_input_cb) { + #ifdef CONFIG_ARM64 + if (pfn_is_map_memory(ts_data->buf_start >> PAGE_SHIFT)) { + #else + if (pfn_valid(ts_data->buf_start >> PAGE_SHIFT)) { + #endif + page = pfn_to_page(ts_data->buf_start >> PAGE_SHIFT); + vaddr = kmap(page) + (ts_data->buf_start & ~PAGE_MASK); + kasan_disable_current(); + //pr_dbg("%s %d buffers start = %lx phy addr = %lx + //vir addr = %lx\n", + //__func__, __LINE__, ts_data.buf_start, tmp, vaddr); + dump_input_cb(pchan->id, -1, DMX_DUMP_INPUT_TYPE, vaddr, + pchan->memdescs->bits.byte_length, &dump_input_head); + kasan_enable_current(); + kunmap(page); + } else { + reg = round_down(ts_data->buf_start, alignment - 1); + length = (ts_data->buf_end - ts_data->buf_start) + + (ts_data->buf_start - reg); + vaddr = (void *)ioremap_wc(reg, length); + if (IS_ERR_OR_NULL(vaddr)) { + dprint("%s %d ioremap fail\n", __func__, __LINE__); + } else { + //pr_dbg("%s %d buffers start = %lx + //phy addr = %lx vir addr = %lx\n", + //__func__, __LINE__, ts_data.buf_start, + //tmp, vaddr); + dump_input_cb(pchan->id, -1, DMX_DUMP_INPUT_TYPE, + vaddr + (ts_data->buf_start - reg), + pchan->memdescs->bits.byte_length, + &dump_input_head); + + iounmap(vaddr); + } + } + } + dma_sync_single_for_device(aml_get_device(), pchan->memdescs_phy, sizeof(union mem_desc), DMA_TO_DEVICE); diff --git a/drivers/dvb/demux/sc2_demux/ts_output.c b/drivers/dvb/demux/sc2_demux/ts_output.c index 2894a095e..92b203888 100644 --- a/drivers/dvb/demux/sc2_demux/ts_output.c +++ b/drivers/dvb/demux/sc2_demux/ts_output.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "sc2_control.h" #include "ts_output.h" @@ -509,7 +510,7 @@ static int section_process(struct out_elem *pout) remain_len = ret - w_size; if (dump_other_cb) dump_other_cb(pout->sid, pout->es_pes->pid, - DMX_DUMP_SECTION_TYPE, pread, w_size, + DMX_DUMP_SECTION_TYPE, pread, ret, &dump_other_head); if (remain_len) { if (pout->pchan->sec_level) @@ -547,6 +548,13 @@ static int dvr_process(struct out_elem *pout) char *pread; int flag = 0; int overflow = 0; + unsigned char *vaddr = 0; + unsigned long reg = 0; + unsigned long length = 0; + unsigned long addr = 0; + int alignment = sizeof(unsigned long); + struct page *page = NULL; + if (pout->pchan->sec_level) flag = 1; @@ -563,10 +571,39 @@ static int dvr_process(struct out_elem *pout) pread, ret, &dump_other_head); } else if (pout->cb_ts_list && flag == 1) { if (dump_other_cb) { - enforce_flush_cache(pread, ret); - dump_other_cb(pout->sid, -1, DMX_DUMP_DVR_TYPE, - pread - pout->pchan->mem_phy + - pout->pchan->mem, ret, &dump_other_head); + addr = (unsigned long)pread; + #ifdef CONFIG_ARM64 + if (pfn_is_map_memory(addr >> PAGE_SHIFT)) { + #else + if (pfn_valid(addr >> PAGE_SHIFT)) { + #endif + page = pfn_to_page(addr >> PAGE_SHIFT); + vaddr = kmap(page) + (addr & ~PAGE_MASK); + kasan_disable_current(); + //pr_dbg("%s %d buffers start = %lx vir addr = %lx\n", + // __func__, __LINE__, pread, vaddr); + dump_other_cb(pout->sid, -1, DMX_DUMP_DVR_TYPE, vaddr, + ret, &dump_other_head); + kasan_enable_current(); + kunmap(page); + } else { + reg = round_down(addr, alignment - 1); + length = ret + ((unsigned long)pread - reg); + vaddr = (void *)ioremap_wc(reg, length); + if (IS_ERR_OR_NULL(vaddr)) { + dprint("%s %d ioremap fail\n", __func__, __LINE__); + } else { + //pr_dbg("%s %d buffers start = %lx reg = %lx + //vir addr = %lx length = %lx ret = %lx + //vaddr = %lx\n", __func__, __LINE__, pread, reg, + //vaddr, length, ret, + //vaddr + ((unsigned long)pread - reg)); + dump_other_cb(pout->sid, -1, DMX_DUMP_DVR_TYPE, + vaddr + ((unsigned long)pread - reg), + ret, &dump_other_head); + iounmap(vaddr); + } + } } write_sec_ts_data(pout, pread, ret); }