From b645fd45317501075102601834d715866b838c28 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Thu, 16 Apr 2020 16:50:33 +0000 Subject: [PATCH] vmm(4): Expose instruction decode to userspace build Permit instruction decoding logic to be compiled outside of the kernel for rapid iteration and validation. Reviewed by: grehan Differential Revision: https://reviews.freebsd.org/D24439 --- sys/amd64/include/vmm_instruction_emul.h | 9 +++++++++ sys/amd64/vmm/vmm_instruction_emul.c | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sys/amd64/include/vmm_instruction_emul.h b/sys/amd64/include/vmm_instruction_emul.h index bca2a02e286c..d084301aee0b 100644 --- a/sys/amd64/include/vmm_instruction_emul.h +++ b/sys/amd64/include/vmm_instruction_emul.h @@ -103,6 +103,7 @@ int vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, */ int vm_gla2gpa_nofault(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, uint64_t gla, int prot, uint64_t *gpa, int *is_fault); +#endif /* _KERNEL */ void vie_init(struct vie *vie, const char *inst_bytes, int inst_length); @@ -117,9 +118,17 @@ void vie_init(struct vie *vie, const char *inst_bytes, int inst_length); * To skip the 'gla' verification for this or any other reason pass * in VIE_INVALID_GLA instead. */ +#ifdef _KERNEL #define VIE_INVALID_GLA (1UL << 63) /* a non-canonical address */ int vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla, enum vm_cpu_mode cpu_mode, int csd, struct vie *vie); +#else /* !_KERNEL */ +/* + * Permit instruction decoding logic to be compiled outside of the kernel for + * rapid iteration and validation. No GLA validation is performed, obviously. + */ +int vmm_decode_instruction(enum vm_cpu_mode cpu_mode, int csd, + struct vie *vie); #endif /* _KERNEL */ #endif /* _VMM_INSTRUCTION_EMUL_H_ */ diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c index f3afa23d8281..2b4be93cbf4e 100644 --- a/sys/amd64/vmm/vmm_instruction_emul.c +++ b/sys/amd64/vmm/vmm_instruction_emul.c @@ -50,9 +50,14 @@ __FBSDID("$FreeBSD$"); #include +#include #include +#include +#include +#include #include #define KASSERT(exp,msg) assert((exp)) +#define panic(...) errx(4, __VA_ARGS__) #endif /* _KERNEL */ #include @@ -1896,7 +1901,6 @@ vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum vm_reg_name seg, return (0); } -#ifdef _KERNEL void vie_init(struct vie *vie, const char *inst_bytes, int inst_length) { @@ -1915,6 +1919,7 @@ vie_init(struct vie *vie, const char *inst_bytes, int inst_length) } } +#ifdef _KERNEL static int pf_error_code(int usermode, int prot, int rsvd, uint64_t pte) { @@ -2189,6 +2194,7 @@ vmm_fetch_instruction(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, vie->num_valid = inst_length; return (0); } +#endif /* _KERNEL */ static int vie_peek(struct vie *vie, uint8_t *x) @@ -2611,6 +2617,7 @@ decode_moffset(struct vie *vie) return (0); } +#ifdef _KERNEL /* * Verify that the 'guest linear address' provided as collateral of the nested * page table fault matches with our instruction decoding. @@ -2702,10 +2709,15 @@ verify_gla(struct vm *vm, int cpuid, uint64_t gla, struct vie *vie, return (0); } +#endif /* _KERNEL */ int +#ifdef _KERNEL vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla, enum vm_cpu_mode cpu_mode, int cs_d, struct vie *vie) +#else +vmm_decode_instruction(enum vm_cpu_mode cpu_mode, int cs_d, struct vie *vie) +#endif { if (decode_prefixes(vie, cpu_mode, cs_d)) @@ -2729,13 +2741,14 @@ vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla, if (decode_moffset(vie)) return (-1); +#ifdef _KERNEL if ((vie->op.op_flags & VIE_OP_F_NO_GLA_VERIFICATION) == 0) { if (verify_gla(vm, cpuid, gla, vie, cpu_mode)) return (-1); } +#endif vie->decoded = 1; /* success */ return (0); } -#endif /* _KERNEL */