From mboxrd@z Thu Jan 1 00:00:00 1970 From: Julien Grall Subject: [PATCH for 4.6] xen/arm: vgic: Correctly emulate write when byte is used Date: Tue, 22 Sep 2015 21:18:48 +0100 Message-ID: <1442953128-4669-1-git-send-email-julien.grall@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1ZeU2q-0005wY-Kl for xen-devel@lists.xenproject.org; Tue, 22 Sep 2015 20:20:08 +0000 List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xenproject.org Cc: Julien Grall , Wei.Liu2@citrix.com, stefano.stabellini@citrix.com, ian.campbell@citrix.com List-Id: xen-devel@lists.xenproject.org When a guest is writing a byte, the value will be located in bits[7:0] of the register. Although the current implementation is expecting the byte at the Nth byte of the register where N = address & 4; When the address is not 4-byte aligned, the corresponding byte in the internal state will always be set to zero rather. Note that byte access are only used for GICD_IPRIORITYR and GICD_ITARGETSR. So the worst things that could happen is not setting the priority correctly and ignore the target vCPU written. Signed-off-by: Julien Grall --- This patch is a candidate for Xen 4.6 and backport to Xen 4.5 and Xen 4.4. Without it, write a byte to a register won't work as expected. Spotted while doing some test on the vGICv2 driver. FWIW, Linux doesn't use byte access in both GICv3 and GICv2 driver. Note that Xen 4.4 will require a different patch because the function was living in vgic.c at that time. --- xen/include/asm-arm/vgic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 41cadb1..96839f0 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -174,10 +174,10 @@ static inline void vgic_byte_write(uint32_t *reg, uint32_t var, int offset) { int byte = offset & 0x3; - var &= (0xff << (8*byte)); + var &= 0xff; *reg &= ~(0xff << (8*byte)); - *reg |= var; + *reg |= (var << (8*byte)); } enum gic_sgi_mode; -- 2.1.4