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

vidtv_ts.c (3560B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * The Virtual DVB test driver serves as a reference DVB driver and helps
      4 * validate the existing APIs in the media subsystem. It can also aid
      5 * developers working on userspace applications.
      6 *
      7 * Copyright (C) 2020 Daniel W. S. Almeida
      8 */
      9
     10#define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
     11
     12#include <linux/math64.h>
     13#include <linux/printk.h>
     14#include <linux/ratelimit.h>
     15#include <linux/types.h>
     16
     17#include "vidtv_common.h"
     18#include "vidtv_ts.h"
     19
     20static u32 vidtv_ts_write_pcr_bits(u8 *to, u32 to_offset, u64 pcr)
     21{
     22	/* Exact same from ffmpeg. PCR is a counter driven by a 27Mhz clock */
     23	u64 div;
     24	u64 rem;
     25	u8 *buf = to + to_offset;
     26	u64 pcr_low;
     27	u64 pcr_high;
     28
     29	div = div64_u64_rem(pcr, 300, &rem);
     30
     31	pcr_low = rem; /* pcr_low = pcr % 300 */
     32	pcr_high = div; /* pcr_high = pcr / 300 */
     33
     34	*buf++ = pcr_high >> 25;
     35	*buf++ = pcr_high >> 17;
     36	*buf++ = pcr_high >>  9;
     37	*buf++ = pcr_high >>  1;
     38	*buf++ = pcr_high <<  7 | pcr_low >> 8 | 0x7e;
     39	*buf++ = pcr_low;
     40
     41	return 6;
     42}
     43
     44void vidtv_ts_inc_cc(u8 *continuity_counter)
     45{
     46	++*continuity_counter;
     47	if (*continuity_counter > TS_CC_MAX_VAL)
     48		*continuity_counter = 0;
     49}
     50
     51u32 vidtv_ts_null_write_into(struct null_packet_write_args args)
     52{
     53	u32 nbytes = 0;
     54	struct vidtv_mpeg_ts ts_header = {};
     55
     56	ts_header.sync_byte          = TS_SYNC_BYTE;
     57	ts_header.bitfield           = cpu_to_be16(TS_NULL_PACKET_PID);
     58	ts_header.payload            = 1;
     59	ts_header.continuity_counter = *args.continuity_counter;
     60
     61	/* copy TS header */
     62	nbytes += vidtv_memcpy(args.dest_buf,
     63			       args.dest_offset + nbytes,
     64			       args.buf_sz,
     65			       &ts_header,
     66			       sizeof(ts_header));
     67
     68	vidtv_ts_inc_cc(args.continuity_counter);
     69
     70	/* fill the rest with empty data */
     71	nbytes += vidtv_memset(args.dest_buf,
     72			       args.dest_offset + nbytes,
     73			       args.buf_sz,
     74			       TS_FILL_BYTE,
     75			       TS_PACKET_LEN - nbytes);
     76
     77	/* we should have written exactly _one_ 188byte packet */
     78	if (nbytes != TS_PACKET_LEN)
     79		pr_warn_ratelimited("Expected exactly %d bytes, got %d\n",
     80				    TS_PACKET_LEN,
     81				    nbytes);
     82
     83	return nbytes;
     84}
     85
     86u32 vidtv_ts_pcr_write_into(struct pcr_write_args args)
     87{
     88	u32 nbytes = 0;
     89	struct vidtv_mpeg_ts ts_header = {};
     90	struct vidtv_mpeg_ts_adaption ts_adap = {};
     91
     92	ts_header.sync_byte     = TS_SYNC_BYTE;
     93	ts_header.bitfield      = cpu_to_be16(args.pid);
     94	ts_header.scrambling    = 0;
     95	/* cc is not incremented, but it is needed. see 13818-1 clause 2.4.3.3 */
     96	ts_header.continuity_counter = *args.continuity_counter;
     97	ts_header.payload            = 0;
     98	ts_header.adaptation_field   = 1;
     99
    100	/* 13818-1 clause 2.4.3.5 */
    101	ts_adap.length = 183;
    102	ts_adap.PCR    = 1;
    103
    104	/* copy TS header */
    105	nbytes += vidtv_memcpy(args.dest_buf,
    106			       args.dest_offset + nbytes,
    107			       args.buf_sz,
    108			       &ts_header,
    109			       sizeof(ts_header));
    110
    111	/* write the adap after the TS header */
    112	nbytes += vidtv_memcpy(args.dest_buf,
    113			       args.dest_offset + nbytes,
    114			       args.buf_sz,
    115			       &ts_adap,
    116			       sizeof(ts_adap));
    117
    118	/* write the PCR optional */
    119	nbytes += vidtv_ts_write_pcr_bits(args.dest_buf,
    120					  args.dest_offset + nbytes,
    121					  args.pcr);
    122
    123	nbytes += vidtv_memset(args.dest_buf,
    124			       args.dest_offset + nbytes,
    125			       args.buf_sz,
    126			       TS_FILL_BYTE,
    127			       TS_PACKET_LEN - nbytes);
    128
    129	/* we should have written exactly _one_ 188byte packet */
    130	if (nbytes != TS_PACKET_LEN)
    131		pr_warn_ratelimited("Expected exactly %d bytes, got %d\n",
    132				    TS_PACKET_LEN,
    133				    nbytes);
    134
    135	return nbytes;
    136}