[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v5 07/13] xen/arm: Extract MMU-specific code



Hi Henry,

On 14/08/2023 05:25, Henry Wang wrote:
Currently, most of the MMU-specific code is in mm.{c,h}. To make the
mm extendable, this commit extract the MMU-specific code by firstly:
- Create a arch/arm/include/asm/mmu/ subdir.
- Create a arch/arm/mmu/ subdir.

Then move the MMU-specific code to above mmu subdir, which includes
below changes:
- Move arch/arm/arm64/mm.c to arch/arm/arm64/mmu/mm.c
- Move MMU-related declaration in arch/arm/include/asm/mm.h to
   arch/arm/include/asm/mmu/mm.h
- Move the MMU-related declaration dump_pt_walk() in asm/page.h
While I agree that dump_pt_walk() is better to be defined in mm.h, I am not entirely sure for ...

   and pte_of_xenaddr() in asm/setup.h to the new asm/mmu/mm.h.

... pte_of_xenaddr(). It was defined in setup.h because this is an helper that is only intended to be used during early boot.


That said, it is probably not worth creating a new helper for that. So I would suggest to at least mark pte_of_xenaddr() __init to make clear of the intended usage.

- Move MMU-related code in arch/arm/mm.c to arch/arm/mmu/mm.c.

Also modify the build system (Makefiles in this case) to pick above
mentioned code changes.

This patch is a pure code movement, no functional change intended.

Signed-off-by: Henry Wang <Henry.Wang@xxxxxxx>
---
With the code movement of this patch, the descriptions on top of
xen/arch/arm/mm.c and xen/arch/arm/mmu/mm.c might need some changes,
suggestions?
v5:
- Rebase on top of xen/arm: Introduce CONFIG_MMU Kconfig option and
   xen/arm: mm: add missing extern variable declaration
v4:
- Rework "[v3,13/52] xen/mmu: extract mmu-specific codes from
   mm.c/mm.h" with the lastest staging branch, only do the code movement
   in this patch to ease the review.
---
  xen/arch/arm/Makefile             |    1 +
  xen/arch/arm/arm64/Makefile       |    1 -
  xen/arch/arm/arm64/mmu/Makefile   |    1 +
  xen/arch/arm/arm64/{ => mmu}/mm.c |    0
  xen/arch/arm/include/asm/mm.h     |   20 +-
  xen/arch/arm/include/asm/mmu/mm.h |   55 ++
  xen/arch/arm/include/asm/page.h   |   15 -
  xen/arch/arm/include/asm/setup.h  |    3 -
  xen/arch/arm/mm.c                 | 1119 ----------------------------
  xen/arch/arm/mmu/Makefile         |    1 +
  xen/arch/arm/mmu/mm.c             | 1146 +++++++++++++++++++++++++++++

I noticed you transferred everything in mm.c But I think some part could go in arm{32,64}/mmu/mm.c.

  11 files changed, 1208 insertions(+), 1154 deletions(-)
  rename xen/arch/arm/arm64/{ => mmu}/mm.c (100%)
  create mode 100644 xen/arch/arm/include/asm/mmu/mm.h
  create mode 100644 xen/arch/arm/mmu/Makefile
  create mode 100644 xen/arch/arm/mmu/mm.c

(I haven't checked if the code was moved correctly. I only checked if the split makes sense).

To ease the review, I think this patch can be split in a more piecemeal patches. The first two pieces would be :
  * Patch #1 transfer xen_pt_update()/dump_pt_walk() and their dependencies
  * Patch #2 transfer root page-table allocation

Then you can have some for each small functions.

[...]

diff --git a/xen/arch/arm/arm64/mm.c b/xen/arch/arm/arm64/mmu/mm.c
similarity index 100%
rename from xen/arch/arm/arm64/mm.c
rename to xen/arch/arm/arm64/mmu/mm.c
diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index aaacba3f04..dc1458b047 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -14,6 +14,10 @@
  # error "unknown ARM variant"
  #endif
+#ifdef CONFIG_MMU
+#include <asm/mmu/mm.h>

I am guessing you will need to include <asm/mpu/mm.h> at some point. So I would add a:

#else
# error "Unknown memory management layout"

This would be easier to find out where includes might be missing.

[...]

@@ -1233,11 +119,6 @@ int map_pages_to_xen(unsigned long virt,
      return xen_pt_update(virt, mfn, nr_mfns, flags);
  }

[...]

+/* MMU setup for secondary CPUS (which already have paging enabled) */
+void mmu_init_secondary_cpu(void)
+{
+    xen_pt_enforce_wnx();
+}
+
+#ifdef CONFIG_ARM_32

Rather than #ifdef, I would prefer if we move each implementation to arm32/mmu/mm.c and ...

+/*
+ * Set up the direct-mapped xenheap:
+ * up to 1GB of contiguous, always-mapped memory.
+ */
+void __init setup_directmap_mappings(unsigned long base_mfn,
+                                     unsigned long nr_mfns)
+{
+    int rc;
+
+    rc = map_pages_to_xen(XENHEAP_VIRT_START, _mfn(base_mfn), nr_mfns,
+                          PAGE_HYPERVISOR_RW | _PAGE_BLOCK);
+    if ( rc )
+        panic("Unable to setup the directmap mappings.\n");
+
+    /* Record where the directmap is, for translation routines. */
+    directmap_virt_end = XENHEAP_VIRT_START + nr_mfns * PAGE_SIZE;
+}
+#else /* CONFIG_ARM_64 */
+/* Map the region in the directmap area. */
+void __init setup_directmap_mappings(unsigned long base_mfn,
+                                     unsigned long nr_mfns)

... arm64/mmu/mm.c.

+{
+    int rc;
+
+    /* First call sets the directmap physical and virtual offset. */
+    if ( mfn_eq(directmap_mfn_start, INVALID_MFN) )
+    {
+        unsigned long mfn_gb = base_mfn & ~((FIRST_SIZE >> PAGE_SHIFT) - 1);
+
+        directmap_mfn_start = _mfn(base_mfn);
+        directmap_base_pdx = mfn_to_pdx(_mfn(base_mfn));
+        /*
+         * The base address may not be aligned to the first level
+         * size (e.g. 1GB when using 4KB pages). This would prevent
+         * superpage mappings for all the regions because the virtual
+         * address and machine address should both be suitably aligned.
+         *
+         * Prevent that by offsetting the start of the directmap virtual
+         * address.
+         */
+        directmap_virt_start = DIRECTMAP_VIRT_START +
+            (base_mfn - mfn_gb) * PAGE_SIZE;
+    }
+
+    if ( base_mfn < mfn_x(directmap_mfn_start) )
+        panic("cannot add directmap mapping at %lx below heap start %lx\n",
+              base_mfn, mfn_x(directmap_mfn_start));
+
+    rc = map_pages_to_xen((vaddr_t)__mfn_to_virt(base_mfn),
+                          _mfn(base_mfn), nr_mfns,
+                          PAGE_HYPERVISOR_RW | _PAGE_BLOCK);
+    if ( rc )
+        panic("Unable to setup the directmap mappings.\n");
+}
+#endif
+
+/* Map a frame table to cover physical addresses ps through pe */
+void __init setup_frametable_mappings(paddr_t ps, paddr_t pe)

I looked at the implement for the MPU and the code is mainly the same. So can we keep this code in common and just ...

+{
+    unsigned long nr_pdxs = mfn_to_pdx(mfn_add(maddr_to_mfn(pe), -1)) -
+                            mfn_to_pdx(maddr_to_mfn(ps)) + 1;
+    unsigned long frametable_size = nr_pdxs * sizeof(struct page_info);
+    mfn_t base_mfn;
+    const unsigned long mapping_size = frametable_size < MB(32) ? MB(2) : 
MB(32);
+    int rc;
+
+    /*
+     * The size of paddr_t should be sufficient for the complete range of
+     * physical address.
+     */
+    BUILD_BUG_ON((sizeof(paddr_t) * BITS_PER_BYTE) < PADDR_BITS);
+    BUILD_BUG_ON(sizeof(struct page_info) != PAGE_INFO_SIZE);
+
+    if ( frametable_size > FRAMETABLE_SIZE )
+        panic("The frametable cannot cover the physical region %#"PRIpaddr" - 
%#"PRIpaddr"\n",
+              ps, pe);
+
+    frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ps));
+    /* Round up to 2M or 32M boundary, as appropriate. */
+    frametable_size = ROUNDUP(frametable_size, mapping_size);
+    base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 32<<(20-12));
+
+    rc = map_pages_to_xen(FRAMETABLE_VIRT_START, base_mfn,
+                          frametable_size >> PAGE_SHIFT,
+                          PAGE_HYPERVISOR_RW | _PAGE_BLOCK);

abstract the frametable mapping? THis would also make clear that the BUILD_BUG_ON() above are not specific to the MMU code.

+    if ( rc )
+        panic("Unable to setup the frametable mappings.\n");
+
+    memset(&frame_table[0], 0, nr_pdxs * sizeof(struct page_info));
+    memset(&frame_table[nr_pdxs], -1,
+           frametable_size - (nr_pdxs * sizeof(struct page_info)));
+
+    frametable_virt_end = FRAMETABLE_VIRT_START + (nr_pdxs * sizeof(struct 
page_info));
+}

--
Julien Grall



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.