qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 19/45] intc/arm_gic: Refactor secure/ns access check in the CPU interface
Date: Tue, 14 Aug 2018 19:17:49 +0100	[thread overview]
Message-ID: <20180814181815.23348-20-peter.maydell@linaro.org> (raw)
In-Reply-To: <20180814181815.23348-1-peter.maydell@linaro.org>

From: Luc Michel <luc.michel@greensocs.com>

An access to the CPU interface is non-secure if the current GIC instance
implements the security extensions, and the memory access is actually
non-secure. Until then, it was checked with tests such as
  if (s->security_extn && !attrs.secure) { ... }
in various places of the CPU interface code.

With the implementation of the virtualization extensions, those tests
must be updated to take into account whether we are in a vCPU interface
or not. This is because the exposed vCPU interface does not implement
security extensions.

This commits replaces all those tests with a call to the
gic_cpu_ns_access() function to check if the current access to the CPU
interface is non-secure. This function takes into account whether the
current CPU is a vCPU or not.

Note that this function is used only in the (v)CPU interface code path.
The distributor code path is left unchanged, as the distributor is not
exposed to vCPUs at all.

Signed-off-by: Luc Michel <luc.michel@greensocs.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180727095421.386-9-luc.michel@greensocs.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/arm_gic.c | 39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 41141fee532..94d5982e2ac 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -74,6 +74,11 @@ static inline bool gic_has_groups(GICState *s)
     return s->revision == 2 || s->security_extn;
 }
 
+static inline bool gic_cpu_ns_access(GICState *s, int cpu, MemTxAttrs attrs)
+{
+    return !gic_is_vcpu(cpu) && s->security_extn && !attrs.secure;
+}
+
 /* TODO: Many places that call this routine could be optimized.  */
 /* Update interrupt status after enabled or pending bits have been changed.  */
 static void gic_update(GICState *s)
@@ -221,7 +226,7 @@ static uint16_t gic_get_current_pending_irq(GICState *s, int cpu,
         /* On a GIC without the security extensions, reading this register
          * behaves in the same way as a secure access to a GIC with them.
          */
-        bool secure = !s->security_extn || attrs.secure;
+        bool secure = !gic_cpu_ns_access(s, cpu, attrs);
 
         if (group == 0 && !secure) {
             /* Group0 interrupts hidden from Non-secure access */
@@ -428,7 +433,7 @@ static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq,
 static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
                                   MemTxAttrs attrs)
 {
-    if (s->security_extn && !attrs.secure) {
+    if (gic_cpu_ns_access(s, cpu, attrs)) {
         if (s->priority_mask[cpu] & 0x80) {
             /* Priority Mask in upper half */
             pmask = 0x80 | (pmask >> 1);
@@ -444,7 +449,7 @@ 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 (gic_cpu_ns_access(s, cpu, attrs)) {
         if (pmask & 0x80) {
             /* Priority Mask in upper half, return Non-secure view */
             pmask = (pmask << 1) & 0xff;
@@ -460,7 +465,7 @@ static uint32_t gic_get_cpu_control(GICState *s, int cpu, MemTxAttrs attrs)
 {
     uint32_t ret = s->cpu_ctlr[cpu];
 
-    if (s->security_extn && !attrs.secure) {
+    if (gic_cpu_ns_access(s, cpu, attrs)) {
         /* Construct the NS banked view of GICC_CTLR from the correct
          * bits of the S banked view. We don't need to move the bypass
          * control bits because we don't implement that (IMPDEF) part
@@ -476,7 +481,7 @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value,
 {
     uint32_t mask;
 
-    if (s->security_extn && !attrs.secure) {
+    if (gic_cpu_ns_access(s, cpu, attrs)) {
         /* The NS view can only write certain bits in the register;
          * the rest are unchanged
          */
@@ -507,7 +512,7 @@ static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
         return 0xff;
     }
 
-    if (s->security_extn && !attrs.secure) {
+    if (gic_cpu_ns_access(s, cpu, attrs)) {
         if (s->running_priority[cpu] & 0x80) {
             /* Running priority in upper half of range: return the Non-secure
              * view of the priority.
@@ -531,7 +536,7 @@ static bool gic_eoi_split(GICState *s, int cpu, MemTxAttrs attrs)
         /* Before GICv2 prio-drop and deactivate are not separable */
         return false;
     }
-    if (s->security_extn && !attrs.secure) {
+    if (gic_cpu_ns_access(s, cpu, attrs)) {
         return s->cpu_ctlr[cpu] & GICC_CTLR_EOIMODE_NS;
     }
     return s->cpu_ctlr[cpu] & GICC_CTLR_EOIMODE;
@@ -563,7 +568,7 @@ static void gic_deactivate_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
         return;
     }
 
-    if (s->security_extn && !attrs.secure && !group) {
+    if (gic_cpu_ns_access(s, cpu, attrs) && !group) {
         DPRINTF("Non-secure DI for Group0 interrupt %d ignored\n", irq);
         return;
     }
@@ -605,7 +610,7 @@ static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
 
     group = gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, cm);
 
-    if (s->security_extn && !attrs.secure && !group) {
+    if (gic_cpu_ns_access(s, cpu, attrs) && !group) {
         DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq);
         return;
     }
@@ -1281,7 +1286,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
         *data = gic_get_priority_mask(s, cpu, attrs);
         break;
     case 0x08: /* Binary Point */
-        if (s->security_extn && !attrs.secure) {
+        if (gic_cpu_ns_access(s, cpu, attrs)) {
             if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
                 /* NS view of BPR when CBPR is 1 */
                 *data = MIN(s->bpr[cpu] + 1, 7);
@@ -1308,7 +1313,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
          * With security extensions, secure access: ABPR (alias of NS BPR)
          * With security extensions, nonsecure access: RAZ/WI
          */
-        if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
+        if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) {
             *data = 0;
         } else {
             *data = s->abpr[cpu];
@@ -1320,7 +1325,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
 
         if (regno >= GIC_NR_APRS || s->revision != 2) {
             *data = 0;
-        } else if (s->security_extn && !attrs.secure) {
+        } else if (gic_cpu_ns_access(s, cpu, attrs)) {
             /* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
             *data = gic_apr_ns_view(s, regno, cpu);
         } else {
@@ -1333,7 +1338,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
         int regno = (offset - 0xe0) / 4;
 
         if (regno >= GIC_NR_APRS || s->revision != 2 || !gic_has_groups(s) ||
-            (s->security_extn && !attrs.secure)) {
+            gic_cpu_ns_access(s, cpu, attrs)) {
             *data = 0;
         } else {
             *data = s->nsapr[regno][cpu];
@@ -1360,7 +1365,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
         gic_set_priority_mask(s, cpu, value, attrs);
         break;
     case 0x08: /* Binary Point */
-        if (s->security_extn && !attrs.secure) {
+        if (gic_cpu_ns_access(s, cpu, attrs)) {
             if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
                 /* WI when CBPR is 1 */
                 return MEMTX_OK;
@@ -1375,7 +1380,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
         gic_complete_irq(s, cpu, value & 0x3ff, attrs);
         return MEMTX_OK;
     case 0x1c: /* Aliased Binary Point */
-        if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
+        if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) {
             /* unimplemented, or NS access: RAZ/WI */
             return MEMTX_OK;
         } else {
@@ -1389,7 +1394,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
         if (regno >= GIC_NR_APRS || s->revision != 2) {
             return MEMTX_OK;
         }
-        if (s->security_extn && !attrs.secure) {
+        if (gic_cpu_ns_access(s, cpu, attrs)) {
             /* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
             gic_apr_write_ns_view(s, regno, cpu, value);
         } else {
@@ -1404,7 +1409,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
         if (regno >= GIC_NR_APRS || s->revision != 2) {
             return MEMTX_OK;
         }
-        if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) {
+        if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) {
             return MEMTX_OK;
         }
         s->nsapr[regno][cpu] = value;
-- 
2.18.0

  parent reply	other threads:[~2018-08-14 18:21 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-14 18:17 [Qemu-devel] [PULL 00/45] target-arm queue Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 01/45] target/arm: Forbid unprivileged mode for M Baseline Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 02/45] nvic: Handle ARMv6-M SCS reserved registers Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 03/45] arm: Add ARMv6-M programmer's model support Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 04/45] nvic: Change NVIC to support ARMv6-M Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 05/45] accel/tcg: Pass read access type through to io_readx() Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 06/45] accel/tcg: Handle get_page_addr_code() returning -1 in hashtable lookups Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 07/45] accel/tcg: Handle get_page_addr_code() returning -1 in tb_check_watchpoint() Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 08/45] accel/tcg: tb_gen_code(): Create single-insn TB for execution from non-RAM Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 09/45] accel/tcg: Return -1 for execution from MMIO regions in get_page_addr_code() Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 10/45] target/arm: Allow execution from small regions Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 11/45] accel/tcg: Check whether TLB entry is RAM consistently with how we set it up Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 12/45] intc/arm_gic: Refactor operations on the distributor Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 13/45] intc/arm_gic: Implement GICD_ISACTIVERn and GICD_ICACTIVERn registers Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 14/45] intc/arm_gic: Remove some dead code and put some functions static Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 15/45] vmstate.h: Provide VMSTATE_UINT16_SUB_ARRAY Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 16/45] intc/arm_gic: Add the virtualization extensions to the GIC state Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 17/45] intc/arm_gic: Add virtual interface register definitions Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 18/45] intc/arm_gic: Add virtualization extensions helper macros and functions Peter Maydell
2018-08-14 18:17 ` Peter Maydell [this message]
2018-08-14 18:17 ` [Qemu-devel] [PULL 20/45] intc/arm_gic: Add virtualization enabled IRQ helper functions Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 21/45] intc/arm_gic: Implement virtualization extensions in gic_(activate_irq|drop_prio) Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 22/45] intc/arm_gic: Implement virtualization extensions in gic_acknowledge_irq Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 23/45] intc/arm_gic: Implement virtualization extensions in gic_(deactivate|complete_irq) Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 24/45] intc/arm_gic: Implement virtualization extensions in gic_cpu_(read|write) Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 25/45] intc/arm_gic: Wire the vCPU interface Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 26/45] intc/arm_gic: Implement the virtual interface registers Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 27/45] intc/arm_gic: Implement gic_update_virt() function Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 28/45] intc/arm_gic: Implement maintenance interrupt generation Peter Maydell
2018-08-14 18:17 ` [Qemu-devel] [PULL 29/45] intc/arm_gic: Improve traces Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 30/45] xlnx-zynqmp: Improve GIC wiring and MMIO mapping Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 31/45] arm/virt: Add support for GICv2 virtualization extensions Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 32/45] arm: Fix return code of arm_load_elf Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 33/45] target/arm: Mask virtual interrupts if HCR_EL2.TGE is set Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 34/45] target/arm: Honour HCR_EL2.TGE and MDCR_EL2.TDE in debug register access checks Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 35/45] target/arm: Honour HCR_EL2.TGE when raising synchronous exceptions Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 36/45] target/arm: Provide accessor functions for HCR_EL2.{IMO, FMO, AMO} Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 37/45] target/arm: Treat SCTLR_EL1.M as if it were zero when HCR_EL2.TGE is set Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 38/45] target/arm: Improve exception-taken logging Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 39/45] target/arm: Initialize exc_secure correctly in do_v7m_exception_exit() Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 40/45] target/arm: Restore M-profile CONTROL.SPSEL before any tailchaining Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 41/45] target/arm: Implement tailchaining for M profile cores Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 42/45] target/arm: Fix sign of sve_cmpeq_ppzw/sve_cmpne_ppzw Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 43/45] target/arm: Fix typo in do_sat_addsub_64 Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 44/45] target/arm: Reorganize SVE WHILE Peter Maydell
2018-08-14 18:18 ` [Qemu-devel] [PULL 45/45] target/arm: Fix typo in helper_sve_movz_d Peter Maydell
2018-08-15 12:29 ` [Qemu-devel] [PULL 00/45] target-arm queue Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180814181815.23348-20-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).