[PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages

Richard Cheng posted 1 patch 5 days ago
tools/testing/cxl/test/cxl.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
[PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
Posted by Richard Cheng 5 days ago
cxl_test allocate synthetic CFMWS HPA windows out of a gen_pool and asks
the allocator for SZ_256M alignment. It has been sufficient on x86 with
4k pages, arm64 with 4k pages since their PMD_SIZE are 2MB.

But for 64k-page arm64 kernel with CONFIG_ARM64_64K_PAGES=y and
CONFIG_PGTABLE_LEVELS=3 , the PMD_SIZE is 512 MB, which is much larger
than the alignment cxl_test guarantees. That results in every CXL region
carved from that window inherits a mis-aligned start.

The DAX driver's cxl_dax_region_probe() then calls "alloc_dax_region()
and the probe fails with -ENOMEM, with error message

"""
    cxl_dax_region dax_region1: probe with driver cxl_dax_region failed
                                with error -12
"""

It was hit while bringing up cxl_test on an ARM64 server with
ARM64_64K_PAGES config.

Raise the alignment passed to "alloc"mock_res()" to the larger of
SZ_256M and PMD_SIZE so that the mock CFMWS window is always at least as
well-aligned as "alloc_dax_region()" require.

Signed-off-by: Richard Cheng <icheng@nvidia.com>
Acked-by: Kai-Heng Feng <kaihengf@nvidia.com>
---
 tools/testing/cxl/test/cxl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 418669927fb0..b40e4bbcc958 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -497,7 +497,8 @@ static int populate_cedt(void)
 		struct acpi_cedt_cfmws *window = mock_cfmws[i];
 
 		cfmws_elc_update(window, i);
-		res = alloc_mock_res(window->window_size, SZ_256M);
+		res = alloc_mock_res(window->window_size,
+				     max_t(int, SZ_256M, PMD_SIZE));
 		if (!res)
 			return -ENOMEM;
 		window->base_hpa = res->range.start;
-- 
2.43.0
Re: [PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
Posted by Dave Jiang 4 days, 6 hours ago

On 5/19/26 4:35 PM, Richard Cheng wrote:
> cxl_test allocate synthetic CFMWS HPA windows out of a gen_pool and asks
> the allocator for SZ_256M alignment. It has been sufficient on x86 with
> 4k pages, arm64 with 4k pages since their PMD_SIZE are 2MB.
> 
> But for 64k-page arm64 kernel with CONFIG_ARM64_64K_PAGES=y and
> CONFIG_PGTABLE_LEVELS=3 , the PMD_SIZE is 512 MB, which is much larger
> than the alignment cxl_test guarantees. That results in every CXL region
> carved from that window inherits a mis-aligned start.
> 
> The DAX driver's cxl_dax_region_probe() then calls "alloc_dax_region()
> and the probe fails with -ENOMEM, with error message
> 
> """
>     cxl_dax_region dax_region1: probe with driver cxl_dax_region failed
>                                 with error -12
> """
> 
> It was hit while bringing up cxl_test on an ARM64 server with
> ARM64_64K_PAGES config.
> 
> Raise the alignment passed to "alloc"mock_res()" to the larger of
> SZ_256M and PMD_SIZE so that the mock CFMWS window is always at least as
> well-aligned as "alloc_dax_region()" require.

https://sashiko.dev/#/patchset/20260519233523.5991-1-icheng%40nvidia.com

Do you need to adjust length as well as alloc_dax_region() also checks length alignment?

DJ

> 
> Signed-off-by: Richard Cheng <icheng@nvidia.com>
> Acked-by: Kai-Heng Feng <kaihengf@nvidia.com>
> ---
>  tools/testing/cxl/test/cxl.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> index 418669927fb0..b40e4bbcc958 100644
> --- a/tools/testing/cxl/test/cxl.c
> +++ b/tools/testing/cxl/test/cxl.c
> @@ -497,7 +497,8 @@ static int populate_cedt(void)
>  		struct acpi_cedt_cfmws *window = mock_cfmws[i];
>  
>  		cfmws_elc_update(window, i);
> -		res = alloc_mock_res(window->window_size, SZ_256M);
> +		res = alloc_mock_res(window->window_size,
> +				     max_t(int, SZ_256M, PMD_SIZE));
>  		if (!res)
>  			return -ENOMEM;
>  		window->base_hpa = res->range.start;
Re: [PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
Posted by Richard Cheng 3 days, 21 hours ago
On Wed, May 20, 2026 at 11:18:23AM +0800, Dave Jiang wrote:
> 
> 
> On 5/19/26 4:35 PM, Richard Cheng wrote:
> > cxl_test allocate synthetic CFMWS HPA windows out of a gen_pool and asks
> > the allocator for SZ_256M alignment. It has been sufficient on x86 with
> > 4k pages, arm64 with 4k pages since their PMD_SIZE are 2MB.
> > 
> > But for 64k-page arm64 kernel with CONFIG_ARM64_64K_PAGES=y and
> > CONFIG_PGTABLE_LEVELS=3 , the PMD_SIZE is 512 MB, which is much larger
> > than the alignment cxl_test guarantees. That results in every CXL region
> > carved from that window inherits a mis-aligned start.
> > 
> > The DAX driver's cxl_dax_region_probe() then calls "alloc_dax_region()
> > and the probe fails with -ENOMEM, with error message
> > 
> > """
> >     cxl_dax_region dax_region1: probe with driver cxl_dax_region failed
> >                                 with error -12
> > """
> > 
> > It was hit while bringing up cxl_test on an ARM64 server with
> > ARM64_64K_PAGES config.
> > 
> > Raise the alignment passed to "alloc"mock_res()" to the larger of
> > SZ_256M and PMD_SIZE so that the mock CFMWS window is always at least as
> > well-aligned as "alloc_dax_region()" require.
> 
> https://sashiko.dev/#/patchset/20260519233523.5991-1-icheng%40nvidia.com
> 
> Do you need to adjust length as well as alloc_dax_region() also checks length alignment?
> 
> DJ
>

Hi Dave,

Thanks for the review. I think there're 2 things I would like to mention
* cfmws6's window_size is SZ_256M * 8UL, which is 2G, not 256M, only cfmws5 is 256M, so the
population in your scenario is narrower.
* The -ENOMEM comes from cxl_dax_region_probe() on the auto region, which carves mock_auto_region_size out of cfmws0,
which is 1G. On ARM64K_PAGES + PGTABLE_LEVELS=3, range_len == SZ_512M == PMD_SIZE and range.start == cfmws0.base_hpa.
Both length and start checks in alloc_dax_region() pass.

A region carved explicitly from cfmws5 with a non-PMD-aligned length would still be rejected, but that path was
already borken on this config and isn't exercised by cxl_test bringup.
I'll be happy to send a follow-up path that bumps cfmws5 to >=PMD_SIZE , if you think that case should be covered, too.
Though that's separate from the bug this patch addresses.

Best regards,
Richard Cheng.
 
> > 
> > Signed-off-by: Richard Cheng <icheng@nvidia.com>
> > Acked-by: Kai-Heng Feng <kaihengf@nvidia.com>
> > ---
> >  tools/testing/cxl/test/cxl.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> > index 418669927fb0..b40e4bbcc958 100644
> > --- a/tools/testing/cxl/test/cxl.c
> > +++ b/tools/testing/cxl/test/cxl.c
> > @@ -497,7 +497,8 @@ static int populate_cedt(void)
> >  		struct acpi_cedt_cfmws *window = mock_cfmws[i];
> >  
> >  		cfmws_elc_update(window, i);
> > -		res = alloc_mock_res(window->window_size, SZ_256M);
> > +		res = alloc_mock_res(window->window_size,
> > +				     max_t(int, SZ_256M, PMD_SIZE));
> >  		if (!res)
> >  			return -ENOMEM;
> >  		window->base_hpa = res->range.start;
>
Re: [PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
Posted by Alison Schofield 3 days, 18 hours ago
On Thu, May 21, 2026 at 11:09:09AM +0800, Richard Cheng wrote:
> On Wed, May 20, 2026 at 11:18:23AM +0800, Dave Jiang wrote:
> > 
> > 
> > On 5/19/26 4:35 PM, Richard Cheng wrote:
> > > cxl_test allocate synthetic CFMWS HPA windows out of a gen_pool and asks
> > > the allocator for SZ_256M alignment. It has been sufficient on x86 with
> > > 4k pages, arm64 with 4k pages since their PMD_SIZE are 2MB.
> > > 
> > > But for 64k-page arm64 kernel with CONFIG_ARM64_64K_PAGES=y and
> > > CONFIG_PGTABLE_LEVELS=3 , the PMD_SIZE is 512 MB, which is much larger
> > > than the alignment cxl_test guarantees. That results in every CXL region
> > > carved from that window inherits a mis-aligned start.
> > > 
> > > The DAX driver's cxl_dax_region_probe() then calls "alloc_dax_region()
> > > and the probe fails with -ENOMEM, with error message
> > > 
> > > """
> > >     cxl_dax_region dax_region1: probe with driver cxl_dax_region failed
> > >                                 with error -12
> > > """
> > > 
> > > It was hit while bringing up cxl_test on an ARM64 server with
> > > ARM64_64K_PAGES config.
> > > 
> > > Raise the alignment passed to "alloc"mock_res()" to the larger of
> > > SZ_256M and PMD_SIZE so that the mock CFMWS window is always at least as
> > > well-aligned as "alloc_dax_region()" require.
> > 
> > https://sashiko.dev/#/patchset/20260519233523.5991-1-icheng%40nvidia.com
> > 
> > Do you need to adjust length as well as alloc_dax_region() also checks length alignment?
> > 
> > DJ
> >
> 
> Hi Dave,
> 
> Thanks for the review. I think there're 2 things I would like to mention
> * cfmws6's window_size is SZ_256M * 8UL, which is 2G, not 256M, only cfmws5 is 256M, so the
> population in your scenario is narrower.
> * The -ENOMEM comes from cxl_dax_region_probe() on the auto region, which carves mock_auto_region_size out of cfmws0,
> which is 1G. On ARM64K_PAGES + PGTABLE_LEVELS=3, range_len == SZ_512M == PMD_SIZE and range.start == cfmws0.base_hpa.
> Both length and start checks in alloc_dax_region() pass.
> 
> A region carved explicitly from cfmws5 with a non-PMD-aligned length would still be rejected, but that path was
> already borken on this config and isn't exercised by cxl_test bringup.
> I'll be happy to send a follow-up path that bumps cfmws5 to >=PMD_SIZE , if you think that case should be covered, too.
> Though that's separate from the bug this patch addresses.
> 

Consider not limiting the scope of this fix to only what
is needed to load cxl-test module for arm64. Think of that
issue as a motivating example to create a new rule.

Would something like this work for you?

cxl/test: Enforce PMD alignment for volatile mock regions

Problem description stays as it is now.

Plan to resolve is a new rule like...

Every volatile mock CFMWS must be PMD aligned in start and size so 
DAX on RAM works on any supported page size config. The auto region
carved from cfmws0 takes size and offset from mock_auto_region_size,
so that value must be PMD aligned too.

And to enforce that rule do 3 things:
1. cfmws5's window_size becomes max(SZ_256M, PMD_SIZE)
2. populate_cedt() aligns volatile windows to max(SZ_256M, PMD_SIZE)
3. cxl_test_init() check mock_auto_region_size alignment

To be clear, this suggestion is to limit applying the alignment
to cfmws's w ACPI_CEDT_CFMWS_RESTRICT_VOLATILE. PMEM windows stay
at SZ_256M because IIUC they don't need PMD alignment.

-- Alison

> Best regards,
> Richard Cheng.
>  
> > > 
> > > Signed-off-by: Richard Cheng <icheng@nvidia.com>
> > > Acked-by: Kai-Heng Feng <kaihengf@nvidia.com>
> > > ---
> > >  tools/testing/cxl/test/cxl.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> > > index 418669927fb0..b40e4bbcc958 100644
> > > --- a/tools/testing/cxl/test/cxl.c
> > > +++ b/tools/testing/cxl/test/cxl.c
> > > @@ -497,7 +497,8 @@ static int populate_cedt(void)
> > >  		struct acpi_cedt_cfmws *window = mock_cfmws[i];
> > >  
> > >  		cfmws_elc_update(window, i);
> > > -		res = alloc_mock_res(window->window_size, SZ_256M);
> > > +		res = alloc_mock_res(window->window_size,
> > > +				     max_t(int, SZ_256M, PMD_SIZE));
> > >  		if (!res)
> > >  			return -ENOMEM;
> > >  		window->base_hpa = res->range.start;
> > 
>
Re: [PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
Posted by Richard Cheng 3 days, 17 hours ago
On Wed, May 20, 2026 at 10:26:04PM +0800, Alison Schofield wrote:
> On Thu, May 21, 2026 at 11:09:09AM +0800, Richard Cheng wrote:
> > On Wed, May 20, 2026 at 11:18:23AM +0800, Dave Jiang wrote:
> > > 
> > > 
> > > On 5/19/26 4:35 PM, Richard Cheng wrote:
> > > > cxl_test allocate synthetic CFMWS HPA windows out of a gen_pool and asks
> > > > the allocator for SZ_256M alignment. It has been sufficient on x86 with
> > > > 4k pages, arm64 with 4k pages since their PMD_SIZE are 2MB.
> > > > 
> > > > But for 64k-page arm64 kernel with CONFIG_ARM64_64K_PAGES=y and
> > > > CONFIG_PGTABLE_LEVELS=3 , the PMD_SIZE is 512 MB, which is much larger
> > > > than the alignment cxl_test guarantees. That results in every CXL region
> > > > carved from that window inherits a mis-aligned start.
> > > > 
> > > > The DAX driver's cxl_dax_region_probe() then calls "alloc_dax_region()
> > > > and the probe fails with -ENOMEM, with error message
> > > > 
> > > > """
> > > >     cxl_dax_region dax_region1: probe with driver cxl_dax_region failed
> > > >                                 with error -12
> > > > """
> > > > 
> > > > It was hit while bringing up cxl_test on an ARM64 server with
> > > > ARM64_64K_PAGES config.
> > > > 
> > > > Raise the alignment passed to "alloc"mock_res()" to the larger of
> > > > SZ_256M and PMD_SIZE so that the mock CFMWS window is always at least as
> > > > well-aligned as "alloc_dax_region()" require.
> > > 
> > > https://sashiko.dev/#/patchset/20260519233523.5991-1-icheng%40nvidia.com
> > > 
> > > Do you need to adjust length as well as alloc_dax_region() also checks length alignment?
> > > 
> > > DJ
> > >
> > 
> > Hi Dave,
> > 
> > Thanks for the review. I think there're 2 things I would like to mention
> > * cfmws6's window_size is SZ_256M * 8UL, which is 2G, not 256M, only cfmws5 is 256M, so the
> > population in your scenario is narrower.
> > * The -ENOMEM comes from cxl_dax_region_probe() on the auto region, which carves mock_auto_region_size out of cfmws0,
> > which is 1G. On ARM64K_PAGES + PGTABLE_LEVELS=3, range_len == SZ_512M == PMD_SIZE and range.start == cfmws0.base_hpa.
> > Both length and start checks in alloc_dax_region() pass.
> > 
> > A region carved explicitly from cfmws5 with a non-PMD-aligned length would still be rejected, but that path was
> > already borken on this config and isn't exercised by cxl_test bringup.
> > I'll be happy to send a follow-up path that bumps cfmws5 to >=PMD_SIZE , if you think that case should be covered, too.
> > Though that's separate from the bug this patch addresses.
> > 
> 
> Consider not limiting the scope of this fix to only what
> is needed to load cxl-test module for arm64. Think of that
> issue as a motivating example to create a new rule.
> 
> Would something like this work for you?
>

Hi Alison,

Thanks for the feedback, it sounds good for me.
 
> cxl/test: Enforce PMD alignment for volatile mock regions
> 
> Problem description stays as it is now.
> 
> Plan to resolve is a new rule like...
> 
> Every volatile mock CFMWS must be PMD aligned in start and size so 
> DAX on RAM works on any supported page size config. The auto region
> carved from cfmws0 takes size and offset from mock_auto_region_size,
> so that value must be PMD aligned too.
> 

Agree.

> And to enforce that rule do 3 things:
> 1. cfmws5's window_size becomes max(SZ_256M, PMD_SIZE)
> 2. populate_cedt() aligns volatile windows to max(SZ_256M, PMD_SIZE)
> 3. cxl_test_init() check mock_auto_region_size alignment
> 
> To be clear, this suggestion is to limit applying the alignment
> to cfmws's w ACPI_CEDT_CFMWS_RESTRICT_VOLATILE. PMEM windows stay
> at SZ_256M because IIUC they don't need PMD alignment.
> 
> -- Alison
> 

No problem, I'll amend these things and make the fix more generic
in version 2.

Best regards,
Richard Cheng.


> > Best regards,
> > Richard Cheng.
> >  
> > > > 
> > > > Signed-off-by: Richard Cheng <icheng@nvidia.com>
> > > > Acked-by: Kai-Heng Feng <kaihengf@nvidia.com>
> > > > ---
> > > >  tools/testing/cxl/test/cxl.c | 3 ++-
> > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> > > > index 418669927fb0..b40e4bbcc958 100644
> > > > --- a/tools/testing/cxl/test/cxl.c
> > > > +++ b/tools/testing/cxl/test/cxl.c
> > > > @@ -497,7 +497,8 @@ static int populate_cedt(void)
> > > >  		struct acpi_cedt_cfmws *window = mock_cfmws[i];
> > > >  
> > > >  		cfmws_elc_update(window, i);
> > > > -		res = alloc_mock_res(window->window_size, SZ_256M);
> > > > +		res = alloc_mock_res(window->window_size,
> > > > +				     max_t(int, SZ_256M, PMD_SIZE));
> > > >  		if (!res)
> > > >  			return -ENOMEM;
> > > >  		window->base_hpa = res->range.start;
> > > 
> >
Re: [PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
Posted by Dave Jiang 4 days, 9 hours ago

On 5/19/26 4:35 PM, Richard Cheng wrote:
> cxl_test allocate synthetic CFMWS HPA windows out of a gen_pool and asks
> the allocator for SZ_256M alignment. It has been sufficient on x86 with
> 4k pages, arm64 with 4k pages since their PMD_SIZE are 2MB.
> 
> But for 64k-page arm64 kernel with CONFIG_ARM64_64K_PAGES=y and
> CONFIG_PGTABLE_LEVELS=3 , the PMD_SIZE is 512 MB, which is much larger
> than the alignment cxl_test guarantees. That results in every CXL region
> carved from that window inherits a mis-aligned start.
> 
> The DAX driver's cxl_dax_region_probe() then calls "alloc_dax_region()
> and the probe fails with -ENOMEM, with error message
> 
> """
>     cxl_dax_region dax_region1: probe with driver cxl_dax_region failed
>                                 with error -12
> """
> 
> It was hit while bringing up cxl_test on an ARM64 server with
> ARM64_64K_PAGES config.
> 
> Raise the alignment passed to "alloc"mock_res()" to the larger of
> SZ_256M and PMD_SIZE so that the mock CFMWS window is always at least as
> well-aligned as "alloc_dax_region()" require.
> 
> Signed-off-by: Richard Cheng <icheng@nvidia.com>
> Acked-by: Kai-Heng Feng <kaihengf@nvidia.com>

Reviewed-by: Dave Jiang <dave.jiang@intel.com>

Does this need a fixes tag?

> ---
>  tools/testing/cxl/test/cxl.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> index 418669927fb0..b40e4bbcc958 100644
> --- a/tools/testing/cxl/test/cxl.c
> +++ b/tools/testing/cxl/test/cxl.c
> @@ -497,7 +497,8 @@ static int populate_cedt(void)
>  		struct acpi_cedt_cfmws *window = mock_cfmws[i];
>  
>  		cfmws_elc_update(window, i);
> -		res = alloc_mock_res(window->window_size, SZ_256M);
> +		res = alloc_mock_res(window->window_size,
> +				     max_t(int, SZ_256M, PMD_SIZE));
>  		if (!res)
>  			return -ENOMEM;
>  		window->base_hpa = res->range.start;