Signed-off-by: Mohamed Mediouni <[email protected]>
---
 target/i386/whpx/whpx-all.c | 106 ++++++++++++++++++++++++++++++++++--
 1 file changed, 102 insertions(+), 4 deletions(-)

diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index d2cd8e8001..1447c777d3 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -121,10 +121,11 @@ static const WHV_REGISTER_NAME whpx_register_names[] = {
     WHvX64RegisterDr2,
     WHvX64RegisterDr3,
     WHvX64RegisterDr6,
-    WHvX64RegisterDr7
+    WHvX64RegisterDr7,
+    WHvRegisterPendingInterruption,
+    WHvRegisterPendingEvent,
     /* Interrupt / Event Registers */
     /*
-     * WHvRegisterPendingInterruption,
      * WHvRegisterInterruptState,
      * WHvRegisterPendingEvent0,
      * WHvRegisterPendingEvent1
@@ -694,7 +695,47 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel 
level)
         assert(whpx_register_names[idx] == WHvX64RegisterDr7);
         vcxt.values[idx++].Reg64 = env->dr[7];
 
-        /* Interrupt / Event Registers - Skipped */
+        /* Interrupt / Event Registers */
+
+        assert(whpx_register_names[idx] == WHvRegisterPendingInterruption);
+        if (!whpx_irqchip_in_kernel() &&
+            env->exception_pending) {
+            vcxt.values[idx].PendingInterruption.InterruptionPending = 1;
+            vcxt.values[idx].PendingInterruption.InterruptionVector = 
env->exception_nr;
+            vcxt.values[idx].PendingInterruption.DeliverErrorCode = 
env->has_error_code;
+            vcxt.values[idx].PendingInterruption.ErrorCode = env->error_code;
+            if (env->exception_is_int) {
+                vcxt.values[idx].PendingInterruption.InterruptionType = 
WHvX64PendingInterrupt;
+            } else if (env->nmi_pending) {
+                vcxt.values[idx].PendingInterruption.InterruptionType = 
WHvX64PendingNmi;
+            } else {
+                vcxt.values[idx].PendingInterruption.InterruptionType = 
WHvX64PendingException;
+            }
+        }
+        idx++;
+
+        assert(whpx_register_names[idx] == WHvRegisterPendingEvent);
+        if (whpx_irqchip_in_kernel() &&
+            env->exception_pending) {
+            if (!env->exception_is_int) {
+                vcxt.values[idx].ExceptionEvent.EventPending = 1;
+                vcxt.values[idx].ExceptionEvent.EventType =
+                    WHvX64PendingEventException;
+                vcxt.values[idx].ExceptionEvent.Vector = env->exception_nr;
+                vcxt.values[idx].ExceptionEvent.DeliverErrorCode
+                    = env->has_error_code;
+                vcxt.values[idx].ExceptionEvent.ErrorCode = env->error_code;
+                vcxt.values[idx].ExceptionEvent.ExceptionParameter =
+                    env->exception_payload;
+            } else if (vcxt.values[idx].ExtIntEvent.EventType
+                == WHvX64PendingEventExtInt) {
+                vcxt.values[idx].ExtIntEvent.EventPending = 1;
+                vcxt.values[idx].ExtIntEvent.Vector = env->exception_nr;
+            }  else {
+                abort();
+            }
+        }
+        idx++;
 
         assert(idx == RTL_NUMBER_OF(whpx_register_names));
     }
@@ -1091,7 +1132,64 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel 
level)
     assert(whpx_register_names[idx] == WHvX64RegisterDr7);
     env->dr[7] = vcxt.values[idx++].Reg64;
 
-    /* Interrupt / Event Registers - Skipped */
+    /* Interrupt / Event Registers */
+
+    assert(whpx_register_names[idx] == WHvRegisterPendingInterruption);
+    if (!whpx_irqchip_in_kernel() &&
+        vcxt.values[idx].PendingInterruption.InterruptionPending) {
+        env->exception_pending = 1;
+        env->exception_nr = 
+            vcxt.values[idx].PendingInterruption.InterruptionVector;
+        env->has_error_code =
+            vcxt.values[idx].PendingInterruption.DeliverErrorCode;
+        env->error_code =
+            vcxt.values[idx].PendingInterruption.ErrorCode;
+        if (vcxt.values[idx].PendingInterruption.InterruptionType
+            == WHvX64PendingInterrupt) {
+            env->exception_is_int = 1;
+            env->nmi_pending = 0;
+        } else if (vcxt.values[idx].PendingInterruption.InterruptionType
+            == WHvX64PendingNmi) {
+            env->exception_is_int = 0;
+            env->nmi_pending = 1;
+        } else if (vcxt.values[idx].PendingInterruption.InterruptionType
+            == WHvX64PendingException) {
+            env->exception_is_int = 0;
+            env->nmi_pending = 0;
+        } else {
+            abort();
+        }
+    }
+    idx++;
+
+    assert(whpx_register_names[idx] == WHvRegisterPendingEvent);
+    if (whpx_irqchip_in_kernel() &&
+        vcxt.values[idx].ExceptionEvent.EventPending) {
+        if (vcxt.values[idx].ExceptionEvent.EventType
+            == WHvX64PendingEventException) {
+            env->exception_pending = 1;
+            env->exception_nr =
+                vcxt.values[idx].ExceptionEvent.Vector;
+            env->has_error_code = 
+                vcxt.values[idx].ExceptionEvent.DeliverErrorCode;
+            env->error_code =
+                vcxt.values[idx].ExceptionEvent.ErrorCode;
+            env->exception_payload =
+                vcxt.values[idx].ExceptionEvent.ExceptionParameter;
+            env->exception_is_int = 0;
+            env->nmi_pending = 0;
+        } else if (vcxt.values[idx].ExtIntEvent.EventType
+            == WHvX64PendingEventExtInt) {
+            env->exception_pending = 1;
+            env->exception_is_int = 1;
+            env->nmi_pending = 0;
+            env->exception_nr = 
+                vcxt.values[idx].ExtIntEvent.Vector;
+        } else {
+            abort();
+        }
+    }
+    idx++;
 
     assert(idx == RTL_NUMBER_OF(whpx_register_names));
 
-- 
2.54.0 (Apple Git-157)


Reply via email to