From: Julien Grall <julien.grall@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Julien Grall <julien.grall@citrix.com>,
linux-kernel@vger.kernel.org, ian.campbell@citrix.com,
linux-arm-kernel@lists.infradead.org,
stefano.stabellini@eu.citrix.com
Subject: [PATCH v1 3/8] xen/arm: Support sign-extension for every read access
Date: Fri, 25 Sep 2015 15:51:02 +0100 [thread overview]
Message-ID: <1443192667-16112-4-git-send-email-julien.grall@citrix.com> (raw)
In-Reply-To: <1443192667-16112-1-git-send-email-julien.grall@citrix.com>
The guest may try to load data from the emulated MMIO region using
instruction with Sign-Extension (i.e ldrs*). This can happen for any
access smaller than the register size (byte/half-word for aarch32,
byte/half-word/word for aarch64).
The support of sign-extension was limited for byte access in vGIG
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>
---
I was thinking to completely drop the sign-extension support in Xen as
it will be very unlikely to use ldrs* instruction to access MMIO.
Although the code is fairly small, so it doesn't harm to keep it
generically.
Changes in v2:
- Patch added
---
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 32b2194..e1b03a2 100644
--- a/xen/arch/arm/io.c
+++ b/xen/arch/arm/io.c
@@ -23,6 +23,32 @@
#include <asm/current.h>
#include <asm/mmio.h>
+static int handle_read(mmio_read_t read_cb, struct vcpu *v,
+ mmio_info_t *info, register_t *r)
+{
+ uint8_t size = (1 << info->dabt.size) * 8;
+
+ if ( !read_cb(v, info, r) )
+ return 0;
+
+ /*
+ * Extend the bit sign if required.
+ * Note that we expect the read handler to have zeroed the bit
+ * unused in the register.
+ */
+ if ( info->dabt.sign && (*r & (1UL << (size - 1)) ))
+ {
+ /*
+ * We are relying on register_t as the same size as
+ * an unsigned long or order to keep the 32bit some 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 +74,8 @@ found:
if ( info->dabt.write )
return mmio_handler->mmio_handler_ops->write_handler(v, info, *r);
else
- return mmio_handler->mmio_handler_ops->read_handler(v, info, r);
+ return handle_read(mmio_handler->mmio_handler_ops->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 3d0ce1d..47f9da9 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 94f1a5c..c013200 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:
@@ -1062,7 +1062,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
next prev parent reply other threads:[~2015-09-25 14:52 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1443192667-16112-1-git-send-email-julien.grall@citrix.com>
2015-09-25 14:51 ` [PATCH v1 1/8] xen/arm: io: remove mmio_check_t typedef Julien Grall
2015-09-25 14:51 ` [PATCH v1 2/8] xen/arm: io: Extend write/read handler to pass the register in parameter Julien Grall
2015-09-25 14:51 ` Julien Grall [this message]
2015-09-25 14:51 ` [PATCH v1 4/8] xen/arm: vgic: ctlr stores a 32-bit hardware register so use uint32_t Julien Grall
2015-09-25 14:51 ` [PATCH v1 5/8] xen/arm: vgic: Optimize the way to store GICD_IPRIORITYR in the rank Julien Grall
2015-09-25 14:51 ` [PATCH v1 6/8] xen/arm: vgic: Optimize the way to store the target vCPU " Julien Grall
2015-09-25 14:51 ` [PATCH v1 7/8] xen/arm: vgic: Introduce helpers to read/write/clear/set vGIC register Julien Grall
2015-09-25 14:51 ` [PATCH v1 8/8] xen/arm: vgic-v3: Support 32-bit access for 64-bit registers Julien Grall
2015-09-25 14:52 ` [PATCH v1 0/8] xen/arm: vgic: Support 32-bit access for 64-bit register Julien Grall
2015-09-25 14:51 Julien Grall
2015-09-25 14:51 ` [PATCH v1 3/8] xen/arm: Support sign-extension for every read access Julien Grall
2015-09-25 16:44 ` Ian Campbell
2015-09-28 16:42 ` Julien Grall
2015-09-29 11:01 ` Ian Campbell
2015-09-29 11:07 ` Julien Grall
2015-09-28 18:22 ` Julien Grall
2015-09-29 11:03 ` Ian Campbell
2015-09-29 11:13 ` Julien Grall
2015-09-29 13:13 ` Ian Campbell
2015-09-29 13:16 ` Julien Grall
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=1443192667-16112-4-git-send-email-julien.grall@citrix.com \
--to=julien.grall@citrix.com \
--cc=ian.campbell@citrix.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--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).