All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery
@ 2026-06-21 17:32 Oz Tiram
  2026-06-21 17:50 ` sashiko-bot
  2026-06-21 18:01 ` Oz Tiram
  0 siblings, 2 replies; 4+ messages in thread
From: Oz Tiram @ 2026-06-21 17:32 UTC (permalink / raw)
  To: amd-gfx
  Cc: Oz Tiram, Alex Deucher, Christian König, David Airlie,
	Simona Vetter, open list:DRM DRIVERS, open list

APUs (e.g. AMD Radeon 780M / HawkPoint, PCI 1002:1900) have no
dedicated VBIOS ROM chip.  amdgpu_get_bios_apu() attempts four paths
before giving up:

  1. ACPI VFCT table
  2. VRAM BAR read
  3. ROM BAR read
  4. platform BIOS

On some systems all four fail:

  - The VFCT table is absent or contains only the discrete GPU entry
    (e.g. when a custom ACPI override is present for the dGPU only).
  - The VRAM BAR is unmapped at probe time.
  - The ROM BAR is zero (PCI firmware did not assign it; observed even
    with pci=realloc,assign-busses).
  - No platform BIOS mapping exists.

The driver then prints "Unable to locate a BIOS ROM" and refuses to
bind, leaving the APU completely unusable under Linux even though the
hardware is functional.

Add a fifth fallback: request a firmware file named
"amdgpu/<vendor>_<device>.bin" (e.g. "amdgpu/1002_1900.bin") via
request_firmware().  This allows a VBIOS image extracted from the
running hardware to be shipped as a firmware blob in /lib/firmware/ and
makes the binding succeed without any change to the ACPI tables.

The fallback is only reached if all existing paths have already failed,
so there is no regression risk for boards where VFCT or ROM BAR work.

Signed-off-by: Oz Tiram <oz@shift-computing.de>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index aa039e148a5e..491f88f495a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -26,6 +26,7 @@
  *          Jerome Glisse
  */
 
+#include <linux/firmware.h>
 #include "amdgpu.h"
 #include "atom.h"
 
@@ -457,6 +458,24 @@ static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
 		goto success;
 	}
 
+	{
+		const struct firmware *fw;
+		char fw_name[32];
+
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%04x_%04x.bin",
+			 adev->pdev->vendor, adev->pdev->device);
+		if (request_firmware(&fw, fw_name, adev->dev) == 0) {
+			adev->bios = kmemdup(fw->data, fw->size, GFP_KERNEL);
+			adev->bios_size = fw->size;
+			release_firmware(fw);
+			if (adev->bios) {
+				dev_info(adev->dev, "Fetched VBIOS from firmware file %s\n",
+					 fw_name);
+				goto success;
+			}
+		}
+	}
+
 	dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
 	return false;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery
  2026-06-21 17:32 [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery Oz Tiram
@ 2026-06-21 17:50 ` sashiko-bot
  2026-06-21 18:01 ` Oz Tiram
  1 sibling, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-21 17:50 UTC (permalink / raw)
  To: Oz Tiram; +Cc: dri-devel

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] The firmware file fallback for APU VBIOS discovery does not validate the loaded firmware with `check_atom_bios()`, potentially leading to a kernel panic or out-of-bounds reads.

Pre-existing issues:
- [High] Pre-existing off-by-one boundary checks in `check_atom_bios()` allow out-of-bounds memory reads when evaluating truncated or malformed VBIOS images.
--

commit 3e01d007e8160f9d82a04903ddd4a636561ac6f7
Author: Oz Tiram <oz@shift-computing.de>

drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery

This patch adds a fifth fallback path for APU VBIOS discovery using a
firmware file loaded via request_firmware(). This allows a VBIOS image
extracted from running hardware to be used when other methods like VFCT
or ROM BAR fail.

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> index aa039e148a5ee..491f88f495a66 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c

[ ... ]

> @@ -457,6 +458,24 @@ static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
>  		goto success;
>  	}
>  
> +	{
> +		const struct firmware *fw;
> +		char fw_name[32];
> +
> +		snprintf(fw_name, sizeof(fw_name), "amdgpu/%04x_%04x.bin",
> +			 adev->pdev->vendor, adev->pdev->device);
> +		if (request_firmware(&fw, fw_name, adev->dev) == 0) {
> +			adev->bios = kmemdup(fw->data, fw->size, GFP_KERNEL);
> +			adev->bios_size = fw->size;
> +			release_firmware(fw);
> +			if (adev->bios) {

[Severity: High]
Does this new firmware fallback path need to validate the fetched memory using
check_atom_bios()?

All other VBIOS discovery paths appear to validate the fetched memory before
accepting the BIOS image. If the provided firmware file is empty (size 0),
kmemdup() returns ZERO_SIZE_PTR (which evaluates to true). The driver will
later dereference this pointer during ATOM BIOS parsing, which could cause a
kernel page fault.

Additionally, if the firmware is malformed or undersized, the ATOM BIOS parser
could read out-of-bounds.

[Severity: High]
This is a pre-existing issue, but check_atom_bios() appears to have off-by-one
boundary checks that can allow out-of-bounds memory reads when evaluating
malformed or truncated VBIOS images:

drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c:check_atom_bios() {
    ...
	if (!bios || size < 0x49) {
		dev_dbg(adev->dev, "VBIOS mem is null or mem size is wrong\n");
		return false;
	}

	...

	bios_header_start = bios[0x48] | (bios[0x49] << 8);
    ...
}

If size is exactly 0x49 (73 bytes), the check size < 0x49 passes, but the code
then accesses bios[0x49], which is the 74th byte, resulting in a 1-byte
out-of-bounds read.

There is another similar boundary check later in the same function:

drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c:check_atom_bios() {
    ...
	tmp = bios_header_start + 4;
	if (size < tmp) {
		dev_dbg(adev->dev, "VBIOS header is broken\n");
		return false;
	}

	if (!memcmp(bios + tmp, "ATOM", 4) ||
    ...
}

If the buffer size is exactly equal to tmp, size < tmp passes, but the
subsequent memcmp() reads 4 bytes starting at tmp, which is completely past
the end of the allocated buffer. Can these boundary checks be updated to
prevent KASAN out-of-bounds warnings when parsing VBIOS blobs?

> +				dev_info(adev->dev, "Fetched VBIOS from firmware file %s\n",
> +					 fw_name);
> +				goto success;
> +			}
> +		}
> +	}
> +
>  	dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
>  	return false;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260621173211.28443-1-oz@shift-computing.de?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery
  2026-06-21 17:32 [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery Oz Tiram
  2026-06-21 17:50 ` sashiko-bot
@ 2026-06-21 18:01 ` Oz Tiram
  2026-06-21 18:09   ` sashiko-bot
  1 sibling, 1 reply; 4+ messages in thread
From: Oz Tiram @ 2026-06-21 18:01 UTC (permalink / raw)
  To: amd-gfx
  Cc: Oz Tiram, Alex Deucher, Christian König, David Airlie,
	Simona Vetter, open list:DRM DRIVERS, open list

APUs (e.g. AMD Radeon 780M / HawkPoint, PCI 1002:1900) have no
dedicated VBIOS ROM chip.  amdgpu_get_bios_apu() attempts four paths
before giving up:

  1. ACPI VFCT table
  2. VRAM BAR read
  3. ROM BAR read
  4. platform BIOS

On some systems all four fail:

  - The VFCT table is absent or contains only the discrete GPU entry
    (e.g. when a custom ACPI override is present for the dGPU only).
  - The VRAM BAR is unmapped at probe time.
  - The ROM BAR is zero (PCI firmware did not assign it; observed even
    with pci=realloc,assign-busses).
  - No platform BIOS mapping exists.

The driver then prints "Unable to locate a BIOS ROM" and refuses to
bind, leaving the APU completely unusable under Linux even though the
hardware is functional.

Add a fifth fallback: request a firmware file named
"amdgpu/<vendor>_<device>.bin" (e.g. "amdgpu/1002_1900.bin") via
request_firmware().  This allows a VBIOS image extracted from the
running hardware to be shipped as a firmware blob in /lib/firmware/ and
makes the binding succeed without any change to the ACPI tables.

The fallback is only reached if all existing paths have already failed,
so there is no regression risk for boards where VFCT or ROM BAR work.

Signed-off-by: Oz Tiram <oz@shift-computing.de>
---
v2: Validate the fetched firmware with check_atom_bios() before accepting
    it, consistent with all other VBIOS discovery paths.  Save fw->size
    before release_firmware() so it remains valid for the size check.
    Release the buffer via amdgpu_bios_release() if validation fails.

 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index aa039e148a5e..86064c753b09 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -26,6 +26,7 @@
  *          Jerome Glisse
  */
 
+#include <linux/firmware.h>
 #include "amdgpu.h"
 #include "atom.h"
 
@@ -457,6 +458,28 @@ static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
 		goto success;
 	}
 
+	{
+		const struct firmware *fw;
+		char fw_name[32];
+		size_t fw_size;
+
+		snprintf(fw_name, sizeof(fw_name), "amdgpu/%04x_%04x.bin",
+			 adev->pdev->vendor, adev->pdev->device);
+		if (request_firmware(&fw, fw_name, adev->dev) == 0) {
+			adev->bios = kmemdup(fw->data, fw->size, GFP_KERNEL);
+			fw_size = fw->size;
+			release_firmware(fw);
+			if (!adev->bios || !check_atom_bios(adev, fw_size)) {
+				amdgpu_bios_release(adev);
+			} else {
+				adev->bios_size = fw_size;
+				dev_info(adev->dev, "Fetched VBIOS from firmware file %s\n",
+					 fw_name);
+				goto success;
+			}
+		}
+	}
+
 	dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
 	return false;
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery
  2026-06-21 18:01 ` Oz Tiram
@ 2026-06-21 18:09   ` sashiko-bot
  0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-21 18:09 UTC (permalink / raw)
  To: Oz Tiram; +Cc: dri-devel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Out-of-bounds reads in `check_atom_bios` when validating VBIOS headers, made directly reachable via the new user-supplied firmware file fallback.
--

commit a2fe12b488b874804f022bf152336e0c586847dc
Author: Oz Tiram <oz@shift-computing.de>

drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery

This commit adds a fifth fallback method to discover an APU VBIOS by
requesting a firmware file when all other methods fail. The fallback uses
request_firmware() and allocates the VBIOS buffer using kmemdup() with the
exact firmware size.

> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> index aa039e148a5ee..86064c753b099 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
[ ... ]
> @@ -457,6 +458,28 @@ static bool amdgpu_get_bios_apu(struct amdgpu_device *adev)
>  		goto success;
>  	}
>  
> +	{
> +		const struct firmware *fw;
> +		char fw_name[32];
> +		size_t fw_size;
> +
> +		snprintf(fw_name, sizeof(fw_name), "amdgpu/%04x_%04x.bin",
> +			 adev->pdev->vendor, adev->pdev->device);
> +		if (request_firmware(&fw, fw_name, adev->dev) == 0) {
> +			adev->bios = kmemdup(fw->data, fw->size, GFP_KERNEL);
> +			fw_size = fw->size;
> +			release_firmware(fw);
> +			if (!adev->bios || !check_atom_bios(adev, fw_size)) {

[Severity: High]
This isn't a bug introduced by this patch, but allocating the buffer to the
exact firmware size via kmemdup() exposes existing out-of-bounds reads in
check_atom_bios().

Looking at check_atom_bios(), the initial size check is:

    if (!bios || size < 0x49) {
        ...
        return false;
    }

But then it reads bios[0x49]:

    bios_header_start = bios[0x48] | (bios[0x49] << 8);

If fw_size is exactly 0x49, bios[0x49] reads 1 byte past the end of the
kmemdup() buffer.

Similarly, check_atom_bios() later checks size against tmp before reading
4 bytes for the ATOM signature:

    tmp = bios_header_start + 4;
    if (size < tmp) {
        ...
        return false;
    }

    if (!memcmp(bios + tmp, "ATOM", 4) ||
        !memcmp(bios + tmp, "MOTA", 4)) {

If size is exactly tmp (or up to tmp + 3), memcmp() will read up to 4 bytes
past the end of the allocation. 

Could a malformed firmware file loaded through this new path trigger KASAN
slab-out-of-bounds warnings or page faults due to these bounds checks?

> +				amdgpu_bios_release(adev);
> +			} else {
> +				adev->bios_size = fw_size;
> +				dev_info(adev->dev, "Fetched VBIOS from firmware file %s\n",
> +					 fw_name);
> +				goto success;
> +			}
> +		}
> +	}
> +
>  	dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
>  	return false;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260621180154.30421-1-oz@shift-computing.de?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-21 18:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-21 17:32 [PATCH] drm/amd/amdgpu: add firmware file fallback for APU VBIOS discovery Oz Tiram
2026-06-21 17:50 ` sashiko-bot
2026-06-21 18:01 ` Oz Tiram
2026-06-21 18:09   ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.