xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Julien Grall <julien.grall@citrix.com>,
	ian.campbell@citrix.com, stefano.stabellini@eu.citrix.com
Subject: [PATCH v3 3/9] xen/arm: io: Support sign-extension for every read access
Date: Wed, 7 Oct 2015 15:41:05 +0100	[thread overview]
Message-ID: <1444228871-383-4-git-send-email-julien.grall@citrix.com> (raw)
In-Reply-To: <1444228871-383-1-git-send-email-julien.grall@citrix.com>

The guest may try to load data from the emulated MMIO region using
instructions with Sign-Extension (i.e ldrs*). Any use of one those,
will set the SSE bit (Syndrome Sign Extend) in the ISS (see B3-1433
in DDI 0406C.b).

Note that the bit can only be set for access size smaller than the
register size (i.e byte/half-word for aarch32, byte/half-word/word for
aarch32). So we don't have to worry about undefined C behavior.

Until now, the support of sign-extension was limited for byte access in
vGIC emulation. Although there is no reason to not have it generically.

So move the support just after we get the data from the MMIO emulation.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>

---

    Changes in v3:
        - Update a comment I forgot to address it in v2
        - Add Ian's acked-by

    Changes in v2:
        - Rebase on top of "xen/arm: io: Extend write/read handler to
        pass private data" [1]
        - Fix typeos
        - Expand the commit message to explain the access size supported
        - Add "io: " in the commit title

    Changes in v1:
        - Patch added

[1] http://lists.xen.org/archives/html/xen-devel/2015-09/msg03753.html
---
 xen/arch/arm/io.c          | 29 ++++++++++++++++++++++++++++-
 xen/arch/arm/vgic-v2.c     | 10 +++++-----
 xen/arch/arm/vgic-v3.c     |  4 ++--
 xen/include/asm-arm/vgic.h |  8 +++-----
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c
index ffe7c21..de5765a 100644
--- a/xen/arch/arm/io.c
+++ b/xen/arch/arm/io.c
@@ -23,6 +23,33 @@
 #include <asm/current.h>
 #include <asm/mmio.h>
 
+static int handle_read(const struct mmio_handler *handler, struct vcpu *v,
+                       mmio_info_t *info, register_t *r)
+{
+    uint8_t size = (1 << info->dabt.size) * 8;
+
+    if ( !handler->ops->read(v, info, r, handler->priv) )
+        return 0;
+
+    /*
+     * Sign extend if required.
+     * Note that we expect the read handler to have zeroed the bits
+     * outside the requested access size.
+     */
+    if ( info->dabt.sign && (*r & (1UL << (size - 1)) ))
+    {
+        /*
+         * We are relying on register_t using the same as
+         * an unsigned long in order to keep the 32-bit assembly
+         * code smaller.
+         */
+        BUILD_BUG_ON(sizeof(register_t) != sizeof(unsigned long));
+        *r |= (~0UL) << size;
+    }
+
+    return 1;
+}
+
 int handle_mmio(mmio_info_t *info)
 {
     struct vcpu *v = current;
@@ -48,7 +75,7 @@ int handle_mmio(mmio_info_t *info)
     if ( info->dabt.write )
         return handler->ops->write(v, info, *r, handler->priv);
     else
-        return handler->ops->read(v, info, r, handler->priv);
+        return handle_read(handler, v, info, r);
 }
 
 void register_mmio_handler(struct domain *d,
diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index dc2c2d2..dcbba0f 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -129,7 +129,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         *r = rank->v2.itargets[REG_RANK_INDEX(8, gicd_reg - GICD_ITARGETSR,
                                               DABT_WORD)];
         if ( dabt.size == DABT_BYTE )
-            *r = vgic_byte_read(*r, dabt.sign, gicd_reg);
+            *r = vgic_byte_read(*r, gicd_reg);
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
@@ -142,7 +142,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
         *r = rank->ipriority[REG_RANK_INDEX(8, gicd_reg - GICD_IPRIORITYR,
                                             DABT_WORD)];
         if ( dabt.size == DABT_BYTE )
-            *r = vgic_byte_read(*r, dabt.sign, gicd_reg);
+            *r = vgic_byte_read(*r, gicd_reg);
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
@@ -377,7 +377,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
 
             new_target = i % 8;
             old_target_mask = vgic_byte_read(rank->v2.itargets[REG_RANK_INDEX(8,
-                                             gicd_reg - GICD_ITARGETSR, DABT_WORD)], 0, i/8);
+                                             gicd_reg - GICD_ITARGETSR, DABT_WORD)], i/8);
             old_target = find_first_bit(&old_target_mask, 8);
 
             if ( new_target != old_target )
@@ -503,7 +503,7 @@ static struct vcpu *vgic_v2_get_target_vcpu(struct vcpu *v, unsigned int irq)
     ASSERT(spin_is_locked(&rank->lock));
 
     target = vgic_byte_read(rank->v2.itargets[REG_RANK_INDEX(8,
-                                              irq, DABT_WORD)], 0, irq & 0x3);
+                                              irq, DABT_WORD)], irq & 0x3);
 
     /* 1-N SPI should be delivered as pending to all the vcpus in the
      * mask, but here we just return the first vcpu for simplicity and
@@ -521,7 +521,7 @@ static int vgic_v2_get_irq_priority(struct vcpu *v, unsigned int irq)
 
     ASSERT(spin_is_locked(&rank->lock));
     priority = vgic_byte_read(rank->ipriority[REG_RANK_INDEX(8,
-                                              irq, DABT_WORD)], 0, irq & 0x3);
+                                              irq, DABT_WORD)], irq & 0x3);
 
     return priority;
 }
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 2a09f86..6de7f00 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -336,7 +336,7 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
         *r = rank->ipriority[REG_RANK_INDEX(8, reg - GICD_IPRIORITYR,
                                             DABT_WORD)];
         if ( dabt.size == DABT_BYTE )
-            *r = vgic_byte_read(*r, dabt.sign, reg);
+            *r = vgic_byte_read(*r, reg);
         vgic_unlock_rank(v, rank, flags);
         return 1;
     case GICD_ICFGR ... GICD_ICFGRN:
@@ -1042,7 +1042,7 @@ static int vgic_v3_get_irq_priority(struct vcpu *v, unsigned int irq)
 
     ASSERT(spin_is_locked(&rank->lock));
     priority = vgic_byte_read(rank->ipriority[REG_RANK_INDEX(8,
-                                              irq, DABT_WORD)], 0, irq & 0x3);
+                                              irq, DABT_WORD)], irq & 0x3);
 
     return priority;
 }
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 96839f0..354c0d4 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -158,15 +158,13 @@ static inline int REG_RANK_NR(int b, uint32_t n)
     }
 }
 
-static inline uint32_t vgic_byte_read(uint32_t val, int sign, int offset)
+static inline uint32_t vgic_byte_read(uint32_t val, int offset)
 {
     int byte = offset & 0x3;
 
     val = val >> (8*byte);
-    if ( sign && (val & 0x80) )
-        val |= 0xffffff00;
-    else
-        val &= 0x000000ff;
+    val &= 0x000000ff;
+
     return val;
 }
 
-- 
2.1.4

  parent reply	other threads:[~2015-10-07 14:43 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-07 14:41 [PATCH v3 0/9] xen/arm: vgic: Support 32-bit access for 64-bit register Julien Grall
2015-10-07 14:41 ` [PATCH v3 1/9] xen/arm: io: remove mmio_check_t typedef Julien Grall
2015-10-07 14:41 ` [PATCH v3 2/9] xen/arm: io: Extend write/read handler to pass the register in parameter Julien Grall
2015-10-07 14:41 ` Julien Grall [this message]
2015-10-07 14:41 ` [PATCH v3 4/9] xen/arm: vgic: ctlr stores a 32-bit hardware register so use uint32_t Julien Grall
2015-10-07 14:41 ` [PATCH v3 5/9] xen/arm: vgic: Optimize the way to store GICD_IPRIORITYR in the rank Julien Grall
2015-10-07 14:41 ` [PATCH v3 6/9] xen/arm: vgic: Introduce a new field to store the rank index and use it Julien Grall
2015-10-07 14:41 ` [PATCH v3 7/9] xen/arm: vgic: Optimize the way to store the target vCPU in the rank Julien Grall
2015-10-07 15:38   ` Ian Campbell
2015-10-07 15:48     ` Julien Grall
2015-10-07 16:00       ` Ian Campbell
2015-10-07 16:29         ` Julien Grall
2015-10-07 19:13           ` Julien Grall
2015-10-08  9:39             ` Ian Campbell
2015-10-08 10:43               ` Julien Grall
2015-10-07 17:26   ` Stefano Stabellini
2015-10-07 18:16     ` Julien Grall
2015-10-08 10:56       ` Ian Campbell
2015-10-08 11:36         ` Stefano Stabellini
2015-10-08 12:23           ` Ian Campbell
2015-10-08 12:34             ` Stefano Stabellini
2015-10-08 13:46             ` Julien Grall
2015-10-08 14:25               ` Ian Campbell
2015-10-08 18:36                 ` Julien Grall
2015-10-09 11:24                   ` Julien Grall
2015-10-09 11:38                     ` Ian Campbell
2015-10-12 10:41                 ` Stefano Stabellini
2015-10-12 11:00                   ` Julien Grall
2015-10-12 11:07                     ` Stefano Stabellini
2015-10-12 11:28                       ` Julien Grall
2015-10-07 14:41 ` [PATCH v3 8/9] xen/arm: vgic: Introduce helpers to extract/update/clear/set vGIC register Julien Grall
2015-10-07 14:41 ` [PATCH v3 9/9] xen/arm: vgic-v3: Support 32-bit access for 64-bit registers Julien Grall
2015-10-08 10:44 ` [PATCH v3 0/9] xen/arm: vgic: Support 32-bit access for 64-bit register Julien Grall
2015-10-08 11:46   ` Ian Campbell

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=1444228871-383-4-git-send-email-julien.grall@citrix.com \
    --to=julien.grall@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xenproject.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).