|
[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
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |