Re: [PATCH v2] cxl/acpi: Check ACPI companion before use
From: Jonathan Cameron
Date: Sun Sep 27 2026 - 18:52:05 EST
On Sat, 26 Sep 2026 15:16:05 +0800
Jiale Yao <yaojiale02@xxxxxxx> wrote:
> Platform drivers can be forced to match devices outside their ID tables
> through driver_override. cxl_acpi_probe() assumes that every bound device
> has an ACPI companion and dereferences adev->dev.bus without checking the
> result of ACPI_COMPANION(). Force-binding cxl_acpi to a platform device
> without a companion therefore causes a NULL pointer dereference.
>
Given I had this drawn to my attention earlier (thanks to Uwe)
let me draw attention to an attempt to add a flag to remove the need
for this sort of defense by blocking driver_override.
https://lore.kernel.org/lkml/20260922-driver-override-opt-out-v1-0-58c35ded3b83@xxxxxxxxxx/
So maybe we can replace what we do here once that lands.
In the meantime it's a valid bug so
Reviewed-by: Jonathan Cameron <jonathan.cameron@xxxxxxxxxxxxxxxx>
> This was reproduced by setting the driver override for the pcspkr platform
> device to cxl_acpi and binding it through sysfs:
>
> BUG: kernel NULL pointer dereference, address: 0000000000000280
> #PF: supervisor read access in kernel mode
> RIP: cxl_acpi_probe+0xf4/0x220
> Call Trace:
> platform_probe+0x4d/0x80
> really_probe+0x106/0x370
> device_driver_attach+0x4c/0xa0
> bind_store+0xd0/0x100
>
> Commit 2b3a5dabe89e ("platform/surface: acpi-notify: Check ACPI
> companion before use") fixed the same force-binding issue in another
> platform driver. Check the companion before setting up the CXL root and
> return -ENODEV when it is absent.
>
> Fixes: 7d4b5ca2e2cb ("cxl/acpi: Add downstream port data to cxl_port instances")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
> ---
>
> Notes:
> Changes in v2:
> - Move the ACPI companion assignment immediately before its NULL check.
> - Reorder local declarations in reverse Christmas tree order.
>
> drivers/cxl/acpi.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
> index 3b818adbd38b..fb09a5ff48c1 100644
> --- a/drivers/cxl/acpi.c
> +++ b/drivers/cxl/acpi.c
> @@ -885,13 +885,17 @@ static int pair_cxl_resource(struct device *dev, void *data)
>
> static int cxl_acpi_probe(struct platform_device *pdev)
> {
> - int rc;
> + struct cxl_cfmws_context ctx;
> + struct acpi_device *adev;
> struct resource *cxl_res;
> struct cxl_root *cxl_root;
> struct cxl_port *root_port;
> struct device *host = &pdev->dev;
> - struct acpi_device *adev = ACPI_COMPANION(host);
> - struct cxl_cfmws_context ctx;
> + int rc;
> +
> + adev = ACPI_COMPANION(host);
> + if (!adev)
> + return -ENODEV;
>
> device_lock_set_class(&pdev->dev, &cxl_root_key);
> rc = devm_add_action_or_reset(&pdev->dev, cxl_acpi_lock_reset_class,