2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2012, Alexander Kudryavtsev <alexk@ispras.ru>
11 * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Alexander Kudryavtsev <alexk@ispras.ru>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vm_guest.h>
22 #include <palacios/vmm_mem_hook.h>
23 #include <palacios/vmm_emulator.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_hashtable.h>
26 #include <palacios/vmm_decoder.h>
28 #include <quix86/quix86.h>
30 #ifdef V3_CONFIG_TM_FUNC
31 #include <extensions/trans_mem.h>
34 #ifndef V3_CONFIG_DEBUG_DECODER
36 #define PrintDebug(fmt, args...)
39 #define GPR_REGISTER 0
40 #define SEGMENT_REGISTER 1
41 #define CTRL_REGISTER 2
42 #define DEBUG_REGISTER 3
44 // QUIX86 does not have to be initialised or deinitialised.
45 int v3_init_decoder(struct guest_info * core) {
48 int v3_deinit_decoder(struct guest_info * core) {
52 static int get_opcode(qx86_insn *inst, struct guest_info *core);
53 static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
54 addr_t * v3_reg, uint_t * reg_len);
56 static int callback(void *data, int rindex, int subreg, unsigned char *value) {
60 struct guest_info *info = (struct guest_info*)data;
61 int v3_reg_type = qx86_register_to_v3_reg(info,
63 (addr_t*)®_addr, ®_size);
65 if(v3_reg_type == -1) {
66 PrintError(info->vm_info, info, "Callback failed to get register index %d\n", rindex);
70 *(uint64_t*)value = 0;
72 case QX86_SUBREG_BASE:
73 *(uint64_t*)value = ((struct v3_segment*)reg_addr)->base;
75 case QX86_SUBREG_LIMIT:
76 *(uint32_t*)value = ((struct v3_segment*)reg_addr)->limit;
78 case QX86_SUBREG_FLAGS:
79 PrintError(info->vm_info, info, "Callback doesn't know how to give flags.\n");
81 case QX86_SUBREG_NONE: {
82 switch(qx86_rinfo(rindex)->size) {
83 case 1: *(uint8_t* )value = *(uint8_t* )reg_addr; break;
84 case 2: *(uint16_t*)value = *(uint16_t*)reg_addr; break;
85 case 4: *(uint32_t*)value = *(uint32_t*)reg_addr; break;
86 case 8: *(uint64_t*)value = *(uint64_t*)reg_addr; break;
95 static inline int qx86_op_to_v3_op(struct guest_info *info, qx86_insn *qx86_insn,
96 int op_num, struct x86_operand * v3_op) {
98 qx86_operand *qx86_op = &qx86_insn->operands[op_num];
99 if (qx86_op->ot == QX86_OPERAND_TYPE_REGISTER) {
100 int v3_reg_type = qx86_register_to_v3_reg(info,
102 &(v3_op->operand), &(v3_op->size));
104 if (v3_reg_type == -1) {
105 PrintError(info->vm_info, info, "Operand %d is an Unhandled Operand: %s\n", op_num,
106 qx86_rinfo(qx86_op->u.r.rindex)->name);
107 v3_op->type = INVALID_OPERAND;
109 } else if (v3_reg_type == SEGMENT_REGISTER) {
110 struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
111 v3_op->operand = (addr_t)&(seg_reg->selector);
113 v3_op->type = REG_OPERAND;
115 } else if(qx86_op->ot == QX86_OPERAND_TYPE_MEMORY) {
116 PrintDebug(info->vm_info, info, "Memory operand (%d)\n", op_num);
117 if((status = qx86_calculate_linear_address(qx86_insn, op_num,
118 (qx86_uint64*)&v3_op->operand)) != QX86_SUCCESS) {
119 PrintError(info->vm_info, info, "Could not get memory operand %d: "
120 "qx86_calculate_linear_address() returns %d\n", op_num, status);
123 v3_op->type = MEM_OPERAND;
124 v3_op->size = qx86_op->size;
126 } else if(qx86_op->ot == QX86_OPERAND_TYPE_IMMEDIATE) {
127 v3_op->size = qx86_op->u.i.valueSize;
129 if (v3_op->size > 4) {
130 PrintError(info->vm_info, info, "Unhandled 64 bit immediates\n");
133 v3_op->operand = (addr_t)*(uint64_t*)qx86_op->u.i.value;
134 v3_op->type = IMM_OPERAND;
137 PrintError(info->vm_info, info, "Unhandled Operand %d Type %d\n", op_num, qx86_op->ot);
141 if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_READ) {
144 if (qx86_op->attributes & QX86_OPERAND_ATTRIBUTE_WRITTEN) {
150 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
153 uint8_t inst_buf[QX86_INSN_SIZE_MAX];
155 /* 441-tm: add 'escape' trap for Haswell instructions, dont want to stumble
158 #ifdef V3_CONFIG_TM_FUNC
160 struct v3_trans_mem * tm = (struct v3_trans_mem *)v3_get_ext_core_state(info, "trans_mem");
161 if (tm->TM_MODE == TM_ON) {
162 int byte1 = *(uint8_t *)(instr_ptr);
163 int byte2 = *(uint8_t *)(instr_ptr + 1);
164 int byte3 = *(uint8_t *)(instr_ptr + 2);
165 if (byte1 == 0xc7 && byte2 == 0xf8) { /* third byte is an immediate */
166 //V3_Print("Decoding %x %x %d\n", byte1, byte2, byte3);
167 instr->instr_length = 6;
169 } else if (byte1 == 0xc6 && byte2 == 0xf8) { /* third byte is an immediate */
170 //V3_Print("Decoding XABORT %x %x %d\n", byte1, byte2, byte3);
171 instr->instr_length = 3;
173 } else if (byte1 == 0x0f && byte2 == 0x01 && byte3 == 0xd5) {
174 //V3_Print("Decoding XEND %x %x %x\n", byte1, byte2, byte3);
175 instr->instr_length = 3;
182 memset(instr, 0, sizeof(struct x86_instr));
183 memset(&qx86_inst, 0, sizeof(qx86_inst));
185 v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
187 switch(v3_get_vm_cpu_mode(info)) {
188 case REAL: case LONG_16_COMPAT:
189 proc_mode = QX86_SIZE_16; break;
190 case PROTECTED: case PROTECTED_PAE: case LONG_32_COMPAT:
191 proc_mode = QX86_SIZE_32; break;
193 proc_mode = QX86_SIZE_64; break;
195 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
199 int left_in_page = 0x1000 - (instr_ptr & 0xfff);
200 if(left_in_page < QX86_INSN_SIZE_MAX) {
204 if (info->mem_mode == PHYSICAL_MEM) {
205 status = v3_gpa_to_hva(info, get_addr_linear(info,
206 (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
208 status = v3_gva_to_hva(info, get_addr_linear(info,
209 (info->rip & ~0xfffULL) + 0x1000, &(info->segments.cs)), &instr_ptr2);
212 PrintError(info->vm_info, info, "Could not translate Instruction Address at second stage "
213 "translation (%p)\n", (void *)(addr_t)info->rip);
217 if(((instr_ptr & ~0xfffUL) + 0x1000) != instr_ptr2) {
218 PrintError(info->vm_info, info, "Note: physical page non-contiguous\n");
219 memcpy(inst_buf, (const void*)instr_ptr, left_in_page);
220 memcpy(inst_buf + left_in_page, (const void*)instr_ptr2,
221 QX86_INSN_SIZE_MAX - left_in_page);
222 instr_ptr = (addr_t)inst_buf;
223 } // in other case, address space is contiguous and everything is OK
226 qx86_inst.callback = callback;
227 qx86_inst.data = info;
229 int status = qx86_decode(&qx86_inst, proc_mode,
230 (const void*)instr_ptr, QX86_INSN_SIZE_MAX);
231 if(status != QX86_SUCCESS) {
232 PrintError(info->vm_info, info, "qx86_decode() returned %d\n", status);
236 instr->instr_length = qx86_inst.rawSize;
238 // 441 - dump memory for quix86 debugging
239 if ((instr->op_type = get_opcode(&qx86_inst,info)) == V3_INVALID_OP) {
240 PrintError(info->vm_info, info, "++==++ QX86 DECODE ++==++\n");
241 v3_dump_mem((void *)instr_ptr, 15);
242 PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
243 qx86_minfo(qx86_inst.mnemonic)->name);
246 if ((instr->op_type = get_opcode(&qx86_inst, info)) == V3_INVALID_OP) {
247 PrintError(info->vm_info, info, "Could not get opcode. (mnemonic=%s)\n",
248 qx86_minfo(qx86_inst.mnemonic)->name);
252 if(instr->op_type == V3_OP_MOVS || instr->op_type == V3_OP_STOS) {
253 instr->is_str_op = 1;
254 if (instr->prefixes.rep == 1) {
255 uint64_t a_mask = (~0ULL >>
256 (64 - QX86_SIZE_OCTETS(qx86_inst.attributes.addressSize) * 8));
258 instr->str_op_length = info->vm_regs.rcx & a_mask;
260 instr->str_op_length = 1;
263 instr->is_str_op = 0;
264 instr->str_op_length = 0;
267 instr->num_operands = qx86_inst.operandCount;
270 if (instr->num_operands >= 1) {
271 if (qx86_op_to_v3_op(info, &qx86_inst, 0, &instr->dst_operand) != 0)
275 // set second operand
276 if (instr->num_operands >= 2) {
277 if (qx86_op_to_v3_op(info, &qx86_inst, 1, &instr->src_operand) != 0)
282 if (instr->num_operands >= 3) {
283 if (qx86_op_to_v3_op(info, &qx86_inst, 2, &instr->third_operand) != 0)
287 #ifdef V3_CONFIG_DEBUG_DECODER
288 qx86_print_options_intel opt;
291 if(qx86_print_intel(&qx86_inst, &opt, buf, &buf_sz) != QX86_SUCCESS) {
292 PrintDebug(info->vm_info, info, "Print failed!\n");
294 PrintDebug(info->vm_info, info, "Instruction (%p): %s\n", (void*)info->rip, buf);
296 PrintDebug(info->vm_info, info, "Operands: dst %p src %p 3rd %p\n", (void*)instr->dst_operand.operand,
297 (void*)instr->src_operand.operand, (void*)instr->third_operand.operand);
302 static int get_opcode(qx86_insn *inst, struct guest_info *core) {
303 switch (inst->mnemonic) {
304 #define IS_CR(op) inst->operands[op].ot == QX86_OPERAND_TYPE_REGISTER && \
305 qx86_rinfo(inst->operands[op].u.r.rindex)->rclass == QX86_RCLASS_CREG
308 case QX86_MNEMONIC_MOV: {
309 if(inst->operands[0].ot == QX86_OPERAND_TYPE_MEMORY
310 || inst->operands[1].ot == QX86_OPERAND_TYPE_MEMORY)
316 // 441 - mov reg reg is also ok
317 if(inst->operands[0].ot == QX86_OPERAND_TYPE_REGISTER
318 || inst->operands[1].ot == QX86_OPERAND_TYPE_REGISTER)
321 PrintError(core->vm_info, core, "Bad operand types for MOV: %d %d\n", inst->operands[0].ot,
322 inst->operands[1].ot);
323 return V3_INVALID_OP;
326 /* Control Instructions */
327 case QX86_MNEMONIC_SMSW:
330 case QX86_MNEMONIC_LMSW:
333 case QX86_MNEMONIC_CLTS:
336 case QX86_MNEMONIC_INVLPG:
339 /* Data Instructions */
340 case QX86_MNEMONIC_ADC:
343 case QX86_MNEMONIC_ADD:
346 case QX86_MNEMONIC_AND:
349 case QX86_MNEMONIC_SUB:
353 case QX86_MNEMONIC_MOVZX:
356 case QX86_MNEMONIC_MOVSX:
360 case QX86_MNEMONIC_DEC:
363 case QX86_MNEMONIC_INC:
366 case QX86_MNEMONIC_OR:
369 case QX86_MNEMONIC_XOR:
372 case QX86_MNEMONIC_NEG:
375 case QX86_MNEMONIC_NOT:
378 case QX86_MNEMONIC_XCHG:
381 case QX86_MNEMONIC_SETB:
384 case QX86_MNEMONIC_SETBE:
387 case QX86_MNEMONIC_SETL:
390 case QX86_MNEMONIC_SETLE:
393 case QX86_MNEMONIC_SETAE:
396 case QX86_MNEMONIC_SETA:
399 case QX86_MNEMONIC_SETGE:
402 case QX86_MNEMONIC_SETG:
405 case QX86_MNEMONIC_SETNO:
408 case QX86_MNEMONIC_SETNP:
411 case QX86_MNEMONIC_SETNS:
414 case QX86_MNEMONIC_SETNZ:
417 case QX86_MNEMONIC_SETO:
420 case QX86_MNEMONIC_SETP:
423 case QX86_MNEMONIC_SETS:
426 case QX86_MNEMONIC_SETZ:
429 case QX86_MNEMONIC_MOVSB:
430 case QX86_MNEMONIC_MOVSW:
431 case QX86_MNEMONIC_MOVSD:
432 case QX86_MNEMONIC_MOVSQ:
435 case QX86_MNEMONIC_STOSB:
436 case QX86_MNEMONIC_STOSW:
437 case QX86_MNEMONIC_STOSD:
438 case QX86_MNEMONIC_STOSQ:
441 /* 441-tm: add in CMP, POP, JLE, CALL cases */
442 case QX86_MNEMONIC_CMP:
445 case QX86_MNEMONIC_POP:
448 case QX86_MNEMONIC_JLE:
451 case QX86_MNEMONIC_CALL:
454 case QX86_MNEMONIC_TEST:
457 case QX86_MNEMONIC_PUSH:
460 case QX86_MNEMONIC_JAE:
463 case QX86_MNEMONIC_JMP:
466 case QX86_MNEMONIC_JNZ:
469 case QX86_MNEMONIC_JZ:
472 case QX86_MNEMONIC_RET:
475 case QX86_MNEMONIC_IMUL:
478 case QX86_MNEMONIC_LEA:
481 case QX86_MNEMONIC_JL:
484 case QX86_MNEMONIC_CMOVZ:
487 case QX86_MNEMONIC_MOVSXD:
490 case QX86_MNEMONIC_JNS:
493 case QX86_MNEMONIC_CMOVS:
496 case QX86_MNEMONIC_SHL:
499 case QX86_MNEMONIC_INT:
503 return V3_INVALID_OP;
507 static int qx86_register_to_v3_reg(struct guest_info * info, int qx86_reg,
508 addr_t * v3_reg, uint_t * reg_len) {
509 PrintDebug(info->vm_info, info, "qx86 Register: %s\n", qx86_rinfo(qx86_reg)->name);
512 case QX86_REGISTER_INVALID:
517 case QX86_REGISTER_RAX:
518 *v3_reg = (addr_t)&(info->vm_regs.rax);
521 case QX86_REGISTER_EAX:
522 *v3_reg = (addr_t)&(info->vm_regs.rax);
525 case QX86_REGISTER_AX:
526 *v3_reg = (addr_t)&(info->vm_regs.rax);
529 case QX86_REGISTER_AH:
530 *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
533 case QX86_REGISTER_AL:
534 *v3_reg = (addr_t)&(info->vm_regs.rax);
538 case QX86_REGISTER_RCX:
539 *v3_reg = (addr_t)&(info->vm_regs.rcx);
542 case QX86_REGISTER_ECX:
543 *v3_reg = (addr_t)&(info->vm_regs.rcx);
546 case QX86_REGISTER_CX:
547 *v3_reg = (addr_t)&(info->vm_regs.rcx);
550 case QX86_REGISTER_CH:
551 *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
554 case QX86_REGISTER_CL:
555 *v3_reg = (addr_t)&(info->vm_regs.rcx);
559 case QX86_REGISTER_RDX:
560 *v3_reg = (addr_t)&(info->vm_regs.rdx);
563 case QX86_REGISTER_EDX:
564 *v3_reg = (addr_t)&(info->vm_regs.rdx);
567 case QX86_REGISTER_DX:
568 *v3_reg = (addr_t)&(info->vm_regs.rdx);
571 case QX86_REGISTER_DH:
572 *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
575 case QX86_REGISTER_DL:
576 *v3_reg = (addr_t)&(info->vm_regs.rdx);
580 case QX86_REGISTER_RBX:
581 *v3_reg = (addr_t)&(info->vm_regs.rbx);
584 case QX86_REGISTER_EBX:
585 *v3_reg = (addr_t)&(info->vm_regs.rbx);
588 case QX86_REGISTER_BX:
589 *v3_reg = (addr_t)&(info->vm_regs.rbx);
592 case QX86_REGISTER_BH:
593 *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
596 case QX86_REGISTER_BL:
597 *v3_reg = (addr_t)&(info->vm_regs.rbx);
602 case QX86_REGISTER_RSP:
603 *v3_reg = (addr_t)&(info->vm_regs.rsp);
606 case QX86_REGISTER_ESP:
607 *v3_reg = (addr_t)&(info->vm_regs.rsp);
610 case QX86_REGISTER_SP:
611 *v3_reg = (addr_t)&(info->vm_regs.rsp);
614 case QX86_REGISTER_SPL:
615 *v3_reg = (addr_t)&(info->vm_regs.rsp);
619 case QX86_REGISTER_RBP:
620 *v3_reg = (addr_t)&(info->vm_regs.rbp);
623 case QX86_REGISTER_EBP:
624 *v3_reg = (addr_t)&(info->vm_regs.rbp);
627 case QX86_REGISTER_BP:
628 *v3_reg = (addr_t)&(info->vm_regs.rbp);
631 case QX86_REGISTER_BPL:
632 *v3_reg = (addr_t)&(info->vm_regs.rbp);
638 case QX86_REGISTER_RSI:
639 *v3_reg = (addr_t)&(info->vm_regs.rsi);
642 case QX86_REGISTER_ESI:
643 *v3_reg = (addr_t)&(info->vm_regs.rsi);
646 case QX86_REGISTER_SI:
647 *v3_reg = (addr_t)&(info->vm_regs.rsi);
650 case QX86_REGISTER_SIL:
651 *v3_reg = (addr_t)&(info->vm_regs.rsi);
656 case QX86_REGISTER_RDI:
657 *v3_reg = (addr_t)&(info->vm_regs.rdi);
660 case QX86_REGISTER_EDI:
661 *v3_reg = (addr_t)&(info->vm_regs.rdi);
664 case QX86_REGISTER_DI:
665 *v3_reg = (addr_t)&(info->vm_regs.rdi);
668 case QX86_REGISTER_DIL:
669 *v3_reg = (addr_t)&(info->vm_regs.rdi);
677 case QX86_REGISTER_R8:
678 *v3_reg = (addr_t)&(info->vm_regs.r8);
681 case QX86_REGISTER_R8D:
682 *v3_reg = (addr_t)&(info->vm_regs.r8);
685 case QX86_REGISTER_R8W:
686 *v3_reg = (addr_t)&(info->vm_regs.r8);
689 case QX86_REGISTER_R8B:
690 *v3_reg = (addr_t)&(info->vm_regs.r8);
694 case QX86_REGISTER_R9:
695 *v3_reg = (addr_t)&(info->vm_regs.r9);
698 case QX86_REGISTER_R9D:
699 *v3_reg = (addr_t)&(info->vm_regs.r9);
702 case QX86_REGISTER_R9W:
703 *v3_reg = (addr_t)&(info->vm_regs.r9);
706 case QX86_REGISTER_R9B:
707 *v3_reg = (addr_t)&(info->vm_regs.r9);
711 case QX86_REGISTER_R10:
712 *v3_reg = (addr_t)&(info->vm_regs.r10);
715 case QX86_REGISTER_R10D:
716 *v3_reg = (addr_t)&(info->vm_regs.r10);
719 case QX86_REGISTER_R10W:
720 *v3_reg = (addr_t)&(info->vm_regs.r10);
723 case QX86_REGISTER_R10B:
724 *v3_reg = (addr_t)&(info->vm_regs.r10);
728 case QX86_REGISTER_R11:
729 *v3_reg = (addr_t)&(info->vm_regs.r11);
732 case QX86_REGISTER_R11D:
733 *v3_reg = (addr_t)&(info->vm_regs.r11);
736 case QX86_REGISTER_R11W:
737 *v3_reg = (addr_t)&(info->vm_regs.r11);
740 case QX86_REGISTER_R11B:
741 *v3_reg = (addr_t)&(info->vm_regs.r11);
745 case QX86_REGISTER_R12:
746 *v3_reg = (addr_t)&(info->vm_regs.r12);
749 case QX86_REGISTER_R12D:
750 *v3_reg = (addr_t)&(info->vm_regs.r12);
753 case QX86_REGISTER_R12W:
754 *v3_reg = (addr_t)&(info->vm_regs.r12);
757 case QX86_REGISTER_R12B:
758 *v3_reg = (addr_t)&(info->vm_regs.r12);
762 case QX86_REGISTER_R13:
763 *v3_reg = (addr_t)&(info->vm_regs.r13);
766 case QX86_REGISTER_R13D:
767 *v3_reg = (addr_t)&(info->vm_regs.r13);
770 case QX86_REGISTER_R13W:
771 *v3_reg = (addr_t)&(info->vm_regs.r13);
774 case QX86_REGISTER_R13B:
775 *v3_reg = (addr_t)&(info->vm_regs.r13);
779 case QX86_REGISTER_R14:
780 *v3_reg = (addr_t)&(info->vm_regs.r14);
783 case QX86_REGISTER_R14D:
784 *v3_reg = (addr_t)&(info->vm_regs.r14);
787 case QX86_REGISTER_R14W:
788 *v3_reg = (addr_t)&(info->vm_regs.r14);
791 case QX86_REGISTER_R14B:
792 *v3_reg = (addr_t)&(info->vm_regs.r14);
796 case QX86_REGISTER_R15:
797 *v3_reg = (addr_t)&(info->vm_regs.r15);
800 case QX86_REGISTER_R15D:
801 *v3_reg = (addr_t)&(info->vm_regs.r15);
804 case QX86_REGISTER_R15W:
805 *v3_reg = (addr_t)&(info->vm_regs.r15);
808 case QX86_REGISTER_R15B:
809 *v3_reg = (addr_t)&(info->vm_regs.r15);
814 case QX86_REGISTER_RIP:
815 *v3_reg = (addr_t)&(info->rip);
817 return CTRL_REGISTER;
818 case QX86_REGISTER_EIP:
819 *v3_reg = (addr_t)&(info->rip);
821 return CTRL_REGISTER;
822 case QX86_REGISTER_IP:
823 *v3_reg = (addr_t)&(info->rip);
825 return CTRL_REGISTER;
827 case QX86_REGISTER_FLAGS:
828 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
830 return CTRL_REGISTER;
831 case QX86_REGISTER_EFLAGS:
832 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
834 return CTRL_REGISTER;
835 case QX86_REGISTER_RFLAGS:
836 *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
838 return CTRL_REGISTER;
840 case QX86_REGISTER_CR0:
841 *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
843 return CTRL_REGISTER;
844 case QX86_REGISTER_CR2:
845 *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
847 return CTRL_REGISTER;
848 case QX86_REGISTER_CR3:
849 *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
851 return CTRL_REGISTER;
852 case QX86_REGISTER_CR4:
853 *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
855 return CTRL_REGISTER;
856 case QX86_REGISTER_CR8:
857 *v3_reg = (addr_t)&(info->ctrl_regs.apic_tpr);
859 return CTRL_REGISTER;
861 case QX86_REGISTER_CR1:
862 case QX86_REGISTER_CR5:
863 case QX86_REGISTER_CR6:
864 case QX86_REGISTER_CR7:
865 case QX86_REGISTER_CR9:
866 case QX86_REGISTER_CR10:
867 case QX86_REGISTER_CR11:
868 case QX86_REGISTER_CR12:
869 case QX86_REGISTER_CR13:
870 case QX86_REGISTER_CR14:
871 case QX86_REGISTER_CR15:
875 case QX86_REGISTER_CS:
876 *v3_reg = (addr_t)&(info->segments.cs);
878 return SEGMENT_REGISTER;
879 case QX86_REGISTER_DS:
880 *v3_reg = (addr_t)&(info->segments.ds);
882 return SEGMENT_REGISTER;
883 case QX86_REGISTER_ES:
884 *v3_reg = (addr_t)&(info->segments.es);
886 return SEGMENT_REGISTER;
887 case QX86_REGISTER_SS:
888 *v3_reg = (addr_t)&(info->segments.ss);
890 return SEGMENT_REGISTER;
891 case QX86_REGISTER_FS:
892 *v3_reg = (addr_t)&(info->segments.fs);
894 return SEGMENT_REGISTER;
895 case QX86_REGISTER_GS:
896 *v3_reg = (addr_t)&(info->segments.gs);
898 return SEGMENT_REGISTER;
901 case QX86_REGISTER_DR0:
902 case QX86_REGISTER_DR1:
903 case QX86_REGISTER_DR2:
904 case QX86_REGISTER_DR3:
905 case QX86_REGISTER_DR4:
906 case QX86_REGISTER_DR5:
907 case QX86_REGISTER_DR6:
908 case QX86_REGISTER_DR7:
909 case QX86_REGISTER_DR8:
910 case QX86_REGISTER_DR9:
911 case QX86_REGISTER_DR10:
912 case QX86_REGISTER_DR11:
913 case QX86_REGISTER_DR12:
914 case QX86_REGISTER_DR13:
915 case QX86_REGISTER_DR14:
916 case QX86_REGISTER_DR15:
920 case QX86_REGISTER_XMM0:
921 case QX86_REGISTER_XMM1:
922 case QX86_REGISTER_XMM2:
923 case QX86_REGISTER_XMM3:
924 case QX86_REGISTER_XMM4:
925 case QX86_REGISTER_XMM5:
926 case QX86_REGISTER_XMM6:
927 case QX86_REGISTER_XMM7:
928 case QX86_REGISTER_XMM8:
929 case QX86_REGISTER_XMM9:
930 case QX86_REGISTER_XMM10:
931 case QX86_REGISTER_XMM11:
932 case QX86_REGISTER_XMM12:
933 case QX86_REGISTER_XMM13:
934 case QX86_REGISTER_XMM14:
935 case QX86_REGISTER_XMM15:
937 case QX86_REGISTER_YMM0:
938 case QX86_REGISTER_YMM1:
939 case QX86_REGISTER_YMM2:
940 case QX86_REGISTER_YMM3:
941 case QX86_REGISTER_YMM4:
942 case QX86_REGISTER_YMM5:
943 case QX86_REGISTER_YMM6:
944 case QX86_REGISTER_YMM7:
945 case QX86_REGISTER_YMM8:
946 case QX86_REGISTER_YMM9:
947 case QX86_REGISTER_YMM10:
948 case QX86_REGISTER_YMM11:
949 case QX86_REGISTER_YMM12:
950 case QX86_REGISTER_YMM13:
951 case QX86_REGISTER_YMM14:
952 case QX86_REGISTER_YMM15:
954 case QX86_REGISTER_MMX0:
955 case QX86_REGISTER_MMX1:
956 case QX86_REGISTER_MMX2:
957 case QX86_REGISTER_MMX3:
958 case QX86_REGISTER_MMX4:
959 case QX86_REGISTER_MMX5:
960 case QX86_REGISTER_MMX6:
961 case QX86_REGISTER_MMX7:
963 case QX86_REGISTER_ST0:
964 case QX86_REGISTER_ST1:
965 case QX86_REGISTER_ST2:
966 case QX86_REGISTER_ST3:
967 case QX86_REGISTER_ST4:
968 case QX86_REGISTER_ST5:
969 case QX86_REGISTER_ST6:
970 case QX86_REGISTER_ST7: