From patchwork Fri May 1 17:50:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 47902 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f72.google.com (mail-la0-f72.google.com [209.85.215.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id F16AB2121F for ; Fri, 1 May 2015 17:50:57 +0000 (UTC) Received: by layy10 with SMTP id y10sf30991067lay.0 for ; Fri, 01 May 2015 10:50:56 -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=V+hBLmXkV2BC4NVnNlMxbBclV76JhOQIllW3j5f1x88=; b=dTBZND4yOL4tPtkdEkkTutCm2tFOwbHT8nXD48ivjlGBlx4q9bZXTz7nfFObwtHMR0 nnLGDW9StTTEsvksyQALxCJMtPZyUPFS+Z4Ql0fAU74AjTRWoveO1n9QrhbITEPO68+G uU6sCIOE6CJYH0z3+SCZyr0309hI5gYJtlFmombT1dLXQBWitS8bLHb8eBePubVIMrdD kLzqo0OR38Ob7rB+q+Iq/A9whDFfbSz76SDwRT9mEqQlK9Si8u97Zkwt61sNpfMU5SFq jRPDNzkby8HXhc3BT6ko6LLodq+YSrwSaO54TH40++pam4Yy9KFvZKI3a79ylM8L5hsh 0uuQ== X-Gm-Message-State: ALoCoQnvxaVhZxlo3ca1Z2A5LGJySF4HTrdYybYyW/cjFIzZERmNZNo1W+UskjpOwkJoz/r0LLz/ X-Received: by 10.112.189.131 with SMTP id gi3mr9224077lbc.6.1430502656808; Fri, 01 May 2015 10:50:56 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.19.162 with SMTP id g2ls546360lae.80.gmail; Fri, 01 May 2015 10:50:56 -0700 (PDT) X-Received: by 10.152.116.49 with SMTP id jt17mr9076930lab.82.1430502656668; Fri, 01 May 2015 10:50:56 -0700 (PDT) Received: from mail-lb0-f178.google.com (mail-lb0-f178.google.com. [209.85.217.178]) by mx.google.com with ESMTPS id qf3si4388509lbb.143.2015.05.01.10.50.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 May 2015 10:50:56 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.178 as permitted sender) client-ip=209.85.217.178; Received: by lbbqq2 with SMTP id qq2so68940837lbb.3 for ; Fri, 01 May 2015 10:50:56 -0700 (PDT) X-Received: by 10.112.125.138 with SMTP id mq10mr9275436lbb.35.1430502656527; Fri, 01 May 2015 10:50:56 -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.67.65 with SMTP id l1csp415100lbt; Fri, 1 May 2015 10:50:56 -0700 (PDT) X-Received: by 10.152.43.110 with SMTP id v14mr4580969lal.4.1430502650430; Fri, 01 May 2015 10:50:50 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id l6si4397203lbd.114.2015.05.01.10.50.50 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 01 May 2015 10:50:50 -0700 (PDT) Received-SPF: none (google.com: pm215@archaic.org.uk does not designate permitted sender hosts) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1YoF5I-0006kz-1z; Fri, 01 May 2015 18:50:44 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Greg Bellows , "Edgar E. Iglesias" Subject: [PATCH v4 10/17] hw/intc/arm_gic: Restrict priority view Date: Fri, 1 May 2015 18:50:36 +0100 Message-Id: <1430502643-25909-11-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1430502643-25909-1-git-send-email-peter.maydell@linaro.org> References: <1430502643-25909-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.178 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: , From: Fabian Aggeler GICs with Security Extensions restrict the non-secure view of the interrupt priority and priority mask registers. Signed-off-by: Fabian Aggeler Signed-off-by: Greg Bellows Message-id: 1429113742-8371-15-git-send-email-greg.bellows@linaro.org [PMM: minor code tweaks; fixed missing masking in gic_set_priority_mask and gic_set_priority] Signed-off-by: Peter Maydell --- hw/intc/arm_gic.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++---- hw/intc/arm_gic_kvm.c | 2 +- hw/intc/gic_internal.h | 3 ++- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index e3bbe9e..7c0ddc8 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -233,8 +233,16 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu) return ret; } -void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val) +void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val, + MemTxAttrs attrs) { + if (s->security_extn && !attrs.secure) { + if (!GIC_TEST_GROUP(irq, (1 << cpu))) { + return; /* Ignore Non-secure access of Group0 IRQ */ + } + val = 0x80 | (val >> 1); /* Non-secure view */ + } + if (irq < GIC_INTERNAL) { s->priority1[irq][cpu] = val; } else { @@ -242,6 +250,51 @@ void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val) } } +static uint32_t gic_get_priority(GICState *s, int cpu, int irq, + MemTxAttrs attrs) +{ + uint32_t prio = GIC_GET_PRIORITY(irq, cpu); + + if (s->security_extn && !attrs.secure) { + if (!GIC_TEST_GROUP(irq, (1 << cpu))) { + return 0; /* Non-secure access cannot read priority of Group0 IRQ */ + } + prio = (prio << 1) & 0xff; /* Non-secure view */ + } + return prio; +} + +static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask, + MemTxAttrs attrs) +{ + if (s->security_extn && !attrs.secure) { + if (s->priority_mask[cpu] & 0x80) { + /* Priority Mask in upper half */ + pmask = 0x80 | (pmask >> 1); + } else { + /* Non-secure write ignored if priority mask is in lower half */ + return; + } + } + s->priority_mask[cpu] = pmask; +} + +static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs attrs) +{ + uint32_t pmask = s->priority_mask[cpu]; + + if (s->security_extn && !attrs.secure) { + if (pmask & 0x80) { + /* Priority Mask in upper half, return Non-secure view */ + pmask = (pmask << 1) & 0xff; + } else { + /* Priority Mask in lower half, RAZ */ + pmask = 0; + } + } + return pmask; +} + static uint32_t gic_get_cpu_control(GICState *s, int cpu, MemTxAttrs attrs) { uint32_t ret = s->cpu_ctlr[cpu]; @@ -451,7 +504,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs) irq = (offset - 0x400) + GIC_BASE_IRQ; if (irq >= s->num_irq) goto bad_reg; - res = GIC_GET_PRIORITY(irq, cpu); + res = gic_get_priority(s, cpu, irq, attrs); } else if (offset < 0xc00) { /* Interrupt CPU Target. */ if (s->num_cpu == 1 && s->revision != REV_11MPCORE) { @@ -669,7 +722,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, irq = (offset - 0x400) + GIC_BASE_IRQ; if (irq >= s->num_irq) goto bad_reg; - gic_set_priority(s, cpu, irq, value); + gic_set_priority(s, cpu, irq, value, attrs); } else if (offset < 0xc00) { /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the * annoying exception of the 11MPCore's GIC. @@ -820,7 +873,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, *data = gic_get_cpu_control(s, cpu, attrs); break; case 0x04: /* Priority mask */ - *data = s->priority_mask[cpu]; + *data = gic_get_priority_mask(s, cpu, attrs); break; case 0x08: /* Binary Point */ if (s->security_extn && !attrs.secure) { @@ -870,7 +923,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset, gic_set_cpu_control(s, cpu, value, attrs); break; case 0x04: /* Priority mask */ - s->priority_mask[cpu] = (value & 0xff); + gic_set_priority_mask(s, cpu, value, attrs); break; case 0x08: /* Binary Point */ if (s->security_extn && !attrs.secure) { diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index c5a2f81..54f18df 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -251,7 +251,7 @@ static void translate_priority(GICState *s, int irq, int cpu, if (to_kernel) { *field = GIC_GET_PRIORITY(irq, cpu) & 0xff; } else { - gic_set_priority(s, cpu, irq, *field & 0xff); + gic_set_priority(s, cpu, irq, *field & 0xff, MEMTXATTRS_UNSPECIFIED); } } diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 81c764c..119fb81 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -82,7 +82,8 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu); void gic_complete_irq(GICState *s, int cpu, int irq); void gic_update(GICState *s); void gic_init_irqs_and_distributor(GICState *s); -void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val); +void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val, + MemTxAttrs attrs); static inline bool gic_test_pending(GICState *s, int irq, int cm) {