Re: [PATCH] tools/testing/cxl: Align mock CFMWS to PMD_SIZE for ARM64 64K pages
From: Alison Schofield
Date: Thu May 21 2026 - 01:27:08 EST
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@xxxxxxxxxx>
> > > Acked-by: Kai-Heng Feng <kaihengf@xxxxxxxxxx>
> > > ---
> > > 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;
> >
>