All of lore.kernel.org
 help / color / mirror / Atom feed
* [XEN v2 00/11] Add support for 32 bit physical address
@ 2023-01-17 17:43 Ayan Kumar Halder
  2023-01-17 17:43 ` [XEN v2 01/11] xen/ns16550: Remove unneeded truncation check in the DT init code Ayan Kumar Halder
                   ` (11 more replies)
  0 siblings, 12 replies; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

Hi All,

Please have a look at https://lists.xenproject.org/archives/html/xen-devel/2022-11/msg01465.html
for the context.

The benefits of using 32 bit physical addresses are as follows :-

1. It helps to use Xen on platforms (for eg R52) which supports 32 bit
physical addresses and has no support for large page address extension.
On 32 bit MPU systems which supports flat-mapping (for eg R52), it helps
to translate 32 bit VA into 32 bit PA.

2. It also helps in code optimization when the underlying platform does not
use large page address extension.


The following points are to be noted :-
1. Device tree always use u64 for address and size. The caller needs to
translate between u64 and u32 (when 32 bit physical addressing is used).
2. Currently, we have enabled this option for Arm_32 as the MMU for Arm_64
uses 48 bit physical addressing.
3. https://lists.xenproject.org/archives/html/xen-devel/2022-12/msg00117.html
has been added to this series.

Changes from :

v1 - 1. Reordered the patches such that the first three patches fixes issues in
the existing codebase. These can be applied independent of the remaining patches
in this serie,

2. Dropped translate_dt_address_size() for the address/size translation between
paddr_t and u64 (as parsed from the device tree). Also, dropped the check for
truncation (while converting u64 to paddr_t).
Instead now we have modified device_tree_get_reg() and typecasted the return for
dt_read_number(), to obtain paddr_t. Also, introduced wrappers for
fdt_get_mem_rsv() and dt_device_get_address() for the same purpose. These can be
found in patch 4/11 and patch 6/11.

3. Split "Other adaptations required to support 32bit paddr" into the following
individual patches for each adaptation :
  xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to
    SMMU_CBn_TTBR0
  xen/arm: guest_walk: LPAE specific bits should be enclosed within
    "ifndef CONFIG_ARM_PA_32"

4. Introduced "xen/arm: p2m: Enable support for 32bit IPA".

Ayan Kumar Halder (11):
  xen/ns16550: Remove unneeded truncation check in the DT init code
  xen/arm: Use the correct format specifier
  xen/arm: domain_build: Replace use of paddr_t in find_domU_holes()
  xen/arm: Typecast the DT values into paddr_t
  xen/arm: Use paddr_t instead of u64 for address/size
  xen/arm: Introduce a wrapper for dt_device_get_address() to handle
    paddr_t
  xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to
    SMMU_CBn_TTBR0
  xen/arm: guest_walk: LPAE specific bits should be enclosed within
    "ifndef CONFIG_ARM_PA_32"
  xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  xen/arm: Restrict zeroeth_table_offset for ARM_64
  xen/arm: p2m: Enable support for 32bit IPA

 xen/arch/arm/Kconfig                   |  9 ++++
 xen/arch/arm/bootfdt.c                 | 23 ++++++----
 xen/arch/arm/domain_build.c            | 32 +++++++-------
 xen/arch/arm/gic-v2.c                  | 17 ++++----
 xen/arch/arm/gic-v3.c                  | 11 ++---
 xen/arch/arm/guest_walk.c              |  2 +
 xen/arch/arm/include/asm/device_tree.h | 59 ++++++++++++++++++++++++++
 xen/arch/arm/include/asm/lpae.h        |  4 ++
 xen/arch/arm/include/asm/page-bits.h   |  2 +
 xen/arch/arm/include/asm/setup.h       |  2 +-
 xen/arch/arm/include/asm/types.h       |  7 +++
 xen/arch/arm/mm.c                      |  9 +---
 xen/arch/arm/p2m.c                     | 10 +++--
 xen/arch/arm/platforms/exynos5.c       | 33 +++++++-------
 xen/arch/arm/platforms/sunxi.c         |  3 +-
 xen/arch/arm/setup.c                   | 14 +++---
 xen/arch/arm/smpboot.c                 |  2 +-
 xen/drivers/char/exynos4210-uart.c     |  5 ++-
 xen/drivers/char/ns16550.c             | 16 +++----
 xen/drivers/char/omap-uart.c           |  5 ++-
 xen/drivers/char/pl011.c               |  7 +--
 xen/drivers/char/scif-uart.c           |  5 ++-
 xen/drivers/passthrough/arm/smmu.c     | 24 ++++++-----
 23 files changed, 199 insertions(+), 102 deletions(-)
 create mode 100644 xen/arch/arm/include/asm/device_tree.h

-- 
2.17.1



^ permalink raw reply	[flat|nested] 64+ messages in thread

* [XEN v2 01/11] xen/ns16550: Remove unneeded truncation check in the DT init code
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-17 17:43 ` [XEN v2 02/11] xen/arm: Use the correct format specifier Ayan Kumar Halder
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

In an earlier commit (7c1de0038895), "ns16550.io_size" was u32 and
"io_size" was u64. Thus, the ASSERT() was needed to check if the values
are the same.
However, in a later commit (c9f8e0aee507), "ns16550.io_size" was changed
to u64. Thus, the ASSERT() became redundant.

So, now as "io_size" and "uart->io_size" are both u64, there will be no
truncation. Thus, one can remove the ASSERT() and extra assignment.

Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---

Changes from :

v1 - 1. Updated commit message/title.
2. Added Rb.

 xen/drivers/char/ns16550.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 01a05c9aa8..58d0ccd889 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -1747,7 +1747,6 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
     struct ns16550 *uart;
     int res;
     u32 reg_shift, reg_width;
-    u64 io_size;
 
     uart = &ns16550_com[0];
 
@@ -1758,14 +1757,10 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
     uart->parity    = UART_PARITY_NONE;
     uart->stop_bits = 1;
 
-    res = dt_device_get_address(dev, 0, &uart->io_base, &io_size);
+    res = dt_device_get_address(dev, 0, &uart->io_base, &uart->io_size);
     if ( res )
         return res;
 
-    uart->io_size = io_size;
-
-    ASSERT(uart->io_size == io_size); /* Detect truncation */
-
     res = dt_property_read_u32(dev, "reg-shift", &reg_shift);
     if ( !res )
         uart->reg_shift = 0;
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
  2023-01-17 17:43 ` [XEN v2 01/11] xen/ns16550: Remove unneeded truncation check in the DT init code Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-19 22:54   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes() Ayan Kumar Halder
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

1. One should use 'PRIpaddr' to display 'paddr_t' variables.
2. One should use 'PRIx64' to display 'u64' in hex format. The current
use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
address.

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

Changes from -

v1 - 1. Moved the patch earlier.
2. Moved a part of change from "[XEN v1 8/9] xen/arm: Other adaptations required to support 32bit paddr"
into this patch.

 xen/arch/arm/domain_build.c | 10 +++++-----
 xen/arch/arm/gic-v2.c       |  6 +++---
 xen/arch/arm/mm.c           |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 829cea8de8..33a5945a2d 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1315,7 +1315,7 @@ static int __init make_memory_node(const struct domain *d,
     dt_dprintk("Create memory node\n");
 
     /* ePAPR 3.4 */
-    snprintf(buf, sizeof(buf), "memory@%"PRIx64, mem->bank[i].start);
+    snprintf(buf, sizeof(buf), "memory@%"PRIpaddr, mem->bank[i].start);
     res = fdt_begin_node(fdt, buf);
     if ( res )
         return res;
@@ -1383,7 +1383,7 @@ static int __init make_shm_memory_node(const struct domain *d,
         __be32 *cells;
         unsigned int len = (addrcells + sizecells) * sizeof(__be32);
 
-        snprintf(buf, sizeof(buf), "xen-shmem@%"PRIx64, mem->bank[i].start);
+        snprintf(buf, sizeof(buf), "xen-shmem@%"PRIpaddr, mem->bank[i].start);
         res = fdt_begin_node(fdt, buf);
         if ( res )
             return res;
@@ -2719,7 +2719,7 @@ static int __init make_gicv2_domU_node(struct kernel_info *kinfo)
     /* Placeholder for interrupt-controller@ + a 64-bit number + \0 */
     char buf[38];
 
-    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIx64,
+    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIpaddr,
              vgic_dist_base(&d->arch.vgic));
     res = fdt_begin_node(fdt, buf);
     if ( res )
@@ -2775,7 +2775,7 @@ static int __init make_gicv3_domU_node(struct kernel_info *kinfo)
     char buf[38];
     unsigned int i, len = 0;
 
-    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIx64,
+    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIpaddr,
              vgic_dist_base(&d->arch.vgic));
 
     res = fdt_begin_node(fdt, buf);
@@ -2861,7 +2861,7 @@ static int __init make_vpl011_uart_node(struct kernel_info *kinfo)
     /* Placeholder for sbsa-uart@ + a 64-bit number + \0 */
     char buf[27];
 
-    snprintf(buf, sizeof(buf), "sbsa-uart@%"PRIx64, d->arch.vpl011.base_addr);
+    snprintf(buf, sizeof(buf), "sbsa-uart@%"PRIpaddr, d->arch.vpl011.base_addr);
     res = fdt_begin_node(fdt, buf);
     if ( res )
         return res;
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 61802839cb..5d4d298b86 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -1049,7 +1049,7 @@ static void __init gicv2_dt_init(void)
     if ( csize < SZ_8K )
     {
         printk(XENLOG_WARNING "GICv2: WARNING: "
-               "The GICC size is too small: %#"PRIx64" expected %#x\n",
+               "The GICC size is too small: %#"PRIpaddr" expected %#x\n",
                csize, SZ_8K);
         if ( platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
         {
@@ -1280,11 +1280,11 @@ static int __init gicv2_init(void)
         gicv2.map_cbase += aliased_offset;
 
         printk(XENLOG_WARNING
-               "GICv2: Adjusting CPU interface base to %#"PRIx64"\n",
+               "GICv2: Adjusting CPU interface base to %#"PRIpaddr"\n",
                cbase + aliased_offset);
     } else if ( csize == SZ_128K )
         printk(XENLOG_WARNING
-               "GICv2: GICC size=%#"PRIx64" but not aliased\n",
+               "GICv2: GICC size=%#"PRIpaddr" but not aliased\n",
                csize);
 
     gicv2.map_hbase = ioremap_nocache(hbase, PAGE_SIZE);
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 0fc6f2992d..fab54618ab 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -249,7 +249,7 @@ void dump_pt_walk(paddr_t ttbr, paddr_t addr,
 
         pte = mapping[offsets[level]];
 
-        printk("%s[0x%03x] = 0x%"PRIpaddr"\n",
+        printk("%s[0x%03x] = 0x%"PRIx64"\n",
                level_strs[level], offsets[level], pte.bits);
 
         if ( level == 3 || !pte.walk.valid || !pte.walk.table )
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes()
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
  2023-01-17 17:43 ` [XEN v2 01/11] xen/ns16550: Remove unneeded truncation check in the DT init code Ayan Kumar Halder
  2023-01-17 17:43 ` [XEN v2 02/11] xen/arm: Use the correct format specifier Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-19 23:02   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t Ayan Kumar Halder
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

bankbase, banksize and bankend are used to hold values of type 'unsigned
long long'. This can be represented as 'uint64_t' instead of 'paddr_t'.
This will ensure consistency with allocate_static_memory() (where we use
'uint64_t' for rambase and ramsize).

In future, paddr_t can be used for 'uin32_t' as well to represent 32bit
physical addresses.

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

Changes from -

v1 - Modified the title/commit message from "[XEN v1 6/9] xen/arm: Use 'u64' to represent 'unsigned long long"
and moved it earlier.

 xen/arch/arm/domain_build.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 33a5945a2d..f904f12408 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1726,9 +1726,9 @@ static int __init find_domU_holes(const struct kernel_info *kinfo,
                                   struct meminfo *ext_regions)
 {
     unsigned int i;
-    paddr_t bankend;
-    const paddr_t bankbase[] = GUEST_RAM_BANK_BASES;
-    const paddr_t banksize[] = GUEST_RAM_BANK_SIZES;
+    uint64_t bankend;
+    const uint64_t bankbase[] = GUEST_RAM_BANK_BASES;
+    const uint64_t banksize[] = GUEST_RAM_BANK_SIZES;
     int res = -ENOENT;
 
     for ( i = 0; i < GUEST_RAM_BANKS; i++ )
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (2 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes() Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-19 23:20   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size Ayan Kumar Halder
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

In future, we wish to support 32 bit physical address.
However, one can only read u64 values from the DT. Thus, we need to
typecast the values appropriately from u64 to paddr_t.

device_tree_get_reg() should now be able to return paddr_t. This is
invoked by various callers to get DT address and size.
Similarly, dt_read_number() is invoked as well to get DT address and
size. The return value is typecasted to paddr_t.
fdt_get_mem_rsv() can only accept u64 values. So, we provide a warpper
for this called fdt_get_mem_rsv_paddr() which will do the necessary
typecasting before invoking fdt_get_mem_rsv() and while returning.

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

Changes from

v1 - 1. Dropped "[XEN v1 2/9] xen/arm: Define translate_dt_address_size() for the translation between u64 and paddr_t" and
"[XEN v1 4/9] xen/arm: Use translate_dt_address_size() to translate between device tree addr/size and paddr_t", instead
this approach achieves the same purpose.

2. No need to check for truncation while converting values from u64 to paddr_t.

 xen/arch/arm/bootfdt.c                 | 23 +++++++++------
 xen/arch/arm/domain_build.c            |  2 +-
 xen/arch/arm/include/asm/device_tree.h | 40 ++++++++++++++++++++++++++
 xen/arch/arm/include/asm/setup.h       |  2 +-
 xen/arch/arm/setup.c                   | 14 ++++-----
 xen/arch/arm/smpboot.c                 |  2 +-
 6 files changed, 65 insertions(+), 18 deletions(-)
 create mode 100644 xen/arch/arm/include/asm/device_tree.h

diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 0085c28d74..f536a3f3ab 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -11,9 +11,9 @@
 #include <xen/efi.h>
 #include <xen/device_tree.h>
 #include <xen/lib.h>
-#include <xen/libfdt/libfdt.h>
 #include <xen/sort.h>
 #include <xsm/xsm.h>
+#include <asm/device_tree.h>
 #include <asm/setup.h>
 
 static bool __init device_tree_node_matches(const void *fdt, int node,
@@ -53,10 +53,15 @@ static bool __init device_tree_node_compatible(const void *fdt, int node,
 }
 
 void __init device_tree_get_reg(const __be32 **cell, u32 address_cells,
-                                u32 size_cells, u64 *start, u64 *size)
+                                u32 size_cells, paddr_t *start, paddr_t *size)
 {
-    *start = dt_next_cell(address_cells, cell);
-    *size = dt_next_cell(size_cells, cell);
+    /*
+     * dt_next_cell will return u64 whereas paddr_t may be u64 or u32. Thus, one
+     * needs to cast paddr_t to u32. Note that we do not check for truncation as
+     * it is user's responsibility to provide the correct values in the DT.
+     */
+    *start = (paddr_t) dt_next_cell(address_cells, cell);
+    *size = (paddr_t) dt_next_cell(size_cells, cell);
 }
 
 static int __init device_tree_get_meminfo(const void *fdt, int node,
@@ -326,7 +331,7 @@ static int __init process_chosen_node(const void *fdt, int node,
         printk("linux,initrd-start property has invalid length %d\n", len);
         return -EINVAL;
     }
-    start = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
+    start = (paddr_t) dt_read_number((void *)&prop->data, dt_size_to_cells(len));
 
     prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
     if ( !prop )
@@ -339,7 +344,7 @@ static int __init process_chosen_node(const void *fdt, int node,
         printk("linux,initrd-end property has invalid length %d\n", len);
         return -EINVAL;
     }
-    end = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
+    end = (paddr_t) dt_read_number((void *)&prop->data, dt_size_to_cells(len));
 
     if ( start >= end )
     {
@@ -594,9 +599,11 @@ static void __init early_print_info(void)
     for ( i = 0; i < nr_rsvd; i++ )
     {
         paddr_t s, e;
-        if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 )
+
+        if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &s, &e) < 0 )
             continue;
-        /* fdt_get_mem_rsv returns length */
+
+        /* fdt_get_mem_rsv_paddr returns length */
         e += s;
         printk(" RESVD[%u]: %"PRIpaddr" - %"PRIpaddr"\n", i, s, e);
     }
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index f904f12408..72b9afbb4c 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -949,7 +949,7 @@ static int __init process_shm(struct domain *d, struct kernel_info *kinfo,
         BUG_ON(!prop);
         cells = (const __be32 *)prop->value;
         device_tree_get_reg(&cells, addr_cells, addr_cells, &pbase, &gbase);
-        psize = dt_read_number(cells, size_cells);
+        psize = (paddr_t) dt_read_number(cells, size_cells);
         if ( !IS_ALIGNED(pbase, PAGE_SIZE) || !IS_ALIGNED(gbase, PAGE_SIZE) )
         {
             printk("%pd: physical address 0x%"PRIpaddr", or guest address 0x%"PRIpaddr" is not suitably aligned.\n",
diff --git a/xen/arch/arm/include/asm/device_tree.h b/xen/arch/arm/include/asm/device_tree.h
new file mode 100644
index 0000000000..51e0f0ae20
--- /dev/null
+++ b/xen/arch/arm/include/asm/device_tree.h
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * xen/arch/arm/include/asm/device_tree.h
+ * 
+ * Wrapper functions for device tree. This helps to convert dt values
+ * between u64 and paddr_t.
+ *
+ * Copyright (C) 2023, Advanced Micro Devices, Inc. All Rights Reserved.
+ */
+
+#ifndef __ARCH_ARM_DEVICE_TREE__
+#define __ARCH_ARM_DEVICE_TREE__
+
+#include <xen/libfdt/libfdt.h>
+
+inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
+                                 paddr_t *address,
+                                 paddr_t *size)
+{
+    uint64_t dt_addr;
+    uint64_t dt_size;
+    int ret = 0;
+
+    ret = fdt_get_mem_rsv(fdt, n, &dt_addr, &dt_size);
+
+    *address = (paddr_t) dt_addr;
+    *size = (paddr_t) dt_size;
+
+    return ret;
+}
+
+#endif /* __ARCH_ARM_DEVICE_TREE__ */
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index a926f30a2b..6105e5cae3 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -158,7 +158,7 @@ extern uint32_t hyp_traps_vector[];
 void init_traps(void);
 
 void device_tree_get_reg(const __be32 **cell, u32 address_cells,
-                         u32 size_cells, u64 *start, u64 *size);
+                         u32 size_cells, paddr_t *start, paddr_t *size);
 
 u32 device_tree_get_u32(const void *fdt, int node,
                         const char *prop_name, u32 dflt);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 1f26f67b90..da13439e62 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -29,7 +29,6 @@
 #include <xen/virtual_region.h>
 #include <xen/vmap.h>
 #include <xen/trace.h>
-#include <xen/libfdt/libfdt.h>
 #include <xen/acpi.h>
 #include <xen/warning.h>
 #include <asm/alternative.h>
@@ -39,6 +38,7 @@
 #include <asm/gic.h>
 #include <asm/cpuerrata.h>
 #include <asm/cpufeature.h>
+#include <asm/device_tree.h>
 #include <asm/platform.h>
 #include <asm/procinfo.h>
 #include <asm/setup.h>
@@ -222,11 +222,11 @@ static void __init dt_unreserved_regions(paddr_t s, paddr_t e,
     {
         paddr_t r_s, r_e;
 
-        if ( fdt_get_mem_rsv(device_tree_flattened, i, &r_s, &r_e ) < 0 )
+        if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &r_s, &r_e ) < 0 )
             /* If we can't read it, pretend it doesn't exist... */
             continue;
 
-        r_e += r_s; /* fdt_get_mem_rsv returns length */
+        r_e += r_s; /* fdt_get_mem_rsv_paddr returns length */
 
         if ( s < r_e && r_s < e )
         {
@@ -502,13 +502,13 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e,
     {
         paddr_t mod_s, mod_e;
 
-        if ( fdt_get_mem_rsv(device_tree_flattened,
-                             i - mi->nr_mods,
-                             &mod_s, &mod_e ) < 0 )
+        if ( fdt_get_mem_rsv_paddr(device_tree_flattened,
+                                   i - mi->nr_mods,
+                                   &mod_s, &mod_e ) < 0 )
             /* If we can't read it, pretend it doesn't exist... */
             continue;
 
-        /* fdt_get_mem_rsv returns length */
+        /* fdt_get_mem_rsv_paddr returns length */
         mod_e += mod_s;
 
         if ( s < mod_e && mod_s < e )
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index 412ae22869..ee59b1d379 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -159,7 +159,7 @@ static void __init dt_smp_init_cpus(void)
             continue;
         }
 
-        addr = dt_read_number(prop, dt_n_addr_cells(cpu));
+        addr = (paddr_t) dt_read_number(prop, dt_n_addr_cells(cpu));
 
         hwid = addr;
         if ( hwid != addr )
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (3 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-18  8:40   ` Jan Beulich
                     ` (2 more replies)
  2023-01-17 17:43 ` [XEN v2 06/11] xen/arm: Introduce a wrapper for dt_device_get_address() to handle paddr_t Ayan Kumar Halder
                   ` (6 subsequent siblings)
  11 siblings, 3 replies; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

One should now be able to use 'paddr_t' to represent address and size.
Consequently, one should use 'PRIpaddr' as a format specifier for paddr_t.

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

Changes from -

v1 - 1. Rebased the patch.

 xen/arch/arm/domain_build.c        |  9 +++++----
 xen/arch/arm/gic-v3.c              |  2 +-
 xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
 xen/drivers/char/exynos4210-uart.c |  2 +-
 xen/drivers/char/ns16550.c         |  8 ++++----
 xen/drivers/char/omap-uart.c       |  2 +-
 xen/drivers/char/pl011.c           |  4 ++--
 xen/drivers/char/scif-uart.c       |  2 +-
 xen/drivers/passthrough/arm/smmu.c |  6 +++---
 9 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 72b9afbb4c..cf8ae37a14 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
     dt_for_each_device_node( dt_host, np )
     {
         unsigned int naddr;
-        u64 addr, size;
+        paddr_t addr, size;
 
         naddr = dt_number_of_address(np);
 
@@ -2445,7 +2445,7 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev,
     unsigned int naddr;
     unsigned int i;
     int res;
-    u64 addr, size;
+    paddr_t addr, size;
     bool own_device = !dt_device_for_passthrough(dev);
     /*
      * We want to avoid mapping the MMIO in dom0 for the following cases:
@@ -2941,9 +2941,10 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
         if ( res )
         {
             printk(XENLOG_ERR "Unable to permit to dom%d access to"
-                   " 0x%"PRIx64" - 0x%"PRIx64"\n",
+                   " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
                    kinfo->d->domain_id,
-                   mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1);
+                   (paddr_t) (mstart & PAGE_MASK),
+                   (paddr_t) (PAGE_ALIGN(mstart + size) - 1));
             return res;
         }
 
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index bb59ea94cd..391dfa53d7 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -1393,7 +1393,7 @@ static void __init gicv3_dt_init(void)
 
     for ( i = 0; i < gicv3.rdist_count; i++ )
     {
-        uint64_t rdist_base, rdist_size;
+        paddr_t rdist_base, rdist_size;
 
         res = dt_device_get_address(node, 1 + i, &rdist_base, &rdist_size);
         if ( res )
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index 6560507092..f79fad9957 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -42,8 +42,8 @@ static int exynos5_init_time(void)
     void __iomem *mct;
     int rc;
     struct dt_device_node *node;
-    u64 mct_base_addr;
-    u64 size;
+    paddr_t mct_base_addr;
+    paddr_t size;
 
     node = dt_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct");
     if ( !node )
@@ -59,7 +59,7 @@ static int exynos5_init_time(void)
         return -ENXIO;
     }
 
-    dprintk(XENLOG_INFO, "mct_base_addr: %016llx size: %016llx\n",
+    dprintk(XENLOG_INFO, "mct_base_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"\n",
             mct_base_addr, size);
 
     mct = ioremap_nocache(mct_base_addr, size);
@@ -97,9 +97,9 @@ static int __init exynos5_smp_init(void)
     struct dt_device_node *node;
     void __iomem *sysram;
     char *compatible;
-    u64 sysram_addr;
-    u64 size;
-    u64 sysram_offset;
+    paddr_t sysram_addr;
+    paddr_t size;
+    paddr_t sysram_offset;
     int rc;
 
     node = dt_find_compatible_node(NULL, NULL, "samsung,secure-firmware");
@@ -131,7 +131,7 @@ static int __init exynos5_smp_init(void)
         dprintk(XENLOG_ERR, "Error in %s\n", compatible);
         return -ENXIO;
     }
-    dprintk(XENLOG_INFO, "sysram_addr: %016llx size: %016llx offset: %016llx\n",
+    dprintk(XENLOG_INFO,"sysram_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"offset: 0x%"PRIpaddr"\n",
             sysram_addr, size, sysram_offset);
 
     sysram = ioremap_nocache(sysram_addr, size);
@@ -189,7 +189,7 @@ static int exynos5_cpu_power_up(void __iomem *power, int cpu)
     return 0;
 }
 
-static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
+static int exynos5_get_pmu_baseandsize(paddr_t *power_base_addr, paddr_t *size)
 {
     struct dt_device_node *node;
     int rc;
@@ -215,7 +215,7 @@ static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
         return -ENXIO;
     }
 
-    dprintk(XENLOG_DEBUG, "power_base_addr: %016llx size: %016llx\n",
+    dprintk(XENLOG_DEBUG, "power_base_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"\n",
             *power_base_addr, *size);
 
     return 0;
@@ -223,8 +223,8 @@ static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
 
 static int exynos5_cpu_up(int cpu)
 {
-    u64 power_base_addr;
-    u64 size;
+    paddr_t power_base_addr;
+    paddr_t size;
     void __iomem *power;
     int rc;
 
@@ -256,8 +256,8 @@ static int exynos5_cpu_up(int cpu)
 
 static void exynos5_reset(void)
 {
-    u64 power_base_addr;
-    u64 size;
+    paddr_t power_base_addr;
+    paddr_t size;
     void __iomem *pmu;
     int rc;
 
diff --git a/xen/drivers/char/exynos4210-uart.c b/xen/drivers/char/exynos4210-uart.c
index 43aaf02e18..32cc8c78b5 100644
--- a/xen/drivers/char/exynos4210-uart.c
+++ b/xen/drivers/char/exynos4210-uart.c
@@ -303,7 +303,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
     const char *config = data;
     struct exynos4210_uart *uart;
     int res;
-    u64 addr, size;
+    paddr_t addr, size;
 
     if ( strcmp(config, "") )
         printk("WARNING: UART configuration is not supported\n");
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 58d0ccd889..8ef895a2bb 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -42,8 +42,8 @@
 
 static struct ns16550 {
     int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
-    u64 io_base;   /* I/O port or memory-mapped I/O address. */
-    u64 io_size;
+    paddr_t io_base;   /* I/O port or memory-mapped I/O address. */
+    paddr_t io_size;
     int reg_shift; /* Bits to shift register offset by */
     int reg_width; /* Size of access to use, the registers
                     * themselves are still bytes */
@@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst uart_config[] =
 static int __init
 pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
 {
-    u64 orig_base = uart->io_base;
+    paddr_t orig_base = uart->io_base;
     unsigned int b, d, f, nextf, i;
 
     /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
@@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
                     else
                         size = len & PCI_BASE_ADDRESS_MEM_MASK;
 
-                    uart->io_base = ((u64)bar_64 << 32) |
+                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
                                     (bar & PCI_BASE_ADDRESS_MEM_MASK);
                 }
                 /* IO based */
diff --git a/xen/drivers/char/omap-uart.c b/xen/drivers/char/omap-uart.c
index d6a5d59aa2..3b53e1909a 100644
--- a/xen/drivers/char/omap-uart.c
+++ b/xen/drivers/char/omap-uart.c
@@ -324,7 +324,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
     struct omap_uart *uart;
     u32 clkspec;
     int res;
-    u64 addr, size;
+    paddr_t addr, size;
 
     if ( strcmp(config, "") )
         printk("WARNING: UART configuration is not supported\n");
diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c
index be67242bc0..256ec11e3f 100644
--- a/xen/drivers/char/pl011.c
+++ b/xen/drivers/char/pl011.c
@@ -222,7 +222,7 @@ static struct uart_driver __read_mostly pl011_driver = {
     .vuart_info   = pl011_vuart,
 };
 
-static int __init pl011_uart_init(int irq, u64 addr, u64 size, bool sbsa)
+static int __init pl011_uart_init(int irq, paddr_t addr, paddr_t size, bool sbsa)
 {
     struct pl011 *uart;
 
@@ -258,7 +258,7 @@ static int __init pl011_dt_uart_init(struct dt_device_node *dev,
 {
     const char *config = data;
     int res;
-    u64 addr, size;
+    paddr_t addr, size;
 
     if ( strcmp(config, "") )
     {
diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
index 2fccafe340..b425881d06 100644
--- a/xen/drivers/char/scif-uart.c
+++ b/xen/drivers/char/scif-uart.c
@@ -311,7 +311,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
     const char *config = data;
     struct scif_uart *uart;
     int res;
-    u64 addr, size;
+    paddr_t addr, size;
 
     if ( strcmp(config, "") )
         printk("WARNING: UART configuration is not supported\n");
diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
index 0a514821b3..490d253d44 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -73,8 +73,8 @@
 /* Xen: Helpers to get device MMIO and IRQs */
 struct resource
 {
-	u64 addr;
-	u64 size;
+	paddr_t addr;
+	paddr_t size;
 	unsigned int type;
 };
 
@@ -169,7 +169,7 @@ static void __iomem *devm_ioremap_resource(struct device *dev,
 	ptr = ioremap_nocache(res->addr, res->size);
 	if (!ptr) {
 		dev_err(dev,
-			"ioremap failed (addr 0x%"PRIx64" size 0x%"PRIx64")\n",
+			"ioremap failed (addr 0x%"PRIpaddr" size 0x%"PRIpaddr")\n",
 			res->addr, res->size);
 		return ERR_PTR(-ENOMEM);
 	}
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 06/11] xen/arm: Introduce a wrapper for dt_device_get_address() to handle paddr_t
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (4 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-19 23:35   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 07/11] xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to SMMU_CBn_TTBR0 Ayan Kumar Halder
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

dt_device_get_address() can accept u64 only for address and size. The
various callers will use 'paddr_t' datatype for address and size.
'paddr_t' is currently defined as u64, but we may support u32 as well.
Thus, we need an appropriate wrapper which can handle this type
conversion.

The callers will now invoke dt_device_get_paddr(). This inturn invokes
dt_device_get_address() with u64 address/size. And then it typecasts
the u64 address/size to paddr_t address/size.

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

Changes from -

v1 - 1. New patch introduced.

 xen/arch/arm/domain_build.c            |  5 +++--
 xen/arch/arm/gic-v2.c                  | 11 ++++++-----
 xen/arch/arm/gic-v3.c                  |  9 +++++----
 xen/arch/arm/include/asm/device_tree.h | 19 +++++++++++++++++++
 xen/arch/arm/platforms/exynos5.c       |  7 ++++---
 xen/arch/arm/platforms/sunxi.c         |  3 ++-
 xen/drivers/char/exynos4210-uart.c     |  3 ++-
 xen/drivers/char/ns16550.c             |  3 ++-
 xen/drivers/char/omap-uart.c           |  3 ++-
 xen/drivers/char/pl011.c               |  3 ++-
 xen/drivers/char/scif-uart.c           |  3 ++-
 xen/drivers/passthrough/arm/smmu.c     |  3 ++-
 12 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index cf8ae37a14..21199b624b 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -7,6 +7,7 @@
 #include <xen/domain_page.h>
 #include <xen/sched.h>
 #include <xen/sizes.h>
+#include <asm/device_tree.h>
 #include <asm/irq.h>
 #include <asm/regs.h>
 #include <xen/errno.h>
@@ -1672,7 +1673,7 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
 
         for ( i = 0; i < naddr; i++ )
         {
-            res = dt_device_get_address(np, i, &addr, &size);
+            res = dt_device_get_paddr(np, i, &addr, &size);
             if ( res )
             {
                 printk(XENLOG_ERR "Unable to retrieve address %u for %s\n",
@@ -2500,7 +2501,7 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev,
     /* Give permission and map MMIOs */
     for ( i = 0; i < naddr; i++ )
     {
-        res = dt_device_get_address(dev, i, &addr, &size);
+        res = dt_device_get_paddr(dev, i, &addr, &size);
         if ( res )
         {
             printk(XENLOG_ERR "Unable to retrieve address %u for %s\n",
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 5d4d298b86..5230c4ebaf 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -24,6 +24,7 @@
 #include <xen/acpi.h>
 #include <acpi/actables.h>
 #include <asm/p2m.h>
+#include <asm/device_tree.h>
 #include <asm/domain.h>
 #include <asm/platform.h>
 #include <asm/device.h>
@@ -993,7 +994,7 @@ static void gicv2_extension_dt_init(const struct dt_device_node *node)
             continue;
 
         /* Get register frame resource from DT. */
-        if ( dt_device_get_address(v2m, 0, &addr, &size) )
+        if ( dt_device_get_paddr(v2m, 0, &addr, &size) )
             panic("GICv2: Cannot find a valid v2m frame address\n");
 
         /*
@@ -1018,19 +1019,19 @@ static void __init gicv2_dt_init(void)
     paddr_t vsize;
     const struct dt_device_node *node = gicv2_info.node;
 
-    res = dt_device_get_address(node, 0, &dbase, NULL);
+    res = dt_device_get_paddr(node, 0, &dbase, NULL);
     if ( res )
         panic("GICv2: Cannot find a valid address for the distributor\n");
 
-    res = dt_device_get_address(node, 1, &cbase, &csize);
+    res = dt_device_get_paddr(node, 1, &cbase, &csize);
     if ( res )
         panic("GICv2: Cannot find a valid address for the CPU\n");
 
-    res = dt_device_get_address(node, 2, &hbase, NULL);
+    res = dt_device_get_paddr(node, 2, &hbase, NULL);
     if ( res )
         panic("GICv2: Cannot find a valid address for the hypervisor\n");
 
-    res = dt_device_get_address(node, 3, &vbase, &vsize);
+    res = dt_device_get_paddr(node, 3, &vbase, &vsize);
     if ( res )
         panic("GICv2: Cannot find a valid address for the virtual CPU\n");
 
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 391dfa53d7..58d2eb0690 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -29,6 +29,7 @@
 
 #include <asm/cpufeature.h>
 #include <asm/device.h>
+#include <asm/device_tree.h>
 #include <asm/gic.h>
 #include <asm/gic_v3_defs.h>
 #include <asm/gic_v3_its.h>
@@ -1377,7 +1378,7 @@ static void __init gicv3_dt_init(void)
     int res, i;
     const struct dt_device_node *node = gicv3_info.node;
 
-    res = dt_device_get_address(node, 0, &dbase, NULL);
+    res = dt_device_get_paddr(node, 0, &dbase, NULL);
     if ( res )
         panic("GICv3: Cannot find a valid distributor address\n");
 
@@ -1395,7 +1396,7 @@ static void __init gicv3_dt_init(void)
     {
         paddr_t rdist_base, rdist_size;
 
-        res = dt_device_get_address(node, 1 + i, &rdist_base, &rdist_size);
+        res = dt_device_get_paddr(node, 1 + i, &rdist_base, &rdist_size);
         if ( res )
             panic("GICv3: No rdist base found for region %d\n", i);
 
@@ -1417,10 +1418,10 @@ static void __init gicv3_dt_init(void)
      * For GICv3 supporting GICv2, GICC and GICV base address will be
      * provided.
      */
-    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
+    res = dt_device_get_paddr(node, 1 + gicv3.rdist_count,
                                 &cbase, &csize);
     if ( !res )
-        dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
+        dt_device_get_paddr(node, 1 + gicv3.rdist_count + 2,
                               &vbase, &vsize);
 }
 
diff --git a/xen/arch/arm/include/asm/device_tree.h b/xen/arch/arm/include/asm/device_tree.h
index 51e0f0ae20..7f58f1f278 100644
--- a/xen/arch/arm/include/asm/device_tree.h
+++ b/xen/arch/arm/include/asm/device_tree.h
@@ -11,6 +11,7 @@
 #ifndef __ARCH_ARM_DEVICE_TREE__
 #define __ARCH_ARM_DEVICE_TREE__
 
+#include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
 
 inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
@@ -29,6 +30,24 @@ inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
     return ret;
 }
 
+inline int dt_device_get_paddr(const struct dt_device_node *dev,
+                               unsigned int index, paddr_t *addr,
+                               paddr_t *size)
+{
+    u64 dt_addr, dt_size;
+    int ret;
+
+    ret = dt_device_get_address(dev, index, &dt_addr, &dt_size);
+
+    if ( addr )
+        *addr = dt_addr;
+
+    if ( size )
+        *size = dt_size;
+
+    return ret;
+}
+
 #endif /* __ARCH_ARM_DEVICE_TREE__ */
 /*
  * Local variables:
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index f79fad9957..55b6ac1e7e 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -22,6 +22,7 @@
 #include <xen/mm.h>
 #include <xen/vmap.h>
 #include <xen/delay.h>
+#include <asm/device_tree.h>
 #include <asm/platforms/exynos5.h>
 #include <asm/platform.h>
 #include <asm/io.h>
@@ -52,7 +53,7 @@ static int exynos5_init_time(void)
         return -ENXIO;
     }
 
-    rc = dt_device_get_address(node, 0, &mct_base_addr, &size);
+    rc = dt_device_get_paddr(node, 0, &mct_base_addr, &size);
     if ( rc )
     {
         dprintk(XENLOG_ERR, "Error in \"samsung,exynos4210-mct\"\n");
@@ -125,7 +126,7 @@ static int __init exynos5_smp_init(void)
         return -ENXIO;
     }
 
-    rc = dt_device_get_address(node, 0, &sysram_addr, &size);
+    rc = dt_device_get_paddr(node, 0, &sysram_addr, &size);
     if ( rc )
     {
         dprintk(XENLOG_ERR, "Error in %s\n", compatible);
@@ -208,7 +209,7 @@ static int exynos5_get_pmu_baseandsize(paddr_t *power_base_addr, paddr_t *size)
         return -ENXIO;
     }
 
-    rc = dt_device_get_address(node, 0, power_base_addr, size);
+    rc = dt_device_get_paddr(node, 0, power_base_addr, size);
     if ( rc )
     {
         dprintk(XENLOG_ERR, "Error in \"samsung,exynos5XXX-pmu\"\n");
diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c
index e8e4d88bef..ce47f97507 100644
--- a/xen/arch/arm/platforms/sunxi.c
+++ b/xen/arch/arm/platforms/sunxi.c
@@ -18,6 +18,7 @@
 
 #include <xen/mm.h>
 #include <xen/vmap.h>
+#include <asm/device_tree.h>
 #include <asm/platform.h>
 #include <asm/io.h>
 
@@ -50,7 +51,7 @@ static void __iomem *sunxi_map_watchdog(bool *new_wdt)
         return NULL;
     }
 
-    ret = dt_device_get_address(node, 0, &wdt_start, &wdt_len);
+    ret = dt_device_get_paddr(node, 0, &wdt_start, &wdt_len);
     if ( ret )
     {
         dprintk(XENLOG_ERR, "Cannot read watchdog register address\n");
diff --git a/xen/drivers/char/exynos4210-uart.c b/xen/drivers/char/exynos4210-uart.c
index 32cc8c78b5..6d2008c44f 100644
--- a/xen/drivers/char/exynos4210-uart.c
+++ b/xen/drivers/char/exynos4210-uart.c
@@ -24,6 +24,7 @@
 #include <xen/irq.h>
 #include <xen/mm.h>
 #include <asm/device.h>
+#include <asm/device_tree.h>
 #include <asm/exynos4210-uart.h>
 #include <asm/io.h>
 
@@ -316,7 +317,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
     uart->parity    = PARITY_NONE;
     uart->stop_bits = 1;
 
-    res = dt_device_get_address(dev, 0, &addr, &size);
+    res = dt_device_get_paddr(dev, 0, &addr, &size);
     if ( res )
     {
         printk("exynos4210: Unable to retrieve the base"
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 8ef895a2bb..7226f3c2f7 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -35,6 +35,7 @@
 #include <asm/io.h>
 #ifdef CONFIG_HAS_DEVICE_TREE
 #include <asm/device.h>
+#include <asm/device_tree.h>
 #endif
 #ifdef CONFIG_X86
 #include <asm/fixmap.h>
@@ -1757,7 +1758,7 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
     uart->parity    = UART_PARITY_NONE;
     uart->stop_bits = 1;
 
-    res = dt_device_get_address(dev, 0, &uart->io_base, &uart->io_size);
+    res = dt_device_get_paddr(dev, 0, &uart->io_base, &uart->io_size);
     if ( res )
         return res;
 
diff --git a/xen/drivers/char/omap-uart.c b/xen/drivers/char/omap-uart.c
index 3b53e1909a..06200bc9f1 100644
--- a/xen/drivers/char/omap-uart.c
+++ b/xen/drivers/char/omap-uart.c
@@ -15,6 +15,7 @@
 #include <xen/init.h>
 #include <xen/irq.h>
 #include <xen/device_tree.h>
+#include <asm/device_tree.h>
 #include <asm/device.h>
 #include <xen/errno.h>
 #include <xen/mm.h>
@@ -344,7 +345,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
     uart->parity = UART_PARITY_NONE;
     uart->stop_bits = 1;
 
-    res = dt_device_get_address(dev, 0, &addr, &size);
+    res = dt_device_get_paddr(dev, 0, &addr, &size);
     if ( res )
     {
         printk("omap-uart: Unable to retrieve the base"
diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c
index 256ec11e3f..b4c1d9d592 100644
--- a/xen/drivers/char/pl011.c
+++ b/xen/drivers/char/pl011.c
@@ -26,6 +26,7 @@
 #include <asm/device.h>
 #include <xen/mm.h>
 #include <xen/vmap.h>
+#include <asm/device_tree.h>
 #include <asm/pl011-uart.h>
 #include <asm/io.h>
 
@@ -265,7 +266,7 @@ static int __init pl011_dt_uart_init(struct dt_device_node *dev,
         printk("WARNING: UART configuration is not supported\n");
     }
 
-    res = dt_device_get_address(dev, 0, &addr, &size);
+    res = dt_device_get_paddr(dev, 0, &addr, &size);
     if ( res )
     {
         printk("pl011: Unable to retrieve the base"
diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
index b425881d06..af14388f70 100644
--- a/xen/drivers/char/scif-uart.c
+++ b/xen/drivers/char/scif-uart.c
@@ -26,6 +26,7 @@
 #include <xen/mm.h>
 #include <xen/delay.h>
 #include <asm/device.h>
+#include <asm/device_tree.h>
 #include <asm/scif-uart.h>
 #include <asm/io.h>
 
@@ -318,7 +319,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
 
     uart = &scif_com;
 
-    res = dt_device_get_address(dev, 0, &addr, &size);
+    res = dt_device_get_paddr(dev, 0, &addr, &size);
     if ( res )
     {
         printk("scif-uart: Unable to retrieve the base"
diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
index 490d253d44..0c89cb644e 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -51,6 +51,7 @@
 #include <xen/sizes.h>
 #include <asm/atomic.h>
 #include <asm/device.h>
+#include <asm/device_tree.h>
 #include <asm/io.h>
 #include <asm/iommu_fwspec.h>
 #include <asm/platform.h>
@@ -101,7 +102,7 @@ static struct resource *platform_get_resource(struct platform_device *pdev,
 
 	switch (type) {
 	case IORESOURCE_MEM:
-		ret = dt_device_get_address(pdev, num, &res.addr, &res.size);
+		ret = dt_device_get_paddr(pdev, num, &res.addr, &res.size);
 
 		return ((ret) ? NULL : &res);
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 07/11] xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to SMMU_CBn_TTBR0
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (5 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 06/11] xen/arm: Introduce a wrapper for dt_device_get_address() to handle paddr_t Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-19 23:40   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32" Ayan Kumar Halder
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

Refer ARM IHI 0062D.c ID070116 (SMMU 2.0 spec), 17-360, 17.3.9,
SMMU_CBn_TTBR0 is a 64 bit register. Thus, one can use
writeq_relaxed_non_atomic() to write to it instead of invoking
writel_relaxed() twice for lower half and upper half of the register.

This also helps us as p2maddr is 'paddr_t' (which may be u32 in future).
Thus, one can assign p2maddr to a 64 bit register and do the bit
manipulations on it, to generate the value for SMMU_CBn_TTBR0.

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

v1 - 1. Extracted the patch from "[XEN v1 8/9] xen/arm: Other adaptations required to support 32bit paddr".
Use writeq_relaxed_non_atomic() to write u64 register in a non-atomic
fashion.

 xen/drivers/passthrough/arm/smmu.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
index 0c89cb644e..84b6803b4e 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -500,8 +500,7 @@ enum arm_smmu_s2cr_privcfg {
 #define ARM_SMMU_CB_SCTLR		0x0
 #define ARM_SMMU_CB_RESUME		0x8
 #define ARM_SMMU_CB_TTBCR2		0x10
-#define ARM_SMMU_CB_TTBR0_LO		0x20
-#define ARM_SMMU_CB_TTBR0_HI		0x24
+#define ARM_SMMU_CB_TTBR0		0x20
 #define ARM_SMMU_CB_TTBCR		0x30
 #define ARM_SMMU_CB_S1_MAIR0		0x38
 #define ARM_SMMU_CB_FSR			0x58
@@ -1084,6 +1083,7 @@ static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
 static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
 {
 	u32 reg;
+	u64 reg64;
 	bool stage1;
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
@@ -1178,12 +1178,13 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
 	dev_notice(smmu->dev, "d%u: p2maddr 0x%"PRIpaddr"\n",
 		   smmu_domain->cfg.domain->domain_id, p2maddr);
 
-	reg = (p2maddr & ((1ULL << 32) - 1));
-	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-	reg = (p2maddr >> 32);
+	reg64 = p2maddr;
+
 	if (stage1)
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+		reg64 |= (((uint64_t) (ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT))
+		         << 32);
+
+	writeq_relaxed_non_atomic(reg64, cb_base + ARM_SMMU_CB_TTBR0);
 
 	/*
 	 * TTBCR
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32"
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (6 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 07/11] xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to SMMU_CBn_TTBR0 Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-19 23:43   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address Ayan Kumar Halder
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

In the subsequent patch, we introduce "CONFIG_ARM_PA_32" to support
32 bit physical addresses. Thus, the code specific to
"Large Page Address Extension" (ie LPAE) should be enclosed within
"ifndef CONFIG_ARM_PA_32".

Refer xen/arch/arm/include/asm/short-desc.h, "short_desc_l1_supersec_t"
unsigned int extbase1:4;    /* Extended base address, PA[35:32] */
unsigned int extbase2:4;    /* Extended base address, PA[39:36] */

Thus, extbase1 and extbase2 are not valid when 32 bit physical addresses
are supported.

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

Changes from -
v1 - 1. Extracted from "[XEN v1 8/9] xen/arm: Other adaptations required to support 32bit paddr".

 xen/arch/arm/guest_walk.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c
index 43d3215304..0feb7b76ec 100644
--- a/xen/arch/arm/guest_walk.c
+++ b/xen/arch/arm/guest_walk.c
@@ -154,8 +154,10 @@ static bool guest_walk_sd(const struct vcpu *v,
             mask = (1ULL << L1DESC_SUPERSECTION_SHIFT) - 1;
             *ipa = gva & mask;
             *ipa |= (paddr_t)(pte.supersec.base) << L1DESC_SUPERSECTION_SHIFT;
+#ifndef CONFIG_ARM_PA_32
             *ipa |= (paddr_t)(pte.supersec.extbase1) << L1DESC_SUPERSECTION_EXT_BASE1_SHIFT;
             *ipa |= (paddr_t)(pte.supersec.extbase2) << L1DESC_SUPERSECTION_EXT_BASE2_SHIFT;
+#endif /* CONFIG_ARM_PA_32 */
         }
 
         /* Set permissions so that the caller can check the flags by herself. */
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (7 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32" Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-18  8:50   ` Jan Beulich
                     ` (2 more replies)
  2023-01-17 17:43 ` [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64 Ayan Kumar Halder
                   ` (2 subsequent siblings)
  11 siblings, 3 replies; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

We have introduced a new config option to support 32 bit physical address.
By default, it is disabled.
ARM_PA_32 cannot be enabled on ARM_64 as the memory management unit works
on 48bit physical addresses.
On ARM_32, it can be used on systems where large page address extension is
not supported.

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

v1 - 1. No changes.

 xen/arch/arm/Kconfig                 | 9 +++++++++
 xen/arch/arm/include/asm/page-bits.h | 2 ++
 xen/arch/arm/include/asm/types.h     | 7 +++++++
 3 files changed, 18 insertions(+)

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 239d3aed3c..aeb0f7252e 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -39,6 +39,15 @@ config ACPI
 config ARM_EFI
 	bool
 
+config ARM_PA_32
+	bool "32 bit Physical Address"
+	depends on ARM_32
+	default n
+	---help---
+
+	  Support 32 bit physical addresses.
+	  If unsure, say N
+
 config GICV3
 	bool "GICv3 driver"
 	depends on !NEW_VGIC
diff --git a/xen/arch/arm/include/asm/page-bits.h b/xen/arch/arm/include/asm/page-bits.h
index 5d6477e599..8f4dcebcfd 100644
--- a/xen/arch/arm/include/asm/page-bits.h
+++ b/xen/arch/arm/include/asm/page-bits.h
@@ -5,6 +5,8 @@
 
 #ifdef CONFIG_ARM_64
 #define PADDR_BITS              48
+#elif CONFIG_ARM_PA_32
+#define PADDR_BITS              32
 #else
 #define PADDR_BITS              40
 #endif
diff --git a/xen/arch/arm/include/asm/types.h b/xen/arch/arm/include/asm/types.h
index 083acbd151..f9595b9098 100644
--- a/xen/arch/arm/include/asm/types.h
+++ b/xen/arch/arm/include/asm/types.h
@@ -37,9 +37,16 @@ typedef signed long long s64;
 typedef unsigned long long u64;
 typedef u32 vaddr_t;
 #define PRIvaddr PRIx32
+#if defined(CONFIG_ARM_PA_32)
+typedef u32 paddr_t;
+#define INVALID_PADDR (~0UL)
+#define PADDR_SHIFT BITS_PER_LONG
+#define PRIpaddr PRIx32
+#else
 typedef u64 paddr_t;
 #define INVALID_PADDR (~0ULL)
 #define PRIpaddr "016llx"
+#endif
 typedef u32 register_t;
 #define PRIregister "08x"
 #elif defined (CONFIG_ARM_64)
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (8 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-20  0:19   ` Stefano Stabellini
  2023-01-17 17:43 ` [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA Ayan Kumar Halder
  2023-01-18 10:12 ` [XEN v2 00/11] Add support for 32 bit physical address Michal Orzel
  11 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

zeroeth_table_offset is not accessed by ARM_32.
Also, when 32 bit physical addresses are used (ie ARM_PA_32=y), this
causes an overflow.

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

v1 - Removed the duplicate declaration for DECLARE_OFFSETS.

 xen/arch/arm/include/asm/lpae.h | 4 ++++
 xen/arch/arm/mm.c               | 7 +------
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/xen/arch/arm/include/asm/lpae.h b/xen/arch/arm/include/asm/lpae.h
index 3fdd5d0de2..2744e0eebf 100644
--- a/xen/arch/arm/include/asm/lpae.h
+++ b/xen/arch/arm/include/asm/lpae.h
@@ -259,7 +259,11 @@ lpae_t mfn_to_xen_entry(mfn_t mfn, unsigned int attr);
 #define first_table_offset(va)  TABLE_OFFSET(first_linear_offset(va))
 #define second_table_offset(va) TABLE_OFFSET(second_linear_offset(va))
 #define third_table_offset(va)  TABLE_OFFSET(third_linear_offset(va))
+#ifdef CONFIG_ARM_64
 #define zeroeth_table_offset(va)  TABLE_OFFSET(zeroeth_linear_offset(va))
+#else
+#define zeroeth_table_offset(va)  0
+#endif
 
 /*
  * Macros to define page-tables:
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index fab54618ab..95784e0c59 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -207,12 +207,7 @@ void dump_pt_walk(paddr_t ttbr, paddr_t addr,
 {
     static const char *level_strs[4] = { "0TH", "1ST", "2ND", "3RD" };
     const mfn_t root_mfn = maddr_to_mfn(ttbr);
-    const unsigned int offsets[4] = {
-        zeroeth_table_offset(addr),
-        first_table_offset(addr),
-        second_table_offset(addr),
-        third_table_offset(addr)
-    };
+    DECLARE_OFFSETS(offsets, addr);
     lpae_t pte, *mapping;
     unsigned int level, root_table;
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (9 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64 Ayan Kumar Halder
@ 2023-01-17 17:43 ` Ayan Kumar Halder
  2023-01-20  0:05   ` Stefano Stabellini
  2023-01-20 11:06   ` Julien Grall
  2023-01-18 10:12 ` [XEN v2 00/11] Add support for 32 bit physical address Michal Orzel
  11 siblings, 2 replies; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-17 17:43 UTC (permalink / raw)
  To: xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, Ayan Kumar Halder

VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
"Virtualization Translation Control Register" for the bit descriptions.

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

v1 - New patch.

 xen/arch/arm/p2m.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 948f199d84..cfdea55e71 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
     register_t val = VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
 
 #ifdef CONFIG_ARM_32
-    if ( p2m_ipa_bits < 40 )
+    if ( p2m_ipa_bits < PADDR_BITS )
         panic("P2M: Not able to support %u-bit IPA at the moment\n",
               p2m_ipa_bits);
 
-    printk("P2M: 40-bit IPA\n");
-    p2m_ipa_bits = 40;
+    printk("P2M: %u-bit IPA\n",PADDR_BITS);
+    p2m_ipa_bits = PADDR_BITS;
+#ifdef CONFIG_ARM_PA_32
+    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
+#else
     val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
+#endif
     val |= VTCR_SL0(0x1); /* P2M starts at first level */
 #else /* CONFIG_ARM_64 */
     static const struct {
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-17 17:43 ` [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size Ayan Kumar Halder
@ 2023-01-18  8:40   ` Jan Beulich
  2023-01-18 11:15     ` Ayan Kumar Halder
  2023-01-19 23:24   ` Stefano Stabellini
  2023-01-20 10:34   ` Julien Grall
  2 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2023-01-18  8:40 UTC (permalink / raw)
  To: Ayan Kumar Halder, julien, Wei Xu
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk,
	bertrand.marquis, xen-devel

On 17.01.2023 18:43, Ayan Kumar Halder wrote:
> One should now be able to use 'paddr_t' to represent address and size.
> Consequently, one should use 'PRIpaddr' as a format specifier for paddr_t.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> 
> Changes from -
> 
> v1 - 1. Rebased the patch.
> 
>  xen/arch/arm/domain_build.c        |  9 +++++----
>  xen/arch/arm/gic-v3.c              |  2 +-
>  xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>  xen/drivers/char/exynos4210-uart.c |  2 +-
>  xen/drivers/char/ns16550.c         |  8 ++++----

Please make sure you Cc all maintainers.

> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst uart_config[] =
>  static int __init
>  pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>  {
> -    u64 orig_base = uart->io_base;
> +    paddr_t orig_base = uart->io_base;
>      unsigned int b, d, f, nextf, i;
>  
>      /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>                      else
>                          size = len & PCI_BASE_ADDRESS_MEM_MASK;
>  
> -                    uart->io_base = ((u64)bar_64 << 32) |
> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>                                      (bar & PCI_BASE_ADDRESS_MEM_MASK);
>                  }

This looks wrong to me: You shouldn't blindly truncate to 32 bits. You need
to refuse acting on 64-bit BARs with the upper address bits non-zero.

If already you correct logic even in code not used on Arm (which I appreciate),
then there's actually also related command line handling which needs adjustment.
The use of simple_strtoul() to obtain ->io_base is bogus - this then needs to
be simple_strtoull() (perhaps in a separate prereq patch), and in the 32-bit-
paddr case you'd again need to check for truncation (in the patch here).

While doing the review I've noticed this

    uart->io_size = spcr->serial_port.bit_width;

in ns16550_acpi_uart_init(). This was introduced in 17b516196c55 ("ns16550:
add ACPI support for ARM only"), so Wei, Julien: Doesn't the right hand value
need DIV_ROUND_UP(, 8) to convert from bit count to byte count?

Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-17 17:43 ` [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address Ayan Kumar Halder
@ 2023-01-18  8:50   ` Jan Beulich
  2023-01-18 11:57     ` Ayan Kumar Halder
  2023-01-18  9:18   ` Julien Grall
  2023-01-30 22:00   ` Julien Grall
  2 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2023-01-18  8:50 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, xen-devel

On 17.01.2023 18:43, Ayan Kumar Halder wrote:
> --- a/xen/arch/arm/include/asm/types.h
> +++ b/xen/arch/arm/include/asm/types.h
> @@ -37,9 +37,16 @@ typedef signed long long s64;
>  typedef unsigned long long u64;
>  typedef u32 vaddr_t;
>  #define PRIvaddr PRIx32
> +#if defined(CONFIG_ARM_PA_32)
> +typedef u32 paddr_t;
> +#define INVALID_PADDR (~0UL)
> +#define PADDR_SHIFT BITS_PER_LONG
> +#define PRIpaddr PRIx32
> +#else

With our plan to consolidate basic type definitions into xen/types.h
the use of ARM_PA_32 is problematic: Preferably we'd have an arch-
independent Kconfig setting, much like Linux'es PHYS_ADDR_T_64BIT
(I don't think we should re-use the name directly, as we have no
phys_addr_t type), which each arch selects (or not) accordingly.
Perhaps architectures already selecting 64BIT wouldn't need to do
this explicitly, and instead 64BIT could select the new setting
(or the new setting could default to Y when 64BIT=y).

Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-17 17:43 ` [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address Ayan Kumar Halder
  2023-01-18  8:50   ` Jan Beulich
@ 2023-01-18  9:18   ` Julien Grall
  2023-01-30 22:00   ` Julien Grall
  2 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-18  9:18 UTC (permalink / raw)
  To: Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Ayan,

On 17/01/2023 17:43, Ayan Kumar Halder wrote:
> We have introduced a new config option to support 32 bit physical address.
> By default, it is disabled.
> ARM_PA_32 cannot be enabled on ARM_64 as the memory management unit works
> on 48bit physical addresses.

I don't understand the "cannot" here. It is possible to have a 64-bit HW 
that support only 32-bit physical address.

After your series, I also don't see any restriction in Xen to enable 
ARM_PA_32.

Whether we want to do it is a different discussion. I don't have any 
strong opinion. But the wording should be clarified.

> On ARM_32, it can be used on systems where large page address extension is
> not supported.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> Changes from -
> 
> v1 - 1. No changes.
> 
>   xen/arch/arm/Kconfig                 | 9 +++++++++
>   xen/arch/arm/include/asm/page-bits.h | 2 ++
>   xen/arch/arm/include/asm/types.h     | 7 +++++++
>   3 files changed, 18 insertions(+)
> 
> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
> index 239d3aed3c..aeb0f7252e 100644
> --- a/xen/arch/arm/Kconfig
> +++ b/xen/arch/arm/Kconfig
> @@ -39,6 +39,15 @@ config ACPI
>   config ARM_EFI
>   	bool
>   
> +config ARM_PA_32
> +	bool "32 bit Physical Address"
> +	depends on ARM_32
> +	default n
> +	---help---
> +
> +	  Support 32 bit physical addresses.

The description is a bit misleading. If you select N, then you can still 
still boot on HW supporting only 32-bit physical address.

It is only not clear from the description why a user may want to select it.

 From an external interface PoV, I think it would be better if we let 
the user decide how much physical address bits they want Xen to support.

In the Kconfig, this would translate as a "choice". For Arm64, there 
will only be one (48 bits) where-as Arm32 there would be two (32, 40).


For an internal interface PoV, this could still translate to select 
ARM_PA_32 (or whichever name we decide) to indicate the type of paddr_t.

> +	  If unsure, say N
> +
>   config GICV3
>   	bool "GICv3 driver"
>   	depends on !NEW_VGIC
> diff --git a/xen/arch/arm/include/asm/page-bits.h b/xen/arch/arm/include/asm/page-bits.h
> index 5d6477e599..8f4dcebcfd 100644
> --- a/xen/arch/arm/include/asm/page-bits.h
> +++ b/xen/arch/arm/include/asm/page-bits.h
> @@ -5,6 +5,8 @@
>   
>   #ifdef CONFIG_ARM_64
>   #define PADDR_BITS              48
> +#elif CONFIG_ARM_PA_32
> +#define PADDR_BITS              32
>   #else
>   #define PADDR_BITS              40
>   #endif
> diff --git a/xen/arch/arm/include/asm/types.h b/xen/arch/arm/include/asm/types.h
> index 083acbd151..f9595b9098 100644
> --- a/xen/arch/arm/include/asm/types.h
> +++ b/xen/arch/arm/include/asm/types.h
> @@ -37,9 +37,16 @@ typedef signed long long s64;
>   typedef unsigned long long u64;
>   typedef u32 vaddr_t;
>   #define PRIvaddr PRIx32
> +#if defined(CONFIG_ARM_PA_32)
> +typedef u32 paddr_t;
> +#define INVALID_PADDR (~0UL)
> +#define PADDR_SHIFT BITS_PER_LONG
> +#define PRIpaddr PRIx32
> +#else
>   typedef u64 paddr_t;
>   #define INVALID_PADDR (~0ULL)
>   #define PRIpaddr "016llx"
> +#endif
>   typedef u32 register_t;
>   #define PRIregister "08x"
>   #elif defined (CONFIG_ARM_64)

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 00/11] Add support for 32 bit physical address
  2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
                   ` (10 preceding siblings ...)
  2023-01-17 17:43 ` [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA Ayan Kumar Halder
@ 2023-01-18 10:12 ` Michal Orzel
  11 siblings, 0 replies; 64+ messages in thread
From: Michal Orzel @ 2023-01-18 10:12 UTC (permalink / raw)
  To: Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis

Hi Ayan,

On 17/01/2023 18:43, Ayan Kumar Halder wrote:
> 
> 
> Hi All,
> 
> Please have a look at https://lists.xenproject.org/archives/html/xen-devel/2022-11/msg01465.html
> for the context.
> 
> The benefits of using 32 bit physical addresses are as follows :-
> 
> 1. It helps to use Xen on platforms (for eg R52) which supports 32 bit
> physical addresses and has no support for large page address extension.
Looking at your entire series, you keep using "large page address extension".
LPAE is ARMv7A thing and it is defined as "large *physical* address extension".
So it would be good to stick to the proper naming.

~Michal


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-18  8:40   ` Jan Beulich
@ 2023-01-18 11:15     ` Ayan Kumar Halder
  2023-01-18 13:14       ` Jan Beulich
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-18 11:15 UTC (permalink / raw)
  To: Jan Beulich, Ayan Kumar Halder, julien, Wei Xu
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk,
	bertrand.marquis, xen-devel, Andrew Cooper, George Dunlap,
	Wei Liu, Rahul Singh

Hi Jan,

On 18/01/2023 08:40, Jan Beulich wrote:
> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
>> One should now be able to use 'paddr_t' to represent address and size.
>> Consequently, one should use 'PRIpaddr' as a format specifier for paddr_t.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>> ---
>>
>> Changes from -
>>
>> v1 - 1. Rebased the patch.
>>
>>   xen/arch/arm/domain_build.c        |  9 +++++----
>>   xen/arch/arm/gic-v3.c              |  2 +-
>>   xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>>   xen/drivers/char/exynos4210-uart.c |  2 +-
>>   xen/drivers/char/ns16550.c         |  8 ++++----
> Please make sure you Cc all maintainers.
Ack.
>
>> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst uart_config[] =
>>   static int __init
>>   pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>>   {
>> -    u64 orig_base = uart->io_base;
>> +    paddr_t orig_base = uart->io_base;
>>       unsigned int b, d, f, nextf, i;
>>   
>>       /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
>> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>>                       else
>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
>>   
>> -                    uart->io_base = ((u64)bar_64 << 32) |
>> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>>                                       (bar & PCI_BASE_ADDRESS_MEM_MASK);
>>                   }
> This looks wrong to me: You shouldn't blindly truncate to 32 bits. You need
> to refuse acting on 64-bit BARs with the upper address bits non-zero.

Yes, I was treating this like others (where Xen does not detect for 
truncation while getting the address/size from device-tree and 
typecasting it to paddr_t).

However in this case, as Xen is reading from PCI registers, so it needs 
to check for truncation.

I think the following change should do good.

@@ -1180,6 +1180,7 @@ pci_uart_config(struct ns16550 *uart, bool_t 
skip_amt, unsigned int idx)
                  unsigned int bar_idx = 0, port_idx = idx;
                  uint32_t bar, bar_64 = 0, len, len_64;
                  u64 size = 0;
+                uint64_t io_base = 0;
                  const struct ns16550_config_param *param = uart_param;

                  nextf = (f || (pci_conf_read16(PCI_SBDF(0, b, d, f),
@@ -1260,8 +1261,11 @@ pci_uart_config(struct ns16550 *uart, bool_t 
skip_amt, unsigned int idx)
                      else
                          size = len & PCI_BASE_ADDRESS_MEM_MASK;

-                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
+                    io_base = ((u64)bar_64 << 32) |
                                      (bar & PCI_BASE_ADDRESS_MEM_MASK);
+
+                    uart->io_base = (paddr_t) io_base;
+                    ASSERT(uart->io_base == io_base); /* Detect 
truncation */
                  }
                  /* IO based */
                  else if ( !param->mmio && (bar & 
PCI_BASE_ADDRESS_SPACE_IO) )

>
> If already you correct logic even in code not used on Arm (which I appreciate),
> then there's actually also related command line handling which needs adjustment.
> The use of simple_strtoul() to obtain ->io_base is bogus - this then needs to
> be simple_strtoull() (perhaps in a separate prereq patch), and in the 32-bit-
> paddr case you'd again need to check for truncation (in the patch here).
Agreed this needs to be done in a separate prereq patch.
>
> While doing the review I've noticed this
>
>      uart->io_size = spcr->serial_port.bit_width;
>
> in ns16550_acpi_uart_init(). This was introduced in 17b516196c55 ("ns16550:
> add ACPI support for ARM only"), so Wei, Julien: Doesn't the right hand value
> need DIV_ROUND_UP(, 8) to convert from bit count to byte count?

Yes, I think it should be

uart->io_size = DIV_ROUND_UP(spcr->serial_port.bit_width, BITS_PER_BYTE);

However, Julien/Wei can confirm this.

- Ayan

>
> Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-18  8:50   ` Jan Beulich
@ 2023-01-18 11:57     ` Ayan Kumar Halder
  2023-01-18 13:19       ` Jan Beulich
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-18 11:57 UTC (permalink / raw)
  To: Jan Beulich, Ayan Kumar Halder
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, xen-devel

Hi Jan,

On 18/01/2023 08:50, Jan Beulich wrote:
> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
>> --- a/xen/arch/arm/include/asm/types.h
>> +++ b/xen/arch/arm/include/asm/types.h
>> @@ -37,9 +37,16 @@ typedef signed long long s64;
>>   typedef unsigned long long u64;
>>   typedef u32 vaddr_t;
>>   #define PRIvaddr PRIx32
>> +#if defined(CONFIG_ARM_PA_32)
>> +typedef u32 paddr_t;
>> +#define INVALID_PADDR (~0UL)
>> +#define PADDR_SHIFT BITS_PER_LONG
>> +#define PRIpaddr PRIx32
>> +#else
> With our plan to consolidate basic type definitions into xen/types.h
> the use of ARM_PA_32 is problematic: Preferably we'd have an arch-
> independent Kconfig setting, much like Linux'es PHYS_ADDR_T_64BIT
> (I don't think we should re-use the name directly, as we have no
> phys_addr_t type), which each arch selects (or not) accordingly.
> Perhaps architectures already selecting 64BIT wouldn't need to do
> this explicitly, and instead 64BIT could select the new setting
> (or the new setting could default to Y when 64BIT=y).

Looking at some of the instances where 64BIT is currently used 
(xen/drivers/passthrough/arm/smmu.c), I understand that it is used to 
define the width of **virtual** address.

Thus, it would not conflict with ARM_PA_32 (which is for physical address).

Later on if we wish to introduce something similar to Linux's 
PHYS_ADDR_T_64BIT (which is arch agnostic), then ARM_PA_32 can be 
selected by "!PHYS_ADDR_T_64BIT" && "CONFIG_ARM_32". (We may decide to 
drop ARM_PA_32 config option, but we can still reuse ARM_PA_32 specific 
changes).

Also, then we will need to support 32 bit physical address (ie 
!PHYS_ADDR_T_64BIT) with 32 bit virtual address (ie !64BIT) and 64 bit 
virtual address (ie 64BIT).

Let's confine the current changes to Arm architecture only (as I don't 
have knowledge about x86 or RISCV). When similar changes will be done 
for other architectures, then we can think about introducing an 
architecture agnostic option.

- Ayan

>
> Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-18 11:15     ` Ayan Kumar Halder
@ 2023-01-18 13:14       ` Jan Beulich
  2023-01-18 13:34         ` George Dunlap
  0 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2023-01-18 13:14 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk,
	bertrand.marquis, xen-devel, Andrew Cooper, George Dunlap,
	Wei Liu, Rahul Singh, Ayan Kumar Halder, julien, Wei Xu

On 18.01.2023 12:15, Ayan Kumar Halder wrote:
> On 18/01/2023 08:40, Jan Beulich wrote:
>> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
>>> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst uart_config[] =
>>>   static int __init
>>>   pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>>>   {
>>> -    u64 orig_base = uart->io_base;
>>> +    paddr_t orig_base = uart->io_base;
>>>       unsigned int b, d, f, nextf, i;
>>>   
>>>       /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
>>> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>>>                       else
>>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
>>>   
>>> -                    uart->io_base = ((u64)bar_64 << 32) |
>>> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>>>                                       (bar & PCI_BASE_ADDRESS_MEM_MASK);
>>>                   }
>> This looks wrong to me: You shouldn't blindly truncate to 32 bits. You need
>> to refuse acting on 64-bit BARs with the upper address bits non-zero.
> 
> Yes, I was treating this like others (where Xen does not detect for 
> truncation while getting the address/size from device-tree and 
> typecasting it to paddr_t).
> 
> However in this case, as Xen is reading from PCI registers, so it needs 
> to check for truncation.
> 
> I think the following change should do good.
> 
> @@ -1180,6 +1180,7 @@ pci_uart_config(struct ns16550 *uart, bool_t 
> skip_amt, unsigned int idx)
>                   unsigned int bar_idx = 0, port_idx = idx;
>                   uint32_t bar, bar_64 = 0, len, len_64;
>                   u64 size = 0;
> +                uint64_t io_base = 0;
>                   const struct ns16550_config_param *param = uart_param;
> 
>                   nextf = (f || (pci_conf_read16(PCI_SBDF(0, b, d, f),
> @@ -1260,8 +1261,11 @@ pci_uart_config(struct ns16550 *uart, bool_t 
> skip_amt, unsigned int idx)
>                       else
>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
> 
> -                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
> +                    io_base = ((u64)bar_64 << 32) |
>                                       (bar & PCI_BASE_ADDRESS_MEM_MASK);
> +
> +                    uart->io_base = (paddr_t) io_base;
> +                    ASSERT(uart->io_base == io_base); /* Detect 
> truncation */
>                   }
>                   /* IO based */
>                   else if ( !param->mmio && (bar & 
> PCI_BASE_ADDRESS_SPACE_IO) )

An assertion can only ever check assumption on behavior elsewhere in Xen.
Anything external needs handling properly, including in non-debug builds.

Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-18 11:57     ` Ayan Kumar Halder
@ 2023-01-18 13:19       ` Jan Beulich
  2023-01-19 23:48         ` Stefano Stabellini
  0 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2023-01-18 13:19 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: sstabellini, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis, xen-devel, Ayan Kumar Halder

On 18.01.2023 12:57, Ayan Kumar Halder wrote:
> Hi Jan,
> 
> On 18/01/2023 08:50, Jan Beulich wrote:
>> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
>>> --- a/xen/arch/arm/include/asm/types.h
>>> +++ b/xen/arch/arm/include/asm/types.h
>>> @@ -37,9 +37,16 @@ typedef signed long long s64;
>>>   typedef unsigned long long u64;
>>>   typedef u32 vaddr_t;
>>>   #define PRIvaddr PRIx32
>>> +#if defined(CONFIG_ARM_PA_32)
>>> +typedef u32 paddr_t;
>>> +#define INVALID_PADDR (~0UL)
>>> +#define PADDR_SHIFT BITS_PER_LONG
>>> +#define PRIpaddr PRIx32
>>> +#else
>> With our plan to consolidate basic type definitions into xen/types.h
>> the use of ARM_PA_32 is problematic: Preferably we'd have an arch-
>> independent Kconfig setting, much like Linux'es PHYS_ADDR_T_64BIT
>> (I don't think we should re-use the name directly, as we have no
>> phys_addr_t type), which each arch selects (or not) accordingly.
>> Perhaps architectures already selecting 64BIT wouldn't need to do
>> this explicitly, and instead 64BIT could select the new setting
>> (or the new setting could default to Y when 64BIT=y).
> 
> Looking at some of the instances where 64BIT is currently used 
> (xen/drivers/passthrough/arm/smmu.c), I understand that it is used to 
> define the width of **virtual** address.
> 
> Thus, it would not conflict with ARM_PA_32 (which is for physical address).
> 
> Later on if we wish to introduce something similar to Linux's 
> PHYS_ADDR_T_64BIT (which is arch agnostic), then ARM_PA_32 can be 
> selected by "!PHYS_ADDR_T_64BIT" && "CONFIG_ARM_32". (We may decide to 
> drop ARM_PA_32 config option, but we can still reuse ARM_PA_32 specific 
> changes).
> 
> Also, then we will need to support 32 bit physical address (ie 
> !PHYS_ADDR_T_64BIT) with 32 bit virtual address (ie !64BIT) and 64 bit 
> virtual address (ie 64BIT).
> 
> Let's confine the current changes to Arm architecture only (as I don't 
> have knowledge about x86 or RISCV). When similar changes will be done 
> for other architectures, then we can think about introducing an 
> architecture agnostic option.

I disagree, not the least with the present goal of reworking xen/types.h
vs asm/types.h. By having an arch-independent Kconfig symbol, paddr_t
could also be manufactured uniformly in xen/types.h.

Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-18 13:14       ` Jan Beulich
@ 2023-01-18 13:34         ` George Dunlap
  2023-01-18 13:58           ` Jan Beulich
  0 siblings, 1 reply; 64+ messages in thread
From: George Dunlap @ 2023-01-18 13:34 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ayan Kumar Halder, sstabellini, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis, xen-devel, Andrew Cooper,
	George Dunlap, Wei Liu, Rahul Singh, Ayan Kumar Halder, julien,
	Wei Xu

[-- Attachment #1: Type: text/plain, Size: 3127 bytes --]

On Wed, Jan 18, 2023 at 1:15 PM Jan Beulich <jbeulich@suse.com> wrote:

> On 18.01.2023 12:15, Ayan Kumar Halder wrote:
> > On 18/01/2023 08:40, Jan Beulich wrote:
> >> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
> >>> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst
> uart_config[] =
> >>>   static int __init
> >>>   pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int
> idx)
> >>>   {
> >>> -    u64 orig_base = uart->io_base;
> >>> +    paddr_t orig_base = uart->io_base;
> >>>       unsigned int b, d, f, nextf, i;
> >>>
> >>>       /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on
> bus 0. */
> >>> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t
> skip_amt, unsigned int idx)
> >>>                       else
> >>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
> >>>
> >>> -                    uart->io_base = ((u64)bar_64 << 32) |
> >>> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
> >>>                                       (bar &
> PCI_BASE_ADDRESS_MEM_MASK);
> >>>                   }
> >> This looks wrong to me: You shouldn't blindly truncate to 32 bits. You
> need
> >> to refuse acting on 64-bit BARs with the upper address bits non-zero.
> >
> > Yes, I was treating this like others (where Xen does not detect for
> > truncation while getting the address/size from device-tree and
> > typecasting it to paddr_t).
> >
> > However in this case, as Xen is reading from PCI registers, so it needs
> > to check for truncation.
> >
> > I think the following change should do good.
> >
> > @@ -1180,6 +1180,7 @@ pci_uart_config(struct ns16550 *uart, bool_t
> > skip_amt, unsigned int idx)
> >                   unsigned int bar_idx = 0, port_idx = idx;
> >                   uint32_t bar, bar_64 = 0, len, len_64;
> >                   u64 size = 0;
> > +                uint64_t io_base = 0;
> >                   const struct ns16550_config_param *param = uart_param;
> >
> >                   nextf = (f || (pci_conf_read16(PCI_SBDF(0, b, d, f),
> > @@ -1260,8 +1261,11 @@ pci_uart_config(struct ns16550 *uart, bool_t
> > skip_amt, unsigned int idx)
> >                       else
> >                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
> >
> > -                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
> > +                    io_base = ((u64)bar_64 << 32) |
> >                                       (bar & PCI_BASE_ADDRESS_MEM_MASK);
> > +
> > +                    uart->io_base = (paddr_t) io_base;
> > +                    ASSERT(uart->io_base == io_base); /* Detect
> > truncation */
> >                   }
> >                   /* IO based */
> >                   else if ( !param->mmio && (bar &
> > PCI_BASE_ADDRESS_SPACE_IO) )
>
> An assertion can only ever check assumption on behavior elsewhere in Xen.
> Anything external needs handling properly, including in non-debug builds.
>

Except in this case, it's detecting the result of the compiler cast just
above it, isn't it?  In which case it seems like it should be a
BUILD_BUG_ON() of some sort.

 -George

[-- Attachment #2: Type: text/html, Size: 4440 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-18 13:34         ` George Dunlap
@ 2023-01-18 13:58           ` Jan Beulich
  2023-01-18 14:45             ` George Dunlap
  0 siblings, 1 reply; 64+ messages in thread
From: Jan Beulich @ 2023-01-18 13:58 UTC (permalink / raw)
  To: George Dunlap
  Cc: Ayan Kumar Halder, sstabellini, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis, xen-devel, Andrew Cooper,
	George Dunlap, Wei Liu, Rahul Singh, Ayan Kumar Halder, julien,
	Wei Xu

On 18.01.2023 14:34, George Dunlap wrote:
> On Wed, Jan 18, 2023 at 1:15 PM Jan Beulich <jbeulich@suse.com> wrote:
> 
>> On 18.01.2023 12:15, Ayan Kumar Halder wrote:
>>> On 18/01/2023 08:40, Jan Beulich wrote:
>>>> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
>>>>> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst
>> uart_config[] =
>>>>>   static int __init
>>>>>   pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int
>> idx)
>>>>>   {
>>>>> -    u64 orig_base = uart->io_base;
>>>>> +    paddr_t orig_base = uart->io_base;
>>>>>       unsigned int b, d, f, nextf, i;
>>>>>
>>>>>       /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on
>> bus 0. */
>>>>> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t
>> skip_amt, unsigned int idx)
>>>>>                       else
>>>>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
>>>>>
>>>>> -                    uart->io_base = ((u64)bar_64 << 32) |
>>>>> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>>>>>                                       (bar &
>> PCI_BASE_ADDRESS_MEM_MASK);
>>>>>                   }
>>>> This looks wrong to me: You shouldn't blindly truncate to 32 bits. You
>> need
>>>> to refuse acting on 64-bit BARs with the upper address bits non-zero.
>>>
>>> Yes, I was treating this like others (where Xen does not detect for
>>> truncation while getting the address/size from device-tree and
>>> typecasting it to paddr_t).
>>>
>>> However in this case, as Xen is reading from PCI registers, so it needs
>>> to check for truncation.
>>>
>>> I think the following change should do good.
>>>
>>> @@ -1180,6 +1180,7 @@ pci_uart_config(struct ns16550 *uart, bool_t
>>> skip_amt, unsigned int idx)
>>>                   unsigned int bar_idx = 0, port_idx = idx;
>>>                   uint32_t bar, bar_64 = 0, len, len_64;
>>>                   u64 size = 0;
>>> +                uint64_t io_base = 0;
>>>                   const struct ns16550_config_param *param = uart_param;
>>>
>>>                   nextf = (f || (pci_conf_read16(PCI_SBDF(0, b, d, f),
>>> @@ -1260,8 +1261,11 @@ pci_uart_config(struct ns16550 *uart, bool_t
>>> skip_amt, unsigned int idx)
>>>                       else
>>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
>>>
>>> -                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>>> +                    io_base = ((u64)bar_64 << 32) |
>>>                                       (bar & PCI_BASE_ADDRESS_MEM_MASK);
>>> +
>>> +                    uart->io_base = (paddr_t) io_base;
>>> +                    ASSERT(uart->io_base == io_base); /* Detect
>>> truncation */
>>>                   }
>>>                   /* IO based */
>>>                   else if ( !param->mmio && (bar &
>>> PCI_BASE_ADDRESS_SPACE_IO) )
>>
>> An assertion can only ever check assumption on behavior elsewhere in Xen.
>> Anything external needs handling properly, including in non-debug builds.
>>
> 
> Except in this case, it's detecting the result of the compiler cast just
> above it, isn't it?

Not really, no - it checks whether there was truncation, but the
absence (or presence) thereof is still a property of the underlying
system, not one in Xen.

>  In which case it seems like it should be a BUILD_BUG_ON() of some sort.

Such a check would then be to make sure paddr_t == uint64_t, which is
precisely an equivalence Ayan wants to do away with.

Jan


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-18 13:58           ` Jan Beulich
@ 2023-01-18 14:45             ` George Dunlap
  0 siblings, 0 replies; 64+ messages in thread
From: George Dunlap @ 2023-01-18 14:45 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ayan Kumar Halder, sstabellini, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis, xen-devel, Andrew Cooper,
	George Dunlap, Wei Liu, Rahul Singh, Ayan Kumar Halder, julien,
	Wei Xu

[-- Attachment #1: Type: text/plain, Size: 3757 bytes --]

On Wed, Jan 18, 2023 at 1:58 PM Jan Beulich <jbeulich@suse.com> wrote:

> On 18.01.2023 14:34, George Dunlap wrote:
> > On Wed, Jan 18, 2023 at 1:15 PM Jan Beulich <jbeulich@suse.com> wrote:
> >
> >> On 18.01.2023 12:15, Ayan Kumar Halder wrote:
> >>> On 18/01/2023 08:40, Jan Beulich wrote:
> >>>> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
> >>>>> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst
> >> uart_config[] =
> >>>>>   static int __init
> >>>>>   pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int
> >> idx)
> >>>>>   {
> >>>>> -    u64 orig_base = uart->io_base;
> >>>>> +    paddr_t orig_base = uart->io_base;
> >>>>>       unsigned int b, d, f, nextf, i;
> >>>>>
> >>>>>       /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on
> >> bus 0. */
> >>>>> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t
> >> skip_amt, unsigned int idx)
> >>>>>                       else
> >>>>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
> >>>>>
> >>>>> -                    uart->io_base = ((u64)bar_64 << 32) |
> >>>>> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
> >>>>>                                       (bar &
> >> PCI_BASE_ADDRESS_MEM_MASK);
> >>>>>                   }
> >>>> This looks wrong to me: You shouldn't blindly truncate to 32 bits. You
> >> need
> >>>> to refuse acting on 64-bit BARs with the upper address bits non-zero.
> >>>
> >>> Yes, I was treating this like others (where Xen does not detect for
> >>> truncation while getting the address/size from device-tree and
> >>> typecasting it to paddr_t).
> >>>
> >>> However in this case, as Xen is reading from PCI registers, so it needs
> >>> to check for truncation.
> >>>
> >>> I think the following change should do good.
> >>>
> >>> @@ -1180,6 +1180,7 @@ pci_uart_config(struct ns16550 *uart, bool_t
> >>> skip_amt, unsigned int idx)
> >>>                   unsigned int bar_idx = 0, port_idx = idx;
> >>>                   uint32_t bar, bar_64 = 0, len, len_64;
> >>>                   u64 size = 0;
> >>> +                uint64_t io_base = 0;
> >>>                   const struct ns16550_config_param *param =
> uart_param;
> >>>
> >>>                   nextf = (f || (pci_conf_read16(PCI_SBDF(0, b, d, f),
> >>> @@ -1260,8 +1261,11 @@ pci_uart_config(struct ns16550 *uart, bool_t
> >>> skip_amt, unsigned int idx)
> >>>                       else
> >>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
> >>>
> >>> -                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
> >>> +                    io_base = ((u64)bar_64 << 32) |
> >>>                                       (bar &
> PCI_BASE_ADDRESS_MEM_MASK);
> >>> +
> >>> +                    uart->io_base = (paddr_t) io_base;
> >>> +                    ASSERT(uart->io_base == io_base); /* Detect
> >>> truncation */
> >>>                   }
> >>>                   /* IO based */
> >>>                   else if ( !param->mmio && (bar &
> >>> PCI_BASE_ADDRESS_SPACE_IO) )
> >>
> >> An assertion can only ever check assumption on behavior elsewhere in
> Xen.
> >> Anything external needs handling properly, including in non-debug
> builds.
> >>
> >
> > Except in this case, it's detecting the result of the compiler cast just
> > above it, isn't it?
>
> Not really, no - it checks whether there was truncation, but the
> absence (or presence) thereof is still a property of the underlying
> system, not one in Xen.
>

Ah, gotcha.  Ayan, it might be helpful to take a look at the 'Handling
unexpected conditions' section of our CODING_STYLE [1] for a discussion of
when (and when not) to use ASSERT().

 -George

[1] https://github.com/xen-project/xen/blob/master/CODING_STYLE

[-- Attachment #2: Type: text/html, Size: 5553 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-17 17:43 ` [XEN v2 02/11] xen/arm: Use the correct format specifier Ayan Kumar Halder
@ 2023-01-19 22:54   ` Stefano Stabellini
  2023-01-20  9:32     ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 22:54 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
> address.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
> 
> Changes from -
> 
> v1 - 1. Moved the patch earlier.
> 2. Moved a part of change from "[XEN v1 8/9] xen/arm: Other adaptations required to support 32bit paddr"
> into this patch.
> 
>  xen/arch/arm/domain_build.c | 10 +++++-----
>  xen/arch/arm/gic-v2.c       |  6 +++---
>  xen/arch/arm/mm.c           |  2 +-
>  3 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 829cea8de8..33a5945a2d 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1315,7 +1315,7 @@ static int __init make_memory_node(const struct domain *d,
>      dt_dprintk("Create memory node\n");
>  
>      /* ePAPR 3.4 */
> -    snprintf(buf, sizeof(buf), "memory@%"PRIx64, mem->bank[i].start);
> +    snprintf(buf, sizeof(buf), "memory@%"PRIpaddr, mem->bank[i].start);
>      res = fdt_begin_node(fdt, buf);
>      if ( res )
>          return res;
> @@ -1383,7 +1383,7 @@ static int __init make_shm_memory_node(const struct domain *d,
>          __be32 *cells;
>          unsigned int len = (addrcells + sizecells) * sizeof(__be32);
>  
> -        snprintf(buf, sizeof(buf), "xen-shmem@%"PRIx64, mem->bank[i].start);
> +        snprintf(buf, sizeof(buf), "xen-shmem@%"PRIpaddr, mem->bank[i].start);
>          res = fdt_begin_node(fdt, buf);
>          if ( res )
>              return res;
> @@ -2719,7 +2719,7 @@ static int __init make_gicv2_domU_node(struct kernel_info *kinfo)
>      /* Placeholder for interrupt-controller@ + a 64-bit number + \0 */
>      char buf[38];
>  
> -    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIx64,
> +    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIpaddr,
>               vgic_dist_base(&d->arch.vgic));
>      res = fdt_begin_node(fdt, buf);
>      if ( res )
> @@ -2775,7 +2775,7 @@ static int __init make_gicv3_domU_node(struct kernel_info *kinfo)
>      char buf[38];
>      unsigned int i, len = 0;
>  
> -    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIx64,
> +    snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIpaddr,
>               vgic_dist_base(&d->arch.vgic));
>  
>      res = fdt_begin_node(fdt, buf);
> @@ -2861,7 +2861,7 @@ static int __init make_vpl011_uart_node(struct kernel_info *kinfo)
>      /* Placeholder for sbsa-uart@ + a 64-bit number + \0 */
>      char buf[27];
>  
> -    snprintf(buf, sizeof(buf), "sbsa-uart@%"PRIx64, d->arch.vpl011.base_addr);
> +    snprintf(buf, sizeof(buf), "sbsa-uart@%"PRIpaddr, d->arch.vpl011.base_addr);
>      res = fdt_begin_node(fdt, buf);
>      if ( res )
>          return res;
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index 61802839cb..5d4d298b86 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -1049,7 +1049,7 @@ static void __init gicv2_dt_init(void)
>      if ( csize < SZ_8K )
>      {
>          printk(XENLOG_WARNING "GICv2: WARNING: "
> -               "The GICC size is too small: %#"PRIx64" expected %#x\n",
> +               "The GICC size is too small: %#"PRIpaddr" expected %#x\n",
>                 csize, SZ_8K);
>          if ( platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
>          {
> @@ -1280,11 +1280,11 @@ static int __init gicv2_init(void)
>          gicv2.map_cbase += aliased_offset;
>  
>          printk(XENLOG_WARNING
> -               "GICv2: Adjusting CPU interface base to %#"PRIx64"\n",
> +               "GICv2: Adjusting CPU interface base to %#"PRIpaddr"\n",
>                 cbase + aliased_offset);
>      } else if ( csize == SZ_128K )
>          printk(XENLOG_WARNING
> -               "GICv2: GICC size=%#"PRIx64" but not aliased\n",
> +               "GICv2: GICC size=%#"PRIpaddr" but not aliased\n",
>                 csize);
>  
>      gicv2.map_hbase = ioremap_nocache(hbase, PAGE_SIZE);
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 0fc6f2992d..fab54618ab 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -249,7 +249,7 @@ void dump_pt_walk(paddr_t ttbr, paddr_t addr,
>  
>          pte = mapping[offsets[level]];
>  
> -        printk("%s[0x%03x] = 0x%"PRIpaddr"\n",
> +        printk("%s[0x%03x] = 0x%"PRIx64"\n",
>                 level_strs[level], offsets[level], pte.bits);
>  
>          if ( level == 3 || !pte.walk.valid || !pte.walk.table )
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes()
  2023-01-17 17:43 ` [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes() Ayan Kumar Halder
@ 2023-01-19 23:02   ` Stefano Stabellini
  2023-01-20  9:48     ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:02 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> bankbase, banksize and bankend are used to hold values of type 'unsigned
> long long'. This can be represented as 'uint64_t' instead of 'paddr_t'.
> This will ensure consistency with allocate_static_memory() (where we use
> 'uint64_t' for rambase and ramsize).
> 
> In future, paddr_t can be used for 'uin32_t' as well to represent 32bit
> physical addresses.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>

I saw that Julien commented about using unsigned long long. To be
honest, given that we typically use explicitly-sized integers (which is
a good thing) and unsigned long long is always uint64_t on all
architectures, I can see the benefits of using uint64_t here.

At the same time, I can see that the reason for change the type here is
that we are dealing with ULL values, so it would make sense to use
unsigned long long.

I cannot see any big problem/advantages either way, so I am OK with
this patch. (Julien, if you prefer unsigned long long I am fine with
that also.)

Acked-by: Stefano Stabellini <sstabellini@kernel.org>



> ---
> 
> Changes from -
> 
> v1 - Modified the title/commit message from "[XEN v1 6/9] xen/arm: Use 'u64' to represent 'unsigned long long"
> and moved it earlier.
> 
>  xen/arch/arm/domain_build.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 33a5945a2d..f904f12408 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1726,9 +1726,9 @@ static int __init find_domU_holes(const struct kernel_info *kinfo,
>                                    struct meminfo *ext_regions)
>  {
>      unsigned int i;
> -    paddr_t bankend;
> -    const paddr_t bankbase[] = GUEST_RAM_BANK_BASES;
> -    const paddr_t banksize[] = GUEST_RAM_BANK_SIZES;
> +    uint64_t bankend;
> +    const uint64_t bankbase[] = GUEST_RAM_BANK_BASES;
> +    const uint64_t banksize[] = GUEST_RAM_BANK_SIZES;
>      int res = -ENOENT;
>  
>      for ( i = 0; i < GUEST_RAM_BANKS; i++ )
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t
  2023-01-17 17:43 ` [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t Ayan Kumar Halder
@ 2023-01-19 23:20   ` Stefano Stabellini
  2023-01-19 23:34     ` Stefano Stabellini
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:20 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> In future, we wish to support 32 bit physical address.
> However, one can only read u64 values from the DT. Thus, we need to
> typecast the values appropriately from u64 to paddr_t.
> 
> device_tree_get_reg() should now be able to return paddr_t. This is
> invoked by various callers to get DT address and size.
> Similarly, dt_read_number() is invoked as well to get DT address and
> size. The return value is typecasted to paddr_t.
> fdt_get_mem_rsv() can only accept u64 values. So, we provide a warpper
> for this called fdt_get_mem_rsv_paddr() which will do the necessary
> typecasting before invoking fdt_get_mem_rsv() and while returning.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>

I know we discussed this before and you implemented exactly what we
suggested, but now looking at this patch I think we should do the
following:

- also add a wrapper for dt_read_number, something like
  dt_read_number_paddr that returns paddr
- add a check for the top 32-bit being zero in all the wrappers
  (dt_read_number_paddr, device_tree_get_reg, fdt_get_mem_rsv_paddr)
  when paddr!=uint64_t. In case the top 32-bit are != zero I think we
  should print an error

Julien, I remember you were concerned about BUG_ON/panic/ASSERT and I
agree with you there (especially considering Vikram's device tree
overlay series). So here I am only suggesting to check truncation and
printk a message, not panic. Would you be OK with that?

Last comment, maybe we could add fdt_get_mem_rsv_paddr to setup.h
instead of introducing xen/arch/arm/include/asm/device_tree.h, given
that we already have device tree definitions there
(device_tree_get_reg). I am OK either way.


> ---
> 
> Changes from
> 
> v1 - 1. Dropped "[XEN v1 2/9] xen/arm: Define translate_dt_address_size() for the translation between u64 and paddr_t" and
> "[XEN v1 4/9] xen/arm: Use translate_dt_address_size() to translate between device tree addr/size and paddr_t", instead
> this approach achieves the same purpose.
> 
> 2. No need to check for truncation while converting values from u64 to paddr_t.
> 
>  xen/arch/arm/bootfdt.c                 | 23 +++++++++------
>  xen/arch/arm/domain_build.c            |  2 +-
>  xen/arch/arm/include/asm/device_tree.h | 40 ++++++++++++++++++++++++++
>  xen/arch/arm/include/asm/setup.h       |  2 +-
>  xen/arch/arm/setup.c                   | 14 ++++-----
>  xen/arch/arm/smpboot.c                 |  2 +-
>  6 files changed, 65 insertions(+), 18 deletions(-)
>  create mode 100644 xen/arch/arm/include/asm/device_tree.h
> 
> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
> index 0085c28d74..f536a3f3ab 100644
> --- a/xen/arch/arm/bootfdt.c
> +++ b/xen/arch/arm/bootfdt.c
> @@ -11,9 +11,9 @@
>  #include <xen/efi.h>
>  #include <xen/device_tree.h>
>  #include <xen/lib.h>
> -#include <xen/libfdt/libfdt.h>
>  #include <xen/sort.h>
>  #include <xsm/xsm.h>
> +#include <asm/device_tree.h>
>  #include <asm/setup.h>
>  
>  static bool __init device_tree_node_matches(const void *fdt, int node,
> @@ -53,10 +53,15 @@ static bool __init device_tree_node_compatible(const void *fdt, int node,
>  }
>  
>  void __init device_tree_get_reg(const __be32 **cell, u32 address_cells,
> -                                u32 size_cells, u64 *start, u64 *size)
> +                                u32 size_cells, paddr_t *start, paddr_t *size)
>  {
> -    *start = dt_next_cell(address_cells, cell);
> -    *size = dt_next_cell(size_cells, cell);
> +    /*
> +     * dt_next_cell will return u64 whereas paddr_t may be u64 or u32. Thus, one
> +     * needs to cast paddr_t to u32. Note that we do not check for truncation as
> +     * it is user's responsibility to provide the correct values in the DT.
> +     */
> +    *start = (paddr_t) dt_next_cell(address_cells, cell);
> +    *size = (paddr_t) dt_next_cell(size_cells, cell);
>  }
>  
>  static int __init device_tree_get_meminfo(const void *fdt, int node,
> @@ -326,7 +331,7 @@ static int __init process_chosen_node(const void *fdt, int node,
>          printk("linux,initrd-start property has invalid length %d\n", len);
>          return -EINVAL;
>      }
> -    start = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> +    start = (paddr_t) dt_read_number((void *)&prop->data, dt_size_to_cells(len));
>  
>      prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
>      if ( !prop )
> @@ -339,7 +344,7 @@ static int __init process_chosen_node(const void *fdt, int node,
>          printk("linux,initrd-end property has invalid length %d\n", len);
>          return -EINVAL;
>      }
> -    end = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> +    end = (paddr_t) dt_read_number((void *)&prop->data, dt_size_to_cells(len));
>  
>      if ( start >= end )
>      {
> @@ -594,9 +599,11 @@ static void __init early_print_info(void)
>      for ( i = 0; i < nr_rsvd; i++ )
>      {
>          paddr_t s, e;
> -        if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 )
> +
> +        if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &s, &e) < 0 )
>              continue;
> -        /* fdt_get_mem_rsv returns length */
> +
> +        /* fdt_get_mem_rsv_paddr returns length */
>          e += s;
>          printk(" RESVD[%u]: %"PRIpaddr" - %"PRIpaddr"\n", i, s, e);
>      }
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index f904f12408..72b9afbb4c 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -949,7 +949,7 @@ static int __init process_shm(struct domain *d, struct kernel_info *kinfo,
>          BUG_ON(!prop);
>          cells = (const __be32 *)prop->value;
>          device_tree_get_reg(&cells, addr_cells, addr_cells, &pbase, &gbase);
> -        psize = dt_read_number(cells, size_cells);
> +        psize = (paddr_t) dt_read_number(cells, size_cells);
>          if ( !IS_ALIGNED(pbase, PAGE_SIZE) || !IS_ALIGNED(gbase, PAGE_SIZE) )
>          {
>              printk("%pd: physical address 0x%"PRIpaddr", or guest address 0x%"PRIpaddr" is not suitably aligned.\n",
> diff --git a/xen/arch/arm/include/asm/device_tree.h b/xen/arch/arm/include/asm/device_tree.h
> new file mode 100644
> index 0000000000..51e0f0ae20
> --- /dev/null
> +++ b/xen/arch/arm/include/asm/device_tree.h
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * xen/arch/arm/include/asm/device_tree.h
> + * 
> + * Wrapper functions for device tree. This helps to convert dt values
> + * between u64 and paddr_t.
> + *
> + * Copyright (C) 2023, Advanced Micro Devices, Inc. All Rights Reserved.
> + */
> +
> +#ifndef __ARCH_ARM_DEVICE_TREE__
> +#define __ARCH_ARM_DEVICE_TREE__
> +
> +#include <xen/libfdt/libfdt.h>
> +
> +inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
> +                                 paddr_t *address,
> +                                 paddr_t *size)
> +{
> +    uint64_t dt_addr;
> +    uint64_t dt_size;
> +    int ret = 0;
> +
> +    ret = fdt_get_mem_rsv(fdt, n, &dt_addr, &dt_size);
> +
> +    *address = (paddr_t) dt_addr;
> +    *size = (paddr_t) dt_size;
> +
> +    return ret;
> +}
> +
> +#endif /* __ARCH_ARM_DEVICE_TREE__ */
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
> index a926f30a2b..6105e5cae3 100644
> --- a/xen/arch/arm/include/asm/setup.h
> +++ b/xen/arch/arm/include/asm/setup.h
> @@ -158,7 +158,7 @@ extern uint32_t hyp_traps_vector[];
>  void init_traps(void);
>  
>  void device_tree_get_reg(const __be32 **cell, u32 address_cells,
> -                         u32 size_cells, u64 *start, u64 *size);
> +                         u32 size_cells, paddr_t *start, paddr_t *size);
>  
>  u32 device_tree_get_u32(const void *fdt, int node,
>                          const char *prop_name, u32 dflt);
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 1f26f67b90..da13439e62 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -29,7 +29,6 @@
>  #include <xen/virtual_region.h>
>  #include <xen/vmap.h>
>  #include <xen/trace.h>
> -#include <xen/libfdt/libfdt.h>
>  #include <xen/acpi.h>
>  #include <xen/warning.h>
>  #include <asm/alternative.h>
> @@ -39,6 +38,7 @@
>  #include <asm/gic.h>
>  #include <asm/cpuerrata.h>
>  #include <asm/cpufeature.h>
> +#include <asm/device_tree.h>
>  #include <asm/platform.h>
>  #include <asm/procinfo.h>
>  #include <asm/setup.h>
> @@ -222,11 +222,11 @@ static void __init dt_unreserved_regions(paddr_t s, paddr_t e,
>      {
>          paddr_t r_s, r_e;
>  
> -        if ( fdt_get_mem_rsv(device_tree_flattened, i, &r_s, &r_e ) < 0 )
> +        if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &r_s, &r_e ) < 0 )
>              /* If we can't read it, pretend it doesn't exist... */
>              continue;
>  
> -        r_e += r_s; /* fdt_get_mem_rsv returns length */
> +        r_e += r_s; /* fdt_get_mem_rsv_paddr returns length */
>  
>          if ( s < r_e && r_s < e )
>          {
> @@ -502,13 +502,13 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e,
>      {
>          paddr_t mod_s, mod_e;
>  
> -        if ( fdt_get_mem_rsv(device_tree_flattened,
> -                             i - mi->nr_mods,
> -                             &mod_s, &mod_e ) < 0 )
> +        if ( fdt_get_mem_rsv_paddr(device_tree_flattened,
> +                                   i - mi->nr_mods,
> +                                   &mod_s, &mod_e ) < 0 )
>              /* If we can't read it, pretend it doesn't exist... */
>              continue;
>  
> -        /* fdt_get_mem_rsv returns length */
> +        /* fdt_get_mem_rsv_paddr returns length */
>          mod_e += mod_s;
>  
>          if ( s < mod_e && mod_s < e )
> diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
> index 412ae22869..ee59b1d379 100644
> --- a/xen/arch/arm/smpboot.c
> +++ b/xen/arch/arm/smpboot.c
> @@ -159,7 +159,7 @@ static void __init dt_smp_init_cpus(void)
>              continue;
>          }
>  
> -        addr = dt_read_number(prop, dt_n_addr_cells(cpu));
> +        addr = (paddr_t) dt_read_number(prop, dt_n_addr_cells(cpu));
>  
>          hwid = addr;
>          if ( hwid != addr )
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-17 17:43 ` [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size Ayan Kumar Halder
  2023-01-18  8:40   ` Jan Beulich
@ 2023-01-19 23:24   ` Stefano Stabellini
  2023-02-06 19:21     ` Ayan Kumar Halder
  2023-01-20 10:34   ` Julien Grall
  2 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:24 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> One should now be able to use 'paddr_t' to represent address and size.
> Consequently, one should use 'PRIpaddr' as a format specifier for paddr_t.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> 
> Changes from -
> 
> v1 - 1. Rebased the patch.
> 
>  xen/arch/arm/domain_build.c        |  9 +++++----
>  xen/arch/arm/gic-v3.c              |  2 +-
>  xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>  xen/drivers/char/exynos4210-uart.c |  2 +-
>  xen/drivers/char/ns16550.c         |  8 ++++----
>  xen/drivers/char/omap-uart.c       |  2 +-
>  xen/drivers/char/pl011.c           |  4 ++--
>  xen/drivers/char/scif-uart.c       |  2 +-
>  xen/drivers/passthrough/arm/smmu.c |  6 +++---
>  9 files changed, 31 insertions(+), 30 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 72b9afbb4c..cf8ae37a14 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
>      dt_for_each_device_node( dt_host, np )
>      {
>          unsigned int naddr;
> -        u64 addr, size;
> +        paddr_t addr, size;
>  
>          naddr = dt_number_of_address(np);
>  
> @@ -2445,7 +2445,7 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev,
>      unsigned int naddr;
>      unsigned int i;
>      int res;
> -    u64 addr, size;
> +    paddr_t addr, size;
>      bool own_device = !dt_device_for_passthrough(dev);
>      /*
>       * We want to avoid mapping the MMIO in dom0 for the following cases:
> @@ -2941,9 +2941,10 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
>          if ( res )
>          {
>              printk(XENLOG_ERR "Unable to permit to dom%d access to"
> -                   " 0x%"PRIx64" - 0x%"PRIx64"\n",
> +                   " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
>                     kinfo->d->domain_id,
> -                   mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1);
> +                   (paddr_t) (mstart & PAGE_MASK),
> +                   (paddr_t) (PAGE_ALIGN(mstart + size) - 1));

Why do you need the casts here? mstart is already defined as paddr_t


>              return res;
>          }
>  
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index bb59ea94cd..391dfa53d7 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -1393,7 +1393,7 @@ static void __init gicv3_dt_init(void)
>  
>      for ( i = 0; i < gicv3.rdist_count; i++ )
>      {
> -        uint64_t rdist_base, rdist_size;
> +        paddr_t rdist_base, rdist_size;
>  
>          res = dt_device_get_address(node, 1 + i, &rdist_base, &rdist_size);
>          if ( res )
> diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
> index 6560507092..f79fad9957 100644
> --- a/xen/arch/arm/platforms/exynos5.c
> +++ b/xen/arch/arm/platforms/exynos5.c
> @@ -42,8 +42,8 @@ static int exynos5_init_time(void)
>      void __iomem *mct;
>      int rc;
>      struct dt_device_node *node;
> -    u64 mct_base_addr;
> -    u64 size;
> +    paddr_t mct_base_addr;
> +    paddr_t size;
>  
>      node = dt_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct");
>      if ( !node )
> @@ -59,7 +59,7 @@ static int exynos5_init_time(void)
>          return -ENXIO;
>      }
>  
> -    dprintk(XENLOG_INFO, "mct_base_addr: %016llx size: %016llx\n",
> +    dprintk(XENLOG_INFO, "mct_base_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"\n",
>              mct_base_addr, size);
>  
>      mct = ioremap_nocache(mct_base_addr, size);
> @@ -97,9 +97,9 @@ static int __init exynos5_smp_init(void)
>      struct dt_device_node *node;
>      void __iomem *sysram;
>      char *compatible;
> -    u64 sysram_addr;
> -    u64 size;
> -    u64 sysram_offset;
> +    paddr_t sysram_addr;
> +    paddr_t size;
> +    paddr_t sysram_offset;
>      int rc;
>  
>      node = dt_find_compatible_node(NULL, NULL, "samsung,secure-firmware");
> @@ -131,7 +131,7 @@ static int __init exynos5_smp_init(void)
>          dprintk(XENLOG_ERR, "Error in %s\n", compatible);
>          return -ENXIO;
>      }
> -    dprintk(XENLOG_INFO, "sysram_addr: %016llx size: %016llx offset: %016llx\n",
> +    dprintk(XENLOG_INFO,"sysram_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"offset: 0x%"PRIpaddr"\n",
>              sysram_addr, size, sysram_offset);
>  
>      sysram = ioremap_nocache(sysram_addr, size);
> @@ -189,7 +189,7 @@ static int exynos5_cpu_power_up(void __iomem *power, int cpu)
>      return 0;
>  }
>  
> -static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
> +static int exynos5_get_pmu_baseandsize(paddr_t *power_base_addr, paddr_t *size)
>  {
>      struct dt_device_node *node;
>      int rc;
> @@ -215,7 +215,7 @@ static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
>          return -ENXIO;
>      }
>  
> -    dprintk(XENLOG_DEBUG, "power_base_addr: %016llx size: %016llx\n",
> +    dprintk(XENLOG_DEBUG, "power_base_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"\n",
>              *power_base_addr, *size);
>  
>      return 0;
> @@ -223,8 +223,8 @@ static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
>  
>  static int exynos5_cpu_up(int cpu)
>  {
> -    u64 power_base_addr;
> -    u64 size;
> +    paddr_t power_base_addr;
> +    paddr_t size;
>      void __iomem *power;
>      int rc;
>  
> @@ -256,8 +256,8 @@ static int exynos5_cpu_up(int cpu)
>  
>  static void exynos5_reset(void)
>  {
> -    u64 power_base_addr;
> -    u64 size;
> +    paddr_t power_base_addr;
> +    paddr_t size;
>      void __iomem *pmu;
>      int rc;
>  
> diff --git a/xen/drivers/char/exynos4210-uart.c b/xen/drivers/char/exynos4210-uart.c
> index 43aaf02e18..32cc8c78b5 100644
> --- a/xen/drivers/char/exynos4210-uart.c
> +++ b/xen/drivers/char/exynos4210-uart.c
> @@ -303,7 +303,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
>      const char *config = data;
>      struct exynos4210_uart *uart;
>      int res;
> -    u64 addr, size;
> +    paddr_t addr, size;
>  
>      if ( strcmp(config, "") )
>          printk("WARNING: UART configuration is not supported\n");
> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
> index 58d0ccd889..8ef895a2bb 100644
> --- a/xen/drivers/char/ns16550.c
> +++ b/xen/drivers/char/ns16550.c
> @@ -42,8 +42,8 @@
>  
>  static struct ns16550 {
>      int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
> -    u64 io_base;   /* I/O port or memory-mapped I/O address. */
> -    u64 io_size;
> +    paddr_t io_base;   /* I/O port or memory-mapped I/O address. */
> +    paddr_t io_size;
>      int reg_shift; /* Bits to shift register offset by */
>      int reg_width; /* Size of access to use, the registers
>                      * themselves are still bytes */
> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst uart_config[] =
>  static int __init
>  pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>  {
> -    u64 orig_base = uart->io_base;
> +    paddr_t orig_base = uart->io_base;
>      unsigned int b, d, f, nextf, i;
>  
>      /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>                      else
>                          size = len & PCI_BASE_ADDRESS_MEM_MASK;
>  
> -                    uart->io_base = ((u64)bar_64 << 32) |
> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>                                      (bar & PCI_BASE_ADDRESS_MEM_MASK);
>                  }
>                  /* IO based */
> diff --git a/xen/drivers/char/omap-uart.c b/xen/drivers/char/omap-uart.c
> index d6a5d59aa2..3b53e1909a 100644
> --- a/xen/drivers/char/omap-uart.c
> +++ b/xen/drivers/char/omap-uart.c
> @@ -324,7 +324,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
>      struct omap_uart *uart;
>      u32 clkspec;
>      int res;
> -    u64 addr, size;
> +    paddr_t addr, size;
>  
>      if ( strcmp(config, "") )
>          printk("WARNING: UART configuration is not supported\n");
> diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c
> index be67242bc0..256ec11e3f 100644
> --- a/xen/drivers/char/pl011.c
> +++ b/xen/drivers/char/pl011.c
> @@ -222,7 +222,7 @@ static struct uart_driver __read_mostly pl011_driver = {
>      .vuart_info   = pl011_vuart,
>  };
>  
> -static int __init pl011_uart_init(int irq, u64 addr, u64 size, bool sbsa)
> +static int __init pl011_uart_init(int irq, paddr_t addr, paddr_t size, bool sbsa)
>  {
>      struct pl011 *uart;
>  
> @@ -258,7 +258,7 @@ static int __init pl011_dt_uart_init(struct dt_device_node *dev,
>  {
>      const char *config = data;
>      int res;
> -    u64 addr, size;
> +    paddr_t addr, size;
>  
>      if ( strcmp(config, "") )
>      {
> diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
> index 2fccafe340..b425881d06 100644
> --- a/xen/drivers/char/scif-uart.c
> +++ b/xen/drivers/char/scif-uart.c
> @@ -311,7 +311,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
>      const char *config = data;
>      struct scif_uart *uart;
>      int res;
> -    u64 addr, size;
> +    paddr_t addr, size;
>  
>      if ( strcmp(config, "") )
>          printk("WARNING: UART configuration is not supported\n");
> diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
> index 0a514821b3..490d253d44 100644
> --- a/xen/drivers/passthrough/arm/smmu.c
> +++ b/xen/drivers/passthrough/arm/smmu.c
> @@ -73,8 +73,8 @@
>  /* Xen: Helpers to get device MMIO and IRQs */
>  struct resource
>  {
> -	u64 addr;
> -	u64 size;
> +	paddr_t addr;
> +	paddr_t size;
>  	unsigned int type;
>  };
>  
> @@ -169,7 +169,7 @@ static void __iomem *devm_ioremap_resource(struct device *dev,
>  	ptr = ioremap_nocache(res->addr, res->size);
>  	if (!ptr) {
>  		dev_err(dev,
> -			"ioremap failed (addr 0x%"PRIx64" size 0x%"PRIx64")\n",
> +			"ioremap failed (addr 0x%"PRIpaddr" size 0x%"PRIpaddr")\n",
>  			res->addr, res->size);
>  		return ERR_PTR(-ENOMEM);
>  	}
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t
  2023-01-19 23:20   ` Stefano Stabellini
@ 2023-01-19 23:34     ` Stefano Stabellini
  2023-01-20 10:16       ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:34 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ayan Kumar Halder, xen-devel, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Thu, 19 Jan 2023, Stefano Stabellini wrote:
> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> > In future, we wish to support 32 bit physical address.
> > However, one can only read u64 values from the DT. Thus, we need to
> > typecast the values appropriately from u64 to paddr_t.
> > 
> > device_tree_get_reg() should now be able to return paddr_t. This is
> > invoked by various callers to get DT address and size.
> > Similarly, dt_read_number() is invoked as well to get DT address and
> > size. The return value is typecasted to paddr_t.
> > fdt_get_mem_rsv() can only accept u64 values. So, we provide a warpper
> > for this called fdt_get_mem_rsv_paddr() which will do the necessary
> > typecasting before invoking fdt_get_mem_rsv() and while returning.
> > 
> > Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> 
> I know we discussed this before and you implemented exactly what we
> suggested, but now looking at this patch I think we should do the
> following:
> 
> - also add a wrapper for dt_read_number, something like
>   dt_read_number_paddr that returns paddr
> - add a check for the top 32-bit being zero in all the wrappers
>   (dt_read_number_paddr, device_tree_get_reg, fdt_get_mem_rsv_paddr)
>   when paddr!=uint64_t. In case the top 32-bit are != zero I think we
>   should print an error
> 
> Julien, I remember you were concerned about BUG_ON/panic/ASSERT and I
> agree with you there (especially considering Vikram's device tree
> overlay series). So here I am only suggesting to check truncation and
> printk a message, not panic. Would you be OK with that?
> 
> Last comment, maybe we could add fdt_get_mem_rsv_paddr to setup.h
> instead of introducing xen/arch/arm/include/asm/device_tree.h, given
> that we already have device tree definitions there
> (device_tree_get_reg). I am OK either way.
 
Actually I noticed you also add dt_device_get_paddr to
xen/arch/arm/include/asm/device_tree.h. So it sounds like it is a good
idea to introduce xen/arch/arm/include/asm/device_tree.h, and we could
also move the declarations of device_tree_get_reg, device_tree_get_u32
there.


 
> > ---
> > 
> > Changes from
> > 
> > v1 - 1. Dropped "[XEN v1 2/9] xen/arm: Define translate_dt_address_size() for the translation between u64 and paddr_t" and
> > "[XEN v1 4/9] xen/arm: Use translate_dt_address_size() to translate between device tree addr/size and paddr_t", instead
> > this approach achieves the same purpose.
> > 
> > 2. No need to check for truncation while converting values from u64 to paddr_t.
> > 
> >  xen/arch/arm/bootfdt.c                 | 23 +++++++++------
> >  xen/arch/arm/domain_build.c            |  2 +-
> >  xen/arch/arm/include/asm/device_tree.h | 40 ++++++++++++++++++++++++++
> >  xen/arch/arm/include/asm/setup.h       |  2 +-
> >  xen/arch/arm/setup.c                   | 14 ++++-----
> >  xen/arch/arm/smpboot.c                 |  2 +-
> >  6 files changed, 65 insertions(+), 18 deletions(-)
> >  create mode 100644 xen/arch/arm/include/asm/device_tree.h
> > 
> > diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
> > index 0085c28d74..f536a3f3ab 100644
> > --- a/xen/arch/arm/bootfdt.c
> > +++ b/xen/arch/arm/bootfdt.c
> > @@ -11,9 +11,9 @@
> >  #include <xen/efi.h>
> >  #include <xen/device_tree.h>
> >  #include <xen/lib.h>
> > -#include <xen/libfdt/libfdt.h>
> >  #include <xen/sort.h>
> >  #include <xsm/xsm.h>
> > +#include <asm/device_tree.h>
> >  #include <asm/setup.h>
> >  
> >  static bool __init device_tree_node_matches(const void *fdt, int node,
> > @@ -53,10 +53,15 @@ static bool __init device_tree_node_compatible(const void *fdt, int node,
> >  }
> >  
> >  void __init device_tree_get_reg(const __be32 **cell, u32 address_cells,
> > -                                u32 size_cells, u64 *start, u64 *size)
> > +                                u32 size_cells, paddr_t *start, paddr_t *size)
> >  {
> > -    *start = dt_next_cell(address_cells, cell);
> > -    *size = dt_next_cell(size_cells, cell);
> > +    /*
> > +     * dt_next_cell will return u64 whereas paddr_t may be u64 or u32. Thus, one
> > +     * needs to cast paddr_t to u32. Note that we do not check for truncation as
> > +     * it is user's responsibility to provide the correct values in the DT.
> > +     */
> > +    *start = (paddr_t) dt_next_cell(address_cells, cell);
> > +    *size = (paddr_t) dt_next_cell(size_cells, cell);
> >  }
> >  
> >  static int __init device_tree_get_meminfo(const void *fdt, int node,
> > @@ -326,7 +331,7 @@ static int __init process_chosen_node(const void *fdt, int node,
> >          printk("linux,initrd-start property has invalid length %d\n", len);
> >          return -EINVAL;
> >      }
> > -    start = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> > +    start = (paddr_t) dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> >  
> >      prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
> >      if ( !prop )
> > @@ -339,7 +344,7 @@ static int __init process_chosen_node(const void *fdt, int node,
> >          printk("linux,initrd-end property has invalid length %d\n", len);
> >          return -EINVAL;
> >      }
> > -    end = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> > +    end = (paddr_t) dt_read_number((void *)&prop->data, dt_size_to_cells(len));
> >  
> >      if ( start >= end )
> >      {
> > @@ -594,9 +599,11 @@ static void __init early_print_info(void)
> >      for ( i = 0; i < nr_rsvd; i++ )
> >      {
> >          paddr_t s, e;
> > -        if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 )
> > +
> > +        if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &s, &e) < 0 )
> >              continue;
> > -        /* fdt_get_mem_rsv returns length */
> > +
> > +        /* fdt_get_mem_rsv_paddr returns length */
> >          e += s;
> >          printk(" RESVD[%u]: %"PRIpaddr" - %"PRIpaddr"\n", i, s, e);
> >      }
> > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> > index f904f12408..72b9afbb4c 100644
> > --- a/xen/arch/arm/domain_build.c
> > +++ b/xen/arch/arm/domain_build.c
> > @@ -949,7 +949,7 @@ static int __init process_shm(struct domain *d, struct kernel_info *kinfo,
> >          BUG_ON(!prop);
> >          cells = (const __be32 *)prop->value;
> >          device_tree_get_reg(&cells, addr_cells, addr_cells, &pbase, &gbase);
> > -        psize = dt_read_number(cells, size_cells);
> > +        psize = (paddr_t) dt_read_number(cells, size_cells);
> >          if ( !IS_ALIGNED(pbase, PAGE_SIZE) || !IS_ALIGNED(gbase, PAGE_SIZE) )
> >          {
> >              printk("%pd: physical address 0x%"PRIpaddr", or guest address 0x%"PRIpaddr" is not suitably aligned.\n",
> > diff --git a/xen/arch/arm/include/asm/device_tree.h b/xen/arch/arm/include/asm/device_tree.h
> > new file mode 100644
> > index 0000000000..51e0f0ae20
> > --- /dev/null
> > +++ b/xen/arch/arm/include/asm/device_tree.h
> > @@ -0,0 +1,40 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * xen/arch/arm/include/asm/device_tree.h
> > + * 
> > + * Wrapper functions for device tree. This helps to convert dt values
> > + * between u64 and paddr_t.
> > + *
> > + * Copyright (C) 2023, Advanced Micro Devices, Inc. All Rights Reserved.
> > + */
> > +
> > +#ifndef __ARCH_ARM_DEVICE_TREE__
> > +#define __ARCH_ARM_DEVICE_TREE__
> > +
> > +#include <xen/libfdt/libfdt.h>
> > +
> > +inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
> > +                                 paddr_t *address,
> > +                                 paddr_t *size)
> > +{
> > +    uint64_t dt_addr;
> > +    uint64_t dt_size;
> > +    int ret = 0;
> > +
> > +    ret = fdt_get_mem_rsv(fdt, n, &dt_addr, &dt_size);
> > +
> > +    *address = (paddr_t) dt_addr;
> > +    *size = (paddr_t) dt_size;
> > +
> > +    return ret;
> > +}
> > +
> > +#endif /* __ARCH_ARM_DEVICE_TREE__ */
> > +/*
> > + * Local variables:
> > + * mode: C
> > + * c-file-style: "BSD"
> > + * c-basic-offset: 4
> > + * indent-tabs-mode: nil
> > + * End:
> > + */
> > diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
> > index a926f30a2b..6105e5cae3 100644
> > --- a/xen/arch/arm/include/asm/setup.h
> > +++ b/xen/arch/arm/include/asm/setup.h
> > @@ -158,7 +158,7 @@ extern uint32_t hyp_traps_vector[];
> >  void init_traps(void);
> >  
> >  void device_tree_get_reg(const __be32 **cell, u32 address_cells,
> > -                         u32 size_cells, u64 *start, u64 *size);
> > +                         u32 size_cells, paddr_t *start, paddr_t *size);
> >  
> >  u32 device_tree_get_u32(const void *fdt, int node,
> >                          const char *prop_name, u32 dflt);
> > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> > index 1f26f67b90..da13439e62 100644
> > --- a/xen/arch/arm/setup.c
> > +++ b/xen/arch/arm/setup.c
> > @@ -29,7 +29,6 @@
> >  #include <xen/virtual_region.h>
> >  #include <xen/vmap.h>
> >  #include <xen/trace.h>
> > -#include <xen/libfdt/libfdt.h>
> >  #include <xen/acpi.h>
> >  #include <xen/warning.h>
> >  #include <asm/alternative.h>
> > @@ -39,6 +38,7 @@
> >  #include <asm/gic.h>
> >  #include <asm/cpuerrata.h>
> >  #include <asm/cpufeature.h>
> > +#include <asm/device_tree.h>
> >  #include <asm/platform.h>
> >  #include <asm/procinfo.h>
> >  #include <asm/setup.h>
> > @@ -222,11 +222,11 @@ static void __init dt_unreserved_regions(paddr_t s, paddr_t e,
> >      {
> >          paddr_t r_s, r_e;
> >  
> > -        if ( fdt_get_mem_rsv(device_tree_flattened, i, &r_s, &r_e ) < 0 )
> > +        if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &r_s, &r_e ) < 0 )
> >              /* If we can't read it, pretend it doesn't exist... */
> >              continue;
> >  
> > -        r_e += r_s; /* fdt_get_mem_rsv returns length */
> > +        r_e += r_s; /* fdt_get_mem_rsv_paddr returns length */
> >  
> >          if ( s < r_e && r_s < e )
> >          {
> > @@ -502,13 +502,13 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e,
> >      {
> >          paddr_t mod_s, mod_e;
> >  
> > -        if ( fdt_get_mem_rsv(device_tree_flattened,
> > -                             i - mi->nr_mods,
> > -                             &mod_s, &mod_e ) < 0 )
> > +        if ( fdt_get_mem_rsv_paddr(device_tree_flattened,
> > +                                   i - mi->nr_mods,
> > +                                   &mod_s, &mod_e ) < 0 )
> >              /* If we can't read it, pretend it doesn't exist... */
> >              continue;
> >  
> > -        /* fdt_get_mem_rsv returns length */
> > +        /* fdt_get_mem_rsv_paddr returns length */
> >          mod_e += mod_s;
> >  
> >          if ( s < mod_e && mod_s < e )
> > diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
> > index 412ae22869..ee59b1d379 100644
> > --- a/xen/arch/arm/smpboot.c
> > +++ b/xen/arch/arm/smpboot.c
> > @@ -159,7 +159,7 @@ static void __init dt_smp_init_cpus(void)
> >              continue;
> >          }
> >  
> > -        addr = dt_read_number(prop, dt_n_addr_cells(cpu));
> > +        addr = (paddr_t) dt_read_number(prop, dt_n_addr_cells(cpu));
> >  
> >          hwid = addr;
> >          if ( hwid != addr )
> > -- 
> > 2.17.1
> > 
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 06/11] xen/arm: Introduce a wrapper for dt_device_get_address() to handle paddr_t
  2023-01-17 17:43 ` [XEN v2 06/11] xen/arm: Introduce a wrapper for dt_device_get_address() to handle paddr_t Ayan Kumar Halder
@ 2023-01-19 23:35   ` Stefano Stabellini
  0 siblings, 0 replies; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:35 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> dt_device_get_address() can accept u64 only for address and size. The
> various callers will use 'paddr_t' datatype for address and size.
> 'paddr_t' is currently defined as u64, but we may support u32 as well.
> Thus, we need an appropriate wrapper which can handle this type
> conversion.
> 
> The callers will now invoke dt_device_get_paddr(). This inturn invokes
> dt_device_get_address() with u64 address/size. And then it typecasts
> the u64 address/size to paddr_t address/size.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> 
> Changes from -
> 
> v1 - 1. New patch introduced.
> 
>  xen/arch/arm/domain_build.c            |  5 +++--
>  xen/arch/arm/gic-v2.c                  | 11 ++++++-----
>  xen/arch/arm/gic-v3.c                  |  9 +++++----
>  xen/arch/arm/include/asm/device_tree.h | 19 +++++++++++++++++++
>  xen/arch/arm/platforms/exynos5.c       |  7 ++++---
>  xen/arch/arm/platforms/sunxi.c         |  3 ++-
>  xen/drivers/char/exynos4210-uart.c     |  3 ++-
>  xen/drivers/char/ns16550.c             |  3 ++-
>  xen/drivers/char/omap-uart.c           |  3 ++-
>  xen/drivers/char/pl011.c               |  3 ++-
>  xen/drivers/char/scif-uart.c           |  3 ++-
>  xen/drivers/passthrough/arm/smmu.c     |  3 ++-
>  12 files changed, 51 insertions(+), 21 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index cf8ae37a14..21199b624b 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -7,6 +7,7 @@
>  #include <xen/domain_page.h>
>  #include <xen/sched.h>
>  #include <xen/sizes.h>
> +#include <asm/device_tree.h>
>  #include <asm/irq.h>
>  #include <asm/regs.h>
>  #include <xen/errno.h>
> @@ -1672,7 +1673,7 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
>  
>          for ( i = 0; i < naddr; i++ )
>          {
> -            res = dt_device_get_address(np, i, &addr, &size);
> +            res = dt_device_get_paddr(np, i, &addr, &size);
>              if ( res )
>              {
>                  printk(XENLOG_ERR "Unable to retrieve address %u for %s\n",
> @@ -2500,7 +2501,7 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev,
>      /* Give permission and map MMIOs */
>      for ( i = 0; i < naddr; i++ )
>      {
> -        res = dt_device_get_address(dev, i, &addr, &size);
> +        res = dt_device_get_paddr(dev, i, &addr, &size);
>          if ( res )
>          {
>              printk(XENLOG_ERR "Unable to retrieve address %u for %s\n",
> diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
> index 5d4d298b86..5230c4ebaf 100644
> --- a/xen/arch/arm/gic-v2.c
> +++ b/xen/arch/arm/gic-v2.c
> @@ -24,6 +24,7 @@
>  #include <xen/acpi.h>
>  #include <acpi/actables.h>
>  #include <asm/p2m.h>
> +#include <asm/device_tree.h>
>  #include <asm/domain.h>
>  #include <asm/platform.h>
>  #include <asm/device.h>
> @@ -993,7 +994,7 @@ static void gicv2_extension_dt_init(const struct dt_device_node *node)
>              continue;
>  
>          /* Get register frame resource from DT. */
> -        if ( dt_device_get_address(v2m, 0, &addr, &size) )
> +        if ( dt_device_get_paddr(v2m, 0, &addr, &size) )
>              panic("GICv2: Cannot find a valid v2m frame address\n");
>  
>          /*
> @@ -1018,19 +1019,19 @@ static void __init gicv2_dt_init(void)
>      paddr_t vsize;
>      const struct dt_device_node *node = gicv2_info.node;
>  
> -    res = dt_device_get_address(node, 0, &dbase, NULL);
> +    res = dt_device_get_paddr(node, 0, &dbase, NULL);
>      if ( res )
>          panic("GICv2: Cannot find a valid address for the distributor\n");
>  
> -    res = dt_device_get_address(node, 1, &cbase, &csize);
> +    res = dt_device_get_paddr(node, 1, &cbase, &csize);
>      if ( res )
>          panic("GICv2: Cannot find a valid address for the CPU\n");
>  
> -    res = dt_device_get_address(node, 2, &hbase, NULL);
> +    res = dt_device_get_paddr(node, 2, &hbase, NULL);
>      if ( res )
>          panic("GICv2: Cannot find a valid address for the hypervisor\n");
>  
> -    res = dt_device_get_address(node, 3, &vbase, &vsize);
> +    res = dt_device_get_paddr(node, 3, &vbase, &vsize);
>      if ( res )
>          panic("GICv2: Cannot find a valid address for the virtual CPU\n");
>  
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index 391dfa53d7..58d2eb0690 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -29,6 +29,7 @@
>  
>  #include <asm/cpufeature.h>
>  #include <asm/device.h>
> +#include <asm/device_tree.h>
>  #include <asm/gic.h>
>  #include <asm/gic_v3_defs.h>
>  #include <asm/gic_v3_its.h>
> @@ -1377,7 +1378,7 @@ static void __init gicv3_dt_init(void)
>      int res, i;
>      const struct dt_device_node *node = gicv3_info.node;
>  
> -    res = dt_device_get_address(node, 0, &dbase, NULL);
> +    res = dt_device_get_paddr(node, 0, &dbase, NULL);
>      if ( res )
>          panic("GICv3: Cannot find a valid distributor address\n");
>  
> @@ -1395,7 +1396,7 @@ static void __init gicv3_dt_init(void)
>      {
>          paddr_t rdist_base, rdist_size;
>  
> -        res = dt_device_get_address(node, 1 + i, &rdist_base, &rdist_size);
> +        res = dt_device_get_paddr(node, 1 + i, &rdist_base, &rdist_size);
>          if ( res )
>              panic("GICv3: No rdist base found for region %d\n", i);
>  
> @@ -1417,10 +1418,10 @@ static void __init gicv3_dt_init(void)
>       * For GICv3 supporting GICv2, GICC and GICV base address will be
>       * provided.
>       */
> -    res = dt_device_get_address(node, 1 + gicv3.rdist_count,
> +    res = dt_device_get_paddr(node, 1 + gicv3.rdist_count,
>                                  &cbase, &csize);
>      if ( !res )
> -        dt_device_get_address(node, 1 + gicv3.rdist_count + 2,
> +        dt_device_get_paddr(node, 1 + gicv3.rdist_count + 2,
>                                &vbase, &vsize);
>  }
>  
> diff --git a/xen/arch/arm/include/asm/device_tree.h b/xen/arch/arm/include/asm/device_tree.h
> index 51e0f0ae20..7f58f1f278 100644
> --- a/xen/arch/arm/include/asm/device_tree.h
> +++ b/xen/arch/arm/include/asm/device_tree.h
> @@ -11,6 +11,7 @@
>  #ifndef __ARCH_ARM_DEVICE_TREE__
>  #define __ARCH_ARM_DEVICE_TREE__
>  
> +#include <xen/device_tree.h>
>  #include <xen/libfdt/libfdt.h>
>  
>  inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
> @@ -29,6 +30,24 @@ inline int fdt_get_mem_rsv_paddr(const void *fdt, int n,
>      return ret;
>  }
>  
> +inline int dt_device_get_paddr(const struct dt_device_node *dev,
> +                               unsigned int index, paddr_t *addr,
> +                               paddr_t *size)
> +{
> +    u64 dt_addr, dt_size;
> +    int ret;
> +
> +    ret = dt_device_get_address(dev, index, &dt_addr, &dt_size);
> +
> +    if ( addr )
> +        *addr = dt_addr;
> +
> +    if ( size )
> +        *size = dt_size;

I think we should check for truncation (top 32-bit != 0) and return an
error in that case.


> +    return ret;
> +}
> +
>  #endif /* __ARCH_ARM_DEVICE_TREE__ */
>  /*
>   * Local variables:
> diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
> index f79fad9957..55b6ac1e7e 100644
> --- a/xen/arch/arm/platforms/exynos5.c
> +++ b/xen/arch/arm/platforms/exynos5.c
> @@ -22,6 +22,7 @@
>  #include <xen/mm.h>
>  #include <xen/vmap.h>
>  #include <xen/delay.h>
> +#include <asm/device_tree.h>
>  #include <asm/platforms/exynos5.h>
>  #include <asm/platform.h>
>  #include <asm/io.h>
> @@ -52,7 +53,7 @@ static int exynos5_init_time(void)
>          return -ENXIO;
>      }
>  
> -    rc = dt_device_get_address(node, 0, &mct_base_addr, &size);
> +    rc = dt_device_get_paddr(node, 0, &mct_base_addr, &size);
>      if ( rc )
>      {
>          dprintk(XENLOG_ERR, "Error in \"samsung,exynos4210-mct\"\n");
> @@ -125,7 +126,7 @@ static int __init exynos5_smp_init(void)
>          return -ENXIO;
>      }
>  
> -    rc = dt_device_get_address(node, 0, &sysram_addr, &size);
> +    rc = dt_device_get_paddr(node, 0, &sysram_addr, &size);
>      if ( rc )
>      {
>          dprintk(XENLOG_ERR, "Error in %s\n", compatible);
> @@ -208,7 +209,7 @@ static int exynos5_get_pmu_baseandsize(paddr_t *power_base_addr, paddr_t *size)
>          return -ENXIO;
>      }
>  
> -    rc = dt_device_get_address(node, 0, power_base_addr, size);
> +    rc = dt_device_get_paddr(node, 0, power_base_addr, size);
>      if ( rc )
>      {
>          dprintk(XENLOG_ERR, "Error in \"samsung,exynos5XXX-pmu\"\n");
> diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c
> index e8e4d88bef..ce47f97507 100644
> --- a/xen/arch/arm/platforms/sunxi.c
> +++ b/xen/arch/arm/platforms/sunxi.c
> @@ -18,6 +18,7 @@
>  
>  #include <xen/mm.h>
>  #include <xen/vmap.h>
> +#include <asm/device_tree.h>
>  #include <asm/platform.h>
>  #include <asm/io.h>
>  
> @@ -50,7 +51,7 @@ static void __iomem *sunxi_map_watchdog(bool *new_wdt)
>          return NULL;
>      }
>  
> -    ret = dt_device_get_address(node, 0, &wdt_start, &wdt_len);
> +    ret = dt_device_get_paddr(node, 0, &wdt_start, &wdt_len);
>      if ( ret )
>      {
>          dprintk(XENLOG_ERR, "Cannot read watchdog register address\n");
> diff --git a/xen/drivers/char/exynos4210-uart.c b/xen/drivers/char/exynos4210-uart.c
> index 32cc8c78b5..6d2008c44f 100644
> --- a/xen/drivers/char/exynos4210-uart.c
> +++ b/xen/drivers/char/exynos4210-uart.c
> @@ -24,6 +24,7 @@
>  #include <xen/irq.h>
>  #include <xen/mm.h>
>  #include <asm/device.h>
> +#include <asm/device_tree.h>
>  #include <asm/exynos4210-uart.h>
>  #include <asm/io.h>
>  
> @@ -316,7 +317,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
>      uart->parity    = PARITY_NONE;
>      uart->stop_bits = 1;
>  
> -    res = dt_device_get_address(dev, 0, &addr, &size);
> +    res = dt_device_get_paddr(dev, 0, &addr, &size);
>      if ( res )
>      {
>          printk("exynos4210: Unable to retrieve the base"
> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
> index 8ef895a2bb..7226f3c2f7 100644
> --- a/xen/drivers/char/ns16550.c
> +++ b/xen/drivers/char/ns16550.c
> @@ -35,6 +35,7 @@
>  #include <asm/io.h>
>  #ifdef CONFIG_HAS_DEVICE_TREE
>  #include <asm/device.h>
> +#include <asm/device_tree.h>
>  #endif
>  #ifdef CONFIG_X86
>  #include <asm/fixmap.h>
> @@ -1757,7 +1758,7 @@ static int __init ns16550_uart_dt_init(struct dt_device_node *dev,
>      uart->parity    = UART_PARITY_NONE;
>      uart->stop_bits = 1;
>  
> -    res = dt_device_get_address(dev, 0, &uart->io_base, &uart->io_size);
> +    res = dt_device_get_paddr(dev, 0, &uart->io_base, &uart->io_size);
>      if ( res )
>          return res;
>  
> diff --git a/xen/drivers/char/omap-uart.c b/xen/drivers/char/omap-uart.c
> index 3b53e1909a..06200bc9f1 100644
> --- a/xen/drivers/char/omap-uart.c
> +++ b/xen/drivers/char/omap-uart.c
> @@ -15,6 +15,7 @@
>  #include <xen/init.h>
>  #include <xen/irq.h>
>  #include <xen/device_tree.h>
> +#include <asm/device_tree.h>
>  #include <asm/device.h>
>  #include <xen/errno.h>
>  #include <xen/mm.h>
> @@ -344,7 +345,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
>      uart->parity = UART_PARITY_NONE;
>      uart->stop_bits = 1;
>  
> -    res = dt_device_get_address(dev, 0, &addr, &size);
> +    res = dt_device_get_paddr(dev, 0, &addr, &size);
>      if ( res )
>      {
>          printk("omap-uart: Unable to retrieve the base"
> diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c
> index 256ec11e3f..b4c1d9d592 100644
> --- a/xen/drivers/char/pl011.c
> +++ b/xen/drivers/char/pl011.c
> @@ -26,6 +26,7 @@
>  #include <asm/device.h>
>  #include <xen/mm.h>
>  #include <xen/vmap.h>
> +#include <asm/device_tree.h>
>  #include <asm/pl011-uart.h>
>  #include <asm/io.h>
>  
> @@ -265,7 +266,7 @@ static int __init pl011_dt_uart_init(struct dt_device_node *dev,
>          printk("WARNING: UART configuration is not supported\n");
>      }
>  
> -    res = dt_device_get_address(dev, 0, &addr, &size);
> +    res = dt_device_get_paddr(dev, 0, &addr, &size);
>      if ( res )
>      {
>          printk("pl011: Unable to retrieve the base"
> diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
> index b425881d06..af14388f70 100644
> --- a/xen/drivers/char/scif-uart.c
> +++ b/xen/drivers/char/scif-uart.c
> @@ -26,6 +26,7 @@
>  #include <xen/mm.h>
>  #include <xen/delay.h>
>  #include <asm/device.h>
> +#include <asm/device_tree.h>
>  #include <asm/scif-uart.h>
>  #include <asm/io.h>
>  
> @@ -318,7 +319,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
>  
>      uart = &scif_com;
>  
> -    res = dt_device_get_address(dev, 0, &addr, &size);
> +    res = dt_device_get_paddr(dev, 0, &addr, &size);
>      if ( res )
>      {
>          printk("scif-uart: Unable to retrieve the base"
> diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
> index 490d253d44..0c89cb644e 100644
> --- a/xen/drivers/passthrough/arm/smmu.c
> +++ b/xen/drivers/passthrough/arm/smmu.c
> @@ -51,6 +51,7 @@
>  #include <xen/sizes.h>
>  #include <asm/atomic.h>
>  #include <asm/device.h>
> +#include <asm/device_tree.h>
>  #include <asm/io.h>
>  #include <asm/iommu_fwspec.h>
>  #include <asm/platform.h>
> @@ -101,7 +102,7 @@ static struct resource *platform_get_resource(struct platform_device *pdev,
>  
>  	switch (type) {
>  	case IORESOURCE_MEM:
> -		ret = dt_device_get_address(pdev, num, &res.addr, &res.size);
> +		ret = dt_device_get_paddr(pdev, num, &res.addr, &res.size);
>  
>  		return ((ret) ? NULL : &res);
>  
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 07/11] xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to SMMU_CBn_TTBR0
  2023-01-17 17:43 ` [XEN v2 07/11] xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to SMMU_CBn_TTBR0 Ayan Kumar Halder
@ 2023-01-19 23:40   ` Stefano Stabellini
  0 siblings, 0 replies; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:40 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> Refer ARM IHI 0062D.c ID070116 (SMMU 2.0 spec), 17-360, 17.3.9,
> SMMU_CBn_TTBR0 is a 64 bit register. Thus, one can use
> writeq_relaxed_non_atomic() to write to it instead of invoking
> writel_relaxed() twice for lower half and upper half of the register.
> 
> This also helps us as p2maddr is 'paddr_t' (which may be u32 in future).
> Thus, one can assign p2maddr to a 64 bit register and do the bit
> manipulations on it, to generate the value for SMMU_CBn_TTBR0.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
> Changes from -
> 
> v1 - 1. Extracted the patch from "[XEN v1 8/9] xen/arm: Other adaptations required to support 32bit paddr".
> Use writeq_relaxed_non_atomic() to write u64 register in a non-atomic
> fashion.
> 
>  xen/drivers/passthrough/arm/smmu.c | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
> index 0c89cb644e..84b6803b4e 100644
> --- a/xen/drivers/passthrough/arm/smmu.c
> +++ b/xen/drivers/passthrough/arm/smmu.c
> @@ -500,8 +500,7 @@ enum arm_smmu_s2cr_privcfg {
>  #define ARM_SMMU_CB_SCTLR		0x0
>  #define ARM_SMMU_CB_RESUME		0x8
>  #define ARM_SMMU_CB_TTBCR2		0x10
> -#define ARM_SMMU_CB_TTBR0_LO		0x20
> -#define ARM_SMMU_CB_TTBR0_HI		0x24
> +#define ARM_SMMU_CB_TTBR0		0x20
>  #define ARM_SMMU_CB_TTBCR		0x30
>  #define ARM_SMMU_CB_S1_MAIR0		0x38
>  #define ARM_SMMU_CB_FSR			0x58
> @@ -1084,6 +1083,7 @@ static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
>  static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
>  {
>  	u32 reg;
> +	u64 reg64;
>  	bool stage1;
>  	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>  	struct arm_smmu_device *smmu = smmu_domain->smmu;
> @@ -1178,12 +1178,13 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
>  	dev_notice(smmu->dev, "d%u: p2maddr 0x%"PRIpaddr"\n",
>  		   smmu_domain->cfg.domain->domain_id, p2maddr);
>  
> -	reg = (p2maddr & ((1ULL << 32) - 1));
> -	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
> -	reg = (p2maddr >> 32);
> +	reg64 = p2maddr;
> +
>  	if (stage1)
> -		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
> -	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
> +		reg64 |= (((uint64_t) (ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT))
> +		         << 32);
> +
> +	writeq_relaxed_non_atomic(reg64, cb_base + ARM_SMMU_CB_TTBR0);
>  
>  	/*
>  	 * TTBCR
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32"
  2023-01-17 17:43 ` [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32" Ayan Kumar Halder
@ 2023-01-19 23:43   ` Stefano Stabellini
  2023-01-20 10:39     ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:43 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> In the subsequent patch, we introduce "CONFIG_ARM_PA_32" to support
> 32 bit physical addresses. Thus, the code specific to
> "Large Page Address Extension" (ie LPAE) should be enclosed within
> "ifndef CONFIG_ARM_PA_32".
> 
> Refer xen/arch/arm/include/asm/short-desc.h, "short_desc_l1_supersec_t"
> unsigned int extbase1:4;    /* Extended base address, PA[35:32] */
> unsigned int extbase2:4;    /* Extended base address, PA[39:36] */
> 
> Thus, extbase1 and extbase2 are not valid when 32 bit physical addresses
> are supported.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>

This patch should be merged with patch 9: we shouldn't start to use a
new kconfig symbol before it is defined.


> ---
> 
> Changes from -
> v1 - 1. Extracted from "[XEN v1 8/9] xen/arm: Other adaptations required to support 32bit paddr".
> 
>  xen/arch/arm/guest_walk.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c
> index 43d3215304..0feb7b76ec 100644
> --- a/xen/arch/arm/guest_walk.c
> +++ b/xen/arch/arm/guest_walk.c
> @@ -154,8 +154,10 @@ static bool guest_walk_sd(const struct vcpu *v,
>              mask = (1ULL << L1DESC_SUPERSECTION_SHIFT) - 1;
>              *ipa = gva & mask;
>              *ipa |= (paddr_t)(pte.supersec.base) << L1DESC_SUPERSECTION_SHIFT;
> +#ifndef CONFIG_ARM_PA_32
>              *ipa |= (paddr_t)(pte.supersec.extbase1) << L1DESC_SUPERSECTION_EXT_BASE1_SHIFT;
>              *ipa |= (paddr_t)(pte.supersec.extbase2) << L1DESC_SUPERSECTION_EXT_BASE2_SHIFT;
> +#endif /* CONFIG_ARM_PA_32 */
>          }
>  
>          /* Set permissions so that the caller can check the flags by herself. */
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-18 13:19       ` Jan Beulich
@ 2023-01-19 23:48         ` Stefano Stabellini
  0 siblings, 0 replies; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-19 23:48 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ayan Kumar Halder, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis, xen-devel,
	Ayan Kumar Halder

On Wed, 18 Jan 2023, Jan Beulich wrote:
> On 18.01.2023 12:57, Ayan Kumar Halder wrote:
> > Hi Jan,
> > 
> > On 18/01/2023 08:50, Jan Beulich wrote:
> >> On 17.01.2023 18:43, Ayan Kumar Halder wrote:
> >>> --- a/xen/arch/arm/include/asm/types.h
> >>> +++ b/xen/arch/arm/include/asm/types.h
> >>> @@ -37,9 +37,16 @@ typedef signed long long s64;
> >>>   typedef unsigned long long u64;
> >>>   typedef u32 vaddr_t;
> >>>   #define PRIvaddr PRIx32
> >>> +#if defined(CONFIG_ARM_PA_32)
> >>> +typedef u32 paddr_t;
> >>> +#define INVALID_PADDR (~0UL)
> >>> +#define PADDR_SHIFT BITS_PER_LONG
> >>> +#define PRIpaddr PRIx32
> >>> +#else
> >> With our plan to consolidate basic type definitions into xen/types.h
> >> the use of ARM_PA_32 is problematic: Preferably we'd have an arch-
> >> independent Kconfig setting, much like Linux'es PHYS_ADDR_T_64BIT
> >> (I don't think we should re-use the name directly, as we have no
> >> phys_addr_t type), which each arch selects (or not) accordingly.
> >> Perhaps architectures already selecting 64BIT wouldn't need to do
> >> this explicitly, and instead 64BIT could select the new setting
> >> (or the new setting could default to Y when 64BIT=y).
> > 
> > Looking at some of the instances where 64BIT is currently used 
> > (xen/drivers/passthrough/arm/smmu.c), I understand that it is used to 
> > define the width of **virtual** address.
> > 
> > Thus, it would not conflict with ARM_PA_32 (which is for physical address).
> > 
> > Later on if we wish to introduce something similar to Linux's 
> > PHYS_ADDR_T_64BIT (which is arch agnostic), then ARM_PA_32 can be 
> > selected by "!PHYS_ADDR_T_64BIT" && "CONFIG_ARM_32". (We may decide to 
> > drop ARM_PA_32 config option, but we can still reuse ARM_PA_32 specific 
> > changes).
> > 
> > Also, then we will need to support 32 bit physical address (ie 
> > !PHYS_ADDR_T_64BIT) with 32 bit virtual address (ie !64BIT) and 64 bit 
> > virtual address (ie 64BIT).
> > 
> > Let's confine the current changes to Arm architecture only (as I don't 
> > have knowledge about x86 or RISCV). When similar changes will be done 
> > for other architectures, then we can think about introducing an 
> > architecture agnostic option.
> 
> I disagree, not the least with the present goal of reworking xen/types.h
> vs asm/types.h. By having an arch-independent Kconfig symbol, paddr_t
> could also be manufactured uniformly in xen/types.h.

Jan is only asking to introduce the new Kconfig symbol as an
arch-independent symbol. In other words, rename ARM_PA_32 to PADDR_32
(or something like that) and move the symbol to xen/arch/Kconfig.

I think that's reasonable. And PADDR_32 could be forced to always be
unselected on x86: I don't think Jan is asking you to rework the whole
of xen/arch/x86 and xen/commons to build on x86 with paddr_t set to
uint32_t.


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-01-17 17:43 ` [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA Ayan Kumar Halder
@ 2023-01-20  0:05   ` Stefano Stabellini
  2023-01-20 11:06   ` Julien Grall
  1 sibling, 0 replies; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-20  0:05 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
> "Virtualization Translation Control Register" for the bit descriptions.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>

Acked-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
> Changes from -
> 
> v1 - New patch.
> 
>  xen/arch/arm/p2m.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 948f199d84..cfdea55e71 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>      register_t val = VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>  
>  #ifdef CONFIG_ARM_32
> -    if ( p2m_ipa_bits < 40 )
> +    if ( p2m_ipa_bits < PADDR_BITS )
>          panic("P2M: Not able to support %u-bit IPA at the moment\n",
>                p2m_ipa_bits);
>  
> -    printk("P2M: 40-bit IPA\n");
> -    p2m_ipa_bits = 40;
> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
> +    p2m_ipa_bits = PADDR_BITS;
> +#ifdef CONFIG_ARM_PA_32
> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
> +#else
>      val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
> +#endif
>      val |= VTCR_SL0(0x1); /* P2M starts at first level */
>  #else /* CONFIG_ARM_64 */
>      static const struct {
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64
  2023-01-17 17:43 ` [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64 Ayan Kumar Halder
@ 2023-01-20  0:19   ` Stefano Stabellini
  2023-01-20 10:53     ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-20  0:19 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: xen-devel, sstabellini, stefano.stabellini, julien,
	Volodymyr_Babchuk, bertrand.marquis

On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> zeroeth_table_offset is not accessed by ARM_32.
> Also, when 32 bit physical addresses are used (ie ARM_PA_32=y), this
> causes an overflow.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> Changes from -
> 
> v1 - Removed the duplicate declaration for DECLARE_OFFSETS.
> 
>  xen/arch/arm/include/asm/lpae.h | 4 ++++
>  xen/arch/arm/mm.c               | 7 +------
>  2 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/xen/arch/arm/include/asm/lpae.h b/xen/arch/arm/include/asm/lpae.h
> index 3fdd5d0de2..2744e0eebf 100644
> --- a/xen/arch/arm/include/asm/lpae.h
> +++ b/xen/arch/arm/include/asm/lpae.h
> @@ -259,7 +259,11 @@ lpae_t mfn_to_xen_entry(mfn_t mfn, unsigned int attr);
>  #define first_table_offset(va)  TABLE_OFFSET(first_linear_offset(va))
>  #define second_table_offset(va) TABLE_OFFSET(second_linear_offset(va))
>  #define third_table_offset(va)  TABLE_OFFSET(third_linear_offset(va))
> +#ifdef CONFIG_ARM_64

Julien was asking for a selectable Kconfig option that would allow us to
have 32-bit paddr_t even on ARM_64. If we do that, assuming we are on
aarch64, and we set VTCR_T0SZ to 0x20, hence we get 32-bit IPA, are we
going to have a 3-level or a 4-level p2m pagetable?

In any case I think this should be:
#ifndef CONFIG_PADDR_32

And if it doesn't work today on aarch64 due to pagetable levels or other
reasons, than I would make CONFIG_PADDR_32 not (yet) selectable on
ARM_64 (until it is fixed).


>  #define zeroeth_table_offset(va)  TABLE_OFFSET(zeroeth_linear_offset(va))
> +#else
> +#define zeroeth_table_offset(va)  0

Rather than 0 it might be better to have 32, hence zeroing the input
address


> +#endif
>  
>  /*
>   * Macros to define page-tables:
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index fab54618ab..95784e0c59 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -207,12 +207,7 @@ void dump_pt_walk(paddr_t ttbr, paddr_t addr,
>  {
>      static const char *level_strs[4] = { "0TH", "1ST", "2ND", "3RD" };
>      const mfn_t root_mfn = maddr_to_mfn(ttbr);
> -    const unsigned int offsets[4] = {
> -        zeroeth_table_offset(addr),
> -        first_table_offset(addr),
> -        second_table_offset(addr),
> -        third_table_offset(addr)
> -    };
> +    DECLARE_OFFSETS(offsets, addr);
>      lpae_t pte, *mapping;
>      unsigned int level, root_table;
>  
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-19 22:54   ` Stefano Stabellini
@ 2023-01-20  9:32     ` Julien Grall
  2023-01-20 11:09       ` Ayan Kumar Halder
  2023-01-20 14:40       ` Michal Orzel
  0 siblings, 2 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-20  9:32 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

On 19/01/2023 22:54, Stefano Stabellini wrote:
> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
>> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
>> address.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> 
> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


I have committed the patch.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes()
  2023-01-19 23:02   ` Stefano Stabellini
@ 2023-01-20  9:48     ` Julien Grall
  2023-01-20  9:52       ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-01-20  9:48 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

On 19/01/2023 23:02, Stefano Stabellini wrote:
> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>> bankbase, banksize and bankend are used to hold values of type 'unsigned
>> long long'. This can be represented as 'uint64_t' instead of 'paddr_t'.
>> This will ensure consistency with allocate_static_memory() (where we use
>> 'uint64_t' for rambase and ramsize).
>>
>> In future, paddr_t can be used for 'uin32_t' as well to represent 32bit
>> physical addresses.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> 
> I saw that Julien commented about using unsigned long long. To be
> honest, given that we typically use explicitly-sized integers (which is
> a good thing) 

 From the CODING_STYLE:

"Fixed width types should only be used when a fixed width quantity is
meant (which for example may be a value read from or to be written to a
register)."

This is also how we used it in the Arm port so far.

> and unsigned long long is always uint64_t on all
> architectures, I can see the benefits of using uint64_t here.

 From my understanding of the C spec, the only requirement is that 
"unsigned long long" can fit a 2^64 - 1. So it may technically be bigger 
than 64-bit.

> 
> At the same time, I can see that the reason for change the type here is
> that we are dealing with ULL values, so it would make sense to use
> unsigned long long. >
> I cannot see any big problem/advantages either way, so I am OK with
> this patch. (Julien, if you prefer unsigned long long I am fine with
> that also.)

I don't mind too much here.

> 
> Acked-by: Stefano Stabellini <sstabellini@kernel.org>
> 
> 
> 
>> ---
>>
>> Changes from -
>>
>> v1 - Modified the title/commit message from "[XEN v1 6/9] xen/arm: Use 'u64' to represent 'unsigned long long"
>> and moved it earlier.
>>
>>   xen/arch/arm/domain_build.c | 6 +++---
>>   1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index 33a5945a2d..f904f12408 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -1726,9 +1726,9 @@ static int __init find_domU_holes(const struct kernel_info *kinfo,
>>                                     struct meminfo *ext_regions)
>>   {
>>       unsigned int i;
>> -    paddr_t bankend;
>> -    const paddr_t bankbase[] = GUEST_RAM_BANK_BASES;
>> -    const paddr_t banksize[] = GUEST_RAM_BANK_SIZES;
>> +    uint64_t bankend;
>> +    const uint64_t bankbase[] = GUEST_RAM_BANK_BASES;
>> +    const uint64_t banksize[] = GUEST_RAM_BANK_SIZES;
>>       int res = -ENOENT;
>>   
>>       for ( i = 0; i < GUEST_RAM_BANKS; i++ )
>> -- 
>> 2.17.1
>>

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes()
  2023-01-20  9:48     ` Julien Grall
@ 2023-01-20  9:52       ` Julien Grall
  0 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-20  9:52 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis



On 20/01/2023 09:48, Julien Grall wrote:
> Hi,
> 
> On 19/01/2023 23:02, Stefano Stabellini wrote:
>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>> bankbase, banksize and bankend are used to hold values of type 'unsigned
>>> long long'. This can be represented as 'uint64_t' instead of 'paddr_t'.
>>> This will ensure consistency with allocate_static_memory() (where we use
>>> 'uint64_t' for rambase and ramsize).
>>>
>>> In future, paddr_t can be used for 'uin32_t' as well to represent 32bit
>>> physical addresses.
>>>
>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>
>> I saw that Julien commented about using unsigned long long. To be
>> honest, given that we typically use explicitly-sized integers (which is
>> a good thing) 
> 
>  From the CODING_STYLE:
> 
> "Fixed width types should only be used when a fixed width quantity is
> meant (which for example may be a value read from or to be written to a
> register)."
> 
> This is also how we used it in the Arm port so far.
> 
>> and unsigned long long is always uint64_t on all
>> architectures, I can see the benefits of using uint64_t here.
> 
>  From my understanding of the C spec, the only requirement is that 
> "unsigned long long" can fit a 2^64 - 1. So it may technically be bigger 
> than 64-bit.
> 
>>
>> At the same time, I can see that the reason for change the type here is
>> that we are dealing with ULL values, so it would make sense to use
>> unsigned long long. >
>> I cannot see any big problem/advantages either way, so I am OK with
>> this patch. (Julien, if you prefer unsigned long long I am fine with
>> that also.)
> 
> I don't mind too much here.
> 
>>
>> Acked-by: Stefano Stabellini <sstabellini@kernel.org>

Committed.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t
  2023-01-19 23:34     ` Stefano Stabellini
@ 2023-01-20 10:16       ` Julien Grall
  2023-01-31 10:51         ` Ayan Kumar Halder
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-01-20 10:16 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Ayan Kumar Halder, xen-devel, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis

Hi,

I am answering to multiple e-mails at the same time.

On 19/01/2023 23:34, Stefano Stabellini wrote:
> On Thu, 19 Jan 2023, Stefano Stabellini wrote:
>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>> In future, we wish to support 32 bit physical address.
>>> However, one can only read u64 values from the DT. Thus, we need to

A cell in the DT is a 32-bit value. So you could read 32-bit value 
(address-size could be #1). It is just that our wrapper return 64-bit 
values because this is how we use the most.

>>> typecast the values appropriately from u64 to paddr_t.

C will perfectly be able to truncate a 64-bit to 32-bit value. So this 
is not a very good argument to explain why all of this is necessary.

>>>
>>> device_tree_get_reg() should now be able to return paddr_t. This is
>>> invoked by various callers to get DT address and size.
>>> Similarly, dt_read_number() is invoked as well to get DT address and
>>> size. The return value is typecasted to paddr_t.
>>> fdt_get_mem_rsv() can only accept u64 values. So, we provide a warpper

Typo: s/warpper/wrapper/

>>> for this called fdt_get_mem_rsv_paddr() which will do the necessary
>>> typecasting before invoking fdt_get_mem_rsv() and while returning.
>>>
>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>
>> I know we discussed this before and you implemented exactly what we
>> suggested, but now looking at this patch I think we should do the
>> following:
>>
>> - also add a wrapper for dt_read_number, something like
>>    dt_read_number_paddr that returns paddr

"number" and "paddr" pretty much means the same. I think it would be 
better to name it "dt_read_paddr".

>> - add a check for the top 32-bit being zero in all the wrappers
>>    (dt_read_number_paddr, device_tree_get_reg, fdt_get_mem_rsv_paddr)
>>    when paddr!=uint64_t. In case the top 32-bit are != zero I think we
>>    should print an error
>>
>> Julien, I remember you were concerned about BUG_ON/panic/ASSERT and I
>> agree with you there (especially considering Vikram's device tree
>> overlay series). So here I am only suggesting to check truncation and
>> printk a message, not panic. Would you be OK with that?

Aside dt_read_number(), I would expect that most of the helper can 
return an error. So if you want to check the truncation, then we should 
propagate the error.

>>
>> Last comment, maybe we could add fdt_get_mem_rsv_paddr to setup.h
>> instead of introducing xen/arch/arm/include/asm/device_tree.h, given
>> that we already have device tree definitions there
>> (device_tree_get_reg). I am OK either way.
>   
> Actually I noticed you also add dt_device_get_paddr to
> xen/arch/arm/include/asm/device_tree.h. So it sounds like it is a good
> idea to introduce xen/arch/arm/include/asm/device_tree.h, and we could
> also move the declarations of device_tree_get_reg, device_tree_get_u32
> there.

None of the helpers you mention sounds arm specific. So why should the 
be move an arch specific headers?

[...]

>>> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
>>> index 0085c28d74..f536a3f3ab 100644
>>> --- a/xen/arch/arm/bootfdt.c
>>> +++ b/xen/arch/arm/bootfdt.c
>>> @@ -11,9 +11,9 @@
>>>   #include <xen/efi.h>
>>>   #include <xen/device_tree.h>
>>>   #include <xen/lib.h>
>>> -#include <xen/libfdt/libfdt.h>
>>>   #include <xen/sort.h>
>>>   #include <xsm/xsm.h>
>>> +#include <asm/device_tree.h>
>>>   #include <asm/setup.h>
>>>   
>>>   static bool __init device_tree_node_matches(const void *fdt, int node,
>>> @@ -53,10 +53,15 @@ static bool __init device_tree_node_compatible(const void *fdt, int node,
>>>   }
>>>   
>>>   void __init device_tree_get_reg(const __be32 **cell, u32 address_cells,
>>> -                                u32 size_cells, u64 *start, u64 *size)
>>> +                                u32 size_cells, paddr_t *start, paddr_t *size)
>>>   {
>>> -    *start = dt_next_cell(address_cells, cell);
>>> -    *size = dt_next_cell(size_cells, cell);
>>> +    /*
>>> +     * dt_next_cell will return u64 whereas paddr_t may be u64 or u32. Thus, one
>>> +     * needs to cast paddr_t to u32. Note that we do not check for truncation as
>>> +     * it is user's responsibility to provide the correct values in the DT.
>>> +     */
>>> +    *start = (paddr_t) dt_next_cell(address_cells, cell);
>>> +    *size = (paddr_t) dt_next_cell(size_cells, cell);

There is no need for explicit cast here.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-17 17:43 ` [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size Ayan Kumar Halder
  2023-01-18  8:40   ` Jan Beulich
  2023-01-19 23:24   ` Stefano Stabellini
@ 2023-01-20 10:34   ` Julien Grall
  2 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-20 10:34 UTC (permalink / raw)
  To: Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

On 17/01/2023 17:43, Ayan Kumar Halder wrote:
> One should now be able to use 'paddr_t' to represent address and size.
> Consequently, one should use 'PRIpaddr' as a format specifier for paddr_t.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> 
> Changes from -
> 
> v1 - 1. Rebased the patch.
> 
>   xen/arch/arm/domain_build.c        |  9 +++++----
>   xen/arch/arm/gic-v3.c              |  2 +-
>   xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>   xen/drivers/char/exynos4210-uart.c |  2 +-
>   xen/drivers/char/ns16550.c         |  8 ++++----
>   xen/drivers/char/omap-uart.c       |  2 +-
>   xen/drivers/char/pl011.c           |  4 ++--
>   xen/drivers/char/scif-uart.c       |  2 +-
>   xen/drivers/passthrough/arm/smmu.c |  6 +++---
>   9 files changed, 31 insertions(+), 30 deletions(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 72b9afbb4c..cf8ae37a14 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
>       dt_for_each_device_node( dt_host, np )
>       {
>           unsigned int naddr;
> -        u64 addr, size;
> +        paddr_t addr, size;

Without the next patch, this change is incorrect because 
dt_device_get_address() expects a 64-bit value rather than paddr_t.

So the type change wants to be moved in the next patch. The same goes 
for any variable you modifed in this patch used by dt_device_get_address().

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32"
  2023-01-19 23:43   ` Stefano Stabellini
@ 2023-01-20 10:39     ` Julien Grall
  0 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-20 10:39 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Stefano,

On 19/01/2023 23:43, Stefano Stabellini wrote:
> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>> In the subsequent patch, we introduce "CONFIG_ARM_PA_32" to support
>> 32 bit physical addresses. Thus, the code specific to
>> "Large Page Address Extension" (ie LPAE) should be enclosed within
>> "ifndef CONFIG_ARM_PA_32".
>>
>> Refer xen/arch/arm/include/asm/short-desc.h, "short_desc_l1_supersec_t"
>> unsigned int extbase1:4;    /* Extended base address, PA[35:32] */
>> unsigned int extbase2:4;    /* Extended base address, PA[39:36] */
>>
>> Thus, extbase1 and extbase2 are not valid when 32 bit physical addresses
>> are supported.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> 
> This patch should be merged with patch 9: we shouldn't start to use a
> new kconfig symbol before it is defined.

I have asked the adaptation to be in a separate patch to avoid having a 
melting-pot patch.

So if you want the new Kconfig to be defined first, then we should 
reshuffle it.

BTW, the reshuffle will likely be necessary if you want to check for 
truncation in earlier patch.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64
  2023-01-20  0:19   ` Stefano Stabellini
@ 2023-01-20 10:53     ` Julien Grall
  2023-01-20 16:53       ` Stefano Stabellini
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-01-20 10:53 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

Title: For me "restrict" means that the code macro cannot be used if 
!ARM_64. But this is not the case here.

On 20/01/2023 00:19, Stefano Stabellini wrote:
> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>> zeroeth_table_offset is not accessed by ARM_32.

I don't quite understand this sentence. The helper is used by 32-bit 
arm. The output may not be used thought.

I would suggest to say that there no zeroeth level on Arm 32-bit. But...

>> Also, when 32 bit physical addresses are used (ie ARM_PA_32=y), this
>> causes an overflow.

... this is the most important part.

>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>> ---
>> Changes from -
>>
>> v1 - Removed the duplicate declaration for DECLARE_OFFSETS.
>>
>>   xen/arch/arm/include/asm/lpae.h | 4 ++++
>>   xen/arch/arm/mm.c               | 7 +------
>>   2 files changed, 5 insertions(+), 6 deletions(-)
>>
>> diff --git a/xen/arch/arm/include/asm/lpae.h b/xen/arch/arm/include/asm/lpae.h
>> index 3fdd5d0de2..2744e0eebf 100644
>> --- a/xen/arch/arm/include/asm/lpae.h
>> +++ b/xen/arch/arm/include/asm/lpae.h
>> @@ -259,7 +259,11 @@ lpae_t mfn_to_xen_entry(mfn_t mfn, unsigned int attr);
>>   #define first_table_offset(va)  TABLE_OFFSET(first_linear_offset(va))
>>   #define second_table_offset(va) TABLE_OFFSET(second_linear_offset(va))
>>   #define third_table_offset(va)  TABLE_OFFSET(third_linear_offset(va))
>> +#ifdef CONFIG_ARM_64
> 
> Julien was asking for a selectable Kconfig option that would allow us to
> have 32-bit paddr_t even on ARM_64. If we do that, assuming we are on
> aarch64, and we set VTCR_T0SZ to 0x20, hence we get 32-bit IPA, are we
> going to have a 3-level or a 4-level p2m pagetable?

It will start at level 1. So 3-level page-table.

> 
> In any case I think this should be:
> #ifndef CONFIG_PADDR_32

+1

> 
> And if it doesn't work today on aarch64 due to pagetable levels or other
> reasons, than I would make CONFIG_PADDR_32 not (yet) selectable on
> ARM_64 (until it is fixed).

+1

>>   #define zeroeth_table_offset(va)  TABLE_OFFSET(zeroeth_linear_offset(va))
>> +#else
>> +#define zeroeth_table_offset(va)  0
> 
> Rather than 0 it might be better to have 32, hence zeroing the input
> address
I don't understand why you suggest 32. The macro is meant to return the 
index in the 0th table. So return 0 is correct here.

> 
> 
>> +#endif
>>   
>>   /*
>>    * Macros to define page-tables:
>> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
>> index fab54618ab..95784e0c59 100644
>> --- a/xen/arch/arm/mm.c
>> +++ b/xen/arch/arm/mm.c
>> @@ -207,12 +207,7 @@ void dump_pt_walk(paddr_t ttbr, paddr_t addr,
>>   {
>>       static const char *level_strs[4] = { "0TH", "1ST", "2ND", "3RD" };
>>       const mfn_t root_mfn = maddr_to_mfn(ttbr);
>> -    const unsigned int offsets[4] = {
>> -        zeroeth_table_offset(addr),
>> -        first_table_offset(addr),
>> -        second_table_offset(addr),
>> -        third_table_offset(addr)
>> -    };
>> +    DECLARE_OFFSETS(offsets, addr);

This wants to be explained in the commit message.

>>       lpae_t pte, *mapping;
>>       unsigned int level, root_table;
>>   
>> -- 
>> 2.17.1
>>

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-01-17 17:43 ` [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA Ayan Kumar Halder
  2023-01-20  0:05   ` Stefano Stabellini
@ 2023-01-20 11:06   ` Julien Grall
  2023-02-07 15:34     ` Ayan Kumar Halder
  1 sibling, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-01-20 11:06 UTC (permalink / raw)
  To: Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Ayan,

On 17/01/2023 17:43, Ayan Kumar Halder wrote:
> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
> "Virtualization Translation Control Register" for the bit descriptions.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> Changes from -
> 
> v1 - New patch.
> 
>   xen/arch/arm/p2m.c | 10 +++++++---
>   1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 948f199d84..cfdea55e71 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>       register_t val = VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>   
>   #ifdef CONFIG_ARM_32
> -    if ( p2m_ipa_bits < 40 )
> +    if ( p2m_ipa_bits < PADDR_BITS )
>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>                 p2m_ipa_bits);
>   
> -    printk("P2M: 40-bit IPA\n");
> -    p2m_ipa_bits = 40;
> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
> +    p2m_ipa_bits = PADDR_BITS;
> +#ifdef CONFIG_ARM_PA_32
> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
> +#else
>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
> +#endif

I am wondering whether this is right time to switch to an array like the 
arm64 code? This would allow to use 32-bit IPA also when Xen support 
64-bit physical address.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20  9:32     ` Julien Grall
@ 2023-01-20 11:09       ` Ayan Kumar Halder
  2023-01-20 14:40       ` Michal Orzel
  1 sibling, 0 replies; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-20 11:09 UTC (permalink / raw)
  To: Julien Grall, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis


On 20/01/2023 09:32, Julien Grall wrote:
> Hi,
Hi Julien,
>
> On 19/01/2023 22:54, Stefano Stabellini wrote:
>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
>>> address.
>>>
>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>
>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>
>
> I have committed the patch.

Thanks for the reviews and commit. :)

Did you miss "[XEN v2 01/11] xen/ns16550: Remove unneeded truncation 
check in the DT init code" ?

- Ayan

>
> Cheers,
>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20  9:32     ` Julien Grall
  2023-01-20 11:09       ` Ayan Kumar Halder
@ 2023-01-20 14:40       ` Michal Orzel
  2023-01-20 15:09         ` Julien Grall
  1 sibling, 1 reply; 64+ messages in thread
From: Michal Orzel @ 2023-01-20 14:40 UTC (permalink / raw)
  To: Julien Grall, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hello,

On 20/01/2023 10:32, Julien Grall wrote:
> 
> 
> Hi,
> 
> On 19/01/2023 22:54, Stefano Stabellini wrote:
>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
>>> address.
>>>
>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>
>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> 
> 
> I have committed the patch.
The CI test jobs (static-mem) failed on this patch:
https://gitlab.com/xen-project/xen/-/pipelines/752911309

I took a look at it and this is because in the test script we
try to find a node whose unit-address does not have leading zeroes.
However, after this patch, we switched to PRIpaddr which is defined as 016lx/016llx and
we end up creating nodes like:

memory@0000000050000000

instead of:

memory@60000000

We could modify the script, but do we really want to create nodes
with leading zeroes? The dt spec does not mention it, although [1]
specifies that the Linux convention is not to have leading zeroes.

[1] https://elinux.org/Device_Tree_Linux

> 
> Cheers,
> 
> --
> Julien Grall
> 

~Michal


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20 14:40       ` Michal Orzel
@ 2023-01-20 15:09         ` Julien Grall
  2023-01-20 16:03           ` Michal Orzel
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-01-20 15:09 UTC (permalink / raw)
  To: Michal Orzel, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis



On 20/01/2023 14:40, Michal Orzel wrote:
> Hello,

Hi,

> 
> On 20/01/2023 10:32, Julien Grall wrote:
>>
>>
>> Hi,
>>
>> On 19/01/2023 22:54, Stefano Stabellini wrote:
>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
>>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
>>>> address.
>>>>
>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>
>>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>>
>>
>> I have committed the patch.
> The CI test jobs (static-mem) failed on this patch:
> https://gitlab.com/xen-project/xen/-/pipelines/752911309

Thanks for the report.

> 
> I took a look at it and this is because in the test script we
> try to find a node whose unit-address does not have leading zeroes.
> However, after this patch, we switched to PRIpaddr which is defined as 016lx/016llx and
> we end up creating nodes like:
> 
> memory@0000000050000000
> 
> instead of:
> 
> memory@60000000
> 
> We could modify the script, 

TBH, I think it was a mistake for the script to rely on how Xen describe 
the memory banks in the Device-Tree.

For instance, from my understanding, it would be valid for Xen to create 
a single node for all the banks or even omitting the unit-address if 
there is only one bank.

> but do we really want to create nodes
> with leading zeroes? The dt spec does not mention it, although [1]
> specifies that the Linux convention is not to have leading zeroes.

Reading through the spec in [2], it suggested the current naming is 
fine. That said the example match the Linux convention (I guess that's 
not surprising...).

I am open to remove the leading. However, I think the CI also needs to 
be updated (see above why).

Cheers,

[2] https://www.devicetree.org/

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20 15:09         ` Julien Grall
@ 2023-01-20 16:03           ` Michal Orzel
  2023-01-20 17:49             ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Michal Orzel @ 2023-01-20 16:03 UTC (permalink / raw)
  To: Julien Grall, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Julien,

On 20/01/2023 16:09, Julien Grall wrote:
> 
> 
> On 20/01/2023 14:40, Michal Orzel wrote:
>> Hello,
> 
> Hi,
> 
>>
>> On 20/01/2023 10:32, Julien Grall wrote:
>>>
>>>
>>> Hi,
>>>
>>> On 19/01/2023 22:54, Stefano Stabellini wrote:
>>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
>>>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
>>>>> address.
>>>>>
>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>
>>>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>>>
>>>
>>> I have committed the patch.
>> The CI test jobs (static-mem) failed on this patch:
>> https://gitlab.com/xen-project/xen/-/pipelines/752911309
> 
> Thanks for the report.
> 
>>
>> I took a look at it and this is because in the test script we
>> try to find a node whose unit-address does not have leading zeroes.
>> However, after this patch, we switched to PRIpaddr which is defined as 016lx/016llx and
>> we end up creating nodes like:
>>
>> memory@0000000050000000
>>
>> instead of:
>>
>> memory@60000000
>>
>> We could modify the script,
> 
> TBH, I think it was a mistake for the script to rely on how Xen describe
> the memory banks in the Device-Tree.
> 
> For instance, from my understanding, it would be valid for Xen to create
> a single node for all the banks or even omitting the unit-address if
> there is only one bank.
> 
>> but do we really want to create nodes
>> with leading zeroes? The dt spec does not mention it, although [1]
>> specifies that the Linux convention is not to have leading zeroes.
> 
> Reading through the spec in [2], it suggested the current naming is
> fine. That said the example match the Linux convention (I guess that's
> not surprising...).
> 
> I am open to remove the leading. However, I think the CI also needs to
> be updated (see above why).
Yes, the CI needs to be updated as well.
I'm in favor of removing leading zeroes because this is what Xen uses in all
the other places when creating nodes (or copying them from the host dtb) including xl
when creating dtb for domUs. Having a mismatch may be confusing and having a unit-address
with leading zeroes looks unusual.

> 
> Cheers,
> 
> [2] https://www.devicetree.org/
> 
> --
> Julien Grall

~Michal



^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64
  2023-01-20 10:53     ` Julien Grall
@ 2023-01-20 16:53       ` Stefano Stabellini
  0 siblings, 0 replies; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-20 16:53 UTC (permalink / raw)
  To: Julien Grall
  Cc: Stefano Stabellini, Ayan Kumar Halder, xen-devel,
	stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

On Fri, 20 Jan 2023, Julien Grall wrote:
> > >   #define zeroeth_table_offset(va)
> > > TABLE_OFFSET(zeroeth_linear_offset(va))
> > > +#else
> > > +#define zeroeth_table_offset(va)  0
> > 
> > Rather than 0 it might be better to have 32, hence zeroing the input
> > address
> I don't understand why you suggest 32. The macro is meant to return the index
> in the 0th table. So return 0 is correct here.

This suggestion was a mistake, 0 is fine.


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20 16:03           ` Michal Orzel
@ 2023-01-20 17:49             ` Julien Grall
  2023-01-20 18:08               ` Ayan Kumar Halder
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-01-20 17:49 UTC (permalink / raw)
  To: Michal Orzel, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis



On 20/01/2023 16:03, Michal Orzel wrote:
> Hi Julien,

Hi Michal,

> 
> On 20/01/2023 16:09, Julien Grall wrote:
>>
>>
>> On 20/01/2023 14:40, Michal Orzel wrote:
>>> Hello,
>>
>> Hi,
>>
>>>
>>> On 20/01/2023 10:32, Julien Grall wrote:
>>>>
>>>>
>>>> Hi,
>>>>
>>>> On 19/01/2023 22:54, Stefano Stabellini wrote:
>>>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>>>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The current
>>>>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a physical
>>>>>> address.
>>>>>>
>>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>>
>>>>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>>>>
>>>>
>>>> I have committed the patch.
>>> The CI test jobs (static-mem) failed on this patch:
>>> https://gitlab.com/xen-project/xen/-/pipelines/752911309
>>
>> Thanks for the report.
>>
>>>
>>> I took a look at it and this is because in the test script we
>>> try to find a node whose unit-address does not have leading zeroes.
>>> However, after this patch, we switched to PRIpaddr which is defined as 016lx/016llx and
>>> we end up creating nodes like:
>>>
>>> memory@0000000050000000
>>>
>>> instead of:
>>>
>>> memory@60000000
>>>
>>> We could modify the script,
>>
>> TBH, I think it was a mistake for the script to rely on how Xen describe
>> the memory banks in the Device-Tree.
>>
>> For instance, from my understanding, it would be valid for Xen to create
>> a single node for all the banks or even omitting the unit-address if
>> there is only one bank.
>>
>>> but do we really want to create nodes
>>> with leading zeroes? The dt spec does not mention it, although [1]
>>> specifies that the Linux convention is not to have leading zeroes.
>>
>> Reading through the spec in [2], it suggested the current naming is
>> fine. That said the example match the Linux convention (I guess that's
>> not surprising...).
>>
>> I am open to remove the leading. However, I think the CI also needs to
>> be updated (see above why).
> Yes, the CI needs to be updated as well.

Can either you or Ayan look at it?

> I'm in favor of removing leading zeroes because this is what Xen uses in all
> the other places when creating nodes (or copying them from the host dtb) including xl
> when creating dtb for domUs. Having a mismatch may be confusing and having a unit-address
> with leading zeroes looks unusual.

I decided to revert the patch mainly because it will be easier to review 
the fix if it is folded in this patch.

I would consider to create a wrapper on top of fdt_begin_node() that 
will take the name of the node and the unit. Something like:

/* XXX: Explain why the wrapper is needed */
static void domain_fdt_begin_node(void *fdt, const char *name, uint64_t 
unit)
{
    char buf[X];

    snprintf(buf, sizeof(buf), "%s@%"PRIx64, ...);
    /* XXX check the return of snprintf() */


    return fdt_begin_node(buf);
}

X would be a value that is large enough to accommodate the existing name.

The reason I don't suggest a new PRI* is because I can't think of a name 
that is short and descriptive enough to understand the different with 
the existing PRIpaddr.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20 17:49             ` Julien Grall
@ 2023-01-20 18:08               ` Ayan Kumar Halder
  2023-01-20 23:01                 ` Stefano Stabellini
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-20 18:08 UTC (permalink / raw)
  To: Julien Grall, Michal Orzel, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Julien/Michal,

On 20/01/2023 17:49, Julien Grall wrote:
>
>
> On 20/01/2023 16:03, Michal Orzel wrote:
>> Hi Julien,
>
> Hi Michal,
>
>>
>> On 20/01/2023 16:09, Julien Grall wrote:
>>>
>>>
>>> On 20/01/2023 14:40, Michal Orzel wrote:
>>>> Hello,
>>>
>>> Hi,
>>>
>>>>
>>>> On 20/01/2023 10:32, Julien Grall wrote:
>>>>>
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 19/01/2023 22:54, Stefano Stabellini wrote:
>>>>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>>>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>>>>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The 
>>>>>>> current
>>>>>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a 
>>>>>>> physical
>>>>>>> address.
>>>>>>>
>>>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>>>
>>>>>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>>>>>
>>>>>
>>>>> I have committed the patch.
>>>> The CI test jobs (static-mem) failed on this patch:
>>>> https://gitlab.com/xen-project/xen/-/pipelines/752911309
>>>
>>> Thanks for the report.
>>>
>>>>
>>>> I took a look at it and this is because in the test script we
>>>> try to find a node whose unit-address does not have leading zeroes.
>>>> However, after this patch, we switched to PRIpaddr which is defined 
>>>> as 016lx/016llx and
>>>> we end up creating nodes like:
>>>>
>>>> memory@0000000050000000
>>>>
>>>> instead of:
>>>>
>>>> memory@60000000
>>>>
>>>> We could modify the script,
>>>
>>> TBH, I think it was a mistake for the script to rely on how Xen 
>>> describe
>>> the memory banks in the Device-Tree.
>>>
>>> For instance, from my understanding, it would be valid for Xen to 
>>> create
>>> a single node for all the banks or even omitting the unit-address if
>>> there is only one bank.
>>>
>>>> but do we really want to create nodes
>>>> with leading zeroes? The dt spec does not mention it, although [1]
>>>> specifies that the Linux convention is not to have leading zeroes.
>>>
>>> Reading through the spec in [2], it suggested the current naming is
>>> fine. That said the example match the Linux convention (I guess that's
>>> not surprising...).
>>>
>>> I am open to remove the leading. However, I think the CI also needs to
>>> be updated (see above why).
>> Yes, the CI needs to be updated as well.
>
> Can either you or Ayan look at it?

Does this change match the expectation ?

diff --git a/automation/scripts/qemu-smoke-dom0less-arm64.sh 
b/automation/scripts/qemu-smoke-dom0less-arm64.sh
index 2b59346fdc..9f5e700f0e 100755
--- a/automation/scripts/qemu-smoke-dom0less-arm64.sh
+++ b/automation/scripts/qemu-smoke-dom0less-arm64.sh
@@ -20,7 +20,7 @@ if [[ "${test_variant}" == "static-mem" ]]; then
      domu_size="10000000"
      passed="${test_variant} test passed"
      domU_check="
-current=\$(hexdump -e '16/1 \"%02x\"' 
/proc/device-tree/memory@${domu_base}/reg 2>/dev/null)
+current=\$(hexdump -e '16/1 \"%02x\"' 
/proc/device-tree/memory@$[0-9]*/reg 2>/dev/null)
  expected=$(printf \"%016x%016x\" 0x${domu_base} 0x${domu_size})
  if [[ \"\${expected}\" == \"\${current}\" ]]; then
         echo \"${passed}\"

>
>> I'm in favor of removing leading zeroes because this is what Xen uses 
>> in all
>> the other places when creating nodes (or copying them from the host 
>> dtb) including xl
>> when creating dtb for domUs. Having a mismatch may be confusing and 
>> having a unit-address
>> with leading zeroes looks unusual.
>
> I decided to revert the patch mainly because it will be easier to 
> review the fix if it is folded in this patch.
>
> I would consider to create a wrapper on top of fdt_begin_node() that 
> will take the name of the node and the unit. Something like:
>
> /* XXX: Explain why the wrapper is needed */
> static void domain_fdt_begin_node(void *fdt, const char *name, 
> uint64_t unit)
> {
>    char buf[X];
>
>    snprintf(buf, sizeof(buf), "%s@%"PRIx64, ...);
>    /* XXX check the return of snprintf() */
>
>
>    return fdt_begin_node(buf);
> }
>
> X would be a value that is large enough to accommodate the existing name.
>
> The reason I don't suggest a new PRI* is because I can't think of a 
> name that is short and descriptive enough to understand the different 
> with the existing PRIpaddr.

Looks fine to me. I can incorporate the change in this existing patch.

- Ayan

>
> Cheers,
>


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20 18:08               ` Ayan Kumar Halder
@ 2023-01-20 23:01                 ` Stefano Stabellini
  2023-01-21 10:24                   ` Michal Orzel
  0 siblings, 1 reply; 64+ messages in thread
From: Stefano Stabellini @ 2023-01-20 23:01 UTC (permalink / raw)
  To: Ayan Kumar Halder
  Cc: Julien Grall, Michal Orzel, Stefano Stabellini,
	Ayan Kumar Halder, xen-devel, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis

[-- Attachment #1: Type: text/plain, Size: 3771 bytes --]

On Fri, 20 Jan 2023, Ayan Kumar Halder wrote:
> Hi Julien/Michal,
> 
> On 20/01/2023 17:49, Julien Grall wrote:
> > 
> > 
> > On 20/01/2023 16:03, Michal Orzel wrote:
> > > Hi Julien,
> > 
> > Hi Michal,
> > 
> > > 
> > > On 20/01/2023 16:09, Julien Grall wrote:
> > > > 
> > > > 
> > > > On 20/01/2023 14:40, Michal Orzel wrote:
> > > > > Hello,
> > > > 
> > > > Hi,
> > > > 
> > > > > 
> > > > > On 20/01/2023 10:32, Julien Grall wrote:
> > > > > > 
> > > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > On 19/01/2023 22:54, Stefano Stabellini wrote:
> > > > > > > On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
> > > > > > > > 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
> > > > > > > > 2. One should use 'PRIx64' to display 'u64' in hex format. The
> > > > > > > > current
> > > > > > > > use of 'PRIpaddr' for printing PTE is buggy as this is not a
> > > > > > > > physical
> > > > > > > > address.
> > > > > > > > 
> > > > > > > > Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> > > > > > > 
> > > > > > > Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> > > > > > 
> > > > > > 
> > > > > > I have committed the patch.
> > > > > The CI test jobs (static-mem) failed on this patch:
> > > > > https://gitlab.com/xen-project/xen/-/pipelines/752911309
> > > > 
> > > > Thanks for the report.
> > > > 
> > > > > 
> > > > > I took a look at it and this is because in the test script we
> > > > > try to find a node whose unit-address does not have leading zeroes.
> > > > > However, after this patch, we switched to PRIpaddr which is defined as
> > > > > 016lx/016llx and
> > > > > we end up creating nodes like:
> > > > > 
> > > > > memory@0000000050000000
> > > > > 
> > > > > instead of:
> > > > > 
> > > > > memory@60000000
> > > > > 
> > > > > We could modify the script,
> > > > 
> > > > TBH, I think it was a mistake for the script to rely on how Xen describe
> > > > the memory banks in the Device-Tree.
> > > > 
> > > > For instance, from my understanding, it would be valid for Xen to create
> > > > a single node for all the banks or even omitting the unit-address if
> > > > there is only one bank.
> > > > 
> > > > > but do we really want to create nodes
> > > > > with leading zeroes? The dt spec does not mention it, although [1]
> > > > > specifies that the Linux convention is not to have leading zeroes.
> > > > 
> > > > Reading through the spec in [2], it suggested the current naming is
> > > > fine. That said the example match the Linux convention (I guess that's
> > > > not surprising...).
> > > > 
> > > > I am open to remove the leading. However, I think the CI also needs to
> > > > be updated (see above why).
> > > Yes, the CI needs to be updated as well.
> > 
> > Can either you or Ayan look at it?
> 
> Does this change match the expectation ?
> 
> diff --git a/automation/scripts/qemu-smoke-dom0less-arm64.sh
> b/automation/scripts/qemu-smoke-dom0less-arm64.sh
> index 2b59346fdc..9f5e700f0e 100755
> --- a/automation/scripts/qemu-smoke-dom0less-arm64.sh
> +++ b/automation/scripts/qemu-smoke-dom0less-arm64.sh
> @@ -20,7 +20,7 @@ if [[ "${test_variant}" == "static-mem" ]]; then
>      domu_size="10000000"
>      passed="${test_variant} test passed"
>      domU_check="
> -current=\$(hexdump -e '16/1 \"%02x\"'
> /proc/device-tree/memory@${domu_base}/reg 2>/dev/null)
> +current=\$(hexdump -e '16/1 \"%02x\"' /proc/device-tree/memory@$[0-9]*/reg
> 2>/dev/null)
>  expected=$(printf \"%016x%016x\" 0x${domu_base} 0x${domu_size})
>  if [[ \"\${expected}\" == \"\${current}\" ]]; then
>         echo \"${passed}\"

We need to check for ${domu_base} with or without leading zeroes:

current=\$(hexdump -e '16/1 \"%02x\"' /proc/device-tree/memory@*(0)${domu_base}/reg 2>/dev/null)

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 02/11] xen/arm: Use the correct format specifier
  2023-01-20 23:01                 ` Stefano Stabellini
@ 2023-01-21 10:24                   ` Michal Orzel
  0 siblings, 0 replies; 64+ messages in thread
From: Michal Orzel @ 2023-01-21 10:24 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: Julien Grall, Ayan Kumar Halder, xen-devel, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis

Hi Stefano, Ayan, Julien

On 21/01/2023 00:01, Stefano Stabellini wrote:
> 
> 
> On Fri, 20 Jan 2023, Ayan Kumar Halder wrote:
>> Hi Julien/Michal,
>>
>> On 20/01/2023 17:49, Julien Grall wrote:
>>>
>>>
>>> On 20/01/2023 16:03, Michal Orzel wrote:
>>>> Hi Julien,
>>>
>>> Hi Michal,
>>>
>>>>
>>>> On 20/01/2023 16:09, Julien Grall wrote:
>>>>>
>>>>>
>>>>> On 20/01/2023 14:40, Michal Orzel wrote:
>>>>>> Hello,
>>>>>
>>>>> Hi,
>>>>>
>>>>>>
>>>>>> On 20/01/2023 10:32, Julien Grall wrote:
>>>>>>>
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 19/01/2023 22:54, Stefano Stabellini wrote:
>>>>>>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>>>>>>> 1. One should use 'PRIpaddr' to display 'paddr_t' variables.
>>>>>>>>> 2. One should use 'PRIx64' to display 'u64' in hex format. The
>>>>>>>>> current
>>>>>>>>> use of 'PRIpaddr' for printing PTE is buggy as this is not a
>>>>>>>>> physical
>>>>>>>>> address.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>>>>>
>>>>>>>> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
>>>>>>>
>>>>>>>
>>>>>>> I have committed the patch.
>>>>>> The CI test jobs (static-mem) failed on this patch:
>>>>>> https://gitlab.com/xen-project/xen/-/pipelines/752911309
>>>>>
>>>>> Thanks for the report.
>>>>>
>>>>>>
>>>>>> I took a look at it and this is because in the test script we
>>>>>> try to find a node whose unit-address does not have leading zeroes.
>>>>>> However, after this patch, we switched to PRIpaddr which is defined as
>>>>>> 016lx/016llx and
>>>>>> we end up creating nodes like:
>>>>>>
>>>>>> memory@0000000050000000
>>>>>>
>>>>>> instead of:
>>>>>>
>>>>>> memory@60000000
>>>>>>
>>>>>> We could modify the script,
>>>>>
>>>>> TBH, I think it was a mistake for the script to rely on how Xen describe
>>>>> the memory banks in the Device-Tree.
>>>>>
>>>>> For instance, from my understanding, it would be valid for Xen to create
>>>>> a single node for all the banks or even omitting the unit-address if
>>>>> there is only one bank.
>>>>>
>>>>>> but do we really want to create nodes
>>>>>> with leading zeroes? The dt spec does not mention it, although [1]
>>>>>> specifies that the Linux convention is not to have leading zeroes.
>>>>>
>>>>> Reading through the spec in [2], it suggested the current naming is
>>>>> fine. That said the example match the Linux convention (I guess that's
>>>>> not surprising...).
>>>>>
>>>>> I am open to remove the leading. However, I think the CI also needs to
>>>>> be updated (see above why).
>>>> Yes, the CI needs to be updated as well.
>>>
>>> Can either you or Ayan look at it?
>>
>> Does this change match the expectation ?
>>
>> diff --git a/automation/scripts/qemu-smoke-dom0less-arm64.sh
>> b/automation/scripts/qemu-smoke-dom0less-arm64.sh
>> index 2b59346fdc..9f5e700f0e 100755
>> --- a/automation/scripts/qemu-smoke-dom0less-arm64.sh
>> +++ b/automation/scripts/qemu-smoke-dom0less-arm64.sh
>> @@ -20,7 +20,7 @@ if [[ "${test_variant}" == "static-mem" ]]; then
>>      domu_size="10000000"
>>      passed="${test_variant} test passed"
>>      domU_check="
>> -current=\$(hexdump -e '16/1 \"%02x\"'
>> /proc/device-tree/memory@${domu_base}/reg 2>/dev/null)
>> +current=\$(hexdump -e '16/1 \"%02x\"' /proc/device-tree/memory@$[0-9]*/reg
>> 2>/dev/null)
>>  expected=$(printf \"%016x%016x\" 0x${domu_base} 0x${domu_size})
>>  if [[ \"\${expected}\" == \"\${current}\" ]]; then
>>         echo \"${passed}\"
> 
> We need to check for ${domu_base} with or without leading zeroes:
> 
> current=\$(hexdump -e '16/1 \"%02x\"' /proc/device-tree/memory@*(0)${domu_base}/reg 2>/dev/null)
This check is still bound to the way Xen exposes a memory node in a device tree which might change
as Julien suggested. We need to have a check not relying on device-tree.
My proposal would be to use /proc/iomem which prints memory ranges in %08x format.
This would look like as follows:

mem_range=$(printf \"%08x-%08x\" ${domu_base} $(( ${domu_base} + ${domu_size} - 1 )))
if grep -q \${mem_range} /proc/iomem; then
    echo ${passed}
fi

If you are ok with that, I will push a patch on Monday.

~Michal


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address
  2023-01-17 17:43 ` [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address Ayan Kumar Halder
  2023-01-18  8:50   ` Jan Beulich
  2023-01-18  9:18   ` Julien Grall
@ 2023-01-30 22:00   ` Julien Grall
  2 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-30 22:00 UTC (permalink / raw)
  To: Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

On 17/01/2023 17:43, Ayan Kumar Halder wrote:
> diff --git a/xen/arch/arm/include/asm/types.h b/xen/arch/arm/include/asm/types.h
> index 083acbd151..f9595b9098 100644
> --- a/xen/arch/arm/include/asm/types.h
> +++ b/xen/arch/arm/include/asm/types.h
> @@ -37,9 +37,16 @@ typedef signed long long s64;
>   typedef unsigned long long u64;
>   typedef u32 vaddr_t;
>   #define PRIvaddr PRIx32
> +#if defined(CONFIG_ARM_PA_32)
> +typedef u32 paddr_t;
> +#define INVALID_PADDR (~0UL)
> +#define PADDR_SHIFT BITS_PER_LONG
You define PADDR_SHIFT but don't seem to use it. Is it intended?

> +#define PRIpaddr PRIx32
> +#else
>   typedef u64 paddr_t;
>   #define INVALID_PADDR (~0ULL)
>   #define PRIpaddr "016llx"
> +#endif
>   typedef u32 register_t;
>   #define PRIregister "08x"
>   #elif defined (CONFIG_ARM_64)

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t
  2023-01-20 10:16       ` Julien Grall
@ 2023-01-31 10:51         ` Ayan Kumar Halder
  2023-01-31 15:57           ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-01-31 10:51 UTC (permalink / raw)
  To: Julien Grall, Stefano Stabellini
  Cc: Ayan Kumar Halder, xen-devel, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis


On 20/01/2023 10:16, Julien Grall wrote:
> Hi,
Hi Julien/Stefano,
>
> I am answering to multiple e-mails at the same time.
>
> On 19/01/2023 23:34, Stefano Stabellini wrote:
>> On Thu, 19 Jan 2023, Stefano Stabellini wrote:
>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>> In future, we wish to support 32 bit physical address.
>>>> However, one can only read u64 values from the DT. Thus, we need to
>
> A cell in the DT is a 32-bit value. So you could read 32-bit value 
> (address-size could be #1). It is just that our wrapper return 64-bit 
> values because this is how we use the most.
ok
>
>>>> typecast the values appropriately from u64 to paddr_t.
>
> C will perfectly be able to truncate a 64-bit to 32-bit value. So this 
> is not a very good argument to explain why all of this is necessary.
I can remove this line from the commit message. However, I have a 
related point below...
>
>
>>>>
>>>> device_tree_get_reg() should now be able to return paddr_t. This is
>>>> invoked by various callers to get DT address and size.
>>>> Similarly, dt_read_number() is invoked as well to get DT address and
>>>> size. The return value is typecasted to paddr_t.
>>>> fdt_get_mem_rsv() can only accept u64 values. So, we provide a warpper
>
> Typo: s/warpper/wrapper/
ok
>
>>>> for this called fdt_get_mem_rsv_paddr() which will do the necessary
>>>> typecasting before invoking fdt_get_mem_rsv() and while returning.
>>>>
>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>
>>> I know we discussed this before and you implemented exactly what we
>>> suggested, but now looking at this patch I think we should do the
>>> following:
>>>
>>> - also add a wrapper for dt_read_number, something like
>>>    dt_read_number_paddr that returns paddr
>
> "number" and "paddr" pretty much means the same. I think it would be 
> better to name it "dt_read_paddr".
ok
>
>>> - add a check for the top 32-bit being zero in all the wrappers
>>>    (dt_read_number_paddr, device_tree_get_reg, fdt_get_mem_rsv_paddr)
>>>    when paddr!=uint64_t. In case the top 32-bit are != zero I think we
>>>    should print an error
>>>
>>> Julien, I remember you were concerned about BUG_ON/panic/ASSERT and I
>>> agree with you there (especially considering Vikram's device tree
>>> overlay series). So here I am only suggesting to check truncation and
>>> printk a message, not panic. Would you be OK with that?
>
> Aside dt_read_number(), I would expect that most of the helper can 
> return an error. So if you want to check the truncation, then we 
> should propagate the error.
ok
>
>>>
>>> Last comment, maybe we could add fdt_get_mem_rsv_paddr to setup.h
>>> instead of introducing xen/arch/arm/include/asm/device_tree.h, given
>>> that we already have device tree definitions there
>>> (device_tree_get_reg). I am OK either way.
>>   Actually I noticed you also add dt_device_get_paddr to
>> xen/arch/arm/include/asm/device_tree.h. So it sounds like it is a good
>> idea to introduce xen/arch/arm/include/asm/device_tree.h, and we could
>> also move the declarations of device_tree_get_reg, device_tree_get_u32
>> there.
>
> None of the helpers you mention sounds arm specific. So why should the 
> be move an arch specific headers?

The functions (fdt_get_mem_rsv_paddr(), device_tree_get_reg(), 
device_tree_get_u32()) are currently used by Arm specific code only.

So, I thought of implementing fdt_get_mem_rsv_paddr() in 
xen/arch/arm/include/asm/device_tree.h.

However, I see your point as well. So the alternative approach would be :-

Approach 1) Implement fdt_get_mem_rsv_paddr() in 
./xen/include/xen/libfdt/libfdt.h.

However libfdt is imported from external sources, so I am not sure if 
this is the  best approach.

Approach 2) Rename fdt_get_mem_rsv_paddr() to dt_get_mem_rsv_paddr() and 
implement it in ./xen/include/xen/device_tree.h.

However, this will be an odd one as it invokes fdt_get_mem_rsv() for 
which we will have to include libfdt.h in device_tree.h.


So, I am biased towards having xen/arch/arm/include/asm/device_tree.h in 
which we can implement all the non-static fdt and dt functions (which 
are required by xen/arch/arm/*).

And then (as Stefano suggested), we can move the definitions of the 
following to xen/arch/arm/include/asm/device_tree.h.

device_tree_get_reg()

device_tree_get_u32()

device_tree_for_each_node()


Please let me know your thoughts.

>
> [...]
>
>>>> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
>>>> index 0085c28d74..f536a3f3ab 100644
>>>> --- a/xen/arch/arm/bootfdt.c
>>>> +++ b/xen/arch/arm/bootfdt.c
>>>> @@ -11,9 +11,9 @@
>>>>   #include <xen/efi.h>
>>>>   #include <xen/device_tree.h>
>>>>   #include <xen/lib.h>
>>>> -#include <xen/libfdt/libfdt.h>
>>>>   #include <xen/sort.h>
>>>>   #include <xsm/xsm.h>
>>>> +#include <asm/device_tree.h>
>>>>   #include <asm/setup.h>
>>>>     static bool __init device_tree_node_matches(const void *fdt, 
>>>> int node,
>>>> @@ -53,10 +53,15 @@ static bool __init 
>>>> device_tree_node_compatible(const void *fdt, int node,
>>>>   }
>>>>     void __init device_tree_get_reg(const __be32 **cell, u32 
>>>> address_cells,
>>>> -                                u32 size_cells, u64 *start, u64 
>>>> *size)
>>>> +                                u32 size_cells, paddr_t *start, 
>>>> paddr_t *size)
>>>>   {
>>>> -    *start = dt_next_cell(address_cells, cell);
>>>> -    *size = dt_next_cell(size_cells, cell);
>>>> +    /*
>>>> +     * dt_next_cell will return u64 whereas paddr_t may be u64 or 
>>>> u32. Thus, one
>>>> +     * needs to cast paddr_t to u32. Note that we do not check for 
>>>> truncation as
>>>> +     * it is user's responsibility to provide the correct values 
>>>> in the DT.
>>>> +     */
>>>> +    *start = (paddr_t) dt_next_cell(address_cells, cell);
>>>> +    *size = (paddr_t) dt_next_cell(size_cells, cell);
>
> There is no need for explicit cast here.

Should we have it for the sake of documentation (that it casts u64 to 
paddr_t) ?

- Ayan

>
> Cheers,
>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t
  2023-01-31 10:51         ` Ayan Kumar Halder
@ 2023-01-31 15:57           ` Julien Grall
  0 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-01-31 15:57 UTC (permalink / raw)
  To: Ayan Kumar Halder, Stefano Stabellini
  Cc: Ayan Kumar Halder, xen-devel, stefano.stabellini,
	Volodymyr_Babchuk, bertrand.marquis

Hi Ayan,

On 31/01/2023 10:51, Ayan Kumar Halder wrote:
> On 20/01/2023 10:16, Julien Grall wrote:
>>>> Last comment, maybe we could add fdt_get_mem_rsv_paddr to setup.h
>>>> instead of introducing xen/arch/arm/include/asm/device_tree.h, given
>>>> that we already have device tree definitions there
>>>> (device_tree_get_reg). I am OK either way.
>>>   Actually I noticed you also add dt_device_get_paddr to
>>> xen/arch/arm/include/asm/device_tree.h. So it sounds like it is a good
>>> idea to introduce xen/arch/arm/include/asm/device_tree.h, and we could
>>> also move the declarations of device_tree_get_reg, device_tree_get_u32
>>> there.
>>
>> None of the helpers you mention sounds arm specific. So why should the 
>> be move an arch specific headers?
> 
> The functions (fdt_get_mem_rsv_paddr(), device_tree_get_reg(), 
> device_tree_get_u32()) are currently used by Arm specific code only.
> 
> So, I thought of implementing fdt_get_mem_rsv_paddr() in 
> xen/arch/arm/include/asm/device_tree.h.
> 
> However, I see your point as well. So the alternative approach would be :-
> 
> Approach 1) Implement fdt_get_mem_rsv_paddr() in 
> ./xen/include/xen/libfdt/libfdt.h.
> 
> However libfdt is imported from external sources, so I am not sure if 
> this is the  best approach.

One way would be to introduce "libfdt_xen.h" which would contain all the 
implementation specific to Xen.

> 
> Approach 2) Rename fdt_get_mem_rsv_paddr() to dt_get_mem_rsv_paddr() and 
> implement it in ./xen/include/xen/device_tree.h.
> 
> However, this will be an odd one as it invokes fdt_get_mem_rsv() for 
> which we will have to include libfdt.h in device_tree.h.

You could implement the functions in the device_tree.c but see below.

> 
> 
> So, I am biased towards having xen/arch/arm/include/asm/device_tree.h in 
> which we can implement all the non-static fdt and dt functions (which 
> are required by xen/arch/arm/*).
> 
> And then (as Stefano suggested), we can move the definitions of the 
> following to xen/arch/arm/include/asm/device_tree.h.
> 
> device_tree_get_reg()
> 
> device_tree_get_u32()
> 
> device_tree_for_each_node()

Well none of them are truly arch specific as well. I could imagine 
RISC-v to use it in the future if they also care about checking the 
truncation.

I have a slight preference to introduce libfdt_xen.h over adding the 
implementation in device_tree.h so we can keep the unflatten API 
(device_tree.h) separated from the flatten API (libfdt.h).

But this is not a strong preference between the two. That said, I would 
strongly argue against adding the helper in asm/*.h because there is 
nothing Arm specific in them.

>>
>> [...]
>>
>>>>> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
>>>>> index 0085c28d74..f536a3f3ab 100644
>>>>> --- a/xen/arch/arm/bootfdt.c
>>>>> +++ b/xen/arch/arm/bootfdt.c
>>>>> @@ -11,9 +11,9 @@
>>>>>   #include <xen/efi.h>
>>>>>   #include <xen/device_tree.h>
>>>>>   #include <xen/lib.h>
>>>>> -#include <xen/libfdt/libfdt.h>
>>>>>   #include <xen/sort.h>
>>>>>   #include <xsm/xsm.h>
>>>>> +#include <asm/device_tree.h>
>>>>>   #include <asm/setup.h>
>>>>>     static bool __init device_tree_node_matches(const void *fdt, 
>>>>> int node,
>>>>> @@ -53,10 +53,15 @@ static bool __init 
>>>>> device_tree_node_compatible(const void *fdt, int node,
>>>>>   }
>>>>>     void __init device_tree_get_reg(const __be32 **cell, u32 
>>>>> address_cells,
>>>>> -                                u32 size_cells, u64 *start, u64 
>>>>> *size)
>>>>> +                                u32 size_cells, paddr_t *start, 
>>>>> paddr_t *size)
>>>>>   {
>>>>> -    *start = dt_next_cell(address_cells, cell);
>>>>> -    *size = dt_next_cell(size_cells, cell);
>>>>> +    /*
>>>>> +     * dt_next_cell will return u64 whereas paddr_t may be u64 or 
>>>>> u32. Thus, one
>>>>> +     * needs to cast paddr_t to u32. Note that we do not check for 
>>>>> truncation as
>>>>> +     * it is user's responsibility to provide the correct values 
>>>>> in the DT.
>>>>> +     */
>>>>> +    *start = (paddr_t) dt_next_cell(address_cells, cell);
>>>>> +    *size = (paddr_t) dt_next_cell(size_cells, cell);
>>
>> There is no need for explicit cast here.
> 
> Should we have it for the sake of documentation (that it casts u64 to 
> paddr_t) ?

You already have a comment on top of dt_next_cell() to explain the 
typecast. So I would rather not add the explicit casts.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-01-19 23:24   ` Stefano Stabellini
@ 2023-02-06 19:21     ` Ayan Kumar Halder
  2023-02-07  9:03       ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-02-06 19:21 UTC (permalink / raw)
  To: Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, julien, Volodymyr_Babchuk,
	bertrand.marquis

Hi Stefano,

On 19/01/2023 23:24, Stefano Stabellini wrote:
> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>> One should now be able to use 'paddr_t' to represent address and size.
>> Consequently, one should use 'PRIpaddr' as a format specifier for paddr_t.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>> ---
>>
>> Changes from -
>>
>> v1 - 1. Rebased the patch.
>>
>>   xen/arch/arm/domain_build.c        |  9 +++++----
>>   xen/arch/arm/gic-v3.c              |  2 +-
>>   xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>>   xen/drivers/char/exynos4210-uart.c |  2 +-
>>   xen/drivers/char/ns16550.c         |  8 ++++----
>>   xen/drivers/char/omap-uart.c       |  2 +-
>>   xen/drivers/char/pl011.c           |  4 ++--
>>   xen/drivers/char/scif-uart.c       |  2 +-
>>   xen/drivers/passthrough/arm/smmu.c |  6 +++---
>>   9 files changed, 31 insertions(+), 30 deletions(-)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index 72b9afbb4c..cf8ae37a14 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const struct kernel_info *kinfo,
>>       dt_for_each_device_node( dt_host, np )
>>       {
>>           unsigned int naddr;
>> -        u64 addr, size;
>> +        paddr_t addr, size;
>>   
>>           naddr = dt_number_of_address(np);
>>   
>> @@ -2445,7 +2445,7 @@ static int __init handle_device(struct domain *d, struct dt_device_node *dev,
>>       unsigned int naddr;
>>       unsigned int i;
>>       int res;
>> -    u64 addr, size;
>> +    paddr_t addr, size;
>>       bool own_device = !dt_device_for_passthrough(dev);
>>       /*
>>        * We want to avoid mapping the MMIO in dom0 for the following cases:
>> @@ -2941,9 +2941,10 @@ static int __init handle_passthrough_prop(struct kernel_info *kinfo,
>>           if ( res )
>>           {
>>               printk(XENLOG_ERR "Unable to permit to dom%d access to"
>> -                   " 0x%"PRIx64" - 0x%"PRIx64"\n",
>> +                   " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
>>                      kinfo->d->domain_id,
>> -                   mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1);
>> +                   (paddr_t) (mstart & PAGE_MASK),
>> +                   (paddr_t) (PAGE_ALIGN(mstart + size) - 1));
> Why do you need the casts here? mstart is already defined as paddr_t

Actually, this is because the PAGE_MASK is defined as 'long'. See 
xen/include/xen/page-size.h :-

#define PAGE_SIZE           (_AC(1,L) << PAGE_SHIFT)
#define PAGE_MASK           (~(PAGE_SIZE-1))

So, the resultant type inferred is 'long unsigned int'. Thus, we need to 
add an explicit cast.

- Ayan

>
>
>>               return res;
>>           }
>>   
>> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
>> index bb59ea94cd..391dfa53d7 100644
>> --- a/xen/arch/arm/gic-v3.c
>> +++ b/xen/arch/arm/gic-v3.c
>> @@ -1393,7 +1393,7 @@ static void __init gicv3_dt_init(void)
>>   
>>       for ( i = 0; i < gicv3.rdist_count; i++ )
>>       {
>> -        uint64_t rdist_base, rdist_size;
>> +        paddr_t rdist_base, rdist_size;
>>   
>>           res = dt_device_get_address(node, 1 + i, &rdist_base, &rdist_size);
>>           if ( res )
>> diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
>> index 6560507092..f79fad9957 100644
>> --- a/xen/arch/arm/platforms/exynos5.c
>> +++ b/xen/arch/arm/platforms/exynos5.c
>> @@ -42,8 +42,8 @@ static int exynos5_init_time(void)
>>       void __iomem *mct;
>>       int rc;
>>       struct dt_device_node *node;
>> -    u64 mct_base_addr;
>> -    u64 size;
>> +    paddr_t mct_base_addr;
>> +    paddr_t size;
>>   
>>       node = dt_find_compatible_node(NULL, NULL, "samsung,exynos4210-mct");
>>       if ( !node )
>> @@ -59,7 +59,7 @@ static int exynos5_init_time(void)
>>           return -ENXIO;
>>       }
>>   
>> -    dprintk(XENLOG_INFO, "mct_base_addr: %016llx size: %016llx\n",
>> +    dprintk(XENLOG_INFO, "mct_base_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"\n",
>>               mct_base_addr, size);
>>   
>>       mct = ioremap_nocache(mct_base_addr, size);
>> @@ -97,9 +97,9 @@ static int __init exynos5_smp_init(void)
>>       struct dt_device_node *node;
>>       void __iomem *sysram;
>>       char *compatible;
>> -    u64 sysram_addr;
>> -    u64 size;
>> -    u64 sysram_offset;
>> +    paddr_t sysram_addr;
>> +    paddr_t size;
>> +    paddr_t sysram_offset;
>>       int rc;
>>   
>>       node = dt_find_compatible_node(NULL, NULL, "samsung,secure-firmware");
>> @@ -131,7 +131,7 @@ static int __init exynos5_smp_init(void)
>>           dprintk(XENLOG_ERR, "Error in %s\n", compatible);
>>           return -ENXIO;
>>       }
>> -    dprintk(XENLOG_INFO, "sysram_addr: %016llx size: %016llx offset: %016llx\n",
>> +    dprintk(XENLOG_INFO,"sysram_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"offset: 0x%"PRIpaddr"\n",
>>               sysram_addr, size, sysram_offset);
>>   
>>       sysram = ioremap_nocache(sysram_addr, size);
>> @@ -189,7 +189,7 @@ static int exynos5_cpu_power_up(void __iomem *power, int cpu)
>>       return 0;
>>   }
>>   
>> -static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
>> +static int exynos5_get_pmu_baseandsize(paddr_t *power_base_addr, paddr_t *size)
>>   {
>>       struct dt_device_node *node;
>>       int rc;
>> @@ -215,7 +215,7 @@ static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
>>           return -ENXIO;
>>       }
>>   
>> -    dprintk(XENLOG_DEBUG, "power_base_addr: %016llx size: %016llx\n",
>> +    dprintk(XENLOG_DEBUG, "power_base_addr: 0x%"PRIpaddr" size: 0x%"PRIpaddr"\n",
>>               *power_base_addr, *size);
>>   
>>       return 0;
>> @@ -223,8 +223,8 @@ static int exynos5_get_pmu_baseandsize(u64 *power_base_addr, u64 *size)
>>   
>>   static int exynos5_cpu_up(int cpu)
>>   {
>> -    u64 power_base_addr;
>> -    u64 size;
>> +    paddr_t power_base_addr;
>> +    paddr_t size;
>>       void __iomem *power;
>>       int rc;
>>   
>> @@ -256,8 +256,8 @@ static int exynos5_cpu_up(int cpu)
>>   
>>   static void exynos5_reset(void)
>>   {
>> -    u64 power_base_addr;
>> -    u64 size;
>> +    paddr_t power_base_addr;
>> +    paddr_t size;
>>       void __iomem *pmu;
>>       int rc;
>>   
>> diff --git a/xen/drivers/char/exynos4210-uart.c b/xen/drivers/char/exynos4210-uart.c
>> index 43aaf02e18..32cc8c78b5 100644
>> --- a/xen/drivers/char/exynos4210-uart.c
>> +++ b/xen/drivers/char/exynos4210-uart.c
>> @@ -303,7 +303,7 @@ static int __init exynos4210_uart_init(struct dt_device_node *dev,
>>       const char *config = data;
>>       struct exynos4210_uart *uart;
>>       int res;
>> -    u64 addr, size;
>> +    paddr_t addr, size;
>>   
>>       if ( strcmp(config, "") )
>>           printk("WARNING: UART configuration is not supported\n");
>> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
>> index 58d0ccd889..8ef895a2bb 100644
>> --- a/xen/drivers/char/ns16550.c
>> +++ b/xen/drivers/char/ns16550.c
>> @@ -42,8 +42,8 @@
>>   
>>   static struct ns16550 {
>>       int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
>> -    u64 io_base;   /* I/O port or memory-mapped I/O address. */
>> -    u64 io_size;
>> +    paddr_t io_base;   /* I/O port or memory-mapped I/O address. */
>> +    paddr_t io_size;
>>       int reg_shift; /* Bits to shift register offset by */
>>       int reg_width; /* Size of access to use, the registers
>>                       * themselves are still bytes */
>> @@ -1166,7 +1166,7 @@ static const struct ns16550_config __initconst uart_config[] =
>>   static int __init
>>   pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>>   {
>> -    u64 orig_base = uart->io_base;
>> +    paddr_t orig_base = uart->io_base;
>>       unsigned int b, d, f, nextf, i;
>>   
>>       /* NB. Start at bus 1 to avoid AMT: a plug-in card cannot be on bus 0. */
>> @@ -1259,7 +1259,7 @@ pci_uart_config(struct ns16550 *uart, bool_t skip_amt, unsigned int idx)
>>                       else
>>                           size = len & PCI_BASE_ADDRESS_MEM_MASK;
>>   
>> -                    uart->io_base = ((u64)bar_64 << 32) |
>> +                    uart->io_base = (paddr_t) ((u64)bar_64 << 32) |
>>                                       (bar & PCI_BASE_ADDRESS_MEM_MASK);
>>                   }
>>                   /* IO based */
>> diff --git a/xen/drivers/char/omap-uart.c b/xen/drivers/char/omap-uart.c
>> index d6a5d59aa2..3b53e1909a 100644
>> --- a/xen/drivers/char/omap-uart.c
>> +++ b/xen/drivers/char/omap-uart.c
>> @@ -324,7 +324,7 @@ static int __init omap_uart_init(struct dt_device_node *dev,
>>       struct omap_uart *uart;
>>       u32 clkspec;
>>       int res;
>> -    u64 addr, size;
>> +    paddr_t addr, size;
>>   
>>       if ( strcmp(config, "") )
>>           printk("WARNING: UART configuration is not supported\n");
>> diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c
>> index be67242bc0..256ec11e3f 100644
>> --- a/xen/drivers/char/pl011.c
>> +++ b/xen/drivers/char/pl011.c
>> @@ -222,7 +222,7 @@ static struct uart_driver __read_mostly pl011_driver = {
>>       .vuart_info   = pl011_vuart,
>>   };
>>   
>> -static int __init pl011_uart_init(int irq, u64 addr, u64 size, bool sbsa)
>> +static int __init pl011_uart_init(int irq, paddr_t addr, paddr_t size, bool sbsa)
>>   {
>>       struct pl011 *uart;
>>   
>> @@ -258,7 +258,7 @@ static int __init pl011_dt_uart_init(struct dt_device_node *dev,
>>   {
>>       const char *config = data;
>>       int res;
>> -    u64 addr, size;
>> +    paddr_t addr, size;
>>   
>>       if ( strcmp(config, "") )
>>       {
>> diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
>> index 2fccafe340..b425881d06 100644
>> --- a/xen/drivers/char/scif-uart.c
>> +++ b/xen/drivers/char/scif-uart.c
>> @@ -311,7 +311,7 @@ static int __init scif_uart_init(struct dt_device_node *dev,
>>       const char *config = data;
>>       struct scif_uart *uart;
>>       int res;
>> -    u64 addr, size;
>> +    paddr_t addr, size;
>>   
>>       if ( strcmp(config, "") )
>>           printk("WARNING: UART configuration is not supported\n");
>> diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c
>> index 0a514821b3..490d253d44 100644
>> --- a/xen/drivers/passthrough/arm/smmu.c
>> +++ b/xen/drivers/passthrough/arm/smmu.c
>> @@ -73,8 +73,8 @@
>>   /* Xen: Helpers to get device MMIO and IRQs */
>>   struct resource
>>   {
>> -	u64 addr;
>> -	u64 size;
>> +	paddr_t addr;
>> +	paddr_t size;
>>   	unsigned int type;
>>   };
>>   
>> @@ -169,7 +169,7 @@ static void __iomem *devm_ioremap_resource(struct device *dev,
>>   	ptr = ioremap_nocache(res->addr, res->size);
>>   	if (!ptr) {
>>   		dev_err(dev,
>> -			"ioremap failed (addr 0x%"PRIx64" size 0x%"PRIx64")\n",
>> +			"ioremap failed (addr 0x%"PRIpaddr" size 0x%"PRIpaddr")\n",
>>   			res->addr, res->size);
>>   		return ERR_PTR(-ENOMEM);
>>   	}
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-02-06 19:21     ` Ayan Kumar Halder
@ 2023-02-07  9:03       ` Julien Grall
  2023-02-07 10:59         ` Ayan Kumar Halder
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-02-07  9:03 UTC (permalink / raw)
  To: Ayan Kumar Halder, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis



On 06/02/2023 19:21, Ayan Kumar Halder wrote:
> Hi Stefano,
> 
> On 19/01/2023 23:24, Stefano Stabellini wrote:
>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>> One should now be able to use 'paddr_t' to represent address and size.
>>> Consequently, one should use 'PRIpaddr' as a format specifier for 
>>> paddr_t.
>>>
>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>> ---
>>>
>>> Changes from -
>>>
>>> v1 - 1. Rebased the patch.
>>>
>>>   xen/arch/arm/domain_build.c        |  9 +++++----
>>>   xen/arch/arm/gic-v3.c              |  2 +-
>>>   xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>>>   xen/drivers/char/exynos4210-uart.c |  2 +-
>>>   xen/drivers/char/ns16550.c         |  8 ++++----
>>>   xen/drivers/char/omap-uart.c       |  2 +-
>>>   xen/drivers/char/pl011.c           |  4 ++--
>>>   xen/drivers/char/scif-uart.c       |  2 +-
>>>   xen/drivers/passthrough/arm/smmu.c |  6 +++---
>>>   9 files changed, 31 insertions(+), 30 deletions(-)
>>>
>>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>>> index 72b9afbb4c..cf8ae37a14 100644
>>> --- a/xen/arch/arm/domain_build.c
>>> +++ b/xen/arch/arm/domain_build.c
>>> @@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const 
>>> struct kernel_info *kinfo,
>>>       dt_for_each_device_node( dt_host, np )
>>>       {
>>>           unsigned int naddr;
>>> -        u64 addr, size;
>>> +        paddr_t addr, size;
>>>           naddr = dt_number_of_address(np);
>>> @@ -2445,7 +2445,7 @@ static int __init handle_device(struct domain 
>>> *d, struct dt_device_node *dev,
>>>       unsigned int naddr;
>>>       unsigned int i;
>>>       int res;
>>> -    u64 addr, size;
>>> +    paddr_t addr, size;
>>>       bool own_device = !dt_device_for_passthrough(dev);
>>>       /*
>>>        * We want to avoid mapping the MMIO in dom0 for the following 
>>> cases:
>>> @@ -2941,9 +2941,10 @@ static int __init 
>>> handle_passthrough_prop(struct kernel_info *kinfo,
>>>           if ( res )
>>>           {
>>>               printk(XENLOG_ERR "Unable to permit to dom%d access to"
>>> -                   " 0x%"PRIx64" - 0x%"PRIx64"\n",
>>> +                   " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
>>>                      kinfo->d->domain_id,
>>> -                   mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1);
>>> +                   (paddr_t) (mstart & PAGE_MASK),
>>> +                   (paddr_t) (PAGE_ALIGN(mstart + size) - 1));
>> Why do you need the casts here? mstart is already defined as paddr_t
> 
> Actually, this is because the PAGE_MASK is defined as 'long'. See 
> xen/include/xen/page-size.h :-
> 
> #define PAGE_SIZE           (_AC(1,L) << PAGE_SHIFT)
> #define PAGE_MASK           (~(PAGE_SIZE-1))
> 
> So, the resultant type inferred is 'long unsigned int'. Thus, we need to 
> add an explicit cast.

Hmmm... I am a bit confused with this statement. If the resultant type 
inferred is actually 'long unsigned int', then why was the current 
specifier worked before ('long unsigned int' is 32-bit on Arm32)?

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-02-07  9:03       ` Julien Grall
@ 2023-02-07 10:59         ` Ayan Kumar Halder
  2023-02-07 12:18           ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-02-07 10:59 UTC (permalink / raw)
  To: Julien Grall, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Julien,

On 07/02/2023 09:03, Julien Grall wrote:
>
>
> On 06/02/2023 19:21, Ayan Kumar Halder wrote:
>> Hi Stefano,
>>
>> On 19/01/2023 23:24, Stefano Stabellini wrote:
>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>> One should now be able to use 'paddr_t' to represent address and size.
>>>> Consequently, one should use 'PRIpaddr' as a format specifier for 
>>>> paddr_t.
>>>>
>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>> ---
>>>>
>>>> Changes from -
>>>>
>>>> v1 - 1. Rebased the patch.
>>>>
>>>>   xen/arch/arm/domain_build.c        |  9 +++++----
>>>>   xen/arch/arm/gic-v3.c              |  2 +-
>>>>   xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>>>>   xen/drivers/char/exynos4210-uart.c |  2 +-
>>>>   xen/drivers/char/ns16550.c         |  8 ++++----
>>>>   xen/drivers/char/omap-uart.c       |  2 +-
>>>>   xen/drivers/char/pl011.c           |  4 ++--
>>>>   xen/drivers/char/scif-uart.c       |  2 +-
>>>>   xen/drivers/passthrough/arm/smmu.c |  6 +++---
>>>>   9 files changed, 31 insertions(+), 30 deletions(-)
>>>>
>>>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>>>> index 72b9afbb4c..cf8ae37a14 100644
>>>> --- a/xen/arch/arm/domain_build.c
>>>> +++ b/xen/arch/arm/domain_build.c
>>>> @@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const 
>>>> struct kernel_info *kinfo,
>>>>       dt_for_each_device_node( dt_host, np )
>>>>       {
>>>>           unsigned int naddr;
>>>> -        u64 addr, size;
>>>> +        paddr_t addr, size;
>>>>           naddr = dt_number_of_address(np);
>>>> @@ -2445,7 +2445,7 @@ static int __init handle_device(struct domain 
>>>> *d, struct dt_device_node *dev,
>>>>       unsigned int naddr;
>>>>       unsigned int i;
>>>>       int res;
>>>> -    u64 addr, size;
>>>> +    paddr_t addr, size;
>>>>       bool own_device = !dt_device_for_passthrough(dev);
>>>>       /*
>>>>        * We want to avoid mapping the MMIO in dom0 for the 
>>>> following cases:
>>>> @@ -2941,9 +2941,10 @@ static int __init 
>>>> handle_passthrough_prop(struct kernel_info *kinfo,
>>>>           if ( res )
>>>>           {
>>>>               printk(XENLOG_ERR "Unable to permit to dom%d access to"
>>>> -                   " 0x%"PRIx64" - 0x%"PRIx64"\n",
>>>> +                   " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
>>>>                      kinfo->d->domain_id,
>>>> -                   mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 
>>>> 1);
>>>> +                   (paddr_t) (mstart & PAGE_MASK),
>>>> +                   (paddr_t) (PAGE_ALIGN(mstart + size) - 1));
>>> Why do you need the casts here? mstart is already defined as paddr_t
>>
>> Actually, this is because the PAGE_MASK is defined as 'long'. See 
>> xen/include/xen/page-size.h :-
>>
>> #define PAGE_SIZE           (_AC(1,L) << PAGE_SHIFT)
>> #define PAGE_MASK           (~(PAGE_SIZE-1))
>>
>> So, the resultant type inferred is 'long unsigned int'. Thus, we need 
>> to add an explicit cast.
>
> Hmmm... I am a bit confused with this statement. If the resultant type 
> inferred is actually 'long unsigned int', then why was the current 
> specifier worked before ('long unsigned int' is 32-bit on Arm32)?

Before this change, mstart was of type paddr_t (ie u64 ie unsigned long 
long on Arm_32). When 'unsigned long long' was operated with 'long' (ie 
PAGE_SIZE), then the resultant type is 'unsigned long long'. The rule 
from 'C Standard 2011' 
(https://web.cs.dal.ca/~vlado/pl/C_Standard_2011-n1570.pdf) , page 53 
(Section 6.3.1.8 Usual arithmetic conversions) is :-

"Otherwise, if the operand that has unsigned integer type has rank 
greater or equal to the rank of the type of the other operand, then the 
operand with signed integer type is converted to the type of the operand 
with unsigned integer type."

And from 6.3.1.1

"The rank of long long int shall be greater than the rank of long int, 
which shall be greater than the rank of int, which shall be greater than 
the rank of short int, which shall be greater than the rank of signed char.

The rank of any unsigned integer type shall equal the rank of the 
corresponding signed integer type, if any."

And using 'PRIx64' to print 'unsigned long long' will not require any cast.

Now with the change,
mstart is of paddr_t (ie 'unsigned int'). 'unsigned int' operated with 
'long', then  the result is 'unsigned long int'. As the rank of 
'unsigned long int' > 'int', thus it cannot be printed using PRIx32 
(integer format specifier) without an explicit cast.

Please let me know if this makes sense.

-Ayan
>
> Cheers,
>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size
  2023-02-07 10:59         ` Ayan Kumar Halder
@ 2023-02-07 12:18           ` Julien Grall
  0 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-02-07 12:18 UTC (permalink / raw)
  To: Ayan Kumar Halder, Stefano Stabellini, Ayan Kumar Halder
  Cc: xen-devel, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi Ayan,

On 07/02/2023 10:59, Ayan Kumar Halder wrote:
> On 07/02/2023 09:03, Julien Grall wrote:
>>
>>
>> On 06/02/2023 19:21, Ayan Kumar Halder wrote:
>>> Hi Stefano,
>>>
>>> On 19/01/2023 23:24, Stefano Stabellini wrote:
>>>> On Tue, 17 Jan 2023, Ayan Kumar Halder wrote:
>>>>> One should now be able to use 'paddr_t' to represent address and size.
>>>>> Consequently, one should use 'PRIpaddr' as a format specifier for 
>>>>> paddr_t.
>>>>>
>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>> ---
>>>>>
>>>>> Changes from -
>>>>>
>>>>> v1 - 1. Rebased the patch.
>>>>>
>>>>>   xen/arch/arm/domain_build.c        |  9 +++++----
>>>>>   xen/arch/arm/gic-v3.c              |  2 +-
>>>>>   xen/arch/arm/platforms/exynos5.c   | 26 +++++++++++++-------------
>>>>>   xen/drivers/char/exynos4210-uart.c |  2 +-
>>>>>   xen/drivers/char/ns16550.c         |  8 ++++----
>>>>>   xen/drivers/char/omap-uart.c       |  2 +-
>>>>>   xen/drivers/char/pl011.c           |  4 ++--
>>>>>   xen/drivers/char/scif-uart.c       |  2 +-
>>>>>   xen/drivers/passthrough/arm/smmu.c |  6 +++---
>>>>>   9 files changed, 31 insertions(+), 30 deletions(-)
>>>>>
>>>>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>>>>> index 72b9afbb4c..cf8ae37a14 100644
>>>>> --- a/xen/arch/arm/domain_build.c
>>>>> +++ b/xen/arch/arm/domain_build.c
>>>>> @@ -1666,7 +1666,7 @@ static int __init find_memory_holes(const 
>>>>> struct kernel_info *kinfo,
>>>>>       dt_for_each_device_node( dt_host, np )
>>>>>       {
>>>>>           unsigned int naddr;
>>>>> -        u64 addr, size;
>>>>> +        paddr_t addr, size;
>>>>>           naddr = dt_number_of_address(np);
>>>>> @@ -2445,7 +2445,7 @@ static int __init handle_device(struct domain 
>>>>> *d, struct dt_device_node *dev,
>>>>>       unsigned int naddr;
>>>>>       unsigned int i;
>>>>>       int res;
>>>>> -    u64 addr, size;
>>>>> +    paddr_t addr, size;
>>>>>       bool own_device = !dt_device_for_passthrough(dev);
>>>>>       /*
>>>>>        * We want to avoid mapping the MMIO in dom0 for the 
>>>>> following cases:
>>>>> @@ -2941,9 +2941,10 @@ static int __init 
>>>>> handle_passthrough_prop(struct kernel_info *kinfo,
>>>>>           if ( res )
>>>>>           {
>>>>>               printk(XENLOG_ERR "Unable to permit to dom%d access to"
>>>>> -                   " 0x%"PRIx64" - 0x%"PRIx64"\n",
>>>>> +                   " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n",
>>>>>                      kinfo->d->domain_id,
>>>>> -                   mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 
>>>>> 1);
>>>>> +                   (paddr_t) (mstart & PAGE_MASK),
>>>>> +                   (paddr_t) (PAGE_ALIGN(mstart + size) - 1));
>>>> Why do you need the casts here? mstart is already defined as paddr_t
>>>
>>> Actually, this is because the PAGE_MASK is defined as 'long'. See 
>>> xen/include/xen/page-size.h :-
>>>
>>> #define PAGE_SIZE           (_AC(1,L) << PAGE_SHIFT)
>>> #define PAGE_MASK           (~(PAGE_SIZE-1))
>>>
>>> So, the resultant type inferred is 'long unsigned int'. Thus, we need 
>>> to add an explicit cast.
>>
>> Hmmm... I am a bit confused with this statement. If the resultant type 
>> inferred is actually 'long unsigned int', then why was the current 
>> specifier worked before ('long unsigned int' is 32-bit on Arm32)?
> 
> Before this change, mstart was of type paddr_t (ie u64 ie unsigned long 
> long on Arm_32). When 'unsigned long long' was operated with 'long' (ie 
> PAGE_SIZE), then the resultant type is 'unsigned long long'. The rule 
> from 'C Standard 2011' 
> (https://web.cs.dal.ca/~vlado/pl/C_Standard_2011-n1570.pdf) , page 53 
> (Section 6.3.1.8 Usual arithmetic conversions) is :-
> 
> "Otherwise, if the operand that has unsigned integer type has rank 
> greater or equal to the rank of the type of the other operand, then the 
> operand with signed integer type is converted to the type of the operand 
> with unsigned integer type."
> 
> And from 6.3.1.1
> 
> "The rank of long long int shall be greater than the rank of long int, 
> which shall be greater than the rank of int, which shall be greater than 
> the rank of short int, which shall be greater than the rank of signed char.
> 
> The rank of any unsigned integer type shall equal the rank of the 
> corresponding signed integer type, if any."
> 
> And using 'PRIx64' to print 'unsigned long long' will not require any cast.
> 
> Now with the change,
> mstart is of paddr_t (ie 'unsigned int'). 'unsigned int' operated with 
> 'long', then  the result is 'unsigned long int'. As the rank of 
> 'unsigned long int' > 'int', thus it cannot be printed using PRIx32 
> (integer format specifier) without an explicit cast.
> 
> Please let me know if this makes sense.

Thanks for the explanation. I would expect that there will be several 
places in Xen where we would need such cast.

So it sounds like we want to define paddr_t as ``unsigned long`` and 
update PRIpaddr accordingly.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-01-20 11:06   ` Julien Grall
@ 2023-02-07 15:34     ` Ayan Kumar Halder
  2023-02-09 11:45       ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-02-07 15:34 UTC (permalink / raw)
  To: Julien Grall, Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis


On 20/01/2023 11:06, Julien Grall wrote:
> Hi Ayan,
Hi Julien,
>
> On 17/01/2023 17:43, Ayan Kumar Halder wrote:
>> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
>> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
>> "Virtualization Translation Control Register" for the bit descriptions.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>> ---
>> Changes from -
>>
>> v1 - New patch.
>>
>>   xen/arch/arm/p2m.c | 10 +++++++---
>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>> index 948f199d84..cfdea55e71 100644
>> --- a/xen/arch/arm/p2m.c
>> +++ b/xen/arch/arm/p2m.c
>> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>>       register_t val = 
>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>     #ifdef CONFIG_ARM_32
>> -    if ( p2m_ipa_bits < 40 )
>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>>                 p2m_ipa_bits);
>>   -    printk("P2M: 40-bit IPA\n");
>> -    p2m_ipa_bits = 40;
>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>> +    p2m_ipa_bits = PADDR_BITS;
>> +#ifdef CONFIG_ARM_PA_32
>> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
>> +#else
>>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>> +#endif
>
> I am wondering whether this is right time to switch to an array like 
> the arm64 code? This would allow to use 32-bit IPA also when Xen 
> support 64-bit physical address.

In AArch64, we use ID_AA64MMFR0_EL1.PARange to determine the physical 
address range supported at runtime. This is then used as an index into 
pa_range_info[] to determine t0sz, root_order, etc.

However, for AArch32 I do not see an equivalent register (similar to 
ID_AA64MMFR0_EL1) or any register to determine the physical address 
range. Thus, I will prefer to keep the code as it is unless you suggest 
any alternative.

- Ayan

>
> Cheers,
>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-02-07 15:34     ` Ayan Kumar Halder
@ 2023-02-09 11:45       ` Julien Grall
  2023-02-10 15:39         ` Ayan Kumar Halder
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-02-09 11:45 UTC (permalink / raw)
  To: Ayan Kumar Halder, Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

On 07/02/2023 15:34, Ayan Kumar Halder wrote:
> 
> On 20/01/2023 11:06, Julien Grall wrote:
>> Hi Ayan,
> Hi Julien,
>>
>> On 17/01/2023 17:43, Ayan Kumar Halder wrote:
>>> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
>>> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
>>> "Virtualization Translation Control Register" for the bit descriptions.
>>>
>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>> ---
>>> Changes from -
>>>
>>> v1 - New patch.
>>>
>>>   xen/arch/arm/p2m.c | 10 +++++++---
>>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>> index 948f199d84..cfdea55e71 100644
>>> --- a/xen/arch/arm/p2m.c
>>> +++ b/xen/arch/arm/p2m.c
>>> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>>>       register_t val = 
>>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>>     #ifdef CONFIG_ARM_32
>>> -    if ( p2m_ipa_bits < 40 )
>>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>>>                 p2m_ipa_bits);
>>>   -    printk("P2M: 40-bit IPA\n");
>>> -    p2m_ipa_bits = 40;
>>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>>> +    p2m_ipa_bits = PADDR_BITS;
>>> +#ifdef CONFIG_ARM_PA_32
>>> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
>>> +#else
>>>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>>> +#endif
>>
>> I am wondering whether this is right time to switch to an array like 
>> the arm64 code? This would allow to use 32-bit IPA also when Xen 
>> support 64-bit physical address.
> 
> In AArch64, we use ID_AA64MMFR0_EL1.PARange to determine the physical 
> address range supported at runtime. This is then used as an index into 
> pa_range_info[] to determine t0sz, root_order, etc.

It is using both the ID_AA64MMFR0_EL1 but also p2m_ipa_bits to decide 
the size.

> 
> However, for AArch32 I do not see an equivalent register (similar to 
> ID_AA64MMFR0_EL1) or any register to determine the physical address 
> range. Thus, I will prefer to keep the code as it is unless you suggest 
> any alternative.

I looked at the Arm Arm and indeed it doesn't look like there are 
equivalent for ID_AA64MMFR0_EL1.PARange.

However, my point was less about reading the system register but more 
about the fact we could have the code a bit more generic and avoid the 
assumption that PADDR_BITS is only modified when CONFIG_ARM_PA_32 is set.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-02-09 11:45       ` Julien Grall
@ 2023-02-10 15:39         ` Ayan Kumar Halder
  2023-02-10 16:19           ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-02-10 15:39 UTC (permalink / raw)
  To: Julien Grall, Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis


On 09/02/2023 11:45, Julien Grall wrote:
> Hi,
Hi Julien,
>
> On 07/02/2023 15:34, Ayan Kumar Halder wrote:
>>
>> On 20/01/2023 11:06, Julien Grall wrote:
>>> Hi Ayan,
>> Hi Julien,
>>>
>>> On 17/01/2023 17:43, Ayan Kumar Halder wrote:
>>>> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
>>>> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
>>>> "Virtualization Translation Control Register" for the bit 
>>>> descriptions.
>>>>
>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>> ---
>>>> Changes from -
>>>>
>>>> v1 - New patch.
>>>>
>>>>   xen/arch/arm/p2m.c | 10 +++++++---
>>>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>>> index 948f199d84..cfdea55e71 100644
>>>> --- a/xen/arch/arm/p2m.c
>>>> +++ b/xen/arch/arm/p2m.c
>>>> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>>>>       register_t val = 
>>>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>>>     #ifdef CONFIG_ARM_32
>>>> -    if ( p2m_ipa_bits < 40 )
>>>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>>>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>>>>                 p2m_ipa_bits);
>>>>   -    printk("P2M: 40-bit IPA\n");
>>>> -    p2m_ipa_bits = 40;
>>>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>>>> +    p2m_ipa_bits = PADDR_BITS;
>>>> +#ifdef CONFIG_ARM_PA_32
>>>> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
>>>> +#else
>>>>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>>>> +#endif
>>>
>>> I am wondering whether this is right time to switch to an array like 
>>> the arm64 code? This would allow to use 32-bit IPA also when Xen 
>>> support 64-bit physical address.
>>
>> In AArch64, we use ID_AA64MMFR0_EL1.PARange to determine the physical 
>> address range supported at runtime. This is then used as an index 
>> into pa_range_info[] to determine t0sz, root_order, etc.
>
> It is using both the ID_AA64MMFR0_EL1 but also p2m_ipa_bits to decide 
> the size.
Ack.
>
>>
>> However, for AArch32 I do not see an equivalent register (similar to 
>> ID_AA64MMFR0_EL1) or any register to determine the physical address 
>> range. Thus, I will prefer to keep the code as it is unless you 
>> suggest any alternative.
>
> I looked at the Arm Arm and indeed it doesn't look like there are 
> equivalent for ID_AA64MMFR0_EL1.PARange.
>
> However, my point was less about reading the system register but more 
> about the fact we could have the code a bit more generic and avoid the 
> assumption that PADDR_BITS is only modified when CONFIG_ARM_PA_32 is set.

I had a rework at the patch. Please let me know if the following looks 
better.

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 948f199d84..bc3bdf5f3e 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -2266,14 +2266,35 @@ void __init setup_virt_paging(void)
      register_t val = 
VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;

  #ifdef CONFIG_ARM_32
-    if ( p2m_ipa_bits < 40 )
+    static const struct {
+        unsigned int pabits; /* Physical Address Size */
+        unsigned int t0sz;   /* Desired T0SZ */
+        unsigned int sl0;    /* Desired SL0 */
+    } pa_range_info[] __initconst = {
+        [0] = { 32,     32,     1 },
+        [1] = { 40,     24,     1 },
+    };
+    int i = 0;
+
+    if ( p2m_ipa_bits < PADDR_BITS )
+        panic("P2M: Not able to support %u-bit IPA at the moment\n",
+              p2m_ipa_bits);
+
+    printk("P2M: %u-bit IPA\n",PADDR_BITS);
+    p2m_ipa_bits = PADDR_BITS;
+
+    for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
+        if ( p2m_ipa_bits == pa_range_info[i].pabits )
+            break;
+
+    if ( i == ARRAY_SIZE(pa_range_info) )
          panic("P2M: Not able to support %u-bit IPA at the moment\n",
                p2m_ipa_bits);

-    printk("P2M: 40-bit IPA\n");
-    p2m_ipa_bits = 40;
-    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
-    val |= VTCR_SL0(0x1); /* P2M starts at first level */
+    val |= VTCR_T0SZ(pa_range_info[i].t0sz);
+    val |= VTCR_SL0(pa_range_info[i].sl0);
+

- Ayan

>
> Cheers,
>


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-02-10 15:39         ` Ayan Kumar Halder
@ 2023-02-10 16:19           ` Julien Grall
  2023-02-10 17:51             ` Ayan Kumar Halder
  0 siblings, 1 reply; 64+ messages in thread
From: Julien Grall @ 2023-02-10 16:19 UTC (permalink / raw)
  To: Ayan Kumar Halder, Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

Hi,

On 10/02/2023 15:39, Ayan Kumar Halder wrote:
> 
> On 09/02/2023 11:45, Julien Grall wrote:
>> Hi,
> Hi Julien,
>>
>> On 07/02/2023 15:34, Ayan Kumar Halder wrote:
>>>
>>> On 20/01/2023 11:06, Julien Grall wrote:
>>>> Hi Ayan,
>>> Hi Julien,
>>>>
>>>> On 17/01/2023 17:43, Ayan Kumar Halder wrote:
>>>>> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
>>>>> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
>>>>> "Virtualization Translation Control Register" for the bit 
>>>>> descriptions.
>>>>>
>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>> ---
>>>>> Changes from -
>>>>>
>>>>> v1 - New patch.
>>>>>
>>>>>   xen/arch/arm/p2m.c | 10 +++++++---
>>>>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>>>> index 948f199d84..cfdea55e71 100644
>>>>> --- a/xen/arch/arm/p2m.c
>>>>> +++ b/xen/arch/arm/p2m.c
>>>>> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>>>>>       register_t val = 
>>>>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>>>>     #ifdef CONFIG_ARM_32
>>>>> -    if ( p2m_ipa_bits < 40 )
>>>>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>>>>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>>>>>                 p2m_ipa_bits);
>>>>>   -    printk("P2M: 40-bit IPA\n");
>>>>> -    p2m_ipa_bits = 40;
>>>>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>>>>> +    p2m_ipa_bits = PADDR_BITS;
>>>>> +#ifdef CONFIG_ARM_PA_32
>>>>> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
>>>>> +#else
>>>>>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>>>>> +#endif
>>>>
>>>> I am wondering whether this is right time to switch to an array like 
>>>> the arm64 code? This would allow to use 32-bit IPA also when Xen 
>>>> support 64-bit physical address.
>>>
>>> In AArch64, we use ID_AA64MMFR0_EL1.PARange to determine the physical 
>>> address range supported at runtime. This is then used as an index 
>>> into pa_range_info[] to determine t0sz, root_order, etc.
>>
>> It is using both the ID_AA64MMFR0_EL1 but also p2m_ipa_bits to decide 
>> the size.
> Ack.
>>
>>>
>>> However, for AArch32 I do not see an equivalent register (similar to 
>>> ID_AA64MMFR0_EL1) or any register to determine the physical address 
>>> range. Thus, I will prefer to keep the code as it is unless you 
>>> suggest any alternative.
>>
>> I looked at the Arm Arm and indeed it doesn't look like there are 
>> equivalent for ID_AA64MMFR0_EL1.PARange.
>>
>> However, my point was less about reading the system register but more 
>> about the fact we could have the code a bit more generic and avoid the 
>> assumption that PADDR_BITS is only modified when CONFIG_ARM_PA_32 is set.
> 
> I had a rework at the patch. Please let me know if the following looks 
> better.
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 948f199d84..bc3bdf5f3e 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -2266,14 +2266,35 @@ void __init setup_virt_paging(void)
>       register_t val = 
> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
> 
>   #ifdef CONFIG_ARM_32
> -    if ( p2m_ipa_bits < 40 )
> +    static const struct {
> +        unsigned int pabits; /* Physical Address Size */
> +        unsigned int t0sz;   /* Desired T0SZ */
> +        unsigned int sl0;    /* Desired SL0 */

Hmmm... Why don't you include the root order? In fact...

> +    } pa_range_info[] __initconst = {
> +        [0] = { 32,     32,     1 },
> +        [1] = { 40,     24,     1 },

... looking at the ARMv7 specification (see B3-1345 in ARM DDI 0406C.d), 
the root page-table is only concatenated for 40-bits.

> +    };
> +    int i = 0;
> +
> +    if ( p2m_ipa_bits < PADDR_BITS )
> +        panic("P2M: Not able to support %u-bit IPA at the moment\n",
> +              p2m_ipa_bits);

This check seems unnecessary now.

> +
> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
> +    p2m_ipa_bits = PADDR_BITS;
> +
> +    for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
> +        if ( p2m_ipa_bits == pa_range_info[i].pabits )
> +            break;
> +
> +    if ( i == ARRAY_SIZE(pa_range_info) )
>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>                 p2m_ipa_bits);
> 
> -    printk("P2M: 40-bit IPA\n");
> -    p2m_ipa_bits = 40;
> -    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
> -    val |= VTCR_SL0(0x1); /* P2M starts at first level */
> +    val |= VTCR_T0SZ(pa_range_info[i].t0sz);
> +    val |= VTCR_SL0(pa_range_info[i].sl0);
> +

I think you can share a lot of code between arm64 and arm32. A diff 
below (not tested):

diff --git a/xen/arch/arm/include/asm/p2m.h b/xen/arch/arm/include/asm/p2m.h
index 91df922e1c9f..05f26780a29d 100644
--- a/xen/arch/arm/include/asm/p2m.h
+++ b/xen/arch/arm/include/asm/p2m.h
@@ -14,16 +14,10 @@
  /* Holds the bit size of IPAs in p2m tables.  */
  extern unsigned int p2m_ipa_bits;

-#ifdef CONFIG_ARM_64
  extern unsigned int p2m_root_order;
  extern unsigned int p2m_root_level;
  #define P2M_ROOT_ORDER    p2m_root_order
  #define P2M_ROOT_LEVEL p2m_root_level
-#else
-/* First level P2M is always 2 consecutive pages */
-#define P2M_ROOT_ORDER    1
-#define P2M_ROOT_LEVEL 1
-#endif

  struct domain;

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 948f199d848f..6fda0b92230a 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -2264,17 +2264,6 @@ void __init setup_virt_paging(void)
  {
      /* Setup Stage 2 address translation */
      register_t val = 
VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
-
-#ifdef CONFIG_ARM_32
-    if ( p2m_ipa_bits < 40 )
-        panic("P2M: Not able to support %u-bit IPA at the moment\n",
-              p2m_ipa_bits);
-
-    printk("P2M: 40-bit IPA\n");
-    p2m_ipa_bits = 40;
-    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
-    val |= VTCR_SL0(0x1); /* P2M starts at first level */
-#else /* CONFIG_ARM_64 */
      static const struct {
          unsigned int pabits; /* Physical Address Size */
          unsigned int t0sz;   /* Desired T0SZ, minimum in comment */
@@ -2286,29 +2275,26 @@ void __init setup_virt_paging(void)
          [0] = { 32,      32/*32*/,  0,          1 },
          [1] = { 36,      28/*28*/,  0,          1 },
          [2] = { 40,      24/*24*/,  1,          1 },
+#ifdef CONFIG_ARM_64
          [3] = { 42,      22/*22*/,  3,          1 },
          [4] = { 44,      20/*20*/,  0,          2 },
          [5] = { 48,      16/*16*/,  0,          2 },
          [6] = { 52,      12/*12*/,  4,          2 },
          [7] = { 0 }  /* Invalid */
+#endif
      };

      unsigned int i;
      unsigned int pa_range = 0x10; /* Larger than any possible value */

+#ifdef CONFIG_ARM_64
      /*
       * Restrict "p2m_ipa_bits" if needed. As P2M table is always 
configured
       * with IPA bits == PA bits, compare against "pabits".
       */
      if ( pa_range_info[system_cpuinfo.mm64.pa_range].pabits < 
p2m_ipa_bits )
          p2m_ipa_bits = pa_range_info[system_cpuinfo.mm64.pa_range].pabits;
-
-    /*
-     * cpu info sanitization made sure we support 16bits VMID only if all
-     * cores are supporting it.
-     */
-    if ( system_cpuinfo.mm64.vmid_bits == MM64_VMID_16_BITS_SUPPORT )
-        max_vmid = MAX_VMID_16_BIT;
+#endif

      /* Choose suitable "pa_range" according to the resulted 
"p2m_ipa_bits". */
      for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
@@ -2324,12 +2310,22 @@ void __init setup_virt_paging(void)
      if ( pa_range >= ARRAY_SIZE(pa_range_info) || 
!pa_range_info[pa_range].pabits )
          panic("Unknown encoding of ID_AA64MMFR0_EL1.PARange %x\n", 
pa_range);

-    val |= VTCR_PS(pa_range);
-    val |= VTCR_TG0_4K;
+#ifdef CONFIG_ARM_64
+    /*
+     * cpu info sanitization made sure we support 16bits VMID only if all
+     * cores are supporting it.
+     */
+    if ( system_cpuinfo.mm64.vmid_bits == MM64_VMID_16_BITS_SUPPORT )
+        max_vmid = MAX_VMID_16_BIT;

      /* Set the VS bit only if 16 bit VMID is supported. */
      if ( MAX_VMID == MAX_VMID_16_BIT )
          val |= VTCR_VS;
+#endif
+
+    val |= VTCR_PS(pa_range);
+    val |= VTCR_TG0_4K;
+
      val |= VTCR_SL0(pa_range_info[pa_range].sl0);
      val |= VTCR_T0SZ(pa_range_info[pa_range].t0sz);

@@ -2341,7 +2337,7 @@ void __init setup_virt_paging(void)
             p2m_ipa_bits,
             pa_range_info[pa_range].pabits,
             ( MAX_VMID == MAX_VMID_16_BIT ) ? 16 : 8);
-#endif
+
      printk("P2M: %d levels with order-%d root, VTCR 0x%"PRIregister"\n",
             4 - P2M_ROOT_LEVEL, P2M_ROOT_ORDER, val);

Cheers,

-- 
Julien Grall


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-02-10 16:19           ` Julien Grall
@ 2023-02-10 17:51             ` Ayan Kumar Halder
  2023-02-10 17:58               ` Julien Grall
  0 siblings, 1 reply; 64+ messages in thread
From: Ayan Kumar Halder @ 2023-02-10 17:51 UTC (permalink / raw)
  To: Julien Grall, Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis


On 10/02/2023 16:19, Julien Grall wrote:
> Hi,

Hi Julien,

I need some inputs.

>
> On 10/02/2023 15:39, Ayan Kumar Halder wrote:
>>
>> On 09/02/2023 11:45, Julien Grall wrote:
>>> Hi,
>> Hi Julien,
>>>
>>> On 07/02/2023 15:34, Ayan Kumar Halder wrote:
>>>>
>>>> On 20/01/2023 11:06, Julien Grall wrote:
>>>>> Hi Ayan,
>>>> Hi Julien,
>>>>>
>>>>> On 17/01/2023 17:43, Ayan Kumar Halder wrote:
>>>>>> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
>>>>>> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
>>>>>> "Virtualization Translation Control Register" for the bit 
>>>>>> descriptions.
>>>>>>
>>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>>> ---
>>>>>> Changes from -
>>>>>>
>>>>>> v1 - New patch.
>>>>>>
>>>>>>   xen/arch/arm/p2m.c | 10 +++++++---
>>>>>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>>>>> index 948f199d84..cfdea55e71 100644
>>>>>> --- a/xen/arch/arm/p2m.c
>>>>>> +++ b/xen/arch/arm/p2m.c
>>>>>> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>>>>>>       register_t val = 
>>>>>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>>>>>     #ifdef CONFIG_ARM_32
>>>>>> -    if ( p2m_ipa_bits < 40 )
>>>>>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>>>>>           panic("P2M: Not able to support %u-bit IPA at the 
>>>>>> moment\n",
>>>>>>                 p2m_ipa_bits);
>>>>>>   -    printk("P2M: 40-bit IPA\n");
>>>>>> -    p2m_ipa_bits = 40;
>>>>>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>>>>>> +    p2m_ipa_bits = PADDR_BITS;
>>>>>> +#ifdef CONFIG_ARM_PA_32
>>>>>> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
>>>>>> +#else
>>>>>>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>>>>>> +#endif
>>>>>
>>>>> I am wondering whether this is right time to switch to an array 
>>>>> like the arm64 code? This would allow to use 32-bit IPA also when 
>>>>> Xen support 64-bit physical address.
>>>>
>>>> In AArch64, we use ID_AA64MMFR0_EL1.PARange to determine the 
>>>> physical address range supported at runtime. This is then used as 
>>>> an index into pa_range_info[] to determine t0sz, root_order, etc.
>>>
>>> It is using both the ID_AA64MMFR0_EL1 but also p2m_ipa_bits to 
>>> decide the size.
>> Ack.
>>>
>>>>
>>>> However, for AArch32 I do not see an equivalent register (similar 
>>>> to ID_AA64MMFR0_EL1) or any register to determine the physical 
>>>> address range. Thus, I will prefer to keep the code as it is unless 
>>>> you suggest any alternative.
>>>
>>> I looked at the Arm Arm and indeed it doesn't look like there are 
>>> equivalent for ID_AA64MMFR0_EL1.PARange.
>>>
>>> However, my point was less about reading the system register but 
>>> more about the fact we could have the code a bit more generic and 
>>> avoid the assumption that PADDR_BITS is only modified when 
>>> CONFIG_ARM_PA_32 is set.
>>
>> I had a rework at the patch. Please let me know if the following 
>> looks better.
>>
>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>> index 948f199d84..bc3bdf5f3e 100644
>> --- a/xen/arch/arm/p2m.c
>> +++ b/xen/arch/arm/p2m.c
>> @@ -2266,14 +2266,35 @@ void __init setup_virt_paging(void)
>>       register_t val = 
>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>
>>   #ifdef CONFIG_ARM_32
>> -    if ( p2m_ipa_bits < 40 )
>> +    static const struct {
>> +        unsigned int pabits; /* Physical Address Size */
>> +        unsigned int t0sz;   /* Desired T0SZ */
>> +        unsigned int sl0;    /* Desired SL0 */
>
> Hmmm... Why don't you include the root order? In fact...
>
>> +    } pa_range_info[] __initconst = {
>> +        [0] = { 32,     32,     1 },
>> +        [1] = { 40,     24,     1 },
>
> ... looking at the ARMv7 specification (see B3-1345 in ARM DDI 
> 0406C.d), the root page-table is only concatenated for 40-bits.
Sorry, I could not follow how you inferred this. Can you paste the 
relevant snippet ?
>
>> +    };
>> +    int i = 0;
>> +
>> +    if ( p2m_ipa_bits < PADDR_BITS )
>> +        panic("P2M: Not able to support %u-bit IPA at the moment\n",
>> +              p2m_ipa_bits);
>
> This check seems unnecessary now.

We still need this check as arm_smmu_device_cfg_probe() invokes 
p2m_restrict_ipa_bits(size).

And referARM IHI 0062D.cID070116 (SMMU arch version 2.0 Specification), 
the IPA address size can be

 0.

    0b0000 32-bit.

 1.

    0b0001 36-bit.

10.

    0b0010 40-bit.

11.

    0b0011 42-bit.

100.

    0b0100 44-bit.

101.

    0b0101 48-bit.

So if p2m_ipa_bits = 36 bits and PADDR_BITS = 40, then we want to panic.

- Ayan

>
>> +
>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>> +    p2m_ipa_bits = PADDR_BITS;
>> +
>> +    for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
>> +        if ( p2m_ipa_bits == pa_range_info[i].pabits )
>> +            break;
>> +
>> +    if ( i == ARRAY_SIZE(pa_range_info) )
>>           panic("P2M: Not able to support %u-bit IPA at the moment\n",
>>                 p2m_ipa_bits);
>>
>> -    printk("P2M: 40-bit IPA\n");
>> -    p2m_ipa_bits = 40;
>> -    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>> -    val |= VTCR_SL0(0x1); /* P2M starts at first level */
>> +    val |= VTCR_T0SZ(pa_range_info[i].t0sz);
>> +    val |= VTCR_SL0(pa_range_info[i].sl0);
>> +
>
> I think you can share a lot of code between arm64 and arm32. A diff 
> below (not tested):
>
> diff --git a/xen/arch/arm/include/asm/p2m.h 
> b/xen/arch/arm/include/asm/p2m.h
> index 91df922e1c9f..05f26780a29d 100644
> --- a/xen/arch/arm/include/asm/p2m.h
> +++ b/xen/arch/arm/include/asm/p2m.h
> @@ -14,16 +14,10 @@
>  /* Holds the bit size of IPAs in p2m tables.  */
>  extern unsigned int p2m_ipa_bits;
>
> -#ifdef CONFIG_ARM_64
>  extern unsigned int p2m_root_order;
>  extern unsigned int p2m_root_level;
>  #define P2M_ROOT_ORDER    p2m_root_order
>  #define P2M_ROOT_LEVEL p2m_root_level
> -#else
> -/* First level P2M is always 2 consecutive pages */
> -#define P2M_ROOT_ORDER    1
> -#define P2M_ROOT_LEVEL 1
> -#endif
>
>  struct domain;
>
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 948f199d848f..6fda0b92230a 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -2264,17 +2264,6 @@ void __init setup_virt_paging(void)
>  {
>      /* Setup Stage 2 address translation */
>      register_t val = 
> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
> -
> -#ifdef CONFIG_ARM_32
> -    if ( p2m_ipa_bits < 40 )
> -        panic("P2M: Not able to support %u-bit IPA at the moment\n",
> -              p2m_ipa_bits);
> -
> -    printk("P2M: 40-bit IPA\n");
> -    p2m_ipa_bits = 40;
> -    val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
> -    val |= VTCR_SL0(0x1); /* P2M starts at first level */
> -#else /* CONFIG_ARM_64 */
>      static const struct {
>          unsigned int pabits; /* Physical Address Size */
>          unsigned int t0sz;   /* Desired T0SZ, minimum in comment */
> @@ -2286,29 +2275,26 @@ void __init setup_virt_paging(void)
>          [0] = { 32,      32/*32*/,  0,          1 },
>          [1] = { 36,      28/*28*/,  0,          1 },
>          [2] = { 40,      24/*24*/,  1,          1 },
> +#ifdef CONFIG_ARM_64
>          [3] = { 42,      22/*22*/,  3,          1 },
>          [4] = { 44,      20/*20*/,  0,          2 },
>          [5] = { 48,      16/*16*/,  0,          2 },
>          [6] = { 52,      12/*12*/,  4,          2 },
>          [7] = { 0 }  /* Invalid */
> +#endif
>      };
>
>      unsigned int i;
>      unsigned int pa_range = 0x10; /* Larger than any possible value */
>
> +#ifdef CONFIG_ARM_64
>      /*
>       * Restrict "p2m_ipa_bits" if needed. As P2M table is always 
> configured
>       * with IPA bits == PA bits, compare against "pabits".
>       */
>      if ( pa_range_info[system_cpuinfo.mm64.pa_range].pabits < 
> p2m_ipa_bits )
>          p2m_ipa_bits = 
> pa_range_info[system_cpuinfo.mm64.pa_range].pabits;
> -
> -    /*
> -     * cpu info sanitization made sure we support 16bits VMID only if 
> all
> -     * cores are supporting it.
> -     */
> -    if ( system_cpuinfo.mm64.vmid_bits == MM64_VMID_16_BITS_SUPPORT )
> -        max_vmid = MAX_VMID_16_BIT;
> +#endif
>
>      /* Choose suitable "pa_range" according to the resulted 
> "p2m_ipa_bits". */
>      for ( i = 0; i < ARRAY_SIZE(pa_range_info); i++ )
> @@ -2324,12 +2310,22 @@ void __init setup_virt_paging(void)
>      if ( pa_range >= ARRAY_SIZE(pa_range_info) || 
> !pa_range_info[pa_range].pabits )
>          panic("Unknown encoding of ID_AA64MMFR0_EL1.PARange %x\n", 
> pa_range);
>
> -    val |= VTCR_PS(pa_range);
> -    val |= VTCR_TG0_4K;
> +#ifdef CONFIG_ARM_64
> +    /*
> +     * cpu info sanitization made sure we support 16bits VMID only if 
> all
> +     * cores are supporting it.
> +     */
> +    if ( system_cpuinfo.mm64.vmid_bits == MM64_VMID_16_BITS_SUPPORT )
> +        max_vmid = MAX_VMID_16_BIT;
>
>      /* Set the VS bit only if 16 bit VMID is supported. */
>      if ( MAX_VMID == MAX_VMID_16_BIT )
>          val |= VTCR_VS;
> +#endif
> +
> +    val |= VTCR_PS(pa_range);
> +    val |= VTCR_TG0_4K;
> +
>      val |= VTCR_SL0(pa_range_info[pa_range].sl0);
>      val |= VTCR_T0SZ(pa_range_info[pa_range].t0sz);
>
> @@ -2341,7 +2337,7 @@ void __init setup_virt_paging(void)
>             p2m_ipa_bits,
>             pa_range_info[pa_range].pabits,
>             ( MAX_VMID == MAX_VMID_16_BIT ) ? 16 : 8);
> -#endif
> +
>      printk("P2M: %d levels with order-%d root, VTCR 0x%"PRIregister"\n",
>             4 - P2M_ROOT_LEVEL, P2M_ROOT_ORDER, val);
>
> Cheers,
>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA
  2023-02-10 17:51             ` Ayan Kumar Halder
@ 2023-02-10 17:58               ` Julien Grall
  0 siblings, 0 replies; 64+ messages in thread
From: Julien Grall @ 2023-02-10 17:58 UTC (permalink / raw)
  To: Ayan Kumar Halder, Ayan Kumar Halder, xen-devel
  Cc: sstabellini, stefano.stabellini, Volodymyr_Babchuk, bertrand.marquis

On 10/02/2023 17:51, Ayan Kumar Halder wrote:
> 
> On 10/02/2023 16:19, Julien Grall wrote:
>> Hi,
>> On 10/02/2023 15:39, Ayan Kumar Halder wrote:
>>>
>>> On 09/02/2023 11:45, Julien Grall wrote:
>>>> Hi,
>>> Hi Julien,
>>>>
>>>> On 07/02/2023 15:34, Ayan Kumar Halder wrote:
>>>>>
>>>>> On 20/01/2023 11:06, Julien Grall wrote:
>>>>>> Hi Ayan,
>>>>> Hi Julien,
>>>>>>
>>>>>> On 17/01/2023 17:43, Ayan Kumar Halder wrote:
>>>>>>> VTCR.T0SZ should be set as 0x20 to support 32bit IPA.
>>>>>>> Refer ARM DDI 0487I.a ID081822, G8-9824, G8.2.171, VTCR,
>>>>>>> "Virtualization Translation Control Register" for the bit 
>>>>>>> descriptions.
>>>>>>>
>>>>>>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>>>>>>> ---
>>>>>>> Changes from -
>>>>>>>
>>>>>>> v1 - New patch.
>>>>>>>
>>>>>>>   xen/arch/arm/p2m.c | 10 +++++++---
>>>>>>>   1 file changed, 7 insertions(+), 3 deletions(-)
>>>>>>>
>>>>>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>>>>>> index 948f199d84..cfdea55e71 100644
>>>>>>> --- a/xen/arch/arm/p2m.c
>>>>>>> +++ b/xen/arch/arm/p2m.c
>>>>>>> @@ -2266,13 +2266,17 @@ void __init setup_virt_paging(void)
>>>>>>>       register_t val = 
>>>>>>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>>>>>>     #ifdef CONFIG_ARM_32
>>>>>>> -    if ( p2m_ipa_bits < 40 )
>>>>>>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>>>>>>           panic("P2M: Not able to support %u-bit IPA at the 
>>>>>>> moment\n",
>>>>>>>                 p2m_ipa_bits);
>>>>>>>   -    printk("P2M: 40-bit IPA\n");
>>>>>>> -    p2m_ipa_bits = 40;
>>>>>>> +    printk("P2M: %u-bit IPA\n",PADDR_BITS);
>>>>>>> +    p2m_ipa_bits = PADDR_BITS;
>>>>>>> +#ifdef CONFIG_ARM_PA_32
>>>>>>> +    val |= VTCR_T0SZ(0x20); /* 32 bit IPA */
>>>>>>> +#else
>>>>>>>       val |= VTCR_T0SZ(0x18); /* 40 bit IPA */
>>>>>>> +#endif
>>>>>>
>>>>>> I am wondering whether this is right time to switch to an array 
>>>>>> like the arm64 code? This would allow to use 32-bit IPA also when 
>>>>>> Xen support 64-bit physical address.
>>>>>
>>>>> In AArch64, we use ID_AA64MMFR0_EL1.PARange to determine the 
>>>>> physical address range supported at runtime. This is then used as 
>>>>> an index into pa_range_info[] to determine t0sz, root_order, etc.
>>>>
>>>> It is using both the ID_AA64MMFR0_EL1 but also p2m_ipa_bits to 
>>>> decide the size.
>>> Ack.
>>>>
>>>>>
>>>>> However, for AArch32 I do not see an equivalent register (similar 
>>>>> to ID_AA64MMFR0_EL1) or any register to determine the physical 
>>>>> address range. Thus, I will prefer to keep the code as it is unless 
>>>>> you suggest any alternative.
>>>>
>>>> I looked at the Arm Arm and indeed it doesn't look like there are 
>>>> equivalent for ID_AA64MMFR0_EL1.PARange.
>>>>
>>>> However, my point was less about reading the system register but 
>>>> more about the fact we could have the code a bit more generic and 
>>>> avoid the assumption that PADDR_BITS is only modified when 
>>>> CONFIG_ARM_PA_32 is set.
>>>
>>> I had a rework at the patch. Please let me know if the following 
>>> looks better.
>>>
>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>> index 948f199d84..bc3bdf5f3e 100644
>>> --- a/xen/arch/arm/p2m.c
>>> +++ b/xen/arch/arm/p2m.c
>>> @@ -2266,14 +2266,35 @@ void __init setup_virt_paging(void)
>>>       register_t val = 
>>> VTCR_RES1|VTCR_SH0_IS|VTCR_ORGN0_WBWA|VTCR_IRGN0_WBWA;
>>>
>>>   #ifdef CONFIG_ARM_32
>>> -    if ( p2m_ipa_bits < 40 )
>>> +    static const struct {
>>> +        unsigned int pabits; /* Physical Address Size */
>>> +        unsigned int t0sz;   /* Desired T0SZ */
>>> +        unsigned int sl0;    /* Desired SL0 */
>>
>> Hmmm... Why don't you include the root order? In fact...
>>
>>> +    } pa_range_info[] __initconst = {
>>> +        [0] = { 32,     32,     1 },
>>> +        [1] = { 40,     24,     1 },
>>
>> ... looking at the ARMv7 specification (see B3-1345 in ARM DDI 
>> 0406C.d), the root page-table is only concatenated for 40-bits.
> Sorry, I could not follow how you inferred this. Can you paste the 
> relevant snippet ?

Use of concatenated second-level translation tables
A stage 2 translation with an input address range of 31-34 bits can 
start the translation either:
• With a first-level lookup, accessing a first-level translation table 
with 2-16 entries.
• With a second-level lookup, accessing a set of concatenated 
second-level translation tables.

>>
>>> +    };
>>> +    int i = 0;
>>> +
>>> +    if ( p2m_ipa_bits < PADDR_BITS )
>>> +        panic("P2M: Not able to support %u-bit IPA at the moment\n",
>>> +              p2m_ipa_bits);
>>
>> This check seems unnecessary now.
> 
> We still need this check as arm_smmu_device_cfg_probe() invokes 
> p2m_restrict_ipa_bits(size).
> 
> And referARM IHI 0062D.cID070116 (SMMU arch version 2.0 Specification), 
> the IPA address size can be
> 
> 0.
> 
>     0b0000 32-bit.
> 
> 1.
> 
>     0b0001 36-bit.
> 
> 10.
> 
>     0b0010 40-bit.
> 
> 11.
> 
>     0b0011 42-bit.
> 
> 100.
> 
>     0b0100 44-bit.
> 
> 101.
> 
>     0b0101 48-bit.
> 
> So if p2m_ipa_bits = 36 bits and PADDR_BITS = 40, then we want to panic.

We can have the same situation on Arm64 (PADDR_BITS = 48), yet we don't 
panic(). So I don't quite understand why we would need to differ...

Or are you saying that for 64-bit we also need such check? If so, then I 
am still not sure why because p2m_ipa_bits represent the guest physical 
address space and PADDR_BITS the Xen physical address space. It is valid 
to have both of them differing.

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2023-02-10 17:58 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-17 17:43 [XEN v2 00/11] Add support for 32 bit physical address Ayan Kumar Halder
2023-01-17 17:43 ` [XEN v2 01/11] xen/ns16550: Remove unneeded truncation check in the DT init code Ayan Kumar Halder
2023-01-17 17:43 ` [XEN v2 02/11] xen/arm: Use the correct format specifier Ayan Kumar Halder
2023-01-19 22:54   ` Stefano Stabellini
2023-01-20  9:32     ` Julien Grall
2023-01-20 11:09       ` Ayan Kumar Halder
2023-01-20 14:40       ` Michal Orzel
2023-01-20 15:09         ` Julien Grall
2023-01-20 16:03           ` Michal Orzel
2023-01-20 17:49             ` Julien Grall
2023-01-20 18:08               ` Ayan Kumar Halder
2023-01-20 23:01                 ` Stefano Stabellini
2023-01-21 10:24                   ` Michal Orzel
2023-01-17 17:43 ` [XEN v2 03/11] xen/arm: domain_build: Replace use of paddr_t in find_domU_holes() Ayan Kumar Halder
2023-01-19 23:02   ` Stefano Stabellini
2023-01-20  9:48     ` Julien Grall
2023-01-20  9:52       ` Julien Grall
2023-01-17 17:43 ` [XEN v2 04/11] xen/arm: Typecast the DT values into paddr_t Ayan Kumar Halder
2023-01-19 23:20   ` Stefano Stabellini
2023-01-19 23:34     ` Stefano Stabellini
2023-01-20 10:16       ` Julien Grall
2023-01-31 10:51         ` Ayan Kumar Halder
2023-01-31 15:57           ` Julien Grall
2023-01-17 17:43 ` [XEN v2 05/11] xen/arm: Use paddr_t instead of u64 for address/size Ayan Kumar Halder
2023-01-18  8:40   ` Jan Beulich
2023-01-18 11:15     ` Ayan Kumar Halder
2023-01-18 13:14       ` Jan Beulich
2023-01-18 13:34         ` George Dunlap
2023-01-18 13:58           ` Jan Beulich
2023-01-18 14:45             ` George Dunlap
2023-01-19 23:24   ` Stefano Stabellini
2023-02-06 19:21     ` Ayan Kumar Halder
2023-02-07  9:03       ` Julien Grall
2023-02-07 10:59         ` Ayan Kumar Halder
2023-02-07 12:18           ` Julien Grall
2023-01-20 10:34   ` Julien Grall
2023-01-17 17:43 ` [XEN v2 06/11] xen/arm: Introduce a wrapper for dt_device_get_address() to handle paddr_t Ayan Kumar Halder
2023-01-19 23:35   ` Stefano Stabellini
2023-01-17 17:43 ` [XEN v2 07/11] xen/arm: smmu: Use writeq_relaxed_non_atomic() for writing to SMMU_CBn_TTBR0 Ayan Kumar Halder
2023-01-19 23:40   ` Stefano Stabellini
2023-01-17 17:43 ` [XEN v2 08/11] xen/arm: guest_walk: LPAE specific bits should be enclosed within "ifndef CONFIG_ARM_PA_32" Ayan Kumar Halder
2023-01-19 23:43   ` Stefano Stabellini
2023-01-20 10:39     ` Julien Grall
2023-01-17 17:43 ` [XEN v2 09/11] xen/arm: Introduce ARM_PA_32 to support 32 bit physical address Ayan Kumar Halder
2023-01-18  8:50   ` Jan Beulich
2023-01-18 11:57     ` Ayan Kumar Halder
2023-01-18 13:19       ` Jan Beulich
2023-01-19 23:48         ` Stefano Stabellini
2023-01-18  9:18   ` Julien Grall
2023-01-30 22:00   ` Julien Grall
2023-01-17 17:43 ` [XEN v2 10/11] xen/arm: Restrict zeroeth_table_offset for ARM_64 Ayan Kumar Halder
2023-01-20  0:19   ` Stefano Stabellini
2023-01-20 10:53     ` Julien Grall
2023-01-20 16:53       ` Stefano Stabellini
2023-01-17 17:43 ` [XEN v2 11/11] xen/arm: p2m: Enable support for 32bit IPA Ayan Kumar Halder
2023-01-20  0:05   ` Stefano Stabellini
2023-01-20 11:06   ` Julien Grall
2023-02-07 15:34     ` Ayan Kumar Halder
2023-02-09 11:45       ` Julien Grall
2023-02-10 15:39         ` Ayan Kumar Halder
2023-02-10 16:19           ` Julien Grall
2023-02-10 17:51             ` Ayan Kumar Halder
2023-02-10 17:58               ` Julien Grall
2023-01-18 10:12 ` [XEN v2 00/11] Add support for 32 bit physical address Michal Orzel

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.