LCOV - code coverage report
Current view: top level - spdk/test/app/fuzz/llvm_nvme_fuzz - llvm_nvme_fuzz.c (source / functions) Hit Total Coverage
Test: Combined Lines: 403 569 70.8 %
Date: 2024-12-15 08:55:18 Functions: 35 50 70.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1410 3457 40.8 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2021 Intel Corporation. All rights reserved.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "spdk/stdinc.h"
       6                 :            : #include "spdk/conf.h"
       7                 :            : #include "spdk/env.h"
       8                 :            : #include "spdk/event.h"
       9                 :            : #include "spdk/util.h"
      10                 :            : #include "spdk/string.h"
      11                 :            : #include "spdk/nvme_spec.h"
      12                 :            : #include "spdk/nvme.h"
      13                 :            : #include "spdk/likely.h"
      14                 :            : #include "spdk/file.h"
      15                 :            : 
      16                 :            : static const uint8_t *g_data;
      17                 :            : static bool g_trid_specified = false;
      18                 :            : static char *g_artifact_prefix;
      19                 :            : static int32_t g_time_in_sec = 10;
      20                 :            : static char *g_corpus_dir;
      21                 :            : static uint8_t *g_repro_data;
      22                 :            : static size_t g_repro_size;
      23                 :            : static pthread_t g_fuzz_td;
      24                 :            : static pthread_t g_reactor_td;
      25                 :            : static bool g_in_fuzzer;
      26                 :            : 
      27                 :            : #define MAX_COMMANDS 5
      28                 :            : 
      29                 :            : struct fuzz_command {
      30                 :            :         struct spdk_nvme_cmd    cmd;
      31                 :            :         void                    *buf;
      32                 :            :         uint32_t                len;
      33                 :            : };
      34                 :            : 
      35                 :            : static struct fuzz_command g_cmds[MAX_COMMANDS];
      36                 :            : 
      37                 :            : typedef void (*fuzz_build_cmd_fn)(struct fuzz_command *cmd);
      38                 :            : 
      39                 :            : struct fuzz_type {
      40                 :            :         fuzz_build_cmd_fn       fn;
      41                 :            :         uint32_t                bytes_per_cmd;
      42                 :            :         bool    is_admin;
      43                 :            : };
      44                 :            : 
      45                 :            : static void
      46                 :         60 : fuzz_admin_command(struct fuzz_command *cmd)
      47                 :            : {
      48   [ +  -  +  -  :         60 :         memcpy(&cmd->cmd, g_data, sizeof(cmd->cmd));
                   +  - ]
      49         [ +  - ]:         60 :         g_data += sizeof(cmd->cmd);
      50                 :            : 
      51                 :            :         /* ASYNC_EVENT_REQUEST won't complete, so pick a different opcode. */
      52   [ +  -  +  -  :         60 :         if (cmd->cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) {
                   +  - ]
      53   [ #  #  #  # ]:          0 :                 cmd->cmd.opc = SPDK_NVME_OPC_SET_FEATURES;
      54                 :          0 :         }
      55                 :            : 
      56                 :            :         /* NVME_OPC_FABRIC is special for fabric transport, so pick a different opcode. */
      57   [ +  -  +  -  :         60 :         if (cmd->cmd.opc == SPDK_NVME_OPC_FABRIC) {
                   +  - ]
      58   [ #  #  #  # ]:          0 :                 cmd->cmd.opc = SPDK_NVME_OPC_SET_FEATURES;
      59                 :          0 :         }
      60                 :            : 
      61                 :            :         /* Fuzz a normal operation, so set a zero value in Fused field. */
      62   [ +  -  +  - ]:         60 :         cmd->cmd.fuse = 0;
      63                 :         60 : }
      64                 :            : 
      65                 :            : static void
      66                 :        159 : fuzz_admin_get_log_page_command(struct fuzz_command *cmd)
      67                 :            : {
      68   [ +  -  +  - ]:        159 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
      69                 :            : 
      70   [ +  -  +  - ]:        159 :         cmd->cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE;
      71                 :            : 
      72                 :            :         /* Only fuzz some of the more interesting parts of the GET_LOG_PAGE command. */
      73                 :            : 
      74   [ +  -  +  -  :        159 :         cmd->cmd.cdw10_bits.get_log_page.numdl = ((uint16_t)g_data[0] << 8) + (uint16_t)g_data[1];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
      75   [ +  -  +  -  :        159 :         cmd->cmd.cdw10_bits.get_log_page.lid = g_data[2];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
      76   [ +  -  +  -  :        159 :         cmd->cmd.cdw10_bits.get_log_page.lsp = g_data[3] & (0x60 >> 5);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
      77   [ +  -  +  -  :        159 :         cmd->cmd.cdw10_bits.get_log_page.rae = g_data[3] & (0x80 >> 7);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
      78                 :            : 
      79   [ +  -  +  -  :        159 :         cmd->cmd.cdw11_bits.get_log_page.numdu = g_data[3] & (0x18 >> 3);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
      80                 :            : 
      81                 :            :         /* Log Page Offset Lower */
      82   [ +  -  +  -  :        159 :         cmd->cmd.cdw12 = ((uint16_t)g_data[4] << 8) + (uint16_t)g_data[5];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
      83                 :            : 
      84                 :            :         /* Offset Type */
      85   [ +  -  +  -  :        159 :         cmd->cmd.cdw14 = g_data[3] & (0x01 >> 0);
          +  -  +  -  +  
                -  +  - ]
      86                 :            : 
      87                 :            :         /* Log Page Offset Upper */
      88   [ +  -  +  -  :        159 :         cmd->cmd.cdw13 = g_data[3] & (0x06 >> 1);
          +  -  +  -  +  
             -  +  -  +  
                      - ]
      89                 :            : 
      90         [ +  - ]:        159 :         g_data += 6;
      91                 :        159 : }
      92                 :            : 
      93                 :            : static void
      94                 :        102 : fuzz_admin_identify_command(struct fuzz_command *cmd)
      95                 :            : {
      96   [ +  -  +  - ]:        102 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
      97                 :            : 
      98   [ +  -  +  - ]:        102 :         cmd->cmd.opc = SPDK_NVME_OPC_IDENTIFY;
      99                 :            : 
     100   [ +  -  +  -  :        102 :         cmd->cmd.cdw10_bits.identify.cns = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     101   [ +  -  +  -  :        102 :         cmd->cmd.cdw10_bits.identify.cntid = ((uint16_t)g_data[1] << 8) + (uint16_t)g_data[2];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     102                 :            : 
     103   [ +  -  +  -  :        102 :         cmd->cmd.cdw11_bits.identify.nvmsetid = ((uint16_t)g_data[3] << 8) + (uint16_t)g_data[4];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     104   [ +  -  +  -  :        102 :         cmd->cmd.cdw11_bits.identify.csi = g_data[5];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     105                 :            : 
     106                 :            :         /* UUID index, bits 0-6 are used */
     107   [ +  -  +  -  :        102 :         cmd->cmd.cdw14 = (g_data[6] & 0x7f);
          +  -  +  -  +  
                      - ]
     108                 :            : 
     109         [ +  - ]:        102 :         g_data += 7;
     110                 :        102 : }
     111                 :            : 
     112                 :            : static void
     113                 :         94 : fuzz_admin_abort_command(struct fuzz_command *cmd)
     114                 :            : {
     115   [ +  -  +  - ]:         94 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     116   [ +  -  +  - ]:         94 :         cmd->cmd.opc = SPDK_NVME_OPC_ABORT;
     117                 :            : 
     118   [ +  -  +  -  :         94 :         cmd->cmd.cdw10_bits.abort.sqid = ((uint16_t)g_data[0] << 8) + (uint16_t)g_data[1];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     119   [ +  -  +  -  :         94 :         cmd->cmd.cdw10_bits.abort.cid = ((uint16_t)g_data[2] << 8) + (uint16_t)g_data[3];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     120                 :            : 
     121         [ +  - ]:         94 :         g_data += 4;
     122                 :         94 : }
     123                 :            : 
     124                 :            : static void
     125                 :         66 : fuzz_admin_create_io_completion_queue_command(struct fuzz_command *cmd)
     126                 :            : {
     127   [ +  -  +  - ]:         66 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     128   [ +  -  +  - ]:         66 :         cmd->cmd.opc = SPDK_NVME_OPC_CREATE_IO_CQ;
     129                 :            : 
     130   [ +  -  +  -  :         66 :         cmd->cmd.cdw10_bits.create_io_q.qid = ((uint16_t)g_data[0] << 8) + (uint16_t)g_data[1];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     131   [ +  -  +  -  :         66 :         cmd->cmd.cdw10_bits.create_io_q.qsize = ((uint16_t)g_data[2] << 8) + (uint16_t)g_data[3];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     132                 :            : 
     133   [ +  -  +  -  :         66 :         cmd->cmd.cdw11_bits.create_io_cq.iv = ((uint16_t)g_data[4] << 8) + (uint16_t)g_data[5];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     134   [ +  -  +  -  :         66 :         cmd->cmd.cdw11_bits.create_io_cq.pc = (g_data[6] >> 7) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     135   [ +  -  +  -  :         66 :         cmd->cmd.cdw11_bits.create_io_cq.ien = (g_data[6] >> 6) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     136                 :            : 
     137         [ +  - ]:         66 :         g_data += 7;
     138                 :         66 : }
     139                 :            : 
     140                 :            : static void
     141                 :         98 : fuzz_admin_create_io_submission_queue_command(struct fuzz_command *cmd)
     142                 :            : {
     143   [ +  -  +  - ]:         98 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     144   [ +  -  +  - ]:         98 :         cmd->cmd.opc = SPDK_NVME_OPC_CREATE_IO_SQ;
     145                 :            : 
     146   [ +  -  +  -  :         98 :         cmd->cmd.cdw10_bits.create_io_q.qid = ((uint16_t)g_data[0] << 8) + (uint16_t)g_data[1];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     147   [ +  -  +  -  :         98 :         cmd->cmd.cdw10_bits.create_io_q.qsize = ((uint16_t)g_data[2] << 8) + (uint16_t)g_data[3];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     148                 :            : 
     149   [ +  -  +  -  :         98 :         cmd->cmd.cdw11_bits.create_io_sq.cqid = ((uint16_t)g_data[4] << 8) + (uint16_t)g_data[5];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     150   [ +  -  +  -  :         98 :         cmd->cmd.cdw11_bits.create_io_sq.qprio = (g_data[6] >> 6) & 0x03;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     151   [ +  -  +  -  :         98 :         cmd->cmd.cdw11_bits.create_io_sq.pc = (g_data[6] >> 5) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     152                 :            : 
     153                 :            :         /* NVM Set Identifier */
     154   [ +  -  +  -  :         98 :         cmd->cmd.cdw12 = ((uint16_t)g_data[7] << 8) + (uint16_t)g_data[8];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     155                 :            : 
     156         [ +  - ]:         98 :         g_data += 9;
     157                 :         98 : }
     158                 :            : 
     159                 :            : static void
     160                 :         78 : fuzz_admin_delete_io_completion_queue_command(struct fuzz_command *cmd)
     161                 :            : {
     162   [ +  -  +  - ]:         78 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     163   [ +  -  +  - ]:         78 :         cmd->cmd.opc = SPDK_NVME_OPC_DELETE_IO_CQ;
     164                 :            : 
     165   [ +  -  +  -  :         78 :         cmd->cmd.cdw10_bits.delete_io_q.qid = ((uint16_t)g_data[0] << 8) + (uint16_t)g_data[1];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     166                 :            : 
     167         [ +  - ]:         78 :         g_data += 2;
     168                 :         78 : }
     169                 :            : 
     170                 :            : static void
     171                 :         59 : fuzz_admin_delete_io_submission_queue_command(struct fuzz_command *cmd)
     172                 :            : {
     173   [ +  -  +  - ]:         59 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     174   [ +  -  +  - ]:         59 :         cmd->cmd.opc = SPDK_NVME_OPC_DELETE_IO_SQ;
     175                 :            : 
     176   [ +  -  +  -  :         59 :         cmd->cmd.cdw10_bits.delete_io_q.qid = ((uint16_t)g_data[0] << 8) + (uint16_t)g_data[1];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     177                 :            : 
     178         [ +  - ]:         59 :         g_data += 2;
     179                 :         59 : }
     180                 :            : 
     181                 :            : static void
     182                 :        124 : fuzz_admin_namespace_attachment_command(struct fuzz_command *cmd)
     183                 :            : {
     184   [ +  -  +  - ]:        124 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     185   [ +  -  +  - ]:        124 :         cmd->cmd.opc = SPDK_NVME_OPC_NS_ATTACHMENT;
     186                 :            : 
     187   [ +  -  +  -  :        124 :         cmd->cmd.cdw10_bits.ns_attach.sel = (g_data[0] >> 4) & 0x0f;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     188                 :            : 
     189         [ +  - ]:        124 :         g_data += 1;
     190                 :        124 : }
     191                 :            : 
     192                 :            : static void
     193                 :        122 : fuzz_admin_namespace_management_command(struct fuzz_command *cmd)
     194                 :            : {
     195   [ +  -  +  - ]:        122 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     196   [ +  -  +  - ]:        122 :         cmd->cmd.opc = SPDK_NVME_OPC_NS_MANAGEMENT;
     197                 :            : 
     198   [ +  -  +  -  :        122 :         cmd->cmd.cdw10_bits.ns_manage.sel = (g_data[0] >> 4) & 0x0f;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     199                 :            : 
     200         [ +  - ]:        122 :         g_data += 1;
     201                 :        122 : }
     202                 :            : 
     203                 :            : static void
     204                 :        104 : fuzz_admin_security_receive_command(struct fuzz_command *cmd)
     205                 :            : {
     206   [ +  -  +  - ]:        104 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     207   [ +  -  +  - ]:        104 :         cmd->cmd.opc = SPDK_NVME_OPC_SECURITY_RECEIVE;
     208                 :            : 
     209   [ +  -  +  -  :        104 :         cmd->cmd.cdw10_bits.sec_send_recv.secp = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     210   [ +  -  +  -  :        104 :         cmd->cmd.cdw10_bits.sec_send_recv.spsp1 = g_data[1];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     211   [ +  -  +  -  :        104 :         cmd->cmd.cdw10_bits.sec_send_recv.spsp0 = g_data[2];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     212   [ +  -  +  -  :        104 :         cmd->cmd.cdw10_bits.sec_send_recv.nssf = g_data[3];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     213                 :            : 
     214                 :            :         /* Allocation Length(AL) */
     215   [ +  -  +  -  :        312 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     216   [ +  -  +  -  :        104 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     217                 :            : 
     218         [ +  - ]:        104 :         g_data += 8;
     219                 :        104 : }
     220                 :            : 
     221                 :            : static void
     222                 :         57 : fuzz_admin_security_send_command(struct fuzz_command *cmd)
     223                 :            : {
     224   [ +  -  +  - ]:         57 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     225   [ +  -  +  - ]:         57 :         cmd->cmd.opc = SPDK_NVME_OPC_SECURITY_SEND;
     226                 :            : 
     227   [ +  -  +  -  :         57 :         cmd->cmd.cdw10_bits.sec_send_recv.secp = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     228   [ +  -  +  -  :         57 :         cmd->cmd.cdw10_bits.sec_send_recv.spsp1 = g_data[1];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     229   [ +  -  +  -  :         57 :         cmd->cmd.cdw10_bits.sec_send_recv.spsp0 = g_data[2];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     230   [ +  -  +  -  :         57 :         cmd->cmd.cdw10_bits.sec_send_recv.nssf = g_data[3];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     231                 :            : 
     232                 :            :         /* Transfer Length(TL) */
     233   [ +  -  +  -  :        171 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     234   [ +  -  +  -  :         57 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     235                 :            : 
     236         [ +  - ]:         57 :         g_data += 8;
     237                 :         57 : }
     238                 :            : 
     239                 :            : static void
     240                 :         91 : fuzz_admin_directive_send_command(struct fuzz_command *cmd)
     241                 :            : {
     242   [ +  -  +  - ]:         91 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     243   [ +  -  +  - ]:         91 :         cmd->cmd.opc = SPDK_NVME_OPC_DIRECTIVE_SEND;
     244                 :            : 
     245   [ +  -  +  -  :        273 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     246   [ +  -  +  -  :         91 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     247                 :            : 
     248   [ +  -  +  -  :         91 :         cmd->cmd.cdw11_bits.directive.dspec = ((uint16_t)g_data[4] << 8) + (uint16_t)g_data[5];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     249   [ +  -  +  -  :         91 :         cmd->cmd.cdw11_bits.directive.dtype = g_data[6];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     250   [ +  -  +  -  :         91 :         cmd->cmd.cdw11_bits.directive.doper = g_data[7];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     251                 :            : 
     252         [ +  - ]:         91 :         g_data += 8;
     253                 :         91 : }
     254                 :            : 
     255                 :            : static void
     256                 :         63 : fuzz_admin_directive_receive_command(struct fuzz_command *cmd)
     257                 :            : {
     258   [ +  -  +  - ]:         63 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     259   [ +  -  +  - ]:         63 :         cmd->cmd.opc = SPDK_NVME_OPC_DIRECTIVE_RECEIVE;
     260                 :            : 
     261   [ +  -  +  -  :        189 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     262   [ +  -  +  -  :         63 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     263                 :            : 
     264   [ +  -  +  -  :         63 :         cmd->cmd.cdw11_bits.directive.dspec = ((uint16_t)g_data[4] << 8) + (uint16_t)g_data[5];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     265   [ +  -  +  -  :         63 :         cmd->cmd.cdw11_bits.directive.dtype = g_data[6];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     266   [ +  -  +  -  :         63 :         cmd->cmd.cdw11_bits.directive.doper = g_data[7];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     267                 :            : 
     268         [ +  - ]:         63 :         g_data += 8;
     269                 :         63 : }
     270                 :            : 
     271                 :            : static void
     272                 :          9 : feat_arbitration(struct fuzz_command *cmd)
     273                 :            : {
     274   [ +  -  +  -  :          9 :         cmd->cmd.cdw11_bits.feat_arbitration.bits.hpw = g_data[2];
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     275   [ +  -  +  -  :          9 :         cmd->cmd.cdw11_bits.feat_arbitration.bits.mpw = g_data[3];
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     276   [ +  -  +  -  :          9 :         cmd->cmd.cdw11_bits.feat_arbitration.bits.lpw = g_data[4];
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     277   [ +  -  +  -  :          9 :         cmd->cmd.cdw11_bits.feat_arbitration.bits.ab = g_data[5] & 0x07;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     278                 :          9 : }
     279                 :            : 
     280                 :            : static void
     281                 :          0 : feat_power_management(struct fuzz_command *cmd)
     282                 :            : {
     283   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_power_management.bits.wh = g_data[2] & 0x07;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     284   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_power_management.bits.ps = (g_data[2] >> 3) & 0x1f;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     285                 :          0 : }
     286                 :            : 
     287                 :            : static void
     288                 :          0 : feat_lba_range_type(struct fuzz_command *cmd)
     289                 :            : {
     290   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_lba_range_type.bits.num = (g_data[2] >> 2) & 0x3f;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     291                 :          0 : }
     292                 :            : 
     293                 :            : static void
     294                 :          0 : feat_temperature_threshold(struct fuzz_command *cmd)
     295                 :            : {
     296   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_temp_threshold.bits.thsel = g_data[2] & 0x03;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     297   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_temp_threshold.bits.tmpsel = (g_data[2] >> 2) & 0x0f;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     298   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_temp_threshold.bits.tmpth = ((uint16_t)g_data[3] << 8) +
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     299   [ #  #  #  # ]:          0 :                         (uint16_t)g_data[4];
     300                 :          0 : }
     301                 :            : 
     302                 :            : static void
     303                 :          0 : feat_error_recover(struct fuzz_command *cmd)
     304                 :            : {
     305   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_error_recovery.bits.dulbe = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     306   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_error_recovery.bits.tler = ((uint16_t)g_data[3] << 8) +
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     307   [ #  #  #  # ]:          0 :                         (uint16_t)g_data[4];
     308                 :          0 : }
     309                 :            : 
     310                 :            : static void
     311                 :          0 : feat_volatile_write_cache(struct fuzz_command *cmd)
     312                 :            : {
     313   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_volatile_write_cache.bits.wce = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     314                 :          0 : }
     315                 :            : 
     316                 :            : static void
     317                 :          0 : feat_number_of_queues(struct fuzz_command *cmd)
     318                 :            : {
     319   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_num_of_queues.bits.ncqr = ((uint16_t)g_data[2] << 8) + (uint16_t)g_data[3];
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     320   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_num_of_queues.bits.nsqr = ((uint16_t)g_data[4] << 8) + (uint16_t)g_data[5];
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     321                 :          0 : }
     322                 :            : 
     323                 :            : static void
     324                 :          0 : feat_interrupt_coalescing(struct fuzz_command *cmd)
     325                 :            : {
     326   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_interrupt_coalescing.bits.time = g_data[2];
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     327   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_interrupt_coalescing.bits.thr = g_data[3];
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     328                 :          0 : }
     329                 :            : 
     330                 :            : static void
     331                 :          0 : feat_interrupt_vector_configuration(struct fuzz_command *cmd)
     332                 :            : {
     333   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_interrupt_vector_configuration.bits.cd = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     334   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_interrupt_vector_configuration.bits.iv = ((uint16_t)g_data[3] << 8) +
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     335   [ #  #  #  # ]:          0 :                         (uint16_t)g_data[4];
     336                 :          0 : }
     337                 :            : 
     338                 :            : static void
     339                 :          2 : feat_write_atomicity(struct fuzz_command *cmd)
     340                 :            : {
     341   [ +  -  +  -  :          2 :         cmd->cmd.cdw11_bits.feat_write_atomicity.bits.dn = g_data[2] & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     342                 :          2 : }
     343                 :            : 
     344                 :            : static void
     345                 :          0 : feat_async_event_cfg(struct fuzz_command *cmd)
     346                 :            : {
     347   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.ana_change_notice = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     348   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.discovery_log_change_notice = (g_data[2] >> 1) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     349   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.fw_activation_notice = (g_data[2] >> 2) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     350   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.ns_attr_notice = (g_data[2] >> 3) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     351   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.telemetry_log_notice = (g_data[2] >> 4) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     352                 :            : 
     353   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.crit_warn.bits.available_spare = g_data[3] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     354   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.crit_warn.bits.device_reliability =
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     355   [ #  #  #  #  :          0 :                 (g_data[3] >> 1) & 0x01;
                   #  # ]
     356   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.crit_warn.bits.read_only = (g_data[3] >> 2) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     357   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.crit_warn.bits.temperature = (g_data[3] >> 3) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     358   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_async_event_cfg.bits.crit_warn.bits.volatile_memory_backup =
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     359   [ #  #  #  #  :          0 :                 (g_data[3] >> 4) & 0x01;
                   #  # ]
     360                 :          0 : }
     361                 :            : 
     362                 :            : static void
     363                 :          0 : feat_keep_alive_timer(struct fuzz_command *cmd)
     364                 :            : {
     365   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_keep_alive_timer.bits.kato = ((uint32_t)g_data[2] << 24) + ((
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     366   [ #  #  #  #  :          0 :                                 uint32_t)g_data[3] << 16) +
             #  #  #  # ]
     367   [ #  #  #  #  :          0 :                         ((uint32_t)g_data[4] << 8) + (uint32_t)g_data[5];
          #  #  #  #  #  
                #  #  # ]
     368                 :          0 : }
     369                 :            : 
     370                 :            : static void
     371                 :          0 : feat_host_identifier(struct fuzz_command *cmd)
     372                 :            : {
     373   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_host_identifier.bits.exhid = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     374                 :          0 : }
     375                 :            : 
     376                 :            : static void
     377                 :          0 : feat_rsv_notification_mask(struct fuzz_command *cmd)
     378                 :            : {
     379   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_rsv_notification_mask.bits.regpre = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     380   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_rsv_notification_mask.bits.respre = (g_data[2] >> 1) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     381   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_rsv_notification_mask.bits.resrel = (g_data[2] >> 2) & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     382                 :          0 : }
     383                 :            : 
     384                 :            : static void
     385                 :          0 : feat_rsv_persistence(struct fuzz_command *cmd)
     386                 :            : {
     387   [ #  #  #  #  :          0 :         cmd->cmd.cdw11_bits.feat_rsv_persistence.bits.ptpl = g_data[2] & 0x01;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     388                 :          0 : }
     389                 :            : 
     390                 :            : static void
     391                 :         71 : fuzz_admin_set_features_command(struct fuzz_command *cmd)
     392                 :            : {
     393   [ +  -  +  - ]:         71 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     394   [ +  -  +  - ]:         71 :         cmd->cmd.opc = SPDK_NVME_OPC_SET_FEATURES;
     395                 :            : 
     396   [ +  -  +  -  :         71 :         cmd->cmd.cdw10_bits.set_features.fid = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     397   [ +  -  +  -  :         71 :         cmd->cmd.cdw10_bits.set_features.sv = (g_data[1] >> 7) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     398                 :            : 
     399   [ +  -  +  -  :         71 :         switch (cmd->cmd.cdw10_bits.set_features.fid) {
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
                   -  - ]
     400                 :            :         case SPDK_NVME_FEAT_ARBITRATION:
     401                 :          0 :                 feat_arbitration(cmd);
     402                 :          0 :                 break;
     403                 :            :         case SPDK_NVME_FEAT_POWER_MANAGEMENT:
     404                 :          0 :                 feat_power_management(cmd);
     405                 :          0 :                 break;
     406                 :            :         case SPDK_NVME_FEAT_LBA_RANGE_TYPE:
     407                 :          0 :                 feat_lba_range_type(cmd);
     408                 :          0 :                 break;
     409                 :            :         case SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD:
     410                 :          0 :                 feat_temperature_threshold(cmd);
     411                 :          0 :                 break;
     412                 :            :         case SPDK_NVME_FEAT_ERROR_RECOVERY:
     413                 :          0 :                 feat_error_recover(cmd);
     414                 :          0 :                 break;
     415                 :            :         case SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE:
     416                 :          0 :                 feat_volatile_write_cache(cmd);
     417                 :          0 :                 break;
     418                 :            :         case SPDK_NVME_FEAT_NUMBER_OF_QUEUES:
     419                 :          0 :                 feat_number_of_queues(cmd);
     420                 :          0 :                 break;
     421                 :            :         case SPDK_NVME_FEAT_INTERRUPT_COALESCING:
     422                 :          0 :                 feat_interrupt_coalescing(cmd);
     423                 :          0 :                 break;
     424                 :            :         case SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
     425                 :          0 :                 feat_interrupt_vector_configuration(cmd);
     426                 :          0 :                 break;
     427                 :            :         case SPDK_NVME_FEAT_WRITE_ATOMICITY:
     428                 :          2 :                 feat_write_atomicity(cmd);
     429                 :          2 :                 break;
     430                 :            :         case SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
     431                 :          0 :                 feat_async_event_cfg(cmd);
     432                 :          0 :                 break;
     433                 :            :         case SPDK_NVME_FEAT_KEEP_ALIVE_TIMER:
     434                 :          0 :                 feat_keep_alive_timer(cmd);
     435                 :          0 :                 break;
     436                 :            :         case SPDK_NVME_FEAT_HOST_IDENTIFIER:
     437                 :          0 :                 feat_host_identifier(cmd);
     438                 :          0 :                 break;
     439                 :            :         case SPDK_NVME_FEAT_HOST_RESERVE_MASK:
     440                 :          0 :                 feat_rsv_notification_mask(cmd);
     441                 :          0 :                 break;
     442                 :            :         case SPDK_NVME_FEAT_HOST_RESERVE_PERSIST:
     443                 :          0 :                 feat_rsv_persistence(cmd);
     444                 :          0 :                 break;
     445                 :            : 
     446                 :            :         default:
     447                 :         69 :                 break;
     448                 :            :         }
     449                 :            : 
     450                 :            :         /* Use g_data[2] through g_data[5] for feature-specific
     451                 :            :            bits and set g_data[6] for cdw14 every iteration
     452                 :            :            UUID index, bits 0-6 are used */
     453   [ +  -  +  -  :         71 :         cmd->cmd.cdw14 = (g_data[6] & 0x7f);
          +  -  +  -  +  
                      - ]
     454                 :            : 
     455         [ +  - ]:         71 :         g_data += 7;
     456                 :         71 : }
     457                 :            : 
     458                 :            : static void
     459                 :         33 : fuzz_admin_get_features_command(struct fuzz_command *cmd)
     460                 :            : {
     461   [ +  -  +  - ]:         33 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     462   [ +  -  +  - ]:         33 :         cmd->cmd.opc = SPDK_NVME_OPC_GET_FEATURES;
     463                 :            : 
     464   [ +  -  +  -  :         33 :         cmd->cmd.cdw10_bits.get_features.fid = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     465   [ +  -  +  -  :         33 :         cmd->cmd.cdw10_bits.get_features.sel = (g_data[1] >> 5) & 0x07;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     466                 :            : 
     467   [ +  -  +  -  :         33 :         switch (cmd->cmd.cdw10_bits.set_features.fid) {
          +  -  +  -  +  
          -  +  +  -  -  
          -  -  -  -  -  
             -  -  -  - ]
     468                 :            :         case SPDK_NVME_FEAT_ARBITRATION:
     469                 :          9 :                 feat_arbitration(cmd);
     470                 :          9 :                 break;
     471                 :            :         case SPDK_NVME_FEAT_POWER_MANAGEMENT:
     472                 :          0 :                 feat_power_management(cmd);
     473                 :          0 :                 break;
     474                 :            :         case SPDK_NVME_FEAT_LBA_RANGE_TYPE:
     475                 :          0 :                 feat_lba_range_type(cmd);
     476                 :          0 :                 break;
     477                 :            :         case SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD:
     478                 :          0 :                 feat_temperature_threshold(cmd);
     479                 :          0 :                 break;
     480                 :            :         case SPDK_NVME_FEAT_ERROR_RECOVERY:
     481                 :          0 :                 feat_error_recover(cmd);
     482                 :          0 :                 break;
     483                 :            :         case SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE:
     484                 :          0 :                 feat_volatile_write_cache(cmd);
     485                 :          0 :                 break;
     486                 :            :         case SPDK_NVME_FEAT_NUMBER_OF_QUEUES:
     487                 :          0 :                 feat_number_of_queues(cmd);
     488                 :          0 :                 break;
     489                 :            :         case SPDK_NVME_FEAT_INTERRUPT_COALESCING:
     490                 :          0 :                 feat_interrupt_coalescing(cmd);
     491                 :          0 :                 break;
     492                 :            :         case SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
     493                 :          0 :                 feat_interrupt_vector_configuration(cmd);
     494                 :          0 :                 break;
     495                 :            :         case SPDK_NVME_FEAT_WRITE_ATOMICITY:
     496                 :          0 :                 feat_write_atomicity(cmd);
     497                 :          0 :                 break;
     498                 :            :         case SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
     499                 :          0 :                 feat_async_event_cfg(cmd);
     500                 :          0 :                 break;
     501                 :            :         case SPDK_NVME_FEAT_KEEP_ALIVE_TIMER:
     502                 :          0 :                 feat_keep_alive_timer(cmd);
     503                 :          0 :                 break;
     504                 :            : 
     505                 :            :         default:
     506                 :         24 :                 break;
     507                 :            :         }
     508                 :            : 
     509                 :            :         /* Use g_data[2] through g_data[5] for feature-specific
     510                 :            :            bits and set g_data[6] for cdw14 every iteration
     511                 :            :            UUID index, bits 0-6 are used */
     512   [ +  -  +  -  :         33 :         cmd->cmd.cdw14 = (g_data[6] & 0x7f);
          +  -  +  -  +  
                      - ]
     513                 :            : 
     514         [ +  - ]:         33 :         g_data += 7;
     515                 :         33 : }
     516                 :            : 
     517                 :            : static void
     518                 :         74 : fuzz_nvm_read_command(struct fuzz_command *cmd)
     519                 :            : {
     520   [ +  -  +  - ]:         74 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     521   [ +  -  +  - ]:         74 :         cmd->cmd.opc = SPDK_NVME_OPC_READ;
     522                 :            : 
     523   [ +  -  +  -  :        222 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     524   [ +  -  +  -  :         74 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     525   [ +  -  +  -  :        222 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     526   [ +  -  +  -  :         74 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     527   [ +  -  +  -  :        222 :         cmd->cmd.cdw12 = ((uint32_t)g_data[8] << 24) + ((uint32_t)g_data[9] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     528   [ +  -  +  -  :         74 :                          ((uint32_t)g_data[10] << 8) + (uint32_t)g_data[11];
          +  -  +  -  +  
                -  +  - ]
     529   [ +  -  +  -  :         74 :         cmd->cmd.cdw13 = g_data[12];
          +  -  +  -  +  
                -  +  - ]
     530   [ +  -  +  -  :        222 :         cmd->cmd.cdw14 = ((uint32_t)g_data[13] << 24) + ((uint32_t)g_data[14] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     531   [ +  -  +  -  :         74 :                          ((uint32_t)g_data[15] << 8) + (uint32_t)g_data[16];
          +  -  +  -  +  
                -  +  - ]
     532   [ +  -  +  -  :        222 :         cmd->cmd.cdw15 = ((uint32_t)g_data[17] << 24) + ((uint32_t)g_data[18] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     533   [ +  -  +  -  :         74 :                          ((uint32_t)g_data[19] << 8) + (uint32_t)g_data[20];
          +  -  +  -  +  
                -  +  - ]
     534                 :            : 
     535         [ +  - ]:         74 :         g_data += 21;
     536                 :         74 : }
     537                 :            : 
     538                 :            : static void
     539                 :        102 : fuzz_nvm_write_command(struct fuzz_command *cmd)
     540                 :            : {
     541   [ +  -  +  - ]:        102 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     542   [ +  -  +  - ]:        102 :         cmd->cmd.opc = SPDK_NVME_OPC_WRITE;
     543                 :            : 
     544   [ +  -  +  -  :        306 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     545   [ +  -  +  -  :        102 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     546   [ +  -  +  -  :        306 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     547   [ +  -  +  -  :        102 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     548   [ +  -  +  -  :        306 :         cmd->cmd.cdw12 = ((uint32_t)g_data[8] << 24) + ((uint32_t)g_data[9] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     549   [ +  -  +  -  :        102 :                          ((uint32_t)g_data[10] << 8) + (uint32_t)g_data[11];
          +  -  +  -  +  
                -  +  - ]
     550   [ +  -  +  -  :        306 :         cmd->cmd.cdw13 = ((uint32_t)g_data[12] << 24) + ((uint32_t)g_data[13] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     551   [ +  -  +  -  :        102 :                          ((uint32_t)g_data[14] << 8) + (uint32_t)g_data[15];
          +  -  +  -  +  
                -  +  - ]
     552   [ +  -  +  -  :        306 :         cmd->cmd.cdw14 = ((uint32_t)g_data[16] << 24) + ((uint32_t)g_data[17] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     553   [ +  -  +  -  :        102 :                          ((uint32_t)g_data[18] << 8) + (uint32_t)g_data[19];
          +  -  +  -  +  
                -  +  - ]
     554   [ +  -  +  -  :        306 :         cmd->cmd.cdw15 = ((uint32_t)g_data[20] << 24) + ((uint32_t)g_data[21] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     555   [ +  -  +  -  :        102 :                          ((uint32_t)g_data[22] << 8) + (uint32_t)g_data[23];
          +  -  +  -  +  
                -  +  - ]
     556                 :            : 
     557         [ +  - ]:        102 :         g_data += 24;
     558                 :        102 : }
     559                 :            : 
     560                 :            : static void
     561                 :         98 : fuzz_nvm_write_zeroes_command(struct fuzz_command *cmd)
     562                 :            : {
     563   [ +  -  +  - ]:         98 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     564   [ +  -  +  - ]:         98 :         cmd->cmd.opc = SPDK_NVME_OPC_WRITE_ZEROES;
     565                 :            : 
     566   [ +  -  +  -  :        294 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     567   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     568   [ +  -  +  -  :        294 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     569   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     570   [ +  -  +  -  :        294 :         cmd->cmd.cdw12 = ((uint32_t)g_data[8] << 24) + ((uint32_t)g_data[9] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     571   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[10] << 8) + (uint32_t)g_data[11];
          +  -  +  -  +  
                -  +  - ]
     572   [ +  -  +  -  :        294 :         cmd->cmd.cdw14 = ((uint32_t)g_data[12] << 24) + ((uint32_t)g_data[13] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     573   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[14] << 8) + (uint32_t)g_data[15];
          +  -  +  -  +  
                -  +  - ]
     574   [ +  -  +  -  :        294 :         cmd->cmd.cdw15 = ((uint32_t)g_data[16] << 24) + ((uint32_t)g_data[17] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     575   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[18] << 8) + (uint32_t)g_data[19];
          +  -  +  -  +  
                -  +  - ]
     576                 :            : 
     577         [ +  - ]:         98 :         g_data += 20;
     578                 :         98 : }
     579                 :            : 
     580                 :            : static void
     581                 :        156 : fuzz_nvm_write_uncorrectable_command(struct fuzz_command *cmd)
     582                 :            : {
     583   [ +  -  +  - ]:        156 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     584   [ +  -  +  - ]:        156 :         cmd->cmd.opc = SPDK_NVME_OPC_WRITE_UNCORRECTABLE;
     585                 :            : 
     586   [ +  -  +  -  :        468 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     587   [ +  -  +  -  :        156 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     588   [ +  -  +  -  :        468 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     589   [ +  -  +  -  :        156 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     590   [ +  -  +  -  :        156 :         cmd->cmd.cdw12 = (g_data[8] << 8) + g_data[9];
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     591                 :            : 
     592         [ +  - ]:        156 :         g_data += 10;
     593                 :        156 : }
     594                 :            : 
     595                 :            : static void
     596                 :         75 : fuzz_nvm_reservation_acquire_command(struct fuzz_command *cmd)
     597                 :            : {
     598   [ +  -  +  - ]:         75 :         struct spdk_nvme_reservation_acquire_data *payload = cmd->buf;
     599   [ +  -  +  - ]:         75 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     600   [ +  -  +  - ]:         75 :         cmd->cmd.opc = SPDK_NVME_OPC_RESERVATION_ACQUIRE;
     601                 :            : 
     602   [ +  -  +  -  :         75 :         cmd->cmd.cdw10_bits.resv_acquire.rtype = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     603   [ +  -  +  -  :         75 :         cmd->cmd.cdw10_bits.resv_acquire.iekey = (g_data[1] >> 7) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     604   [ +  -  +  -  :         75 :         cmd->cmd.cdw10_bits.resv_acquire.racqa = (g_data[1] >> 4) & 0x07;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     605                 :            : 
     606   [ +  -  +  -  :        225 :         payload->crkey = ((uint64_t)g_data[2] << 56) + ((uint64_t)g_data[3] << 48) +
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     607   [ +  -  +  -  :        150 :                          ((uint64_t)g_data[4] << 40) + ((uint64_t)g_data[5] << 32) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     608   [ +  -  +  -  :        150 :                          ((uint64_t)g_data[6] << 24) + ((uint64_t)g_data[7] << 16) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     609   [ +  -  +  -  :         75 :                          ((uint64_t)g_data[8] << 8) + (uint64_t)g_data[9];
          +  -  +  -  +  
                -  +  - ]
     610                 :            : 
     611   [ +  -  +  -  :        225 :         payload->prkey = ((uint64_t)g_data[10] << 56) + ((uint64_t)g_data[11] << 48) +
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     612   [ +  -  +  -  :        150 :                          ((uint64_t)g_data[12] << 40) + ((uint64_t)g_data[13] << 32) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     613   [ +  -  +  -  :        150 :                          ((uint64_t)g_data[14] << 24) + ((uint64_t)g_data[15] << 16) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     614   [ +  -  +  -  :         75 :                          ((uint64_t)g_data[16] << 8) + (uint64_t)g_data[17];
          +  -  +  -  +  
                -  +  - ]
     615                 :            : 
     616   [ +  -  +  - ]:         75 :         cmd->len = sizeof(struct spdk_nvme_reservation_acquire_data);
     617                 :            : 
     618         [ +  - ]:         75 :         g_data += 18;
     619                 :         75 : }
     620                 :            : 
     621                 :            : static void
     622                 :         81 : fuzz_nvm_reservation_release_command(struct fuzz_command *cmd)
     623                 :            : {
     624   [ +  -  +  - ]:         81 :         struct spdk_nvme_reservation_key_data *payload = cmd->buf;
     625   [ +  -  +  - ]:         81 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     626   [ +  -  +  - ]:         81 :         cmd->cmd.opc = SPDK_NVME_OPC_RESERVATION_RELEASE;
     627                 :            : 
     628   [ +  -  +  -  :         81 :         cmd->cmd.cdw10_bits.resv_release.rtype = g_data[0];
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     629   [ +  -  +  -  :         81 :         cmd->cmd.cdw10_bits.resv_release.iekey = (g_data[1] >> 7) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     630   [ +  -  +  -  :         81 :         cmd->cmd.cdw10_bits.resv_release.rrela = (g_data[1] >> 4) & 0x07;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     631                 :            : 
     632   [ +  -  +  -  :        243 :         payload->crkey = ((uint64_t)g_data[2] << 56) + ((uint64_t)g_data[3] << 48) +
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     633   [ +  -  +  -  :        162 :                          ((uint64_t)g_data[4] << 40) + ((uint64_t)g_data[5] << 32) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     634   [ +  -  +  -  :        162 :                          ((uint64_t)g_data[6] << 24) + ((uint64_t)g_data[7] << 16) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     635   [ +  -  +  -  :         81 :                          ((uint64_t)g_data[8] << 8) + (uint64_t)g_data[9];
          +  -  +  -  +  
                -  +  - ]
     636                 :            : 
     637   [ +  -  +  - ]:         81 :         cmd->len = sizeof(struct spdk_nvme_reservation_key_data);
     638                 :            : 
     639         [ +  - ]:         81 :         g_data += 10;
     640                 :         81 : }
     641                 :            : 
     642                 :            : static void
     643                 :         58 : fuzz_nvm_reservation_register_command(struct fuzz_command *cmd)
     644                 :            : {
     645   [ +  -  +  - ]:         58 :         struct spdk_nvme_reservation_register_data *payload = cmd->buf;
     646   [ +  -  +  - ]:         58 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     647   [ +  -  +  - ]:         58 :         cmd->cmd.opc = SPDK_NVME_OPC_RESERVATION_REGISTER;
     648                 :            : 
     649   [ +  -  +  -  :         58 :         cmd->cmd.cdw10_bits.resv_register.cptpl = (g_data[0] >> 6) & 0x03;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     650   [ +  -  +  -  :         58 :         cmd->cmd.cdw10_bits.resv_register.iekey = (g_data[0] >> 5) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     651   [ +  -  +  -  :         58 :         cmd->cmd.cdw10_bits.resv_register.rrega = (g_data[0] >> 2) & 0x07;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     652                 :            : 
     653   [ +  -  +  -  :        174 :         payload->crkey = ((uint64_t)g_data[1] << 56) + ((uint64_t)g_data[2] << 48) +
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     654   [ +  -  +  -  :        116 :                          ((uint64_t)g_data[3] << 40) + ((uint64_t)g_data[4] << 32) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     655   [ +  -  +  -  :        116 :                          ((uint64_t)g_data[5] << 24) + ((uint64_t)g_data[6] << 16) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     656   [ +  -  +  -  :         58 :                          ((uint64_t)g_data[7] << 8) + (uint64_t)g_data[8];
          +  -  +  -  +  
                -  +  - ]
     657                 :            : 
     658   [ +  -  +  -  :        174 :         payload->nrkey = ((uint64_t)g_data[9] << 56) + ((uint64_t)g_data[10] << 48) +
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     659   [ +  -  +  -  :        116 :                          ((uint64_t)g_data[11] << 40) + ((uint64_t)g_data[12] << 32) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     660   [ +  -  +  -  :        116 :                          ((uint64_t)g_data[13] << 24) + ((uint64_t)g_data[14] << 16) +
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     661   [ +  -  +  -  :         58 :                          ((uint64_t)g_data[15] << 8) + (uint64_t)g_data[16];
          +  -  +  -  +  
                -  +  - ]
     662                 :            : 
     663                 :            : 
     664   [ +  -  +  - ]:         58 :         cmd->len = sizeof(struct spdk_nvme_reservation_register_data);
     665                 :            : 
     666         [ +  - ]:         58 :         g_data += 17;
     667                 :         58 : }
     668                 :            : 
     669                 :            : static void
     670                 :         69 : fuzz_nvm_reservation_report_command(struct fuzz_command *cmd)
     671                 :            : {
     672   [ +  -  +  - ]:         69 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     673   [ +  -  +  - ]:         69 :         cmd->cmd.opc = SPDK_NVME_OPC_RESERVATION_REPORT;
     674                 :            : 
     675   [ +  -  +  -  :        207 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     676   [ +  -  +  -  :         69 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     677                 :            : 
     678   [ +  -  +  -  :         69 :         cmd->cmd.cdw11_bits.resv_report.eds = (g_data[4] >> 7) & 0x01;
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     679                 :            : 
     680         [ +  - ]:         69 :         g_data += 5;
     681                 :         69 : }
     682                 :            : 
     683                 :            : static void
     684                 :         98 : fuzz_nvm_compare_command(struct fuzz_command *cmd)
     685                 :            : {
     686   [ +  -  +  - ]:         98 :         memset(&cmd->cmd, 0, sizeof(cmd->cmd));
     687   [ +  -  +  - ]:         98 :         cmd->cmd.opc = SPDK_NVME_OPC_COMPARE;
     688                 :            : 
     689   [ +  -  +  -  :        294 :         cmd->cmd.cdw10 = ((uint32_t)g_data[0] << 24) + ((uint32_t)g_data[1] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     690   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[2] << 8) + (uint32_t)g_data[3];
          +  -  +  -  +  
                -  +  - ]
     691   [ +  -  +  -  :        294 :         cmd->cmd.cdw11 = ((uint32_t)g_data[4] << 24) + ((uint32_t)g_data[5] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     692   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[6] << 8) + (uint32_t)g_data[7];
          +  -  +  -  +  
                -  +  - ]
     693   [ +  -  +  -  :        294 :         cmd->cmd.cdw12 = ((uint32_t)g_data[8] << 24) + ((uint32_t)g_data[9] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                      - ]
     694   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[10] << 8) + (uint32_t)g_data[11];
          +  -  +  -  +  
                -  +  - ]
     695   [ +  -  +  -  :        294 :         cmd->cmd.cdw14 = ((uint32_t)g_data[12] << 24) + ((uint32_t)g_data[13] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     696   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[14] << 8) + (uint32_t)g_data[15];
          +  -  +  -  +  
                -  +  - ]
     697   [ +  -  +  -  :        294 :         cmd->cmd.cdw15 = ((uint32_t)g_data[16] << 24) + ((uint32_t)g_data[17] << 16) +
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     698   [ +  -  +  -  :         98 :                          ((uint32_t)g_data[18] << 8) + (uint32_t)g_data[19];
          +  -  +  -  +  
                -  +  - ]
     699                 :            : 
     700         [ +  - ]:         98 :         g_data += 20;
     701                 :         98 : }
     702                 :            : 
     703                 :            : static struct fuzz_type g_fuzzers[] = {
     704                 :            :         { .fn = fuzz_admin_command, .bytes_per_cmd = sizeof(struct spdk_nvme_cmd), .is_admin = true},
     705                 :            :         { .fn = fuzz_admin_get_log_page_command, .bytes_per_cmd = 6, .is_admin = true},
     706                 :            :         { .fn = fuzz_admin_identify_command, .bytes_per_cmd = 7, .is_admin = true},
     707                 :            :         { .fn = fuzz_admin_abort_command, .bytes_per_cmd = 4, .is_admin = true},
     708                 :            :         { .fn = fuzz_admin_create_io_completion_queue_command, .bytes_per_cmd = 7, .is_admin = true},
     709                 :            :         { .fn = fuzz_admin_create_io_submission_queue_command, .bytes_per_cmd = 9, .is_admin = true},
     710                 :            :         { .fn = fuzz_admin_delete_io_completion_queue_command, .bytes_per_cmd = 2, .is_admin = true},
     711                 :            :         { .fn = fuzz_admin_delete_io_submission_queue_command, .bytes_per_cmd = 2, .is_admin = true},
     712                 :            :         { .fn = fuzz_admin_namespace_attachment_command, .bytes_per_cmd = 1, .is_admin = true},
     713                 :            :         { .fn = fuzz_admin_namespace_management_command, .bytes_per_cmd = 1, .is_admin = true},
     714                 :            :         { .fn = fuzz_admin_security_receive_command, .bytes_per_cmd = 8, .is_admin = true},
     715                 :            :         { .fn = fuzz_admin_security_send_command, .bytes_per_cmd = 8, .is_admin = true},
     716                 :            :         { .fn = fuzz_admin_directive_send_command, .bytes_per_cmd = 8, .is_admin = true},
     717                 :            :         { .fn = fuzz_admin_directive_receive_command, .bytes_per_cmd = 8, .is_admin = true},
     718                 :            :         { .fn = fuzz_admin_set_features_command, .bytes_per_cmd = 7, .is_admin = true},
     719                 :            :         { .fn = fuzz_admin_get_features_command, .bytes_per_cmd = 7, .is_admin = true},
     720                 :            :         { .fn = fuzz_nvm_read_command, .bytes_per_cmd = 21, .is_admin = false},
     721                 :            :         { .fn = fuzz_nvm_write_command, .bytes_per_cmd = 24, .is_admin = false},
     722                 :            :         { .fn = fuzz_nvm_write_zeroes_command, .bytes_per_cmd = 20, .is_admin = false},
     723                 :            :         { .fn = fuzz_nvm_write_uncorrectable_command, .bytes_per_cmd = 10, .is_admin = false},
     724                 :            :         { .fn = fuzz_nvm_reservation_acquire_command, .bytes_per_cmd = 18, .is_admin = false},
     725                 :            :         { .fn = fuzz_nvm_reservation_release_command, .bytes_per_cmd = 10, .is_admin = false},
     726                 :            :         { .fn = fuzz_nvm_reservation_register_command, .bytes_per_cmd = 17, .is_admin = false},
     727                 :            :         { .fn = fuzz_nvm_reservation_report_command, .bytes_per_cmd = 5, .is_admin = false},
     728                 :            :         { .fn = fuzz_nvm_compare_command, .bytes_per_cmd = 20, .is_admin = false},
     729                 :            :         { .fn = NULL, .bytes_per_cmd = 0, .is_admin = 0}
     730                 :            : };
     731                 :            : 
     732                 :            : #define NUM_FUZZERS (SPDK_COUNTOF(g_fuzzers) - 1)
     733                 :            : 
     734                 :            : static struct fuzz_type *g_fuzzer;
     735                 :            : 
     736                 :            : struct spdk_nvme_transport_id g_trid;
     737                 :            : static struct spdk_nvme_ctrlr *g_ctrlr;
     738                 :            : static struct spdk_nvme_qpair *g_io_qpair;
     739                 :            : static void
     740                 :       2192 : nvme_fuzz_cpl_cb(void *cb_arg, const struct spdk_nvme_cpl *cpl)
     741                 :            : {
     742                 :       2192 :         int *outstanding = cb_arg;
     743                 :            : 
     744   [ +  -  +  -  :       2192 :         assert(*outstanding > 0);
                   #  # ]
     745         [ +  - ]:       2192 :         (*outstanding)--;
     746                 :       2192 : }
     747                 :            : 
     748                 :            : static int
     749                 :        788 : run_cmds(uint32_t queue_depth)
     750                 :            : {
     751                 :        788 :         int rc, outstanding = 0;
     752                 :            :         uint32_t i;
     753                 :            : 
     754         [ +  + ]:       2980 :         for (i = 0; i < queue_depth; i++) {
     755   [ +  -  +  - ]:       2192 :                 struct fuzz_command *cmd = &g_cmds[i];
     756                 :            : 
     757   [ +  -  +  -  :       2192 :                 g_fuzzer->fn(cmd);
             -  +  -  + ]
     758         [ +  - ]:       2192 :                 outstanding++;
     759   [ +  -  +  -  :       2192 :                 if (g_fuzzer->is_admin) {
             +  -  +  + ]
     760   [ -  +  -  +  :       1381 :                         rc = spdk_nvme_ctrlr_cmd_admin_raw(g_ctrlr, &cmd->cmd, cmd->buf, cmd->len, nvme_fuzz_cpl_cb,
          -  +  -  +  -  
                      + ]
     761                 :            :                                                            &outstanding);
     762                 :       1381 :                 } else {
     763   [ -  +  -  +  :        811 :                         rc = spdk_nvme_ctrlr_cmd_io_raw(g_ctrlr, g_io_qpair, &cmd->cmd, cmd->buf, cmd->len,
          -  +  -  +  -  
                      + ]
     764                 :            :                                                         nvme_fuzz_cpl_cb, &outstanding);
     765                 :            :                 }
     766         [ -  + ]:       2192 :                 if (rc) {
     767                 :          0 :                         return rc;
     768                 :            :                 }
     769                 :       2192 :         }
     770                 :            : 
     771         [ +  + ]:      12572 :         while (outstanding > 0) {
     772                 :      11784 :                 spdk_nvme_qpair_process_completions(g_io_qpair, 0);
     773                 :      11784 :                 spdk_nvme_ctrlr_process_admin_completions(g_ctrlr);
     774                 :            :         }
     775                 :        788 :         return 0;
     776                 :        788 : }
     777                 :            : 
     778                 :            : static int
     779                 :       1359 : TestOneInput(const uint8_t *data, size_t size)
     780                 :            : {
     781                 :       1359 :         int ret = 0;
     782                 :       1359 :         struct spdk_nvme_detach_ctx *detach_ctx = NULL;
     783                 :            : 
     784   [ +  -  +  -  :       1359 :         if (size < g_fuzzer->bytes_per_cmd) {
                   +  + ]
     785                 :        571 :                 return -1;
     786                 :            :         }
     787                 :            : 
     788                 :        788 :         g_ctrlr = spdk_nvme_connect(&g_trid, NULL, 0);
     789         [ +  - ]:        788 :         if (g_ctrlr == NULL) {
     790                 :          0 :                 fprintf(stderr, "spdk_nvme_connect() failed for transport address '%s'\n",
     791                 :            :                         g_trid.traddr);
     792                 :          0 :                 spdk_app_stop(-1);
     793                 :          0 :                 return -1;
     794                 :            :         }
     795                 :            : 
     796                 :        788 :         g_io_qpair = spdk_nvme_ctrlr_alloc_io_qpair(g_ctrlr, NULL, 0);
     797         [ +  - ]:        788 :         if (g_io_qpair == NULL) {
     798                 :          0 :                 fprintf(stderr, "spdk_nvme_ctrlr_alloc_io_qpair failed\n");
     799                 :          0 :                 ret = -1;
     800                 :          0 :                 goto detach_ctrlr;
     801                 :            :         }
     802                 :            : 
     803                 :        788 :         g_data = data;
     804                 :            : 
     805   [ +  -  +  -  :        788 :         run_cmds(size / g_fuzzer->bytes_per_cmd);
                   +  - ]
     806                 :        788 :         spdk_nvme_ctrlr_free_io_qpair(g_io_qpair);
     807                 :            : detach_ctrlr:
     808                 :        788 :         spdk_nvme_detach_async(g_ctrlr, &detach_ctx);
     809                 :            : 
     810         [ +  - ]:        788 :         if (detach_ctx) {
     811                 :        788 :                 spdk_nvme_detach_poll(detach_ctx);
     812                 :        788 :         }
     813         [ +  - ]:        788 :         if (ret < 0) {
     814                 :          0 :                 spdk_app_stop(ret);
     815                 :          0 :         }
     816                 :            : 
     817                 :        788 :         return ret;
     818                 :       1359 : }
     819                 :            : 
     820                 :            : int LLVMFuzzerRunDriver(int *argc, char ***argv, int (*UserCb)(const uint8_t *Data, size_t Size));
     821                 :            : 
     822                 :            : static void
     823                 :         25 : exit_handler(void)
     824                 :            : {
     825   [ +  -  -  + ]:         25 :         if (g_in_fuzzer) {
     826                 :         25 :                 spdk_app_stop(0);
     827                 :         25 :                 pthread_join(g_reactor_td, NULL);
     828                 :         25 :         }
     829                 :         25 : }
     830                 :            : 
     831                 :            : static void *
     832                 :         25 : start_fuzzer(void *ctx)
     833                 :            : {
     834                 :         25 :         char *_argv[] = {
     835                 :            :                 "spdk",
     836                 :            :                 "-len_control=0",
     837                 :            :                 "-detect_leaks=1",
     838                 :            :                 NULL,
     839                 :            :                 NULL,
     840                 :            :                 NULL,
     841                 :            :                 NULL
     842                 :            :         };
     843                 :            :         char time_str[128];
     844                 :            :         char prefix[PATH_MAX];
     845                 :            :         char len_str[128];
     846                 :         25 :         char **argv = _argv;
     847                 :         25 :         int argc = SPDK_COUNTOF(_argv);
     848                 :            :         uint32_t len;
     849                 :            :         int rc;
     850                 :            : 
     851                 :         25 :         spdk_unaffinitize_thread();
     852                 :         25 :         snprintf(prefix, sizeof(prefix), "-artifact_prefix=%s", g_artifact_prefix);
     853   [ +  -  +  -  :         25 :         argv[argc - 4] = prefix;
                   +  - ]
     854   [ +  -  +  - ]:         25 :         len = MAX_COMMANDS * g_fuzzer->bytes_per_cmd;
     855                 :         25 :         snprintf(len_str, sizeof(len_str), "-max_len=%d", len);
     856   [ +  -  +  -  :         25 :         argv[argc - 3] = len_str;
                   +  - ]
     857                 :         25 :         snprintf(time_str, sizeof(time_str), "-max_total_time=%d", g_time_in_sec);
     858   [ +  -  +  -  :         25 :         argv[argc - 2] = time_str;
                   +  - ]
     859   [ +  -  +  -  :         25 :         argv[argc - 1] = g_corpus_dir;
                   +  - ]
     860                 :            : 
     861                 :         25 :         g_in_fuzzer = true;
     862         [ +  - ]:         25 :         atexit(exit_handler);
     863                 :            : 
     864                 :         25 :         free(g_artifact_prefix);
     865                 :            : 
     866         [ -  + ]:         25 :         if (g_repro_data) {
     867                 :          0 :                 printf("Running single test based on reproduction data file.\n");
     868                 :          0 :                 rc = TestOneInput(g_repro_data, g_repro_size);
     869                 :          0 :                 printf("Done.\n");
     870                 :          0 :         } else {
     871                 :         25 :                 rc = LLVMFuzzerRunDriver(&argc, &argv, TestOneInput);
     872                 :            :                 /* TODO: in the normal case, LLVMFuzzerRunDriver never returns - it calls exit()
     873                 :            :                  * directly and we never get here.  But this behavior isn't really documented
     874                 :            :                  * anywhere by LLVM, so call spdk_app_stop(0) if it does return, which will
     875                 :            :                  * result in the app exiting like a normal SPDK application (spdk_app_start()
     876                 :            :                  * returns to main().
     877                 :            :                  */
     878                 :            :         }
     879                 :         25 :         g_in_fuzzer = false;
     880                 :         25 :         spdk_app_stop(rc);
     881                 :            : 
     882                 :         25 :         return NULL;
     883                 :            : }
     884                 :            : 
     885                 :            : static void
     886                 :         25 : begin_fuzz(void *ctx)
     887                 :            : {
     888                 :            :         int i;
     889                 :            : 
     890                 :         25 :         g_reactor_td = pthread_self();
     891                 :            : 
     892   [ +  +  +  - ]:        150 :         for (i = 0; i < MAX_COMMANDS; i++) {
     893   [ +  -  +  -  :        125 :                 g_cmds[i].buf = spdk_malloc(4096, 0, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
             +  -  +  - ]
     894   [ +  -  +  -  :        125 :                 assert(g_cmds[i].buf);
          +  -  +  -  +  
                -  #  # ]
     895   [ +  -  +  -  :        125 :                 g_cmds[i].len = 4096;
             +  -  +  - ]
     896                 :        125 :         }
     897                 :            : 
     898   [ +  -  +  - ]:         25 :         pthread_create(&g_fuzz_td, NULL, start_fuzzer, NULL);
     899                 :         25 : }
     900                 :            : 
     901                 :            : static void
     902                 :          0 : nvme_fuzz_usage(void)
     903                 :            : {
     904                 :          0 :         fprintf(stderr, " -D                        Path of corpus directory.\n");
     905                 :          0 :         fprintf(stderr, " -F                        Transport ID for subsystem that should be fuzzed.\n");
     906                 :          0 :         fprintf(stderr, " -N                        Name of reproduction data file.\n");
     907                 :          0 :         fprintf(stderr, " -P                        Provide a prefix to use when saving artifacts.\n");
     908                 :          0 :         fprintf(stderr, " -t                        Time to run fuzz tests (in seconds). Default: 10\n");
     909                 :          0 :         fprintf(stderr, " -Z                        Fuzzer to run (0 to %lu)\n", NUM_FUZZERS - 1);
     910                 :          0 : }
     911                 :            : 
     912                 :            : static int
     913                 :        125 : nvme_fuzz_parse(int ch, char *arg)
     914                 :            : {
     915                 :            :         long long tmp;
     916                 :            :         int rc;
     917                 :            : 
     918   [ +  -  +  +  :        125 :         switch (ch) {
                -  +  - ]
     919                 :            :         case 'D':
     920         [ +  - ]:         25 :                 g_corpus_dir = strdup(optarg);
     921                 :         25 :                 break;
     922                 :            :         case 'F':
     923   [ +  -  -  + ]:         25 :                 if (g_trid_specified) {
     924                 :          0 :                         fprintf(stderr, "Can only specify one trid\n");
     925                 :          0 :                         return -1;
     926                 :            :                 }
     927                 :         25 :                 g_trid_specified = true;
     928                 :         25 :                 rc = spdk_nvme_transport_id_parse(&g_trid, optarg);
     929         [ +  - ]:         25 :                 if (rc < 0) {
     930                 :          0 :                         fprintf(stderr, "failed to parse transport ID: %s\n", optarg);
     931                 :          0 :                         return -1;
     932                 :            :                 }
     933                 :         25 :                 break;
     934                 :            :         case 'N':
     935                 :          0 :                 g_repro_data = spdk_posix_file_load_from_name(optarg, &g_repro_size);
     936         [ #  # ]:          0 :                 if (g_repro_data == NULL) {
     937                 :          0 :                         fprintf(stderr, "could not load data for file %s\n", optarg);
     938                 :          0 :                         return -1;
     939                 :            :                 }
     940                 :          0 :                 break;
     941                 :            :         case 'P':
     942         [ +  - ]:         25 :                 g_artifact_prefix = strdup(optarg);
     943         [ +  - ]:         25 :                 if (!g_artifact_prefix) {
     944                 :          0 :                         fprintf(stderr, "cannot strdup: %s\n", optarg);
     945                 :          0 :                         return -ENOMEM;
     946                 :            :                 }
     947                 :         25 :                 break;
     948                 :            :         case 't':
     949                 :            :         case 'Z':
     950                 :         50 :                 tmp = spdk_strtoll(optarg, 10);
     951   [ +  -  -  + ]:         50 :                 if (tmp < 0 || tmp >= INT_MAX) {
     952                 :          0 :                         fprintf(stderr, "Invalid value '%s' for option -%c.\n", optarg, ch);
     953                 :          0 :                         return -EINVAL;
     954                 :            :                 }
     955      [ -  +  + ]:         50 :                 switch (ch) {
     956                 :            :                 case 't':
     957                 :         25 :                         g_time_in_sec = tmp;
     958                 :         25 :                         break;
     959                 :            :                 case 'Z':
     960         [ -  + ]:         25 :                         if ((unsigned long)tmp >= NUM_FUZZERS) {
     961                 :          0 :                                 fprintf(stderr, "Invalid fuzz type %lld (max %lu)\n", tmp, NUM_FUZZERS - 1);
     962                 :          0 :                                 return -EINVAL;
     963                 :            :                         }
     964   [ -  +  -  + ]:         25 :                         g_fuzzer = &g_fuzzers[tmp];
     965                 :         25 :                         break;
     966                 :            :                 }
     967                 :         50 :                 break;
     968                 :          0 :         case '?':
     969                 :            :         default:
     970                 :          0 :                 return -EINVAL;
     971                 :            :         }
     972                 :        125 :         return 0;
     973                 :        125 : }
     974                 :            : 
     975                 :            : static void
     976                 :          0 : fuzz_shutdown(void)
     977                 :            : {
     978                 :            :         /* If the user terminates the fuzzer prematurely, it is likely due
     979                 :            :          * to an input hang.  So raise a SIGSEGV signal which will cause the
     980                 :            :          * fuzzer to generate a crash file for the last input.
     981                 :            :          *
     982                 :            :          * Note that the fuzzer will always generate a crash file, even if
     983                 :            :          * we get our TestOneInput() function (which is called by the fuzzer)
     984                 :            :          * to pthread_exit().  So just doing the SIGSEGV here in all cases is
     985                 :            :          * simpler than trying to differentiate between hung inputs and
     986                 :            :          * an impatient user.
     987                 :            :          */
     988                 :          0 :         pthread_kill(g_fuzz_td, SIGSEGV);
     989                 :          0 : }
     990                 :            : 
     991                 :            : int
     992                 :         25 : main(int argc, char **argv)
     993                 :            : {
     994                 :         25 :         struct spdk_app_opts opts = {};
     995                 :            :         int rc;
     996                 :            : 
     997                 :         25 :         spdk_app_opts_init(&opts, sizeof(opts));
     998                 :         25 :         opts.name = "nvme_fuzz";
     999                 :         25 :         opts.shutdown_cb = fuzz_shutdown;
    1000                 :         25 :         opts.rpc_addr = NULL;
    1001                 :            : 
    1002   [ -  +  -  + ]:         50 :         if ((rc = spdk_app_parse_args(argc, argv, &opts, "D:F:N:P:t:Z:", NULL, nvme_fuzz_parse,
    1003                 :         25 :                                       nvme_fuzz_usage) != SPDK_APP_PARSE_ARGS_SUCCESS)) {
    1004                 :          0 :                 return rc;
    1005                 :            :         }
    1006                 :            : 
    1007         [ +  - ]:         25 :         if (!g_corpus_dir) {
    1008                 :          0 :                 fprintf(stderr, "Must specify corpus dir with -D option\n");
    1009                 :          0 :                 return -1;
    1010                 :            :         }
    1011                 :            : 
    1012   [ -  +  +  - ]:         25 :         if (!g_trid_specified) {
    1013                 :          0 :                 fprintf(stderr, "Must specify trid with -F option\n");
    1014                 :          0 :                 return -1;
    1015                 :            :         }
    1016                 :            : 
    1017         [ +  - ]:         25 :         if (!g_fuzzer) {
    1018                 :          0 :                 fprintf(stderr, "Must specify fuzzer with -Z option\n");
    1019                 :          0 :                 return -1;
    1020                 :            :         }
    1021                 :            : 
    1022                 :         25 :         rc = spdk_app_start(&opts, begin_fuzz, NULL);
    1023                 :            : 
    1024                 :         25 :         spdk_app_fini();
    1025                 :         25 :         return rc;
    1026                 :         25 : }

Generated by: LCOV version 1.15