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

virtio.h (8068B)


      1/*
      2 * Virtio driver bits
      3 *
      4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
      5 *
      6 * This work is licensed under the terms of the GNU GPL, version 2 or (at
      7 * your option) any later version. See the COPYING file in the top-level
      8 * directory.
      9 */
     10
     11#ifndef VIRTIO_H
     12#define VIRTIO_H
     13
     14/* Status byte for guest to report progress, and synchronize features. */
     15/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
     16#define VIRTIO_CONFIG_S_ACKNOWLEDGE     1
     17/* We have found a driver for the device. */
     18#define VIRTIO_CONFIG_S_DRIVER          2
     19/* Driver has used its parts of the config, and is happy */
     20#define VIRTIO_CONFIG_S_DRIVER_OK       4
     21/* We've given up on this device. */
     22#define VIRTIO_CONFIG_S_FAILED          0x80
     23
     24enum VirtioDevType {
     25    VIRTIO_ID_NET = 1,
     26    VIRTIO_ID_BLOCK = 2,
     27    VIRTIO_ID_CONSOLE = 3,
     28    VIRTIO_ID_BALLOON = 5,
     29    VIRTIO_ID_SCSI = 8,
     30};
     31typedef enum VirtioDevType VirtioDevType;
     32
     33struct VqInfo {
     34    uint64_t queue;
     35    uint32_t align;
     36    uint16_t index;
     37    uint16_t num;
     38} __attribute__((packed));
     39typedef struct VqInfo VqInfo;
     40
     41struct VqConfig {
     42    uint16_t index;
     43    uint16_t num;
     44} __attribute__((packed));
     45typedef struct VqConfig VqConfig;
     46
     47#define VIRTIO_RING_SIZE            (PAGE_SIZE * 8)
     48#define VIRTIO_MAX_VQS              3
     49#define KVM_S390_VIRTIO_RING_ALIGN  4096
     50
     51#define VRING_USED_F_NO_NOTIFY  1
     52
     53/* This marks a buffer as continuing via the next field. */
     54#define VRING_DESC_F_NEXT       1
     55/* This marks a buffer as write-only (otherwise read-only). */
     56#define VRING_DESC_F_WRITE      2
     57/* This means the buffer contains a list of buffer descriptors. */
     58#define VRING_DESC_F_INDIRECT   4
     59
     60/* Internal flag to mark follow-up segments as such */
     61#define VRING_HIDDEN_IS_CHAIN   256
     62
     63/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
     64struct VRingDesc {
     65    /* Address (guest-physical). */
     66    uint64_t addr;
     67    /* Length. */
     68    uint32_t len;
     69    /* The flags as indicated above. */
     70    uint16_t flags;
     71    /* We chain unused descriptors via this, too */
     72    uint16_t next;
     73} __attribute__((packed));
     74typedef struct VRingDesc VRingDesc;
     75
     76struct VRingAvail {
     77    uint16_t flags;
     78    uint16_t idx;
     79    uint16_t ring[];
     80} __attribute__((packed));
     81typedef struct VRingAvail VRingAvail;
     82
     83/* uint32_t is used here for ids for padding reasons. */
     84struct VRingUsedElem {
     85    /* Index of start of used descriptor chain. */
     86    uint32_t id;
     87    /* Total length of the descriptor chain which was used (written to) */
     88    uint32_t len;
     89} __attribute__((packed));
     90typedef struct VRingUsedElem VRingUsedElem;
     91
     92struct VRingUsed {
     93    uint16_t flags;
     94    uint16_t idx;
     95    VRingUsedElem ring[];
     96} __attribute__((packed));
     97typedef struct VRingUsed VRingUsed;
     98
     99struct VRing {
    100    unsigned int num;
    101    int next_idx;
    102    int used_idx;
    103    VRingDesc *desc;
    104    VRingAvail *avail;
    105    VRingUsed *used;
    106    SubChannelId schid;
    107    long cookie;
    108    int id;
    109};
    110typedef struct VRing VRing;
    111
    112
    113/***********************************************
    114 *               Virtio block                  *
    115 ***********************************************/
    116
    117/*
    118 * Command types
    119 *
    120 * Usage is a bit tricky as some bits are used as flags and some are not.
    121 *
    122 * Rules:
    123 *   VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or
    124 *   VIRTIO_BLK_T_BARRIER.  VIRTIO_BLK_T_FLUSH is a command of its own
    125 *   and may not be combined with any of the other flags.
    126 */
    127
    128/* These two define direction. */
    129#define VIRTIO_BLK_T_IN         0
    130#define VIRTIO_BLK_T_OUT        1
    131
    132/* This bit says it's a scsi command, not an actual read or write. */
    133#define VIRTIO_BLK_T_SCSI_CMD   2
    134
    135/* Cache flush command */
    136#define VIRTIO_BLK_T_FLUSH      4
    137
    138/* Barrier before this op. */
    139#define VIRTIO_BLK_T_BARRIER    0x80000000
    140
    141/* This is the first element of the read scatter-gather list. */
    142struct VirtioBlkOuthdr {
    143        /* VIRTIO_BLK_T* */
    144        uint32_t type;
    145        /* io priority. */
    146        uint32_t ioprio;
    147        /* Sector (ie. 512 byte offset) */
    148        uint64_t sector;
    149};
    150typedef struct VirtioBlkOuthdr VirtioBlkOuthdr;
    151
    152struct VirtioBlkConfig {
    153    uint64_t capacity; /* in 512-byte sectors */
    154    uint32_t size_max; /* max segment size (if VIRTIO_BLK_F_SIZE_MAX) */
    155    uint32_t seg_max;  /* max number of segments (if VIRTIO_BLK_F_SEG_MAX) */
    156
    157    struct VirtioBlkGeometry {
    158        uint16_t cylinders;
    159        uint8_t heads;
    160        uint8_t sectors;
    161    } geometry; /* (if VIRTIO_BLK_F_GEOMETRY) */
    162
    163    uint32_t blk_size; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
    164
    165    /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY  */
    166    uint8_t physical_block_exp; /* exponent for physical blk per logical blk */
    167    uint8_t alignment_offset;   /* alignment offset in logical blocks */
    168    uint16_t min_io_size;       /* min I/O size without performance penalty
    169                              in logical blocks */
    170    uint32_t opt_io_size;       /* optimal sustained I/O size in logical blks */
    171
    172    uint8_t wce; /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */
    173} __attribute__((packed));
    174typedef struct VirtioBlkConfig VirtioBlkConfig;
    175
    176enum guessed_disk_nature_type {
    177    VIRTIO_GDN_NONE     = 0,
    178    VIRTIO_GDN_DASD     = 1,
    179    VIRTIO_GDN_CDROM    = 2,
    180    VIRTIO_GDN_SCSI     = 3,
    181};
    182typedef enum guessed_disk_nature_type VirtioGDN;
    183
    184VirtioGDN virtio_guessed_disk_nature(void);
    185void virtio_assume_scsi(void);
    186void virtio_assume_eckd(void);
    187void virtio_assume_iso9660(void);
    188
    189extern bool virtio_disk_is_scsi(void);
    190extern bool virtio_disk_is_eckd(void);
    191extern bool virtio_ipl_disk_is_valid(void);
    192extern int virtio_get_block_size(void);
    193extern uint8_t virtio_get_heads(void);
    194extern uint8_t virtio_get_sectors(void);
    195extern uint64_t virtio_get_blocks(void);
    196extern int virtio_read_many(ulong sector, void *load_addr, int sec_num);
    197
    198#define VIRTIO_SECTOR_SIZE 512
    199#define VIRTIO_ISO_BLOCK_SIZE 2048
    200#define VIRTIO_SCSI_BLOCK_SIZE 512
    201
    202static inline ulong virtio_sector_adjust(ulong sector)
    203{
    204    return sector * (virtio_get_block_size() / VIRTIO_SECTOR_SIZE);
    205}
    206
    207struct VirtioScsiConfig {
    208    uint32_t num_queues;
    209    uint32_t seg_max;
    210    uint32_t max_sectors;
    211    uint32_t cmd_per_lun;
    212    uint32_t event_info_size;
    213    uint32_t sense_size;
    214    uint32_t cdb_size;
    215    uint16_t max_channel;
    216    uint16_t max_target;
    217    uint32_t max_lun;
    218} __attribute__((packed));
    219typedef struct VirtioScsiConfig VirtioScsiConfig;
    220
    221struct ScsiDevice {
    222    uint16_t channel;   /* Always 0 in QEMU     */
    223    uint16_t target;    /* will be scanned over */
    224    uint32_t lun;       /* will be reported     */
    225};
    226typedef struct ScsiDevice ScsiDevice;
    227
    228struct VirtioNetConfig {
    229    uint8_t mac[6];
    230    /* uint16_t status; */               /* Only with VIRTIO_NET_F_STATUS */
    231    /* uint16_t max_virtqueue_pairs; */  /* Only with VIRTIO_NET_F_MQ */
    232};
    233typedef struct VirtioNetConfig VirtioNetConfig;
    234
    235struct VDev {
    236    int nr_vqs;
    237    VRing *vrings;
    238    int cmd_vr_idx;
    239    void *ring_area;
    240    long wait_reply_timeout;
    241    VirtioGDN guessed_disk_nature;
    242    SubChannelId schid;
    243    SenseId senseid;
    244    union {
    245        VirtioBlkConfig blk;
    246        VirtioScsiConfig scsi;
    247        VirtioNetConfig net;
    248    } config;
    249    ScsiDevice *scsi_device;
    250    bool is_cdrom;
    251    int scsi_block_size;
    252    int blk_factor;
    253    uint64_t scsi_last_block;
    254    uint32_t scsi_dev_cyls;
    255    uint8_t scsi_dev_heads;
    256    bool scsi_device_selected;
    257    ScsiDevice selected_scsi_device;
    258    uint64_t netboot_start_addr;
    259    uint32_t max_transfer;
    260    uint32_t guest_features[2];
    261};
    262typedef struct VDev VDev;
    263
    264VDev *virtio_get_device(void);
    265VirtioDevType virtio_get_device_type(void);
    266
    267struct VirtioCmd {
    268    void *data;
    269    int size;
    270    int flags;
    271};
    272typedef struct VirtioCmd VirtioCmd;
    273
    274bool vring_notify(VRing *vr);
    275int drain_irqs(SubChannelId schid);
    276void vring_send_buf(VRing *vr, void *p, int len, int flags);
    277int vr_poll(VRing *vr);
    278int vring_wait_reply(void);
    279int virtio_run(VDev *vdev, int vqid, VirtioCmd *cmd);
    280void virtio_setup_ccw(VDev *vdev);
    281
    282int virtio_net_init(void *mac_addr);
    283
    284#endif /* VIRTIO_H */