/* * This struct is used to carry enough information from the instruction * decoder to main KVM so that a decision can be made whether the * instruction needs to be intercepted or not.
*/ struct x86_instruction_info {
u8 intercept; /* which intercept */
u8 rep_prefix; /* rep prefix? */
u8 modrm_mod; /* mod part of modrm */
u8 modrm_reg; /* index of register used */
u8 modrm_rm; /* rm part of modrm */
u64 src_val; /* value of source operand */
u64 dst_val; /* value of destination operand */
u8 src_bytes; /* size of source operand */
u8 dst_bytes; /* size of destination operand */
u8 src_type; /* type of source operand */
u8 dst_type; /* type of destination operand */
u8 ad_bytes; /* size of src/dst address */
u64 rip; /* rip of the instruction */
u64 next_rip; /* rip following the instruction */
};
/* * x86_emulate_ops: * * These operations represent the instruction emulator's interface to memory. * There are two categories of operation: those that act on ordinary memory * regions (*_std), and those that act on memory regions known to require * special treatment or emulation (*_emulated). * * The emulator assumes that an instruction accesses only one 'emulated memory' * location, that this location is the given linear faulting address (cr2), and * that this is one of the instruction's data operands. Instruction fetches and * stack operations are assumed never to access emulated memory. The emulator * automatically deduces which operand of a string-move operation is accessing * emulated memory, and assumes that the other operand accesses normal memory. * * NOTES: * 1. The emulator isn't very smart about emulated vs. standard memory. * 'Emulated memory' access addresses should be checked for sanity. * 'Normal memory' accesses may fault, and the caller must arrange to * detect and handle reentrancy into the emulator via recursive faults. * Accesses may be unaligned and may cross page boundaries. * 2. If the access fails (cannot emulate, or a standard access faults) then * it is up to the memop to propagate the fault to the guest VM via * some out-of-band mechanism, unknown to the emulator. The memop signals * failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will * then immediately bail. * 3. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only * cmpxchg8b_emulated need support 8-byte accesses. * 4. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
*/ /* Access completed successfully: continue emulation as normal. */ #define X86EMUL_CONTINUE 0 /* Access is unhandleable: bail from emulation and return error to caller. */ #define X86EMUL_UNHANDLEABLE 1 /* Terminate emulation but return success to the caller. */ #define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */ #define X86EMUL_RETRY_INSTR 3 /* retry the instruction for some reason */ #define X86EMUL_CMPXCHG_FAILED 4 /* cmpxchg did not see expected value */ #define X86EMUL_IO_NEEDED 5 /* IO is needed to complete emulation */ #define X86EMUL_INTERCEPTED 6 /* Intercepted by nested VMCB/VMCS */ /* Emulation during event vectoring is unhandleable. */ #define X86EMUL_UNHANDLEABLE_VECTORING 7
struct x86_emulate_ops { void (*vm_bugged)(struct x86_emulate_ctxt *ctxt); /* * read_gpr: read a general purpose register (rax - r15) * * @reg: gpr number.
*/
ulong (*read_gpr)(struct x86_emulate_ctxt *ctxt, unsigned reg); /* * write_gpr: write a general purpose register (rax - r15) * * @reg: gpr number. * @val: value to write.
*/ void (*write_gpr)(struct x86_emulate_ctxt *ctxt, unsigned reg, ulong val); /* * read_std: Read bytes of standard (non-emulated/special) memory. * Used for descriptor reading. * @addr: [IN ] Linear address from which to read. * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. * @system:[IN ] Whether the access is forced to be at CPL0.
*/ int (*read_std)(struct x86_emulate_ctxt *ctxt, unsignedlong addr, void *val, unsignedint bytes, struct x86_exception *fault, bool system);
/* * write_std: Write bytes of standard (non-emulated/special) memory. * Used for descriptor writing. * @addr: [IN ] Linear address to which to write. * @val: [OUT] Value write to memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to write to memory. * @system:[IN ] Whether the access is forced to be at CPL0.
*/ int (*write_std)(struct x86_emulate_ctxt *ctxt, unsignedlong addr, void *val, unsignedint bytes, struct x86_exception *fault, bool system); /* * fetch: Read bytes of standard (non-emulated/special) memory. * Used for instruction fetch. * @addr: [IN ] Linear address from which to read. * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory.
*/ int (*fetch)(struct x86_emulate_ctxt *ctxt, unsignedlong addr, void *val, unsignedint bytes, struct x86_exception *fault);
/* * read_emulated: Read bytes from emulated/special memory area. * @addr: [IN ] Linear address from which to read. * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory.
*/ int (*read_emulated)(struct x86_emulate_ctxt *ctxt, unsignedlong addr, void *val, unsignedint bytes, struct x86_exception *fault);
/* * write_emulated: Write bytes to emulated/special memory area. * @addr: [IN ] Linear address to which to write. * @val: [IN ] Value to write to memory (low-order bytes used as * required). * @bytes: [IN ] Number of bytes to write to memory.
*/ int (*write_emulated)(struct x86_emulate_ctxt *ctxt, unsignedlong addr, constvoid *val, unsignedint bytes, struct x86_exception *fault);
/* * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an * emulated/special memory area. * @addr: [IN ] Linear address to access. * @old: [IN ] Value expected to be current at @addr. * @new: [IN ] Value to write to @addr. * @bytes: [IN ] Number of bytes to access using CMPXCHG.
*/ int (*cmpxchg_emulated)(struct x86_emulate_ctxt *ctxt, unsignedlong addr, constvoid *old, constvoid *new, unsignedint bytes, struct x86_exception *fault); void (*invlpg)(struct x86_emulate_ctxt *ctxt, ulong addr);
int (*pio_in_emulated)(struct x86_emulate_ctxt *ctxt, int size, unsignedshort port, void *val, unsignedint count);
int (*pio_out_emulated)(struct x86_emulate_ctxt *ctxt, int size, unsignedshort port, constvoid *val, unsignedint count);
bool (*get_segment)(struct x86_emulate_ctxt *ctxt, u16 *selector, struct desc_struct *desc, u32 *base3, int seg); void (*set_segment)(struct x86_emulate_ctxt *ctxt, u16 selector, struct desc_struct *desc, u32 base3, int seg); unsignedlong (*get_cached_segment_base)(struct x86_emulate_ctxt *ctxt, int seg); void (*get_gdt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt); void (*get_idt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt); void (*set_gdt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt); void (*set_idt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
ulong (*get_cr)(struct x86_emulate_ctxt *ctxt, int cr); int (*set_cr)(struct x86_emulate_ctxt *ctxt, int cr, ulong val); int (*cpl)(struct x86_emulate_ctxt *ctxt);
ulong (*get_dr)(struct x86_emulate_ctxt *ctxt, int dr); int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value); int (*set_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data); int (*get_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata); int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata); int (*check_rdpmc_early)(struct x86_emulate_ctxt *ctxt, u32 pmc); int (*read_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc, u64 *pdata); void (*halt)(struct x86_emulate_ctxt *ctxt); void (*wbinvd)(struct x86_emulate_ctxt *ctxt); int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt); int (*intercept)(struct x86_emulate_ctxt *ctxt, struct x86_instruction_info *info, enum x86_intercept_stage stage);
/* * fastop functions are declared as taking a never-defined fastop parameter, * so they can't be called from C directly.
*/ struct fastop;
typedefvoid (*fastop_t)(struct fastop *);
/* * The emulator's _regs array tracks only the GPRs, i.e. excludes RIP. RIP is * tracked/accessed via _eip, and except for RIP relative addressing, which * also uses _eip, RIP cannot be a register operand nor can it be an operand in * a ModRM or SIB byte.
*/ #ifdef CONFIG_X86_64 #define NR_EMULATOR_GPRS 16 #else #define NR_EMULATOR_GPRS 8 #endif
/* GPA available */ bool gpa_available;
gpa_t gpa_val;
/* * decode cache
*/
/* current opcode length in bytes */
u8 opcode_len;
u8 b;
u8 intercept;
u8 op_bytes;
u8 ad_bytes; union { int (*execute)(struct x86_emulate_ctxt *ctxt);
fastop_t fop;
}; int (*check_perm)(struct x86_emulate_ctxt *ctxt);
bool rip_relative;
u8 rex_prefix;
u8 lock_prefix;
u8 rep_prefix; /* bitmaps of registers in _regs[] that can be read */
u16 regs_valid; /* bitmaps of registers in _regs[] that have been written */
u16 regs_dirty; /* modrm */
u8 modrm;
u8 modrm_mod;
u8 modrm_reg;
u8 modrm_rm;
u8 modrm_seg;
u8 seg_override;
u64 d; unsignedlong _eip;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.