12f728d66SSean Christopherson /* SPDX-License-Identifier: GPL-2.0 */
22f728d66SSean Christopherson /******************************************************************************
32f728d66SSean Christopherson * x86_emulate.h
42f728d66SSean Christopherson *
52f728d66SSean Christopherson * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
62f728d66SSean Christopherson *
72f728d66SSean Christopherson * Copyright (c) 2005 Keir Fraser
82f728d66SSean Christopherson *
92f728d66SSean Christopherson * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
102f728d66SSean Christopherson */
112f728d66SSean Christopherson
122f728d66SSean Christopherson #ifndef _ASM_X86_KVM_X86_EMULATE_H
132f728d66SSean Christopherson #define _ASM_X86_KVM_X86_EMULATE_H
142f728d66SSean Christopherson
152f728d66SSean Christopherson #include <asm/desc_defs.h>
1643e51464SSiddharth Chandrasekaran #include "fpu.h"
172f728d66SSean Christopherson
182f728d66SSean Christopherson struct x86_emulate_ctxt;
192f728d66SSean Christopherson enum x86_intercept;
202f728d66SSean Christopherson enum x86_intercept_stage;
212f728d66SSean Christopherson
222f728d66SSean Christopherson struct x86_exception {
232f728d66SSean Christopherson u8 vector;
242f728d66SSean Christopherson bool error_code_valid;
252f728d66SSean Christopherson u16 error_code;
262f728d66SSean Christopherson bool nested_page_fault;
272f728d66SSean Christopherson u64 address; /* cr2 or nested page fault gpa */
282f728d66SSean Christopherson u8 async_page_fault;
292f728d66SSean Christopherson };
302f728d66SSean Christopherson
312f728d66SSean Christopherson /*
322f728d66SSean Christopherson * This struct is used to carry enough information from the instruction
332f728d66SSean Christopherson * decoder to main KVM so that a decision can be made whether the
342f728d66SSean Christopherson * instruction needs to be intercepted or not.
352f728d66SSean Christopherson */
362f728d66SSean Christopherson struct x86_instruction_info {
372f728d66SSean Christopherson u8 intercept; /* which intercept */
382f728d66SSean Christopherson u8 rep_prefix; /* rep prefix? */
392f728d66SSean Christopherson u8 modrm_mod; /* mod part of modrm */
402f728d66SSean Christopherson u8 modrm_reg; /* index of register used */
412f728d66SSean Christopherson u8 modrm_rm; /* rm part of modrm */
422f728d66SSean Christopherson u64 src_val; /* value of source operand */
432f728d66SSean Christopherson u64 dst_val; /* value of destination operand */
442f728d66SSean Christopherson u8 src_bytes; /* size of source operand */
452f728d66SSean Christopherson u8 dst_bytes; /* size of destination operand */
462f728d66SSean Christopherson u8 ad_bytes; /* size of src/dst address */
472f728d66SSean Christopherson u64 next_rip; /* rip following the instruction */
482f728d66SSean Christopherson };
492f728d66SSean Christopherson
502f728d66SSean Christopherson /*
512f728d66SSean Christopherson * x86_emulate_ops:
522f728d66SSean Christopherson *
532f728d66SSean Christopherson * These operations represent the instruction emulator's interface to memory.
542f728d66SSean Christopherson * There are two categories of operation: those that act on ordinary memory
552f728d66SSean Christopherson * regions (*_std), and those that act on memory regions known to require
562f728d66SSean Christopherson * special treatment or emulation (*_emulated).
572f728d66SSean Christopherson *
582f728d66SSean Christopherson * The emulator assumes that an instruction accesses only one 'emulated memory'
592f728d66SSean Christopherson * location, that this location is the given linear faulting address (cr2), and
602f728d66SSean Christopherson * that this is one of the instruction's data operands. Instruction fetches and
612f728d66SSean Christopherson * stack operations are assumed never to access emulated memory. The emulator
622f728d66SSean Christopherson * automatically deduces which operand of a string-move operation is accessing
632f728d66SSean Christopherson * emulated memory, and assumes that the other operand accesses normal memory.
642f728d66SSean Christopherson *
652f728d66SSean Christopherson * NOTES:
662f728d66SSean Christopherson * 1. The emulator isn't very smart about emulated vs. standard memory.
672f728d66SSean Christopherson * 'Emulated memory' access addresses should be checked for sanity.
682f728d66SSean Christopherson * 'Normal memory' accesses may fault, and the caller must arrange to
692f728d66SSean Christopherson * detect and handle reentrancy into the emulator via recursive faults.
702f728d66SSean Christopherson * Accesses may be unaligned and may cross page boundaries.
712f728d66SSean Christopherson * 2. If the access fails (cannot emulate, or a standard access faults) then
722f728d66SSean Christopherson * it is up to the memop to propagate the fault to the guest VM via
732f728d66SSean Christopherson * some out-of-band mechanism, unknown to the emulator. The memop signals
742f728d66SSean Christopherson * failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
752f728d66SSean Christopherson * then immediately bail.
762f728d66SSean Christopherson * 3. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
772f728d66SSean Christopherson * cmpxchg8b_emulated need support 8-byte accesses.
782f728d66SSean Christopherson * 4. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
792f728d66SSean Christopherson */
802f728d66SSean Christopherson /* Access completed successfully: continue emulation as normal. */
812f728d66SSean Christopherson #define X86EMUL_CONTINUE 0
822f728d66SSean Christopherson /* Access is unhandleable: bail from emulation and return error to caller. */
832f728d66SSean Christopherson #define X86EMUL_UNHANDLEABLE 1
842f728d66SSean Christopherson /* Terminate emulation but return success to the caller. */
852f728d66SSean Christopherson #define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
862f728d66SSean Christopherson #define X86EMUL_RETRY_INSTR 3 /* retry the instruction for some reason */
872f728d66SSean Christopherson #define X86EMUL_CMPXCHG_FAILED 4 /* cmpxchg did not see expected value */
882f728d66SSean Christopherson #define X86EMUL_IO_NEEDED 5 /* IO is needed to complete emulation */
892f728d66SSean Christopherson #define X86EMUL_INTERCEPTED 6 /* Intercepted by nested VMCB/VMCS */
902f728d66SSean Christopherson
912f728d66SSean Christopherson struct x86_emulate_ops {
921cca2f8cSSean Christopherson void (*vm_bugged)(struct x86_emulate_ctxt *ctxt);
932f728d66SSean Christopherson /*
942f728d66SSean Christopherson * read_gpr: read a general purpose register (rax - r15)
952f728d66SSean Christopherson *
962f728d66SSean Christopherson * @reg: gpr number.
972f728d66SSean Christopherson */
982f728d66SSean Christopherson ulong (*read_gpr)(struct x86_emulate_ctxt *ctxt, unsigned reg);
992f728d66SSean Christopherson /*
1002f728d66SSean Christopherson * write_gpr: write a general purpose register (rax - r15)
1012f728d66SSean Christopherson *
1022f728d66SSean Christopherson * @reg: gpr number.
1032f728d66SSean Christopherson * @val: value to write.
1042f728d66SSean Christopherson */
1052f728d66SSean Christopherson void (*write_gpr)(struct x86_emulate_ctxt *ctxt, unsigned reg, ulong val);
1062f728d66SSean Christopherson /*
1072f728d66SSean Christopherson * read_std: Read bytes of standard (non-emulated/special) memory.
1082f728d66SSean Christopherson * Used for descriptor reading.
1092f728d66SSean Christopherson * @addr: [IN ] Linear address from which to read.
1102f728d66SSean Christopherson * @val: [OUT] Value read from memory, zero-extended to 'u_long'.
1112f728d66SSean Christopherson * @bytes: [IN ] Number of bytes to read from memory.
1122f728d66SSean Christopherson * @system:[IN ] Whether the access is forced to be at CPL0.
1132f728d66SSean Christopherson */
1142f728d66SSean Christopherson int (*read_std)(struct x86_emulate_ctxt *ctxt,
1152f728d66SSean Christopherson unsigned long addr, void *val,
1162f728d66SSean Christopherson unsigned int bytes,
1172f728d66SSean Christopherson struct x86_exception *fault, bool system);
1182f728d66SSean Christopherson
1192f728d66SSean Christopherson /*
1202f728d66SSean Christopherson * write_std: Write bytes of standard (non-emulated/special) memory.
1212f728d66SSean Christopherson * Used for descriptor writing.
1222f728d66SSean Christopherson * @addr: [IN ] Linear address to which to write.
1232f728d66SSean Christopherson * @val: [OUT] Value write to memory, zero-extended to 'u_long'.
1242f728d66SSean Christopherson * @bytes: [IN ] Number of bytes to write to memory.
1252f728d66SSean Christopherson * @system:[IN ] Whether the access is forced to be at CPL0.
1262f728d66SSean Christopherson */
1272f728d66SSean Christopherson int (*write_std)(struct x86_emulate_ctxt *ctxt,
1282f728d66SSean Christopherson unsigned long addr, void *val, unsigned int bytes,
1292f728d66SSean Christopherson struct x86_exception *fault, bool system);
1302f728d66SSean Christopherson /*
1312f728d66SSean Christopherson * fetch: Read bytes of standard (non-emulated/special) memory.
1322f728d66SSean Christopherson * Used for instruction fetch.
1332f728d66SSean Christopherson * @addr: [IN ] Linear address from which to read.
1342f728d66SSean Christopherson * @val: [OUT] Value read from memory, zero-extended to 'u_long'.
1352f728d66SSean Christopherson * @bytes: [IN ] Number of bytes to read from memory.
1362f728d66SSean Christopherson */
1372f728d66SSean Christopherson int (*fetch)(struct x86_emulate_ctxt *ctxt,
1382f728d66SSean Christopherson unsigned long addr, void *val, unsigned int bytes,
1392f728d66SSean Christopherson struct x86_exception *fault);
1402f728d66SSean Christopherson
1412f728d66SSean Christopherson /*
1422f728d66SSean Christopherson * read_emulated: Read bytes from emulated/special memory area.
1432f728d66SSean Christopherson * @addr: [IN ] Linear address from which to read.
1442f728d66SSean Christopherson * @val: [OUT] Value read from memory, zero-extended to 'u_long'.
1452f728d66SSean Christopherson * @bytes: [IN ] Number of bytes to read from memory.
1462f728d66SSean Christopherson */
1472f728d66SSean Christopherson int (*read_emulated)(struct x86_emulate_ctxt *ctxt,
1482f728d66SSean Christopherson unsigned long addr, void *val, unsigned int bytes,
1492f728d66SSean Christopherson struct x86_exception *fault);
1502f728d66SSean Christopherson
1512f728d66SSean Christopherson /*
1522f728d66SSean Christopherson * write_emulated: Write bytes to emulated/special memory area.
1532f728d66SSean Christopherson * @addr: [IN ] Linear address to which to write.
1542f728d66SSean Christopherson * @val: [IN ] Value to write to memory (low-order bytes used as
1552f728d66SSean Christopherson * required).
1562f728d66SSean Christopherson * @bytes: [IN ] Number of bytes to write to memory.
1572f728d66SSean Christopherson */
1582f728d66SSean Christopherson int (*write_emulated)(struct x86_emulate_ctxt *ctxt,
1592f728d66SSean Christopherson unsigned long addr, const void *val,
1602f728d66SSean Christopherson unsigned int bytes,
1612f728d66SSean Christopherson struct x86_exception *fault);
1622f728d66SSean Christopherson
1632f728d66SSean Christopherson /*
1642f728d66SSean Christopherson * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
1652f728d66SSean Christopherson * emulated/special memory area.
1662f728d66SSean Christopherson * @addr: [IN ] Linear address to access.
1672f728d66SSean Christopherson * @old: [IN ] Value expected to be current at @addr.
1682f728d66SSean Christopherson * @new: [IN ] Value to write to @addr.
1692f728d66SSean Christopherson * @bytes: [IN ] Number of bytes to access using CMPXCHG.
1702f728d66SSean Christopherson */
1712f728d66SSean Christopherson int (*cmpxchg_emulated)(struct x86_emulate_ctxt *ctxt,
1722f728d66SSean Christopherson unsigned long addr,
1732f728d66SSean Christopherson const void *old,
1742f728d66SSean Christopherson const void *new,
1752f728d66SSean Christopherson unsigned int bytes,
1762f728d66SSean Christopherson struct x86_exception *fault);
1772f728d66SSean Christopherson void (*invlpg)(struct x86_emulate_ctxt *ctxt, ulong addr);
1782f728d66SSean Christopherson
1792f728d66SSean Christopherson int (*pio_in_emulated)(struct x86_emulate_ctxt *ctxt,
1802f728d66SSean Christopherson int size, unsigned short port, void *val,
1812f728d66SSean Christopherson unsigned int count);
1822f728d66SSean Christopherson
1832f728d66SSean Christopherson int (*pio_out_emulated)(struct x86_emulate_ctxt *ctxt,
1842f728d66SSean Christopherson int size, unsigned short port, const void *val,
1852f728d66SSean Christopherson unsigned int count);
1862f728d66SSean Christopherson
1872f728d66SSean Christopherson bool (*get_segment)(struct x86_emulate_ctxt *ctxt, u16 *selector,
1882f728d66SSean Christopherson struct desc_struct *desc, u32 *base3, int seg);
1892f728d66SSean Christopherson void (*set_segment)(struct x86_emulate_ctxt *ctxt, u16 selector,
1902f728d66SSean Christopherson struct desc_struct *desc, u32 base3, int seg);
1912f728d66SSean Christopherson unsigned long (*get_cached_segment_base)(struct x86_emulate_ctxt *ctxt,
1922f728d66SSean Christopherson int seg);
1932f728d66SSean Christopherson void (*get_gdt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
1942f728d66SSean Christopherson void (*get_idt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
1952f728d66SSean Christopherson void (*set_gdt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
1962f728d66SSean Christopherson void (*set_idt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
1972f728d66SSean Christopherson ulong (*get_cr)(struct x86_emulate_ctxt *ctxt, int cr);
1982f728d66SSean Christopherson int (*set_cr)(struct x86_emulate_ctxt *ctxt, int cr, ulong val);
1992f728d66SSean Christopherson int (*cpl)(struct x86_emulate_ctxt *ctxt);
20029d6ca41SPaolo Bonzini void (*get_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong *dest);
2012f728d66SSean Christopherson int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
202ac8d6cadSHou Wenlong int (*set_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
203ac8d6cadSHou Wenlong int (*get_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
2042f728d66SSean Christopherson int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
2052f728d66SSean Christopherson int (*check_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc);
2062f728d66SSean Christopherson int (*read_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc, u64 *pdata);
2072f728d66SSean Christopherson void (*halt)(struct x86_emulate_ctxt *ctxt);
2082f728d66SSean Christopherson void (*wbinvd)(struct x86_emulate_ctxt *ctxt);
2092f728d66SSean Christopherson int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt);
2102f728d66SSean Christopherson int (*intercept)(struct x86_emulate_ctxt *ctxt,
2112f728d66SSean Christopherson struct x86_instruction_info *info,
2122f728d66SSean Christopherson enum x86_intercept_stage stage);
2132f728d66SSean Christopherson
2142f728d66SSean Christopherson bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx,
215f91af517SSean Christopherson u32 *ecx, u32 *edx, bool exact_only);
2162f728d66SSean Christopherson bool (*guest_has_movbe)(struct x86_emulate_ctxt *ctxt);
2172f728d66SSean Christopherson bool (*guest_has_fxsr)(struct x86_emulate_ctxt *ctxt);
218a836839cSHou Wenlong bool (*guest_has_rdpid)(struct x86_emulate_ctxt *ctxt);
2192f728d66SSean Christopherson
2202f728d66SSean Christopherson void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
2212f728d66SSean Christopherson
222*32e69f23SMaxim Levitsky bool (*is_smm)(struct x86_emulate_ctxt *ctxt);
223*32e69f23SMaxim Levitsky bool (*is_guest_mode)(struct x86_emulate_ctxt *ctxt);
224f1554150SPaolo Bonzini int (*leave_smm)(struct x86_emulate_ctxt *ctxt);
22525b17226SSean Christopherson void (*triple_fault)(struct x86_emulate_ctxt *ctxt);
2262f728d66SSean Christopherson int (*set_xcr)(struct x86_emulate_ctxt *ctxt, u32 index, u64 xcr);
2272f728d66SSean Christopherson };
2282f728d66SSean Christopherson
2292f728d66SSean Christopherson /* Type, address-of, and value of an instruction's operand. */
2302f728d66SSean Christopherson struct operand {
2312f728d66SSean Christopherson enum { OP_REG, OP_MEM, OP_MEM_STR, OP_IMM, OP_XMM, OP_MM, OP_NONE } type;
2322f728d66SSean Christopherson unsigned int bytes;
2332f728d66SSean Christopherson unsigned int count;
2342f728d66SSean Christopherson union {
2352f728d66SSean Christopherson unsigned long orig_val;
2362f728d66SSean Christopherson u64 orig_val64;
2372f728d66SSean Christopherson };
2382f728d66SSean Christopherson union {
2392f728d66SSean Christopherson unsigned long *reg;
2402f728d66SSean Christopherson struct segmented_address {
2412f728d66SSean Christopherson ulong ea;
2422f728d66SSean Christopherson unsigned seg;
2432f728d66SSean Christopherson } mem;
2442f728d66SSean Christopherson unsigned xmm;
2452f728d66SSean Christopherson unsigned mm;
2462f728d66SSean Christopherson } addr;
2472f728d66SSean Christopherson union {
2482f728d66SSean Christopherson unsigned long val;
2492f728d66SSean Christopherson u64 val64;
2502f728d66SSean Christopherson char valptr[sizeof(sse128_t)];
2512f728d66SSean Christopherson sse128_t vec_val;
2522f728d66SSean Christopherson u64 mm_val;
2532f728d66SSean Christopherson void *data;
2542f728d66SSean Christopherson };
2552f728d66SSean Christopherson };
2562f728d66SSean Christopherson
2572f728d66SSean Christopherson struct fetch_cache {
2582f728d66SSean Christopherson u8 data[15];
2592f728d66SSean Christopherson u8 *ptr;
2602f728d66SSean Christopherson u8 *end;
2612f728d66SSean Christopherson };
2622f728d66SSean Christopherson
2632f728d66SSean Christopherson struct read_cache {
2642f728d66SSean Christopherson u8 data[1024];
2652f728d66SSean Christopherson unsigned long pos;
2662f728d66SSean Christopherson unsigned long end;
2672f728d66SSean Christopherson };
2682f728d66SSean Christopherson
2692f728d66SSean Christopherson /* Execution mode, passed to the emulator. */
2702f728d66SSean Christopherson enum x86emul_mode {
2712f728d66SSean Christopherson X86EMUL_MODE_REAL, /* Real mode. */
2722f728d66SSean Christopherson X86EMUL_MODE_VM86, /* Virtual 8086 mode. */
2732f728d66SSean Christopherson X86EMUL_MODE_PROT16, /* 16-bit protected mode. */
2742f728d66SSean Christopherson X86EMUL_MODE_PROT32, /* 32-bit protected mode. */
2752f728d66SSean Christopherson X86EMUL_MODE_PROT64, /* 64-bit (long) mode. */
2762f728d66SSean Christopherson };
2772f728d66SSean Christopherson
2782f728d66SSean Christopherson /*
2792f728d66SSean Christopherson * fastop functions are declared as taking a never-defined fastop parameter,
2802f728d66SSean Christopherson * so they can't be called from C directly.
2812f728d66SSean Christopherson */
2822f728d66SSean Christopherson struct fastop;
2832f728d66SSean Christopherson
2842f728d66SSean Christopherson typedef void (*fastop_t)(struct fastop *);
2852f728d66SSean Christopherson
286a5ba67b4SSean Christopherson /*
287a5ba67b4SSean Christopherson * The emulator's _regs array tracks only the GPRs, i.e. excludes RIP. RIP is
288a5ba67b4SSean Christopherson * tracked/accessed via _eip, and except for RIP relative addressing, which
289a5ba67b4SSean Christopherson * also uses _eip, RIP cannot be a register operand nor can it be an operand in
290a5ba67b4SSean Christopherson * a ModRM or SIB byte.
291a5ba67b4SSean Christopherson */
292b443183aSSean Christopherson #ifdef CONFIG_X86_64
293a5ba67b4SSean Christopherson #define NR_EMULATOR_GPRS 16
294b443183aSSean Christopherson #else
295b443183aSSean Christopherson #define NR_EMULATOR_GPRS 8
296b443183aSSean Christopherson #endif
297a5ba67b4SSean Christopherson
2982f728d66SSean Christopherson struct x86_emulate_ctxt {
2992f728d66SSean Christopherson void *vcpu;
3002f728d66SSean Christopherson const struct x86_emulate_ops *ops;
3012f728d66SSean Christopherson
3022f728d66SSean Christopherson /* Register state before/after emulation. */
3032f728d66SSean Christopherson unsigned long eflags;
3042f728d66SSean Christopherson unsigned long eip; /* eip before instruction emulation */
3052f728d66SSean Christopherson /* Emulated execution mode, represented by an X86EMUL_MODE value. */
3062f728d66SSean Christopherson enum x86emul_mode mode;
3072f728d66SSean Christopherson
3082f728d66SSean Christopherson /* interruptibility state, as a result of execution of STI or MOV SS */
3092f728d66SSean Christopherson int interruptibility;
3102f728d66SSean Christopherson
3112f728d66SSean Christopherson bool perm_ok; /* do not check permissions if true */
3122f728d66SSean Christopherson bool tf; /* TF value before instruction (after for syscall/sysret) */
3132f728d66SSean Christopherson
3142f728d66SSean Christopherson bool have_exception;
3152f728d66SSean Christopherson struct x86_exception exception;
3162f728d66SSean Christopherson
3172f728d66SSean Christopherson /* GPA available */
3182f728d66SSean Christopherson bool gpa_available;
3192f728d66SSean Christopherson gpa_t gpa_val;
3202f728d66SSean Christopherson
3212f728d66SSean Christopherson /*
3222f728d66SSean Christopherson * decode cache
3232f728d66SSean Christopherson */
3242f728d66SSean Christopherson
3252f728d66SSean Christopherson /* current opcode length in bytes */
3262f728d66SSean Christopherson u8 opcode_len;
3272f728d66SSean Christopherson u8 b;
3282f728d66SSean Christopherson u8 intercept;
3292f728d66SSean Christopherson u8 op_bytes;
3302f728d66SSean Christopherson u8 ad_bytes;
3312f728d66SSean Christopherson union {
3322f728d66SSean Christopherson int (*execute)(struct x86_emulate_ctxt *ctxt);
3332f728d66SSean Christopherson fastop_t fop;
3342f728d66SSean Christopherson };
3352f728d66SSean Christopherson int (*check_perm)(struct x86_emulate_ctxt *ctxt);
33673ab4a35SSean Christopherson
3372f728d66SSean Christopherson bool rip_relative;
3382f728d66SSean Christopherson u8 rex_prefix;
3392f728d66SSean Christopherson u8 lock_prefix;
3402f728d66SSean Christopherson u8 rep_prefix;
3412f728d66SSean Christopherson /* bitmaps of registers in _regs[] that can be read */
3420cbc60d4SSean Christopherson u16 regs_valid;
3432f728d66SSean Christopherson /* bitmaps of registers in _regs[] that have been written */
3440cbc60d4SSean Christopherson u16 regs_dirty;
3452f728d66SSean Christopherson /* modrm */
3462f728d66SSean Christopherson u8 modrm;
3472f728d66SSean Christopherson u8 modrm_mod;
3482f728d66SSean Christopherson u8 modrm_reg;
3492f728d66SSean Christopherson u8 modrm_rm;
3502f728d66SSean Christopherson u8 modrm_seg;
3512f728d66SSean Christopherson u8 seg_override;
3522f728d66SSean Christopherson u64 d;
3532f728d66SSean Christopherson unsigned long _eip;
35406add254SSean Christopherson
35506add254SSean Christopherson /* Here begins the usercopy section. */
35606add254SSean Christopherson struct operand src;
35706add254SSean Christopherson struct operand src2;
35806add254SSean Christopherson struct operand dst;
3592f728d66SSean Christopherson struct operand memop;
360a5ba67b4SSean Christopherson unsigned long _regs[NR_EMULATOR_GPRS];
3612f728d66SSean Christopherson struct operand *memopp;
3622f728d66SSean Christopherson struct fetch_cache fetch;
3632f728d66SSean Christopherson struct read_cache io_read;
3642f728d66SSean Christopherson struct read_cache mem_read;
365018d70ffSEric Hankland bool is_branch;
3662f728d66SSean Christopherson };
3672f728d66SSean Christopherson
3681cca2f8cSSean Christopherson #define KVM_EMULATOR_BUG_ON(cond, ctxt) \
3691cca2f8cSSean Christopherson ({ \
3701cca2f8cSSean Christopherson int __ret = (cond); \
3711cca2f8cSSean Christopherson \
3721cca2f8cSSean Christopherson if (WARN_ON_ONCE(__ret)) \
3731cca2f8cSSean Christopherson ctxt->ops->vm_bugged(ctxt); \
3741cca2f8cSSean Christopherson unlikely(__ret); \
3751cca2f8cSSean Christopherson })
3761cca2f8cSSean Christopherson
3772f728d66SSean Christopherson /* Repeat String Operation Prefix */
3782f728d66SSean Christopherson #define REPE_PREFIX 0xf3
3792f728d66SSean Christopherson #define REPNE_PREFIX 0xf2
3802f728d66SSean Christopherson
3812f728d66SSean Christopherson /* CPUID vendors */
3822f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
3832f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
3842f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
3852f728d66SSean Christopherson
3862f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
3872f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
3882f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
3892f728d66SSean Christopherson
3902f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_HygonGenuine_ebx 0x6f677948
3912f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_HygonGenuine_ecx 0x656e6975
3922f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_HygonGenuine_edx 0x6e65476e
3932f728d66SSean Christopherson
3942f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
3952f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
3962f728d66SSean Christopherson #define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
3972f728d66SSean Christopherson
3988d892311SSean Christopherson #define X86EMUL_CPUID_VENDOR_CentaurHauls_ebx 0x746e6543
3998d892311SSean Christopherson #define X86EMUL_CPUID_VENDOR_CentaurHauls_ecx 0x736c7561
4008d892311SSean Christopherson #define X86EMUL_CPUID_VENDOR_CentaurHauls_edx 0x48727561
4018d892311SSean Christopherson
is_guest_vendor_intel(u32 ebx,u32 ecx,u32 edx)40215608ed0SSean Christopherson static inline bool is_guest_vendor_intel(u32 ebx, u32 ecx, u32 edx)
40315608ed0SSean Christopherson {
40415608ed0SSean Christopherson return ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
40515608ed0SSean Christopherson ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
40615608ed0SSean Christopherson edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx;
40715608ed0SSean Christopherson }
40815608ed0SSean Christopherson
is_guest_vendor_amd(u32 ebx,u32 ecx,u32 edx)40915608ed0SSean Christopherson static inline bool is_guest_vendor_amd(u32 ebx, u32 ecx, u32 edx)
41015608ed0SSean Christopherson {
41115608ed0SSean Christopherson return (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
41215608ed0SSean Christopherson ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
41315608ed0SSean Christopherson edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx) ||
41415608ed0SSean Christopherson (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
41515608ed0SSean Christopherson ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
41615608ed0SSean Christopherson edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx);
41715608ed0SSean Christopherson }
41815608ed0SSean Christopherson
is_guest_vendor_hygon(u32 ebx,u32 ecx,u32 edx)41915608ed0SSean Christopherson static inline bool is_guest_vendor_hygon(u32 ebx, u32 ecx, u32 edx)
42015608ed0SSean Christopherson {
42115608ed0SSean Christopherson return ebx == X86EMUL_CPUID_VENDOR_HygonGenuine_ebx &&
42215608ed0SSean Christopherson ecx == X86EMUL_CPUID_VENDOR_HygonGenuine_ecx &&
42315608ed0SSean Christopherson edx == X86EMUL_CPUID_VENDOR_HygonGenuine_edx;
42415608ed0SSean Christopherson }
42515608ed0SSean Christopherson
4262f728d66SSean Christopherson enum x86_intercept_stage {
4272f728d66SSean Christopherson X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */
4282f728d66SSean Christopherson X86_ICPT_PRE_EXCEPT,
4292f728d66SSean Christopherson X86_ICPT_POST_EXCEPT,
4302f728d66SSean Christopherson X86_ICPT_POST_MEMACCESS,
4312f728d66SSean Christopherson };
4322f728d66SSean Christopherson
4332f728d66SSean Christopherson enum x86_intercept {
4342f728d66SSean Christopherson x86_intercept_none,
4352f728d66SSean Christopherson x86_intercept_cr_read,
4362f728d66SSean Christopherson x86_intercept_cr_write,
4372f728d66SSean Christopherson x86_intercept_clts,
4382f728d66SSean Christopherson x86_intercept_lmsw,
4392f728d66SSean Christopherson x86_intercept_smsw,
4402f728d66SSean Christopherson x86_intercept_dr_read,
4412f728d66SSean Christopherson x86_intercept_dr_write,
4422f728d66SSean Christopherson x86_intercept_lidt,
4432f728d66SSean Christopherson x86_intercept_sidt,
4442f728d66SSean Christopherson x86_intercept_lgdt,
4452f728d66SSean Christopherson x86_intercept_sgdt,
4462f728d66SSean Christopherson x86_intercept_lldt,
4472f728d66SSean Christopherson x86_intercept_sldt,
4482f728d66SSean Christopherson x86_intercept_ltr,
4492f728d66SSean Christopherson x86_intercept_str,
4502f728d66SSean Christopherson x86_intercept_rdtsc,
4512f728d66SSean Christopherson x86_intercept_rdpmc,
4522f728d66SSean Christopherson x86_intercept_pushf,
4532f728d66SSean Christopherson x86_intercept_popf,
4542f728d66SSean Christopherson x86_intercept_cpuid,
4552f728d66SSean Christopherson x86_intercept_rsm,
4562f728d66SSean Christopherson x86_intercept_iret,
4572f728d66SSean Christopherson x86_intercept_intn,
4582f728d66SSean Christopherson x86_intercept_invd,
4592f728d66SSean Christopherson x86_intercept_pause,
4602f728d66SSean Christopherson x86_intercept_hlt,
4612f728d66SSean Christopherson x86_intercept_invlpg,
4622f728d66SSean Christopherson x86_intercept_invlpga,
4632f728d66SSean Christopherson x86_intercept_vmrun,
4642f728d66SSean Christopherson x86_intercept_vmload,
4652f728d66SSean Christopherson x86_intercept_vmsave,
4662f728d66SSean Christopherson x86_intercept_vmmcall,
4672f728d66SSean Christopherson x86_intercept_stgi,
4682f728d66SSean Christopherson x86_intercept_clgi,
4692f728d66SSean Christopherson x86_intercept_skinit,
4702f728d66SSean Christopherson x86_intercept_rdtscp,
4712183de41SSean Christopherson x86_intercept_rdpid,
4722f728d66SSean Christopherson x86_intercept_icebp,
4732f728d66SSean Christopherson x86_intercept_wbinvd,
4742f728d66SSean Christopherson x86_intercept_monitor,
4752f728d66SSean Christopherson x86_intercept_mwait,
4762f728d66SSean Christopherson x86_intercept_rdmsr,
4772f728d66SSean Christopherson x86_intercept_wrmsr,
4782f728d66SSean Christopherson x86_intercept_in,
4792f728d66SSean Christopherson x86_intercept_ins,
4802f728d66SSean Christopherson x86_intercept_out,
4812f728d66SSean Christopherson x86_intercept_outs,
4822f728d66SSean Christopherson x86_intercept_xsetbv,
4832f728d66SSean Christopherson
4842f728d66SSean Christopherson nr_x86_intercepts
4852f728d66SSean Christopherson };
4862f728d66SSean Christopherson
4872f728d66SSean Christopherson /* Host execution mode. */
4882f728d66SSean Christopherson #if defined(CONFIG_X86_32)
4892f728d66SSean Christopherson #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
4902f728d66SSean Christopherson #elif defined(CONFIG_X86_64)
4912f728d66SSean Christopherson #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
4922f728d66SSean Christopherson #endif
4932f728d66SSean Christopherson
494b35491e6SWanpeng Li int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len, int emulation_type);
4952f728d66SSean Christopherson bool x86_page_table_writing_insn(struct x86_emulate_ctxt *ctxt);
4962f728d66SSean Christopherson #define EMULATION_FAILED -1
4972f728d66SSean Christopherson #define EMULATION_OK 0
4982f728d66SSean Christopherson #define EMULATION_RESTART 1
4992f728d66SSean Christopherson #define EMULATION_INTERCEPTED 2
5002f728d66SSean Christopherson void init_decode_cache(struct x86_emulate_ctxt *ctxt);
5012f728d66SSean Christopherson int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
5022f728d66SSean Christopherson int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
5032f728d66SSean Christopherson u16 tss_selector, int idt_index, int reason,
5042f728d66SSean Christopherson bool has_error_code, u32 error_code);
5052f728d66SSean Christopherson int emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq);
5062f728d66SSean Christopherson void emulator_invalidate_register_cache(struct x86_emulate_ctxt *ctxt);
5072f728d66SSean Christopherson void emulator_writeback_register_cache(struct x86_emulate_ctxt *ctxt);
5082f728d66SSean Christopherson bool emulator_can_use_gpa(struct x86_emulate_ctxt *ctxt);
5092f728d66SSean Christopherson
reg_read(struct x86_emulate_ctxt * ctxt,unsigned nr)510f1554150SPaolo Bonzini static inline ulong reg_read(struct x86_emulate_ctxt *ctxt, unsigned nr)
511f1554150SPaolo Bonzini {
512f1554150SPaolo Bonzini if (KVM_EMULATOR_BUG_ON(nr >= NR_EMULATOR_GPRS, ctxt))
513f1554150SPaolo Bonzini nr &= NR_EMULATOR_GPRS - 1;
514f1554150SPaolo Bonzini
515f1554150SPaolo Bonzini if (!(ctxt->regs_valid & (1 << nr))) {
516f1554150SPaolo Bonzini ctxt->regs_valid |= 1 << nr;
517f1554150SPaolo Bonzini ctxt->_regs[nr] = ctxt->ops->read_gpr(ctxt, nr);
518f1554150SPaolo Bonzini }
519f1554150SPaolo Bonzini return ctxt->_regs[nr];
520f1554150SPaolo Bonzini }
521f1554150SPaolo Bonzini
reg_write(struct x86_emulate_ctxt * ctxt,unsigned nr)522f1554150SPaolo Bonzini static inline ulong *reg_write(struct x86_emulate_ctxt *ctxt, unsigned nr)
523f1554150SPaolo Bonzini {
524f1554150SPaolo Bonzini if (KVM_EMULATOR_BUG_ON(nr >= NR_EMULATOR_GPRS, ctxt))
525f1554150SPaolo Bonzini nr &= NR_EMULATOR_GPRS - 1;
526f1554150SPaolo Bonzini
527f1554150SPaolo Bonzini BUILD_BUG_ON(sizeof(ctxt->regs_dirty) * BITS_PER_BYTE < NR_EMULATOR_GPRS);
528f1554150SPaolo Bonzini BUILD_BUG_ON(sizeof(ctxt->regs_valid) * BITS_PER_BYTE < NR_EMULATOR_GPRS);
529f1554150SPaolo Bonzini
530f1554150SPaolo Bonzini ctxt->regs_valid |= 1 << nr;
531f1554150SPaolo Bonzini ctxt->regs_dirty |= 1 << nr;
532f1554150SPaolo Bonzini return &ctxt->_regs[nr];
533f1554150SPaolo Bonzini }
534f1554150SPaolo Bonzini
reg_rmw(struct x86_emulate_ctxt * ctxt,unsigned nr)535f1554150SPaolo Bonzini static inline ulong *reg_rmw(struct x86_emulate_ctxt *ctxt, unsigned nr)
536f1554150SPaolo Bonzini {
537f1554150SPaolo Bonzini reg_read(ctxt, nr);
538f1554150SPaolo Bonzini return reg_write(ctxt, nr);
539f1554150SPaolo Bonzini }
540f1554150SPaolo Bonzini
5412f728d66SSean Christopherson #endif /* _ASM_X86_KVM_X86_EMULATE_H */
542