Coverage Report

Created: 2026-08-28 06:22

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.36M
# define mode_64bit() (ctxt->addr_size == 64)
43
401k
# define r(name) r ## name
44
1.50M
# define PTR_POISON ((void *)0x8086000000008086UL) /* non-canonical */
45
#endif
46
47
/* Operand sizes: 8-bit operands or specified/overridden size. */
48
460k
#define ByteOp      (1<<0) /* 8-bit operands. */
49
/* Destination operand type. */
50
343k
#define DstNone     (0<<1) /* No destination operand. */
51
2.25k
#define DstImplicit (0<<1) /* Destination operand is implicit in the opcode. */
52
3.59k
#define DstBitBase  (1<<1) /* Memory operand, bit string. */
53
131k
#define DstReg      (2<<1) /* Register operand. */
54
13.8k
#define DstEax      DstReg /* Register EAX (aka DstReg with no ModRM) */
55
142k
#define DstMem      (3<<1) /* Memory operand. */
56
538k
#define DstMask     (3<<1)
57
/* Source operand type. */
58
245k
#define SrcNone     (0<<3) /* No source operand. */
59
1.20k
#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
60
53.8k
#define SrcReg      (1<<3) /* Register operand. */
61
#define SrcEax      SrcReg /* Register EAX (aka SrcReg with no ModRM) */
62
237k
#define SrcMem      (2<<3) /* Memory operand. */
63
49.0k
#define SrcMem16    (3<<3) /* Memory operand (16-bit). */
64
47.2k
#define SrcImm      (4<<3) /* Immediate operand. */
65
82.2k
#define SrcImmByte  (5<<3) /* 8-bit sign-extended immediate operand. */
66
3.11k
#define SrcImm16    (6<<3) /* 16-bit zero-extended immediate operand. */
67
1.02M
#define SrcMask     (7<<3)
68
/* Generic ModRM decode. */
69
1.35M
#define ModRM       (1<<6)
70
/* vSIB addressing mode (0f38 extension opcodes only), aliasing ModRM. */
71
753
#define vSIB        (1<<6)
72
/* Destination is only written; never read. */
73
152k
#define Mov         (1<<7)
74
/* VEX/EVEX (SIMD only): 2nd source operand unused (must be all ones) */
75
25.5k
#define TwoOp       Mov
76
/* All operands are implicit in the opcode. */
77
8
#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
110k
#define REX_PREFIX 0x40
121
45.5k
#define REX_B 0x01
122
2.25k
#define REX_X 0x02
123
13.7k
#define REX_R 0x04
124
501k
#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
enum vex_opcx {
199
    vex_none,
200
    vex_0f,
201
    vex_0f38,
202
    vex_0f3a,
203
    evex_map5 = 5,
204
    evex_map6,
205
};
206
207
enum vex_pfx {
208
    vex_np,
209
    vex_66,
210
    vex_f3,
211
    vex_f2
212
};
213
214
26.8k
#define VEX_PREFIX_DOUBLE_MASK 0x1
215
36.8k
#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
66.9k
#define imm1 ea.val
333
2.95k
#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
108
#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
124k
#define EFLAGS_MASK (X86_EFLAGS_OF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \
443
124k
                     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
1.97k
#define EFLAGS_MODIFIABLE (X86_EFLAGS_ID | X86_EFLAGS_AC | X86_EFLAGS_RF | \
450
1.97k
                           X86_EFLAGS_NT | X86_EFLAGS_IOPL | X86_EFLAGS_DF | \
451
1.97k
                           X86_EFLAGS_IF | X86_EFLAGS_TF | EFLAGS_MASK)
452
453
357k
#define truncate_word(ea, byte_width)           \
454
357k
({  unsigned long __ea = (ea);                  \
455
357k
    unsigned int _width = (byte_width);         \
456
357k
    ((_width == sizeof(unsigned long)) ? __ea : \
457
357k
     (__ea & ((1UL << (_width << 3)) - 1)));    \
458
357k
})
459
310k
#define truncate_ea(ea) truncate_word((ea), ad_bytes)
460
461
746k
#define fail_if(p)                                      \
462
746k
do {                                                    \
463
746k
    rc = (p) ? X86EMUL_UNHANDLEABLE : X86EMUL_OKAY;     \
464
746k
    if ( rc ) goto done;                                \
465
746k
} while (0)
466
467
224k
#define EXPECT(p)                                       \
468
224k
do {                                                    \
469
224k
    if ( unlikely(!(p)) )                               \
470
224k
    {                                                   \
471
0
        ASSERT_UNREACHABLE();                           \
472
0
        goto unhandleable;                              \
473
0
    }                                                   \
474
224k
} while (0)
475
476
static inline int mkec(uint8_t e, int32_t ec, ...)
477
3.10k
{
478
3.10k
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
3.10k
}
x86-emulate.c:mkec
Line
Count
Source
477
2.93k
{
478
2.93k
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
2.93k
}
0f01.c:mkec
Line
Count
Source
477
73
{
478
73
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
73
}
0fae.c:mkec
Line
Count
Source
477
23
{
478
23
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
23
}
0fc7.c:mkec
Line
Count
Source
477
9
{
478
9
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
9
}
decode.c:mkec
Line
Count
Source
477
48
{
478
48
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
48
}
fpu.c:mkec
Line
Count
Source
477
12
{
478
12
    return (e < 32 && ((1u << e) & X86_EXC_HAVE_EC)) ? ec : X86_EVENT_NO_EC;
479
12
}
480
481
3.99M
#define generate_exception_if(p, e, ec...)                                \
482
6.11M
({  if ( (p) ) {                                                          \
483
3.10k
        x86_emul_hw_exception(e, mkec(e, ##ec, 0), ctxt);                 \
484
3.10k
        rc = X86EMUL_EXCEPTION;                                           \
485
3.10k
        goto done;                                                        \
486
3.10k
    }                                                                     \
487
349k
})
488
489
191
#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
41.7k
{
496
41.7k
    unsigned long cr0;
497
41.7k
    int rc;
498
499
41.7k
    if ( ops->read_cr == NULL )
500
2.73k
        return 0;
501
502
38.9k
    rc = ops->read_cr(0, &cr0, ctxt);
503
38.9k
    return (!rc && !(cr0 & X86_CR0_PE));
504
41.7k
}
x86-emulate.c:in_realmode
Line
Count
Source
495
13.9k
{
496
13.9k
    unsigned long cr0;
497
13.9k
    int rc;
498
499
13.9k
    if ( ops->read_cr == NULL )
500
2.16k
        return 0;
501
502
11.8k
    rc = ops->read_cr(0, &cr0, ctxt);
503
11.8k
    return (!rc && !(cr0 & X86_CR0_PE));
504
13.9k
}
0f01.c:in_realmode
Line
Count
Source
495
441
{
496
441
    unsigned long cr0;
497
441
    int rc;
498
499
441
    if ( ops->read_cr == NULL )
500
33
        return 0;
501
502
408
    rc = ops->read_cr(0, &cr0, ctxt);
503
408
    return (!rc && !(cr0 & X86_CR0_PE));
504
441
}
Unexecuted instantiation: 0fae.c:in_realmode
Unexecuted instantiation: 0fc7.c:in_realmode
decode.c:in_realmode
Line
Count
Source
495
27.2k
{
496
27.2k
    unsigned long cr0;
497
27.2k
    int rc;
498
499
27.2k
    if ( ops->read_cr == NULL )
500
538
        return 0;
501
502
26.7k
    rc = ops->read_cr(0, &cr0, ctxt);
503
26.7k
    return (!rc && !(cr0 & X86_CR0_PE));
504
27.2k
}
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
13.9k
{
511
13.9k
    return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM));
512
13.9k
}
x86-emulate.c:in_protmode
Line
Count
Source
510
13.5k
{
511
13.5k
    return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM));
512
13.5k
}
0f01.c:in_protmode
Line
Count
Source
510
441
{
511
441
    return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM));
512
441
}
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
3.77k
#define mode_ring0() ({                         \
515
3.77k
    int _cpl = x86emul_get_cpl(ctxt, ops);      \
516
3.77k
    fail_if(_cpl < 0);                          \
517
3.77k
    (_cpl == 0);                                \
518
2.80k
})
519
520
static inline bool
521
_amd_like(const struct cpu_policy *cp)
522
19.4k
{
523
19.4k
    return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
524
19.4k
}
x86-emulate.c:_amd_like
Line
Count
Source
522
15.5k
{
523
15.5k
    return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
524
15.5k
}
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
3.93k
{
523
3.93k
    return cp->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON);
524
3.93k
}
Unexecuted instantiation: fpu.c:_amd_like
525
526
static inline bool
527
amd_like(const struct x86_emulate_ctxt *ctxt)
528
15.1k
{
529
15.1k
    return _amd_like(ctxt->cpu_policy);
530
15.1k
}
x86-emulate.c:amd_like
Line
Count
Source
528
11.2k
{
529
11.2k
    return _amd_like(ctxt->cpu_policy);
530
11.2k
}
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
3.93k
{
529
3.93k
    return _amd_like(ctxt->cpu_policy);
530
3.93k
}
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
487
#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
8.14k
#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
218
#define vcpu_has_wbnoinvd()    (ctxt->cpuid->extd.wbnoinvd)
568
2.97k
#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
22
#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_movrs()       (ctxt->cpuid->feat.movrs)
616
#define vcpu_has_avx_vnni_int8() (ctxt->cpuid->feat.avx_vnni_int8)
617
#define vcpu_has_avx_ne_convert() (ctxt->cpuid->feat.avx_ne_convert)
618
#define vcpu_has_avx_vnni_int16() (ctxt->cpuid->feat.avx_vnni_int16)
619
620
#define vcpu_must_have(feat) \
621
229k
    generate_exception_if(!vcpu_has_##feat(), X86_EXC_UD)
622
623
/*
624
 * Instruction emulation:
625
 * Most instructions are emulated directly via a fragment of inline assembly
626
 * code. This allows us to save/restore EFLAGS and thus very easily pick up
627
 * any modified flags.
628
 */
629
630
#if defined(__x86_64__)
631
#define _LO32 "k"          /* force 32-bit operand */
632
#define _STK  "%%rsp"      /* stack pointer */
633
#elif defined(__i386__)
634
#define _LO32 ""           /* force 32-bit operand */
635
#define _STK  "%%esp"      /* stack pointer */
636
#endif
637
638
/* Before executing instruction: restore necessary bits in EFLAGS. */
639
#define _PRE_EFLAGS(_sav, _msk, _tmp)                           \
640
/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
641
"movl %"_LO32 _sav",%"_LO32 _tmp"; "                            \
642
"push %"_tmp"; "                                                \
643
"push %"_tmp"; "                                                \
644
"movl %"_msk",%"_LO32 _tmp"; "                                  \
645
"andl %"_LO32 _tmp",("_STK"); "                                 \
646
"pushf; "                                                       \
647
"notl %"_LO32 _tmp"; "                                          \
648
"andl %"_LO32 _tmp",("_STK"); "                                 \
649
"andl %"_LO32 _tmp", 2 * " STR(__SIZEOF_LONG__) "("_STK"); "    \
650
"pop  %"_tmp"; "                                                \
651
"orl  %"_LO32 _tmp",("_STK"); "                                 \
652
"popf; "                                                        \
653
"pop  %"_tmp"; "                                                \
654
"movl %"_LO32 _tmp",%"_LO32 _sav"; "
655
656
/* After executing instruction: write-back necessary bits in EFLAGS. */
657
#define _POST_EFLAGS(_sav, _msk, _tmp)          \
658
/* _sav |= EFLAGS & _msk; */                    \
659
"pushf; "                                       \
660
"pop  %"_tmp"; "                                \
661
"andl %"_msk",%"_LO32 _tmp"; "                  \
662
"orl  %"_LO32 _tmp",%"_LO32 _sav"; "
663
664
#ifdef __XEN__
665
666
# include <xen/domain_page.h>
667
# include <asm/uaccess.h>
668
669
# define get_stub(stb) ({                                    \
670
    void *_ptr;                                              \
671
    BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX_INST_LEN + 1);      \
672
    ASSERT(!(stb).ptr);                                      \
673
    (stb).addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;   \
674
    (stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn))) + \
675
        ((stb).addr & ~PAGE_MASK);                           \
676
    _ptr = memset((stb).ptr, 0xcc, STUB_BUF_SIZE / 2);       \
677
    if ( cpu_has_xen_ibt )                                   \
678
    {                                                        \
679
        place_endbr64(_ptr);                                 \
680
        _ptr += 4;                                           \
681
    }                                                        \
682
    _ptr;                                                    \
683
})
684
685
# define put_stub(stb) ({             \
686
    if ( (stb).ptr )                  \
687
    {                                 \
688
        unmap_domain_page((stb).ptr); \
689
        (stb).ptr = NULL;             \
690
    }                                 \
691
})
692
693
694
struct stub_exn {
695
    union stub_exception_token info;
696
    unsigned int line;
697
};
698
699
# define invoke_stub(pre, post, constraints...) do {                    \
700
    stub_exn.info = (union stub_exception_token) { .raw = ~0 };         \
701
    stub_exn.line = __LINE__; /* Utility outweighs livepatching cost */ \
702
    block_speculation(); /* SCSB */                                     \
703
    asm volatile ( pre "\n\t"                                           \
704
                   "INDIRECT_CALL %[stub]\n"                            \
705
                   ".Lret%=:\n\t"                                       \
706
                   post "\n\t"                                          \
707
                   ".Lskip%=:\n\t"                                      \
708
                   ".pushsection .fixup,\"ax\"\n"                       \
709
                   ".Lfix%=:\n\t"                                       \
710
                   "pop %[exn]\n\t"                                     \
711
                   "jmp .Lskip%=\n\t"                                   \
712
                   ".popsection\n\t"                                    \
713
                   _ASM_EXTABLE(.Lret%=, .Lfix%=)                       \
714
                   : [exn] "+g" (stub_exn.info) ASM_CALL_CONSTRAINT,    \
715
                     constraints,                                       \
716
                     [stub] "r" (stub.func),                            \
717
                     "m" (*(uint8_t(*)[MAX_INST_LEN + 1])stub.ptr) );   \
718
    if ( unlikely(~stub_exn.info.raw) )                                 \
719
        goto emulation_stub_failure;                                    \
720
} while (0)
721
722
#else /* !__XEN__ */
723
724
182k
# define get_stub(stb) ({                        \
725
182k
    assert(!(stb).addr);                         \
726
182k
    (void *)((stb).addr = (uintptr_t)(stb).buf); \
727
182k
})
728
729
742k
# define put_stub(stb) ((stb).addr = 0)
730
731
struct stub_exn {};
732
733
# define invoke_stub(pre, post, constraints...)                         \
734
181k
    asm volatile ( pre "\n\tcall *%[stub]\n\t" post                     \
735
181k
                   : constraints, [stub] "rm" (stub.func),              \
736
181k
                     "m" (*(typeof(stub.buf) *)stub.addr) )
737
738
#endif /* __XEN__ */
739
740
int x86emul_get_cpl(struct x86_emulate_ctxt *ctxt,
741
                    const struct x86_emulate_ops *ops);
742
743
int x86emul_get_fpu(enum x86_emulate_fpu_type type,
744
                    struct x86_emulate_ctxt *ctxt,
745
                    const struct x86_emulate_ops *ops);
746
747
179k
#define get_fpu(type)                                           \
748
179k
do {                                                            \
749
179k
    rc = x86emul_get_fpu(fpu_type = (type), ctxt, ops);         \
750
179k
    if ( rc ) goto done;                                        \
751
179k
} while (0)
752
753
int x86emul_decode(struct x86_emulate_state *s,
754
                   struct x86_emulate_ctxt *ctxt,
755
                   const struct x86_emulate_ops *ops);
756
757
int x86emul_fpu(struct x86_emulate_state *s,
758
                struct cpu_user_regs *regs,
759
                struct operand *dst,
760
                struct operand *src,
761
                struct x86_emulate_ctxt *ctxt,
762
                const struct x86_emulate_ops *ops,
763
                unsigned int *insn_bytes,
764
                enum x86_emulate_fpu_type *fpu_type,
765
                mmval_t *mmvalp);
766
int x86emul_0f01(struct x86_emulate_state *s,
767
                 struct cpu_user_regs *regs,
768
                 struct operand *dst,
769
                 struct x86_emulate_ctxt *ctxt,
770
                 const struct x86_emulate_ops *ops);
771
int x86emul_0fae(struct x86_emulate_state *s,
772
                 struct cpu_user_regs *regs,
773
                 struct operand *dst,
774
                 const struct operand *src,
775
                 struct x86_emulate_ctxt *ctxt,
776
                 const struct x86_emulate_ops *ops,
777
                 enum x86_emulate_fpu_type *fpu_type);
778
int x86emul_0fc7(struct x86_emulate_state *s,
779
                 struct cpu_user_regs *regs,
780
                 struct operand *dst,
781
                 struct x86_emulate_ctxt *ctxt,
782
                 const struct x86_emulate_ops *ops,
783
                 mmval_t *mmvalp);
784
785
/* Initialise output state in x86_emulate_ctxt */
786
static inline void init_context(struct x86_emulate_ctxt *ctxt)
787
502k
{
788
502k
    ctxt->retire.raw = 0;
789
502k
    x86_emul_reset_event(ctxt);
790
502k
}
x86-emulate.c:init_context
Line
Count
Source
787
502k
{
788
502k
    ctxt->retire.raw = 0;
789
502k
    x86_emul_reset_event(ctxt);
790
502k
}
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
791
792
static inline bool is_aligned(enum x86_segment seg, unsigned long offs,
793
                              unsigned int size, struct x86_emulate_ctxt *ctxt,
794
                              const struct x86_emulate_ops *ops)
795
8.50k
{
796
8.50k
    struct segment_register reg;
797
798
    /* Expecting powers of two only. */
799
8.50k
    ASSERT(!(size & (size - 1)));
800
801
8.50k
    if ( mode_64bit() && seg < x86_seg_fs )
802
1.28k
        memset(&reg, 0, sizeof(reg));
803
7.22k
    else
804
7.22k
    {
805
        /* No alignment checking when we have no way to read segment data. */
806
7.22k
        if ( !ops->read_segment )
807
3.76k
            return true;
808
809
3.45k
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
810
0
            return false;
811
3.45k
    }
812
813
4.73k
    return !((reg.base + offs) & (size - 1));
814
8.50k
}
x86-emulate.c:is_aligned
Line
Count
Source
795
8.14k
{
796
8.14k
    struct segment_register reg;
797
798
    /* Expecting powers of two only. */
799
8.14k
    ASSERT(!(size & (size - 1)));
800
801
8.14k
    if ( mode_64bit() && seg < x86_seg_fs )
802
1.10k
        memset(&reg, 0, sizeof(reg));
803
7.03k
    else
804
7.03k
    {
805
        /* No alignment checking when we have no way to read segment data. */
806
7.03k
        if ( !ops->read_segment )
807
3.68k
            return true;
808
809
3.35k
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
810
0
            return false;
811
3.35k
    }
812
813
4.45k
    return !((reg.base + offs) & (size - 1));
814
8.14k
}
Unexecuted instantiation: 0f01.c:is_aligned
0fae.c:is_aligned
Line
Count
Source
795
4
{
796
4
    struct segment_register reg;
797
798
    /* Expecting powers of two only. */
799
4
    ASSERT(!(size & (size - 1)));
800
801
4
    if ( mode_64bit() && seg < x86_seg_fs )
802
1
        memset(&reg, 0, sizeof(reg));
803
3
    else
804
3
    {
805
        /* No alignment checking when we have no way to read segment data. */
806
3
        if ( !ops->read_segment )
807
1
            return true;
808
809
2
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
810
0
            return false;
811
2
    }
812
813
3
    return !((reg.base + offs) & (size - 1));
814
4
}
0fc7.c:is_aligned
Line
Count
Source
795
356
{
796
356
    struct segment_register reg;
797
798
    /* Expecting powers of two only. */
799
356
    ASSERT(!(size & (size - 1)));
800
801
356
    if ( mode_64bit() && seg < x86_seg_fs )
802
175
        memset(&reg, 0, sizeof(reg));
803
181
    else
804
181
    {
805
        /* No alignment checking when we have no way to read segment data. */
806
181
        if ( !ops->read_segment )
807
79
            return true;
808
809
102
        if ( ops->read_segment(seg, &reg, ctxt) != X86EMUL_OKAY )
810
0
            return false;
811
102
    }
812
813
277
    return !((reg.base + offs) & (size - 1));
814
356
}
Unexecuted instantiation: decode.c:is_aligned
Unexecuted instantiation: fpu.c:is_aligned
815
816
static inline bool umip_active(struct x86_emulate_ctxt *ctxt,
817
                               const struct x86_emulate_ops *ops)
818
15.1k
{
819
15.1k
    unsigned long cr4;
820
821
    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
822
15.1k
    return x86emul_get_cpl(ctxt, ops) > 0 &&
823
5.76k
           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
824
5.03k
           (cr4 & X86_CR4_UMIP);
825
15.1k
}
x86-emulate.c:umip_active
Line
Count
Source
818
949
{
819
949
    unsigned long cr4;
820
821
    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
822
949
    return x86emul_get_cpl(ctxt, ops) > 0 &&
823
413
           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
824
249
           (cr4 & X86_CR4_UMIP);
825
949
}
0f01.c:umip_active
Line
Count
Source
818
14.2k
{
819
14.2k
    unsigned long cr4;
820
821
    /* Intentionally not using mode_ring0() here to avoid its fail_if(). */
822
14.2k
    return x86emul_get_cpl(ctxt, ops) > 0 &&
823
5.35k
           ops->read_cr && ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY &&
824
4.78k
           (cr4 & X86_CR4_UMIP);
825
14.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
826
827
/* Compatibility function: read guest memory, zero-extend result to a ulong. */
828
static inline int read_ulong(enum x86_segment seg,
829
                             unsigned long offset,
830
                             unsigned long *val,
831
                             unsigned int bytes,
832
                             struct x86_emulate_ctxt *ctxt,
833
                             const struct x86_emulate_ops *ops)
834
112k
{
835
112k
    *val = 0;
836
112k
    return ops->read(seg, offset, val, bytes, ctxt);
837
112k
}
x86-emulate.c:read_ulong
Line
Count
Source
834
93.0k
{
835
93.0k
    *val = 0;
836
93.0k
    return ops->read(seg, offset, val, bytes, ctxt);
837
93.0k
}
0f01.c:read_ulong
Line
Count
Source
834
19.5k
{
835
19.5k
    *val = 0;
836
19.5k
    return ops->read(seg, offset, val, bytes, ctxt);
837
19.5k
}
Unexecuted instantiation: 0fae.c:read_ulong
Unexecuted instantiation: 0fc7.c:read_ulong
Unexecuted instantiation: decode.c:read_ulong
Unexecuted instantiation: fpu.c:read_ulong
838
839
#endif /* X86_EMULATE_PRIVATE_H */