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

RE: [PATCH v2 20/40] xen/mpu: plump early_fdt_map in MPU systems


  • To: Julien Grall <julien@xxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Penny Zheng <Penny.Zheng@xxxxxxx>
  • Date: Tue, 7 Feb 2023 06:30:35 +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=CBX6WIPprRbeDcEysvckpxtaMitb4BjzUgmDZzHmKms=; b=SRUeZkMUSQ0JEBmLzSPSv+YGCigMQbtzrpE9xpHMaZv44CKsuDzmQXpObc9+8xGAJNzAK+gn+dj+lq/YQ/mhsQAXP78uFocDF+/qpZ70CC4Pq/2hX/vsNhYvyKu6uWmbjNEEoZn+24r92gO9MSV8rtqD9anT1W5Dqsw+IZAF4U/LZbM/6qR3CzdLi4WFgXixrshwvAtj4/N2+cGsi+bztMAY6r/IuyollGiZDg2/7tPeAEqqlqim3z2Q2Ricoj0PEHfqe/SmVwpb3v2XX5BL8styB1CfzGaI1iTi1mcu40/H3XqlvpF528869vJgwdkfym98aep5JMJnb2kZWv5kNg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=chbp3bnEsa1nc4liqIFoS6bMxIuXDQS6/H43HjyC131R7ZDntzmAPWEW4/U/HoU48E950LgXSIp5OfJU1WJDMi8iD06w75FQseTlpptSnSZP8w1qEqvIjE0MuUwg5kJiEP0xWhRbjQwsgMtss7XPiCQijb7qIDwoiVxI+Ts+UmT56phEHnAYHOnvL/tYhvHDA/hLOTtURiwSzVN5LuWbszeuFgdOHGCLfrjG/lG6N97F7dBEoBAkqfBKOUglnIg0lBFiXL2XQfK4vMIxIFr70nQtN5jgoYgWgPP9+dbCzTOa088zm9mCfOWqNdl0gVTGaXBQvOoy3EPjynBNifGslw==
  • 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>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Tue, 07 Feb 2023 06:31:30 +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: AQHZJxA1N6B15lsZP0qYNGyz15VK/q7B2JQAgAE/6UA=
  • Thread-topic: [PATCH v2 20/40] xen/mpu: plump early_fdt_map in MPU systems

Hi Julien

> -----Original Message-----
> From: Julien Grall <julien@xxxxxxx>
> Sent: Monday, February 6, 2023 6:11 PM
> To: Penny Zheng <Penny.Zheng@xxxxxxx>; xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Wei Chen <Wei.Chen@xxxxxxx>; Stefano Stabellini
> <sstabellini@xxxxxxxxxx>; Bertrand Marquis <Bertrand.Marquis@xxxxxxx>;
> Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
> Subject: Re: [PATCH v2 20/40] xen/mpu: plump early_fdt_map in MPU
> systems
> 
> Hi,
> 
> A few more remarks.
> 
> On 13/01/2023 05:28, Penny Zheng wrote:
> > In MPU system, device tree binary can be packed with Xen image through
> > CONFIG_DTB_FILE, or provided by bootloader through x0.
> >
> > In MPU system, each section in xen.lds.S is PAGE_SIZE aligned.
> > So in order to not overlap with the previous BSS section, dtb section
> > should be made page-aligned too.
> > We add . = ALIGN(PAGE_SIZE); in the head of dtb section to make it happen.
> >
> > In this commit, we map early FDT with a transient MPU memory region at
> > rear with REGION_HYPERVISOR_BOOT.
> >
> > Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
> > Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
> > ---
> >   xen/arch/arm/include/asm/arm64/mpu.h |  5 +++
> >   xen/arch/arm/mm_mpu.c                | 63 +++++++++++++++++++++++++---
> >   xen/arch/arm/xen.lds.S               |  5 ++-
> >   3 files changed, 67 insertions(+), 6 deletions(-)
> >
> > diff --git a/xen/arch/arm/include/asm/arm64/mpu.h
> > b/xen/arch/arm/include/asm/arm64/mpu.h
> > index fcde6ad0db..b85e420a90 100644
> > --- a/xen/arch/arm/include/asm/arm64/mpu.h
> > +++ b/xen/arch/arm/include/asm/arm64/mpu.h
> > @@ -45,18 +45,22 @@
> >    * [3:4] Execute Never
> >    * [5:6] Access Permission
> >    * [7]   Region Present
> > + * [8]   Boot-only Region
> >    */
> >   #define _REGION_AI_BIT            0
> >   #define _REGION_XN_BIT            3
> >   #define _REGION_AP_BIT            5
> >   #define _REGION_PRESENT_BIT       7
> > +#define _REGION_BOOTONLY_BIT      8
> >   #define _REGION_XN                (2U << _REGION_XN_BIT)
> >   #define _REGION_RO                (2U << _REGION_AP_BIT)
> >   #define _REGION_PRESENT           (1U << _REGION_PRESENT_BIT)
> > +#define _REGION_BOOTONLY          (1U << _REGION_BOOTONLY_BIT)
> >   #define REGION_AI_MASK(x)         (((x) >> _REGION_AI_BIT) & 0x7U)
> >   #define REGION_XN_MASK(x)         (((x) >> _REGION_XN_BIT) & 0x3U)
> >   #define REGION_AP_MASK(x)         (((x) >> _REGION_AP_BIT) & 0x3U)
> >   #define REGION_RO_MASK(x)         (((x) >> _REGION_AP_BIT) & 0x2U)
> > +#define REGION_BOOTONLY_MASK(x)   (((x) >> _REGION_BOOTONLY_BIT)
> & 0x1U)
> >
> >   /*
> >    * _REGION_NORMAL is convenience define. It is not meant to be used
> > @@ -68,6 +72,7 @@
> >   #define REGION_HYPERVISOR_RO
> (_REGION_NORMAL|_REGION_XN|_REGION_RO)
> >
> >   #define REGION_HYPERVISOR         REGION_HYPERVISOR_RW
> > +#define REGION_HYPERVISOR_BOOT
> (REGION_HYPERVISOR_RW|_REGION_BOOTONLY)
> >
> >   #define INVALID_REGION            (~0UL)
> >
> > diff --git a/xen/arch/arm/mm_mpu.c b/xen/arch/arm/mm_mpu.c index
> > 08720a7c19..b34dbf4515 100644
> > --- a/xen/arch/arm/mm_mpu.c
> > +++ b/xen/arch/arm/mm_mpu.c
> > @@ -20,11 +20,16 @@
> >    */
> >
> >   #include <xen/init.h>
> > +#include <xen/libfdt/libfdt.h>
> >   #include <xen/mm.h>
> >   #include <xen/page-size.h>
> > +#include <xen/pfn.h>
> > +#include <xen/sizes.h>
> >   #include <xen/spinlock.h>
> >   #include <asm/arm64/mpu.h>
> > +#include <asm/early_printk.h>
> >   #include <asm/page.h>
> > +#include <asm/setup.h>
> >
> >   #ifdef NDEBUG
> >   static inline void
> > @@ -62,6 +67,8 @@ uint64_t __ro_after_init max_xen_mpumap;
> >
> >   static DEFINE_SPINLOCK(xen_mpumap_lock);
> >
> > +static paddr_t dtb_paddr;
> > +
> >   /* Write a MPU protection region */
> >   #define WRITE_PROTECTION_REGION(sel, pr, prbar_el2, prlar_el2) ({       \
> >       uint64_t _sel = sel;                                                \
> > @@ -403,7 +410,16 @@ static int xen_mpumap_update_entry(paddr_t
> base,
> > paddr_t limit,
> >
> >           /* During boot time, the default index is next_fixed_region_idx. 
> > */
> >           if ( system_state <= SYS_STATE_active )
> > -            idx = next_fixed_region_idx;
> > +        {
> > +            /*
> > +             * If it is a boot-only region (i.e. region for early FDT),
> > +             * it shall be added from the tail for late init re-organizing
> > +             */
> > +            if ( REGION_BOOTONLY_MASK(flags) )
> > +                idx = next_transient_region_idx;
> > +            else
> > +                idx = next_fixed_region_idx;
> > +        }
> >
> >           xen_mpumap[idx] = pr_of_xenaddr(base, limit - 1,
> REGION_AI_MASK(flags));
> >           /* Set permission */
> > @@ -465,14 +481,51 @@ int map_pages_to_xen(unsigned long virt,
> >                                mfn_to_maddr(mfn_add(mfn, nr_mfns)), flags);
> >   }
> >
> > -/* TODO: Implementation on the first usage */ -void
> > dump_hyp_walk(vaddr_t addr)
> > +void * __init early_fdt_map(paddr_t fdt_paddr)
> >   {
> > +    void *fdt_virt;
> > +    uint32_t size;
> > +
> > +    /*
> > +     * Check whether the physical FDT address is set and meets the
> minimum
> > +     * alignment requirement. Since we are relying on MIN_FDT_ALIGN to
> be at
> > +     * least 8 bytes so that we always access the magic and size fields
> > +     * of the FDT header after mapping the first chunk, double check if
> > +     * that is indeed the case.
> > +     */
> > +     BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
> > +     if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN )
> > +         return NULL;
> > +
> > +    dtb_paddr = fdt_paddr;
> > +    /*
> > +     * In MPU system, device tree binary can be packed with Xen image
> > +     * through CONFIG_DTB_FILE, or provided by bootloader through x0.
> 
> The behavior you describe is not specific to the MPU system. I also don't
> quite understand how describing the method to pass the DT actually matters
> here.
> 
> > +     * Map FDT with a transient MPU memory region of MAX_FDT_SIZE.
> > +     * After that, we can do some magic check.
> > +     */
> > +    if ( map_pages_to_xen(round_pgdown(fdt_paddr),
> 
> I haven't looked at the rest of the series. But from here, it seems a bit 
> strange
> to use map_pages_to_xen() because the virt and the phys should be the
> same.
> 

Hmm, t thought map_pages_to_xen, is to set up memory mapping for access.
In MPU, we also need to set up a MPU memory region for the FDT, even without
virt-to-phys conversion 

> Do you plan to share some code where map_pages_to_xen() will be used?
> 

Each time, in C boot-time, we build up a new MPU memory region for stage 1
EL2 memory mapping, we use this map_pages_to_xen to complete.
I think it has the same effect as it has in MMU, other than MMU sets up
virt-to-phys memory mapping and MPU always sets up identity memory mapping.

> > +                          maddr_to_mfn(round_pgdown(fdt_paddr)),
> > +                          round_pgup(MAX_FDT_SIZE) >> PAGE_SHIFT,
> 
> This will not work properly is the Device-Tree is MAX_FDT_SIZE (could
> already be page-aligned) but the start address is not page-aligned.
> 
> But I think trying to map the maximum size from the start could potentially
> result to some issue. Below the excerpt from the Image
> documentation:
> 
> "The device tree blob (dtb) must be placed on an 8-byte boundary and must
> not exceed 2 megabytes in size. Since the dtb will be mapped cacheable using
> blocks of up to 2 megabytes in size, it must not be placed within any 2M
> region which must be mapped with any specific attributes."
> 
> So it would be better to map the first 2MB. Check the size and then re-map
> with an extra 2MB if needed.
> 

Oh, under special circumstances, the current implementation will map exceeding 
2MB.
Thanks for explanation!
I will map as you suggested.

> > +                          REGION_HYPERVISOR_BOOT) ) > +        
> > panic("Unable to
> map the device-tree.\n");
> > +
> > +    /* VA == PA */
> 
> I have seen in a few places where you add a similar comment. But I am not
> sure to understand how this help to describe the implementation of
> maddr_to_virt().
> 
> > +    fdt_virt = maddr_to_virt(fdt_paddr);
> > +
> > +    if ( fdt_magic(fdt_virt) != FDT_MAGIC )
> > +        return NULL;
> > +
> > +    size = fdt_totalsize(fdt_virt);
> > +    if ( size > MAX_FDT_SIZE )
> > +        return NULL;
> > +
> > +    return fdt_virt;
> >   }
> >
> > -void * __init early_fdt_map(paddr_t fdt_paddr)
> > +/* TODO: Implementation on the first usage */ void
> > +dump_hyp_walk(vaddr_t addr)
> >   {
> > -    return NULL;
> >   }
> >
> >   void __init remove_early_mappings(void) diff --git
> > a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index
> > 79965a3c17..0565e22a1f 100644
> > --- a/xen/arch/arm/xen.lds.S
> > +++ b/xen/arch/arm/xen.lds.S
> > @@ -218,7 +218,10 @@ SECTIONS
> >     _end = . ;
> >
> >     /* Section for the device tree blob (if any). */
> > -  .dtb : { *(.dtb) } :text
> > +  .dtb : {
> > +      . = ALIGN(PAGE_SIZE);
> > +      *(.dtb)
> > +  } :text
> >
> >     DWARF2_DEBUG_SECTIONS
> >
> 
> Cheers,
> 
> --
> Julien Grall

 


Rackspace

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