cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vscsiif.h (12815B)


      1/* SPDX-License-Identifier: MIT */
      2/******************************************************************************
      3 * vscsiif.h
      4 *
      5 * Based on the blkif.h code.
      6 *
      7 * Copyright(c) FUJITSU Limited 2008.
      8 */
      9
     10#ifndef __XEN__PUBLIC_IO_SCSI_H__
     11#define __XEN__PUBLIC_IO_SCSI_H__
     12
     13#include "ring.h"
     14#include "../grant_table.h"
     15
     16/*
     17 * Feature and Parameter Negotiation
     18 * =================================
     19 * The two halves of a Xen pvSCSI driver utilize nodes within the XenStore to
     20 * communicate capabilities and to negotiate operating parameters.  This
     21 * section enumerates these nodes which reside in the respective front and
     22 * backend portions of the XenStore, following the XenBus convention.
     23 *
     24 * Any specified default value is in effect if the corresponding XenBus node
     25 * is not present in the XenStore.
     26 *
     27 * XenStore nodes in sections marked "PRIVATE" are solely for use by the
     28 * driver side whose XenBus tree contains them.
     29 *
     30 *****************************************************************************
     31 *                            Backend XenBus Nodes
     32 *****************************************************************************
     33 *
     34 *------------------ Backend Device Identification (PRIVATE) ------------------
     35 *
     36 * p-devname
     37 *      Values:         string
     38 *
     39 *      A free string used to identify the physical device (e.g. a disk name).
     40 *
     41 * p-dev
     42 *      Values:         string
     43 *
     44 *      A string specifying the backend device: either a 4-tuple "h:c:t:l"
     45 *      (host, controller, target, lun, all integers), or a WWN (e.g.
     46 *      "naa.60014054ac780582:0").
     47 *
     48 * v-dev
     49 *      Values:         string
     50 *
     51 *      A string specifying the frontend device in form of a 4-tuple "h:c:t:l"
     52 *      (host, controller, target, lun, all integers).
     53 *
     54 *--------------------------------- Features ---------------------------------
     55 *
     56 * feature-sg-grant
     57 *      Values:         unsigned [VSCSIIF_SG_TABLESIZE...65535]
     58 *      Default Value:  0
     59 *
     60 *      Specifies the maximum number of scatter/gather elements in grant pages
     61 *      supported. If not set, the backend supports up to VSCSIIF_SG_TABLESIZE
     62 *      SG elements specified directly in the request.
     63 *
     64 *****************************************************************************
     65 *                            Frontend XenBus Nodes
     66 *****************************************************************************
     67 *
     68 *----------------------- Request Transport Parameters -----------------------
     69 *
     70 * event-channel
     71 *      Values:         unsigned
     72 *
     73 *      The identifier of the Xen event channel used to signal activity
     74 *      in the ring buffer.
     75 *
     76 * ring-ref
     77 *      Values:         unsigned
     78 *
     79 *      The Xen grant reference granting permission for the backend to map
     80 *      the sole page in a single page sized ring buffer.
     81 *
     82 * protocol
     83 *      Values:         string (XEN_IO_PROTO_ABI_*)
     84 *      Default Value:  XEN_IO_PROTO_ABI_NATIVE
     85 *
     86 *      The machine ABI rules governing the format of all ring request and
     87 *      response structures.
     88 */
     89
     90/*
     91 * Xenstore format in practice
     92 * ===========================
     93 *
     94 * The backend driver uses a single_host:many_devices notation to manage domU
     95 * devices. Everything is stored in /local/domain/<backend_domid>/backend/vscsi/.
     96 * The xenstore layout looks like this (dom0 is assumed to be the backend_domid):
     97 *
     98 *     <domid>/<vhost>/feature-host = "0"
     99 *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0"
    100 *     <domid>/<vhost>/frontend-id = "<domid>"
    101 *     <domid>/<vhost>/online = "1"
    102 *     <domid>/<vhost>/state = "4"
    103 *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" or "naa.wwn:lun"
    104 *     <domid>/<vhost>/vscsi-devs/dev-0/state = "4"
    105 *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0"
    106 *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2"
    107 *     <domid>/<vhost>/vscsi-devs/dev-1/state = "4"
    108 *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0"
    109 *
    110 * The frontend driver maintains its state in
    111 * /local/domain/<domid>/device/vscsi/.
    112 *
    113 *     <vhost>/backend = "/local/domain/0/backend/vscsi/<domid>/<vhost>"
    114 *     <vhost>/backend-id = "0"
    115 *     <vhost>/event-channel = "20"
    116 *     <vhost>/ring-ref = "43"
    117 *     <vhost>/state = "4"
    118 *     <vhost>/vscsi-devs/dev-0/state = "4"
    119 *     <vhost>/vscsi-devs/dev-1/state = "4"
    120 *
    121 * In addition to the entries for backend and frontend these flags are stored
    122 * for the toolstack:
    123 *
    124 *     <domid>/<vhost>/vscsi-devs/dev-1/p-devname = "/dev/$device"
    125 *     <domid>/<vhost>/libxl_ctrl_index = "0"
    126 *
    127 *
    128 * Backend/frontend protocol
    129 * =========================
    130 *
    131 * To create a vhost along with a device:
    132 *     <domid>/<vhost>/feature-host = "0"
    133 *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0"
    134 *     <domid>/<vhost>/frontend-id = "<domid>"
    135 *     <domid>/<vhost>/online = "1"
    136 *     <domid>/<vhost>/state = "1"
    137 *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1"
    138 *     <domid>/<vhost>/vscsi-devs/dev-0/state = "1"
    139 *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0"
    140 * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-0/state become 4
    141 *
    142 * To add another device to a vhost:
    143 *     <domid>/<vhost>/state = "7"
    144 *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2"
    145 *     <domid>/<vhost>/vscsi-devs/dev-1/state = "1"
    146 *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0"
    147 * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-1/state become 4
    148 *
    149 * To remove a device from a vhost:
    150 *     <domid>/<vhost>/state = "7"
    151 *     <domid>/<vhost>/vscsi-devs/dev-1/state = "5"
    152 * Wait for <domid>/<vhost>/state to become 4
    153 * Wait for <domid>/<vhost>/vscsi-devs/dev-1/state become 6
    154 * Remove <domid>/<vhost>/vscsi-devs/dev-1/{state,p-dev,v-dev,p-devname}
    155 * Remove <domid>/<vhost>/vscsi-devs/dev-1/
    156 *
    157 */
    158
    159/* Requests from the frontend to the backend */
    160
    161/*
    162 * Request a SCSI operation specified via a CDB in vscsiif_request.cmnd.
    163 * The target is specified via channel, id and lun.
    164 *
    165 * The operation to be performed is specified via a CDB in cmnd[], the length
    166 * of the CDB is in cmd_len. sc_data_direction specifies the direction of data
    167 * (to the device, from the device, or none at all).
    168 *
    169 * If data is to be transferred to or from the device the buffer(s) in the
    170 * guest memory is/are specified via one or multiple scsiif_request_segment
    171 * descriptors each specifying a memory page via a grant_ref_t, a offset into
    172 * the page and the length of the area in that page. All scsiif_request_segment
    173 * areas concatenated form the resulting data buffer used by the operation.
    174 * If the number of scsiif_request_segment areas is not too large (less than
    175 * or equal VSCSIIF_SG_TABLESIZE) the areas can be specified directly in the
    176 * seg[] array and the number of valid scsiif_request_segment elements is to be
    177 * set in nr_segments.
    178 *
    179 * If "feature-sg-grant" in the Xenstore is set it is possible to specify more
    180 * than VSCSIIF_SG_TABLESIZE scsiif_request_segment elements via indirection.
    181 * The maximum number of allowed scsiif_request_segment elements is the value
    182 * of the "feature-sg-grant" entry from Xenstore. When using indirection the
    183 * seg[] array doesn't contain specifications of the data buffers, but
    184 * references to scsiif_request_segment arrays, which in turn reference the
    185 * data buffers. While nr_segments holds the number of populated seg[] entries
    186 * (plus the set VSCSIIF_SG_GRANT bit), the number of scsiif_request_segment
    187 * elements referencing the target data buffers is calculated from the lengths
    188 * of the seg[] elements (the sum of all valid seg[].length divided by the
    189 * size of one scsiif_request_segment structure). The frontend may use a mix of
    190 * direct and indirect requests.
    191 */
    192#define VSCSIIF_ACT_SCSI_CDB		1
    193
    194/*
    195 * Request abort of a running operation for the specified target given by
    196 * channel, id, lun and the operation's rqid in ref_rqid.
    197 */
    198#define VSCSIIF_ACT_SCSI_ABORT		2
    199
    200/*
    201 * Request a device reset of the specified target (channel and id).
    202 */
    203#define VSCSIIF_ACT_SCSI_RESET		3
    204
    205/*
    206 * Preset scatter/gather elements for a following request. Deprecated.
    207 * Keeping the define only to avoid usage of the value "4" for other actions.
    208 */
    209#define VSCSIIF_ACT_SCSI_SG_PRESET	4
    210
    211/*
    212 * Maximum scatter/gather segments per request.
    213 *
    214 * Considering balance between allocating at least 16 "vscsiif_request"
    215 * structures on one page (4096 bytes) and the number of scatter/gather
    216 * elements needed, we decided to use 26 as a magic number.
    217 *
    218 * If "feature-sg-grant" is set, more scatter/gather elements can be specified
    219 * by placing them in one or more (up to VSCSIIF_SG_TABLESIZE) granted pages.
    220 * In this case the vscsiif_request seg elements don't contain references to
    221 * the user data, but to the SG elements referencing the user data.
    222 */
    223#define VSCSIIF_SG_TABLESIZE		26
    224
    225/*
    226 * based on Linux kernel 2.6.18, still valid
    227 *
    228 * Changing these values requires support of multiple protocols via the rings
    229 * as "old clients" will blindly use these values and the resulting structure
    230 * sizes.
    231 */
    232#define VSCSIIF_MAX_COMMAND_SIZE	16
    233#define VSCSIIF_SENSE_BUFFERSIZE	96
    234#define VSCSIIF_PAGE_SIZE		4096
    235
    236struct scsiif_request_segment {
    237	grant_ref_t gref;
    238	uint16_t offset;
    239	uint16_t length;
    240};
    241
    242#define VSCSIIF_SG_PER_PAGE	(VSCSIIF_PAGE_SIZE / \
    243				 sizeof(struct scsiif_request_segment))
    244
    245/* Size of one request is 252 bytes */
    246struct vscsiif_request {
    247	uint16_t rqid;		/* private guest value, echoed in resp  */
    248	uint8_t act;		/* command between backend and frontend */
    249	uint8_t cmd_len;	/* valid CDB bytes */
    250
    251	uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE];	/* the CDB */
    252	uint16_t timeout_per_command;	/* deprecated */
    253	uint16_t channel, id, lun;	/* (virtual) device specification */
    254	uint16_t ref_rqid;		/* command abort reference */
    255	uint8_t sc_data_direction;	/* for DMA_TO_DEVICE(1)
    256					   DMA_FROM_DEVICE(2)
    257					   DMA_NONE(3) requests */
    258	uint8_t nr_segments;		/* Number of pieces of scatter-gather */
    259/*
    260 * flag in nr_segments: SG elements via grant page
    261 *
    262 * If VSCSIIF_SG_GRANT is set, the low 7 bits of nr_segments specify the number
    263 * of grant pages containing SG elements. Usable if "feature-sg-grant" set.
    264 */
    265#define VSCSIIF_SG_GRANT	0x80
    266
    267	struct scsiif_request_segment seg[VSCSIIF_SG_TABLESIZE];
    268	uint32_t reserved[3];
    269};
    270
    271/* Size of one response is 252 bytes */
    272struct vscsiif_response {
    273	uint16_t rqid;		/* identifies request */
    274	uint8_t padding;
    275	uint8_t sense_len;
    276	uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
    277	int32_t rslt;
    278	uint32_t residual_len;	/* request bufflen -
    279				   return the value from physical device */
    280	uint32_t reserved[36];
    281};
    282
    283/* SCSI I/O status from vscsiif_response->rslt */
    284#define XEN_VSCSIIF_RSLT_STATUS(x)  ((x) & 0x00ff)
    285
    286/* Host I/O status from vscsiif_response->rslt */
    287#define XEN_VSCSIIF_RSLT_HOST(x)    (((x) & 0x00ff0000) >> 16)
    288#define XEN_VSCSIIF_RSLT_HOST_OK                   0
    289/* Couldn't connect before timeout */
    290#define XEN_VSCSIIF_RSLT_HOST_NO_CONNECT           1
    291/* Bus busy through timeout */
    292#define XEN_VSCSIIF_RSLT_HOST_BUS_BUSY             2
    293/* Timed out for other reason */
    294#define XEN_VSCSIIF_RSLT_HOST_TIME_OUT             3
    295/* Bad target */
    296#define XEN_VSCSIIF_RSLT_HOST_BAD_TARGET           4
    297/* Abort for some other reason */
    298#define XEN_VSCSIIF_RSLT_HOST_ABORT                5
    299/* Parity error */
    300#define XEN_VSCSIIF_RSLT_HOST_PARITY               6
    301/* Internal error */
    302#define XEN_VSCSIIF_RSLT_HOST_ERROR                7
    303/* Reset by somebody */
    304#define XEN_VSCSIIF_RSLT_HOST_RESET                8
    305/* Unexpected interrupt */
    306#define XEN_VSCSIIF_RSLT_HOST_BAD_INTR             9
    307/* Force command past mid-layer */
    308#define XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH         10
    309/* Retry requested */
    310#define XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR          11
    311/* Hidden retry requested */
    312#define XEN_VSCSIIF_RSLT_HOST_IMM_RETRY           12
    313/* Requeue command requested */
    314#define XEN_VSCSIIF_RSLT_HOST_REQUEUE             13
    315/* Transport error disrupted I/O */
    316#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED 14
    317/* Transport class fastfailed */
    318#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST  15
    319/* Permanent target failure */
    320#define XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE      16
    321/* Permanent nexus failure on path */
    322#define XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE       17
    323/* Space allocation on device failed */
    324#define XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE       18
    325/* Medium error */
    326#define XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR        19
    327/* Transport marginal errors */
    328#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL  20
    329
    330/* Result values of reset operations */
    331#define XEN_VSCSIIF_RSLT_RESET_SUCCESS  0x2002
    332#define XEN_VSCSIIF_RSLT_RESET_FAILED   0x2003
    333
    334DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response);
    335
    336
    337#endif  /*__XEN__PUBLIC_IO_SCSI_H__*/