diff mbox series

[3/7] xen/arm32: head: Introduce get_table_slot() and use it

Message ID 20220812192448.43016-4-julien@xen.org (mailing list archive)
State New, archived
Headers show
Series xen/arm: More clean-ups and improvement | expand

Commit Message

Julien Grall Aug. 12, 2022, 7:24 p.m. UTC
From: Julien Grall <jgrall@amazon.com>

There are a few places in the code that need to find the slot at a
given page-table level.

So create a new macro get_table_slot() for that. This will reduce
the effort to figure out whether the code is doing the right thing.

The new macro is using 'ubfx' (or 'lsr' for the first level) rather
than the existing sequence (mov_w, lsr, and) because it doesn't require
a scratch register and reduce the number of instructions (4 -> 1).

Signed-off-by: Julien Grall <jgrall@amazon.com>
---
 xen/arch/arm/arm32/head.S | 56 ++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 24 deletions(-)

Comments

Wei Chen Aug. 15, 2022, 1:48 a.m. UTC | #1
Hi Julien,

On 2022/8/13 3:24, Julien Grall wrote:
> From: Julien Grall <jgrall@amazon.com>
> 
> There are a few places in the code that need to find the slot at a
> given page-table level.
> 
> So create a new macro get_table_slot() for that. This will reduce
> the effort to figure out whether the code is doing the right thing.
> 
> The new macro is using 'ubfx' (or 'lsr' for the first level) rather
> than the existing sequence (mov_w, lsr, and) because it doesn't require
> a scratch register and reduce the number of instructions (4 -> 1).
> 
> Signed-off-by: Julien Grall <jgrall@amazon.com>
> ---
>   xen/arch/arm/arm32/head.S | 56 ++++++++++++++++++++++-----------------
>   1 file changed, 32 insertions(+), 24 deletions(-)
> 
> diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
> index 46d93bebbabe..50f6fa4eb38d 100644
> --- a/xen/arch/arm/arm32/head.S
> +++ b/xen/arch/arm/arm32/head.S
> @@ -358,13 +358,31 @@ cpu_init_done:
>           mov   pc, r5                        /* Return address is in r5 */
>   ENDPROC(cpu_init)
>   
> +/*
> + * Macro to find the slot number at a given page-table level
> + *
> + * slot:     slot computed
> + * virt:     virtual address
> + * lvl:      page-table level
> + *
> + * Note that ubxf is unpredictable when the end bit is above 32-bit. So we
> + * can't use it for first level offset.
> + */
> +.macro get_table_slot, slot, virt, lvl
> +    .if \lvl == 1
> +        lsr   \slot, \virt, #XEN_PT_LEVEL_SHIFT(\lvl)
> +    .else
> +        ubfx  \slot, \virt, #XEN_PT_LEVEL_SHIFT(\lvl), #XEN_PT_LPAE_SHIFT
> +    .endif
> +.endm
> +
>   /*
>    * Macro to create a page table entry in \ptbl to \tbl
>    *
>    * ptbl:    table symbol where the entry will be created
>    * tbl:     table symbol to point to
>    * virt:    virtual address
> - * shift:   #imm page table shift
> + * lvl:     page-table level
>    * mmu:     Is the MMU turned on/off. If not specified it will be off
>    *
>    * Preserves \virt
> @@ -374,11 +392,9 @@ ENDPROC(cpu_init)
>    *
>    * Note that \virt should be in a register other than r1 - r4
>    */
> -.macro create_table_entry, ptbl, tbl, virt, shift, mmu=0
> -        lsr   r1, \virt, #\shift
> -        mov_w r2, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r2             /* r1 := slot in \tlb */
> -        lsl   r1, r1, #3             /* r1 := slot offset in \tlb */
> +.macro create_table_entry, ptbl, tbl, virt, lvl, mmu=0
> +        get_table_slot r1, \virt, \lvl  /* r1 := slot in \tlb */
> +        lsl   r1, r1, #3                /* r1 := slot offset in \tlb */
>   
>           load_paddr r4, \tbl
>   
> @@ -448,8 +464,8 @@ ENDPROC(cpu_init)
>   create_page_tables:
>           /* Prepare the page-tables for mapping Xen */
>           ldr   r0, =XEN_VIRT_START
> -        create_table_entry boot_pgtable, boot_second, r0, FIRST_SHIFT
> -        create_table_entry boot_second, boot_third, r0, SECOND_SHIFT
> +        create_table_entry boot_pgtable, boot_second, r0, 1
> +        create_table_entry boot_second, boot_third, r0, 2
>   
>           /* Setup boot_third: */
>           adr_l r4, boot_third, mmu=0
> @@ -486,12 +502,10 @@ create_page_tables:
>            * then the 1:1 mapping will use its own set of page-tables from
>            * the second level.
>            */
> -        lsr   r1, r9, #FIRST_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0              /* r1 := first slot */
> +        get_table_slot r1, r9, 1     /* r1 := first slot */
>           cmp   r1, #XEN_FIRST_SLOT
>           beq   1f
> -        create_table_entry boot_pgtable, boot_second_id, r9, FIRST_SHIFT
> +        create_table_entry boot_pgtable, boot_second_id, r9, 1
>           b     link_from_second_id
>   
>   1:
> @@ -501,16 +515,14 @@ create_page_tables:
>            * third level. For slot XEN_SECOND_SLOT, Xen is not yet able to handle
>            * it.
>            */
> -        lsr   r1, r9, #SECOND_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0             /* r1 := second slot */
> +        get_table_slot r1, r9, 2     /* r1 := second slot */
>           cmp   r1, #XEN_SECOND_SLOT
>           beq   virtphys_clash
> -        create_table_entry boot_second, boot_third_id, r9, SECOND_SHIFT
> +        create_table_entry boot_second, boot_third_id, r9, 2
>           b     link_from_third_id
>   
>   link_from_second_id:
> -        create_table_entry boot_second_id, boot_third_id, r9, SECOND_SHIFT
> +        create_table_entry boot_second_id, boot_third_id, r9, 2
>   link_from_third_id:
>           create_mapping_entry boot_third_id, r9, r9
>           mov   pc, lr
> @@ -571,9 +583,7 @@ remove_identity_mapping:
>            * Find the first slot used. Remove the entry for the first
>            * table if the slot is not XEN_FIRST_SLOT.
>            */
> -        lsr   r1, r9, #FIRST_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0              /* r1 := first slot */
> +        get_table_slot r1, r9, 1     /* r1 := first slot */
>           cmp   r1, #XEN_FIRST_SLOT
>           beq   1f
>           /* It is not in slot 0, remove the entry */
> @@ -587,9 +597,7 @@ remove_identity_mapping:
>            * Find the second slot used. Remove the entry for the first
>            * table if the slot is not XEN_SECOND_SLOT.
>            */
> -        lsr   r1, r9, #SECOND_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0             /* r1 := second slot */
> +        get_table_slot r1, r9, 2     /* r1 := second slot */
>           cmp   r1, #XEN_SECOND_SLOT
>           beq   identity_mapping_removed
>           /* It is not in slot 1, remove the entry */
> @@ -628,7 +636,7 @@ setup_fixmap:
>   #endif
>           /* Map fixmap into boot_second */
>           mov_w r0, FIXMAP_ADDR(0)
> -        create_table_entry boot_second, xen_fixmap, r0, SECOND_SHIFT, mmu=1
> +        create_table_entry boot_second, xen_fixmap, r0, 2, mmu=1
>           /* Ensure any page table updates made above have occurred. */
>           dsb   nshst
>   

Reviewed-by: Wei Chen <Wei.Chen@arm.com>
Bertrand Marquis Aug. 15, 2022, 2:56 p.m. UTC | #2
Hi Julien,

> On 12 Aug 2022, at 20:24, Julien Grall <julien@xen.org> wrote:
> 
> From: Julien Grall <jgrall@amazon.com>
> 
> There are a few places in the code that need to find the slot at a
> given page-table level.
> 
> So create a new macro get_table_slot() for that. This will reduce
> the effort to figure out whether the code is doing the right thing.
> 
> The new macro is using 'ubfx' (or 'lsr' for the first level) rather
> than the existing sequence (mov_w, lsr, and) because it doesn't require
> a scratch register and reduce the number of instructions (4 -> 1).
> 
> Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>

Also I passed our test suite on arm32 qemu so:
Tested-by: Bertrand Marquis <bertrand.marquis@arm.com>

Cheers
Bertrand


> ---
> xen/arch/arm/arm32/head.S | 56 ++++++++++++++++++++++-----------------
> 1 file changed, 32 insertions(+), 24 deletions(-)
> 
> diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
> index 46d93bebbabe..50f6fa4eb38d 100644
> --- a/xen/arch/arm/arm32/head.S
> +++ b/xen/arch/arm/arm32/head.S
> @@ -358,13 +358,31 @@ cpu_init_done:
>         mov   pc, r5                        /* Return address is in r5 */
> ENDPROC(cpu_init)
> 
> +/*
> + * Macro to find the slot number at a given page-table level
> + *
> + * slot:     slot computed
> + * virt:     virtual address
> + * lvl:      page-table level
> + *
> + * Note that ubxf is unpredictable when the end bit is above 32-bit. So we
> + * can't use it for first level offset.
> + */
> +.macro get_table_slot, slot, virt, lvl
> +    .if \lvl == 1
> +        lsr   \slot, \virt, #XEN_PT_LEVEL_SHIFT(\lvl)
> +    .else
> +        ubfx  \slot, \virt, #XEN_PT_LEVEL_SHIFT(\lvl), #XEN_PT_LPAE_SHIFT
> +    .endif
> +.endm
> +
> /*
>  * Macro to create a page table entry in \ptbl to \tbl
>  *
>  * ptbl:    table symbol where the entry will be created
>  * tbl:     table symbol to point to
>  * virt:    virtual address
> - * shift:   #imm page table shift
> + * lvl:     page-table level
>  * mmu:     Is the MMU turned on/off. If not specified it will be off
>  *
>  * Preserves \virt
> @@ -374,11 +392,9 @@ ENDPROC(cpu_init)
>  *
>  * Note that \virt should be in a register other than r1 - r4
>  */
> -.macro create_table_entry, ptbl, tbl, virt, shift, mmu=0
> -        lsr   r1, \virt, #\shift
> -        mov_w r2, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r2             /* r1 := slot in \tlb */
> -        lsl   r1, r1, #3             /* r1 := slot offset in \tlb */
> +.macro create_table_entry, ptbl, tbl, virt, lvl, mmu=0
> +        get_table_slot r1, \virt, \lvl  /* r1 := slot in \tlb */
> +        lsl   r1, r1, #3                /* r1 := slot offset in \tlb */
> 
>         load_paddr r4, \tbl
> 
> @@ -448,8 +464,8 @@ ENDPROC(cpu_init)
> create_page_tables:
>         /* Prepare the page-tables for mapping Xen */
>         ldr   r0, =XEN_VIRT_START
> -        create_table_entry boot_pgtable, boot_second, r0, FIRST_SHIFT
> -        create_table_entry boot_second, boot_third, r0, SECOND_SHIFT
> +        create_table_entry boot_pgtable, boot_second, r0, 1
> +        create_table_entry boot_second, boot_third, r0, 2
> 
>         /* Setup boot_third: */
>         adr_l r4, boot_third, mmu=0
> @@ -486,12 +502,10 @@ create_page_tables:
>          * then the 1:1 mapping will use its own set of page-tables from
>          * the second level.
>          */
> -        lsr   r1, r9, #FIRST_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0              /* r1 := first slot */
> +        get_table_slot r1, r9, 1     /* r1 := first slot */
>         cmp   r1, #XEN_FIRST_SLOT
>         beq   1f
> -        create_table_entry boot_pgtable, boot_second_id, r9, FIRST_SHIFT
> +        create_table_entry boot_pgtable, boot_second_id, r9, 1
>         b     link_from_second_id
> 
> 1:
> @@ -501,16 +515,14 @@ create_page_tables:
>          * third level. For slot XEN_SECOND_SLOT, Xen is not yet able to handle
>          * it.
>          */
> -        lsr   r1, r9, #SECOND_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0             /* r1 := second slot */
> +        get_table_slot r1, r9, 2     /* r1 := second slot */
>         cmp   r1, #XEN_SECOND_SLOT
>         beq   virtphys_clash
> -        create_table_entry boot_second, boot_third_id, r9, SECOND_SHIFT
> +        create_table_entry boot_second, boot_third_id, r9, 2
>         b     link_from_third_id
> 
> link_from_second_id:
> -        create_table_entry boot_second_id, boot_third_id, r9, SECOND_SHIFT
> +        create_table_entry boot_second_id, boot_third_id, r9, 2
> link_from_third_id:
>         create_mapping_entry boot_third_id, r9, r9
>         mov   pc, lr
> @@ -571,9 +583,7 @@ remove_identity_mapping:
>          * Find the first slot used. Remove the entry for the first
>          * table if the slot is not XEN_FIRST_SLOT.
>          */
> -        lsr   r1, r9, #FIRST_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0              /* r1 := first slot */
> +        get_table_slot r1, r9, 1     /* r1 := first slot */
>         cmp   r1, #XEN_FIRST_SLOT
>         beq   1f
>         /* It is not in slot 0, remove the entry */
> @@ -587,9 +597,7 @@ remove_identity_mapping:
>          * Find the second slot used. Remove the entry for the first
>          * table if the slot is not XEN_SECOND_SLOT.
>          */
> -        lsr   r1, r9, #SECOND_SHIFT
> -        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
> -        and   r1, r1, r0             /* r1 := second slot */
> +        get_table_slot r1, r9, 2     /* r1 := second slot */
>         cmp   r1, #XEN_SECOND_SLOT
>         beq   identity_mapping_removed
>         /* It is not in slot 1, remove the entry */
> @@ -628,7 +636,7 @@ setup_fixmap:
> #endif
>         /* Map fixmap into boot_second */
>         mov_w r0, FIXMAP_ADDR(0)
> -        create_table_entry boot_second, xen_fixmap, r0, SECOND_SHIFT, mmu=1
> +        create_table_entry boot_second, xen_fixmap, r0, 2, mmu=1
>         /* Ensure any page table updates made above have occurred. */
>         dsb   nshst
> 
> -- 
> 2.37.1
>
diff mbox series

Patch

diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 46d93bebbabe..50f6fa4eb38d 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -358,13 +358,31 @@  cpu_init_done:
         mov   pc, r5                        /* Return address is in r5 */
 ENDPROC(cpu_init)
 
+/*
+ * Macro to find the slot number at a given page-table level
+ *
+ * slot:     slot computed
+ * virt:     virtual address
+ * lvl:      page-table level
+ *
+ * Note that ubxf is unpredictable when the end bit is above 32-bit. So we
+ * can't use it for first level offset.
+ */
+.macro get_table_slot, slot, virt, lvl
+    .if \lvl == 1
+        lsr   \slot, \virt, #XEN_PT_LEVEL_SHIFT(\lvl)
+    .else
+        ubfx  \slot, \virt, #XEN_PT_LEVEL_SHIFT(\lvl), #XEN_PT_LPAE_SHIFT
+    .endif
+.endm
+
 /*
  * Macro to create a page table entry in \ptbl to \tbl
  *
  * ptbl:    table symbol where the entry will be created
  * tbl:     table symbol to point to
  * virt:    virtual address
- * shift:   #imm page table shift
+ * lvl:     page-table level
  * mmu:     Is the MMU turned on/off. If not specified it will be off
  *
  * Preserves \virt
@@ -374,11 +392,9 @@  ENDPROC(cpu_init)
  *
  * Note that \virt should be in a register other than r1 - r4
  */
-.macro create_table_entry, ptbl, tbl, virt, shift, mmu=0
-        lsr   r1, \virt, #\shift
-        mov_w r2, XEN_PT_LPAE_ENTRY_MASK
-        and   r1, r1, r2             /* r1 := slot in \tlb */
-        lsl   r1, r1, #3             /* r1 := slot offset in \tlb */
+.macro create_table_entry, ptbl, tbl, virt, lvl, mmu=0
+        get_table_slot r1, \virt, \lvl  /* r1 := slot in \tlb */
+        lsl   r1, r1, #3                /* r1 := slot offset in \tlb */
 
         load_paddr r4, \tbl
 
@@ -448,8 +464,8 @@  ENDPROC(cpu_init)
 create_page_tables:
         /* Prepare the page-tables for mapping Xen */
         ldr   r0, =XEN_VIRT_START
-        create_table_entry boot_pgtable, boot_second, r0, FIRST_SHIFT
-        create_table_entry boot_second, boot_third, r0, SECOND_SHIFT
+        create_table_entry boot_pgtable, boot_second, r0, 1
+        create_table_entry boot_second, boot_third, r0, 2
 
         /* Setup boot_third: */
         adr_l r4, boot_third, mmu=0
@@ -486,12 +502,10 @@  create_page_tables:
          * then the 1:1 mapping will use its own set of page-tables from
          * the second level.
          */
-        lsr   r1, r9, #FIRST_SHIFT
-        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
-        and   r1, r1, r0              /* r1 := first slot */
+        get_table_slot r1, r9, 1     /* r1 := first slot */
         cmp   r1, #XEN_FIRST_SLOT
         beq   1f
-        create_table_entry boot_pgtable, boot_second_id, r9, FIRST_SHIFT
+        create_table_entry boot_pgtable, boot_second_id, r9, 1
         b     link_from_second_id
 
 1:
@@ -501,16 +515,14 @@  create_page_tables:
          * third level. For slot XEN_SECOND_SLOT, Xen is not yet able to handle
          * it.
          */
-        lsr   r1, r9, #SECOND_SHIFT
-        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
-        and   r1, r1, r0             /* r1 := second slot */
+        get_table_slot r1, r9, 2     /* r1 := second slot */
         cmp   r1, #XEN_SECOND_SLOT
         beq   virtphys_clash
-        create_table_entry boot_second, boot_third_id, r9, SECOND_SHIFT
+        create_table_entry boot_second, boot_third_id, r9, 2
         b     link_from_third_id
 
 link_from_second_id:
-        create_table_entry boot_second_id, boot_third_id, r9, SECOND_SHIFT
+        create_table_entry boot_second_id, boot_third_id, r9, 2
 link_from_third_id:
         create_mapping_entry boot_third_id, r9, r9
         mov   pc, lr
@@ -571,9 +583,7 @@  remove_identity_mapping:
          * Find the first slot used. Remove the entry for the first
          * table if the slot is not XEN_FIRST_SLOT.
          */
-        lsr   r1, r9, #FIRST_SHIFT
-        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
-        and   r1, r1, r0              /* r1 := first slot */
+        get_table_slot r1, r9, 1     /* r1 := first slot */
         cmp   r1, #XEN_FIRST_SLOT
         beq   1f
         /* It is not in slot 0, remove the entry */
@@ -587,9 +597,7 @@  remove_identity_mapping:
          * Find the second slot used. Remove the entry for the first
          * table if the slot is not XEN_SECOND_SLOT.
          */
-        lsr   r1, r9, #SECOND_SHIFT
-        mov_w r0, XEN_PT_LPAE_ENTRY_MASK
-        and   r1, r1, r0             /* r1 := second slot */
+        get_table_slot r1, r9, 2     /* r1 := second slot */
         cmp   r1, #XEN_SECOND_SLOT
         beq   identity_mapping_removed
         /* It is not in slot 1, remove the entry */
@@ -628,7 +636,7 @@  setup_fixmap:
 #endif
         /* Map fixmap into boot_second */
         mov_w r0, FIXMAP_ADDR(0)
-        create_table_entry boot_second, xen_fixmap, r0, SECOND_SHIFT, mmu=1
+        create_table_entry boot_second, xen_fixmap, r0, 2, mmu=1
         /* Ensure any page table updates made above have occurred. */
         dsb   nshst