All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien@xen.org>
To: xen-devel@lists.xenproject.org
Cc: julien@xen.org, "Wei Liu" <wei.liu2@citrix.com>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Bertrand Marquis" <bertrand.marquis@arm.com>,
	"Volodymyr Babchuk" <Volodymyr_Babchuk@epam.com>,
	"George Dunlap" <george.dunlap@citrix.com>,
	"Hongyan Xia" <hongyxia@amazon.com>,
	"Julien Grall" <jgrall@amazon.com>,
	"Jan Beulich" <jbeulich@suse.com>, "Wei Liu" <wl@xen.org>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH v3 14/19] xen/arm: add Persistent Map (PMAP) infrastructure
Date: Mon, 21 Feb 2022 10:22:13 +0000	[thread overview]
Message-ID: <20220221102218.33785-15-julien@xen.org> (raw)
In-Reply-To: <20220221102218.33785-1-julien@xen.org>

From: Wei Liu <wei.liu2@citrix.com>

The basic idea is like Persistent Kernel Map (PKMAP) in Linux. We
pre-populate all the relevant page tables before the system is fully
set up.

We will need it on Arm in order to rework the arm64 version of
xenheap_setup_mappings() as we may need to use pages allocated from
the boot allocator before they are effectively mapped.

This infrastructure is not lock-protected therefore can only be used
before smpboot. After smpboot, map_domain_page() has to be used.

This is based on the x86 version [1] that was originally implemented
by Wei Liu.

The PMAP infrastructure is implemented in common code with some
arch helpers to set/clear the page-table entries and convertion
between a fixmap slot to a virtual address...

As mfn_to_xen_entry() now needs to be exported, take the opportunity
to swich the parameter attr from unsigned to unsigned int.

[1] <e92da4ad6015b6089737fcccba3ec1d6424649a5.1588278317.git.hongyxia@amazon.com>

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: Hongyan Xia <hongyxia@amazon.com>
[julien: Adapted for Arm]
Signed-off-by: Julien Grall <jgrall@amazon.com>

---
    Changes in v3:
        - s/BITS_PER_LONG/BITS_PER_BYTE/
        - Move pmap to common code

    Changes in v2:
        - New patch

Cc: Jan Beulich <jbeulich@suse.com>
Cc: Wei Liu <wl@xen.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Roger Pau Monné <roger.pau@citrix.com>
---
 xen/arch/arm/Kconfig              |  1 +
 xen/arch/arm/include/asm/fixmap.h | 17 +++++++
 xen/arch/arm/include/asm/lpae.h   |  8 ++++
 xen/arch/arm/include/asm/pmap.h   | 33 +++++++++++++
 xen/arch/arm/mm.c                 |  7 +--
 xen/common/Kconfig                |  3 ++
 xen/common/Makefile               |  1 +
 xen/common/pmap.c                 | 79 +++++++++++++++++++++++++++++++
 xen/include/xen/pmap.h            | 16 +++++++
 9 files changed, 159 insertions(+), 6 deletions(-)
 create mode 100644 xen/arch/arm/include/asm/pmap.h
 create mode 100644 xen/common/pmap.c
 create mode 100644 xen/include/xen/pmap.h

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index ecfa6822e4d3..a89a67802aa9 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -14,6 +14,7 @@ config ARM
 	select HAS_DEVICE_TREE
 	select HAS_PASSTHROUGH
 	select HAS_PDX
+	select HAS_PMAP
 	select IOMMU_FORCE_PT_SHARE
 
 config ARCH_DEFCONFIG
diff --git a/xen/arch/arm/include/asm/fixmap.h b/xen/arch/arm/include/asm/fixmap.h
index 1cee51e52ab9..c46a15e59de4 100644
--- a/xen/arch/arm/include/asm/fixmap.h
+++ b/xen/arch/arm/include/asm/fixmap.h
@@ -5,12 +5,20 @@
 #define __ASM_FIXMAP_H
 
 #include <xen/acpi.h>
+#include <xen/pmap.h>
 
 /* Fixmap slots */
 #define FIXMAP_CONSOLE  0  /* The primary UART */
 #define FIXMAP_MISC     1  /* Ephemeral mappings of hardware */
 #define FIXMAP_ACPI_BEGIN  2  /* Start mappings of ACPI tables */
 #define FIXMAP_ACPI_END    (FIXMAP_ACPI_BEGIN + NUM_FIXMAP_ACPI_PAGES - 1)  /* End mappings of ACPI tables */
+#define FIXMAP_PMAP_BEGIN (FIXMAP_ACPI_END + 1) /* Start of PMAP */
+#define FIXMAP_PMAP_END (FIXMAP_PMAP_BEGIN + NUM_FIX_PMAP - 1) /* End of PMAP */
+
+#define FIXMAP_LAST FIXMAP_PMAP_END
+
+#define FIXADDR_START FIXMAP_ADDR(0)
+#define FIXADDR_TOP FIXMAP_ADDR(FIXMAP_LAST)
 
 #ifndef __ASSEMBLY__
 
@@ -19,6 +27,15 @@ extern void set_fixmap(unsigned map, mfn_t mfn, unsigned attributes);
 /* Remove a mapping from a fixmap entry */
 extern void clear_fixmap(unsigned map);
 
+#define fix_to_virt(slot) ((void *)FIXMAP_ADDR(slot))
+
+static inline unsigned int virt_to_fix(vaddr_t vaddr)
+{
+    BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+
+    return ((vaddr - FIXADDR_START) >> PAGE_SHIFT);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_FIXMAP_H */
diff --git a/xen/arch/arm/include/asm/lpae.h b/xen/arch/arm/include/asm/lpae.h
index 8cf932b5c947..6099037da1c0 100644
--- a/xen/arch/arm/include/asm/lpae.h
+++ b/xen/arch/arm/include/asm/lpae.h
@@ -4,6 +4,7 @@
 #ifndef __ASSEMBLY__
 
 #include <xen/page-defs.h>
+#include <xen/mm-frame.h>
 
 /*
  * WARNING!  Unlike the x86 pagetable code, where l1 is the lowest level and
@@ -168,6 +169,13 @@ static inline bool lpae_is_superpage(lpae_t pte, unsigned int level)
         third_table_offset(addr)            \
     }
 
+/*
+ * Standard entry type that we'll use to build Xen's own pagetables.
+ * We put the same permissions at every level, because they're ignored
+ * by the walker in non-leaf entries.
+ */
+lpae_t mfn_to_xen_entry(mfn_t mfn, unsigned int attr);
+
 #endif /* __ASSEMBLY__ */
 
 /*
diff --git a/xen/arch/arm/include/asm/pmap.h b/xen/arch/arm/include/asm/pmap.h
new file mode 100644
index 000000000000..70eafe2891d7
--- /dev/null
+++ b/xen/arch/arm/include/asm/pmap.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_PMAP_H__
+#define __ASM_PMAP_H__
+
+#include <xen/mm.h>
+
+/* XXX: Find an header to declare it */
+extern lpae_t xen_fixmap[XEN_PT_LPAE_ENTRIES];
+
+static inline void arch_pmap_map(unsigned int slot, mfn_t mfn)
+{
+    lpae_t *entry = &xen_fixmap[slot];
+    lpae_t pte;
+
+    ASSERT(!lpae_is_valid(*entry));
+
+    pte = mfn_to_xen_entry(mfn, PAGE_HYPERVISOR_RW);
+    pte.pt.table = 1;
+    write_pte(entry, pte);
+}
+
+static inline void arch_pmap_unmap(unsigned int slot)
+{
+    lpae_t pte = {};
+
+    write_pte(&xen_fixmap[slot], pte);
+
+    flush_xen_tlb_range_va_local(FIXMAP_ADDR(slot), PAGE_SIZE);
+}
+
+void arch_pmap_map_slot(unsigned int slot, mfn_t mfn);
+void arch_pmap_clear_slot(void *ptr);
+
+#endif /* __ASM_PMAP_H__ */
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index d6a4b9407c43..b7942464d4de 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -290,12 +290,7 @@ void dump_hyp_walk(vaddr_t addr)
     dump_pt_walk(ttbr, addr, HYP_PT_ROOT_LEVEL, 1);
 }
 
-/*
- * Standard entry type that we'll use to build Xen's own pagetables.
- * We put the same permissions at every level, because they're ignored
- * by the walker in non-leaf entries.
- */
-static inline lpae_t mfn_to_xen_entry(mfn_t mfn, unsigned attr)
+lpae_t mfn_to_xen_entry(mfn_t mfn, unsigned int attr)
 {
     lpae_t e = (lpae_t) {
         .pt = {
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index db687b1785e7..b6c55af2eb03 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -49,6 +49,9 @@ config HAS_KEXEC
 config HAS_PDX
 	bool
 
+config HAS_PMAP
+	bool
+
 config HAS_SCHED_GRANULARITY
 	bool
 
diff --git a/xen/common/Makefile b/xen/common/Makefile
index ca839118e4d1..8b42b0828134 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -28,6 +28,7 @@ obj-y += multicall.o
 obj-y += notifier.o
 obj-y += page_alloc.o
 obj-$(CONFIG_HAS_PDX) += pdx.o
+obj-bin-$(CONFIG_HAS_PMAP) += pmap.init.o
 obj-$(CONFIG_PERF_COUNTERS) += perfc.o
 obj-y += preempt.o
 obj-y += random.o
diff --git a/xen/common/pmap.c b/xen/common/pmap.c
new file mode 100644
index 000000000000..cea730ead545
--- /dev/null
+++ b/xen/common/pmap.c
@@ -0,0 +1,79 @@
+#include <xen/bitops.h>
+#include <xen/init.h>
+#include <xen/pmap.h>
+
+#include <asm/pmap.h>
+#include <asm/fixmap.h>
+
+/*
+ * Simple mapping infrastructure to map / unmap pages in fixed map.
+ * This is used to set up the page table for mapcache, which is used
+ * by map domain page infrastructure.
+ *
+ * This structure is not protected by any locks, so it must not be used after
+ * smp bring-up.
+ */
+
+/* Bitmap to track which slot is used */
+static unsigned long __initdata inuse;
+
+void *__init pmap_map(mfn_t mfn)
+{
+    unsigned long flags;
+    unsigned int idx;
+    unsigned int slot;
+
+    BUILD_BUG_ON(sizeof(inuse) * BITS_PER_BYTE < NUM_FIX_PMAP);
+
+    ASSERT(system_state < SYS_STATE_smp_boot);
+
+    local_irq_save(flags);
+
+    idx = find_first_zero_bit(&inuse, NUM_FIX_PMAP);
+    if ( idx == NUM_FIX_PMAP )
+        panic("Out of PMAP slots\n");
+
+    __set_bit(idx, &inuse);
+
+    slot = idx + FIXMAP_PMAP_BEGIN;
+    ASSERT(slot >= FIXMAP_PMAP_BEGIN && slot <= FIXMAP_PMAP_END);
+
+    /*
+     * We cannot use set_fixmap() here. We use PMAP when there is no direct map,
+     * so map_pages_to_xen() called by set_fixmap() needs to map pages on
+     * demand, which then calls pmap() again, resulting in a loop. Modify the
+     * PTEs directly instead. The same is true for pmap_unmap().
+     */
+    arch_pmap_map(slot, mfn);
+
+    local_irq_restore(flags);
+
+    return fix_to_virt(slot);
+}
+
+void __init pmap_unmap(const void *p)
+{
+    unsigned long flags;
+    unsigned int idx;
+    unsigned int slot = virt_to_fix((unsigned long)p);
+
+    ASSERT(system_state < SYS_STATE_smp_boot);
+    ASSERT(slot >= FIXMAP_PMAP_BEGIN && slot <= FIXMAP_PMAP_END);
+
+    idx = slot - FIXMAP_PMAP_BEGIN;
+    local_irq_save(flags);
+
+    __clear_bit(idx, &inuse);
+    arch_pmap_unmap(slot);
+
+    local_irq_restore(flags);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/pmap.h b/xen/include/xen/pmap.h
new file mode 100644
index 000000000000..93e61b10870e
--- /dev/null
+++ b/xen/include/xen/pmap.h
@@ -0,0 +1,16 @@
+#ifndef __XEN_PMAP_H__
+#define __XEN_PMAP_H__
+
+/* Large enough for mapping 5 levels of page tables with some headroom */
+#define NUM_FIX_PMAP 8
+
+#ifndef __ASSEMBLY__
+
+#include <xen/mm-frame.h>
+
+void *pmap_map(mfn_t mfn);
+void pmap_unmap(const void *p);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __XEN_PMAP_H__ */
-- 
2.32.0



  parent reply	other threads:[~2022-02-21 10:51 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-21 10:21 [PATCH v3 00/19] xen/arm: mm: Remove open-coding mappings Julien Grall
2022-02-21 10:22 ` [PATCH v3 01/19] xen/arm: lpae: Rename LPAE_ENTRIES_MASK_GS to LPAE_ENTRY_MASK_GS Julien Grall
2022-02-22 13:30   ` Michal Orzel
2022-02-24 22:19     ` Julien Grall
2022-02-22 15:21   ` Bertrand Marquis
2022-02-21 10:22 ` [PATCH v3 02/19] xen/arm: lpae: Use the generic helpers to defined the Xen PT helpers Julien Grall
2022-02-22 14:26   ` Michal Orzel
2022-02-22 15:38   ` Bertrand Marquis
2022-02-24 22:24     ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 03/19] xen/arm: p2m: Replace level_{orders, masks} arrays with XEN_PT_LEVEL_{ORDER, MASK} Julien Grall
2022-02-22 15:55   ` Bertrand Marquis
2022-02-24 22:41     ` Julien Grall
2022-02-25  8:27       ` Bertrand Marquis
2022-02-25 16:41         ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 04/19] xen/arm: mm: Allow other mapping size in xen_pt_update_entry() Julien Grall
2022-04-01 23:35   ` Stefano Stabellini
2022-04-02 15:59     ` Julien Grall
2022-04-05 20:46       ` Stefano Stabellini
2022-04-10 12:17         ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 05/19] xen/arm: mm: Add support for the contiguous bit Julien Grall
2022-02-26 19:30   ` Julien Grall
2022-03-21  5:46     ` Hongda Deng
2022-04-01 23:53   ` Stefano Stabellini
2022-04-02 16:18     ` Julien Grall
2022-04-05 20:47       ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 06/19] xen/arm: mm: Avoid flushing the TLBs when mapping are inserted Julien Grall
2022-04-02  0:00   ` Stefano Stabellini
2022-04-02 16:38     ` Julien Grall
2022-04-05 20:49       ` Stefano Stabellini
2022-04-10 12:30         ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 07/19] xen/arm: mm: Don't open-code Xen PT update in remove_early_mappings() Julien Grall
2022-04-02  0:04   ` Stefano Stabellini
2022-04-02 16:47     ` Julien Grall
2022-04-05 20:51       ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 08/19] xen/arm: mm: Re-implement early_fdt_map() using map_pages_to_xen() Julien Grall
2022-03-18  7:36   ` Hongda Deng
2022-03-18 19:44     ` Julien Grall
2022-04-02  0:10   ` Stefano Stabellini
2022-04-02 17:02     ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 09/19] xen/arm32: mm: Check if the virtual address is shared before updating it Julien Grall
2022-03-18 10:44   ` Hongda Deng
2022-03-18 22:15     ` Julien Grall
2022-03-19 15:59   ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 10/19] xen/arm32: mm: Re-implement setup_xenheap_mappings() using map_pages_to_xen() Julien Grall
2022-04-02  0:11   ` Stefano Stabellini
2022-05-14  9:42   ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 11/19] xen/arm: mm: Allocate xen page tables in domheap rather than xenheap Julien Grall
2022-02-21 10:22 ` [PATCH v3 12/19] xen/arm: mm: Allow page-table allocation from the boot allocator Julien Grall
2022-04-05 20:58   ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 13/19] xen/arm: Move fixmap definitions in a separate header Julien Grall
2022-02-22 15:10   ` Jan Beulich
2022-04-05 21:12   ` Stefano Stabellini
2022-04-05 21:47     ` Julien Grall
2022-04-06  0:10       ` Stefano Stabellini
2022-04-06  8:24         ` Julien Grall
2022-02-21 10:22 ` Julien Grall [this message]
2022-02-22 15:22   ` [PATCH v3 14/19] xen/arm: add Persistent Map (PMAP) infrastructure Jan Beulich
2022-02-28  9:55     ` Julien Grall
2022-02-28 10:10       ` Jan Beulich
2022-02-28 10:20         ` Julien Grall
2022-02-28 10:30           ` Jan Beulich
2022-02-28 10:52             ` Julien Grall
2022-04-05 21:27   ` Stefano Stabellini
2022-05-14 10:17     ` Julien Grall
2022-02-21 10:22 ` [PATCH v3 15/19] xen/arm: mm: Clean-up the includes and order them Julien Grall
2022-04-05 21:29   ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 16/19] xen/arm: mm: Use the PMAP helpers in xen_{,un}map_table() Julien Grall
2022-04-05 21:36   ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 17/19] xen/arm64: mm: Add memory to the boot allocator first Julien Grall
2022-04-05 21:50   ` Stefano Stabellini
2022-04-05 22:12     ` Julien Grall
2022-04-06  0:02       ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 18/19] xen/arm: mm: Rework setup_xenheap_mappings() Julien Grall
2022-04-05 23:57   ` Stefano Stabellini
2022-02-21 10:22 ` [PATCH v3 19/19] xen/arm: mm: Re-implement setup_frame_table_mappings() with map_pages_to_xen() Julien Grall
2022-03-16  6:10   ` Hongda Deng
2022-04-06  0:01   ` Stefano Stabellini
2022-05-14 10:02     ` Julien Grall
2022-02-27 19:25 ` [PATCH v3 00/19] xen/arm: mm: Remove open-coding mappings Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220221102218.33785-15-julien@xen.org \
    --to=julien@xen.org \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=bertrand.marquis@arm.com \
    --cc=george.dunlap@citrix.com \
    --cc=hongyxia@amazon.com \
    --cc=jbeulich@suse.com \
    --cc=jgrall@amazon.com \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=wei.liu2@citrix.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.