From: Stefano Stabellini <sstabellini@kernel.org>
To: Julien Grall <julien.grall@arm.com>
Cc: xen-devel@lists.xenproject.org,
Stefano Stabellini <sstabellini@kernel.org>,
Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
Subject: Re: [Xen-devel] [PATCH v3 26/28] xen/arm64: head: Use a page mapping for the 1:1 mapping in create_page_tables()
Date: Fri, 23 Aug 2019 18:16:57 -0700 (PDT) [thread overview]
Message-ID: <alpine.DEB.2.21.1908231754060.26226@sstabellini-ThinkPad-T480s> (raw)
In-Reply-To: <20190812173019.11956-27-julien.grall@arm.com>
On Mon, 12 Aug 2019, Julien Grall wrote:
> At the moment the function create_page_tables() will use 1GB/2MB
> mapping for the identity mapping. As we don't know what is present
> before and after Xen in memory, we may end up to map
> device/reserved-memory with cacheable memory. This may result to
> mismatched attributes as other users may access the same region
> differently.
>
> To prevent any issues, we should only map the strict minimum in the
> 1:1 mapping. A check in xen.lds.S already guarantees anything
> necessary for turning on the MMU fits in a page (at the moment 4K).
>
> As only one page will be mapped for the 1:1 mapping, it is necessary
> to pre-allocate a page for the 3rd level table.
>
> For simplicity, all the tables that may be necessary for setting up the
> 1:1 mapping are linked together in advance. They will then be linked to
> the boot page tables at the correct level.
>
> Signed-off-by: Julien Grall <julien.grall@arm.com>
>
> ---
> Changes in v3:
> - Patch added
> ---
> xen/arch/arm/arm64/head.S | 176 ++++++++++++++++++++--------------------------
> xen/arch/arm/mm.c | 2 +
> 2 files changed, 78 insertions(+), 100 deletions(-)
>
> diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
> index f4177dbba1..1e5b1035b8 100644
> --- a/xen/arch/arm/arm64/head.S
> +++ b/xen/arch/arm/arm64/head.S
> @@ -566,100 +566,17 @@ ENDPROC(cpu_init)
> * x19: paddr(start)
> * x20: phys offset
> *
> - * Clobbers x0 - x4, x25
> - *
> - * Register usage within this function:
> - * x25: Identity map in place
> + * Clobbers x0 - x4
> */
> create_page_tables:
> - /*
> - * If Xen is loaded at exactly XEN_VIRT_START then we don't
> - * need an additional 1:1 mapping, the virtual mapping will
> - * suffice.
> - */
> - cmp x19, #XEN_VIRT_START
> - cset x25, eq /* x25 := identity map in place, or not */
> -
> - load_paddr x4, boot_pgtable
> -
> - /* Setup boot_pgtable: */
> - load_paddr x1, boot_first
> -
> - /* ... map boot_first in boot_pgtable[0] */
> - mov x3, #PT_PT /* x2 := table map of boot_first */
> - orr x2, x1, x3 /* + rights for linear PT */
> - str x2, [x4, #0] /* Map it in slot 0 */
> -
> - /* ... map of paddr(start) in boot_pgtable+boot_first_id */
> - lsr x1, x19, #ZEROETH_SHIFT/* Offset of base paddr in boot_pgtable */
> - cbz x1, 1f /* It's in slot 0, map in boot_first
> - * or boot_second later on */
> -
> - /*
> - * Level zero does not support superpage mappings, so we have
> - * to use an extra first level page in which we create a 1GB mapping.
> - */
> - load_paddr x2, boot_first_id
> -
> - mov x3, #PT_PT /* x2 := table map of boot_first_id */
> - orr x2, x2, x3 /* + rights for linear PT */
> - str x2, [x4, x1, lsl #3]
> -
> - load_paddr x4, boot_first_id
> -
> - lsr x1, x19, #FIRST_SHIFT /* x1 := Offset of base paddr in boot_first_id */
> - lsl x2, x1, #FIRST_SHIFT /* x2 := Base address for 1GB mapping */
> - mov x3, #PT_MEM /* x2 := Section map */
> - orr x2, x2, x3
> - and x1, x1, #LPAE_ENTRY_MASK /* x1 := Slot offset */
> - str x2, [x4, x1, lsl #3] /* Mapping of paddr(start) */
> - mov x25, #1 /* x25 := identity map now in place */
> -
> -1: /* Setup boot_first: */
> - load_paddr x4, boot_first /* Next level into boot_first */
> -
> - /* ... map boot_second in boot_first[0] */
> - load_paddr x1, boot_second
> - mov x3, #PT_PT /* x2 := table map of boot_second */
> - orr x2, x1, x3 /* + rights for linear PT */
> - str x2, [x4, #0] /* Map it in slot 0 */
> -
> - /* ... map of paddr(start) in boot_first */
> - cbnz x25, 1f /* x25 is set if already created */
> - lsr x2, x19, #FIRST_SHIFT /* x2 := Offset of base paddr in boot_first */
> - and x1, x2, #LPAE_ENTRY_MASK /* x1 := Slot to use */
> - cbz x1, 1f /* It's in slot 0, map in boot_second */
> -
> - lsl x2, x2, #FIRST_SHIFT /* Base address for 1GB mapping */
> - mov x3, #PT_MEM /* x2 := Section map */
> - orr x2, x2, x3
> - str x2, [x4, x1, lsl #3] /* Create mapping of paddr(start)*/
> - mov x25, #1 /* x25 := identity map now in place */
> -
> -1: /* Setup boot_second: */
> - load_paddr x4, boot_second
> -
> - /* ... map boot_third in boot_second[1] */
> - load_paddr x1, boot_third
> - mov x3, #PT_PT /* x2 := table map of boot_third */
> - orr x2, x1, x3 /* + rights for linear PT */
> - str x2, [x4, #8] /* Map it in slot 1 */
> -
> - /* ... map of paddr(start) in boot_second */
> - cbnz x25, 1f /* x25 is set if already created */
> - lsr x2, x19, #SECOND_SHIFT /* x2 := Offset of base paddr in boot_second */
> - and x1, x2, #LPAE_ENTRY_MASK /* x1 := Slot to use */
> - cmp x1, #1
> - b.eq virtphys_clash /* It's in slot 1, which we cannot handle */
> -
> - lsl x2, x2, #SECOND_SHIFT /* Base address for 2MB mapping */
> - mov x3, #PT_MEM /* x2 := Section map */
> - orr x2, x2, x3
> - str x2, [x4, x1, lsl #3] /* Create mapping of paddr(start)*/
> - mov x25, #1 /* x25 := identity map now in place */
> + /* Prepare the page-tables for mapping Xen */
> + ldr x0, =XEN_VIRT_START
> + create_table_entry boot_pgtable, boot_first, x0, ZEROETH_SHIFT, x1, x2, x3
> + create_table_entry boot_first, boot_second, x0, FIRST_SHIFT, x1, x2, x3
> + create_table_entry boot_second, boot_third, x0, SECOND_SHIFT, x1, x2, x3
>
> -1: /* Setup boot_third: */
> - load_paddr x4, boot_third
> + /* Map Xen */
> + adr_l x4, boot_third
>
> lsr x2, x19, #THIRD_SHIFT /* Base address for 4K mapping */
> lsl x2, x2, #THIRD_SHIFT
> @@ -674,21 +591,80 @@ create_page_tables:
> cmp x1, #(LPAE_ENTRIES<<3) /* 512 entries per page */
> b.lt 1b
Why can't we use create_mapping_entry here?
> - /* Defer fixmap and dtb mapping until after paging enabled, to
> - * avoid them clashing with the 1:1 mapping. */
> + /*
> + * If Xen is loaded at exactly XEN_VIRT_START then we don't
> + * need an additional 1:1 mapping, the virtual mapping will
> + * suffice.
> + */
> + cmp x19, #XEN_VIRT_START
> + bne 1f
> + ret
> +1:
> + /*
> + * Only the first page of Xen will be part of the 1:1 mapping.
> + * All the boot_*_id tables are linked together even if they may
> + * not be all used. They will then be linked to the boot page
> + * tables at the correct level.
> + */
> + create_table_entry boot_first_id, boot_second_id, x19, FIRST_SHIFT, x0, x1, x2
> + create_table_entry boot_second_id, boot_third_id, x19, SECOND_SHIFT, x0, x1, x2
If I understood the code right, it is not actually required to link
boot_first_id -> boot_second_id and/or boot_second_id -> boot_third_id:
it depends on whether x19 clashes with XEN_FIRST_SLOT, XEN_SECOND_SLOT,
etc. Do you think it would be possible without making the code complex
to only call create_table_entry boot_first_id, boot_second_id and
create_table_entry boot_second_id, boot_third_id when required? So
moving the calls below after the relevant checks? It looks like it could
be done by adding those calls before "ret". I wouldn't mind if they are
duplicated but we could avoid it by adding appropriate labels and having
a single return path:
out1:
create_table_entry boot_first_id, boot_second_id, x19, FIRST_SHIFT, x0, x1, x2
out2:
create_table_entry boot_second_id, boot_third_id, x19, SECOND_SHIFT, x0, x1, x2
out3:
ret
(I have similar comments for the arm32 version, I guess your answers
will be the same for both.)
> + create_mapping_entry boot_third_id, x19, x19, x0, x1, x2
> +
> + /*
> + * Find the zeroeth slot used. Link boot_first_id into
> + * boot_pgtable if the slot is not XEN_ZEROETH_SLOT. For slot
> + * XEN_ZEROETH_SLOT, the tables associated with the 1:1 mapping
> + * will need to be linked in boot_first or boot_second.
> + */
> + lsr x0, x19, #ZEROETH_SHIFT /* x0 := zeroeth slot */
> + cmp x0, #XEN_ZEROETH_SLOT
> + beq 1f
> + /*
> + * It is not in slot XEN_ZEROETH_SLOT. Link boot_first_id
> + * into boot_pgtable.
> + */
> + create_table_entry boot_pgtable, boot_first_id, x19, ZEROETH_SHIFT, x0, x1, x2
> + ret
> +
> +1:
> + /*
> + * Find the first slot used. Link boot_second_id into boot_first
> + * if the slot is not XEN_FIRST_SLOT. For slot XEN_FIRST_SLOT,
> + * the tables associated with the 1:1 mapping will need to be
> + * linked in boot_second.
> + */
> + lsr x0, x19, #FIRST_SHIFT
> + and x0, x0, #LPAE_ENTRY_MASK /* x0 := first slot */
> + cmp x0, #XEN_FIRST_SLOT
> + beq 1f
> + /*
> + * It is not in slot XEN_FIRST_SLOT. Link boot_second_id into
> + * boot_first
> + */
> + create_table_entry boot_first, boot_second_id, x19, FIRST_SHIFT, x0, x1, x2
> + ret
>
> - /* boot pagetable setup complete */
> +1:
> + /*
> + * Find the second slot used. Link boot_third_id into boot_second
> + * if the slot is not XEN_SECOND_SLOT. For slot XEN_SECOND_SLOT,
> + * Xen is not yet able to handle it.
> + */
> + lsr x0, x19, #SECOND_SHIFT
> + and x0, x0, #LPAE_ENTRY_MASK /* x0 := first slot */
> + cmp x0, #XEN_SECOND_SLOT
> + beq virtphys_clash
> + /*
> + * It is not in slot XEN_SECOND_SLOT. Link boot_third_id into
> + * boot_second.
> + */
> + create_table_entry boot_second, boot_third_id, x19, SECOND_SHIFT, x0, x1, x2
> + ret
>
> - cbnz x25, 1f /* Did we manage to create an identity mapping ? */
> - PRINT("Unable to build boot page tables - Failed to identity map Xen.\r\n")
> - b fail
> virtphys_clash:
> /* Identity map clashes with boot_third, which we cannot handle yet */
> PRINT("- Unable to build boot page tables - virt and phys addresses clash. -\r\n")
> b fail
> -
> -1:
> - ret
> ENDPROC(create_page_tables)
>
> /*
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 65552da4ba..72ffea7472 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -105,6 +105,8 @@ DEFINE_BOOT_PAGE_TABLE(boot_pgtable);
> #ifdef CONFIG_ARM_64
> DEFINE_BOOT_PAGE_TABLE(boot_first);
> DEFINE_BOOT_PAGE_TABLE(boot_first_id);
> +DEFINE_BOOT_PAGE_TABLE(boot_second_id);
> +DEFINE_BOOT_PAGE_TABLE(boot_third_id);
> #endif
> DEFINE_BOOT_PAGE_TABLE(boot_second);
> DEFINE_BOOT_PAGE_TABLE(boot_third);
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-08-24 1:17 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-12 17:29 [Xen-devel] [PATCH v3 00/28] xen/arm: Rework head.S to make it more compliant with the Arm Arm Julien Grall
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 01/28] xen/arm: lpae: Allow more LPAE helpers to be used in assembly Julien Grall
2019-08-22 17:07 ` Stefano Stabellini
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 02/28] xen/arm64: head: Remove 1:1 mapping as soon as it is not used Julien Grall
2019-08-22 17:58 ` Stefano Stabellini
2019-08-22 18:25 ` Julien Grall
2019-08-22 18:29 ` Stefano Stabellini
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 03/28] xen/arm64: head: Rework and document setup_fixmap() Julien Grall
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 04/28] xen/arm64: head: Rework and document launch() Julien Grall
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 05/28] xen/arm64: head: Setup TTBR_EL2 in enable_mmu() and add missing isb Julien Grall
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 06/28] xen/arm64: head: Introduce a macro to get a PC-relative address of a symbol Julien Grall
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 07/28] xen/arm64: head: Fix typo in the documentation on top of init_uart() Julien Grall
2019-08-22 17:08 ` Stefano Stabellini
2019-08-12 17:29 ` [Xen-devel] [PATCH v3 08/28] xen/arm32: head: Add a macro to move an immediate constant into a 32-bit register Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 09/28] xen/arm32: head: Mark the end of subroutines with ENDPROC Julien Grall
2019-08-12 17:33 ` Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 10/28] xen/arm32: head: Don't clobber r14/lr in the macro PRINT Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 11/28] xen/arm32: head: Rework UART initialization on boot CPU Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 12/28] xen/arm32: head: Introduce print_reg Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 13/28] xen/arm32: head: Introduce distinct paths for the boot CPU and secondary CPUs Julien Grall
2019-08-22 17:11 ` Stefano Stabellini
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 14/28] xen/arm32: head: Rework and document check_cpu_mode() Julien Grall
2019-08-22 17:14 ` Stefano Stabellini
2019-09-07 10:35 ` Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 15/28] xen/arm32: head: Rework and document zero_bss() Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 16/28] xen/arm32: head: Document create_pages_tables() Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 17/28] xen/arm32: head: Document enable_mmu() Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 18/28] xen/arm32: head: Move assembly switch to the runtime PT in secondary CPUs path Julien Grall
2019-08-22 17:17 ` Stefano Stabellini
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 19/28] xen/arm32: head: Don't setup the fixmap on secondary CPUs Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 20/28] xen/arm32: head: Remove 1:1 mapping as soon as it is not used Julien Grall
2019-08-22 18:17 ` Stefano Stabellini
2019-08-22 18:31 ` Julien Grall
2019-08-22 22:53 ` Stefano Stabellini
2019-08-22 23:39 ` Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 21/28] xen/arm32: head: Rework and document setup_fixmap() Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 22/28] xen/arm32: head: Rework and document launch() Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 23/28] xen/arm32: head: Setup HTTBR in enable_mmu() and add missing isb Julien Grall
2019-08-22 17:15 ` Stefano Stabellini
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 24/28] xen/arm: Zero BSS after the MMU and D-cache is turned on Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 25/28] xen/arm64: head: Introduce macros to create table and mapping entry Julien Grall
2019-08-22 23:31 ` Stefano Stabellini
2019-08-22 23:44 ` Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 26/28] xen/arm64: head: Use a page mapping for the 1:1 mapping in create_page_tables() Julien Grall
2019-08-24 1:16 ` Stefano Stabellini [this message]
2019-09-17 17:53 ` Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 27/28] xen/arm32: head: Introduce macros to create table and mapping entry Julien Grall
2019-08-23 1:10 ` Stefano Stabellini
2019-08-23 9:40 ` Julien Grall
2019-08-12 17:30 ` [Xen-devel] [PATCH v3 28/28] xen/arm32: head: Use a page mapping for the 1:1 mapping in create_page_tables() 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=alpine.DEB.2.21.1908231754060.26226@sstabellini-ThinkPad-T480s \
--to=sstabellini@kernel.org \
--cc=Volodymyr_Babchuk@epam.com \
--cc=julien.grall@arm.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).