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

Re: [PATCH v3] xen/arm: skip holes in physical address space when setting up frametable


  • To: Michal Orzel <michal.orzel@xxxxxxx>
  • From: Luca Fancellu <Luca.Fancellu@xxxxxxx>
  • Date: Wed, 6 May 2026 14:06:02 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=amd.com smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • 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=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=9kyZ75V/CI+PZSmQvvjR+dnfX4WO7h6pV9IUgDpoM04=; b=u2D4Ij8bxUFOO5RSsywBvFZ7SdsYAeMRaDWtFK8Ljgt81OTDmZ9r9B4byvVZ6q+A/Tr6dd4z4/qLS/Y6r679Jt5YRMZNR/byQ+wfkS3GeLDcO3FDds54k4yTTJb3ilNITlA+sXfsFP2KVoQN9N58P6gXzLJizOFMtu6AHchJ1rc2YdMjmGFjSZ2U0pc+euxVrJc6Pwj213tRkpp6VTrQvV0gqFiPX61c2DOs/xQ0wIom9St3f7+3OQzhoyMloXGpFxdDZtIfXzZ5LrcnfWmKNzZ27rJHesqWaWeJKqwJe03c9dgexaDi1ygJTfNARPbHCqFw5d8iXJhyCFVb1B7l+A==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=9kyZ75V/CI+PZSmQvvjR+dnfX4WO7h6pV9IUgDpoM04=; b=TfuXfiTr4K46bv1VtPpgQFHaC6kWKKg7JINa2uh8tewzOpemyZ+ZFAno1LZOq+xAC3RvICEI1hGc/V9UHT7chjjWMbFC7L4XeN/G5/+7Q6vlly5BoB1w12mKNwxlhzddejnEzzvjA2OTOj2629dt+iXMrommcGfgIz3yPoUVzYNSN+KaZq5Ekx6hMfJxb6w2l2f2e5+czh48Sd3hkPSz1itBABWh6ZyxpfDN9e1neh/N++OnaDXfKmix8+6OwC80jMXQKTcALYndjSkww8MPTRfpo+pclaFiTl15QM+QVG1aDWxN1hSBbyrqCi0/xUVA+yNJn8eIXU+bmlIDkGERvQ==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=JwSk72q3OmrYIYt6zuzOvfW4EarRJlloZzkfoNkFVCrLHGUNrxRaIdgrUDN8kZDgp8adoywySeF+y2IEtb+qCwVw5NfUykVGa4OHq8ZgyCcVb17ytIQgE2Gjg2Jpiz6DX2Twa2Xg0TZjOrZ48chb5txFgjgdakhVY7+jlezjC6FirUEIyBqK29oQkj5fH3Kh3NlThGtyqIGodFeoKW8pbxkqR92i5ab0yZKaw4QKWIZojSYeXA1CJwlRmZ0CJY+uSUd3/LcXLgeYIqOL5YFARSol5Buv5RA/N1ksgYJY031fMH8l8l8jPx4zIIT/2gd/omKZuqcF9irmbZHRDgPV9w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=fon7iGKnHOQ4DjETQs1GPcp6Fz8ghJdeX1zFgQhfjPC8R93bl2dgwRhkE53Hi9JyQTOd/okYc19tmYU3TxutPdqCeaJK17QY2Oijo4pRMhVEYzjJTaCdN9iA3+FjQzkZslD70CDmkf0VfXhANkyoOKX2229WRGcQuXwZ4QJAGwoEurJPGv07OC4OHPFAhyZViqsYQU9F8GG9BsJZnd/kqJ4O7JYwoZvbjtQ5q8WVM+anVd2RSoBHW/NKeNkZe/w/llKMOUkQdUWLODegnrgjHhj66KrFs/7f5RqsyE8Czo00c2SiQVLZVS6yE6J/BJxMgiicxXnVpTFW+VDw1T1ROQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=arm.com header.i="@arm.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"; dkim=pass header.s=selector1 header.d=arm.com header.i="@arm.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <Bertrand.Marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Wed, 06 May 2026 14:07:19 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHc3TRHoODpo5BtK0edRSwNDE97NLYBCGOA
  • Thread-topic: [PATCH v3] xen/arm: skip holes in physical address space when setting up frametable

Hi Michal,

> diff --git a/xen/arch/arm/mmu/mm.c b/xen/arch/arm/mmu/mm.c
> index 6604f3bf4e6a..c4018a61aa01 100644
> --- a/xen/arch/arm/mmu/mm.c
> +++ b/xen/arch/arm/mmu/mm.c
> @@ -6,18 +6,55 @@

Should we have also #include <xen/bitops.h> because we use
find_next_*? Apologies I missed this in previous reviews.

> #include <xen/mm.h>
> #include <xen/mm-frame.h>
> #include <xen/pdx.h>
> +#include <xen/sizes.h>
> #include <xen/string.h>
> 
> -/* Map a frame table to cover physical addresses ps through pe */
> -void __init setup_frametable_mappings(paddr_t ps, paddr_t pe)
> +static void __init init_frametable_chunk(unsigned long pdx_s,
> +                                         unsigned long pdx_e)
> {
> -    unsigned long nr_pdxs = mfn_to_pdx(mfn_add(maddr_to_mfn(pe), -1)) -
> -                            mfn_to_pdx(maddr_to_mfn(ps)) + 1;
> -    unsigned long frametable_size = nr_pdxs * sizeof(struct page_info);
> -    mfn_t base_mfn;
> -    const unsigned long mapping_size = frametable_size < MB(32) ? MB(2)
> -                                                                : MB(32);
> +    unsigned long nr_pdxs = pdx_e - pdx_s;
> +    unsigned long chunk_size = nr_pdxs * sizeof(struct page_info);
> +    unsigned long pfn_align;
> +    struct page_info *pg;
>     int rc;
> +    mfn_t base_mfn;
> +
> +    /*
> +     * In-loop chunks span whole PDX groups, which are always page-size
> +     * aligned. The last chunk ending at max_pdx may not be, so round up.
> +     */
> +    chunk_size = ROUNDUP(chunk_size, PAGE_SIZE);
> +
> +    /*
> +     * Try to align the allocation to the contiguous mapping size so that
> +     * map_pages_to_xen() can use the contiguous bit.
> +     */
> +    pfn_align = ((chunk_size >= MB(32)) ? MB(32) : MB(2)) >> PAGE_SHIFT;
> +
> +    base_mfn = alloc_boot_pages(chunk_size >> PAGE_SHIFT, pfn_align);
> +
> +    /*
> +     * Resolve the frametable VA via mfn_to_page(pdx_to_mfn(...)) rather
> +     * than pdx_to_page() because the generic pdx_to_page() does not subtract
> +     * frametable_base_pdx. There's more work to be done to make it generic, 
> so
> +     * for now route through mfn_to_page(), which on Arm applies the
> +     * frametable_base_pdx offset and yields the correct VA.
> +     */
> +    pg = mfn_to_page(pdx_to_mfn(pdx_s));
> +    rc = map_pages_to_xen((unsigned long)pg, base_mfn,
> +                          chunk_size >> PAGE_SHIFT,
> +                          PAGE_HYPERVISOR_RW | _PAGE_BLOCK);
> +    if ( rc )
> +        panic("Unable to setup the frametable mappings\n");
> +
> +    memset(pg, 0, nr_pdxs * sizeof(struct page_info));
> +    memset(pg + nr_pdxs, -1,
> +           chunk_size - nr_pdxs * sizeof(struct page_info));
> +}
> +
> +void __init init_frametable(paddr_t ram_start)
> +{
> +    unsigned int sidx, nidx, max_idx;
> 
>     /*
>      * The size of paddr_t should be sufficient for the complete range of
> @@ -26,24 +63,40 @@ void __init setup_frametable_mappings(paddr_t ps, paddr_t 
> pe)
>     BUILD_BUG_ON((sizeof(paddr_t) * BITS_PER_BYTE) < PADDR_BITS);
>     BUILD_BUG_ON(sizeof(struct page_info) != PAGE_INFO_SIZE);
> 
> -    if ( frametable_size > FRAMETABLE_SIZE )
> -        panic("The frametable cannot cover the physical region %#"PRIpaddr" 
> - %#"PRIpaddr"\n",
> -              ps, pe);
> +    /* init_frametable_chunk() allocation alignment assumes 4KB granule */
> +    BUILD_BUG_ON(PAGE_SIZE != SZ_4K);
> 
> -    frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ps));
> -    /* Round up to 2M or 32M boundary, as appropriate. */
> -    frametable_size = ROUNDUP(frametable_size, mapping_size);
> -    base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 32<<(20-12));
> +    /* In-loop chunks must produce page-aligned frametable regions */
> +    BUILD_BUG_ON((PDX_GROUP_COUNT * sizeof(struct page_info)) % PAGE_SIZE);
> 
> -    rc = map_pages_to_xen(FRAMETABLE_VIRT_START, base_mfn,
> -                          frametable_size >> PAGE_SHIFT,
> -                          PAGE_HYPERVISOR_RW | _PAGE_BLOCK);
> -    if ( rc )
> -        panic("Unable to setup the frametable mappings.\n");
> +    max_idx = DIV_ROUND_UP(max_pdx, PDX_GROUP_COUNT);
> +    frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ram_start));
> +
> +    /*
> +     * Mapping address in init_frametable_chunk must be page-aligned
> +     * for map_pages_to_xen(). Aligning to PDX_GROUP_COUNT guarantees this
> +     * because PDX_GROUP_COUNT * sizeof(page_info) is always a multiple of
> +     * PAGE_SIZE by construction.
> +     */
> +    frametable_base_pdx = ROUNDDOWN(frametable_base_pdx, PDX_GROUP_COUNT);
> +
> +    if ( (max_pdx - frametable_base_pdx) > FRAMETABLE_NR )
> +        panic("Frametable too small\n");
> +
> +    for ( sidx = (frametable_base_pdx / PDX_GROUP_COUNT); ; sidx = nidx )
> +    {
> +        unsigned int eidx;
> +
> +        eidx = find_next_zero_bit(pdx_group_valid, max_idx, sidx);
> +        nidx = find_next_bit(pdx_group_valid, max_idx, eidx);
> +
> +        if ( nidx >= max_idx )
> +            break;
> +
> +        init_frametable_chunk(sidx * PDX_GROUP_COUNT, eidx * 
> PDX_GROUP_COUNT);
> +    }
> 
> -    memset(&frame_table[0], 0, nr_pdxs * sizeof(struct page_info));
> -    memset(&frame_table[nr_pdxs], -1,
> -           frametable_size - (nr_pdxs * sizeof(struct page_info)));
> +    init_frametable_chunk(sidx * PDX_GROUP_COUNT, max_pdx);
> }


Apart from that the rest looks ok to me. I’ve also tested for Arm64 MMU/MPU and 
Arm32 MMU.

Reviewed-by: Luca Fancellu <luca.fancellu@xxxxxxx>
Tested-by: Luca Fancellu <luca.fancellu@xxxxxxx>

Cheers,
Luca


 


Rackspace

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