summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/vmm_instruction_emul.c
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2012-11-29 06:26:42 +0000
committergrehan <grehan@FreeBSD.org>2012-11-29 06:26:42 +0000
commitffd1f089c33d0e59c0cb85b52bc683272f7880dd (patch)
treeae1cace65dd274cdb8c7e60c5747c289e4959216 /sys/amd64/vmm/vmm_instruction_emul.c
parentda4e87dfd614fffb88e5a93c988e1caec9c9efe7 (diff)
downloadFreeBSD-src-ffd1f089c33d0e59c0cb85b52bc683272f7880dd.zip
FreeBSD-src-ffd1f089c33d0e59c0cb85b52bc683272f7880dd.tar.gz
Add support for the 0x81 AND instruction, now generated
by clang in the local APIC code. 0x81 is a read-modify-write instruction - the EPT check that only allowed read or write and not both has been relaxed to allow read and write. Reviewed by: neel Obtained from: NetApp
Diffstat (limited to 'sys/amd64/vmm/vmm_instruction_emul.c')
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index 5e5399b..0a7286b 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -81,6 +81,11 @@ static const struct vie_op one_byte_opcodes[256] = {
[0x23] = {
.op_byte = 0x23,
.op_type = VIE_OP_TYPE_AND,
+ },
+ [0x81] = {
+ .op_byte = 0x81,
+ .op_type = VIE_OP_TYPE_AND,
+ .op_flags = VIE_OP_F_IMM,
}
};
@@ -299,6 +304,30 @@ emulate_and(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
val1 &= val2;
error = vie_update_register(vm, vcpuid, reg, val1, size);
break;
+ case 0x81:
+ printf("0x81 AND\n");
+ /*
+ * AND reg (ModRM:reg) with immediate and store the
+ * result in reg
+ *
+ * 81/ and r/m32, imm32
+ * REX.W + 81/ and r/m64, imm32 sign-extended to 64
+ */
+ if (vie->rex_w)
+ size = 8;
+
+ /* get the first operand */
+ error = memread(vm, vcpuid, gpa, &val1, size, arg);
+ if (error)
+ break;
+
+ /*
+ * perform the operation with the pre-fetched immediate
+ * operand and write the result
+ */
+ val1 &= vie->immediate;
+ error = memwrite(vm, vcpuid, gpa, val1, size, arg);
+ break;
default:
break;
}
OpenPOWER on IntegriCloud