aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2026-05-19 05:36:55 +0000
committeriximeow <me@iximeow.net>2026-05-25 01:37:15 +0000
commite9b3973cbf689eac2ea11c2dacf6f2d8c2ce01c5 (patch)
tree1148265454a1d3a2fedf65a94e23137a1b64b0b4
parent485851c914695e0884609c68e318d22fee1db9b8 (diff)
invept precision
-rw-r--r--CHANGELOG2
-rw-r--r--src/isa_settings.rs7
-rw-r--r--test/long_mode/mod.rs10
-rw-r--r--test/protected_mode/mod.rs10
-rw-r--r--test/real_mode/mod.rs2
5 files changed, 31 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 5072dde..8e5ad86 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -29,6 +29,8 @@
always decoded as ymm.
* vmaskmovqdu now reports a memory access size for the implied write to ds:[rdi/edi/di].
* correct swapped operand order of 0xD6-opcode movq. in 32/16-bit, fix this opcode being decoded as vmovd.
+* some instructions (such as invept, invvpid) were accepted by uarch-specific
+ deocders when they should not have been.
## 2.0.0
diff --git a/src/isa_settings.rs b/src/isa_settings.rs
index 76fab5a..c996bd2 100644
--- a/src/isa_settings.rs
+++ b/src/isa_settings.rs
@@ -764,6 +764,13 @@ macro_rules! gen_isa_settings {
return Err(<$decode_err>::InvalidOpcode);
}
}
+ <$opcode>::INVEPT |
+ <$opcode>::INVVPID => {
+ if !settings.vmx() {
+ return Err(<$decode_err>::InvalidOpcode);
+ }
+ }
+
other => {
if !settings.bmi1() {
if BMI1.contains(&other) {
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index f53170b..649d979 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -2986,6 +2986,12 @@ fn test_sha() {
#[test]
fn test_vmx() {
+ fn test_display_vmx(bytes: &[u8], text: &'static str) {
+ test_display_under(&InstDecoder::minimal().with_vmx(), bytes, text);
+ test_display_under(&InstDecoder::default(), bytes, text);
+ test_invalid_under(&InstDecoder::minimal(), bytes);
+ }
+
test_display(&[0x0f, 0xc7, 0x3f], "vmptrst qword [rdi]");
test_display(&[0x0f, 0xc7, 0x37], "vmptrld qword [rdi]");
test_display(&[0xf3, 0x0f, 0xc7, 0x37], "vmxon qword [rdi]");
@@ -2998,6 +3004,10 @@ fn test_vmx() {
test_display(&[0x66, 0x0f, 0xc7, 0x33], "vmclear qword [rbx]");
test_display(&[0xf3, 0x4f, 0x0f, 0xc7, 0x33], "vmxon qword [r11]");
test_display(&[0xf3, 0x0f, 0xc7, 0x33], "vmxon qword [rbx]");
+
+ // these need vmx and invept features
+ test_display_vmx(&[0x66, 0x0f, 0x38, 0x80, 0x01], "invept rax, xmmword [rcx]");
+ test_display_vmx(&[0x66, 0x0f, 0x38, 0x81, 0x01], "invvpid rax, xmmword [rcx]");
}
#[test]
diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs
index 681184c..0ee8696 100644
--- a/test/protected_mode/mod.rs
+++ b/test/protected_mode/mod.rs
@@ -2628,6 +2628,12 @@ fn test_sha() {
#[test]
fn test_vmx() {
+ fn test_display_vmx(bytes: &[u8], text: &'static str) {
+ test_display_under(&InstDecoder::minimal().with_vmx(), bytes, text);
+ test_display_under(&InstDecoder::default(), bytes, text);
+ test_invalid_under(&InstDecoder::minimal(), bytes);
+ }
+
test_display(&[0x0f, 0xc7, 0x3f], "vmptrst qword [edi]");
test_display(&[0x0f, 0xc7, 0x37], "vmptrld qword [edi]");
test_display(&[0xf3, 0x0f, 0xc7, 0x37], "vmxon qword [edi]");
@@ -2638,6 +2644,10 @@ fn test_vmx() {
// test_invalid(&[0x66, 0x0f, 0xc7, 0x03]);
test_display(&[0x66, 0x0f, 0xc7, 0x33], "vmclear qword [ebx]");
test_display(&[0xf3, 0x0f, 0xc7, 0x33], "vmxon qword [ebx]");
+
+ // these need vmx and invept features
+ test_display_vmx(&[0x66, 0x0f, 0x38, 0x80, 0x01], "invept eax, xmmword [ecx]");
+ test_display_vmx(&[0x66, 0x0f, 0x38, 0x81, 0x01], "invvpid eax, xmmword [ecx]");
}
#[test]
diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs
index 72ccede..d29cda4 100644
--- a/test/real_mode/mod.rs
+++ b/test/real_mode/mod.rs
@@ -16756,7 +16756,9 @@ fn test_real_mode() {
test_display(&[0x66, 0x0f, 0x38, 0x00, 0xda], "pshufb xmm3, xmm2");
test_display(&[0x66, 0x0f, 0x38, 0x37, 0x03], "pcmpgtq xmm0, xmmword [bp + di * 1]");
test_display(&[0x66, 0x0f, 0x38, 0x37, 0xc3], "pcmpgtq xmm0, xmm3");
+ test_display(&[0x66, 0x0f, 0x38, 0x80, 0x01], "invept eax, xmmword [bx + di * 1]");
test_display(&[0x66, 0x0f, 0x38, 0x80, 0x2f], "invept ebp, xmmword [bx]");
+ test_display(&[0x66, 0x0f, 0x38, 0x81, 0x01], "invvpid eax, xmmword [bx + di * 1]");
test_display(&[0x66, 0x0f, 0x38, 0x81, 0x2f], "invvpid ebp, xmmword [bx]");
test_display(&[0x66, 0x0f, 0x38, 0x82, 0x2f], "invpcid ebp, xmmword [bx]");
test_display(&[0x66, 0x0f, 0x38, 0xcf, 0x1c], "gf2p8mulb xmm3, xmmword [si]");