# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID eaee11008e685166e121adf7f75690988dca504a
# Parent 778394bb27f3c4d093631ff0357a0ca164aa0ca6
Add MOVSX instr support to VMX MMIO decoder.
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
diff -r 778394bb27f3 -r eaee11008e68 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Fri Nov 11 09:39:20 2005
+++ b/xen/arch/x86/vmx_io.c Fri Nov 11 09:41:25 2005
@@ -459,14 +459,56 @@
}
break;
- case INSTR_MOVZ:
+ case INSTR_MOVZX:
if (dst & REGISTER) {
+ switch (size) {
+ case BYTE:
+ p->u.data &= 0xFFULL;
+ break;
+
+ case WORD:
+ p->u.data &= 0xFFFFULL;
+ break;
+
+ case LONG:
+ p->u.data &= 0xFFFFFFFFULL;
+ break;
+
+ default:
+ printk("Impossible source operand size of movzx instr: %d\n",
size);
+ domain_crash_synchronous();
+ }
index = operand_index(dst);
+ set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
+ }
+ break;
+
+ case INSTR_MOVSX:
+ if (dst & REGISTER) {
switch (size) {
- case BYTE: p->u.data = p->u.data & 0xFFULL; break;
- case WORD: p->u.data = p->u.data & 0xFFFFULL; break;
- case LONG: p->u.data = p->u.data & 0xFFFFFFFFULL; break;
+ case BYTE:
+ p->u.data &= 0xFFULL;
+ if ( p->u.data & 0x80ULL )
+ p->u.data |= 0xFFFFFFFFFFFFFF00ULL;
+ break;
+
+ case WORD:
+ p->u.data &= 0xFFFFULL;
+ if ( p->u.data & 0x8000ULL )
+ p->u.data |= 0xFFFFFFFFFFFF0000ULL;
+ break;
+
+ case LONG:
+ p->u.data &= 0xFFFFFFFFULL;
+ if ( p->u.data & 0x80000000ULL )
+ p->u.data |= 0xFFFFFFFF00000000ULL;
+ break;
+
+ default:
+ printk("Impossible source operand size of movsx instr: %d\n",
size);
+ domain_crash_synchronous();
}
+ index = operand_index(dst);
set_reg_value(operand_size(dst), index, 0, regs, p->u.data);
}
break;
diff -r 778394bb27f3 -r eaee11008e68 xen/arch/x86/vmx_platform.c
--- a/xen/arch/x86/vmx_platform.c Fri Nov 11 09:39:20 2005
+++ b/xen/arch/x86/vmx_platform.c Fri Nov 11 09:41:25 2005
@@ -581,25 +581,39 @@
}
switch (*++opcode) {
- case 0xB6: /* movz m8, r16/r32 */
- instr->instr = INSTR_MOVZ;
+ case 0xB6: /* movzx m8, r16/r32/r64 */
+ instr->instr = INSTR_MOVZX;
GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
index = get_index(opcode + 1, rex);
instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
return DECODE_success;
- case 0xB7: /* movz m16/m32, r32/r64 */
- instr->instr = INSTR_MOVZ;
+ case 0xB7: /* movzx m16/m32, r32/r64 */
+ instr->instr = INSTR_MOVZX;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
index = get_index(opcode + 1, rex);
- if (rex & 0x8) {
- instr->op_size = LONG;
- instr->operand[1] = mk_operand(QUAD, index, 0, REGISTER);
- } else {
- instr->op_size = WORD;
- instr->operand[1] = mk_operand(LONG, index, 0, REGISTER);
- }
- instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY);
+ if (rex & 0x8)
+ instr->operand[0] = mk_operand(LONG, 0, 0, MEMORY);
+ else
+ instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
+ instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
+ return DECODE_success;
+
+ case 0xBE: /* movsx m8, r16/r32/r64 */
+ instr->instr = INSTR_MOVSX;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ index = get_index(opcode + 1, rex);
+ instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
+ instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
+ return DECODE_success;
+
+ case 0xBF: /* movsx m16, r32/r64 */
+ instr->instr = INSTR_MOVSX;
+ GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
+ index = get_index(opcode + 1, rex);
+ instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
+ instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
return DECODE_success;
case 0xA3: /* bt r32, m32 */
@@ -702,7 +716,7 @@
send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0);
} else if (inst->operand[0] & MEMORY) { /* dest is register */
/* send the request and wait for the value */
- if (inst->instr == INSTR_MOVZ)
+ if ( (inst->instr == INSTR_MOVZX) || (inst->instr == INSTR_MOVSX) )
send_mmio_req(type, gpa, 1, size_reg, 0, IOREQ_READ, 0);
else
send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0);
@@ -827,7 +841,8 @@
break;
}
- case INSTR_MOVZ:
+ case INSTR_MOVZX:
+ case INSTR_MOVSX:
mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
break;
diff -r 778394bb27f3 -r eaee11008e68 xen/arch/x86/vmx_vlapic.c
--- a/xen/arch/x86/vmx_vlapic.c Fri Nov 11 09:39:20 2005
+++ b/xen/arch/x86/vmx_vlapic.c Fri Nov 11 09:41:25 2005
@@ -567,7 +567,9 @@
if ( len != 4) {
/* some bugs on kernel cause read this with byte*/
- printk("Local APIC read with len = %lx, should be 4 instead\n", len);
+ VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
+ "Local APIC read with len = %lx, should be 4 instead\n",
+ len);
}
alignment = offset & 0x3;
diff -r 778394bb27f3 -r eaee11008e68 xen/include/asm-x86/vmx_platform.h
--- a/xen/include/asm-x86/vmx_platform.h Fri Nov 11 09:39:20 2005
+++ b/xen/include/asm-x86/vmx_platform.h Fri Nov 11 09:41:25 2005
@@ -55,17 +55,18 @@
#define REPNZ 0x2
#define OVERLAP 0x4
-#define INSTR_PIO 1
-#define INSTR_OR 2
-#define INSTR_AND 3
-#define INSTR_XOR 4
-#define INSTR_CMP 5
-#define INSTR_MOV 6
-#define INSTR_MOVS 7
-#define INSTR_MOVZ 8
-#define INSTR_STOS 9
-#define INSTR_TEST 10
-#define INSTR_BT 11
+#define INSTR_PIO 1
+#define INSTR_OR 2
+#define INSTR_AND 3
+#define INSTR_XOR 4
+#define INSTR_CMP 5
+#define INSTR_MOV 6
+#define INSTR_MOVS 7
+#define INSTR_MOVZX 8
+#define INSTR_MOVSX 9
+#define INSTR_STOS 10
+#define INSTR_TEST 11
+#define INSTR_BT 12
struct instruction {
__s8 instr; /* instruction type */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|