[PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures

Ayan Kumar Halder posted 3 patches 6 months, 1 week ago
There is a newer version of this series
[PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Ayan Kumar Halder 6 months, 1 week ago
Modify Arm32 assembly boot code to reset any unused MPU region, initialise
'max_mpu_regions' with the number of supported MPU regions and set/clear the
bitmap 'xen_mpumap_mask' used to track the enabled regions.

Use the macro definition for "dcache_line_size" from linux.

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

1. Introduce cache.S to hold arm32 cache initialization instructions.

2. Use dcache_line_size macro definition from linux.

3. Use mov_w instead of ldr.

4. Use a single stm instruction for 'store_pair' macro definition.

 xen/arch/arm/arm32/Makefile              |  1 +
 xen/arch/arm/arm32/asm-offsets.c         |  6 ++++
 xen/arch/arm/arm32/cache.S               | 41 ++++++++++++++++++++++++
 xen/arch/arm/arm32/mpu/head.S            | 25 +++++++++++++++
 xen/arch/arm/include/asm/mpu/regions.inc |  2 +-
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 xen/arch/arm/arm32/cache.S

diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
index 537969d753..531168f58a 100644
--- a/xen/arch/arm/arm32/Makefile
+++ b/xen/arch/arm/arm32/Makefile
@@ -2,6 +2,7 @@ obj-y += lib/
 obj-$(CONFIG_MMU) += mmu/
 obj-$(CONFIG_MPU) += mpu/
 
+obj-y += cache.o
 obj-$(CONFIG_EARLY_PRINTK) += debug.o
 obj-y += domctl.o
 obj-y += domain.o
diff --git a/xen/arch/arm/arm32/asm-offsets.c b/xen/arch/arm/arm32/asm-offsets.c
index 8bbb0f938e..c203ce269d 100644
--- a/xen/arch/arm/arm32/asm-offsets.c
+++ b/xen/arch/arm/arm32/asm-offsets.c
@@ -75,6 +75,12 @@ void __dummy__(void)
 
    OFFSET(INITINFO_stack, struct init_info, stack);
    BLANK();
+
+#ifdef CONFIG_MPU
+   DEFINE(XEN_MPUMAP_MASK_sizeof, sizeof(xen_mpumap_mask));
+   DEFINE(XEN_MPUMAP_sizeof, sizeof(xen_mpumap));
+   BLANK();
+#endif
 }
 
 /*
diff --git a/xen/arch/arm/arm32/cache.S b/xen/arch/arm/arm32/cache.S
new file mode 100644
index 0000000000..00ea390ce4
--- /dev/null
+++ b/xen/arch/arm/arm32/cache.S
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Cache maintenance */
+
+#include <asm/arm32/sysregs.h>
+
+/* dcache_line_size - get the minimum D-cache line size from the CTR register */
+    .macro  dcache_line_size, reg, tmp
+    mrc p15, 0, \tmp, c0, c0, 1     /* read ctr */
+    lsr \tmp, \tmp, #16
+    and \tmp, \tmp, #0xf            /* cache line size encoding */
+    mov \reg, #4                    /* bytes per word */
+    mov \reg, \reg, lsl \tmp        /* actual cache line size */
+    .endm
+
+/*
+ * __invalidate_dcache_area(addr, size)
+ *
+ * Ensure that the data held in the cache for the buffer is invalidated.
+ *
+ * - addr - start address of the buffer
+ * - size - size of the buffer
+ */
+FUNC(__invalidate_dcache_area)
+    dcache_line_size r2, r3
+    add   r1, r0, r1
+    sub   r3, r2, #1
+    bic   r0, r0, r3
+1:  mcr   CP32(r0, DCIMVAC)     /* invalidate D line / unified line */
+    add   r0, r0, r2
+    cmp   r0, r1
+    blo   1b
+    dsb   sy
+    ret
+END(__invalidate_dcache_area)
+
+/*
+ * Local variables:
+ * mode: ASM
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/arm32/mpu/head.S b/xen/arch/arm/arm32/mpu/head.S
index b2c5245e51..435b140d09 100644
--- a/xen/arch/arm/arm32/mpu/head.S
+++ b/xen/arch/arm/arm32/mpu/head.S
@@ -49,6 +49,10 @@ FUNC(enable_boot_cpu_mm)
     mrc   CP32(r5, MPUIR_EL2)
     and   r5, r5, #NUM_MPU_REGIONS_MASK
 
+    mov_w   r0, max_mpu_regions
+    str   r5, [r0]
+    mcr   CP32(r0, DCIMVAC) /* Invalidate cache for max_mpu_regions addr */
+
     /* x0: region sel */
     mov   r0, #0
     /* Xen text section. */
@@ -83,6 +87,27 @@ FUNC(enable_boot_cpu_mm)
     prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR
 #endif
 
+zero_mpu:
+    /* Reset remaining MPU regions */
+    cmp   r0, r5
+    beq   out_zero_mpu
+    mov   r1, #0
+    mov   r2, #1
+    prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prlar=REGION_DISABLED_PRLAR
+    b     zero_mpu
+
+out_zero_mpu:
+    /* Invalidate data cache for MPU data structures */
+    mov r4, lr
+    mov_w r0, xen_mpumap_mask
+    mov r1, #XEN_MPUMAP_MASK_sizeof
+    bl __invalidate_dcache_area
+
+    ldr r0, =xen_mpumap
+    mov r1, #XEN_MPUMAP_sizeof
+    bl __invalidate_dcache_area
+    mov lr, r4
+
     b    enable_mpu
 END(enable_boot_cpu_mm)
 
diff --git a/xen/arch/arm/include/asm/mpu/regions.inc b/xen/arch/arm/include/asm/mpu/regions.inc
index 6b8c233e6c..631b0b2b86 100644
--- a/xen/arch/arm/include/asm/mpu/regions.inc
+++ b/xen/arch/arm/include/asm/mpu/regions.inc
@@ -24,7 +24,7 @@
 #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
 
 .macro store_pair reg1, reg2, dst
-    .word 0xe7f000f0                    /* unimplemented */
+    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register than reg1 */
 .endm
 
 #endif
-- 
2.25.1
Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Orzel, Michal 6 months, 1 week ago

On 06/06/2025 18:48, Ayan Kumar Halder wrote:
> Modify Arm32 assembly boot code to reset any unused MPU region, initialise
> 'max_mpu_regions' with the number of supported MPU regions and set/clear the
> bitmap 'xen_mpumap_mask' used to track the enabled regions.
> 
> Use the macro definition for "dcache_line_size" from linux.
> 
> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
> ---
> Changes from v1 :-
> 
> 1. Introduce cache.S to hold arm32 cache initialization instructions.
> 
> 2. Use dcache_line_size macro definition from linux.
> 
> 3. Use mov_w instead of ldr.
> 
> 4. Use a single stm instruction for 'store_pair' macro definition.
> 
>  xen/arch/arm/arm32/Makefile              |  1 +
>  xen/arch/arm/arm32/asm-offsets.c         |  6 ++++
>  xen/arch/arm/arm32/cache.S               | 41 ++++++++++++++++++++++++
>  xen/arch/arm/arm32/mpu/head.S            | 25 +++++++++++++++
>  xen/arch/arm/include/asm/mpu/regions.inc |  2 +-
>  5 files changed, 74 insertions(+), 1 deletion(-)
>  create mode 100644 xen/arch/arm/arm32/cache.S
> 
> diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
> index 537969d753..531168f58a 100644
> --- a/xen/arch/arm/arm32/Makefile
> +++ b/xen/arch/arm/arm32/Makefile
> @@ -2,6 +2,7 @@ obj-y += lib/
>  obj-$(CONFIG_MMU) += mmu/
>  obj-$(CONFIG_MPU) += mpu/
>  
> +obj-y += cache.o
>  obj-$(CONFIG_EARLY_PRINTK) += debug.o
>  obj-y += domctl.o
>  obj-y += domain.o
> diff --git a/xen/arch/arm/arm32/asm-offsets.c b/xen/arch/arm/arm32/asm-offsets.c
> index 8bbb0f938e..c203ce269d 100644
> --- a/xen/arch/arm/arm32/asm-offsets.c
> +++ b/xen/arch/arm/arm32/asm-offsets.c
> @@ -75,6 +75,12 @@ void __dummy__(void)
>  
>     OFFSET(INITINFO_stack, struct init_info, stack);
>     BLANK();
> +
> +#ifdef CONFIG_MPU
> +   DEFINE(XEN_MPUMAP_MASK_sizeof, sizeof(xen_mpumap_mask));
> +   DEFINE(XEN_MPUMAP_sizeof, sizeof(xen_mpumap));
> +   BLANK();
> +#endif
>  }
>  
>  /*
> diff --git a/xen/arch/arm/arm32/cache.S b/xen/arch/arm/arm32/cache.S
> new file mode 100644
> index 0000000000..00ea390ce4
> --- /dev/null
> +++ b/xen/arch/arm/arm32/cache.S
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Cache maintenance */
> +
> +#include <asm/arm32/sysregs.h>
> +
> +/* dcache_line_size - get the minimum D-cache line size from the CTR register */
> +    .macro  dcache_line_size, reg, tmp
> +    mrc p15, 0, \tmp, c0, c0, 1     /* read ctr */
Why open coding macro CTR? Especially if below you use DCIMVAC.

> +    lsr \tmp, \tmp, #16
> +    and \tmp, \tmp, #0xf            /* cache line size encoding */
> +    mov \reg, #4                    /* bytes per word */
> +    mov \reg, \reg, lsl \tmp        /* actual cache line size */
> +    .endm
> +
> +/*
> + * __invalidate_dcache_area(addr, size)
> + *
> + * Ensure that the data held in the cache for the buffer is invalidated.
> + *
> + * - addr - start address of the buffer
> + * - size - size of the buffer
> + */
I do think that for new functions in assembly we should write what registers are
clobbered. Arm64 cache.S originated from Linux, hence it lacks this information.

> +FUNC(__invalidate_dcache_area)
> +    dcache_line_size r2, r3
> +    add   r1, r0, r1
> +    sub   r3, r2, #1
> +    bic   r0, r0, r3
> +1:  mcr   CP32(r0, DCIMVAC)     /* invalidate D line / unified line */
> +    add   r0, r0, r2
> +    cmp   r0, r1
> +    blo   1b
> +    dsb   sy
> +    ret
> +END(__invalidate_dcache_area)
> +
> +/*
> + * Local variables:
> + * mode: ASM
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/arm/arm32/mpu/head.S b/xen/arch/arm/arm32/mpu/head.S
> index b2c5245e51..435b140d09 100644
> --- a/xen/arch/arm/arm32/mpu/head.S
> +++ b/xen/arch/arm/arm32/mpu/head.S
> @@ -49,6 +49,10 @@ FUNC(enable_boot_cpu_mm)
>      mrc   CP32(r5, MPUIR_EL2)
>      and   r5, r5, #NUM_MPU_REGIONS_MASK
>  
> +    mov_w   r0, max_mpu_regions
> +    str   r5, [r0]
> +    mcr   CP32(r0, DCIMVAC) /* Invalidate cache for max_mpu_regions addr */
> +
>      /* x0: region sel */
>      mov   r0, #0
>      /* Xen text section. */
> @@ -83,6 +87,27 @@ FUNC(enable_boot_cpu_mm)
>      prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR
>  #endif
>  
> +zero_mpu:
> +    /* Reset remaining MPU regions */
> +    cmp   r0, r5
> +    beq   out_zero_mpu
> +    mov   r1, #0
> +    mov   r2, #1
> +    prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prlar=REGION_DISABLED_PRLAR
> +    b     zero_mpu
> +
> +out_zero_mpu:
> +    /* Invalidate data cache for MPU data structures */
> +    mov r4, lr
> +    mov_w r0, xen_mpumap_mask
> +    mov r1, #XEN_MPUMAP_MASK_sizeof
> +    bl __invalidate_dcache_area
> +
> +    ldr r0, =xen_mpumap
> +    mov r1, #XEN_MPUMAP_sizeof
> +    bl __invalidate_dcache_area
> +    mov lr, r4
> +
>      b    enable_mpu
>  END(enable_boot_cpu_mm)
>  
> diff --git a/xen/arch/arm/include/asm/mpu/regions.inc b/xen/arch/arm/include/asm/mpu/regions.inc
> index 6b8c233e6c..631b0b2b86 100644
> --- a/xen/arch/arm/include/asm/mpu/regions.inc
> +++ b/xen/arch/arm/include/asm/mpu/regions.inc
> @@ -24,7 +24,7 @@
>  #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
>  
>  .macro store_pair reg1, reg2, dst
> -    .word 0xe7f000f0                    /* unimplemented */
> +    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register than reg1 */
Didn't we agree not to use STM (I suggested it but then Julien pointed out that
it's use in macro might not be the best)?

~Michal
Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Ayan Kumar Halder 6 months, 1 week ago
Hi Michal,

On 09/06/2025 08:41, Orzel, Michal wrote:
>
> On 06/06/2025 18:48, Ayan Kumar Halder wrote:
>> Modify Arm32 assembly boot code to reset any unused MPU region, initialise
>> 'max_mpu_regions' with the number of supported MPU regions and set/clear the
>> bitmap 'xen_mpumap_mask' used to track the enabled regions.
>>
>> Use the macro definition for "dcache_line_size" from linux.
>>
>> Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
>> ---
>> Changes from v1 :-
>>
>> 1. Introduce cache.S to hold arm32 cache initialization instructions.
>>
>> 2. Use dcache_line_size macro definition from linux.
>>
>> 3. Use mov_w instead of ldr.
>>
>> 4. Use a single stm instruction for 'store_pair' macro definition.
>>
>>   xen/arch/arm/arm32/Makefile              |  1 +
>>   xen/arch/arm/arm32/asm-offsets.c         |  6 ++++
>>   xen/arch/arm/arm32/cache.S               | 41 ++++++++++++++++++++++++
>>   xen/arch/arm/arm32/mpu/head.S            | 25 +++++++++++++++
>>   xen/arch/arm/include/asm/mpu/regions.inc |  2 +-
>>   5 files changed, 74 insertions(+), 1 deletion(-)
>>   create mode 100644 xen/arch/arm/arm32/cache.S
>>
>> diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
>> index 537969d753..531168f58a 100644
>> --- a/xen/arch/arm/arm32/Makefile
>> +++ b/xen/arch/arm/arm32/Makefile
>> @@ -2,6 +2,7 @@ obj-y += lib/
>>   obj-$(CONFIG_MMU) += mmu/
>>   obj-$(CONFIG_MPU) += mpu/
>>   
>> +obj-y += cache.o
>>   obj-$(CONFIG_EARLY_PRINTK) += debug.o
>>   obj-y += domctl.o
>>   obj-y += domain.o
>> diff --git a/xen/arch/arm/arm32/asm-offsets.c b/xen/arch/arm/arm32/asm-offsets.c
>> index 8bbb0f938e..c203ce269d 100644
>> --- a/xen/arch/arm/arm32/asm-offsets.c
>> +++ b/xen/arch/arm/arm32/asm-offsets.c
>> @@ -75,6 +75,12 @@ void __dummy__(void)
>>   
>>      OFFSET(INITINFO_stack, struct init_info, stack);
>>      BLANK();
>> +
>> +#ifdef CONFIG_MPU
>> +   DEFINE(XEN_MPUMAP_MASK_sizeof, sizeof(xen_mpumap_mask));
>> +   DEFINE(XEN_MPUMAP_sizeof, sizeof(xen_mpumap));
>> +   BLANK();
>> +#endif
>>   }
>>   
>>   /*
>> diff --git a/xen/arch/arm/arm32/cache.S b/xen/arch/arm/arm32/cache.S
>> new file mode 100644
>> index 0000000000..00ea390ce4
>> --- /dev/null
>> +++ b/xen/arch/arm/arm32/cache.S
>> @@ -0,0 +1,41 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/* Cache maintenance */
>> +
>> +#include <asm/arm32/sysregs.h>
>> +
>> +/* dcache_line_size - get the minimum D-cache line size from the CTR register */
>> +    .macro  dcache_line_size, reg, tmp
>> +    mrc p15, 0, \tmp, c0, c0, 1     /* read ctr */
> Why open coding macro CTR? Especially if below you use DCIMVAC.
>
>> +    lsr \tmp, \tmp, #16
>> +    and \tmp, \tmp, #0xf            /* cache line size encoding */
>> +    mov \reg, #4                    /* bytes per word */
>> +    mov \reg, \reg, lsl \tmp        /* actual cache line size */
>> +    .endm
>> +
>> +/*
>> + * __invalidate_dcache_area(addr, size)
>> + *
>> + * Ensure that the data held in the cache for the buffer is invalidated.
>> + *
>> + * - addr - start address of the buffer
>> + * - size - size of the buffer
>> + */
> I do think that for new functions in assembly we should write what registers are
> clobbered. Arm64 cache.S originated from Linux, hence it lacks this information.
>
>> +FUNC(__invalidate_dcache_area)
>> +    dcache_line_size r2, r3
>> +    add   r1, r0, r1
>> +    sub   r3, r2, #1
>> +    bic   r0, r0, r3
>> +1:  mcr   CP32(r0, DCIMVAC)     /* invalidate D line / unified line */
>> +    add   r0, r0, r2
>> +    cmp   r0, r1
>> +    blo   1b
>> +    dsb   sy
>> +    ret
>> +END(__invalidate_dcache_area)
>> +
>> +/*
>> + * Local variables:
>> + * mode: ASM
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/arch/arm/arm32/mpu/head.S b/xen/arch/arm/arm32/mpu/head.S
>> index b2c5245e51..435b140d09 100644
>> --- a/xen/arch/arm/arm32/mpu/head.S
>> +++ b/xen/arch/arm/arm32/mpu/head.S
>> @@ -49,6 +49,10 @@ FUNC(enable_boot_cpu_mm)
>>       mrc   CP32(r5, MPUIR_EL2)
>>       and   r5, r5, #NUM_MPU_REGIONS_MASK
>>   
>> +    mov_w   r0, max_mpu_regions
>> +    str   r5, [r0]
>> +    mcr   CP32(r0, DCIMVAC) /* Invalidate cache for max_mpu_regions addr */
>> +
>>       /* x0: region sel */
>>       mov   r0, #0
>>       /* Xen text section. */
>> @@ -83,6 +87,27 @@ FUNC(enable_boot_cpu_mm)
>>       prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR
>>   #endif
>>   
>> +zero_mpu:
>> +    /* Reset remaining MPU regions */
>> +    cmp   r0, r5
>> +    beq   out_zero_mpu
>> +    mov   r1, #0
>> +    mov   r2, #1
>> +    prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prlar=REGION_DISABLED_PRLAR
>> +    b     zero_mpu
>> +
>> +out_zero_mpu:
>> +    /* Invalidate data cache for MPU data structures */
>> +    mov r4, lr
>> +    mov_w r0, xen_mpumap_mask
>> +    mov r1, #XEN_MPUMAP_MASK_sizeof
>> +    bl __invalidate_dcache_area
>> +
>> +    ldr r0, =xen_mpumap
>> +    mov r1, #XEN_MPUMAP_sizeof
>> +    bl __invalidate_dcache_area
>> +    mov lr, r4
>> +
>>       b    enable_mpu
>>   END(enable_boot_cpu_mm)
>>   
>> diff --git a/xen/arch/arm/include/asm/mpu/regions.inc b/xen/arch/arm/include/asm/mpu/regions.inc
>> index 6b8c233e6c..631b0b2b86 100644
>> --- a/xen/arch/arm/include/asm/mpu/regions.inc
>> +++ b/xen/arch/arm/include/asm/mpu/regions.inc
>> @@ -24,7 +24,7 @@
>>   #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
>>   
>>   .macro store_pair reg1, reg2, dst
>> -    .word 0xe7f000f0                    /* unimplemented */
>> +    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register than reg1 */
> Didn't we agree not to use STM (I suggested it but then Julien pointed out that
> it's use in macro might not be the best)?

Ah my last response was not sent.

I realized that I cannot use strd due to the following error

Error: first transfer register must be even -- `strd r3,r4,[r1]'

So,  I am using stm with the following comment

stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register than reg1 */

- Ayan

>
> ~Michal
>

Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Julien Grall 6 months, 1 week ago
Hi Ayan,

On 09/06/2025 09:27, Ayan Kumar Halder wrote:
> On 09/06/2025 08:41, Orzel, Michal wrote:
>>> diff --git a/xen/arch/arm/include/asm/mpu/regions.inc b/xen/arch/arm/ 
>>> include/asm/mpu/regions.inc
>>> index 6b8c233e6c..631b0b2b86 100644
>>> --- a/xen/arch/arm/include/asm/mpu/regions.inc
>>> +++ b/xen/arch/arm/include/asm/mpu/regions.inc
>>> @@ -24,7 +24,7 @@
>>>   #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
>>>   .macro store_pair reg1, reg2, dst
>>> -    .word 0xe7f000f0                    /* unimplemented */
>>> +    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register 
>>> than reg1 */
>> Didn't we agree not to use STM (I suggested it but then Julien pointed 
>> out that
>> it's use in macro might not be the best)?
> 
> Ah my last response was not sent.
> 
> I realized that I cannot use strd due to the following error
> 
> Error: first transfer register must be even -- `strd r3,r4,[r1]'

Ah I missed the "even" part when reading the specification. However, we 
control the set of registers, so we can't we follow the restriction? 
This would be better...

> 
> So,  I am using stm with the following comment

... than a comment and hoping the developper/reviewer will notice it 
(the code is also misplaced). I am ready to bet this will likely cause 
some problem in the future.

Cheers,

-- 
Julien Grall


Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Ayan Kumar Halder 6 months, 1 week ago
On 09/06/2025 09:42, Julien Grall wrote:
> Hi Ayan,
Hi Julien,
>
> On 09/06/2025 09:27, Ayan Kumar Halder wrote:
>> On 09/06/2025 08:41, Orzel, Michal wrote:
>>>> diff --git a/xen/arch/arm/include/asm/mpu/regions.inc 
>>>> b/xen/arch/arm/ include/asm/mpu/regions.inc
>>>> index 6b8c233e6c..631b0b2b86 100644
>>>> --- a/xen/arch/arm/include/asm/mpu/regions.inc
>>>> +++ b/xen/arch/arm/include/asm/mpu/regions.inc
>>>> @@ -24,7 +24,7 @@
>>>>   #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
>>>>   .macro store_pair reg1, reg2, dst
>>>> -    .word 0xe7f000f0                    /* unimplemented */
>>>> +    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register 
>>>> than reg1 */
>>> Didn't we agree not to use STM (I suggested it but then Julien 
>>> pointed out that
>>> it's use in macro might not be the best)?
>>
>> Ah my last response was not sent.
>>
>> I realized that I cannot use strd due to the following error
>>
>> Error: first transfer register must be even -- `strd r3,r4,[r1]'
>
> Ah I missed the "even" part when reading the specification. However, 
> we control the set of registers, so we can't we follow the 
> restriction? This would be better...

I am ok to follow this. I just want to make sure that this looks ok to you

prepare_xen_region() invokes store_pair(). They are in common header.

So we need to make the change wherever prepare_xen_region() is invoked 
from arm32/mpu/head.S. This would look like

--- a/xen/arch/arm/arm32/mpu/head.S
+++ b/xen/arch/arm/arm32/mpu/head.S
@@ -58,33 +58,33 @@ FUNC(enable_boot_cpu_mm)
      /* Xen text section. */
      mov_w   r1, _stext
      mov_w   r2, _etext
-    prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_TEXT_PRBAR
+    prepare_xen_region r0, r1, r2, r4, r3, r5, attr_prbar=REGION_TEXT_PRBAR

      /* Xen read-only data section. */
      mov_w   r1, _srodata
      mov_w   r2, _erodata
-    prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_RO_PRBAR
+    prepare_xen_region r0, r1, r2, r4, r3, r5, attr_prbar=REGION_RO_PRBAR

      /* Xen read-only after init and data section. (RW data) */
      mov_w   r1, __ro_after_init_start
      mov_w   r2, __init_begin
-    prepare_xen_region r0, r1, r2, r3, r4, r5
+    prepare_xen_region r0, r1, r2, r4, r3, r5

      /* Xen code section. */
      mov_w   r1, __init_begin
      mov_w   r2, __init_data_begin
-    prepare_xen_region r0, r1, r2, r3, r4, r5, attr_prbar=REGION_TEXT_PRBAR
+    prepare_xen_region r0, r1, r2, r4, r3, r5, attr_prbar=REGION_TEXT_PRBAR

      /* Xen data and BSS section. */
      mov_w   r1, __init_data_begin
      mov_w   r2, __bss_end
-    prepare_xen_region r0, r1, r2, r3, r4, r5
+    prepare_xen_region r0, r1, r2, r4, r3, r5

  #ifdef CONFIG_EARLY_PRINTK
      /* Xen early UART section. */
      mov_w   r1, CONFIG_EARLY_UART_BASE_ADDRESS
      mov_w   r2, (CONFIG_EARLY_UART_BASE_ADDRESS + CONFIG_EARLY_UART_SIZE)
-    prepare_xen_region r0, r1, r2, r3, r4, r5, 
attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR
+    prepare_xen_region r0, r1, r2, r4, r3, r5, 
attr_prbar=REGION_DEVICE_PRBAR, attr_prlar=REGION_DEVICE_PRLAR
  #endif

  zero_mpu:
@@ -93,7 +93,7 @@ zero_mpu:
      beq   out_zero_mpu
      mov   r1, #0
      mov   r2, #1
-    prepare_xen_region r0, r1, r2, r3, r4, r5, 
attr_prlar=REGION_DISABLED_PRLAR
+    prepare_xen_region r0, r1, r2, r4, r3, r5, 
attr_prlar=REGION_DISABLED_PRLAR

So this would look a different different from its arm64 counterpart.

Are you ok with this change ?

- Ayan

>
>>
>> So,  I am using stm with the following comment
>
> ... than a comment and hoping the developper/reviewer will notice it 
> (the code is also misplaced). I am ready to bet this will likely cause 
> some problem in the future.
>
> Cheers,
>

Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Ayan Kumar Halder 6 months, 1 week ago
Hi,

On 09/06/2025 10:16, Ayan Kumar Halder wrote:
>
> On 09/06/2025 09:42, Julien Grall wrote:
>> Hi Ayan,
> Hi Julien,
>>
>> On 09/06/2025 09:27, Ayan Kumar Halder wrote:
>>> On 09/06/2025 08:41, Orzel, Michal wrote:
>>>>> diff --git a/xen/arch/arm/include/asm/mpu/regions.inc 
>>>>> b/xen/arch/arm/ include/asm/mpu/regions.inc
>>>>> index 6b8c233e6c..631b0b2b86 100644
>>>>> --- a/xen/arch/arm/include/asm/mpu/regions.inc
>>>>> +++ b/xen/arch/arm/include/asm/mpu/regions.inc
>>>>> @@ -24,7 +24,7 @@
>>>>>   #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
>>>>>   .macro store_pair reg1, reg2, dst
>>>>> -    .word 0xe7f000f0                    /* unimplemented */
>>>>> +    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register 
>>>>> than reg1 */
>>>> Didn't we agree not to use STM (I suggested it but then Julien 
>>>> pointed out that
>>>> it's use in macro might not be the best)?
>>>
>>> Ah my last response was not sent.
>>>
>>> I realized that I cannot use strd due to the following error
>>>
>>> Error: first transfer register must be even -- `strd r3,r4,[r1]'
>>
>> Ah I missed the "even" part when reading the specification. However, 
>> we control the set of registers, so we can't we follow the 
>> restriction? This would be better...
>
> I am ok to follow this. I just want to make sure that this looks ok to 
> you
>
> prepare_xen_region() invokes store_pair(). They are in common header.
>
> So we need to make the change wherever prepare_xen_region() is invoked 
> from arm32/mpu/head.S. This would look like
>
> --- a/xen/arch/arm/arm32/mpu/head.S
> +++ b/xen/arch/arm/arm32/mpu/head.S
> @@ -58,33 +58,33 @@ FUNC(enable_boot_cpu_mm)
>      /* Xen text section. */
>      mov_w   r1, _stext
>      mov_w   r2, _etext
> -    prepare_xen_region r0, r1, r2, r3, r4, r5, 
> attr_prbar=REGION_TEXT_PRBAR
> +    prepare_xen_region r0, r1, r2, r4, r3, r5, 
> attr_prbar=REGION_TEXT_PRBAR

My mistake, It should be

prepare_xen_region r0, r1, r2, r4, r5, r6, attr_prbar=REGION_TEXT_PRBAR

We will be clobbering an extra register.

- Ayan


Re: [PATCH v2 2/3] arm/mpu: Provide and populate MPU C data structures
Posted by Julien Grall 6 months, 1 week ago
Hi Ayan,

On 09/06/2025 11:43, Ayan Kumar Halder wrote:
> Hi,
> 
> On 09/06/2025 10:16, Ayan Kumar Halder wrote:
>>
>> On 09/06/2025 09:42, Julien Grall wrote:
>>> Hi Ayan,
>> Hi Julien,
>>>
>>> On 09/06/2025 09:27, Ayan Kumar Halder wrote:
>>>> On 09/06/2025 08:41, Orzel, Michal wrote:
>>>>>> diff --git a/xen/arch/arm/include/asm/mpu/regions.inc b/xen/arch/ 
>>>>>> arm/ include/asm/mpu/regions.inc
>>>>>> index 6b8c233e6c..631b0b2b86 100644
>>>>>> --- a/xen/arch/arm/include/asm/mpu/regions.inc
>>>>>> +++ b/xen/arch/arm/include/asm/mpu/regions.inc
>>>>>> @@ -24,7 +24,7 @@
>>>>>>   #define XEN_MPUMAP_ENTRY_SHIFT  0x3     /* 8 byte structure */
>>>>>>   .macro store_pair reg1, reg2, dst
>>>>>> -    .word 0xe7f000f0                    /* unimplemented */
>>>>>> +    stm \dst, {\reg1, \reg2}  /* reg2 should be a higher register 
>>>>>> than reg1 */
>>>>> Didn't we agree not to use STM (I suggested it but then Julien 
>>>>> pointed out that
>>>>> it's use in macro might not be the best)?
>>>>
>>>> Ah my last response was not sent.
>>>>
>>>> I realized that I cannot use strd due to the following error
>>>>
>>>> Error: first transfer register must be even -- `strd r3,r4,[r1]'
>>>
>>> Ah I missed the "even" part when reading the specification. However, 
>>> we control the set of registers, so we can't we follow the 
>>> restriction? This would be better...
>>
>> I am ok to follow this. I just want to make sure that this looks ok to 
>> you
>>
>> prepare_xen_region() invokes store_pair(). They are in common header.
>>
>> So we need to make the change wherever prepare_xen_region() is invoked 
>> from arm32/mpu/head.S. This would look like
>>
>> --- a/xen/arch/arm/arm32/mpu/head.S
>> +++ b/xen/arch/arm/arm32/mpu/head.S
>> @@ -58,33 +58,33 @@ FUNC(enable_boot_cpu_mm)
>>      /* Xen text section. */
>>      mov_w   r1, _stext
>>      mov_w   r2, _etext
>> -    prepare_xen_region r0, r1, r2, r3, r4, r5, 
>> attr_prbar=REGION_TEXT_PRBAR
>> +    prepare_xen_region r0, r1, r2, r4, r3, r5, 
>> attr_prbar=REGION_TEXT_PRBAR
> 
> My mistake, It should be
> 
> prepare_xen_region r0, r1, r2, r4, r5, r6, attr_prbar=REGION_TEXT_PRBAR
> 
> We will be clobbering an extra register.

Why can't we use r3 instead of r6?

 > So this would look a different different from its arm64 counterpart.

I don't see the problem with that. The code is not common. And TBH 
prepare_xen_region should never have been common ... but I will not 
re-open this discussion :).

Cheers,

-- 
Julien Grall