| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 1 | /****************************************************************************** | 
|  | 2 | * x86_emulate.h | 
|  | 3 | * | 
|  | 4 | * Generic x86 (32-bit and 64-bit) instruction decoder and emulator. | 
|  | 5 | * | 
|  | 6 | * Copyright (c) 2005 Keir Fraser | 
|  | 7 | * | 
|  | 8 | * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4 | 
|  | 9 | */ | 
|  | 10 |  | 
|  | 11 | #ifndef __X86_EMULATE_H__ | 
|  | 12 | #define __X86_EMULATE_H__ | 
|  | 13 |  | 
|  | 14 | struct x86_emulate_ctxt; | 
|  | 15 |  | 
|  | 16 | /* | 
|  | 17 | * x86_emulate_ops: | 
|  | 18 | * | 
|  | 19 | * These operations represent the instruction emulator's interface to memory. | 
|  | 20 | * There are two categories of operation: those that act on ordinary memory | 
|  | 21 | * regions (*_std), and those that act on memory regions known to require | 
|  | 22 | * special treatment or emulation (*_emulated). | 
|  | 23 | * | 
|  | 24 | * The emulator assumes that an instruction accesses only one 'emulated memory' | 
|  | 25 | * location, that this location is the given linear faulting address (cr2), and | 
|  | 26 | * that this is one of the instruction's data operands. Instruction fetches and | 
|  | 27 | * stack operations are assumed never to access emulated memory. The emulator | 
|  | 28 | * automatically deduces which operand of a string-move operation is accessing | 
|  | 29 | * emulated memory, and assumes that the other operand accesses normal memory. | 
|  | 30 | * | 
|  | 31 | * NOTES: | 
|  | 32 | *  1. The emulator isn't very smart about emulated vs. standard memory. | 
|  | 33 | *     'Emulated memory' access addresses should be checked for sanity. | 
|  | 34 | *     'Normal memory' accesses may fault, and the caller must arrange to | 
|  | 35 | *     detect and handle reentrancy into the emulator via recursive faults. | 
|  | 36 | *     Accesses may be unaligned and may cross page boundaries. | 
|  | 37 | *  2. If the access fails (cannot emulate, or a standard access faults) then | 
|  | 38 | *     it is up to the memop to propagate the fault to the guest VM via | 
|  | 39 | *     some out-of-band mechanism, unknown to the emulator. The memop signals | 
|  | 40 | *     failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will | 
|  | 41 | *     then immediately bail. | 
|  | 42 | *  3. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only | 
|  | 43 | *     cmpxchg8b_emulated need support 8-byte accesses. | 
|  | 44 | *  4. The emulator cannot handle 64-bit mode emulation on an x86/32 system. | 
|  | 45 | */ | 
|  | 46 | /* Access completed successfully: continue emulation as normal. */ | 
|  | 47 | #define X86EMUL_CONTINUE        0 | 
|  | 48 | /* Access is unhandleable: bail from emulation and return error to caller. */ | 
|  | 49 | #define X86EMUL_UNHANDLEABLE    1 | 
|  | 50 | /* Terminate emulation but return success to the caller. */ | 
|  | 51 | #define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */ | 
|  | 52 | #define X86EMUL_RETRY_INSTR     2 /* retry the instruction for some reason */ | 
|  | 53 | #define X86EMUL_CMPXCHG_FAILED  2 /* cmpxchg did not see expected value */ | 
|  | 54 | struct x86_emulate_ops { | 
|  | 55 | /* | 
|  | 56 | * read_std: Read bytes of standard (non-emulated/special) memory. | 
|  | 57 | *           Used for instruction fetch, stack operations, and others. | 
|  | 58 | *  @addr:  [IN ] Linear address from which to read. | 
|  | 59 | *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'. | 
|  | 60 | *  @bytes: [IN ] Number of bytes to read from memory. | 
|  | 61 | */ | 
| Avi Kivity | 4c690a1 | 2007-04-22 15:28:19 +0300 | [diff] [blame] | 62 | int (*read_std)(unsigned long addr, void *val, | 
| Laurent Vivier | cebff02 | 2007-07-30 13:35:24 +0300 | [diff] [blame] | 63 | unsigned int bytes, struct kvm_vcpu *vcpu); | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 64 |  | 
|  | 65 | /* | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 66 | * read_emulated: Read bytes from emulated/special memory area. | 
|  | 67 | *  @addr:  [IN ] Linear address from which to read. | 
|  | 68 | *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'. | 
|  | 69 | *  @bytes: [IN ] Number of bytes to read from memory. | 
|  | 70 | */ | 
| Joe Perches | 0c7825e | 2008-03-23 01:02:35 -0700 | [diff] [blame] | 71 | int (*read_emulated)(unsigned long addr, | 
|  | 72 | void *val, | 
|  | 73 | unsigned int bytes, | 
|  | 74 | struct kvm_vcpu *vcpu); | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 75 |  | 
|  | 76 | /* | 
|  | 77 | * write_emulated: Read bytes from emulated/special memory area. | 
|  | 78 | *  @addr:  [IN ] Linear address to which to write. | 
|  | 79 | *  @val:   [IN ] Value to write to memory (low-order bytes used as | 
|  | 80 | *                required). | 
|  | 81 | *  @bytes: [IN ] Number of bytes to write to memory. | 
|  | 82 | */ | 
| Joe Perches | 0c7825e | 2008-03-23 01:02:35 -0700 | [diff] [blame] | 83 | int (*write_emulated)(unsigned long addr, | 
|  | 84 | const void *val, | 
|  | 85 | unsigned int bytes, | 
|  | 86 | struct kvm_vcpu *vcpu); | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 87 |  | 
|  | 88 | /* | 
|  | 89 | * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an | 
|  | 90 | *                   emulated/special memory area. | 
|  | 91 | *  @addr:  [IN ] Linear address to access. | 
|  | 92 | *  @old:   [IN ] Value expected to be current at @addr. | 
|  | 93 | *  @new:   [IN ] Value to write to @addr. | 
|  | 94 | *  @bytes: [IN ] Number of bytes to access using CMPXCHG. | 
|  | 95 | */ | 
| Joe Perches | 0c7825e | 2008-03-23 01:02:35 -0700 | [diff] [blame] | 96 | int (*cmpxchg_emulated)(unsigned long addr, | 
|  | 97 | const void *old, | 
|  | 98 | const void *new, | 
|  | 99 | unsigned int bytes, | 
|  | 100 | struct kvm_vcpu *vcpu); | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 101 |  | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 102 | }; | 
|  | 103 |  | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 104 | /* Type, address-of, and value of an instruction's operand. */ | 
|  | 105 | struct operand { | 
| Laurent Vivier | a01af5e | 2007-09-24 11:10:56 +0200 | [diff] [blame] | 106 | enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 107 | unsigned int bytes; | 
|  | 108 | unsigned long val, orig_val, *ptr; | 
|  | 109 | }; | 
|  | 110 |  | 
| Avi Kivity | 6226686 | 2007-11-20 13:15:52 +0200 | [diff] [blame] | 111 | struct fetch_cache { | 
|  | 112 | u8 data[15]; | 
|  | 113 | unsigned long start; | 
|  | 114 | unsigned long end; | 
|  | 115 | }; | 
|  | 116 |  | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 117 | struct decode_cache { | 
|  | 118 | u8 twobyte; | 
|  | 119 | u8 b; | 
|  | 120 | u8 lock_prefix; | 
|  | 121 | u8 rep_prefix; | 
|  | 122 | u8 op_bytes; | 
|  | 123 | u8 ad_bytes; | 
| Avi Kivity | 33615aa | 2007-10-31 11:15:56 +0200 | [diff] [blame] | 124 | u8 rex_prefix; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 125 | struct operand src; | 
|  | 126 | struct operand dst; | 
| Avi Kivity | 7a5b56d | 2008-06-22 16:22:51 +0300 | [diff] [blame] | 127 | bool has_seg_override; | 
|  | 128 | u8 seg_override; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 129 | unsigned int d; | 
|  | 130 | unsigned long regs[NR_VCPU_REGS]; | 
|  | 131 | unsigned long eip; | 
|  | 132 | /* modrm */ | 
|  | 133 | u8 modrm; | 
|  | 134 | u8 modrm_mod; | 
|  | 135 | u8 modrm_reg; | 
|  | 136 | u8 modrm_rm; | 
|  | 137 | u8 use_modrm_ea; | 
| Avi Kivity | f5b4edc | 2008-06-15 22:09:11 -0700 | [diff] [blame] | 138 | bool rip_relative; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 139 | unsigned long modrm_ea; | 
| Avi Kivity | 107d6d2 | 2008-05-05 14:58:26 +0300 | [diff] [blame] | 140 | void *modrm_ptr; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 141 | unsigned long modrm_val; | 
| Avi Kivity | 6226686 | 2007-11-20 13:15:52 +0200 | [diff] [blame] | 142 | struct fetch_cache fetch; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 143 | }; | 
|  | 144 |  | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 145 | struct x86_emulate_ctxt { | 
|  | 146 | /* Register state before/after emulation. */ | 
|  | 147 | struct kvm_vcpu *vcpu; | 
|  | 148 |  | 
| Joe Perches | 0c7825e | 2008-03-23 01:02:35 -0700 | [diff] [blame] | 149 | /* Linear faulting address (if emulating a page-faulting instruction) */ | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 150 | unsigned long eflags; | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 151 |  | 
|  | 152 | /* Emulated execution mode, represented by an X86EMUL_MODE value. */ | 
|  | 153 | int mode; | 
|  | 154 |  | 
| Avi Kivity | 7a5b56d | 2008-06-22 16:22:51 +0300 | [diff] [blame] | 155 | u32 cs_base; | 
| Laurent Vivier | e4e03de | 2007-09-18 11:52:50 +0200 | [diff] [blame] | 156 |  | 
|  | 157 | /* decode cache */ | 
|  | 158 |  | 
|  | 159 | struct decode_cache decode; | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 160 | }; | 
|  | 161 |  | 
| Guillaume Thouvenin | 90e0a28 | 2007-11-22 11:32:09 +0100 | [diff] [blame] | 162 | /* Repeat String Operation Prefix */ | 
|  | 163 | #define REPE_PREFIX  1 | 
|  | 164 | #define REPNE_PREFIX    2 | 
|  | 165 |  | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 166 | /* Execution mode, passed to the emulator. */ | 
|  | 167 | #define X86EMUL_MODE_REAL     0	/* Real mode.             */ | 
|  | 168 | #define X86EMUL_MODE_PROT16   2	/* 16-bit protected mode. */ | 
|  | 169 | #define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */ | 
|  | 170 | #define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */ | 
|  | 171 |  | 
|  | 172 | /* Host execution mode. */ | 
|  | 173 | #if defined(__i386__) | 
|  | 174 | #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32 | 
| Avi Kivity | 05b3e0c | 2006-12-13 00:33:45 -0800 | [diff] [blame] | 175 | #elif defined(CONFIG_X86_64) | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 176 | #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64 | 
|  | 177 | #endif | 
|  | 178 |  | 
| Laurent Vivier | 1be3aa4 | 2007-09-18 11:27:27 +0200 | [diff] [blame] | 179 | int x86_decode_insn(struct x86_emulate_ctxt *ctxt, | 
|  | 180 | struct x86_emulate_ops *ops); | 
|  | 181 | int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, | 
|  | 182 | struct x86_emulate_ops *ops); | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 183 |  | 
| Avi Kivity | 6aa8b73 | 2006-12-10 02:21:36 -0800 | [diff] [blame] | 184 | #endif				/* __X86_EMULATE_H__ */ |