Coverage Report

Created: 2026-07-10 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xen/xen/arch/x86/x86_emulate/private.h
Line
Count
Source
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
/******************************************************************************
3
 * private.h - interface between x86_emulate.c and its helpers
4
 *
5
 * Copyright (c) 2005-2007 Keir Fraser
6
 * Copyright (c) 2005-2007 XenSource Inc.
7
 */
8
9
#ifndef X86_EMULATE_PRIVATE_H
10
#define X86_EMULATE_PRIVATE_H
11
12
#ifdef __XEN__
13
14
# include <xen/bug.h>
15
# include <xen/kernel.h>
16
17
# include <asm/cpu-user-regs.h>
18
# include <asm/endbr.h>
19
# include <asm/msr-index.h>
20
# include <asm/stubs.h>
21
# include <asm/x86-vendors.h>
22
# include <asm/x86_emulate.h>
23
24
# undef BUG /* Make sure it's not used anywhere here. */
25
void BUG(void);
26
27
# ifndef CONFIG_HVM
28
#  define X86EMUL_NO_FPU
29
#  define X86EMUL_NO_MMX
30
#  define X86EMUL_NO_SIMD
31
# endif
32
33
#else /* !__XEN__ */
34
# include "x86-emulate.h"
35
#endif
36
37
#ifdef __i386__
38
# define mode_64bit() false
39
# define r(name) e ## name
40
# define PTR_POISON NULL /* 32-bit builds are for user-space, so NULL is OK. */
41
#else
42
1.28M
# define mode_64bit() (ctxt->addr_size == 64)
43
384k
# define r(name) r ## name
44
1.42M
# define PTR_POISON ((void *)0x8086000000008086UL) /* non-canonical */
45
#endif
46
47
/* Operand sizes: 8-bit operands or specified/overridden size. */
48
447k
#define ByteOp      (1<<0) /* 8-bit operands. */
49
/* Destination operand type. */
50
309k
#define DstNone     (0<<1) /* No destination operand. */
51
1.60k
#define DstImplicit (0<<1) /* Destination operand is implicit in the opcode. */
52
3.52k
#define DstBitBase  (1<<1) /* Memory operand, bit string. */
53
118k
#define DstReg      (2<<1) /* Register operand. */
54
13.6k
#define DstEax      DstReg /* Register EAX (aka DstReg with no ModRM) */
55
146k
#define DstMem      (3<<1) /* Memory operand. */
56
506k
#define DstMask     (3<<1)
57
/* Source operand type. */
58
235k
#define SrcNone     (0<<3) /* No source operand. */
59
1.80k
#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
60
64.9k
#define SrcReg      (1<<3) /* Register operand. */
61
#define SrcEax      SrcReg /* Register EAX (aka SrcReg with no ModRM) */
62
196k
#define SrcMem      (2<<3) /* Memory operand. */
63
39.6k
#define SrcMem16    (3<<3) /* Memory operand (16-bit). */
64
47.6k
#define SrcImm      (4<<3) /* Immediate operand. */
65
78.7k
#define SrcImmByte  (5<<3) /* 8-bit sign-extended immediate operand. */
66
2.42k
#define SrcImm16    (6<<3) /* 16-bit zero-extended immediate operand. */
67
969k
#define SrcMask     (7<<3)
68
/* Generic ModRM decode. */
69
1.26M
#define ModRM       (1<<6)
70
/* vSIB addressing mode (0f38 extension opcodes only), aliasing ModRM. */
71
438
#define vSIB        (1<<6)
72
/* Destination is only written; never read. */
73
177k
#define Mov         (1<<7)
74
/* VEX/EVEX (SIMD only): 2nd source operand unused (must be all ones) */
75
22.1k
#define TwoOp       Mov
76
/* All operands are implicit in the opcode. */
77
10
#define ImplicitOps (DstImplicit|SrcImplicit)
78
79
typedef uint8_t opcode_desc_t;
80
81
enum disp8scale {
82
    /* Values 0 ... 4 are explicit sizes. */
83
    d8s_bw = 5,
84
    d8s_dq,
85
    /* EVEX.W ignored outside of 64-bit mode */
86
    d8s_dq64,
87
    /*
88
     * All further values must strictly be last and in the order
89
     * given so that arithmetic on the values works.
90
     */
91
    d8s_vl,
92
    d8s_vl_by_2,
93
    d8s_vl_by_4,
94
    d8s_vl_by_8,
95
};
96
typedef uint8_t disp8scale_t;
97
98
/* Type, address-of, and value of an instruction's operand. */
99
struct operand {
100
    enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
101
    unsigned int bytes;
102
103
    /* Operand value. */
104
    unsigned long val;
105
106
    /* Original operand value. */
107
    unsigned long orig_val;
108
109
    /* OP_REG: Pointer to register field. */
110
    unsigned long *reg;
111
112
    /* OP_MEM: Segment and offset. */
113
    struct {
114
        enum x86_segment seg;
115
        unsigned long    off;
116
    } mem;
117
};
118
119
#if defined(__x86_64__)
120
86.4k
#define REX_PREFIX 0x40
121
38.9k
#define REX_B 0x01
122
1.98k
#define REX_X 0x02
123
9.82k
#define REX_R 0x04
124
474k
#define REX_W 0x08
125
#elif defined(__i386__)
126
#define REX_PREFIX 0
127
#define REX_B 0
128
#define REX_X 0
129
#define REX_R 0
130
#define REX_W 0
131
#endif
132
133
enum simd_opsize {
134
    simd_none,
135
136
    /*
137
     * Ordinary packed integers:
138
     * - 64 bits without prefix 66 (MMX)
139
     * - 128 bits with prefix 66 (SSEn)
140
     * - 128/256/512 bits depending on VEX.L/EVEX.LR (AVX+)
141
     */
142
    simd_packed_int,
143
144
    /*
145
     * Ordinary packed/scalar floating point:
146
     * - 128 bits without prefix or with prefix 66 (SSEn)
147
     * - 128/256/512 bits depending on VEX.L/EVEX.LR (AVX+)
148
     * - 32 bits with prefix F3 (scalar single)
149
     * - 64 bits with prefix F2 (scalar doubgle)
150
     */
151
    simd_any_fp,
152
153
    /*
154
     * Packed floating point:
155
     * - 128 bits without prefix or with prefix 66 (SSEn)
156
     * - 128/256/512 bits depending on VEX.L/EVEX.LR (AVX+)
157
     */
158
    simd_packed_fp,
159
160
    /*
161
     * Single precision packed/scalar floating point:
162
     * - 128 bits without prefix (SSEn)
163
     * - 128/256/512 bits depending on VEX.L/EVEX.LR (AVX+)
164
     * - 32 bits with prefix F3 (scalar)
165
     */
166
    simd_single_fp,
167
168
    /*
169
     * Scalar floating point:
170
     * - 32 bits with low opcode bit clear (scalar single)
171
     * - 64 bits with low opcode bit set (scalar double)
172
     */
173
    simd_scalar_opc,
174
175
    /*
176
     * Scalar floating point:
177
     * - 32/64 bits depending on VEX.W/EVEX.W
178
     */
179
    simd_scalar_vexw,
180
181
    /*
182
     * 128 bits of integer or floating point data, with no further
183
     * formatting information, or with it encoded by EVEX.W.
184
     */
185
    simd_128,
186
187
    /*
188
     * 256 bits of integer or floating point data, with formatting
189
     * encoded by EVEX.W.
190
     */
191
    simd_256,
192
193
    /* Operand size encoded in non-standard way. */
194
    simd_other
195
};
196
typedef uint8_t simd_opsize_t;
197
198
166k
#define vex_none 0
199
200
enum vex_opcx {
201
    vex_0f = vex_none + 1,
202
    vex_0f38,
203
    vex_0f3a,
204
    evex_map5 = 5,
205
    evex_map6,
206
};
207
208
enum vex_pfx {
209
    vex_66 = vex_none + 1,
210
    vex_f3,
211
    vex_f2
212
};
213
214
19.9k
#define VEX_PREFIX_DOUBLE_MASK 0x1
215
29.3k
#define VEX_PREFIX_SCALAR_MASK 0x2
216
217
union vex {
218
    uint8_t raw[2];
219
    struct {             /* SDM names */
220
        uint8_t opcx:5;  /* mmmmm */
221
        uint8_t b:1;     /* B */
222
        uint8_t x:1;     /* X */
223
        uint8_t r:1;     /* R */
224
        uint8_t pfx:2;   /* pp */
225
        uint8_t l:1;     /* L */
226
        uint8_t reg:4;   /* vvvv */
227
        uint8_t w:1;     /* W */
228
    };
229
};
230
231
union evex {
232
    uint8_t raw[3];
233
    struct {             /* SDM names */
234
        uint8_t opcx:3;  /* mmm */
235
        uint8_t mbz:1;
236
        uint8_t R:1;     /* R' */
237
        uint8_t b:1;     /* B */
238
        uint8_t x:1;     /* X */
239
        uint8_t r:1;     /* R */
240
        uint8_t pfx:2;   /* pp */
241
        uint8_t mbs:1;
242
        uint8_t reg:4;   /* vvvv */
243
        uint8_t w:1;     /* W */
244
        uint8_t opmsk:3; /* aaa */
245
        uint8_t RX:1;    /* V' */
246
        uint8_t brs:1;   /* b */
247
        uint8_t lr:2;    /* L'L */
248
        uint8_t z:1;     /* z */
249
    };
250
};
251
252
struct x86_emulate_state {
253
    unsigned int op_bytes, ad_bytes;
254
255
    enum {
256
        ext_none = vex_none,
257
        ext_0f   = vex_0f,
258
        ext_0f38 = vex_0f38,
259
        ext_0f3a = vex_0f3a,
260
        ext_map5 = evex_map5,
261
        ext_map6 = evex_map6,
262
        /*
263
         * For XOP use values such that the respective instruction field
264
         * can be used without adjustment.
265
         */
266
        ext_8f08 = 8,
267
        ext_8f09,
268
        ext_8f0a,
269
    } ext;
270
    enum {
271
        rmw_NONE,
272
        rmw_adc,
273
        rmw_add,
274
        rmw_and,
275
        rmw_btc,
276
        rmw_btr,
277
        rmw_bts,
278
        rmw_cmpccxadd,
279
        rmw_dec,
280
        rmw_inc,
281
        rmw_neg,
282
        rmw_not,
283
        rmw_or,
284
        rmw_rcl,
285
        rmw_rcr,
286
        rmw_rol,
287
        rmw_ror,
288
        rmw_sar,
289
        rmw_sbb,
290
        rmw_shl,
291
        rmw_shld,
292
        rmw_shr,
293
        rmw_shrd,
294
        rmw_sub,
295
        rmw_xadd,
296
        rmw_xchg,
297
        rmw_xor,
298
    } rmw;
299
    enum {
300
        blk_NONE,
301
        blk_enqcmd,
302
#ifndef X86EMUL_NO_FPU
303
        blk_fld, /* FLDENV, FRSTOR */
304
        blk_fst, /* FNSTENV, FNSAVE */
305
#endif
306
#if !defined(X86EMUL_NO_FPU) || !defined(X86EMUL_NO_MMX) || \
307
    !defined(X86EMUL_NO_SIMD)
308
        blk_fxrstor,
309
        blk_fxsave,
310
#endif
311
        blk_movdir,
312
    } blk;
313
    uint8_t modrm, modrm_mod, modrm_reg, modrm_rm;
314
    uint8_t sib_index, sib_scale;
315
    uint8_t rex_prefix;
316
    bool lock_prefix;
317
    bool not_64bit; /* Instruction not available in 64bit. */
318
    bool fpu_ctrl;  /* Instruction is an FPU control one. */
319
    bool fp16;      /* Instruction has half-precision FP source operand. */
320
    opcode_desc_t desc;
321
    union vex vex;
322
    union evex evex;
323
    enum simd_opsize simd_size;
324
325
    /*
326
     * Data operand effective address (usually computed from ModRM).
327
     * Default is a memory operand relative to segment DS.
328
     */
329
    struct operand ea;
330
331
    /* Immediate operand values, if any. Use otherwise unused fields. */
332
60.3k
#define imm1 ea.val
333
2.09k
#define imm2 ea.orig_val
334
335
    unsigned long ip;
336
337
    struct stub_exn *stub_exn;
338
339
#ifndef NDEBUG
340
    /*
341
     * Track caller of x86_decode_insn() to spot missing as well as
342
     * premature calls to x86_emulate_free_state().
343
     */
344
    void *caller;
345
#endif
346
};
347
348
static inline void check_state(const struct x86_emulate_state *s)
349
0
{
350
0
#if defined(__XEN__) && !defined(NDEBUG)
351
0
    ASSERT(s->caller);
352
0
#endif
353
0
}
Unexecuted instantiation: x86-emulate.c:check_state
Unexecuted instantiation: 0f01.c:check_state
Unexecuted instantiation: 0fae.c:check_state
Unexecuted instantiation: 0fc7.c:check_state
Unexecuted instantiation: decode.c:check_state
Unexecuted instantiation: fpu.c:check_state
354
355
typedef union {
356
    uint64_t mmx;
357
    uint64_t __attribute__ ((aligned(16))) xmm[2];
358
    uint64_t __attribute__ ((aligned(32))) ymm[4];
359
    uint64_t __attribute__ ((aligned(64))) zmm[8];
360
    uint32_t data32[16];
361
} mmval_t;
362
363
struct x86_fxsr {
364
    uint16_t fcw;
365
    uint16_t fsw;
366
    uint8_t ftw, :8;
367
    uint16_t fop;
368
    union {
369
        struct {
370
            uint32_t offs;
371
            uint16_t sel, :16;
372
        };
373
        uint64_t addr;
374
    } fip, fdp;
375
    uint32_t mxcsr;
376
    uint32_t mxcsr_mask;
377
    struct {
378
        uint8_t data[10];
379
        uint16_t :16, :16, :16;
380
    } fpreg[8];
381
    uint64_t __attribute__ ((aligned(16))) xmm[16][2];
382
    uint64_t rsvd[6];
383
    uint64_t avl[6];
384
};
385
386
#ifndef X86EMUL_NO_FPU
387
struct x87_env16 {
388
    uint16_t fcw;
389
    uint16_t fsw;
390
    uint16_t ftw;
391
    union {
392
        struct {
393
            uint16_t fip_lo;
394
            uint16_t fop:11, :1, fip_hi:4;
395
            uint16_t fdp_lo;
396
            uint16_t :12, fdp_hi:4;
397
        } real;
398
        struct {
399
            uint16_t fip;
400
            uint16_t fcs;
401
            uint16_t fdp;
402
            uint16_t fds;
403
        } prot;
404
    } mode;
405
};
406
407
struct x87_env32 {
408
    uint32_t fcw:16, :16;
409
    uint32_t fsw:16, :16;
410
    uint32_t ftw:16, :16;
411
    union {
412
        struct {
413
            /* some CPUs/FPUs also store the full FIP here */
414
            uint32_t fip_lo:16, :16;
415
            uint32_t fop:11, :1, fip_hi:16, :4;
416
            /* some CPUs/FPUs also store the full FDP here */
417
            uint32_t fdp_lo:16, :16;
418
            uint32_t :12, fdp_hi:16, :4;
419
        } real;
420
        struct {
421
            uint32_t fip;
422
            uint32_t fcs:16, fop:11, :5;
423
            uint32_t fdp;
424
            uint32_t fds:16, :16;
425
        } prot;
426
    } mode;
427
};
428
#endif
429
430
/*
431
 * Externally visible return codes from x86_emulate() are non-negative.
432
 * Use negative values for internal state change indicators from helpers
433
 * to the main function.
434
 */
435
132
#define X86EMUL_rdtsc        (-1)
436
#define X86EMUL_stub_failure (-2)
437
438
/*
439
 * These EFLAGS bits are restored from saved value during emulation, and
440
 * any changes are written back to the saved value after emulation.
441
 */
442
143k
#define EFLAGS_MASK (X86_EFLAGS_OF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \
443
143k
                     X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF)
444
445
/*
446
 * These EFLAGS bits are modifiable (by POPF and IRET), possibly subject
447
 * to further CPL and IOPL constraints.
448
 */
449
2.16k
#define EFLAGS_MODIFIABLE (X86_EFLAGS_ID | X86_EFLAGS_AC | X86_EFLAGS_RF | \
450
2.16k
                           X86_EFLAGS_NT | X86_EFLAGS_IOPL | X86_EFLAGS_DF | \
451
2.16k
                           X86_EFLAGS_IF | X86_EFLAGS_TF | EFLAGS_MASK)
452
453
363k
#define truncate_word(ea, byte_width)           \
454
363k
({  unsigned long __ea = (ea);                  \
455
363k
    unsigned int _width = (byte_width);         \
456
363k
    ((_width == sizeof(unsigned long)) ? __ea : \
457
363k
     (__ea & ((1UL << (_width << 3)) - 1)));    \
458
363k
})
459
316k
#define truncate_ea(ea) truncate_word((ea), ad_bytes)
460
461
657k
#define fail_if(p)                                      \
462
657k
do {                                                    \
463
657k
    rc = (p) ? X86EMUL_UNHANDLEABLE : X86EMUL_OKAY;     \
464
657k
    if ( rc ) goto done;                                \
465
657k
} while (0)
466
467
180k
#define EXPECT(p)                                       \
468
180k
do {                                                    \
469
180k
    if ( unlikely(!(p)) )                               \
470
180k
    {                                                   \
471
0
        ASSERT_UNREACHABLE();                           \
472
0
        goto unhandleable;                              \
473
0
    }                                                   \
474
180k
} while (0)
475
476
static inline int mkec(uint8_t e, int32_t ec, ...)
477
3.53k
{
478
3.53k
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
3.53k
}
x86-emulate.c:mkec
Line
Count
Source
477
3.22k
{
478
3.22k
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
3.22k
}
0f01.c:mkec
Line
Count
Source
477
163
{
478
163
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
163
}
0fae.c:mkec
Line
Count
Source
477
38
{
478
38
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
38
}
0fc7.c:mkec
Line
Count
Source
477
6
{
478
6
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
6
}
decode.c:mkec
Line
Count
Source
477
64
{
478
64
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
64
}
fpu.c:mkec
Line
Count
Source
477
39
{
478
39
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
39
}
480
481
3.62M
#define generate_exception_if(p, e, ec...)                                \
482
5.66M
({  if ( (p) ) {                                                          \
483
3.53k
        x86_emul_hw_exception(e, mkec(e, ##ec, 0), ctxt);                 \
484
3.53k
        rc = X86EMUL_EXCEPTION;                                           \
485
3.53k
        goto done;                                                        \
486
3.53k
    }                                                                     \
487
287k
})
488
489
259
#define generate_exception(e, ec...) generate_exception_if(true, e, ##ec)
490
491
static inline bool
492
in_realmode(
493
    struct x86_emulate_ctxt *ctxt,
494
    const struct x86_emulate_ops *ops)
495
36.5k
{
496
36.5k
    unsigned long cr0;
497
36.5k
    int rc;
498
499
36.5k
    if ( ops->read_cr == NULL )
500
3.76k
        return 0;
501
502
32.7k
    rc = ops->read_cr(0, &cr0, ctxt);
503
32.7k
    return (!rc && !(cr0 & X86_CR0_PE));
504
36.5k
}
x86-emulate.c:in_realmode
Line
Count
Source
495
15.3k
{
496
15.3k
    unsigned long cr0;
497
15.3k
    int rc;
498
499
15.3k
    if ( ops->read_cr == NULL )
500
3.08k
        return 0;
501
502
12.2k
    rc = ops->read_cr(0, &cr0, ctxt);
503
12.2k
    return (!rc && !(cr0 & X86_CR0_PE));
504
15.3k
}
0f01.c:in_realmode
Line
Count
Source
495
778
{
496
778
    unsigned long cr0;
497
778
    int rc;
498
499
778
    if ( ops->read_cr == NULL )
500
221
        return 0;
501
502
557
    rc = ops->read_cr(0, &cr0, ctxt);
503
557
    return (!rc && !(cr0 & X86_CR0_PE));
504
778
}
Unexecuted instantiation: 0fae.c:in_realmode
Unexecuted instantiation: 0fc7.c:in_realmode
decode.c:in_realmode
Line
Count
Source
495
20.4k
{
496
20.4k
    unsigned long cr0;
497
20.4k
    int rc;
498
499
20.4k
    if ( ops->read_cr == NULL )
500
462
        return 0;
501
502
19.9k
    rc = ops->read_cr(0, &cr0, ctxt);
503
19.9k
    return (!rc && !(cr0 & X86_CR0_PE));
504
20.4k
}
Unexecuted instantiation: fpu.c:in_realmode
505
506
static inline bool
507
in_protmode(
508
    struct x86_emulate_ctxt *ctxt,
509
    const struct x86_emulate_ops *ops)
510
15.8k
{
511
15.8k
    return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM));
512
15.8k
}
x86-emulate.c:in_protmode
Line
Count
Source
510
15.0k
{
511
15.0k
    return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM));
512
15.0k
}
0f01.c:in_protmode
Line
Count
Source
510
778
{
511
778
    return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM));
512
778
}
Unexecuted instantiation: 0fae.c:in_protmode
Unexecuted instantiation: 0fc7.c:in_protmode
Unexecuted instantiation: decode.c:in_protmode
Unexecuted instantiation: fpu.c:in_protmode
513
514
4.44k
#define mode_ring0() ({                         \
515
4.44k
    int _cpl = x86emul_get_cpl(ctxt, ops);      \
516
4.44k
    fail_if(_cpl < 0);                          \
517
4.44k
    (_cpl == 0);                                \
518
3.03k
})
519
520
static inline bool
521
_amd_like(const struct cpu_policy *cp)
522
20.3k
{
523
20.3k
    return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
524
20.3k
}
x86-emulate.c:_amd_like
Line
Count
Source
522
16.1k
{
523
16.1k
    return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
524
16.1k
}
Unexecuted instantiation: 0f01.c:_amd_like
Unexecuted instantiation: 0fae.c:_amd_like
Unexecuted instantiation: 0fc7.c:_amd_like
decode.c:_amd_like
Line
Count
Source
522
4.14k
{
523
4.14k
    return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
524
4.14k
}
Unexecuted instantiation: fpu.c:_amd_like
525
526
static inline bool
527
amd_like(const struct x86_emulate_ctxt *ctxt)
528
16.0k
{
529
16.0k
    return _amd_like(ctxt->cpu_policy);
530
16.0k
}
x86-emulate.c:amd_like
Line
Count
Source
528
11.8k
{
529
11.8k
    return _amd_like(ctxt->cpu_policy);
530
11.8k
}
Unexecuted instantiation: 0f01.c:amd_like
Unexecuted instantiation: 0fae.c:amd_like
Unexecuted instantiation: 0fc7.c:amd_like
decode.c:amd_like
Line
Count
Source
528
4.14k
{
529
4.14k
    return _amd_like(ctxt->cpu_policy);
530
4.14k
}
Unexecuted instantiation: fpu.c:amd_like
531
532
#define vcpu_has_fpu()         (ctxt->cpuid->basic.fpu)
533
#define vcpu_has_sep()         (ctxt->cpuid->basic.sep)
534
#define vcpu_has_cx8()         (ctxt->cpuid->basic.cx8)
535
#define vcpu_has_cmov()        (ctxt->cpuid->basic.cmov)
536
#define vcpu_has_clflush()     (ctxt->cpuid->basic.clflush)
537
#define vcpu_has_mmx()         (ctxt->cpuid->basic.mmx)
538
#define vcpu_has_fxsr()        (ctxt->cpuid->basic.fxsr)
539
#define vcpu_has_sse()         (ctxt->cpuid->basic.sse)
540
#define vcpu_has_sse2()        (ctxt->cpuid->basic.sse2)
541
#define vcpu_has_sse3()        (ctxt->cpuid->basic.sse3)
542
#define vcpu_has_pclmulqdq()   (ctxt->cpuid->basic.pclmulqdq)
543
#define vcpu_has_ssse3()       (ctxt->cpuid->basic.ssse3)
544
#define vcpu_has_fma()         (ctxt->cpuid->basic.fma)
545
#define vcpu_has_cx16()        (ctxt->cpuid->basic.cx16)
546
#define vcpu_has_sse4_1()      (ctxt->cpuid->basic.sse4_1)
547
#define vcpu_has_sse4_2()      (ctxt->cpuid->basic.sse4_2)
548
#define vcpu_has_movbe()       (ctxt->cpuid->basic.movbe)
549
#define vcpu_has_popcnt()      (ctxt->cpuid->basic.popcnt)
550
#define vcpu_has_aesni()       (ctxt->cpuid->basic.aesni)
551
#define vcpu_has_avx()         (ctxt->cpuid->basic.avx)
552
#define vcpu_has_f16c()        (ctxt->cpuid->basic.f16c)
553
#define vcpu_has_rdrand()      (ctxt->cpuid->basic.rdrand)
554
555
#define vcpu_has_mmxext()      (ctxt->cpuid->extd.mmxext || vcpu_has_sse())
556
#define vcpu_has_3dnow_ext()   (ctxt->cpuid->extd._3dnowext)
557
#define vcpu_has_3dnow()       (ctxt->cpuid->extd._3dnow)
558
#define vcpu_has_lahf_lm()     (ctxt->cpuid->extd.lahf_lm)
559
1
#define vcpu_has_cr8_legacy()  (ctxt->cpuid->extd.cr8_legacy)
560
#define vcpu_has_lzcnt()       (ctxt->cpuid->extd.abm)
561
#define vcpu_has_sse4a()       (ctxt->cpuid->extd.sse4a)
562
7.17k
#define vcpu_has_misalignsse() (ctxt->cpuid->extd.misalignsse)
563
#define vcpu_has_xop()         (ctxt->cpuid->extd.xop)
564
#define vcpu_has_fma4()        (ctxt->cpuid->extd.fma4)
565
#define vcpu_has_tbm()         (ctxt->cpuid->extd.tbm)
566
#define vcpu_has_clzero()      (ctxt->cpuid->extd.clzero)
567
53
#define vcpu_has_wbnoinvd()    (ctxt->cpuid->extd.wbnoinvd)
568
1.38k
#define vcpu_has_nscb()        (ctxt->cpuid->extd.nscb)
569
#define vcpu_has_avx512_bmm()  (ctxt->cpuid->extd.avx512_bmm)
570
571
#define vcpu_has_bmi1()        (ctxt->cpuid->feat.bmi1)
572
#define vcpu_has_hle()         (ctxt->cpuid->feat.hle)
573
#define vcpu_has_avx2()        (ctxt->cpuid->feat.avx2)
574
#define vcpu_has_bmi2()        (ctxt->cpuid->feat.bmi2)
575
#define vcpu_has_invpcid()     (ctxt->cpuid->feat.invpcid)
576
639
#define vcpu_has_rtm()         (ctxt->cpuid->feat.rtm)
577
0
#define vcpu_has_mpx()         (ctxt->cpuid->feat.mpx)
578
#define vcpu_has_avx512f()     (ctxt->cpuid->feat.avx512f)
579
#define vcpu_has_avx512dq()    (ctxt->cpuid->feat.avx512dq)
580
#define vcpu_has_rdseed()      (ctxt->cpuid->feat.rdseed)
581
#define vcpu_has_adx()         (ctxt->cpuid->feat.adx)
582
#define vcpu_has_smap()        (ctxt->cpuid->feat.smap)
583
#define vcpu_has_avx512_ifma() (ctxt->cpuid->feat.avx512_ifma)
584
#define vcpu_has_clflushopt()  (ctxt->cpuid->feat.clflushopt)
585
#define vcpu_has_clwb()        (ctxt->cpuid->feat.clwb)
586
#define vcpu_has_avx512cd()    (ctxt->cpuid->feat.avx512cd)
587
#define vcpu_has_sha()         (ctxt->cpuid->feat.sha)
588
#define vcpu_has_avx512bw()    (ctxt->cpuid->feat.avx512bw)
589
#define vcpu_has_avx512vl()    (ctxt->cpuid->feat.avx512vl)
590
#define vcpu_has_avx512_vbmi() (ctxt->cpuid->feat.avx512_vbmi)
591
#define vcpu_has_avx512_vbmi2() (ctxt->cpuid->feat.avx512_vbmi2)
592
#define vcpu_has_gfni()        (ctxt->cpuid->feat.gfni)
593
#define vcpu_has_vaes()        (ctxt->cpuid->feat.vaes)
594
#define vcpu_has_vpclmulqdq()  (ctxt->cpuid->feat.vpclmulqdq)
595
#define vcpu_has_avx512_vnni() (ctxt->cpuid->feat.avx512_vnni)
596
#define vcpu_has_avx512_bitalg() (ctxt->cpuid->feat.avx512_bitalg)
597
#define vcpu_has_avx512_vpopcntdq() (ctxt->cpuid->feat.avx512_vpopcntdq)
598
#define vcpu_has_rdpid()       (ctxt->cpuid->feat.rdpid)
599
#define vcpu_has_movdiri()     (ctxt->cpuid->feat.movdiri)
600
#define vcpu_has_movdir64b()   (ctxt->cpuid->feat.movdir64b)
601
#define vcpu_has_enqcmd()      (ctxt->cpuid->feat.enqcmd)
602
#define vcpu_has_avx512_vp2intersect() (ctxt->cpuid->feat.avx512_vp2intersect)
603
#define vcpu_has_serialize()   (ctxt->cpuid->feat.serialize)
604
#define vcpu_has_tsxldtrk()    (ctxt->cpuid->feat.tsxldtrk)
605
#define vcpu_has_avx512_fp16() (ctxt->cpuid->feat.avx512_fp16)
606
#define vcpu_has_sha512()      (ctxt->cpuid->feat.sha512)
607
#define vcpu_has_sm3()         (ctxt->cpuid->feat.sm3)
608
#define vcpu_has_sm4()         (ctxt->cpuid->feat.sm4)
609
#define vcpu_has_avx_vnni()    (ctxt->cpuid->feat.avx_vnni)
610
#define vcpu_has_avx512_bf16() (ctxt->cpuid->feat.avx512_bf16)
611
#define vcpu_has_cmpccxadd()   (ctxt->cpuid->feat.cmpccxadd)
612
#define vcpu_has_lkgs()        (ctxt->cpuid->feat.lkgs)
613
#define vcpu_has_wrmsrns()     (ctxt->cpuid->feat.wrmsrns)
614
#define vcpu_has_avx_ifma()    (ctxt->cpuid->feat.avx_ifma)
615
#define vcpu_has_avx_vnni_int8() (ctxt->cpuid->feat.avx_vnni_int8)
616
#define vcpu_has_avx_ne_convert() (ctxt->cpuid->feat.avx_ne_convert)
617
#define vcpu_has_avx_vnni_int16() (ctxt->cpuid->feat.avx_vnni_int16)
618
619
#define vcpu_must_have(feat) \
620
190k
    generate_exception_if(!vcpu_has_##feat(), X86_EXC_UD)
621
622
#ifdef __XEN__
623
/*
624
 * Note the difference between vcpu_must_have(<feature>) and
625
 * host_and_vcpu_must_have(<feature>): The latter needs to be used when
626
 * emulation code is using the same instruction class for carrying out
627
 * the actual operation.
628
 */
629
# define host_and_vcpu_must_have(feat) ({ \
630
    generate_exception_if(!cpu_has_##feat, X86_EXC_UD); \
631
    vcpu_must_have(feat); \
632
})
633
#else
634
/*
635
 * For the test harness both are fine to be used interchangeably, i.e.
636
 * features known to always be available (e.g. SSE/SSE2) to (64-bit) Xen
637
 * may be checked for by just vcpu_must_have().
638
 */
639
124k
# define host_and_vcpu_must_have(feat) vcpu_must_have(feat)
640
#endif
641
642
/*
643
 * Instruction emulation:
644
 * Most instructions are emulated directly via a fragment of inline assembly
645
 * code. This allows us to save/restore EFLAGS and thus very easily pick up
646
 * any modified flags.
647
 */
648
649
#if defined(__x86_64__)
650
#define _LO32 "k"          /* force 32-bit operand */
651
#define _STK  "%%rsp"      /* stack pointer */
652
#elif defined(__i386__)
653
#define _LO32 ""           /* force 32-bit operand */
654
#define _STK  "%%esp"      /* stack pointer */
655
#endif
656
657
/* Before executing instruction: restore necessary bits in EFLAGS. */
658
#define _PRE_EFLAGS(_sav, _msk, _tmp)                           \
659
/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
660
"movl %"_LO32 _sav",%"_LO32 _tmp"; "                            \
661
"push %"_tmp"; "                                                \
662
"push %"_tmp"; "                                                \
663
"movl %"_msk",%"_LO32 _tmp"; "                                  \
664
"andl %"_LO32 _tmp",("_STK"); "                                 \
665
"pushf; "                                                       \
666
"notl %"_LO32 _tmp"; "                                          \
667
"andl %"_LO32 _tmp",("_STK"); "                                 \
668
"andl %"_LO32 _tmp", 2 * " STR(__SIZEOF_LONG__) "("_STK"); "    \
669
"pop  %"_tmp"; "                                                \
670
"orl  %"_LO32 _tmp",("_STK"); "                                 \
671
"popf; "                                                        \
672
"pop  %"_tmp"; "                                                \
673
"movl %"_LO32 _tmp",%"_LO32 _sav"; "
674
675
/* After executing instruction: write-back necessary bits in EFLAGS. */
676
#define _POST_EFLAGS(_sav, _msk, _tmp)          \
677
/* _sav |= EFLAGS & _msk; */                    \
678
"pushf; "                                       \
679
"pop  %"_tmp"; "                                \
680
"andl %"_msk",%"_LO32 _tmp"; "                  \
681
"orl  %"_LO32 _tmp",%"_LO32 _sav"; "
682
683
#ifdef __XEN__
684
685
# include <xen/domain_page.h>
686
# include <asm/uaccess.h>
687
688
# define get_stub(stb) ({                                    \
689
    void *_ptr;                                              \
690
    BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX_INST_LEN + 1);      \
691
    ASSERT(!(stb).ptr);                                      \
692
    (stb).addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;   \
693
    (stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn))) + \
694
        ((stb).addr & ~PAGE_MASK);                           \
695
    _ptr = memset((stb).ptr, 0xcc, STUB_BUF_SIZE / 2);       \
696
    if ( cpu_has_xen_ibt )                                   \
697
    {                                                        \
698
        place_endbr64(_ptr);                                 \
699
        _ptr += 4;                                           \
700
    }                                                        \
701
    _ptr;                                                    \
702
})
703
704
# define put_stub(stb) ({             \
705
    if ( (stb).ptr )                  \
706
    {                                 \
707
        unmap_domain_page((stb).ptr); \
708
        (stb).ptr = NULL;             \
709
    }                                 \
710
})
711
712
713
struct stub_exn {
714
    union stub_exception_token info;
715
    unsigned int line;
716
};
717
718
# define invoke_stub(pre, post, constraints...) do {                    \
719
    stub_exn.info = (union stub_exception_token) { .raw = ~0 };         \
720
    stub_exn.line = __LINE__; /* Utility outweighs livepatching cost */ \
721
    block_speculation(); /* SCSB */                                     \
722
    asm volatile ( pre "\n\t"                                           \
723
                   "INDIRECT_CALL %[stub]\n"                            \
724
                   ".Lret%=:\n\t"                                       \
725
                   post "\n\t"                                          \
726
                   ".Lskip%=:\n\t"                                      \
727
                   ".pushsection .fixup,\"ax\"\n"                       \
728
                   ".Lfix%=:\n\t"                                       \
729
                   "pop %[exn]\n\t"                                     \
730
                   "jmp .Lskip%=\n\t"                                   \
731
                   ".popsection\n\t"                                    \
732
                   _ASM_EXTABLE(.Lret%=, .Lfix%=)                       \
733
                   : [exn] "+g" (stub_exn.info) ASM_CALL_CONSTRAINT,    \
734
                     constraints,                                       \
735
                     [stub] "r" (stub.func),                            \
736
                     "m" (*(uint8_t(*)[MAX_INST_LEN + 1])stub.ptr) );   \
737
    if ( unlikely(~stub_exn.info.raw) )                                 \
738
        goto emulation_stub_failure;                                    \
739
} while (0)
740
741
#else /* !__XEN__ */
742
743
146k
# define get_stub(stb) ({                        \
744
146k
    assert(!(stb).addr);                         \
745
146k
    (void *)((stb).addr = (uintptr_t)(stb).buf); \
746
146k
})
747
748
667k
# define put_stub(stb) ((stb).addr = 0)
749
750
struct stub_exn {};
751
752
# define invoke_stub(pre, post, constraints...)                         \
753
145k
    asm volatile ( pre "\n\tcall *%[stub]\n\t" post                     \
754
145k
                   : constraints, [stub] "rm" (stub.func),              \
755
145k
                     "m" (*(typeof(stub.buf) *)stub.addr) )
756
757
#endif /* __XEN__ */
758
759
int x86emul_get_cpl(struct x86_emulate_ctxt *ctxt,
760
                    const struct x86_emulate_ops *ops);
761
762
int x86emul_get_fpu(enum x86_emulate_fpu_type type,
763
                    struct x86_emulate_ctxt *ctxt,
764
                    const struct x86_emulate_ops *ops);
765
766
144k
#define get_fpu(type)                                           \
767
144k
do {                                                            \
768
144k
    rc = x86emul_get_fpu(fpu_type = (type), ctxt, ops);         \
769
144k
    if ( rc ) goto done;                                        \
770
144k
} while (0)
771
772
int x86emul_decode(struct x86_emulate_state *s,
773
                   struct x86_emulate_ctxt *ctxt,
774
                   const struct x86_emulate_ops *ops);
775
776
int x86emul_fpu(struct x86_emulate_state *s,
777
                struct cpu_user_regs *regs,
778
                struct operand *dst,
779
                struct operand *src,
780
                struct x86_emulate_ctxt *ctxt,
781
                const struct x86_emulate_ops *ops,
782
                unsigned int *insn_bytes,
783
                enum x86_emulate_fpu_type *fpu_type,
784
                mmval_t *mmvalp);
785
int x86emul_0f01(struct x86_emulate_state *s,
786
                 struct cpu_user_regs *regs,
787
                 struct operand *dst,
788
                 struct x86_emulate_ctxt *ctxt,
789
                 const struct x86_emulate_ops *ops);
790
int x86emul_0fae(struct x86_emulate_state *s,
791
                 struct cpu_user_regs *regs,
792
                 struct operand *dst,
793
                 const struct operand *src,
794
                 struct x86_emulate_ctxt *ctxt,
795
                 const struct x86_emulate_ops *ops,
796
                 enum x86_emulate_fpu_type *fpu_type);
797
int x86emul_0fc7(struct x86_emulate_state *s,
798
                 struct cpu_user_regs *regs,
799
                 struct operand *dst,
800
                 struct x86_emulate_ctxt *ctxt,
801
                 const struct x86_emulate_ops *ops,
802
                 mmval_t *mmvalp);
803
804
/* Initialise output state in x86_emulate_ctxt */
805
static inline void init_context(struct x86_emulate_ctxt *ctxt)
806
475k
{
807
475k
    ctxt->retire.raw = 0;
808
475k
    x86_emul_reset_event(ctxt);
809
475k
}
x86-emulate.c:init_context
Line
Count
Source
806
475k
{
807
475k
    ctxt->retire.raw = 0;
808
475k
    x86_emul_reset_event(ctxt);
809
475k
}
Unexecuted instantiation: 0f01.c:init_context
Unexecuted instantiation: 0fae.c:init_context
Unexecuted instantiation: 0fc7.c:init_context
Unexecuted instantiation: decode.c:init_context
Unexecuted instantiation: fpu.c:init_context
810
811
static inline bool is_aligned(enum x86_segment seg, unsigned long offs,
812
                              unsigned int size, struct x86_emulate_ctxt *ctxt,
813
                              const struct x86_emulate_ops *ops)
814
7.40k
{
815
7.40k
    struct segment_register reg;
816
817
    /* Expecting powers of two only. */
818
7.40k
    ASSERT(!(size & (size - 1)));
819
820
7.40k
    if ( mode_64bit() && seg < x86_seg_fs )
821
945
        memset(&reg, 0, sizeof(reg));
822
6.45k
    else
823
6.45k
    {
824
        /* No alignment checking when we have no way to read segment data. */
825
6.45k
        if ( !ops->read_segment )
826
4.24k
            return true;
827
828
2.21k
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
829
0
            return false;
830
2.21k
    }
831
832
3.15k
    return !((reg.base + offs) & (size - 1));
833
7.40k
}
x86-emulate.c:is_aligned
Line
Count
Source
814
7.17k
{
815
7.17k
    struct segment_register reg;
816
817
    /* Expecting powers of two only. */
818
7.17k
    ASSERT(!(size & (size - 1)));
819
820
7.17k
    if ( mode_64bit() && seg < x86_seg_fs )
821
793
        memset(&reg, 0, sizeof(reg));
822
6.38k
    else
823
6.38k
    {
824
        /* No alignment checking when we have no way to read segment data. */
825
6.38k
        if ( !ops->read_segment )
826
4.19k
            return true;
827
828
2.18k
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
829
0
            return false;
830
2.18k
    }
831
832
2.98k
    return !((reg.base + offs) & (size - 1));
833
7.17k
}
Unexecuted instantiation: 0f01.c:is_aligned
0fae.c:is_aligned
Line
Count
Source
814
5
{
815
5
    struct segment_register reg;
816
817
    /* Expecting powers of two only. */
818
5
    ASSERT(!(size & (size - 1)));
819
820
5
    if ( mode_64bit() && seg < x86_seg_fs )
821
2
        memset(&reg, 0, sizeof(reg));
822
3
    else
823
3
    {
824
        /* No alignment checking when we have no way to read segment data. */
825
3
        if ( !ops->read_segment )
826
1
            return true;
827
828
2
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
829
0
            return false;
830
2
    }
831
832
4
    return !((reg.base + offs) & (size - 1));
833
5
}
0fc7.c:is_aligned
Line
Count
Source
814
220
{
815
220
    struct segment_register reg;
816
817
    /* Expecting powers of two only. */
818
220
    ASSERT(!(size & (size - 1)));
819
820
220
    if ( mode_64bit() && seg < x86_seg_fs )
821
150
        memset(&reg, 0, sizeof(reg));
822
70
    else
823
70
    {
824
        /* No alignment checking when we have no way to read segment data. */
825
70
        if ( !ops->read_segment )
826
50
            return true;
827
828
20
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
829
0
            return false;
830
20
    }
831
832
170
    return !((reg.base + offs) & (size - 1));
833
220
}
Unexecuted instantiation: decode.c:is_aligned
Unexecuted instantiation: fpu.c:is_aligned
834
835
static inline bool umip_active(struct x86_emulate_ctxt *ctxt,
836
                               const struct x86_emulate_ops *ops)
837
13.7k
{
838
13.7k
    unsigned long cr4;
839
840
    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
841
13.7k
    return x86emul_get_cpl(ctxt, ops) > 0 &&
842
4.48k
           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
843
3.77k
           (cr4 & X86_CR4_UMIP);
844
13.7k
}
x86-emulate.c:umip_active
Line
Count
Source
837
1.50k
{
838
1.50k
    unsigned long cr4;
839
840
    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
841
1.50k
    return x86emul_get_cpl(ctxt, ops) > 0 &&
842
586
           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
843
343
           (cr4 & X86_CR4_UMIP);
844
1.50k
}
0f01.c:umip_active
Line
Count
Source
837
12.2k
{
838
12.2k
    unsigned long cr4;
839
840
    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
841
12.2k
    return x86emul_get_cpl(ctxt, ops) > 0 &&
842
3.89k
           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
843
3.43k
           (cr4 & X86_CR4_UMIP);
844
12.2k
}
Unexecuted instantiation: 0fae.c:umip_active
Unexecuted instantiation: 0fc7.c:umip_active
Unexecuted instantiation: decode.c:umip_active
Unexecuted instantiation: fpu.c:umip_active
845
846
/* Compatibility function: read guest memory, zero-extend result to a ulong. */
847
static inline int read_ulong(enum x86_segment seg,
848
                             unsigned long offset,
849
                             unsigned long *val,
850
                             unsigned int bytes,
851
                             struct x86_emulate_ctxt *ctxt,
852
                             const struct x86_emulate_ops *ops)
853
124k
{
854
124k
    *val = 0;
855
124k
    return ops->read(seg, offset, val, bytes, ctxt);
856
124k
}
x86-emulate.c:read_ulong
Line
Count
Source
853
107k
{
854
107k
    *val = 0;
855
107k
    return ops->read(seg, offset, val, bytes, ctxt);
856
107k
}
0f01.c:read_ulong
Line
Count
Source
853
16.9k
{
854
16.9k
    *val = 0;
855
16.9k
    return ops->read(seg, offset, val, bytes, ctxt);
856
16.9k
}
Unexecuted instantiation: 0fae.c:read_ulong
Unexecuted instantiation: 0fc7.c:read_ulong
Unexecuted instantiation: decode.c:read_ulong
Unexecuted instantiation: fpu.c:read_ulong
857
858
#endif /* X86_EMULATE_PRIVATE_H */