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

cio.h (13992B)


      1/*
      2 * Channel IO definitions
      3 *
      4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
      5 *
      6 * Inspired by various s390 headers in Linux 3.9.
      7 *
      8 * This work is licensed under the terms of the GNU GPL, version 2 or (at
      9 * your option) any later version. See the COPYING file in the top-level
     10 * directory.
     11 */
     12
     13#ifndef CIO_H
     14#define CIO_H
     15
     16/*
     17 * path management control word
     18 */
     19struct pmcw {
     20    __u32 intparm;      /* interruption parameter */
     21    __u32 qf:1;         /* qdio facility */
     22    __u32 w:1;
     23    __u32 isc:3;        /* interruption sublass */
     24    __u32 res5:3;       /* reserved zeros */
     25    __u32 ena:1;        /* enabled */
     26    __u32 lm:2;         /* limit mode */
     27    __u32 mme:2;        /* measurement-mode enable */
     28    __u32 mp:1;         /* multipath mode */
     29    __u32 tf:1;         /* timing facility */
     30    __u32 dnv:1;        /* device number valid */
     31    __u32 dev:16;       /* device number */
     32    __u8  lpm;          /* logical path mask */
     33    __u8  pnom;         /* path not operational mask */
     34    __u8  lpum;         /* last path used mask */
     35    __u8  pim;          /* path installed mask */
     36    __u16 mbi;          /* measurement-block index */
     37    __u8  pom;          /* path operational mask */
     38    __u8  pam;          /* path available mask */
     39    __u8  chpid[8];     /* CHPID 0-7 (if available) */
     40    __u32 unused1:8;    /* reserved zeros */
     41    __u32 st:3;         /* subchannel type */
     42    __u32 unused2:18;   /* reserved zeros */
     43    __u32 mbfc:1;       /* measurement block format control */
     44    __u32 xmwme:1;      /* extended measurement word mode enable */
     45    __u32 csense:1;     /* concurrent sense; can be enabled ...*/
     46                        /*  ... per MSCH, however, if facility */
     47                        /*  ... is not installed, this results */
     48                        /*  ... in an operand exception.       */
     49} __attribute__ ((packed));
     50
     51/* Target SCHIB configuration. */
     52struct schib_config {
     53    __u64 mba;
     54    __u32 intparm;
     55    __u16 mbi;
     56    __u32 isc:3;
     57    __u32 ena:1;
     58    __u32 mme:2;
     59    __u32 mp:1;
     60    __u32 csense:1;
     61    __u32 mbfc:1;
     62} __attribute__ ((packed));
     63
     64struct scsw {
     65    __u16 flags;
     66    __u16 ctrl;
     67    __u32 cpa;
     68    __u8 dstat;
     69    __u8 cstat;
     70    __u16 count;
     71} __attribute__ ((packed));
     72
     73/* Function Control */
     74#define SCSW_FCTL_START_FUNC 0x4000
     75#define SCSW_FCTL_HALT_FUNC 0x2000
     76#define SCSW_FCTL_CLEAR_FUNC 0x1000
     77
     78/* Activity Control */
     79#define SCSW_ACTL_RESUME_PEND   0x0800
     80#define SCSW_ACTL_START_PEND    0x0400
     81#define SCSW_ACTL_HALT_PEND     0x0200
     82#define SCSW_ACTL_CLEAR_PEND    0x0100
     83#define SCSW_ACTL_CH_ACTIVE     0x0080
     84#define SCSW_ACTL_DEV_ACTIVE    0x0040
     85#define SCSW_ACTL_SUSPENDED     0x0020
     86
     87/* Status Control */
     88#define SCSW_SCTL_ALERT         0x0010
     89#define SCSW_SCTL_INTERMED      0x0008
     90#define SCSW_SCTL_PRIMARY       0x0004
     91#define SCSW_SCTL_SECONDARY     0x0002
     92#define SCSW_SCTL_STATUS_PEND   0x0001
     93
     94/* SCSW Device Status Flags */
     95#define SCSW_DSTAT_ATTN     0x80
     96#define SCSW_DSTAT_STATMOD  0x40
     97#define SCSW_DSTAT_CUEND    0x20
     98#define SCSW_DSTAT_BUSY     0x10
     99#define SCSW_DSTAT_CHEND    0x08
    100#define SCSW_DSTAT_DEVEND   0x04
    101#define SCSW_DSTAT_UCHK     0x02
    102#define SCSW_DSTAT_UEXCP    0x01
    103
    104/* SCSW Subchannel Status Flags */
    105#define SCSW_CSTAT_PCINT    0x80
    106#define SCSW_CSTAT_BADLEN   0x40
    107#define SCSW_CSTAT_PROGCHK  0x20
    108#define SCSW_CSTAT_PROTCHK  0x10
    109#define SCSW_CSTAT_CHDCHK   0x08
    110#define SCSW_CSTAT_CHCCHK   0x04
    111#define SCSW_CSTAT_ICCHK    0x02
    112#define SCSW_CSTAT_CHAINCHK 0x01
    113
    114/*
    115 * subchannel information block
    116 */
    117typedef struct schib {
    118    struct pmcw pmcw;     /* path management control word */
    119    struct scsw scsw;     /* subchannel status word */
    120    __u64 mba;            /* measurement block address */
    121    __u8 mda[4];          /* model dependent area */
    122} __attribute__ ((packed, aligned(4))) Schib;
    123
    124typedef struct subchannel_id {
    125    union {
    126        struct {
    127            __u16 cssid:8;
    128            __u16 reserved:4;
    129            __u16 m:1;
    130            __u16 ssid:2;
    131            __u16 one:1;
    132        };
    133        __u16 sch_id;
    134    };
    135    __u16 sch_no;
    136} __attribute__ ((packed, aligned(4))) SubChannelId;
    137
    138struct chsc_header {
    139    __u16 length;
    140    __u16 code;
    141} __attribute__((packed));
    142
    143typedef struct chsc_area_sda {
    144    struct chsc_header request;
    145    __u8 reserved1:4;
    146    __u8 format:4;
    147    __u8 reserved2;
    148    __u16 operation_code;
    149    __u32 reserved3;
    150    __u32 reserved4;
    151    __u32 operation_data_area[252];
    152    struct chsc_header response;
    153    __u32 reserved5:4;
    154    __u32 format2:4;
    155    __u32 reserved6:24;
    156} __attribute__((packed)) ChscAreaSda;
    157
    158/*
    159 * TPI info structure
    160 */
    161struct tpi_info {
    162    struct subchannel_id schid;
    163    __u32 intparm;      /* interruption parameter */
    164    __u32 adapter_IO:1;
    165    __u32 reserved2:1;
    166    __u32 isc:3;
    167    __u32 reserved3:12;
    168    __u32 int_type:3;
    169    __u32 reserved4:12;
    170} __attribute__ ((packed, aligned(4)));
    171
    172/* channel command word (format 0) */
    173typedef struct ccw0 {
    174    __u8 cmd_code;
    175    __u32 cda:24;
    176    __u32 chainData:1;
    177    __u32 chain:1;
    178    __u32 sli:1;
    179    __u32 skip:1;
    180    __u32 pci:1;
    181    __u32 ida:1;
    182    __u32 suspend:1;
    183    __u32 mida:1;
    184    __u8 reserved;
    185    __u16 count;
    186} __attribute__ ((packed, aligned(8))) Ccw0;
    187
    188/* channel command word (format 1) */
    189typedef struct ccw1 {
    190    __u8 cmd_code;
    191    __u8 flags;
    192    __u16 count;
    193    __u32 cda;
    194} __attribute__ ((packed, aligned(8))) Ccw1;
    195
    196/* do_cio() CCW formats */
    197#define CCW_FMT0                 0x00
    198#define CCW_FMT1                 0x01
    199
    200#define CCW_FLAG_DC              0x80
    201#define CCW_FLAG_CC              0x40
    202#define CCW_FLAG_SLI             0x20
    203#define CCW_FLAG_SKIP            0x10
    204#define CCW_FLAG_PCI             0x08
    205#define CCW_FLAG_IDA             0x04
    206#define CCW_FLAG_SUSPEND         0x02
    207
    208/* Common CCW commands */
    209#define CCW_CMD_READ_IPL         0x02
    210#define CCW_CMD_NOOP             0x03
    211#define CCW_CMD_BASIC_SENSE      0x04
    212#define CCW_CMD_TIC              0x08
    213#define CCW_CMD_SENSE_ID         0xe4
    214
    215/* Virtio CCW commands */
    216#define CCW_CMD_SET_VQ           0x13
    217#define CCW_CMD_VDEV_RESET       0x33
    218#define CCW_CMD_READ_FEAT        0x12
    219#define CCW_CMD_WRITE_FEAT       0x11
    220#define CCW_CMD_READ_CONF        0x22
    221#define CCW_CMD_WRITE_CONF       0x21
    222#define CCW_CMD_WRITE_STATUS     0x31
    223#define CCW_CMD_SET_IND          0x43
    224#define CCW_CMD_SET_CONF_IND     0x53
    225#define CCW_CMD_READ_VQ_CONF     0x32
    226
    227/* DASD CCW commands */
    228#define CCW_CMD_DASD_READ             0x06
    229#define CCW_CMD_DASD_SEEK             0x07
    230#define CCW_CMD_DASD_SEARCH_ID_EQ     0x31
    231#define CCW_CMD_DASD_READ_MT          0x86
    232
    233/*
    234 * Command-mode operation request block
    235 */
    236typedef struct cmd_orb {
    237    __u32 intparm;    /* interruption parameter */
    238    __u32 key:4;      /* flags, like key, suspend control, etc. */
    239    __u32 spnd:1;     /* suspend control */
    240    __u32 res1:1;     /* reserved */
    241    __u32 mod:1;      /* modification control */
    242    __u32 sync:1;     /* synchronize control */
    243    __u32 fmt:1;      /* format control */
    244    __u32 pfch:1;     /* prefetch control */
    245    __u32 isic:1;     /* initial-status-interruption control */
    246    __u32 alcc:1;     /* address-limit-checking control */
    247    __u32 ssic:1;     /* suppress-suspended-interr. control */
    248    __u32 res2:1;     /* reserved */
    249    __u32 c64:1;      /* IDAW/QDIO 64 bit control  */
    250    __u32 i2k:1;      /* IDAW 2/4kB block size control */
    251    __u32 lpm:8;      /* logical path mask */
    252    __u32 ils:1;      /* incorrect length */
    253    __u32 zero:6;     /* reserved zeros */
    254    __u32 orbx:1;     /* ORB extension control */
    255    __u32 cpa;    /* channel program address */
    256}  __attribute__ ((packed, aligned(4))) CmdOrb;
    257
    258struct ciw {
    259    __u8 type;
    260    __u8 command;
    261    __u16 count;
    262};
    263
    264#define CU_TYPE_UNKNOWN         0x0000
    265#define CU_TYPE_DASD_2107       0x2107
    266#define CU_TYPE_VIRTIO          0x3832
    267#define CU_TYPE_DASD_3990       0x3990
    268
    269/*
    270 * sense-id response buffer layout
    271 */
    272typedef struct senseid {
    273    /* common part */
    274    __u8  reserved;   /* always 0x'FF' */
    275    __u16 cu_type;    /* control unit type */
    276    __u8  cu_model;   /* control unit model */
    277    __u16 dev_type;   /* device type */
    278    __u8  dev_model;  /* device model */
    279    __u8  unused;     /* padding byte */
    280    /* extended part */
    281    struct ciw ciw[62];
    282}  __attribute__ ((packed, aligned(4))) SenseId;
    283
    284/*
    285 * architected values for first sense byte - common_status. Bits 0-5 of this
    286 * field are common to all device types.
    287 */
    288#define SNS_STAT0_CMD_REJECT         0x80
    289#define SNS_STAT0_INTERVENTION_REQ   0x40
    290#define SNS_STAT0_BUS_OUT_CHECK      0x20
    291#define SNS_STAT0_EQUIPMENT_CHECK    0x10
    292#define SNS_STAT0_DATA_CHECK         0x08
    293#define SNS_STAT0_OVERRUN            0x04
    294#define SNS_STAT0_INCOMPL_DOMAIN     0x01
    295
    296/* ECKD DASD status[0] byte */
    297#define SNS_STAT1_PERM_ERR           0x80
    298#define SNS_STAT1_INV_TRACK_FORMAT   0x40
    299#define SNS_STAT1_EOC                0x20
    300#define SNS_STAT1_MESSAGE_TO_OPER    0x10
    301#define SNS_STAT1_NO_REC_FOUND       0x08
    302#define SNS_STAT1_FILE_PROTECTED     0x04
    303#define SNS_STAT1_WRITE_INHIBITED    0x02
    304#define SNS_STAT1_IMPRECISE_END      0x01
    305
    306/* ECKD DASD status[1] byte */
    307#define SNS_STAT2_REQ_INH_WRITE      0x80
    308#define SNS_STAT2_CORRECTABLE        0x40
    309#define SNS_STAT2_FIRST_LOG_ERR      0x20
    310#define SNS_STAT2_ENV_DATA_PRESENT   0x10
    311#define SNS_STAT2_IMPRECISE_END      0x04
    312
    313/* ECKD DASD 24-byte Sense fmt_msg codes */
    314#define SENSE24_FMT_PROG_SYS    0x0
    315#define SENSE24_FMT_EQUIPMENT   0x2
    316#define SENSE24_FMT_CONTROLLER  0x3
    317#define SENSE24_FMT_MISC        0xF
    318
    319/* basic sense response buffer layout */
    320typedef struct SenseDataEckdDasd {
    321    uint8_t common_status;
    322    uint8_t status[2];
    323    uint8_t res_count;
    324    uint8_t phys_drive_id;
    325    uint8_t low_cyl_addr;
    326    uint8_t head_high_cyl_addr;
    327    uint8_t fmt_msg;
    328    uint64_t fmt_dependent_info[2];
    329    uint8_t reserved;
    330    uint8_t program_action_code;
    331    uint16_t config_info;
    332    uint8_t mcode_hicyl;
    333    uint8_t cyl_head_addr[3];
    334}  __attribute__ ((packed, aligned(4))) SenseDataEckdDasd;
    335
    336#define ECKD_SENSE24_GET_FMT(sd)     (sd->fmt_msg & 0xF0 >> 4)
    337#define ECKD_SENSE24_GET_MSG(sd)     (sd->fmt_msg & 0x0F)
    338
    339#define unit_check(irb)         ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
    340#define iface_ctrl_check(irb)   ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
    341
    342/* interruption response block */
    343typedef struct irb {
    344    struct scsw scsw;
    345    __u32 esw[5];
    346    __u32 ecw[8];
    347    __u32 emw[8];
    348}  __attribute__ ((packed, aligned(4))) Irb;
    349
    350/* Used for SEEK ccw commands */
    351typedef struct CcwSeekData {
    352    uint16_t reserved;
    353    uint16_t cyl;
    354    uint16_t head;
    355} __attribute__((packed)) CcwSeekData;
    356
    357/* Used for SEARCH ID ccw commands */
    358typedef struct CcwSearchIdData {
    359    uint16_t cyl;
    360    uint16_t head;
    361    uint8_t record;
    362} __attribute__((packed)) CcwSearchIdData;
    363
    364int enable_mss_facility(void);
    365void enable_subchannel(SubChannelId schid);
    366uint16_t cu_type(SubChannelId schid);
    367int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
    368                 uint16_t data_size);
    369int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt);
    370
    371/*
    372 * Some S390 specific IO instructions as inline
    373 */
    374
    375static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
    376{
    377    register struct subchannel_id reg1 asm ("1") = schid;
    378    int ccode = -EIO;
    379
    380    asm volatile(
    381        "    stsch    0(%3)\n"
    382        "0:  ipm    %0\n"
    383        "    srl    %0,28\n"
    384        "1:\n"
    385        : "+d" (ccode), "=m" (*addr)
    386        : "d" (reg1), "a" (addr)
    387        : "cc");
    388    return ccode;
    389}
    390
    391static inline int msch(struct subchannel_id schid, struct schib *addr)
    392{
    393    register struct subchannel_id reg1 asm ("1") = schid;
    394    int ccode;
    395
    396    asm volatile(
    397        "    msch    0(%2)\n"
    398        "    ipm    %0\n"
    399        "    srl    %0,28"
    400        : "=d" (ccode)
    401        : "d" (reg1), "a" (addr), "m" (*addr)
    402        : "cc");
    403    return ccode;
    404}
    405
    406static inline int msch_err(struct subchannel_id schid, struct schib *addr)
    407{
    408    register struct subchannel_id reg1 asm ("1") = schid;
    409    int ccode = -EIO;
    410
    411    asm volatile(
    412        "    msch    0(%2)\n"
    413        "0:  ipm    %0\n"
    414        "    srl    %0,28\n"
    415        "1:\n"
    416        : "+d" (ccode)
    417        : "d" (reg1), "a" (addr), "m" (*addr)
    418        : "cc");
    419    return ccode;
    420}
    421
    422static inline int tsch(struct subchannel_id schid, struct irb *addr)
    423{
    424    register struct subchannel_id reg1 asm ("1") = schid;
    425    int ccode;
    426
    427    asm volatile(
    428        "    tsch    0(%3)\n"
    429        "    ipm    %0\n"
    430        "    srl    %0,28"
    431        : "=d" (ccode), "=m" (*addr)
    432        : "d" (reg1), "a" (addr)
    433        : "cc");
    434    return ccode;
    435}
    436
    437static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr)
    438{
    439    register struct subchannel_id reg1 asm("1") = schid;
    440    int ccode = -EIO;
    441
    442    asm volatile(
    443        "    ssch    0(%2)\n"
    444        "0:  ipm    %0\n"
    445        "    srl    %0,28\n"
    446        "1:\n"
    447        : "+d" (ccode)
    448        : "d" (reg1), "a" (addr), "m" (*addr)
    449        : "cc", "memory");
    450    return ccode;
    451}
    452
    453static inline int csch(struct subchannel_id schid)
    454{
    455    register struct subchannel_id reg1 asm("1") = schid;
    456    int ccode;
    457
    458    asm volatile(
    459        "    csch\n"
    460        "    ipm    %0\n"
    461        "    srl    %0,28"
    462        : "=d" (ccode)
    463        : "d" (reg1)
    464        : "cc");
    465    return ccode;
    466}
    467
    468static inline int tpi(struct tpi_info *addr)
    469{
    470    int ccode;
    471
    472    asm volatile(
    473        "    tpi    0(%2)\n"
    474        "    ipm    %0\n"
    475        "    srl    %0,28"
    476        : "=d" (ccode), "=m" (*addr)
    477        : "a" (addr)
    478        : "cc");
    479    return ccode;
    480}
    481
    482static inline int chsc(void *chsc_area)
    483{
    484    typedef struct { char _[4096]; } addr_type;
    485    int cc;
    486
    487    asm volatile(
    488        "    .insn    rre,0xb25f0000,%2,0\n"
    489        "    ipm    %0\n"
    490        "    srl    %0,28\n"
    491        : "=d" (cc), "=m" (*(addr_type *) chsc_area)
    492        : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
    493        : "cc");
    494    return cc;
    495}
    496
    497#endif /* CIO_H */