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
sys/amd64
@ -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,
|
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);
|
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);
|
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
|
* To skip the 'gla' verification for this or any other reason pass
|
||||||
* in VIE_INVALID_GLA instead.
|
* in VIE_INVALID_GLA instead.
|
||||||
*/
|
*/
|
||||||
|
#ifdef _KERNEL
|
||||||
#define VIE_INVALID_GLA (1UL << 63) /* a non-canonical address */
|
#define VIE_INVALID_GLA (1UL << 63) /* a non-canonical address */
|
||||||
int vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla,
|
int vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla,
|
||||||
enum vm_cpu_mode cpu_mode, int csd, struct vie *vie);
|
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 /* _KERNEL */
|
||||||
|
|
||||||
#endif /* _VMM_INSTRUCTION_EMUL_H_ */
|
#endif /* _VMM_INSTRUCTION_EMUL_H_ */
|
||||||
|
@ -50,9 +50,14 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/vmm.h>
|
#include <machine/vmm.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <strings.h>
|
||||||
#include <vmmapi.h>
|
#include <vmmapi.h>
|
||||||
#define KASSERT(exp,msg) assert((exp))
|
#define KASSERT(exp,msg) assert((exp))
|
||||||
|
#define panic(...) errx(4, __VA_ARGS__)
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
#include <machine/vmm_instruction_emul.h>
|
#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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _KERNEL
|
|
||||||
void
|
void
|
||||||
vie_init(struct vie *vie, const char *inst_bytes, int inst_length)
|
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
|
static int
|
||||||
pf_error_code(int usermode, int prot, int rsvd, uint64_t pte)
|
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;
|
vie->num_valid = inst_length;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vie_peek(struct vie *vie, uint8_t *x)
|
vie_peek(struct vie *vie, uint8_t *x)
|
||||||
@ -2611,6 +2617,7 @@ decode_moffset(struct vie *vie)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
/*
|
/*
|
||||||
* Verify that the 'guest linear address' provided as collateral of the nested
|
* Verify that the 'guest linear address' provided as collateral of the nested
|
||||||
* page table fault matches with our instruction decoding.
|
* 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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
int
|
int
|
||||||
|
#ifdef _KERNEL
|
||||||
vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla,
|
vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla,
|
||||||
enum vm_cpu_mode cpu_mode, int cs_d, struct vie *vie)
|
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))
|
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))
|
if (decode_moffset(vie))
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
if ((vie->op.op_flags & VIE_OP_F_NO_GLA_VERIFICATION) == 0) {
|
if ((vie->op.op_flags & VIE_OP_F_NO_GLA_VERIFICATION) == 0) {
|
||||||
if (verify_gla(vm, cpuid, gla, vie, cpu_mode))
|
if (verify_gla(vm, cpuid, gla, vie, cpu_mode))
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vie->decoded = 1; /* success */
|
vie->decoded = 1; /* success */
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif /* _KERNEL */
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user