qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 3/5] hw/arm/boot: Configure secure GIC to make IRQs


From: Peter Maydell
Subject: [Qemu-devel] [PATCH 3/5] hw/arm/boot: Configure secure GIC to make IRQs NS if booting an NS kernel
Date: Tue, 30 Jun 2015 14:07:27 +0100

If our builtin kernel bootloader is directly booting a kernel in
the NonSecure world, then we must configure the GIC to put all
the IRQs into the NonSecure group. (By default all interrupts
are configured to be Secure on reset, which means that a NonSecure
guest kernel cannot use any of them.) This job would usually
be done by the Secure boot firmware, but our builtin bootloader
is doing the job of firmware.

Signed-off-by: Peter Maydell <address@hidden>
---
 hw/arm/boot.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1e7fd28..3974499 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -13,6 +13,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/loader.h"
+#include "hw/intc/arm_gic_common.h"
 #include "elf.h"
 #include "sysemu/device_tree.h"
 #include "qemu/config-file.h"
@@ -557,6 +558,33 @@ static void load_image_to_fw_cfg(FWCfgState *fw_cfg, 
uint16_t size_key,
     fw_cfg_add_bytes(fw_cfg, data_key, data, size);
 }
 
+static int find_gics(Object *obj, void *opaque)
+{
+    GICState *gic = (GICState *)object_dynamic_cast(obj, TYPE_ARM_GIC_COMMON);
+    bool has_sec_extns;
+
+    if (!gic) {
+        /* Might be a container, traverse it for children */
+        return object_child_foreach(obj, find_gics, opaque);
+    }
+
+    has_sec_extns = object_property_get_bool(obj, "has-security-extensions",
+                                             &error_abort);
+    if (has_sec_extns) {
+        object_property_set_bool(obj, true, "irqs-reset-nonsecure",
+                                 &error_abort);
+    }
+    return 0;
+}
+
+static void reconfigure_gics_nonsecure(void)
+{
+    /* Find every GIC in the system and tell it to reconfigure
+     * itself with interrupts as NonSecure.
+     */
+    object_child_foreach(qdev_get_machine(), find_gics, NULL);
+}
+
 static void arm_load_kernel_notify(Notifier *notifier, void *data)
 {
     CPUState *cs;
@@ -767,6 +795,17 @@ static void arm_load_kernel_notify(Notifier *notifier, 
void *data)
     }
     info->is_linux = is_linux;
 
+    if (is_linux && arm_feature(&cpu->env, ARM_FEATURE_EL3) &&
+        !info->secure_boot) {
+        /* We're directly booting a kernel into NonSecure. If the system
+         * has a GIC which implements the security extensions then we must
+         * configure it to have all the interrupts be NonSecure (this is
+         * a job that is done by the Secure boot firmware, and boot.c is
+         * a minimalist firmware-and-boot-loader equivalent).
+         */
+        reconfigure_gics_nonsecure();
+    }
+
     for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
         ARM_CPU(cs)->env.boot_info = info;
     }
-- 
1.9.1




reply via email to

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