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
This commit is contained in:
parent
cbba9a7bda
commit
b645fd4531
@ -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_ */
|
||||
|
@ -50,9 +50,14 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/vmm.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <vmmapi.h>
|
||||
#define KASSERT(exp,msg) assert((exp))
|
||||
#define panic(...) errx(4, __VA_ARGS__)
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#include <machine/vmm_instruction_emul.h>
|
||||
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user