]> xenbits.xensource.com Git - people/aperard/xen-unstable.git/commitdiff
x86/emul: Emulate %cr8 accesses
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 27 Mar 2025 14:06:09 +0000 (15:06 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 27 Mar 2025 14:06:09 +0000 (15:06 +0100)
Petr reports:

  (XEN) MMIO emulation failed (1): d12v1 64bit @ 0010:fffff8057ba7dfbf -> 45 0f 20 c2 ...

during introspection.

This is MOV %cr8, which is wired up for hvm_mov_{to,from}_cr(); the VMExit
fastpaths, but not for the full emulation slowpaths.

Xen's handling of %cr8 turns out to be quite wrong.  At a minimum, we need
storage for %cr8 separate to APIC_TPR, and to alter intercepts based on
whether the vLAPIC is enabled or not.  But that's more work than there is time
for in the short term, so make a stopgap fix.

Extend hvmemul_{read,write}_cr() with %cr8 cases.  Unlike hvm_mov_to_cr(),
hardware hasn't filtered out invalid values (#GP checks are ahead of
intercepts), so introduce X86_CR8_VALID_MASK.

Reported-by: Petr Beneš <w1benny@gmail.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: 14fd9b5642cd4805b49fbe716bf2cd577e724169
master date: 2025-03-26 11:54:59 +0000

xen/arch/x86/hvm/emulate.c
xen/arch/x86/include/asm/x86-defns.h

index cb071be5860867ef7bd6c433924fae379ad4e078..f4b9352c3915d6c6d03d17ac31e86741c3f80a05 100644 (file)
@@ -2309,6 +2309,10 @@ static int cf_check hvmemul_read_cr(
         val = curr->arch.hvm.guest_cr[reg];
         break;
 
+    case 8:
+        val = (vlapic_get_reg(vcpu_vlapic(curr), APIC_TASKPRI) & 0xf0) >> 4;
+        break;
+
     default:
         return X86EMUL_UNHANDLEABLE;
     }
@@ -2354,6 +2358,17 @@ static int cf_check hvmemul_write_cr(
         rc = hvm_set_cr4(val, true);
         break;
 
+    case 8:
+        if ( val & ~X86_CR8_VALID_MASK )
+        {
+            rc = X86EMUL_EXCEPTION;
+            break;
+        }
+
+        vlapic_set_reg(vcpu_vlapic(curr), APIC_TASKPRI, val << 4);
+        rc = X86EMUL_OKAY;
+        break;
+
     default:
         rc = X86EMUL_UNHANDLEABLE;
         break;
index caa92829eaa9f2f0b2b521157a43bfb60b242d18..64af95389886df71a6ac7605131ca21d7b0df2ed 100644 (file)
@@ -76,6 +76,8 @@
 #define X86_CR4_CET        0x00800000 /* Control-flow Enforcement Technology */
 #define X86_CR4_PKS        0x01000000 /* Protection Key Supervisor */
 
+#define X86_CR8_VALID_MASK 0xf
+
 /*
  * XSTATE component flags in XCR0 | MSR_XSS
  */