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

scsi_trace.c (8453B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2010 FUJITSU LIMITED
      4 * Copyright (C) 2010 Tomohiro Kusumi <kusumi.tomohiro@jp.fujitsu.com>
      5 */
      6#include <linux/kernel.h>
      7#include <linux/trace_seq.h>
      8#include <asm/unaligned.h>
      9#include <trace/events/scsi.h>
     10
     11#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
     12#define SERVICE_ACTION32(cdb) (get_unaligned_be16(&cdb[8]))
     13
     14static const char *
     15scsi_trace_misc(struct trace_seq *, unsigned char *, int);
     16
     17static const char *
     18scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
     19{
     20	const char *ret = trace_seq_buffer_ptr(p);
     21	u32 lba, txlen;
     22
     23	lba = get_unaligned_be24(&cdb[1]) & 0x1fffff;
     24	/*
     25	 * From SBC-2: a TRANSFER LENGTH field set to zero specifies that 256
     26	 * logical blocks shall be read (READ(6)) or written (WRITE(6)).
     27	 */
     28	txlen = cdb[4] ? cdb[4] : 256;
     29
     30	trace_seq_printf(p, "lba=%u txlen=%u", lba, txlen);
     31	trace_seq_putc(p, 0);
     32
     33	return ret;
     34}
     35
     36static const char *
     37scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
     38{
     39	const char *ret = trace_seq_buffer_ptr(p);
     40	u32 lba, txlen;
     41
     42	lba = get_unaligned_be32(&cdb[2]);
     43	txlen = get_unaligned_be16(&cdb[7]);
     44
     45	trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen,
     46			 cdb[1] >> 5);
     47
     48	if (cdb[0] == WRITE_SAME)
     49		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
     50
     51	trace_seq_putc(p, 0);
     52
     53	return ret;
     54}
     55
     56static const char *
     57scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
     58{
     59	const char *ret = trace_seq_buffer_ptr(p);
     60	u32 lba, txlen;
     61
     62	lba = get_unaligned_be32(&cdb[2]);
     63	txlen = get_unaligned_be32(&cdb[6]);
     64
     65	trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen,
     66			 cdb[1] >> 5);
     67	trace_seq_putc(p, 0);
     68
     69	return ret;
     70}
     71
     72static const char *
     73scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
     74{
     75	const char *ret = trace_seq_buffer_ptr(p);
     76	u64 lba;
     77	u32 txlen;
     78
     79	lba = get_unaligned_be64(&cdb[2]);
     80	txlen = get_unaligned_be32(&cdb[10]);
     81
     82	trace_seq_printf(p, "lba=%llu txlen=%u protect=%u", lba, txlen,
     83			 cdb[1] >> 5);
     84
     85	if (cdb[0] == WRITE_SAME_16)
     86		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
     87
     88	trace_seq_putc(p, 0);
     89
     90	return ret;
     91}
     92
     93static const char *
     94scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
     95{
     96	const char *ret = trace_seq_buffer_ptr(p), *cmd;
     97	u64 lba;
     98	u32 ei_lbrt, txlen;
     99
    100	switch (SERVICE_ACTION32(cdb)) {
    101	case READ_32:
    102		cmd = "READ";
    103		break;
    104	case VERIFY_32:
    105		cmd = "VERIFY";
    106		break;
    107	case WRITE_32:
    108		cmd = "WRITE";
    109		break;
    110	case WRITE_SAME_32:
    111		cmd = "WRITE_SAME";
    112		break;
    113	default:
    114		trace_seq_puts(p, "UNKNOWN");
    115		goto out;
    116	}
    117
    118	lba = get_unaligned_be64(&cdb[12]);
    119	ei_lbrt = get_unaligned_be32(&cdb[20]);
    120	txlen = get_unaligned_be32(&cdb[28]);
    121
    122	trace_seq_printf(p, "%s_32 lba=%llu txlen=%u protect=%u ei_lbrt=%u",
    123			 cmd, lba, txlen, cdb[10] >> 5, ei_lbrt);
    124
    125	if (SERVICE_ACTION32(cdb) == WRITE_SAME_32)
    126		trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1);
    127
    128out:
    129	trace_seq_putc(p, 0);
    130
    131	return ret;
    132}
    133
    134static const char *
    135scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
    136{
    137	const char *ret = trace_seq_buffer_ptr(p);
    138	unsigned int regions = get_unaligned_be16(&cdb[7]);
    139
    140	trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
    141	trace_seq_putc(p, 0);
    142
    143	return ret;
    144}
    145
    146static const char *
    147scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
    148{
    149	const char *ret = trace_seq_buffer_ptr(p), *cmd;
    150	u64 lba;
    151	u32 alloc_len;
    152
    153	switch (SERVICE_ACTION16(cdb)) {
    154	case SAI_READ_CAPACITY_16:
    155		cmd = "READ_CAPACITY_16";
    156		break;
    157	case SAI_GET_LBA_STATUS:
    158		cmd = "GET_LBA_STATUS";
    159		break;
    160	default:
    161		trace_seq_puts(p, "UNKNOWN");
    162		goto out;
    163	}
    164
    165	lba = get_unaligned_be64(&cdb[2]);
    166	alloc_len = get_unaligned_be32(&cdb[10]);
    167
    168	trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, lba, alloc_len);
    169
    170out:
    171	trace_seq_putc(p, 0);
    172
    173	return ret;
    174}
    175
    176static const char *
    177scsi_trace_maintenance_in(struct trace_seq *p, unsigned char *cdb, int len)
    178{
    179	const char *ret = trace_seq_buffer_ptr(p), *cmd;
    180	u32 alloc_len;
    181
    182	switch (SERVICE_ACTION16(cdb)) {
    183	case MI_REPORT_IDENTIFYING_INFORMATION:
    184		cmd = "REPORT_IDENTIFYING_INFORMATION";
    185		break;
    186	case MI_REPORT_TARGET_PGS:
    187		cmd = "REPORT_TARGET_PORT_GROUPS";
    188		break;
    189	case MI_REPORT_ALIASES:
    190		cmd = "REPORT_ALIASES";
    191		break;
    192	case MI_REPORT_SUPPORTED_OPERATION_CODES:
    193		cmd = "REPORT_SUPPORTED_OPERATION_CODES";
    194		break;
    195	case MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS:
    196		cmd = "REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS";
    197		break;
    198	case MI_REPORT_PRIORITY:
    199		cmd = "REPORT_PRIORITY";
    200		break;
    201	case MI_REPORT_TIMESTAMP:
    202		cmd = "REPORT_TIMESTAMP";
    203		break;
    204	case MI_MANAGEMENT_PROTOCOL_IN:
    205		cmd = "MANAGEMENT_PROTOCOL_IN";
    206		break;
    207	default:
    208		trace_seq_puts(p, "UNKNOWN");
    209		goto out;
    210	}
    211
    212	alloc_len = get_unaligned_be32(&cdb[6]);
    213
    214	trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
    215
    216out:
    217	trace_seq_putc(p, 0);
    218
    219	return ret;
    220}
    221
    222static const char *
    223scsi_trace_maintenance_out(struct trace_seq *p, unsigned char *cdb, int len)
    224{
    225	const char *ret = trace_seq_buffer_ptr(p), *cmd;
    226	u32 alloc_len;
    227
    228	switch (SERVICE_ACTION16(cdb)) {
    229	case MO_SET_IDENTIFYING_INFORMATION:
    230		cmd = "SET_IDENTIFYING_INFORMATION";
    231		break;
    232	case MO_SET_TARGET_PGS:
    233		cmd = "SET_TARGET_PORT_GROUPS";
    234		break;
    235	case MO_CHANGE_ALIASES:
    236		cmd = "CHANGE_ALIASES";
    237		break;
    238	case MO_SET_PRIORITY:
    239		cmd = "SET_PRIORITY";
    240		break;
    241	case MO_SET_TIMESTAMP:
    242		cmd = "SET_TIMESTAMP";
    243		break;
    244	case MO_MANAGEMENT_PROTOCOL_OUT:
    245		cmd = "MANAGEMENT_PROTOCOL_OUT";
    246		break;
    247	default:
    248		trace_seq_puts(p, "UNKNOWN");
    249		goto out;
    250	}
    251
    252	alloc_len = get_unaligned_be32(&cdb[6]);
    253
    254	trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
    255
    256out:
    257	trace_seq_putc(p, 0);
    258
    259	return ret;
    260}
    261
    262static const char *
    263scsi_trace_zbc_in(struct trace_seq *p, unsigned char *cdb, int len)
    264{
    265	const char *ret = trace_seq_buffer_ptr(p), *cmd;
    266	u64 zone_id;
    267	u32 alloc_len;
    268	u8 options;
    269
    270	switch (SERVICE_ACTION16(cdb)) {
    271	case ZI_REPORT_ZONES:
    272		cmd = "REPORT_ZONES";
    273		break;
    274	default:
    275		trace_seq_puts(p, "UNKNOWN");
    276		goto out;
    277	}
    278
    279	zone_id = get_unaligned_be64(&cdb[2]);
    280	alloc_len = get_unaligned_be32(&cdb[10]);
    281	options = cdb[14] & 0x3f;
    282
    283	trace_seq_printf(p, "%s zone=%llu alloc_len=%u options=%u partial=%u",
    284			 cmd, (unsigned long long)zone_id, alloc_len,
    285			 options, (cdb[14] >> 7) & 1);
    286
    287out:
    288	trace_seq_putc(p, 0);
    289
    290	return ret;
    291}
    292
    293static const char *
    294scsi_trace_zbc_out(struct trace_seq *p, unsigned char *cdb, int len)
    295{
    296	const char *ret = trace_seq_buffer_ptr(p), *cmd;
    297	u64 zone_id;
    298
    299	switch (SERVICE_ACTION16(cdb)) {
    300	case ZO_CLOSE_ZONE:
    301		cmd = "CLOSE_ZONE";
    302		break;
    303	case ZO_FINISH_ZONE:
    304		cmd = "FINISH_ZONE";
    305		break;
    306	case ZO_OPEN_ZONE:
    307		cmd = "OPEN_ZONE";
    308		break;
    309	case ZO_RESET_WRITE_POINTER:
    310		cmd = "RESET_WRITE_POINTER";
    311		break;
    312	default:
    313		trace_seq_puts(p, "UNKNOWN");
    314		goto out;
    315	}
    316
    317	zone_id = get_unaligned_be64(&cdb[2]);
    318
    319	trace_seq_printf(p, "%s zone=%llu all=%u", cmd,
    320			 (unsigned long long)zone_id, cdb[14] & 1);
    321
    322out:
    323	trace_seq_putc(p, 0);
    324
    325	return ret;
    326}
    327
    328static const char *
    329scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
    330{
    331	switch (SERVICE_ACTION32(cdb)) {
    332	case READ_32:
    333	case VERIFY_32:
    334	case WRITE_32:
    335	case WRITE_SAME_32:
    336		return scsi_trace_rw32(p, cdb, len);
    337	default:
    338		return scsi_trace_misc(p, cdb, len);
    339	}
    340}
    341
    342static const char *
    343scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
    344{
    345	const char *ret = trace_seq_buffer_ptr(p);
    346
    347	trace_seq_putc(p, '-');
    348	trace_seq_putc(p, 0);
    349
    350	return ret;
    351}
    352
    353const char *
    354scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
    355{
    356	switch (cdb[0]) {
    357	case READ_6:
    358	case WRITE_6:
    359		return scsi_trace_rw6(p, cdb, len);
    360	case READ_10:
    361	case VERIFY:
    362	case WRITE_10:
    363	case WRITE_SAME:
    364		return scsi_trace_rw10(p, cdb, len);
    365	case READ_12:
    366	case VERIFY_12:
    367	case WRITE_12:
    368		return scsi_trace_rw12(p, cdb, len);
    369	case READ_16:
    370	case VERIFY_16:
    371	case WRITE_16:
    372	case WRITE_SAME_16:
    373		return scsi_trace_rw16(p, cdb, len);
    374	case UNMAP:
    375		return scsi_trace_unmap(p, cdb, len);
    376	case SERVICE_ACTION_IN_16:
    377		return scsi_trace_service_action_in(p, cdb, len);
    378	case VARIABLE_LENGTH_CMD:
    379		return scsi_trace_varlen(p, cdb, len);
    380	case MAINTENANCE_IN:
    381		return scsi_trace_maintenance_in(p, cdb, len);
    382	case MAINTENANCE_OUT:
    383		return scsi_trace_maintenance_out(p, cdb, len);
    384	case ZBC_IN:
    385		return scsi_trace_zbc_in(p, cdb, len);
    386	case ZBC_OUT:
    387		return scsi_trace_zbc_out(p, cdb, len);
    388	default:
    389		return scsi_trace_misc(p, cdb, len);
    390	}
    391}