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:
Conrad Meyer 2020-04-16 16:50:33 +00:00
parent cbba9a7bda
commit b645fd4531
2 changed files with 24 additions and 2 deletions

View File

@ -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_ */

View File

@ -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 */