qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-arm] [PATCH] target/arm: Implement VI/VF bits


From: Andrew Walbran
Subject: [Qemu-arm] [PATCH] target/arm: Implement VI/VF bits
Date: Mon, 10 Dec 2018 18:38:36 +0000

From: Wedson Almeida Filho <address@hidden>

This lets hypervisors running at EL2 inject virtual interrupts into guest VMs.

Signed-off-by: Wedson Almeida Filho <address@hidden>
Signed-off-by: Andrew Walbran <address@hidden>
---
 target/arm/op_helper.c | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index 0d6e89e474..abd29b22c1 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -1098,9 +1098,44 @@ void HELPER(exception_return)(CPUARMState *env)
         goto illegal_return;
     }
 
-    if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE)
-        && !arm_is_secure_below_el3(env)) {
-        goto illegal_return;
+    if (new_el == 1) {
+        uint64_t hcr = env->cp15.hcr_el2;
+        bool is_secure = arm_is_secure_below_el3(env);
+        bool irq = false, fiq = false;
+        CPUState *cpu = CPU(arm_env_get_cpu(env));
+
+        if ((hcr & HCR_TGE) && !is_secure) {
+            goto illegal_return;
+        }
+
+        /* The VI and VF fields of HCR_EL2 include the following note: In an
+         * implementation that includes EL3, when the value of SCR_EL3.NS
+         * is 0 the PE behaves as if this field is 0 for all purposes other
+         * than a direct read or write access of HCR_EL2.
+         *
+         * So we only check them if not in secure mode. Additionally, both also
+         * have the following note: The virtual IRQ/FIQ is enabled only when
+         * the value of HCR_EL2.{TGE, IMO/FMO} is {0, 1}.
+         */
+        if (!is_secure) {
+            if ((hcr & (HCR_VI | HCR_TGE | HCR_IMO)) == (HCR_VI | HCR_IMO))
+                irq = true;
+
+            if ((hcr & (HCR_VF | HCR_TGE | HCR_FMO)) == (HCR_VF | HCR_FMO))
+                fiq = true;
+        }
+
+        qemu_mutex_lock_iothread();
+        if (irq)
+            cpu_interrupt(cpu, CPU_INTERRUPT_VIRQ);
+        else
+            cpu_reset_interrupt(cpu, CPU_INTERRUPT_VIRQ);
+
+        if (fiq)
+            cpu_interrupt(cpu, CPU_INTERRUPT_VFIQ);
+        else
+            cpu_reset_interrupt(cpu, CPU_INTERRUPT_VFIQ);
+        qemu_mutex_unlock_iothread();
     }
 
     qemu_mutex_lock_iothread();
-- 
2.20.0.rc2.403.gdbc3b29805-goog




reply via email to

[Prev in Thread] Current Thread [Next in Thread]