cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

vmw_pvscsi.h (14567B)


      1/*
      2 * VMware PVSCSI header file
      3 *
      4 * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
      5 *
      6 * This program is free software; you can redistribute it and/or modify it
      7 * under the terms of the GNU General Public License as published by the
      8 * Free Software Foundation; version 2 of the License and no later version.
      9 *
     10 * This program is distributed in the hope that it will be useful, but
     11 * WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
     13 * NON INFRINGEMENT.  See the GNU General Public License for more
     14 * details.
     15 *
     16 * You should have received a copy of the GNU General Public License
     17 * along with this program; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     19 *
     20 * Maintained by: Arvind Kumar <arvindkumar@vmware.com>
     21 *
     22 */
     23
     24#ifndef VMW_PVSCSI_H
     25#define VMW_PVSCSI_H
     26
     27#define VMW_PAGE_SIZE  (4096)
     28#define VMW_PAGE_SHIFT (12)
     29
     30#define MASK(n)        ((1 << (n)) - 1)        /* make an n-bit mask */
     31
     32/*
     33 * host adapter status/error codes
     34 */
     35enum HostBusAdapterStatus {
     36   BTSTAT_SUCCESS       = 0x00,  /* CCB complete normally with no errors */
     37   BTSTAT_LINKED_COMMAND_COMPLETED           = 0x0a,
     38   BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b,
     39   BTSTAT_DATA_UNDERRUN = 0x0c,
     40   BTSTAT_SELTIMEO      = 0x11,  /* SCSI selection timeout */
     41   BTSTAT_DATARUN       = 0x12,  /* data overrun/underrun */
     42   BTSTAT_BUSFREE       = 0x13,  /* unexpected bus free */
     43   BTSTAT_INVPHASE      = 0x14,  /* invalid bus phase or sequence */
     44                                 /* requested by target           */
     45   BTSTAT_LUNMISMATCH   = 0x17,  /* linked CCB has different LUN  */
     46                                 /* from first CCB                */
     47   BTSTAT_SENSFAILED    = 0x1b,  /* auto request sense failed */
     48   BTSTAT_TAGREJECT     = 0x1c,  /* SCSI II tagged queueing message */
     49                                 /* rejected by target              */
     50   BTSTAT_BADMSG        = 0x1d,  /* unsupported message received by */
     51                                 /* the host adapter                */
     52   BTSTAT_HAHARDWARE    = 0x20,  /* host adapter hardware failed */
     53   BTSTAT_NORESPONSE    = 0x21,  /* target did not respond to SCSI ATN, */
     54                                 /* sent a SCSI RST                     */
     55   BTSTAT_SENTRST       = 0x22,  /* host adapter asserted a SCSI RST */
     56   BTSTAT_RECVRST       = 0x23,  /* other SCSI devices asserted a SCSI RST */
     57   BTSTAT_DISCONNECT    = 0x24,  /* target device reconnected improperly */
     58                                 /* (w/o tag)                            */
     59   BTSTAT_BUSRESET      = 0x25,  /* host adapter issued BUS device reset */
     60   BTSTAT_ABORTQUEUE    = 0x26,  /* abort queue generated */
     61   BTSTAT_HASOFTWARE    = 0x27,  /* host adapter software error */
     62   BTSTAT_HATIMEOUT     = 0x30,  /* host adapter hardware timeout error */
     63   BTSTAT_SCSIPARITY    = 0x34,  /* SCSI parity error detected */
     64};
     65
     66/*
     67 * Register offsets.
     68 *
     69 * These registers are accessible both via i/o space and mm i/o.
     70 */
     71
     72enum PVSCSIRegOffset {
     73    PVSCSI_REG_OFFSET_COMMAND        =    0x0,
     74    PVSCSI_REG_OFFSET_COMMAND_DATA   =    0x4,
     75    PVSCSI_REG_OFFSET_COMMAND_STATUS =    0x8,
     76    PVSCSI_REG_OFFSET_LAST_STS_0     =  0x100,
     77    PVSCSI_REG_OFFSET_LAST_STS_1     =  0x104,
     78    PVSCSI_REG_OFFSET_LAST_STS_2     =  0x108,
     79    PVSCSI_REG_OFFSET_LAST_STS_3     =  0x10c,
     80    PVSCSI_REG_OFFSET_INTR_STATUS    = 0x100c,
     81    PVSCSI_REG_OFFSET_INTR_MASK      = 0x2010,
     82    PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014,
     83    PVSCSI_REG_OFFSET_DEBUG          = 0x3018,
     84    PVSCSI_REG_OFFSET_KICK_RW_IO     = 0x4018,
     85};
     86
     87/*
     88 * Virtual h/w commands.
     89 */
     90
     91enum PVSCSICommands {
     92    PVSCSI_CMD_FIRST             = 0, /* has to be first */
     93
     94    PVSCSI_CMD_ADAPTER_RESET     = 1,
     95    PVSCSI_CMD_ISSUE_SCSI        = 2,
     96    PVSCSI_CMD_SETUP_RINGS       = 3,
     97    PVSCSI_CMD_RESET_BUS         = 4,
     98    PVSCSI_CMD_RESET_DEVICE      = 5,
     99    PVSCSI_CMD_ABORT_CMD         = 6,
    100    PVSCSI_CMD_CONFIG            = 7,
    101    PVSCSI_CMD_SETUP_MSG_RING    = 8,
    102    PVSCSI_CMD_DEVICE_UNPLUG     = 9,
    103
    104    PVSCSI_CMD_LAST              = 10  /* has to be last */
    105};
    106
    107#define PVSCSI_COMMAND_PROCESSING_SUCCEEDED   (0)
    108#define PVSCSI_COMMAND_PROCESSING_FAILED     (-1)
    109#define PVSCSI_COMMAND_NOT_ENOUGH_DATA       (-2)
    110
    111/*
    112 * Command descriptor for PVSCSI_CMD_RESET_DEVICE --
    113 */
    114
    115struct PVSCSICmdDescResetDevice {
    116    uint32_t    target;
    117    uint8_t     lun[8];
    118} QEMU_PACKED;
    119
    120typedef struct PVSCSICmdDescResetDevice PVSCSICmdDescResetDevice;
    121
    122/*
    123 * Command descriptor for PVSCSI_CMD_ABORT_CMD --
    124 *
    125 * - currently does not support specifying the LUN.
    126 * - pad should be 0.
    127 */
    128
    129struct PVSCSICmdDescAbortCmd {
    130    uint64_t    context;
    131    uint32_t    target;
    132    uint32_t    pad;
    133} QEMU_PACKED;
    134
    135typedef struct PVSCSICmdDescAbortCmd PVSCSICmdDescAbortCmd;
    136
    137/*
    138 * Command descriptor for PVSCSI_CMD_SETUP_RINGS --
    139 *
    140 * Notes:
    141 * - reqRingNumPages and cmpRingNumPages need to be power of two.
    142 * - reqRingNumPages and cmpRingNumPages need to be different from 0,
    143 * - reqRingNumPages and cmpRingNumPages need to be inferior to
    144 *   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES.
    145 */
    146
    147#define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES        32
    148struct PVSCSICmdDescSetupRings {
    149    uint32_t    reqRingNumPages;
    150    uint32_t    cmpRingNumPages;
    151    uint64_t    ringsStatePPN;
    152    uint64_t    reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
    153    uint64_t    cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
    154} QEMU_PACKED;
    155
    156typedef struct PVSCSICmdDescSetupRings PVSCSICmdDescSetupRings;
    157
    158/*
    159 * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING --
    160 *
    161 * Notes:
    162 * - this command was not supported in the initial revision of the h/w
    163 *   interface. Before using it, you need to check that it is supported by
    164 *   writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then
    165 *   immediately after read the 'command status' register:
    166 *       * a value of -1 means that the cmd is NOT supported,
    167 *       * a value != -1 means that the cmd IS supported.
    168 *   If it's supported the 'command status' register should return:
    169 *      sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t).
    170 * - this command should be issued _after_ the usual SETUP_RINGS so that the
    171 *   RingsState page is already setup. If not, the command is a nop.
    172 * - numPages needs to be a power of two,
    173 * - numPages needs to be different from 0,
    174 * - pad should be zero.
    175 */
    176
    177#define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES  16
    178
    179struct PVSCSICmdDescSetupMsgRing {
    180    uint32_t    numPages;
    181    uint32_t    pad;
    182    uint64_t    ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
    183} QEMU_PACKED;
    184
    185typedef struct PVSCSICmdDescSetupMsgRing PVSCSICmdDescSetupMsgRing;
    186
    187enum PVSCSIMsgType {
    188    PVSCSI_MSG_DEV_ADDED          = 0,
    189    PVSCSI_MSG_DEV_REMOVED        = 1,
    190    PVSCSI_MSG_LAST               = 2,
    191};
    192
    193/*
    194 * Msg descriptor.
    195 *
    196 * sizeof(struct PVSCSIRingMsgDesc) == 128.
    197 *
    198 * - type is of type enum PVSCSIMsgType.
    199 * - the content of args depend on the type of event being delivered.
    200 */
    201
    202struct PVSCSIRingMsgDesc {
    203    uint32_t    type;
    204    uint32_t    args[31];
    205} QEMU_PACKED;
    206
    207typedef struct PVSCSIRingMsgDesc PVSCSIRingMsgDesc;
    208
    209struct PVSCSIMsgDescDevStatusChanged {
    210    uint32_t    type;  /* PVSCSI_MSG_DEV _ADDED / _REMOVED */
    211    uint32_t    bus;
    212    uint32_t    target;
    213    uint8_t     lun[8];
    214    uint32_t    pad[27];
    215} QEMU_PACKED;
    216
    217typedef struct PVSCSIMsgDescDevStatusChanged PVSCSIMsgDescDevStatusChanged;
    218
    219/*
    220 * Rings state.
    221 *
    222 * - the fields:
    223 *    . msgProdIdx,
    224 *    . msgConsIdx,
    225 *    . msgNumEntriesLog2,
    226 *   .. are only used once the SETUP_MSG_RING cmd has been issued.
    227 * - 'pad' helps to ensure that the msg related fields are on their own
    228 *   cache-line.
    229 */
    230
    231struct PVSCSIRingsState {
    232    uint32_t    reqProdIdx;
    233    uint32_t    reqConsIdx;
    234    uint32_t    reqNumEntriesLog2;
    235
    236    uint32_t    cmpProdIdx;
    237    uint32_t    cmpConsIdx;
    238    uint32_t    cmpNumEntriesLog2;
    239
    240    uint8_t     pad[104];
    241
    242    uint32_t    msgProdIdx;
    243    uint32_t    msgConsIdx;
    244    uint32_t    msgNumEntriesLog2;
    245} QEMU_PACKED;
    246
    247typedef struct PVSCSIRingsState PVSCSIRingsState;
    248
    249/*
    250 * Request descriptor.
    251 *
    252 * sizeof(RingReqDesc) = 128
    253 *
    254 * - context: is a unique identifier of a command. It could normally be any
    255 *   64bit value, however we currently store it in the serialNumber variable
    256 *   of struct SCSI_Command, so we have the following restrictions due to the
    257 *   way this field is handled in the vmkernel storage stack:
    258 *    * this value can't be 0,
    259 *    * the upper 32bit need to be 0 since serialNumber is as a uint32_t.
    260 *   Currently tracked as PR 292060.
    261 * - dataLen: contains the total number of bytes that need to be transferred.
    262 * - dataAddr:
    263 *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first
    264 *     s/g table segment, each s/g segment is entirely contained on a single
    265 *     page of physical memory,
    266 *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of
    267 *     the buffer used for the DMA transfer,
    268 * - flags:
    269 *   * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above,
    270 *   * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved,
    271 *   * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory,
    272 *   * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device,
    273 *   * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than
    274 *     16bytes. To be specified.
    275 * - vcpuHint: vcpuId of the processor that will be most likely waiting for the
    276 *   completion of the i/o. For guest OSes that use lowest priority message
    277 *   delivery mode (such as windows), we use this "hint" to deliver the
    278 *   completion action to the proper vcpu. For now, we can use the vcpuId of
    279 *   the processor that initiated the i/o as a likely candidate for the vcpu
    280 *   that will be waiting for the completion..
    281 * - bus should be 0: we currently only support bus 0 for now.
    282 * - unused should be zero'd.
    283 */
    284
    285#define PVSCSI_FLAG_CMD_WITH_SG_LIST        (1 << 0)
    286#define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB     (1 << 1)
    287#define PVSCSI_FLAG_CMD_DIR_NONE            (1 << 2)
    288#define PVSCSI_FLAG_CMD_DIR_TOHOST          (1 << 3)
    289#define PVSCSI_FLAG_CMD_DIR_TODEVICE        (1 << 4)
    290
    291#define PVSCSI_KNOWN_FLAGS \
    292  (PVSCSI_FLAG_CMD_WITH_SG_LIST     | \
    293   PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB  | \
    294   PVSCSI_FLAG_CMD_DIR_NONE         | \
    295   PVSCSI_FLAG_CMD_DIR_TOHOST       | \
    296   PVSCSI_FLAG_CMD_DIR_TODEVICE)
    297
    298struct PVSCSIRingReqDesc {
    299    uint64_t    context;
    300    uint64_t    dataAddr;
    301    uint64_t    dataLen;
    302    uint64_t    senseAddr;
    303    uint32_t    senseLen;
    304    uint32_t    flags;
    305    uint8_t     cdb[16];
    306    uint8_t     cdbLen;
    307    uint8_t     lun[8];
    308    uint8_t     tag;
    309    uint8_t     bus;
    310    uint8_t     target;
    311    uint8_t     vcpuHint;
    312    uint8_t     unused[59];
    313} QEMU_PACKED;
    314
    315typedef struct PVSCSIRingReqDesc PVSCSIRingReqDesc;
    316
    317/*
    318 * Scatter-gather list management.
    319 *
    320 * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the
    321 * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g
    322 * table segment.
    323 *
    324 * - each segment of the s/g table contain a succession of struct
    325 *   PVSCSISGElement.
    326 * - each segment is entirely contained on a single physical page of memory.
    327 * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in
    328 *   PVSCSISGElement.flags and in this case:
    329 *     * addr is the PA of the next s/g segment,
    330 *     * length is undefined, assumed to be 0.
    331 */
    332
    333struct PVSCSISGElement {
    334    uint64_t    addr;
    335    uint32_t    length;
    336    uint32_t    flags;
    337} QEMU_PACKED;
    338
    339typedef struct PVSCSISGElement PVSCSISGElement;
    340
    341/*
    342 * Completion descriptor.
    343 *
    344 * sizeof(RingCmpDesc) = 32
    345 *
    346 * - context: identifier of the command. The same thing that was specified
    347 *   under "context" as part of struct RingReqDesc at initiation time,
    348 * - dataLen: number of bytes transferred for the actual i/o operation,
    349 * - senseLen: number of bytes written into the sense buffer,
    350 * - hostStatus: adapter status,
    351 * - scsiStatus: device status,
    352 * - pad should be zero.
    353 */
    354
    355struct PVSCSIRingCmpDesc {
    356    uint64_t    context;
    357    uint64_t    dataLen;
    358    uint32_t    senseLen;
    359    uint16_t    hostStatus;
    360    uint16_t    scsiStatus;
    361    uint32_t    pad[2];
    362} QEMU_PACKED;
    363
    364typedef struct PVSCSIRingCmpDesc PVSCSIRingCmpDesc;
    365
    366/*
    367 * Interrupt status / IRQ bits.
    368 */
    369
    370#define PVSCSI_INTR_CMPL_0                 (1 << 0)
    371#define PVSCSI_INTR_CMPL_1                 (1 << 1)
    372#define PVSCSI_INTR_CMPL_MASK              MASK(2)
    373
    374#define PVSCSI_INTR_MSG_0                  (1 << 2)
    375#define PVSCSI_INTR_MSG_1                  (1 << 3)
    376#define PVSCSI_INTR_MSG_MASK               (MASK(2) << 2)
    377
    378#define PVSCSI_INTR_ALL_SUPPORTED          MASK(4)
    379
    380/*
    381 * Number of MSI-X vectors supported.
    382 */
    383#define PVSCSI_MAX_INTRS        24
    384
    385/*
    386 * Enumeration of supported MSI-X vectors
    387 */
    388#define PVSCSI_VECTOR_COMPLETION   0
    389
    390/*
    391 * Misc constants for the rings.
    392 */
    393
    394#define PVSCSI_MAX_NUM_PAGES_REQ_RING   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
    395#define PVSCSI_MAX_NUM_PAGES_CMP_RING   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
    396#define PVSCSI_MAX_NUM_PAGES_MSG_RING   PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
    397
    398#define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
    399                (VMW_PAGE_SIZE / sizeof(struct PVSCSIRingReqDesc))
    400
    401#define PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE \
    402                (VMW_PAGE_SIZE / sizeof(PVSCSIRingCmpDesc))
    403
    404#define PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE \
    405                (VMW_PAGE_SIZE / sizeof(PVSCSIRingMsgDesc))
    406
    407#define PVSCSI_MAX_REQ_QUEUE_DEPTH \
    408    (PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
    409
    410#define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES     1
    411#define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES 1
    412#define PVSCSI_MEM_SPACE_MISC_NUM_PAGES        2
    413#define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES     2
    414#define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES        2
    415
    416enum PVSCSIMemSpace {
    417    PVSCSI_MEM_SPACE_COMMAND_PAGE       = 0,
    418    PVSCSI_MEM_SPACE_INTR_STATUS_PAGE   = 1,
    419    PVSCSI_MEM_SPACE_MISC_PAGE          = 2,
    420    PVSCSI_MEM_SPACE_KICK_IO_PAGE       = 4,
    421    PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE    = 6,
    422    PVSCSI_MEM_SPACE_MSIX_PBA_PAGE      = 7,
    423};
    424
    425#define PVSCSI_MEM_SPACE_NUM_PAGES \
    426    (PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES +       \
    427     PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES +   \
    428     PVSCSI_MEM_SPACE_MISC_NUM_PAGES +          \
    429     PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES +       \
    430     PVSCSI_MEM_SPACE_MSIX_NUM_PAGES)
    431
    432#define PVSCSI_MEM_SPACE_SIZE    (PVSCSI_MEM_SPACE_NUM_PAGES * VMW_PAGE_SIZE)
    433
    434#endif /* VMW_PVSCSI_H */