diff options
author | neel <neel@FreeBSD.org> | 2014-05-24 20:26:57 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2014-05-24 20:26:57 +0000 |
commit | 6a6e13c407a246faf2265a0ed79ab28fd9419bb6 (patch) | |
tree | 507882e99e7a06753f2707b9ed35d4f6aeea4020 /sys/amd64/include/vmm_instruction_emul.h | |
parent | 52a4f11861c5ba735a7bb75bd093905e734e16bd (diff) | |
download | FreeBSD-src-6a6e13c407a246faf2265a0ed79ab28fd9419bb6.zip FreeBSD-src-6a6e13c407a246faf2265a0ed79ab28fd9419bb6.tar.gz |
Consolidate all the information needed by the guest page table walker into
'struct vm_guest_paging'.
Check for canonical addressing in vmm_gla2gpa() and inject a protection
fault into the guest if a violation is detected.
If the page table walk is restarted in vmm_gla2gpa() then reset 'ptpphys' to
point to the root of the page tables.
Diffstat (limited to 'sys/amd64/include/vmm_instruction_emul.h')
-rw-r--r-- | sys/amd64/include/vmm_instruction_emul.h | 78 |
1 files changed, 10 insertions, 68 deletions
diff --git a/sys/amd64/include/vmm_instruction_emul.h b/sys/amd64/include/vmm_instruction_emul.h index 797cb39..1703feb 100644 --- a/sys/amd64/include/vmm_instruction_emul.h +++ b/sys/amd64/include/vmm_instruction_emul.h @@ -29,66 +29,6 @@ #ifndef _VMM_INSTRUCTION_EMUL_H_ #define _VMM_INSTRUCTION_EMUL_H_ -enum vm_reg_name; - -enum vie_cpu_mode { - CPU_MODE_COMPATIBILITY, /* IA-32E mode (CS.L = 0) */ - CPU_MODE_64BIT, /* IA-32E mode (CS.L = 1) */ -}; - -enum vie_paging_mode { - PAGING_MODE_FLAT, - PAGING_MODE_32, - PAGING_MODE_PAE, - PAGING_MODE_64, -}; - -/* - * The data structures 'vie' and 'vie_op' are meant to be opaque to the - * consumers of instruction decoding. The only reason why their contents - * need to be exposed is because they are part of the 'vm_exit' structure. - */ -struct vie_op { - uint8_t op_byte; /* actual opcode byte */ - uint8_t op_type; /* type of operation (e.g. MOV) */ - uint16_t op_flags; -}; - -#define VIE_INST_SIZE 15 -struct vie { - uint8_t inst[VIE_INST_SIZE]; /* instruction bytes */ - uint8_t num_valid; /* size of the instruction */ - uint8_t num_processed; - - uint8_t rex_w:1, /* REX prefix */ - rex_r:1, - rex_x:1, - rex_b:1, - rex_present:1; - - uint8_t mod:2, /* ModRM byte */ - reg:4, - rm:4; - - uint8_t ss:2, /* SIB byte */ - index:4, - base:4; - - uint8_t disp_bytes; - uint8_t imm_bytes; - - uint8_t scale; - int base_register; /* VM_REG_GUEST_xyz */ - int index_register; /* VM_REG_GUEST_xyz */ - - int64_t displacement; /* optional addr displacement */ - int64_t immediate; /* optional immediate operand */ - - uint8_t decoded; /* set to 1 if successfully decoded */ - - struct vie_op op; /* opcode description */ -}; - /* * Callback functions to read and write memory regions. */ @@ -122,6 +62,9 @@ int vie_update_register(void *vm, int vcpuid, enum vm_reg_name reg, int vie_alignment_check(int cpl, int operand_size, uint64_t cr0, uint64_t rflags, uint64_t gla); +/* Returns 1 if the 'gla' is not canonical and 0 otherwise. */ +int vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla); + uint64_t vie_size2mask(int size); #ifdef _KERNEL @@ -131,23 +74,22 @@ uint64_t vie_size2mask(int size); * 'vie' must be initialized before calling 'vmm_fetch_instruction()' */ int vmm_fetch_instruction(struct vm *vm, int cpuid, - uint64_t rip, int inst_length, uint64_t cr3, - enum vie_paging_mode paging_mode, int cpl, - struct vie *vie); + struct vm_guest_paging *guest_paging, + uint64_t rip, int inst_length, struct vie *vie); /* * Translate the guest linear address 'gla' to a guest physical address. * * Returns 0 on success and '*gpa' contains the result of the translation. - * Returns 1 if a page fault exception was injected into the guest. + * Returns 1 if an exception was injected into the guest. * Returns -1 otherwise. */ -int vmm_gla2gpa(struct vm *vm, int vcpuid, uint64_t gla, uint64_t cr3, - uint64_t *gpa, enum vie_paging_mode paging_mode, int cpl, int prot); +int vmm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, + uint64_t gla, int prot, uint64_t *gpa); void vie_init(struct vie *vie); -uint64_t vie_segbase(enum vm_reg_name segment, enum vie_cpu_mode cpu_mode, +uint64_t vie_segbase(enum vm_reg_name segment, enum vm_cpu_mode cpu_mode, const struct seg_desc *desc); /* @@ -163,7 +105,7 @@ uint64_t vie_segbase(enum vm_reg_name segment, enum vie_cpu_mode cpu_mode, */ #define VIE_INVALID_GLA (1UL << 63) /* a non-canonical address */ int vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla, - enum vie_cpu_mode cpu_mode, struct vie *vie); + enum vm_cpu_mode cpu_mode, struct vie *vie); #endif /* _KERNEL */ #endif /* _VMM_INSTRUCTION_EMUL_H_ */ |