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

RE: [PATCH v2 11/40] xen/mpu: build up start-of-day Xen MPU memory region map


  • To: Ayan Kumar Halder <ayankuma@xxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Penny Zheng <Penny.Zheng@xxxxxxx>
  • Date: Sun, 29 Jan 2023 06:47:30 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5dWuG2UPPtT7nqAbc7D7vzScag53zwV8SczmR3BjogA=; b=NzE9BtmPC9asC1ChNOpg4uL/XC803iO4wTQjESomH4R7VJlgRqyisamDrH/3LUrf9mgMfXDYa0mAmaQHl/gyhcyt3lUwBUJ/xt/abHECUYb2o5JXwyRE/fi2dGMvklM12GxFwtZMYNTfrYMAbQyklBJgy24SKGmZDciKWZXybe+QGPob8t1kWQkfz+APN4wf12alqjgUBNRtCOrWtfuqBwcimphbblvVScoP88Mcd6BUHNuKC3l6E32XTvdQLLStkAlgdi1bZ4/p4TqgWwbA3cHNW9hkfpFOHezyqPE7TEdOrqLODrEyYAiINZOxiyoJaLqc6KJ2uzAFvDf/Wh7opw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iDvY0xQhGoragX7QSI2rQqldyUuAzvvVofEyOxKENSOMmejEetNeaoasTIKvuQ2m+xMYHR5IN3bu+dBugzSwfwnGvNnxcqtZv5FgmwHufm7d4eRevvibHgqMWLaZiRdf2FlAEkPmqyPLp5kzvTSoDj+dVM6JgL9DQPTxSJErLhZU6QPSYqmjbnBCVI6Ixw3SSjth3Gq7fCXLe9C1dsB+3LPKnQo8OhMYZ/PFb/njQ5Yfs7LFqDW1LEKkhNQ/Pk1XtHBA9UHAacvDSC8CqOBOc+/tMtuvLO1typs0cmRXM6LcFEVBPCREx9Jewju6dEtj43KsaqLBmQuCzSQ6etDEzA==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: Wei Chen <Wei.Chen@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, "Volodymyr_Babchuk@xxxxxxxx" <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Sun, 29 Jan 2023 06:48:02 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHZJxAhTWb1zeTHm029bSgcZo/2Yq6lkLCAgA92BsA=
  • Thread-topic: [PATCH v2 11/40] xen/mpu: build up start-of-day Xen MPU memory region map

Hi Ayan

> -----Original Message-----
> From: Ayan Kumar Halder <ayankuma@xxxxxxx>
> Sent: Thursday, January 19, 2023 6:19 PM
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Wei Chen <Wei.Chen@xxxxxxx>; Penny Zheng
> <Penny.Zheng@xxxxxxx>; Stefano Stabellini <sstabellini@xxxxxxxxxx>; Julien
> Grall <julien@xxxxxxx>; Bertrand Marquis <Bertrand.Marquis@xxxxxxx>;
> Volodymyr_Babchuk@xxxxxxxx
> Subject: Re: [PATCH v2 11/40] xen/mpu: build up start-of-day Xen MPU
> memory region map
> 
> 
> On 13/01/2023 05:28, Penny Zheng wrote:
> > CAUTION: This message has originated from an External Source. Please use
> proper judgment and caution when opening attachments, clicking links, or
> responding to this email.
> >
> >
> > From: Penny Zheng <penny.zheng@xxxxxxx>
> >
> > The start-of-day Xen MPU memory region layout shall be like as follows:
> >
> > xen_mpumap[0] : Xen text
> > xen_mpumap[1] : Xen read-only data
> > xen_mpumap[2] : Xen read-only after init data xen_mpumap[3] : Xen
> > read-write data xen_mpumap[4] : Xen BSS ......
> > xen_mpumap[max_xen_mpumap - 2]: Xen init data
> > xen_mpumap[max_xen_mpumap - 1]: Xen init text
> >
> > max_xen_mpumap refers to the number of regions supported by the EL2
> MPU.
> > The layout shall be compliant with what we describe in xen.lds.S, or
> > the codes need adjustment.
> >
> > As MMU system and MPU system have different functions to create the
> > boot MMU/MPU memory management data, instead of introducing extra
> > #ifdef in main code flow, we introduce a neutral name
> > prepare_early_mappings for both, and also to replace create_page_tables
> for MMU.
> >
> > Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
> > Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
> > ---
> >   xen/arch/arm/arm64/Makefile              |   2 +
> >   xen/arch/arm/arm64/head.S                |  17 +-
> >   xen/arch/arm/arm64/head_mmu.S            |   4 +-
> >   xen/arch/arm/arm64/head_mpu.S            | 323
> +++++++++++++++++++++++
> >   xen/arch/arm/include/asm/arm64/mpu.h     |  63 +++++
> >   xen/arch/arm/include/asm/arm64/sysregs.h |  49 ++++
> >   xen/arch/arm/mm_mpu.c                    |  48 ++++
> >   xen/arch/arm/xen.lds.S                   |   4 +
> >   8 files changed, 502 insertions(+), 8 deletions(-)
> >   create mode 100644 xen/arch/arm/arm64/head_mpu.S
> >   create mode 100644 xen/arch/arm/include/asm/arm64/mpu.h
> >   create mode 100644 xen/arch/arm/mm_mpu.c
> >
> > diff --git a/xen/arch/arm/arm64/Makefile
> b/xen/arch/arm/arm64/Makefile
> > index 22da2f54b5..438c9737ad 100644
> > --- a/xen/arch/arm/arm64/Makefile
> > +++ b/xen/arch/arm/arm64/Makefile
> > @@ -10,6 +10,8 @@ obj-y += entry.o
> >   obj-y += head.o
> >   ifneq ($(CONFIG_HAS_MPU),y)
> >   obj-y += head_mmu.o
> > +else
> > +obj-y += head_mpu.o
> >   endif
> >   obj-y += insn.o
> >   obj-$(CONFIG_LIVEPATCH) += livepatch.o diff --git
> > a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index
> > 782bd1f94c..145e3d53dc 100644
> > --- a/xen/arch/arm/arm64/head.S
> > +++ b/xen/arch/arm/arm64/head.S
> > @@ -68,9 +68,9 @@
> >    *  x24 -
> >    *  x25 -
> >    *  x26 - skip_zero_bss (boot cpu only)
> > - *  x27 -
> > - *  x28 -
> > - *  x29 -
> > + *  x27 - region selector (mpu only)
> > + *  x28 - prbar (mpu only)
> > + *  x29 - prlar (mpu only)
> >    *  x30 - lr
> >    */
> >
> > @@ -82,7 +82,7 @@
> >    * ---------------------------
> >    *
> >    * The requirements are:
> > - *   MMU = off, D-cache = off, I-cache = on or off,
> > + *   MMU/MPU = off, D-cache = off, I-cache = on or off,
> >    *   x0 = physical address to the FDT blob.
> >    *
> >    * This must be the very first address in the loaded image.
> > @@ -252,7 +252,12 @@ real_start_efi:
> >
> >           bl    check_cpu_mode
> >           bl    cpu_init
> > -        bl    create_page_tables
> > +
> > +        /*
> > +         * Create boot memory management data, pagetable for MMU
> systems
> > +         * and memory regions for MPU systems.
> > +         */
> > +        bl    prepare_early_mappings
> >           bl    enable_mmu
> >
> >           /* We are still in the 1:1 mapping. Jump to the runtime
> > Virtual Address. */ @@ -310,7 +315,7 @@ GLOBAL(init_secondary)
> >   #endif
> >           bl    check_cpu_mode
> >           bl    cpu_init
> > -        bl    create_page_tables
> > +        bl    prepare_early_mappings
> >           bl    enable_mmu
> >
> >           /* We are still in the 1:1 mapping. Jump to the runtime
> > Virtual Address. */ diff --git a/xen/arch/arm/arm64/head_mmu.S
> > b/xen/arch/arm/arm64/head_mmu.S index 6ff13c751c..2346f755df
> 100644
> > --- a/xen/arch/arm/arm64/head_mmu.S
> > +++ b/xen/arch/arm/arm64/head_mmu.S
> > @@ -123,7 +123,7 @@
> >    *
> >    * Clobbers x0 - x4
> >    */
> > -ENTRY(create_page_tables)
> > +ENTRY(prepare_early_mappings)
> >           /* Prepare the page-tables for mapping Xen */
> >           ldr   x0, =XEN_VIRT_START
> >           create_table_entry boot_pgtable, boot_first, x0, 0, x1, x2,
> > x3 @@ -208,7 +208,7 @@ 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
> > -ENDPROC(create_page_tables)
> > +ENDPROC(prepare_early_mappings)
> 
> NIT:- Can this renaming be done in a separate patch of its own (before this
> patch).
> 

Yay, you're right. I'll put it in different commit.

> So that this patch can be only about the new functionality introduced.
> 
> >
> >   /*
> >    * Turn on the Data Cache and the MMU. The function will return on
> > the 1:1 diff --git a/xen/arch/arm/arm64/head_mpu.S
> > b/xen/arch/arm/arm64/head_mpu.S new file mode 100644 index
> > 0000000000..0b97ce4646
> > --- /dev/null
> > +++ b/xen/arch/arm/arm64/head_mpu.S
> > @@ -0,0 +1,323 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Start-of-day code for an Armv8-R AArch64 MPU system.
> > + */
> > +
> > +#include <asm/arm64/mpu.h>
> > +#include <asm/early_printk.h>
> > +#include <asm/page.h>
> > +
> > +/*
> > + * One entry in Xen MPU memory region mapping table(xen_mpumap) is
> a
> > +structure
> > + * of pr_t, which is 16-bytes size, so the entry offset is the order of 4.
> > + */
> NIT :- It would be good to quote Arm ARM from which can be referred for
> the definitions.
> > +#define MPU_ENTRY_SHIFT         0x4
> > +
> > +#define REGION_SEL_MASK         0xf
> > +
> > +#define REGION_TEXT_PRBAR       0x38    /* SH=11 AP=10 XN=00 */
> > +#define REGION_RO_PRBAR         0x3A    /* SH=11 AP=10 XN=10 */
> > +#define REGION_DATA_PRBAR       0x32    /* SH=11 AP=00 XN=10 */
> > +
> > +#define REGION_NORMAL_PRLAR     0x0f    /* NS=0 ATTR=111 EN=1 */
> > +
> > +/*
> > + * Macro to round up the section address to be PAGE_SIZE aligned
> > + * Each section(e.g. .text, .data, etc) in xen.lds.S is page-aligned,
> > + * which is usually guarded with ". = ALIGN(PAGE_SIZE)" in the head,
> > + * or in the end
> > + */
> > +.macro roundup_section, xb
> > +        add   \xb, \xb, #(PAGE_SIZE-1)
> > +        and   \xb, \xb, #PAGE_MASK
> > +.endm
> > +
> > +/*
> > + * Macro to create a new MPU memory region entry, which is a
> > +structure
> > + * of pr_t,  in \prmap.
> > + *
> > + * Inputs:
> > + * prmap:   mpu memory region map table symbol
> > + * sel:     region selector
> > + * prbar:   preserve value for PRBAR_EL2
> > + * prlar    preserve value for PRLAR_EL2
> > + *
> > + * Clobbers \tmp1, \tmp2
> > + *
> > + */
> > +.macro create_mpu_entry prmap, sel, prbar, prlar, tmp1, tmp2
> > +    mov   \tmp2, \sel
> > +    lsl   \tmp2, \tmp2, #MPU_ENTRY_SHIFT
> > +    adr_l \tmp1, \prmap
> > +    /* Write the first 8 bytes(prbar_t) of pr_t */
> > +    str   \prbar, [\tmp1, \tmp2]
> > +
> > +    add   \tmp2, \tmp2, #8
> > +    /* Write the last 8 bytes(prlar_t) of pr_t */
> > +    str   \prlar, [\tmp1, \tmp2]
> > +.endm
> > +
> > +/*
> > + * Macro to store the maximum number of regions supported by the EL2
> > +MPU
> > + * in max_xen_mpumap, which is identified by MPUIR_EL2.
> > + *
> > + * Outputs:
> > + * nr_regions: preserve the maximum number of regions supported by
> > +the EL2 MPU
> > + *
> > + * Clobbers \tmp1
> > + *
> > + */
> > +.macro read_max_el2_regions, nr_regions, tmp1
> > +    load_paddr \tmp1, max_xen_mpumap
> > +    mrs   \nr_regions, MPUIR_EL2
> > +    isb
> > +    str   \nr_regions, [\tmp1]
> > +.endm
> > +
> > +/*
> > + * Macro to prepare and set a MPU memory region
> > + *
> > + * Inputs:
> > + * base:        base address symbol (should be page-aligned)
> > + * limit:       limit address symbol
> > + * sel:         region selector
> > + * prbar:       store computed PRBAR_EL2 value
> > + * prlar:       store computed PRLAR_EL2 value
> > + * attr_prbar:  PRBAR_EL2-related memory attributes. If not specified
> > +it will be REGION_DATA_PRBAR
> > + * attr_prlar:  PRLAR_EL2-related memory attributes. If not specified
> > +it will be REGION_NORMAL_PRLAR
> > + *
> > + * Clobber \tmp1
> > + *
> > + */
> > +.macro prepare_xen_region, base, limit, sel, prbar, prlar, tmp1,
> attr_prbar=REGION_DATA_PRBAR, attr_prlar=REGION_NORMAL_PRLAR
> > +    /* Prepare value for PRBAR_EL2 reg and preserve it in \prbar.*/
> > +    load_paddr \prbar, \base
> > +    and   \prbar, \prbar, #MPU_REGION_MASK
> > +    mov   \tmp1, #\attr_prbar
> > +    orr   \prbar, \prbar, \tmp1
> > +
> > +    /* Prepare value for PRLAR_EL2 reg and preserve it in \prlar.*/
> > +    load_paddr \prlar, \limit
> > +    /* Round up limit address to be PAGE_SIZE aligned */
> > +    roundup_section \prlar
> > +    /* Limit address should be inclusive */
> > +    sub   \prlar, \prlar, #1
> > +    and   \prlar, \prlar, #MPU_REGION_MASK
> > +    mov   \tmp1, #\attr_prlar
> > +    orr   \prlar, \prlar, \tmp1
> > +
> > +    mov   x27, \sel
> > +    mov   x28, \prbar
> > +    mov   x29, \prlar
> 
> Any reasons for using x27, x28, x29 to pass function parameters.
> 
> https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
> states x0..x7 should be used (Table 2, General-purpose registers and
> AAPCS64 usage).
> 

These registers are documented and reserved in xen/arch/arm/arm64/head.S, like
how we reserve x26 to pass function parameter in skip_zero_bss, see
```
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 782bd1f94c..145e3d53dc 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -68,9 +68,9 @@
  *  x24 -
  *  x25 -
  *  x26 - skip_zero_bss (boot cpu only)
- *  x27 -
- *  x28 -
- *  x29 -
+ *  x27 - region selector (mpu only)
+ *  x28 - prbar (mpu only)
+ *  x29 - prlar (mpu only)
  *  x30 - lr
  */
```
x0...x7 are already commonly used in xen/arch/arm/arm64/head.S, it is difficult 
for me
to preserve them only for write_pr.

If we are using x0...x7 as function parameter, I need to stack/pop them to 
mutate
stack operation in write_pr to avoid corruption.

> > +    /*
> > +     * x2skip_zero7, x28, x29 are special registers designed as
> > +     * inputs for function write_pr
> > +     */
> > +    bl    write_pr
> > +.endm
> > +
[...]
> > --
> > 2.25.1
> >
> NIT:- Would you consider splitting this patch, something like this :-
> 
> 1. Renaming of the mmu function
> 
> 2. Define sysregs, prlar_t, prbar_t and other other hardware specific macros.
> 
> 3. Define write_pr
> 
> 4. The rest of the changes (ie prepare_early_mappings(), xen.lds.S, etc)
> 

For 2, 3 and 4, it will break the rule of "Always define and introduce at the
first usage".
However, I know that this commit is very big ;/, so as long as maintainers are 
also
in favor of your splitting suggestion, I'm happy to do the split too~

> - Ayan


 


Rackspace

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