All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
To: <xen-devel@lists.xenproject.org>
Cc: <sstabellini@kernel.org>, <stefanos@xilinx.com>, <julien@xen.org>,
	<Volodymyr_Babchuk@epam.com>, <bertrand.marquis@arm.com>,
	<michal.orzel@amd.com>, <jgrall@amazon.com>,
	<burzalodowa@gmail.com>,
	"Ayan Kumar Halder" <ayan.kumar.halder@amd.com>
Subject: [XEN v5 10/11] xen/Arm: GICv3: Define macros to read/write 64 bit
Date: Mon, 5 Dec 2022 13:26:36 +0000	[thread overview]
Message-ID: <20221205132637.26775-11-ayan.kumar.halder@amd.com> (raw)
In-Reply-To: <20221205132637.26775-1-ayan.kumar.halder@amd.com>

On AArch32, ldrd/strd instructions are not atomic when used to access MMIO.
Furthermore, ldrd/strd instructions are not decoded by Arm when running as
a guest to access emulated MMIO region.
Thus, we have defined readq_relaxed_non_atomic()/writeq_relaxed_non_atomic()
which in turn calls readl_relaxed()/writel_relaxed() for the lower and upper
32 bits.
For AArch64, readq_relaxed_non_atomic()/writeq_relaxed_non_atomic() invokes
readq_relaxed()/writeq_relaxed() respectively.
As GICv3 registers (GICD_IROUTER, GICR_TYPER) can be accessed in a non atomic
manner, so we have used readq_relaxed_non_atomic()/readq_relaxed_non_atomic().

However, the following points are noted for the non atomic access :-
1. In gicv3_dist_init(), using non atomic write on GICD_IROUTER is fine as this
gets invoked when interrupts are disabled.
2. In gicv3_populate_rdist(), using non atomic read on GICR_TYPER is fine as
the register is read and the interrupts are disabled as well.
3. In gicv3_irq_set_affinity(), using non atomic write on GICD_IROUTER. This
may be called with interrupts enabled. So, a non-atomic access (on AArch32)
means the GIC will see a transient value when only one of two 32-bit will be
updated. However, only AFF3 is defined in the upper 32 bits and they are 0, so
this will never change.
On AArch64, writeq_relaxed_non_atomic() invokes writeq_relaxed() (which is
atomic), so this problem does not arise.

Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
---

Changes from :-
v1 - 1. Use ldrd/strd for readq_relaxed()/writeq_relaxed().
2. No need to use le64_to_cpu() as the returned byte order is already in cpu
endianess.

v2 - 1. Replace {read/write}q_relaxed with {read/write}q_relaxed_non_atomic().

v3 - 1. Use inline function definitions for {read/write}q_relaxed_non_atomic().
2. For AArch64, {read/write}q_relaxed_non_atomic() should invoke {read/write}q_relaxed().
Thus, we can avoid any ifdef in gic-v3.c.

v4 - 1. Updated the commit message.

 xen/arch/arm/gic-v3.c               |  6 +++---
 xen/arch/arm/include/asm/arm32/io.h | 20 ++++++++++++++++++++
 xen/arch/arm/include/asm/arm64/io.h |  2 ++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 6457e7033c..3c5b88148c 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -651,7 +651,7 @@ static void __init gicv3_dist_init(void)
     affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
 
     for ( i = NR_GIC_LOCAL_IRQS; i < nr_lines; i++ )
-        writeq_relaxed(affinity, GICD + GICD_IROUTER + i * 8);
+        writeq_relaxed_non_atomic(affinity, GICD + GICD_IROUTER + i * 8);
 }
 
 static int gicv3_enable_redist(void)
@@ -745,7 +745,7 @@ static int __init gicv3_populate_rdist(void)
         }
 
         do {
-            typer = readq_relaxed(ptr + GICR_TYPER);
+            typer = readq_relaxed_non_atomic(ptr + GICR_TYPER);
 
             if ( (typer >> 32) == aff )
             {
@@ -1265,7 +1265,7 @@ static void gicv3_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
     affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
 
     if ( desc->irq >= NR_GIC_LOCAL_IRQS )
-        writeq_relaxed(affinity, (GICD + GICD_IROUTER + desc->irq * 8));
+        writeq_relaxed_non_atomic(affinity, (GICD + GICD_IROUTER + desc->irq * 8));
 
     spin_unlock(&gicv3.lock);
 }
diff --git a/xen/arch/arm/include/asm/arm32/io.h b/xen/arch/arm/include/asm/arm32/io.h
index 73a879e9fb..782b564809 100644
--- a/xen/arch/arm/include/asm/arm32/io.h
+++ b/xen/arch/arm/include/asm/arm32/io.h
@@ -80,10 +80,30 @@ static inline u32 __raw_readl(const volatile void __iomem *addr)
                                         __raw_readw(c)); __r; })
 #define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
                                         __raw_readl(c)); __r; })
+/*
+ * ldrd instructions are not decoded by Arm when running as a guest to access
+ * emulated MMIO region. Thus, readq_relaxed_non_atomic() invokes readl_relaxed()
+ * twice to read the lower and upper 32 bits.
+ */
+static inline u64 readq_relaxed_non_atomic(const volatile void __iomem *addr)
+{
+        u64 val = (((u64)readl_relaxed(addr + 4)) << 32) | readl_relaxed(addr);
+        return val;
+}
 
 #define writeb_relaxed(v,c)     __raw_writeb(v,c)
 #define writew_relaxed(v,c)     __raw_writew((__force u16) cpu_to_le16(v),c)
 #define writel_relaxed(v,c)     __raw_writel((__force u32) cpu_to_le32(v),c)
+/*
+ * strd instructions are not decoded by Arm when running as a guest to access
+ * emulated MMIO region. Thus, writeq_relaxed_non_atomic() invokes writel_relaxed()
+ * twice to write the lower and upper 32 bits.
+ */
+static inline void writeq_relaxed_non_atomic(u64 val, volatile void __iomem *addr)
+{
+        writel_relaxed((u32)val, addr);
+        writel_relaxed((u32)(val >> 32), addr + 4);
+}
 
 #define readb(c)                ({ u8  __v = readb_relaxed(c); __iormb(); __v; })
 #define readw(c)                ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
diff --git a/xen/arch/arm/include/asm/arm64/io.h b/xen/arch/arm/include/asm/arm64/io.h
index 30bfc78d9e..2e2ab24f78 100644
--- a/xen/arch/arm/include/asm/arm64/io.h
+++ b/xen/arch/arm/include/asm/arm64/io.h
@@ -102,11 +102,13 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 #define readw_relaxed(c)        ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; })
 #define readl_relaxed(c)        ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; })
 #define readq_relaxed(c)        ({ u64 __v = le64_to_cpu((__force __le64)__raw_readq(c)); __v; })
+#define readq_relaxed_non_atomic(c)           readq_relaxed(c)
 
 #define writeb_relaxed(v,c)     ((void)__raw_writeb((v),(c)))
 #define writew_relaxed(v,c)     ((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
 #define writel_relaxed(v,c)     ((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
 #define writeq_relaxed(v,c)     ((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
+#define writeq_relaxed_non_atomic(v,c)        writeq_relaxed(v,c)
 
 /*
  * I/O memory access primitives. Reads are ordered relative to any
-- 
2.17.1



  parent reply	other threads:[~2022-12-05 14:53 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-05 13:26 [XEN v5 00/11] Arm: Enable GICv3 for AArch32 Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 01/11] xen/Arm: vGICv3: Sysreg emulation is applicable for AArch64 only Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 02/11] xen/Arm: GICv3: Do not calculate affinity level 3 for AArch32 Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 03/11] xen/Arm: vreg: Support vreg_reg64_* helpers on AArch32 Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 04/11] xen/Arm: vGICv3: Adapt emulation of GICR_TYPER for AArch32 Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 05/11] xen/Arm: GICv3: Fix GICR_{PENDBASER, PROPBASER} emulation on 32-bit host Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 06/11] xen/Arm: vGICv3: Fix emulation of ICC_SGI1R on AArch32 Ayan Kumar Halder
2022-12-05 13:26 ` [XEN v5 07/11] xen/Arm: GICv3: Define ICH_LR<n>_EL2 " Ayan Kumar Halder
2022-12-13 21:21   ` Julien Grall
2022-12-05 13:26 ` [XEN v5 08/11] xen/Arm: GICv3: Define ICH_AP0R<n> and ICH_AP1R<n> for AArch32 Ayan Kumar Halder
2022-12-13 21:21   ` Julien Grall
2022-12-05 13:26 ` [XEN v5 09/11] xen/Arm: GICv3: Define remaining GIC registers " Ayan Kumar Halder
2022-12-13 21:22   ` Julien Grall
2022-12-05 13:26 ` Ayan Kumar Halder [this message]
2022-12-13 21:24   ` [XEN v5 10/11] xen/Arm: GICv3: Define macros to read/write 64 bit Julien Grall
2022-12-05 13:26 ` [XEN v5 11/11] xen/Arm: GICv3: Enable GICv3 for AArch32 Ayan Kumar Halder
2022-12-13 21:26   ` Julien Grall
2022-12-15 11:28 ` [XEN v5 00/11] Arm: " 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=20221205132637.26775-11-ayan.kumar.halder@amd.com \
    --to=ayan.kumar.halder@amd.com \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=bertrand.marquis@arm.com \
    --cc=burzalodowa@gmail.com \
    --cc=jgrall@amazon.com \
    --cc=julien@xen.org \
    --cc=michal.orzel@amd.com \
    --cc=sstabellini@kernel.org \
    --cc=stefanos@xilinx.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.