From patchwork Thu Jul 16 20:11:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 51206 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9C39A22A8A for ; Thu, 16 Jul 2015 20:11:28 +0000 (UTC) Received: by lafd3 with SMTP id d3sf21282467laf.1 for ; Thu, 16 Jul 2015 13:11:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=if7vD3s9brFV28LnC4Lhn8OVYSf+megBxRd7OqGx8E4=; b=aojxrPyzWW8WzL6/MEKgahawG9SCcjTBWSX2n2kbHsvjN2AHYDDJHkN3srlrcxVnCr cc0/wmgIISyxIeHDU9mls3iRHsygtBwUtykCR71OO+YGqGJ5osm/wSydw0ytbDlRl3Gu gAXtruPh3Rj56tg0XK693gs0IX9Y0XxqMAvU3M2tK1a9P2/5zlqAjoXInkJuNst+IPsV IKIBM1aGiMMgV5jza8sw2zbmaPy391YqLsD5xTr1fUHYehMSYx/3jq/049FKMNCpISYl nWbYaXjzhZ7lHImWJQH5/fHMiylYevvL8LJNAq9TTkk7L/vlrX5DyR5vonV5s6OPgdAu v1og== X-Gm-Message-State: ALoCoQn92qT/0Sib7v7vTKabWk2XxDUvmir7mnc45krX4BY6LiAxkrPWZK8huK/k/l03g3Yi+KcU X-Received: by 10.112.13.200 with SMTP id j8mr5655919lbc.14.1437077487599; Thu, 16 Jul 2015 13:11:27 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.170.195 with SMTP id ao3ls108088lac.53.gmail; Thu, 16 Jul 2015 13:11:27 -0700 (PDT) X-Received: by 10.152.21.227 with SMTP id y3mr4687782lae.24.1437077487452; Thu, 16 Jul 2015 13:11:27 -0700 (PDT) Received: from mail-lb0-f171.google.com (mail-lb0-f171.google.com. [209.85.217.171]) by mx.google.com with ESMTPS id t5si7891132lbb.35.2015.07.16.13.11.27 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Jul 2015 13:11:27 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) client-ip=209.85.217.171; Received: by lbbzr7 with SMTP id zr7so50260133lbb.1 for ; Thu, 16 Jul 2015 13:11:27 -0700 (PDT) X-Received: by 10.152.206.75 with SMTP id lm11mr10731188lac.41.1437077487027; Thu, 16 Jul 2015 13:11:27 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp474431lbb; Thu, 16 Jul 2015 13:11:25 -0700 (PDT) X-Received: by 10.66.138.40 with SMTP id qn8mr21970043pab.19.1437077481799; Thu, 16 Jul 2015 13:11:21 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [81.2.115.146]) by mx.google.com with ESMTPS id xf2si14643170pbb.190.2015.07.16.13.11.19 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 16 Jul 2015 13:11:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1ZFpUv-0001Bl-BK; Thu, 16 Jul 2015 21:11:13 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, "Edgar E. Iglesias" , Peter Crosthwaite , =?UTF-8?q?Andreas=20F=C3=A4rber?= Subject: [PATCH v2 3/6] hw/intc/arm_gic_common: Configure IRQs as NS if doing direct NS kernel boot Date: Thu, 16 Jul 2015 21:11:10 +0100 Message-Id: <1437077473-4532-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1437077473-4532-1-git-send-email-peter.maydell@linaro.org> References: <1437077473-4532-1-git-send-email-peter.maydell@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , If we directly boot a kernel in NonSecure on a system where the GIC supports the security extensions then we must cause the GIC to configure its interrupts into group 1 (NonSecure) rather than the usual group 0, and with their initial priority set to the highest NonSecure priority rather than the usual highest Secure priority. Otherwise the guest kernel will be unable to use any interrupts. Implement this behaviour, controlled by a flag which we set if appropriate when the ARM bootloader code calls our ARMLinuxBootIf interface callback. Signed-off-by: Peter Maydell --- hw/intc/arm_gic_common.c | 51 +++++++++++++++++++++++++++++++++++++--- include/hw/intc/arm_gic_common.h | 1 + 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index a64d071..ae7c74e 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -19,6 +19,7 @@ */ #include "gic_internal.h" +#include "hw/arm/linux-boot-if.h" static void gic_pre_save(void *opaque) { @@ -124,12 +125,27 @@ static void arm_gic_common_reset(DeviceState *dev) { GICState *s = ARM_GIC_COMMON(dev); int i, j; + int resetprio; + + /* If we're resetting a TZ-aware GIC as if secure firmware + * had set it up ready to start a kernel in non-secure, + * we need to set interrupt priorities to a "zero for the + * NS view" value. This is particularly critical for the + * priority_mask[] values, because if they are zero then NS + * code cannot ever rewrite the priority to anything else. + */ + if (s->security_extn && s->irq_reset_nonsecure) { + resetprio = 0x80; + } else { + resetprio = 0; + } + memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state)); for (i = 0 ; i < s->num_cpu; i++) { if (s->revision == REV_11MPCORE) { s->priority_mask[i] = 0xf0; } else { - s->priority_mask[i] = 0; + s->priority_mask[i] = resetprio; } s->current_pending[i] = 1023; s->running_irq[i] = 1023; @@ -138,7 +154,7 @@ static void arm_gic_common_reset(DeviceState *dev) s->bpr[i] = GIC_MIN_BPR; s->abpr[i] = GIC_MIN_ABPR; for (j = 0; j < GIC_INTERNAL; j++) { - s->priority1[j][i] = 0; + s->priority1[j][i] = resetprio; } for (j = 0; j < GIC_NR_SGIS; j++) { s->sgi_pending[j][i] = 0; @@ -150,7 +166,7 @@ static void arm_gic_common_reset(DeviceState *dev) } for (i = 0; i < ARRAY_SIZE(s->priority2); i++) { - s->priority2[i] = 0; + s->priority2[i] = resetprio; } for (i = 0; i < GIC_MAXIRQ; i++) { @@ -161,9 +177,32 @@ static void arm_gic_common_reset(DeviceState *dev) s->irq_target[i] = 0; } } + if (s->security_extn && s->irq_reset_nonsecure) { + for (i = 0; i < GIC_MAXIRQ; i++) { + GIC_SET_GROUP(i, ALL_CPU_MASK); + } + } + s->ctlr = 0; } +static void arm_gic_common_linux_init(ARMLinuxBootIf *obj, + bool secure_boot) +{ + GICState *s = ARM_GIC_COMMON(obj); + + if (s->security_extn && !secure_boot) { + /* We're directly booting a kernel into NonSecure. If this GIC + * 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 in real hardware, and in + * this mode QEMU is acting as a minimalist firmware-and-bootloader + * equivalent). + */ + s->irq_reset_nonsecure = true; + } +} + static Property arm_gic_common_properties[] = { DEFINE_PROP_UINT32("num-cpu", GICState, num_cpu, 1), DEFINE_PROP_UINT32("num-irq", GICState, num_irq, 32), @@ -180,11 +219,13 @@ static Property arm_gic_common_properties[] = { static void arm_gic_common_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_CLASS(klass); dc->reset = arm_gic_common_reset; dc->realize = arm_gic_common_realize; dc->props = arm_gic_common_properties; dc->vmsd = &vmstate_gic; + albifc->arm_linux_init = arm_gic_common_linux_init; } static const TypeInfo arm_gic_common_type = { @@ -194,6 +235,10 @@ static const TypeInfo arm_gic_common_type = { .class_size = sizeof(ARMGICCommonClass), .class_init = arm_gic_common_class_init, .abstract = true, + .interfaces = (InterfaceInfo []) { + { TYPE_ARM_LINUX_BOOT_IF }, + { }, + }, }; static void register_types(void) diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 899db3d..cfc1cce 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -118,6 +118,7 @@ typedef struct GICState { uint32_t num_irq; uint32_t revision; bool security_extn; + bool irq_reset_nonsecure; /* configure IRQs as group 1 (NS) on reset? */ int dev_fd; /* kvm device fd if backed by kvm vgic support */ } GICState;