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

x86.h (9578B)


      1/*
      2 * Copyright (C) 2016 Veertu Inc,
      3 * Copyright (C) 2017 Veertu Inc,
      4 *
      5 * This program is free software; you can redistribute it and/or
      6 * modify it under the terms of the GNU Lesser General Public
      7 * License as published by the Free Software Foundation; either
      8 * version 2.1 of the License, or (at your option) any later version.
      9 *
     10 * This program is distributed in the hope that it will be useful,
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13 * Lesser General Public License for more details.
     14 *
     15 * You should have received a copy of the GNU Lesser General Public
     16 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
     17 */
     18
     19#ifndef HVF_X86_H
     20#define HVF_X86_H
     21
     22typedef struct x86_register {
     23    union {
     24        struct {
     25            uint64_t rrx;               /* full 64 bit */
     26        };
     27        struct {
     28            uint32_t erx;               /* low 32 bit part */
     29            uint32_t hi32_unused1;
     30        };
     31        struct {
     32            uint16_t rx;                /* low 16 bit part */
     33            uint16_t hi16_unused1;
     34            uint32_t hi32_unused2;
     35        };
     36        struct {
     37            uint8_t lx;                 /* low 8 bit part */
     38            uint8_t hx;                 /* high 8 bit */
     39            uint16_t hi16_unused2;
     40            uint32_t hi32_unused3;
     41        };
     42    };
     43} __attribute__ ((__packed__)) x86_register;
     44
     45typedef enum x86_reg_cr0 {
     46    CR0_PE =            (1L << 0),
     47    CR0_MP =            (1L << 1),
     48    CR0_EM =            (1L << 2),
     49    CR0_TS =            (1L << 3),
     50    CR0_ET =            (1L << 4),
     51    CR0_NE =            (1L << 5),
     52    CR0_WP =            (1L << 16),
     53    CR0_AM =            (1L << 18),
     54    CR0_NW =            (1L << 29),
     55    CR0_CD =            (1L << 30),
     56    CR0_PG =            (1L << 31),
     57} x86_reg_cr0;
     58
     59typedef enum x86_reg_cr4 {
     60    CR4_VME =            (1L << 0),
     61    CR4_PVI =            (1L << 1),
     62    CR4_TSD =            (1L << 2),
     63    CR4_DE  =            (1L << 3),
     64    CR4_PSE =            (1L << 4),
     65    CR4_PAE =            (1L << 5),
     66    CR4_MSE =            (1L << 6),
     67    CR4_PGE =            (1L << 7),
     68    CR4_PCE =            (1L << 8),
     69    CR4_OSFXSR =         (1L << 9),
     70    CR4_OSXMMEXCPT =     (1L << 10),
     71    CR4_VMXE =           (1L << 13),
     72    CR4_SMXE =           (1L << 14),
     73    CR4_FSGSBASE =       (1L << 16),
     74    CR4_PCIDE =          (1L << 17),
     75    CR4_OSXSAVE =        (1L << 18),
     76    CR4_SMEP =           (1L << 20),
     77} x86_reg_cr4;
     78
     79/* 16 bit Task State Segment */
     80typedef struct x86_tss_segment16 {
     81    uint16_t link;
     82    uint16_t sp0;
     83    uint16_t ss0;
     84    uint32_t sp1;
     85    uint16_t ss1;
     86    uint32_t sp2;
     87    uint16_t ss2;
     88    uint16_t ip;
     89    uint16_t flags;
     90    uint16_t ax;
     91    uint16_t cx;
     92    uint16_t dx;
     93    uint16_t bx;
     94    uint16_t sp;
     95    uint16_t bp;
     96    uint16_t si;
     97    uint16_t di;
     98    uint16_t es;
     99    uint16_t cs;
    100    uint16_t ss;
    101    uint16_t ds;
    102    uint16_t ldtr;
    103} __attribute__((packed)) x86_tss_segment16;
    104
    105/* 32 bit Task State Segment */
    106typedef struct x86_tss_segment32 {
    107    uint32_t prev_tss;
    108    uint32_t esp0;
    109    uint32_t ss0;
    110    uint32_t esp1;
    111    uint32_t ss1;
    112    uint32_t esp2;
    113    uint32_t ss2;
    114    uint32_t cr3;
    115    uint32_t eip;
    116    uint32_t eflags;
    117    uint32_t eax;
    118    uint32_t ecx;
    119    uint32_t edx;
    120    uint32_t ebx;
    121    uint32_t esp;
    122    uint32_t ebp;
    123    uint32_t esi;
    124    uint32_t edi;
    125    uint32_t es;
    126    uint32_t cs;
    127    uint32_t ss;
    128    uint32_t ds;
    129    uint32_t fs;
    130    uint32_t gs;
    131    uint32_t ldt;
    132    uint16_t trap;
    133    uint16_t iomap_base;
    134} __attribute__ ((__packed__)) x86_tss_segment32;
    135
    136/* 64 bit Task State Segment */
    137typedef struct x86_tss_segment64 {
    138    uint32_t unused;
    139    uint64_t rsp0;
    140    uint64_t rsp1;
    141    uint64_t rsp2;
    142    uint64_t unused1;
    143    uint64_t ist1;
    144    uint64_t ist2;
    145    uint64_t ist3;
    146    uint64_t ist4;
    147    uint64_t ist5;
    148    uint64_t ist6;
    149    uint64_t ist7;
    150    uint64_t unused2;
    151    uint16_t unused3;
    152    uint16_t iomap_base;
    153} __attribute__ ((__packed__)) x86_tss_segment64;
    154
    155/* segment descriptors */
    156typedef struct x86_segment_descriptor {
    157    uint64_t    limit0:16;
    158    uint64_t    base0:16;
    159    uint64_t    base1:8;
    160    uint64_t    type:4;
    161    uint64_t    s:1;
    162    uint64_t    dpl:2;
    163    uint64_t    p:1;
    164    uint64_t    limit1:4;
    165    uint64_t    avl:1;
    166    uint64_t    l:1;
    167    uint64_t    db:1;
    168    uint64_t    g:1;
    169    uint64_t    base2:8;
    170} __attribute__ ((__packed__)) x86_segment_descriptor;
    171
    172static inline uint32_t x86_segment_base(x86_segment_descriptor *desc)
    173{
    174    return (uint32_t)((desc->base2 << 24) | (desc->base1 << 16) | desc->base0);
    175}
    176
    177static inline void x86_set_segment_base(x86_segment_descriptor *desc,
    178                                        uint32_t base)
    179{
    180    desc->base2 = base >> 24;
    181    desc->base1 = (base >> 16) & 0xff;
    182    desc->base0 = base & 0xffff;
    183}
    184
    185static inline uint32_t x86_segment_limit(x86_segment_descriptor *desc)
    186{
    187    uint32_t limit = (uint32_t)((desc->limit1 << 16) | desc->limit0);
    188    if (desc->g) {
    189        return (limit << 12) | 0xfff;
    190    }
    191    return limit;
    192}
    193
    194static inline void x86_set_segment_limit(x86_segment_descriptor *desc,
    195                                         uint32_t limit)
    196{
    197    desc->limit0 = limit & 0xffff;
    198    desc->limit1 = limit >> 16;
    199}
    200
    201typedef struct x86_call_gate {
    202    uint64_t offset0:16;
    203    uint64_t selector:16;
    204    uint64_t param_count:4;
    205    uint64_t reserved:3;
    206    uint64_t type:4;
    207    uint64_t dpl:1;
    208    uint64_t p:1;
    209    uint64_t offset1:16;
    210} __attribute__ ((__packed__)) x86_call_gate;
    211
    212static inline uint32_t x86_call_gate_offset(x86_call_gate *gate)
    213{
    214    return (uint32_t)((gate->offset1 << 16) | gate->offset0);
    215}
    216
    217#define GDT_SEL     0
    218#define LDT_SEL     1
    219
    220typedef struct x68_segment_selector {
    221    union {
    222        uint16_t sel;
    223        struct {
    224            uint16_t rpl:2;
    225            uint16_t ti:1;
    226            uint16_t index:13;
    227        };
    228    };
    229} __attribute__ ((__packed__)) x68_segment_selector;
    230
    231/* useful register access  macros */
    232#define x86_reg(cpu, reg) ((x86_register *) &cpu->regs[reg])
    233
    234#define RRX(cpu, reg)   (x86_reg(cpu, reg)->rrx)
    235#define RAX(cpu)        RRX(cpu, R_EAX)
    236#define RCX(cpu)        RRX(cpu, R_ECX)
    237#define RDX(cpu)        RRX(cpu, R_EDX)
    238#define RBX(cpu)        RRX(cpu, R_EBX)
    239#define RSP(cpu)        RRX(cpu, R_ESP)
    240#define RBP(cpu)        RRX(cpu, R_EBP)
    241#define RSI(cpu)        RRX(cpu, R_ESI)
    242#define RDI(cpu)        RRX(cpu, R_EDI)
    243#define R8(cpu)         RRX(cpu, R_R8)
    244#define R9(cpu)         RRX(cpu, R_R9)
    245#define R10(cpu)        RRX(cpu, R_R10)
    246#define R11(cpu)        RRX(cpu, R_R11)
    247#define R12(cpu)        RRX(cpu, R_R12)
    248#define R13(cpu)        RRX(cpu, R_R13)
    249#define R14(cpu)        RRX(cpu, R_R14)
    250#define R15(cpu)        RRX(cpu, R_R15)
    251
    252#define ERX(cpu, reg)   (x86_reg(cpu, reg)->erx)
    253#define EAX(cpu)        ERX(cpu, R_EAX)
    254#define ECX(cpu)        ERX(cpu, R_ECX)
    255#define EDX(cpu)        ERX(cpu, R_EDX)
    256#define EBX(cpu)        ERX(cpu, R_EBX)
    257#define ESP(cpu)        ERX(cpu, R_ESP)
    258#define EBP(cpu)        ERX(cpu, R_EBP)
    259#define ESI(cpu)        ERX(cpu, R_ESI)
    260#define EDI(cpu)        ERX(cpu, R_EDI)
    261
    262#define RX(cpu, reg)   (x86_reg(cpu, reg)->rx)
    263#define AX(cpu)        RX(cpu, R_EAX)
    264#define CX(cpu)        RX(cpu, R_ECX)
    265#define DX(cpu)        RX(cpu, R_EDX)
    266#define BP(cpu)        RX(cpu, R_EBP)
    267#define SP(cpu)        RX(cpu, R_ESP)
    268#define BX(cpu)        RX(cpu, R_EBX)
    269#define SI(cpu)        RX(cpu, R_ESI)
    270#define DI(cpu)        RX(cpu, R_EDI)
    271
    272#define RL(cpu, reg)   (x86_reg(cpu, reg)->lx)
    273#define AL(cpu)        RL(cpu, R_EAX)
    274#define CL(cpu)        RL(cpu, R_ECX)
    275#define DL(cpu)        RL(cpu, R_EDX)
    276#define BL(cpu)        RL(cpu, R_EBX)
    277
    278#define RH(cpu, reg)   (x86_reg(cpu, reg)->hx)
    279#define AH(cpu)        RH(cpu, R_EAX)
    280#define CH(cpu)        RH(cpu, R_ECX)
    281#define DH(cpu)        RH(cpu, R_EDX)
    282#define BH(cpu)        RH(cpu, R_EBX)
    283
    284/* deal with GDT/LDT descriptors in memory */
    285bool x86_read_segment_descriptor(struct CPUState *cpu,
    286                                 struct x86_segment_descriptor *desc,
    287                                 x68_segment_selector sel);
    288bool x86_write_segment_descriptor(struct CPUState *cpu,
    289                                  struct x86_segment_descriptor *desc,
    290                                  x68_segment_selector sel);
    291
    292bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
    293                        int gate);
    294
    295/* helpers */
    296bool x86_is_protected(struct CPUState *cpu);
    297bool x86_is_real(struct CPUState *cpu);
    298bool x86_is_v8086(struct CPUState *cpu);
    299bool x86_is_long_mode(struct CPUState *cpu);
    300bool x86_is_long64_mode(struct CPUState *cpu);
    301bool x86_is_paging_mode(struct CPUState *cpu);
    302bool x86_is_pae_enabled(struct CPUState *cpu);
    303
    304enum X86Seg;
    305target_ulong linear_addr(struct CPUState *cpu, target_ulong addr, enum X86Seg seg);
    306target_ulong linear_addr_size(struct CPUState *cpu, target_ulong addr, int size,
    307                              enum X86Seg seg);
    308target_ulong linear_rip(struct CPUState *cpu, target_ulong rip);
    309
    310static inline uint64_t rdtscp(void)
    311{
    312    uint64_t tsc;
    313    __asm__ __volatile__("rdtscp; "         /* serializing read of tsc */
    314                         "shl $32,%%rdx; "  /* shift higher 32 bits stored in rdx up */
    315                         "or %%rdx,%%rax"   /* and or onto rax */
    316                         : "=a"(tsc)        /* output to tsc variable */
    317                         :
    318                         : "%rcx", "%rdx"); /* rcx and rdx are clobbered */
    319
    320    return tsc;
    321}
    322
    323#endif