xref: /freebsd/sys/amd64/vmm/vmm_instruction_emul.c (revision 8a166cafe0965f6bd72cd3d2f5372704f05cb5e8)
1 /*-
2  * Copyright (c) 2012 Sandvine, Inc.
3  * Copyright (c) 2012 NetApp, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #ifdef _KERNEL
34 #include <sys/param.h>
35 #include <sys/pcpu.h>
36 #include <sys/systm.h>
37 
38 #include <vm/vm.h>
39 #include <vm/pmap.h>
40 
41 #include <machine/pmap.h>
42 #include <machine/vmparam.h>
43 #include <machine/vmm.h>
44 #else	/* !_KERNEL */
45 #include <sys/types.h>
46 #include <sys/errno.h>
47 
48 #include <machine/vmm.h>
49 
50 #include <vmmapi.h>
51 #endif	/* _KERNEL */
52 
53 
54 
55 /* struct vie_op.op_type */
56 enum {
57 	VIE_OP_TYPE_NONE = 0,
58 	VIE_OP_TYPE_MOV,
59 	VIE_OP_TYPE_AND,
60 	VIE_OP_TYPE_LAST
61 };
62 
63 /* struct vie_op.op_flags */
64 #define	VIE_OP_F_IMM		(1 << 0)	/* immediate operand present */
65 #define	VIE_OP_F_IMM8		(1 << 1)	/* 8-bit immediate operand */
66 
67 static const struct vie_op one_byte_opcodes[256] = {
68 	[0x88] = {
69 		.op_byte = 0x88,
70 		.op_type = VIE_OP_TYPE_MOV,
71 	},
72 	[0x89] = {
73 		.op_byte = 0x89,
74 		.op_type = VIE_OP_TYPE_MOV,
75 	},
76 	[0x8B] = {
77 		.op_byte = 0x8B,
78 		.op_type = VIE_OP_TYPE_MOV,
79 	},
80 	[0xC7] = {
81 		.op_byte = 0xC7,
82 		.op_type = VIE_OP_TYPE_MOV,
83 		.op_flags = VIE_OP_F_IMM,
84 	},
85 	[0x23] = {
86 		.op_byte = 0x23,
87 		.op_type = VIE_OP_TYPE_AND,
88 	},
89 	[0x81] = {
90 		/* XXX Group 1 extended opcode - not just AND */
91 		.op_byte = 0x81,
92 		.op_type = VIE_OP_TYPE_AND,
93 		.op_flags = VIE_OP_F_IMM,
94 	}
95 };
96 
97 /* struct vie.mod */
98 #define	VIE_MOD_INDIRECT		0
99 #define	VIE_MOD_INDIRECT_DISP8		1
100 #define	VIE_MOD_INDIRECT_DISP32		2
101 #define	VIE_MOD_DIRECT			3
102 
103 /* struct vie.rm */
104 #define	VIE_RM_SIB			4
105 #define	VIE_RM_DISP32			5
106 
107 #define	GB				(1024 * 1024 * 1024)
108 
109 static enum vm_reg_name gpr_map[16] = {
110 	VM_REG_GUEST_RAX,
111 	VM_REG_GUEST_RCX,
112 	VM_REG_GUEST_RDX,
113 	VM_REG_GUEST_RBX,
114 	VM_REG_GUEST_RSP,
115 	VM_REG_GUEST_RBP,
116 	VM_REG_GUEST_RSI,
117 	VM_REG_GUEST_RDI,
118 	VM_REG_GUEST_R8,
119 	VM_REG_GUEST_R9,
120 	VM_REG_GUEST_R10,
121 	VM_REG_GUEST_R11,
122 	VM_REG_GUEST_R12,
123 	VM_REG_GUEST_R13,
124 	VM_REG_GUEST_R14,
125 	VM_REG_GUEST_R15
126 };
127 
128 static uint64_t size2mask[] = {
129 	[1] = 0xff,
130 	[2] = 0xffff,
131 	[4] = 0xffffffff,
132 	[8] = 0xffffffffffffffff,
133 };
134 
135 static int
136 vie_valid_register(enum vm_reg_name reg)
137 {
138 #ifdef _KERNEL
139 	/*
140 	 * XXX
141 	 * The operand register in which we store the result of the
142 	 * read must be a GPR that we can modify even if the vcpu
143 	 * is "running". All the GPRs qualify except for %rsp.
144 	 *
145 	 * This is a limitation of the vm_set_register() API
146 	 * and can be fixed if necessary.
147 	 */
148 	if (reg == VM_REG_GUEST_RSP)
149 		return (0);
150 #endif
151 	return (1);
152 }
153 
154 static int
155 vie_read_register(void *vm, int vcpuid, enum vm_reg_name reg, uint64_t *rval)
156 {
157 	int error;
158 
159 	if (!vie_valid_register(reg))
160 		return (EINVAL);
161 
162 	error = vm_get_register(vm, vcpuid, reg, rval);
163 
164 	return (error);
165 }
166 
167 static int
168 vie_read_bytereg(void *vm, int vcpuid, struct vie *vie, uint8_t *rval)
169 {
170 	uint64_t val;
171 	int error, rshift;
172 	enum vm_reg_name reg;
173 
174 	rshift = 0;
175 	reg = gpr_map[vie->reg];
176 
177 	/*
178 	 * 64-bit mode imposes limitations on accessing legacy byte registers.
179 	 *
180 	 * The legacy high-byte registers cannot be addressed if the REX
181 	 * prefix is present. In this case the values 4, 5, 6 and 7 of the
182 	 * 'ModRM:reg' field address %spl, %bpl, %sil and %dil respectively.
183 	 *
184 	 * If the REX prefix is not present then the values 4, 5, 6 and 7
185 	 * of the 'ModRM:reg' field address the legacy high-byte registers,
186 	 * %ah, %ch, %dh and %bh respectively.
187 	 */
188 	if (!vie->rex_present) {
189 		if (vie->reg & 0x4) {
190 			/*
191 			 * Obtain the value of %ah by reading %rax and shifting
192 			 * right by 8 bits (same for %bh, %ch and %dh).
193 			 */
194 			rshift = 8;
195 			reg = gpr_map[vie->reg & 0x3];
196 		}
197 	}
198 
199 	if (!vie_valid_register(reg))
200 		return (EINVAL);
201 
202 	error = vm_get_register(vm, vcpuid, reg, &val);
203 	*rval = val >> rshift;
204 	return (error);
205 }
206 
207 static int
208 vie_update_register(void *vm, int vcpuid, enum vm_reg_name reg,
209 		    uint64_t val, int size)
210 {
211 	int error;
212 	uint64_t origval;
213 
214 	if (!vie_valid_register(reg))
215 		return (EINVAL);
216 
217 	switch (size) {
218 	case 1:
219 	case 2:
220 		error = vie_read_register(vm, vcpuid, reg, &origval);
221 		if (error)
222 			return (error);
223 		val &= size2mask[size];
224 		val |= origval & ~size2mask[size];
225 		break;
226 	case 4:
227 		val &= 0xffffffffUL;
228 		break;
229 	case 8:
230 		break;
231 	default:
232 		return (EINVAL);
233 	}
234 
235 	error = vm_set_register(vm, vcpuid, reg, val);
236 	return (error);
237 }
238 
239 /*
240  * The following simplifying assumptions are made during emulation:
241  *
242  * - guest is in 64-bit mode
243  *   - default address size is 64-bits
244  *   - default operand size is 32-bits
245  *
246  * - operand size override is not supported
247  *
248  * - address size override is not supported
249  */
250 static int
251 emulate_mov(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
252 	    mem_region_read_t memread, mem_region_write_t memwrite, void *arg)
253 {
254 	int error, size;
255 	enum vm_reg_name reg;
256 	uint8_t byte;
257 	uint64_t val;
258 
259 	size = 4;
260 	error = EINVAL;
261 
262 	switch (vie->op.op_byte) {
263 	case 0x88:
264 		/*
265 		 * MOV byte from reg (ModRM:reg) to mem (ModRM:r/m)
266 		 * 88/r:	mov r/m8, r8
267 		 * REX + 88/r:	mov r/m8, r8 (%ah, %ch, %dh, %bh not available)
268 		 */
269 		size = 1;
270 		error = vie_read_bytereg(vm, vcpuid, vie, &byte);
271 		if (error == 0)
272 			error = memwrite(vm, vcpuid, gpa, byte, size, arg);
273 		break;
274 	case 0x89:
275 		/*
276 		 * MOV from reg (ModRM:reg) to mem (ModRM:r/m)
277 		 * 89/r:	mov r/m32, r32
278 		 * REX.W + 89/r	mov r/m64, r64
279 		 */
280 		if (vie->rex_w)
281 			size = 8;
282 		reg = gpr_map[vie->reg];
283 		error = vie_read_register(vm, vcpuid, reg, &val);
284 		if (error == 0) {
285 			val &= size2mask[size];
286 			error = memwrite(vm, vcpuid, gpa, val, size, arg);
287 		}
288 		break;
289 	case 0x8B:
290 		/*
291 		 * MOV from mem (ModRM:r/m) to reg (ModRM:reg)
292 		 * 8B/r:	mov r32, r/m32
293 		 * REX.W 8B/r:	mov r64, r/m64
294 		 */
295 		if (vie->rex_w)
296 			size = 8;
297 		error = memread(vm, vcpuid, gpa, &val, size, arg);
298 		if (error == 0) {
299 			reg = gpr_map[vie->reg];
300 			error = vie_update_register(vm, vcpuid, reg, val, size);
301 		}
302 		break;
303 	case 0xC7:
304 		/*
305 		 * MOV from imm32 to mem (ModRM:r/m)
306 		 * C7/0		mov r/m32, imm32
307 		 * REX.W + C7/0	mov r/m64, imm32 (sign-extended to 64-bits)
308 		 */
309 		val = vie->immediate;		/* already sign-extended */
310 
311 		if (vie->rex_w)
312 			size = 8;
313 
314 		if (size != 8)
315 			val &= size2mask[size];
316 
317 		error = memwrite(vm, vcpuid, gpa, val, size, arg);
318 		break;
319 	default:
320 		break;
321 	}
322 
323 	return (error);
324 }
325 
326 static int
327 emulate_and(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
328 	    mem_region_read_t memread, mem_region_write_t memwrite, void *arg)
329 {
330 	int error, size;
331 	enum vm_reg_name reg;
332 	uint64_t val1, val2;
333 
334 	size = 4;
335 	error = EINVAL;
336 
337 	switch (vie->op.op_byte) {
338 	case 0x23:
339 		/*
340 		 * AND reg (ModRM:reg) and mem (ModRM:r/m) and store the
341 		 * result in reg.
342 		 *
343 		 * 23/r		and r32, r/m32
344 		 * REX.W + 23/r	and r64, r/m64
345 		 */
346 		if (vie->rex_w)
347 			size = 8;
348 
349 		/* get the first operand */
350 		reg = gpr_map[vie->reg];
351 		error = vie_read_register(vm, vcpuid, reg, &val1);
352 		if (error)
353 			break;
354 
355 		/* get the second operand */
356 		error = memread(vm, vcpuid, gpa, &val2, size, arg);
357 		if (error)
358 			break;
359 
360 		/* perform the operation and write the result */
361 		val1 &= val2;
362 		error = vie_update_register(vm, vcpuid, reg, val1, size);
363 		break;
364 	case 0x81:
365 		/*
366 		 * AND reg (ModRM:reg) with immediate and store the
367 		 * result in reg
368 		 *
369 		 * 81/          and r/m32, imm32
370 		 * REX.W + 81/  and r/m64, imm32 sign-extended to 64
371 		 *
372 		 * Currently, only the AND operation of the 0x81 opcode
373 		 * is implemented (ModRM:reg = b100).
374 		 */
375 		if ((vie->reg & 7) != 4)
376 			break;
377 
378 		if (vie->rex_w)
379 			size = 8;
380 
381 		/* get the first operand */
382                 error = memread(vm, vcpuid, gpa, &val1, size, arg);
383                 if (error)
384 			break;
385 
386                 /*
387 		 * perform the operation with the pre-fetched immediate
388 		 * operand and write the result
389 		 */
390                 val1 &= vie->immediate;
391                 error = memwrite(vm, vcpuid, gpa, val1, size, arg);
392 		break;
393 	default:
394 		break;
395 	}
396 	return (error);
397 }
398 
399 int
400 vmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
401 			mem_region_read_t memread, mem_region_write_t memwrite,
402 			void *memarg)
403 {
404 	int error;
405 
406 	if (!vie->decoded)
407 		return (EINVAL);
408 
409 	switch (vie->op.op_type) {
410 	case VIE_OP_TYPE_MOV:
411 		error = emulate_mov(vm, vcpuid, gpa, vie,
412 				    memread, memwrite, memarg);
413 		break;
414 	case VIE_OP_TYPE_AND:
415 		error = emulate_and(vm, vcpuid, gpa, vie,
416 				    memread, memwrite, memarg);
417 		break;
418 	default:
419 		error = EINVAL;
420 		break;
421 	}
422 
423 	return (error);
424 }
425 
426 #ifdef _KERNEL
427 static void
428 vie_init(struct vie *vie)
429 {
430 
431 	bzero(vie, sizeof(struct vie));
432 
433 	vie->base_register = VM_REG_LAST;
434 	vie->index_register = VM_REG_LAST;
435 }
436 
437 static int
438 gla2gpa(struct vm *vm, uint64_t gla, uint64_t ptpphys,
439 	uint64_t *gpa, uint64_t *gpaend)
440 {
441 	vm_paddr_t hpa;
442 	int nlevels, ptpshift, ptpindex;
443 	uint64_t *ptpbase, pte, pgsize;
444 
445 	/*
446 	 * XXX assumes 64-bit guest with 4 page walk levels
447 	 */
448 	nlevels = 4;
449 	while (--nlevels >= 0) {
450 		/* Zero out the lower 12 bits and the upper 12 bits */
451 		ptpphys >>= 12; ptpphys <<= 24; ptpphys >>= 12;
452 
453 		hpa = vm_gpa2hpa(vm, ptpphys, PAGE_SIZE);
454 		if (hpa == -1)
455 			goto error;
456 
457 		ptpbase = (uint64_t *)PHYS_TO_DMAP(hpa);
458 
459 		ptpshift = PAGE_SHIFT + nlevels * 9;
460 		ptpindex = (gla >> ptpshift) & 0x1FF;
461 		pgsize = 1UL << ptpshift;
462 
463 		pte = ptpbase[ptpindex];
464 
465 		if ((pte & PG_V) == 0)
466 			goto error;
467 
468 		if (pte & PG_PS) {
469 			if (pgsize > 1 * GB)
470 				goto error;
471 			else
472 				break;
473 		}
474 
475 		ptpphys = pte;
476 	}
477 
478 	/* Zero out the lower 'ptpshift' bits and the upper 12 bits */
479 	pte >>= ptpshift; pte <<= (ptpshift + 12); pte >>= 12;
480 	*gpa = pte | (gla & (pgsize - 1));
481 	*gpaend = pte + pgsize;
482 	return (0);
483 
484 error:
485 	return (-1);
486 }
487 
488 int
489 vmm_fetch_instruction(struct vm *vm, int cpuid, uint64_t rip, int inst_length,
490 		      uint64_t cr3, struct vie *vie)
491 {
492 	int n, err;
493 	uint64_t hpa, gpa, gpaend, off;
494 
495 	/*
496 	 * XXX cache previously fetched instructions using 'rip' as the tag
497 	 */
498 
499 	if (inst_length > VIE_INST_SIZE)
500 		panic("vmm_fetch_instruction: invalid length %d", inst_length);
501 
502 	vie_init(vie);
503 
504 	/* Copy the instruction into 'vie' */
505 	while (vie->num_valid < inst_length) {
506 		err = gla2gpa(vm, rip, cr3, &gpa, &gpaend);
507 		if (err)
508 			break;
509 
510 		off = gpa & PAGE_MASK;
511 		n = min(inst_length - vie->num_valid, PAGE_SIZE - off);
512 
513 		hpa = vm_gpa2hpa(vm, gpa, n);
514 		if (hpa == -1)
515 			break;
516 
517 		bcopy((void *)PHYS_TO_DMAP(hpa), &vie->inst[vie->num_valid], n);
518 
519 		rip += n;
520 		vie->num_valid += n;
521 	}
522 
523 	if (vie->num_valid == inst_length)
524 		return (0);
525 	else
526 		return (-1);
527 }
528 
529 static int
530 vie_peek(struct vie *vie, uint8_t *x)
531 {
532 
533 	if (vie->num_processed < vie->num_valid) {
534 		*x = vie->inst[vie->num_processed];
535 		return (0);
536 	} else
537 		return (-1);
538 }
539 
540 static void
541 vie_advance(struct vie *vie)
542 {
543 
544 	vie->num_processed++;
545 }
546 
547 static int
548 decode_rex(struct vie *vie)
549 {
550 	uint8_t x;
551 
552 	if (vie_peek(vie, &x))
553 		return (-1);
554 
555 	if (x >= 0x40 && x <= 0x4F) {
556 		vie->rex_present = 1;
557 
558 		vie->rex_w = x & 0x8 ? 1 : 0;
559 		vie->rex_r = x & 0x4 ? 1 : 0;
560 		vie->rex_x = x & 0x2 ? 1 : 0;
561 		vie->rex_b = x & 0x1 ? 1 : 0;
562 
563 		vie_advance(vie);
564 	}
565 
566 	return (0);
567 }
568 
569 static int
570 decode_opcode(struct vie *vie)
571 {
572 	uint8_t x;
573 
574 	if (vie_peek(vie, &x))
575 		return (-1);
576 
577 	vie->op = one_byte_opcodes[x];
578 
579 	if (vie->op.op_type == VIE_OP_TYPE_NONE)
580 		return (-1);
581 
582 	vie_advance(vie);
583 	return (0);
584 }
585 
586 /*
587  * XXX assuming 32-bit or 64-bit guest
588  */
589 static int
590 decode_modrm(struct vie *vie)
591 {
592 	uint8_t x;
593 
594 	if (vie_peek(vie, &x))
595 		return (-1);
596 
597 	vie->mod = (x >> 6) & 0x3;
598 	vie->rm =  (x >> 0) & 0x7;
599 	vie->reg = (x >> 3) & 0x7;
600 
601 	/*
602 	 * A direct addressing mode makes no sense in the context of an EPT
603 	 * fault. There has to be a memory access involved to cause the
604 	 * EPT fault.
605 	 */
606 	if (vie->mod == VIE_MOD_DIRECT)
607 		return (-1);
608 
609 	if ((vie->mod == VIE_MOD_INDIRECT && vie->rm == VIE_RM_DISP32) ||
610 	    (vie->mod != VIE_MOD_DIRECT && vie->rm == VIE_RM_SIB)) {
611 		/*
612 		 * Table 2-5: Special Cases of REX Encodings
613 		 *
614 		 * mod=0, r/m=5 is used in the compatibility mode to
615 		 * indicate a disp32 without a base register.
616 		 *
617 		 * mod!=3, r/m=4 is used in the compatibility mode to
618 		 * indicate that the SIB byte is present.
619 		 *
620 		 * The 'b' bit in the REX prefix is don't care in
621 		 * this case.
622 		 */
623 	} else {
624 		vie->rm |= (vie->rex_b << 3);
625 	}
626 
627 	vie->reg |= (vie->rex_r << 3);
628 
629 	/* SIB */
630 	if (vie->mod != VIE_MOD_DIRECT && vie->rm == VIE_RM_SIB)
631 		goto done;
632 
633 	vie->base_register = gpr_map[vie->rm];
634 
635 	switch (vie->mod) {
636 	case VIE_MOD_INDIRECT_DISP8:
637 		vie->disp_bytes = 1;
638 		break;
639 	case VIE_MOD_INDIRECT_DISP32:
640 		vie->disp_bytes = 4;
641 		break;
642 	case VIE_MOD_INDIRECT:
643 		if (vie->rm == VIE_RM_DISP32) {
644 			vie->disp_bytes = 4;
645 			vie->base_register = VM_REG_LAST;	/* no base */
646 		}
647 		break;
648 	}
649 
650 	/* Figure out immediate operand size (if any) */
651 	if (vie->op.op_flags & VIE_OP_F_IMM)
652 		vie->imm_bytes = 4;
653 	else if (vie->op.op_flags & VIE_OP_F_IMM8)
654 		vie->imm_bytes = 1;
655 
656 done:
657 	vie_advance(vie);
658 
659 	return (0);
660 }
661 
662 static int
663 decode_sib(struct vie *vie)
664 {
665 	uint8_t x;
666 
667 	/* Proceed only if SIB byte is present */
668 	if (vie->mod == VIE_MOD_DIRECT || vie->rm != VIE_RM_SIB)
669 		return (0);
670 
671 	if (vie_peek(vie, &x))
672 		return (-1);
673 
674 	/* De-construct the SIB byte */
675 	vie->ss = (x >> 6) & 0x3;
676 	vie->index = (x >> 3) & 0x7;
677 	vie->base = (x >> 0) & 0x7;
678 
679 	/* Apply the REX prefix modifiers */
680 	vie->index |= vie->rex_x << 3;
681 	vie->base |= vie->rex_b << 3;
682 
683 	switch (vie->mod) {
684 	case VIE_MOD_INDIRECT_DISP8:
685 		vie->disp_bytes = 1;
686 		break;
687 	case VIE_MOD_INDIRECT_DISP32:
688 		vie->disp_bytes = 4;
689 		break;
690 	}
691 
692 	if (vie->mod == VIE_MOD_INDIRECT &&
693 	    (vie->base == 5 || vie->base == 13)) {
694 		/*
695 		 * Special case when base register is unused if mod = 0
696 		 * and base = %rbp or %r13.
697 		 *
698 		 * Documented in:
699 		 * Table 2-3: 32-bit Addressing Forms with the SIB Byte
700 		 * Table 2-5: Special Cases of REX Encodings
701 		 */
702 		vie->disp_bytes = 4;
703 	} else {
704 		vie->base_register = gpr_map[vie->base];
705 	}
706 
707 	/*
708 	 * All encodings of 'index' are valid except for %rsp (4).
709 	 *
710 	 * Documented in:
711 	 * Table 2-3: 32-bit Addressing Forms with the SIB Byte
712 	 * Table 2-5: Special Cases of REX Encodings
713 	 */
714 	if (vie->index != 4)
715 		vie->index_register = gpr_map[vie->index];
716 
717 	/* 'scale' makes sense only in the context of an index register */
718 	if (vie->index_register < VM_REG_LAST)
719 		vie->scale = 1 << vie->ss;
720 
721 	vie_advance(vie);
722 
723 	return (0);
724 }
725 
726 static int
727 decode_displacement(struct vie *vie)
728 {
729 	int n, i;
730 	uint8_t x;
731 
732 	union {
733 		char	buf[4];
734 		int8_t	signed8;
735 		int32_t	signed32;
736 	} u;
737 
738 	if ((n = vie->disp_bytes) == 0)
739 		return (0);
740 
741 	if (n != 1 && n != 4)
742 		panic("decode_displacement: invalid disp_bytes %d", n);
743 
744 	for (i = 0; i < n; i++) {
745 		if (vie_peek(vie, &x))
746 			return (-1);
747 
748 		u.buf[i] = x;
749 		vie_advance(vie);
750 	}
751 
752 	if (n == 1)
753 		vie->displacement = u.signed8;		/* sign-extended */
754 	else
755 		vie->displacement = u.signed32;		/* sign-extended */
756 
757 	return (0);
758 }
759 
760 static int
761 decode_immediate(struct vie *vie)
762 {
763 	int i, n;
764 	uint8_t x;
765 	union {
766 		char	buf[4];
767 		int8_t	signed8;
768 		int32_t	signed32;
769 	} u;
770 
771 	if ((n = vie->imm_bytes) == 0)
772 		return (0);
773 
774 	if (n != 1 && n != 4)
775 		panic("decode_immediate: invalid imm_bytes %d", n);
776 
777 	for (i = 0; i < n; i++) {
778 		if (vie_peek(vie, &x))
779 			return (-1);
780 
781 		u.buf[i] = x;
782 		vie_advance(vie);
783 	}
784 
785 	if (n == 1)
786 		vie->immediate = u.signed8;		/* sign-extended */
787 	else
788 		vie->immediate = u.signed32;		/* sign-extended */
789 
790 	return (0);
791 }
792 
793 #define	VERIFY_GLA
794 /*
795  * Verify that the 'guest linear address' provided as collateral of the nested
796  * page table fault matches with our instruction decoding.
797  */
798 #ifdef VERIFY_GLA
799 static int
800 verify_gla(struct vm *vm, int cpuid, uint64_t gla, struct vie *vie)
801 {
802 	int error;
803 	uint64_t base, idx;
804 
805 	base = 0;
806 	if (vie->base_register != VM_REG_LAST) {
807 		error = vm_get_register(vm, cpuid, vie->base_register, &base);
808 		if (error) {
809 			printf("verify_gla: error %d getting base reg %d\n",
810 				error, vie->base_register);
811 			return (-1);
812 		}
813 	}
814 
815 	idx = 0;
816 	if (vie->index_register != VM_REG_LAST) {
817 		error = vm_get_register(vm, cpuid, vie->index_register, &idx);
818 		if (error) {
819 			printf("verify_gla: error %d getting index reg %d\n",
820 				error, vie->index_register);
821 			return (-1);
822 		}
823 	}
824 
825 	if (base + vie->scale * idx + vie->displacement != gla) {
826 		printf("verify_gla mismatch: "
827 		       "base(0x%0lx), scale(%d), index(0x%0lx), "
828 		       "disp(0x%0lx), gla(0x%0lx)\n",
829 		       base, vie->scale, idx, vie->displacement, gla);
830 		return (-1);
831 	}
832 
833 	return (0);
834 }
835 #endif	/* VERIFY_GLA */
836 
837 int
838 vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla, struct vie *vie)
839 {
840 
841 	if (decode_rex(vie))
842 		return (-1);
843 
844 	if (decode_opcode(vie))
845 		return (-1);
846 
847 	if (decode_modrm(vie))
848 		return (-1);
849 
850 	if (decode_sib(vie))
851 		return (-1);
852 
853 	if (decode_displacement(vie))
854 		return (-1);
855 
856 	if (decode_immediate(vie))
857 		return (-1);
858 
859 #ifdef VERIFY_GLA
860 	if (verify_gla(vm, cpuid, gla, vie))
861 		return (-1);
862 #endif
863 
864 	vie->decoded = 1;	/* success */
865 
866 	return (0);
867 }
868 #endif	/* _KERNEL */
869