summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include/vmm_instruction_emul.h
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-05-24 20:26:57 +0000
committerneel <neel@FreeBSD.org>2014-05-24 20:26:57 +0000
commit6a6e13c407a246faf2265a0ed79ab28fd9419bb6 (patch)
tree507882e99e7a06753f2707b9ed35d4f6aeea4020 /sys/amd64/include/vmm_instruction_emul.h
parent52a4f11861c5ba735a7bb75bd093905e734e16bd (diff)
downloadFreeBSD-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.h78
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_ */
OpenPOWER on IntegriCloud