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

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


  • To: "Orzel, Michal" <Michal.Orzel@xxxxxxx>
  • From: Luca Fancellu <Luca.Fancellu@xxxxxxx>
  • Date: Mon, 20 Apr 2026 14:06:59 +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=c3RbtOAMMkQ+oLoWdnf0f1Y7EtnKscpNvF1OZ1CLJj8=; b=pH+OzRXTieQEvsLGJe7AHwVT97iw7bnmjBJyisCuYrOBxxYqrUbSNbZuCaJ2D3kwBUKWIbvAF1cpznurw/NbaK9s9FJTLtK3pb3UuOvYlOcrlClADOCHU6ij4nngixd7VdqmgbyIudnHMKECG0WsbtH15B6K0I9Mo4IGAgZDOpRQCrfNb52YqF4NdsXe/e95wWwgaVNS3ODdoDlTlUzn49KNvcaUIEhVZa4QRfh9sqAuOO+lc8ljTwopcRL9rP3ZvgQCuJQjTlhfI2rF14FMUI/OVXEx8Kz00YsHff70nd29HgHlTvGCGi8BoXQmbdDD8ZiIlNqo5QgBdY28gpKyDg==
  • 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=c3RbtOAMMkQ+oLoWdnf0f1Y7EtnKscpNvF1OZ1CLJj8=; b=at/h3N4e3QHdEZF1xV7jVoB9uZLxn/WzXMN8VyLWXwAIO74EnxmhbcPhWPUr9+vv8uotSa3YQ7z2P49fXP8Ikj8wL6ihyQpgGuGce2fhytiZxFuSl2En7DGPAq5RixEViWsWMNUGBxWGj5cp/LDvoyd9gJMQ5TKX2SsAi1yTLm3/K5s9mrNGbKNsn7phV374B6+LvdtJnYc+MZ9mreeLouKh4vLDVKYdOPXksvWq4MzpIDg8IxV+5EsshOXKPIzfrR3IHEu1H2K0b0Cx7mco0xMSyxP4Cnx+tbJmc8uIoA0SqwVJ2uNaA+js+FaDJkh3LapTHhWCUrdSQQ2a18Vlqw==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=gOyRjI3oZU/5nbEHMdplSsoqE1oCLN2nVQDgXJcp5IviiZKMSgEBLAGu5R9BnV/BJYjT/LrHS23POeVmTi2Xqv5X1jAQyB7/XvHguFb2pZpc4QTbmd7v9QwuCHIgVgBWOSGh2sE8bx1wJ7rVV46LEwquxFwnzn9lhqRrwmapEU2sYWenBpoJ0z4cqMqjd02AHNr8c5XpR7E+uSc6CBArW5mFW12RTvJbqD5PofwOTHpWNwctDLieC0jQfipZg6QimoOuCMCZ4OPebltN7bs4+aoUllHDDiaocYUAuU7nvWvZoNZbKRvvie5ggFVRKXi/UBsiKoZDKmIHpY2Z2ii89A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FU4+mLGHUBL0q8QV7CPFQR0mfPeQlbXYHwHUn2p3LSugnEk7kg8Rlj+pGpgzQ4DYnLmKQOq7btk1oHuTtdgrMi6HCC2HytwKvs2jznyscQy2VdIAbP6Mk6VlMqwfpgbTGrdCBTswYSp2yj1BJxXQzpXpm/uimWzAA3wnkARnmAOW7idqBa1rvArldvUaCXj4dxl18tlFxhtT1nSQ63TFhfDh+o8ic71xfaKCMiaVQfpnG78aECWhY9xHjfcB3G6yOVPV6RJ7Xj8uFR+mAQbofK/pboIW1+BtK5U1Y7XeCIpaEo3Wfu1Y8miAgJk203Tn6Db1syCGdSCEZaaCRdCmCQ==
  • 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: Mon, 20 Apr 2026 14:08:12 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHczko4909b0LdR6E6hEGKgM2/tzrXjJWsAgAASSYCABMl7gA==
  • Thread-topic: [PATCH] xen/arm: skip holes in physical address space when setting up frametable

HI Michal,

>>> +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 +47,34 @@ 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);
>>> +    max_idx = DIV_ROUND_UP(max_pdx, PDX_GROUP_COUNT);
>>> +    frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ram_start));
>>> 
>>> -    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));
>>> +    /*
>>> +     * pdx_to_page(pdx_s) 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);
>> 
>> We are now rounding down frametable_base_pdx which before this patch it was 
>> the start of the ram,
>> but in xen/xen/arch/arm/include/asm/mm.h, mfn_valid(mfn) is using 
>> frametable_base_pdx to check for
>> mfn validity, this means that we could pass an mfn before the start of the 
>> ram and if __mfn_valid is happy,
>> we are getting a regression.
>> 
>> Can this happen or am I missing something?
> mfn_valid() can indeed return true for an MFN below ram_start that falls
> in the same PDX group, but this is safe. init_frametable_chunk() maps
> and zeroes the frametable for that range, so mfn_to_page() won't fault.
> The zeroed page_info has count_info == 0 and no owner, so any get_page()
> call on it will fail — the page is effectively inert.

Yes, I’ve checked and many path relying on mfn_valid() go also through 
mfn_to_page()
and/or get_page(), there is only one in process_shm() that potentially could 
add a shared memory page
given that we are relaxing mfn_valid now.

I’m trying also to follow is_iomem_page(), to check if subsequent mfn_to_page() 
fail safely, but I think that depending
on that (mfn_valid) the page will be only treated differently, not sure if it’s 
a latent bug to leave mfn_valid() as it is.

Would it be valid to have something like mfn_to_page() != 0 to be part of 
mfn_valid() to ensure it’s a real host ram page?
I’m truly asking here because I didn’t check if it’s doable.

Otherwise we could split the round down and the frametable_base_pdx in this way 
maybe?

diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index 605ec1bcd108..a6802d331178 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -183,6 +183,7 @@ struct page_info
 
 /* PDX of the first page in the frame table. */
 extern unsigned long frametable_base_pdx;
+extern unsigned long frametable_base_grp;
 
 #define PDX_GROUP_SHIFT SECOND_SHIFT
 
@@ -228,9 +229,9 @@ static inline void __iomem *ioremap_wc(paddr_t start, 
size_t len)
 
 /* Convert between machine frame numbers and page-info structures. */
 #define mfn_to_page(mfn)                                            \
-    (frame_table + (mfn_to_pdx(mfn) - frametable_base_pdx))
+    (frame_table + (mfn_to_pdx(mfn) - frametable_base_grp))
 #define page_to_mfn(pg)                                             \
-    pdx_to_mfn((unsigned long)((pg) - frame_table) + frametable_base_pdx)
+    pdx_to_mfn((unsigned long)((pg) - frame_table) + frametable_base_grp)
 
 /* Convert between machine addresses and page-info structures. */
 #define maddr_to_page(ma) mfn_to_page(maddr_to_mfn(ma))
diff --git a/xen/arch/arm/include/asm/mmu/mm.h 
b/xen/arch/arm/include/asm/mmu/mm.h
index 7f4d59137d0d..48a0e342307b 100644
--- a/xen/arch/arm/include/asm/mmu/mm.h
+++ b/xen/arch/arm/include/asm/mmu/mm.h
@@ -88,7 +88,7 @@ static inline struct page_info *virt_to_page(const void *v)
 
     pdx = (va - XENHEAP_VIRT_START) >> PAGE_SHIFT;
     pdx += mfn_to_pdx(directmap_mfn_start);
-    return frame_table + pdx - frametable_base_pdx;
+    return frame_table + pdx - frametable_base_grp;
 }
 
 /*
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index e6b651956927..765896ec2c32 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -28,6 +28,8 @@
 
 unsigned long frametable_base_pdx __read_mostly;
 
+unsigned long frametable_base_grp __read_mostly;
+
 #if defined(CONFIG_ARM_64) || defined(CONFIG_MPU)
 void __init setup_mm(void)
 {
diff --git a/xen/arch/arm/mmu/mm.c b/xen/arch/arm/mmu/mm.c
index 4b4da349c16c..11c47c2d0e25 100644
--- a/xen/arch/arm/mmu/mm.c
+++ b/xen/arch/arm/mmu/mm.c
@@ -9,7 +9,7 @@
 #include <xen/string.h>
 
 #undef pdx_to_page
-#define pdx_to_page(pdx) gcc11_wrap(frame_table + ((pdx) - 
frametable_base_pdx))
+#define pdx_to_page(pdx) gcc11_wrap(frame_table + ((pdx) - 
frametable_base_grp))
 
 static void __init
 init_frametable_chunk(unsigned long pdx_s, unsigned long pdx_e)
@@ -56,12 +56,12 @@ void __init init_frametable(paddr_t ram_start)
      * 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);
+    frametable_base_grp = ROUNDDOWN(frametable_base_pdx, PDX_GROUP_COUNT);
 
-    if ( (max_pdx - frametable_base_pdx) > FRAMETABLE_NR )
+    if ( (max_pdx - frametable_base_grp) > FRAMETABLE_NR )
         panic("Frametable too small\n");
 
-    for ( sidx = (frametable_base_pdx / PDX_GROUP_COUNT); ; sidx = nidx )
+    for ( sidx = (frametable_base_grp / PDX_GROUP_COUNT); ; sidx = nidx )
     {
         unsigned int eidx;
 
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index bd7b02fd33b5..870bfd2be5e7 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -207,6 +207,7 @@ void __init init_frametable(paddr_t ram_start)
     BUILD_BUG_ON(sizeof(struct page_info) != PAGE_INFO_SIZE);
 
     frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ram_start));
+    frametable_base_grp = frametable_base_pdx;
     nr_pdxs = max_pdx - frametable_base_pdx;
     frametable_size = nr_pdxs * sizeof(struct page_info);
 

Not sure! Maybe another maintainer can give another opinion if I’m overthinking 
too much on mfn_valid()

Cheers,
Luca




 


Rackspace

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