firmware_loader: built-in API and make x86 use it
Subsystems (11)
Luis R. Rodriguez
maintainercover firmware_loader: built-in API and make x86 use it
From: Luis Chamberlain <[email protected]>
A while ago I noted to Boris how we could likely do away the odd direct use of the firmware sections on x86 and instead have it use the API directly. This indeed was possible but it required quite a bit of spring cleaning as well and on its way I spotted a small fix.
This goes with a new series of tests against built-in firmware as well. Boris has confirmed this also does work for the x86 microcode loader. 0day is happy with the build results. You can find these changes on my git tree branch 20210916-firmware-builtin-v2 [0].
Borislav Petkov (1):
x86/microcode: Use the firmware_loader built-in API
Luis Chamberlain (13):
firmware_loader: fix pre-allocated buf built-in firmware use
firmware_loader: split built-in firmware call
firmware_loader: add a sanity check for firmware_request_builtin()
firmware_loader: add built-in firmware kconfig entry
firmware_loader: formalize built-in firmware API
firmware_loader: remove old DECLARE_BUILTIN_FIRMWARE()
firmware_loader: move struct builtin_fw to the only place used vmlinux.lds.h: wrap built-in firmware support under its kconfig symbol x86/build: Tuck away built-in firmware under its kconfig symbol
firmware_loader: rename EXTRA_FIRMWARE and EXTRA_FIRMWARE_DIR
firmware_loader: move builtin build helper to shared library
test_firmware: move a few test knobs out to its library
test_firmware: add support for testing built-in firmware
.../driver-api/firmware/built-in-fw.rst | 8 +- Documentation/x86/microcode.rst | 9 +- arch/x86/Kconfig | 4 +- arch/x86/include/asm/microcode.h | 3 - arch/x86/kernel/cpu/microcode/amd.c | 14 ++- arch/x86/kernel/cpu/microcode/core.c | 17 --- arch/x86/kernel/cpu/microcode/intel.c | 9 +- arch/x86/tools/relocs.c | 2 + drivers/base/firmware_loader/Kconfig | 39 ++++--- drivers/base/firmware_loader/Makefile | 4 +- drivers/base/firmware_loader/builtin/Makefile | 43 ++------ .../base/firmware_loader/builtin/lib.Makefile | 32 ++++++ drivers/base/firmware_loader/builtin/main.c | 101 ++++++++++++++++++ drivers/base/firmware_loader/firmware.h | 17 +++ drivers/base/firmware_loader/main.c | 65 +---------- .../firmware_loader/test-builtin/.gitignore | 3 + .../firmware_loader/test-builtin/Makefile | 18 ++++ drivers/staging/media/av7110/Kconfig | 4 +- include/asm-generic/vmlinux.lds.h | 20 ++-- include/linux/firmware.h | 26 ++--- lib/Kconfig.debug | 34 ++++++ lib/test_firmware.c | 52 ++++++++- .../testing/selftests/firmware/fw_builtin.sh | 69 ++++++++++++ .../selftests/firmware/fw_filesystem.sh | 16 --- tools/testing/selftests/firmware/fw_lib.sh | 24 +++++ .../selftests/firmware/fw_run_tests.sh | 2 + 26 files changed, 447 insertions(+), 188 deletions(-) create mode 100644 drivers/base/firmware_loader/builtin/lib.Makefile create mode 100644 drivers/base/firmware_loader/builtin/main.c create mode 100644 drivers/base/firmware_loader/test-builtin/.gitignore create mode 100644 drivers/base/firmware_loader/test-builtin/Makefile create mode 100755 tools/testing/selftests/firmware/fw_builtin.sh
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 1/14 firmware_loader: fix pre-allocated buf built-in firmware use
From: Luis Chamberlain <[email protected]>
The firmware_loader can be used with a pre-allocated buffer through the use of the API calls:
o request_firmware_into_buf()
o request_partial_firmware_into_buf()
If the firmware was built-in and present, our current check for if the built-in firmware fits into the pre-allocated buffer does not return any errors, and we proceed to tell the caller that everything worked fine. It's a lie and no firmware would end up being copied into the pre-allocated buffer. So if the caller trust the result it may end up writing a bunch of 0's to a device!
Fix this by making the function that checks for the pre-allocated buffer return non-void. Since the typical use case is when no pre-allocated buffer is provided make this return successfully for that case. If the built-in firmware does *not* fit into the pre-allocated buffer size return a failure as we should have been doing before.
I'm not aware of users of the built-in firmware using the API calls with a pre-allocated buffer, as such I doubt this fixes any real life issue. But you never know... perhaps some oddball private tree might use it.
In so far as upstream is concerned this just fixes our code for correctness.
--- drivers/base/firmware_loader/main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/base/firmware_loader/main.c +7 -6
@@ -100,12 +100,15 @@ static struct firmware_cache fw_cache;extern struct builtin_fw __start_builtin_fw[];extern struct builtin_fw __end_builtin_fw[]; -static void fw_copy_to_prealloc_buf (struct firmware *fw, +static bool fw_copy_to_prealloc_buf (struct firmware *fw,void *buf,size_t size) { -if (!buf || size < fw->size) -return ; +if (!buf) +return true; +if (size < fw->size) +return false;memcpy (buf, fw->data, fw->size); +return true; } static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
@@ -117,9 +120,7 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,if (strcmp (name, b_fw->name) ==0 ) { fw->size = b_fw->size; fw->data = b_fw->data; -fw_copy_to_prealloc_buf (fw, buf, size); - -return true; +return fw_copy_to_prealloc_buf (fw, buf, size); } }
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 2/14 firmware_loader: split built-in firmware call
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
There are two ways the firmware_loader can use the built-in
firmware: with or without the pre-allocated buffer. We already have one explicit use case for each of these, and so split them up so that it is clear what the intention is on the caller side.
This also paves the way so that eventually other callers outside of the firmware loader can uses these if and when needed.
While at it, adopt the firmware prefix for the routine names.
--- drivers/base/firmware_loader/main.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/base/firmware_loader/main.c +21 -8
@@ -111,8 +111,7 @@ static bool fw_copy_to_prealloc_buf(struct firmware *fw,return true; } -static bool fw_get_builtin_firmware (struct firmware *fw,const char *name, -void *buf,size_t size) +static bool firmware_request_builtin (struct firmware *fw,const char *name) {struct builtin_fw *b_fw;
@@ -120,13 +119,21 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,if (strcmp (name, b_fw->name) ==0 ) { fw->size = b_fw->size; fw->data = b_fw->data; -return fw_copy_to_prealloc_buf (fw, buf, size); +return true; } }return false; } +static bool firmware_request_builtin_buf (struct firmware *fw,const char *name, +void *buf,size_t size) +{ +if (!firmware_request_builtin (fw, name)) +return false; +return fw_copy_to_prealloc_buf (fw, buf, size); +} +static bool fw_is_builtin_firmware (const struct firmware *fw) {struct builtin_fw *b_fw;
@@ -140,9 +147,15 @@ static bool fw_is_builtin_firmware(const struct firmware *fw)#else /* Module case - no builtin firmware support */ -static inline bool fw_get_builtin_firmware (struct firmware *fw, -const char *name,void *buf, -size_t size) +static inline bool firmware_request_builtin (struct firmware *fw, +const char *name) +{ +return false; +} + +static inline bool firmware_request_builtin_buf (struct firmware *fw, +const char *name,void *buf, +size_t size) {return false; }
@@ -737,7 +750,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,return -ENOMEM ; } -if (fw_get_builtin_firmware (firmware, name, dbuf, size)) { +if (firmware_request_builtin_buf (firmware, name, dbuf, size)) {dev_dbg (device,"using built-in %s\n" , name);return 0 ;/* assigned */ }
@@ -1216,7 +1229,7 @@ static int uncache_firmware(const char *fw_name)pr_debug ("%s: %s\n" , __func__, fw_name); -if (fw_get_builtin_firmware (&fw, fw_name,NULL ,0 )) +if (firmware_request_builtin (&fw, fw_name))return 0 ; fw_priv =lookup_fw_priv (fw_name);
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 3/14 firmware_loader: add a sanity check for firmware_request_builtin()
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
Right now firmware_request_builtin() is used internally only and so we have control over the callers. But if we want to expose that API more broadly we should ensure the firmware pointer is valid.
This doesn't fix any known issue, it just prepares us to later expose this API to other users.
--- drivers/base/firmware_loader/main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/base/firmware_loader/main.c +3 -0
@@ -115,6 +115,9 @@ static bool firmware_request_builtin(struct firmware *fw, const char *name) {struct builtin_fw *b_fw; +if (!fw) +return false; +for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {if (strcmp (name, b_fw->name) ==0 ) { fw->size = b_fw->size;
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 4/14 firmware_loader: add built-in firmware kconfig entry
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
The built-in firmware is always supported when a user enables FW_LOADER=y today, that is, it is built-in to the kernel. When the firmware loader is built as a module, support for built-in firmware is skipped. This requirement is not really clear to users or even developers.
Also, by default the EXTRA_FIRMWARE is always set to an empty string and so by default we really have nothing built-in to that kernel's sections for built-in firmware, so today a all FW_LOADER=y kernels spins their wheels on an empty set of built-in firmware for each firmware request with no true need for it.
Add a new kconfig entry to represent built-in firmware support more clearly. This let's knock 3 birds with one stone:
o Clarifies that support for built-in firmware requires the firmware loader to be built-in to the kernel
o By default we now always skip built-in firmware even if a FW_LOADER=y
o This also lets us make it clear that the EXTRA_FIRMWARE_DIR kconfig entry is only used for built-in firmware
--- .../driver-api/firmware/built-in-fw.rst | 2 ++ Documentation/x86/microcode.rst | 5 ++-- drivers/base/firmware_loader/Kconfig | 25 +++++++++++++------ drivers/base/firmware_loader/Makefile | 3 +-- drivers/base/firmware_loader/main.c | 4 +-- 5 files changed, 26 insertions(+), 13 deletions(-)
Documentation/driver-api/firmware/built-in-fw.rst +2 -0
@@ -8,6 +8,7 @@ the filesystem. Instead, firmware can be looked for inside the kernel directly. You can enable built-in firmware using the kernel configuration options: + * CONFIG_FW_LOADER_BUILTIN * CONFIG_EXTRA_FIRMWARE * CONFIG_EXTRA_FIRMWARE_DIR
@@ -17,6 +18,7 @@ into the kernel with CONFIG_EXTRA_FIRMWARE: * Speed * Firmware is needed for accessing the boot device, and the user doesn't want to stuff the firmware into the boot initramfs. +* Testing built-in firmware Even if you have these needs there are a few reasons why you may not be able to make use of built-in firmware:
Documentation/x86/microcode.rst +3 -2
@@ -114,11 +114,12 @@ Builtin microcode ================= The loader supports also loading of a builtin microcode supplied through -the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is -currently supported. +the regular builtin firmware method using CONFIG_FW_LOADER_BUILTIN and +CONFIG_EXTRA_FIRMWARE. Only 64-bit is currently supported. Here's an example:: + CONFIG_FW_LOADER_BUILTIN=y CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"
drivers/base/firmware_loader/Kconfig +18 -7
@@ -29,8 +29,10 @@ if FW_LOADER config FW_LOADER_PAGED_BUF bool -config EXTRA_FIRMWARE - string "Build named firmware blobs into the kernel binary" +config FW_LOADER_BUILTIN + bool "Enable support for built-in firmware" + default n + depends on FW_LOADER=y help Device drivers which require firmware can typically deal with having the kernel load firmware from the various supported
@@ -43,7 +45,14 @@ config EXTRA_FIRMWARE in boot and cannot rely on the firmware being placed in an initrd or initramfs. - This option is a string and takes the (space-separated) names of the + Support for built-in firmware is not supported if you are using + the firmware loader as a module. + +config EXTRA_FIRMWARE + string "Build named firmware blobs into the kernel binary" + depends on FW_LOADER_BUILTIN + help + This option is a string and takes the space-separated names of the firmware files -- the same names that appear in MODULE_FIRMWARE() and request_firmware() in the source. These files should exist under the directory specified by the EXTRA_FIRMWARE_DIR option, which is
@@ -61,12 +70,14 @@ config EXTRA_FIRMWARE consult a lawyer of your own before distributing such an image. config EXTRA_FIRMWARE_DIR - string "Firmware blobs root directory" - depends on EXTRA_FIRMWARE != "" + string "Directory with firmware to be built-in to the kernel" + depends on FW_LOADER_BUILTIN default "/lib/firmware" help - This option controls the directory in which the kernel build system - looks for the firmware files listed in the EXTRA_FIRMWARE option. + This option specifies the directory which the kernel build system + will use to look for the firmware files which are going to be + built into the kernel using the space-separated EXTRA_FIRMWARE + entries. config FW_LOADER_USER_HELPER bool "Enable the firmware sysfs fallback mechanism"
drivers/base/firmware_loader/Makefile +1 -2
@@ -1,10 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for the Linux firmware loader +obj-$(CONFIG_FW_LOADER_BUILTIN) += builtin/ obj-$(CONFIG_FW_LOADER_USER_HELPER) += fallback_table.o obj-$(CONFIG_FW_LOADER) += firmware_class.o firmware_class-objs := main.o firmware_class-$(CONFIG_FW_LOADER_USER_HELPER) += fallback.o firmware_class-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += fallback_platform.o - -obj-y += builtin/
drivers/base/firmware_loader/main.c +2 -2
@@ -95,7 +95,7 @@ static struct firmware_cache fw_cache;/* Builtin firmware support */ -#ifdef CONFIG_FW_LOADER +#ifdef CONFIG_FW_LOADER_BUILTIN extern struct builtin_fw __start_builtin_fw[];extern struct builtin_fw __end_builtin_fw[];
@@ -148,7 +148,7 @@ static bool fw_is_builtin_firmware(const struct firmware *fw) return false; } -#else /* Module case - no builtin firmware support */ +#else static inline bool firmware_request_builtin (struct firmware *fw,const char *name)
Signature · 1 line
2.30.2
Greg KH
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 79 lines · Luis R. Rodriguez
From: Luis Chamberlain <[email protected]>
The built-in firmware is always supported when a user enables FW_LOADER=y today, that is, it is built-in to the kernel. When the firmware loader is built as a module, support for built-in firmware is skipped. This requirement is not really clear to users or even developers.
Also, by default the
EXTRA_FIRMWAREis always set to an empty string and so by default we really have nothing built-in to that kernel's sections for built-in firmware, so today a all FW_LOADER=y kernels spins their wheels on an empty set of built-in firmware for each firmware request with no true need for it.Add a new kconfig entry to represent built-in firmware support more clearly. This let's knock 3 birds with one stone:
o Clarifies that support for built-in firmware requires the firmware loader to be built-in to the kernel
o By default we now always skip built-in firmware even if a FW_LOADER=y
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmwareReviewed-by Borislav Petkov <[email protected]>Signed-off-by Luis Chamberlain <[email protected]>--- .../driver-api/firmware/built-in-fw.rst | 2 ++ Documentation/x86/microcode.rst | 5 ++-- drivers/base/firmware_loader/Kconfig | 25 +++++++++++++------ drivers/base/firmware_loader/Makefile | 3 +-- drivers/base/firmware_loader/main.c | 4 +-- 5 files changed, 26 insertions(+), 13 deletions(-)Documentation/driver-api/firmware/built-in-fw.rst +2
-0@@ -8,6 +8,7 @@ the filesystem. Instead, firmware can be looked for inside the kernel directly. You can enable built-in firmware using the kernel configuration options: + * CONFIG_FW_LOADER_BUILTIN * CONFIG_EXTRA_FIRMWARE * CONFIG_EXTRA_FIRMWARE_DIR@@ -17,6 +18,7 @@ into the kernel with CONFIG_EXTRA_FIRMWARE: * Speed * Firmware is needed for accessing the boot device, and the user doesn't want to stuff the firmware into the boot initramfs. +* Testing built-in firmware Even if you have these needs there are a few reasons why you may not be able to make use of built-in firmware:Documentation/x86/microcode.rst +3
-2@@ -114,11 +114,12 @@ Builtin microcode ================= The loader supports also loading of a builtin microcode supplied through -the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is -currently supported. +the regular builtin firmware method using CONFIG_FW_LOADER_BUILTIN and +CONFIG_EXTRA_FIRMWARE. Only 64-bit is currently supported. Here's an example:: + CONFIG_FW_LOADER_BUILTIN=y CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"drivers/base/firmware_loader/Kconfig +0
-0
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 34
Quoted 8 lines
drivers/base/firmware_loader/Kconfig +3
-2@@ -29,8 +29,10 @@ if FW_LOADER config FW_LOADER_PAGED_BUF bool -config EXTRA_FIRMWARE - string "Build named firmware blobs into the kernel binary" +config FW_LOADER_BUILTIN + bool "Enable support for built-in firmware" + default n
n is always the default, no need to list it again.
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 35
Quoted 1 line
drivers/base/firmware_loader/Kconfig +1
-0+ depends on FW_LOADER=y
I don't see what this gets us to add another config option. Are you making things easier later on?
Anyway, I took the first 3 patches here, please fix this up and rebase and resend.
thanks,
greg k-h
Luis Chamberlain
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 83 lines · Greg KH
Quoted 82 lines · Luis R. Rodriguez
From: Luis Chamberlain <[email protected]>
The built-in firmware is always supported when a user enables FW_LOADER=y today, that is, it is built-in to the kernel. When the firmware loader is built as a module, support for built-in firmware is skipped. This requirement is not really clear to users or even developers.
Also, by default the
EXTRA_FIRMWAREis always set to an empty string and so by default we really have nothing built-in to that kernel's sections for built-in firmware, so today a all FW_LOADER=y kernels spins their wheels on an empty set of built-in firmware for each firmware request with no true need for it.Add a new kconfig entry to represent built-in firmware support more clearly. This let's knock 3 birds with one stone:
o Clarifies that support for built-in firmware requires the firmware loader to be built-in to the kernel
o By default we now always skip built-in firmware even if a FW_LOADER=y
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmwareReviewed-by Borislav Petkov <[email protected]>Signed-off-by Luis Chamberlain <[email protected]>--- .../driver-api/firmware/built-in-fw.rst | 2 ++ Documentation/x86/microcode.rst | 5 ++-- drivers/base/firmware_loader/Kconfig | 25 +++++++++++++------ drivers/base/firmware_loader/Makefile | 3 +-- drivers/base/firmware_loader/main.c | 4 +-- 5 files changed, 26 insertions(+), 13 deletions(-)Documentation/driver-api/firmware/built-in-fw.rst +2
-0@@ -8,6 +8,7 @@ the filesystem. Instead, firmware can be looked for inside the kernel directly. You can enable built-in firmware using the kernel configuration options: + * CONFIG_FW_LOADER_BUILTIN * CONFIG_EXTRA_FIRMWARE * CONFIG_EXTRA_FIRMWARE_DIR@@ -17,6 +18,7 @@ into the kernel with CONFIG_EXTRA_FIRMWARE: * Speed * Firmware is needed for accessing the boot device, and the user doesn't want to stuff the firmware into the boot initramfs. +* Testing built-in firmware Even if you have these needs there are a few reasons why you may not be able to make use of built-in firmware:Documentation/x86/microcode.rst +3
-2@@ -114,11 +114,12 @@ Builtin microcode ================= The loader supports also loading of a builtin microcode supplied through -the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is -currently supported. +the regular builtin firmware method using CONFIG_FW_LOADER_BUILTIN and +CONFIG_EXTRA_FIRMWARE. Only 64-bit is currently supported. Here's an example:: + CONFIG_FW_LOADER_BUILTIN=y CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"drivers/base/firmware_loader/Kconfig +0
-0@@ -29,8 +29,10 @@ if FW_LOADER config FW_LOADER_PAGED_BUF bool
Quoted 7 lines
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 34
Quoted 5 lines
drivers/base/firmware_loader/Kconfig +3
-2-config EXTRA_FIRMWARE - string "Build named firmware blobs into the kernel binary" +config FW_LOADER_BUILTIN + bool "Enable support for built-in firmware" + default nn is always the default, no need to list it again.
Oh, alrighty, I'll remove that line.
Quoted 4 lines
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 35
Quoted 1 line
drivers/base/firmware_loader/Kconfig +1
-0+ depends on FW_LOADER=yI don't see what this gets us to add another config option. Are you making things easier later on?
This makes a few things clearer for both developers and users. The code in question is a *feature* *only* when FW_LOADER=y, by adding a new kconfig to represent this and clearly makeing it depend on FW_LOADER=y it let's us:
o Clarify that support for built-in firmware requires
the firmware loader to be built-in to the kernel
o By default we now always skip built-in firmware even if a FW_LOADER=y
o This also lets us make it clear that the EXTRA_FIRMWARE_DIR kconfig entry is only used for built-in firmware
The above is not easily obvious to developers (including myself when I was reviewing this code) or users without this new kconfig entry.
Should I re-send by just removing the one line you asked for?
Luis
Greg KH
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 99 lines · Luis Chamberlain
Quoted 83 lines · Greg KH
Quoted 82 lines · Luis R. Rodriguez
From: Luis Chamberlain <[email protected]>
The built-in firmware is always supported when a user enables FW_LOADER=y today, that is, it is built-in to the kernel. When the firmware loader is built as a module, support for built-in firmware is skipped. This requirement is not really clear to users or even developers.
Also, by default the
EXTRA_FIRMWAREis always set to an empty string and so by default we really have nothing built-in to that kernel's sections for built-in firmware, so today a all FW_LOADER=y kernels spins their wheels on an empty set of built-in firmware for each firmware request with no true need for it.Add a new kconfig entry to represent built-in firmware support more clearly. This let's knock 3 birds with one stone:
o Clarifies that support for built-in firmware requires the firmware loader to be built-in to the kernel
o By default we now always skip built-in firmware even if a FW_LOADER=y
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmwareReviewed-by Borislav Petkov <[email protected]>Signed-off-by Luis Chamberlain <[email protected]>--- .../driver-api/firmware/built-in-fw.rst | 2 ++ Documentation/x86/microcode.rst | 5 ++-- drivers/base/firmware_loader/Kconfig | 25 +++++++++++++------ drivers/base/firmware_loader/Makefile | 3 +-- drivers/base/firmware_loader/main.c | 4 +-- 5 files changed, 26 insertions(+), 13 deletions(-)Documentation/driver-api/firmware/built-in-fw.rst +2
-0@@ -8,6 +8,7 @@ the filesystem. Instead, firmware can be looked for inside the kernel directly. You can enable built-in firmware using the kernel configuration options: + * CONFIG_FW_LOADER_BUILTIN * CONFIG_EXTRA_FIRMWARE * CONFIG_EXTRA_FIRMWARE_DIR@@ -17,6 +18,7 @@ into the kernel with CONFIG_EXTRA_FIRMWARE: * Speed * Firmware is needed for accessing the boot device, and the user doesn't want to stuff the firmware into the boot initramfs. +* Testing built-in firmware Even if you have these needs there are a few reasons why you may not be able to make use of built-in firmware:Documentation/x86/microcode.rst +3
-2@@ -114,11 +114,12 @@ Builtin microcode ================= The loader supports also loading of a builtin microcode supplied through -the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is -currently supported. +the regular builtin firmware method using CONFIG_FW_LOADER_BUILTIN and +CONFIG_EXTRA_FIRMWARE. Only 64-bit is currently supported. Here's an example:: + CONFIG_FW_LOADER_BUILTIN=y CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"drivers/base/firmware_loader/Kconfig +0
-0@@ -29,8 +29,10 @@ if FW_LOADER config FW_LOADER_PAGED_BUF boolQuoted 7 lines
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 34
Quoted 5 lines
drivers/base/firmware_loader/Kconfig +3
-2-config EXTRA_FIRMWARE - string "Build named firmware blobs into the kernel binary" +config FW_LOADER_BUILTIN + bool "Enable support for built-in firmware" + default nn is always the default, no need to list it again.
Oh, alrighty, I'll remove that line.
Quoted 4 lines
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 35
Quoted 1 line
drivers/base/firmware_loader/Kconfig +1
-0+ depends on FW_LOADER=yI don't see what this gets us to add another config option. Are you making things easier later on?
Quoted 7 lines
This makes a few things clearer for both developers and users. The code in question is a *feature* *only* when FW_LOADER=y, by adding a new kconfig to represent this and clearly makeing it depend on FW_LOADER=y it let's us:
o Clarify that support for built-in firmware requires the firmware loader to be built-in to the kernel
That is good.
Quoted 1 line
o By default we now always skip built-in firmware even if a FW_LOADER=y
I do not understand, why would we ever want to skip built-in firmware?
Quoted 2 lines
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmware
How was it ever used for anything else? :)
Quoted 4 lines
The above is not easily obvious to developers (including myself when I was reviewing this code) or users without this new kconfig entry.
Should I re-send by just removing the one line you asked for?
I can not take this as-is, so yes :)
thanks,
greg k-h
Luis Chamberlain
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 105 lines · Greg KH
Quoted 104 lines · Luis Chamberlain
Quoted 83 lines · Greg KH
Quoted 82 lines · Luis R. Rodriguez
From: Luis Chamberlain <[email protected]>
The built-in firmware is always supported when a user enables FW_LOADER=y today, that is, it is built-in to the kernel. When the firmware loader is built as a module, support for built-in firmware is skipped. This requirement is not really clear to users or even developers.
Also, by default the
EXTRA_FIRMWAREis always set to an empty string and so by default we really have nothing built-in to that kernel's sections for built-in firmware, so today a all FW_LOADER=y kernels spins their wheels on an empty set of built-in firmware for each firmware request with no true need for it.Add a new kconfig entry to represent built-in firmware support more clearly. This let's knock 3 birds with one stone:
o Clarifies that support for built-in firmware requires the firmware loader to be built-in to the kernel
o By default we now always skip built-in firmware even if a FW_LOADER=y
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmwareReviewed-by Borislav Petkov <[email protected]>Signed-off-by Luis Chamberlain <[email protected]>--- .../driver-api/firmware/built-in-fw.rst | 2 ++ Documentation/x86/microcode.rst | 5 ++-- drivers/base/firmware_loader/Kconfig | 25 +++++++++++++------ drivers/base/firmware_loader/Makefile | 3 +-- drivers/base/firmware_loader/main.c | 4 +-- 5 files changed, 26 insertions(+), 13 deletions(-)Documentation/driver-api/firmware/built-in-fw.rst +2
-0@@ -8,6 +8,7 @@ the filesystem. Instead, firmware can be looked for inside the kernel directly. You can enable built-in firmware using the kernel configuration options: + * CONFIG_FW_LOADER_BUILTIN * CONFIG_EXTRA_FIRMWARE * CONFIG_EXTRA_FIRMWARE_DIR@@ -17,6 +18,7 @@ into the kernel with CONFIG_EXTRA_FIRMWARE: * Speed * Firmware is needed for accessing the boot device, and the user doesn't want to stuff the firmware into the boot initramfs. +* Testing built-in firmware Even if you have these needs there are a few reasons why you may not be able to make use of built-in firmware:Documentation/x86/microcode.rst +3
-2@@ -114,11 +114,12 @@ Builtin microcode ================= The loader supports also loading of a builtin microcode supplied through -the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is -currently supported. +the regular builtin firmware method using CONFIG_FW_LOADER_BUILTIN and +CONFIG_EXTRA_FIRMWARE. Only 64-bit is currently supported. Here's an example:: + CONFIG_FW_LOADER_BUILTIN=y CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware"drivers/base/firmware_loader/Kconfig +0
-0@@ -29,8 +29,10 @@ if FW_LOADER config FW_LOADER_PAGED_BUF boolQuoted 7 lines
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 34
Quoted 5 lines
drivers/base/firmware_loader/Kconfig +3
-2-config EXTRA_FIRMWARE - string "Build named firmware blobs into the kernel binary" +config FW_LOADER_BUILTIN + bool "Enable support for built-in firmware" + default nn is always the default, no need to list it again.
Oh, alrighty, I'll remove that line.
Quoted 4 lines
drivers/base/firmware_loader/Kconfig if FW_LOADER · line 35
Quoted 1 line
drivers/base/firmware_loader/Kconfig +1
-0+ depends on FW_LOADER=yI don't see what this gets us to add another config option. Are you making things easier later on?
This makes a few things clearer for both developers and users. The code in question is a *feature* *only* when FW_LOADER=y, by adding a new kconfig to represent this and clearly makeing it depend on FW_LOADER=y it let's us:
Quoted 8 lines
Quoted 2 lines
o Clarify that support for built-in firmware requires the firmware loader to be built-in to the kernel
That is good.
Quoted 1 line
o By default we now always skip built-in firmware even if a FW_LOADER=y
I do not understand, why would we ever want to skip built-in firmware?
Because it is done this way today only implicitly because EXTRA_FIRMWARE is empty. Using a kconfig entry makes this more obvious.
Quoted 4 lines
Quoted 2 lines
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmwareHow was it ever used for anything else? :)
Well later this patch set also renames this to something more sensible, and so that change is clearer through this patch.
Quoted 1 line
I can not take this as-is, so yes :)
Well please let me know again once you read the above explanations.
I think the new kconfig is very well justified given the above.
Luis
Luis Chamberlain
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 8 lines · Luis Chamberlain
Quoted 3 lines · Greg KH
Quoted 1 line
o By default we now always skip built-in firmware even if a FW_LOADER=y
I do not understand, why would we ever want to skip built-in firmware?
Because it is done this way today only implicitly because
EXTRA_FIRMWAREis empty. Using a kconfig entry makes this more obvious.
Greg,
The fact that it was not obvious to you we were effectively disabling the built-in firmware functionality by default using side kconfig symbols is a good reason to clarify this situation with its own kconfig symbol.
And consider what I started below as well.
Please let me know why on the other hand we should *not* add this new kconfig symbol?
Quoted 15 lines
Quoted 4 lines
Quoted 2 lines
o This also lets us make it clear that the
EXTRA_FIRMWARE_DIRkconfig entry is only used for built-in firmwareHow was it ever used for anything else? :)
Well later this patch set also renames this to something more sensible, and so that change is clearer through this patch.
Quoted 1 line
I can not take this as-is, so yes :)
Well please let me know again once you read the above explanations.
I think the new kconfig is very well justified given the above.
Luis
Greg KH
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 17 lines · Luis Chamberlain
Quoted 8 lines · Luis Chamberlain
Quoted 3 lines · Greg KH
Quoted 1 line
o By default we now always skip built-in firmware even if a FW_LOADER=y
I do not understand, why would we ever want to skip built-in firmware?
Because it is done this way today only implicitly because
EXTRA_FIRMWAREis empty. Using a kconfig entry makes this more obvious.Greg,
The fact that it was not obvious to you we were effectively disabling the built-in firmware functionality by default using side kconfig symbols is a good reason to clarify this situation with its own kconfig symbol.
Quoted 4 lines
And consider what I started below as well.
Please let me know why on the other hand we should *not* add this new kconfig symbol?
Because added complexity for no real good reason? You need to justify why we need yet-another firmware kconfig option here. We should be working to remove them, not add more, if at all possible.
thanks,
greg k-h
Luis Chamberlain
maintainerRe: [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry
Quoted 18 lines · Greg KH
Quoted 17 lines · Luis Chamberlain
Quoted 8 lines · Luis Chamberlain
Quoted 3 lines · Greg KH
Quoted 1 line
o By default we now always skip built-in firmware even if a FW_LOADER=y
I do not understand, why would we ever want to skip built-in firmware?
Because it is done this way today only implicitly because
EXTRA_FIRMWAREis empty. Using a kconfig entry makes this more obvious.Greg,
The fact that it was not obvious to you we were effectively disabling the built-in firmware functionality by default using side kconfig symbols is a good reason to clarify this situation with its own kconfig symbol.
Quoted 8 lines
Quoted 4 lines
And consider what I started below as well.
Please let me know why on the other hand we should *not* add this new kconfig symbol?
Because added complexity for no real good reason? You need to justify why we need yet-another firmware kconfig option here. We should be working to remove them, not add more, if at all possible.
I did, it actually simplifies things more and makes the fact that we disable the functionality of the built-in firmware by default clearer.
So no, this is not adding complexity.
Luis
Luis R. Rodriguez
maintainerPATCH 5/14 firmware_loader: formalize built-in firmware API
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
Now that we have a kconfig entry to represent built-in firmware support, formalize its use with a proper API. This can later be used by other callers where all they need is built-in firmware.
We export the firmware_request_builtin() call for now only under the TEST_FIRMWARE symbol namespace as there are no direct modular users for it. If they pop up they are free to export it generally. Built-in code always gets access to the callers and we'll demonstrate a hidden user which has been lurking in the kernel for a while and the reason why using a proper API was better long term.
--- drivers/base/firmware_loader/builtin/Makefile | 6 +- drivers/base/firmware_loader/builtin/main.c | 95 +++++++++++++++++++ drivers/base/firmware_loader/firmware.h | 17 ++++ drivers/base/firmware_loader/main.c | 78 +-------------- include/linux/firmware.h | 11 +++ 5 files changed, 128 insertions(+), 79 deletions(-) create mode 100644 drivers/base/firmware_loader/builtin/main.c
drivers/base/firmware_loader/builtin/Makefile +4 -2
@@ -1,11 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 +obj-y += main.o # Create $(fwdir) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree). fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR)) fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) -obj-y := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) +firmware := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) +obj-y += $(firmware) FWNAME = $(patsubst $(obj)/%.gen.S,%,$@) FWSTR = $(subst $(comma),_,$(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME)))))
@@ -34,7 +36,7 @@ $(obj)/%.gen.S: FORCE $(call filechk,fwbin) # The .o files depend on the binaries directly; the .S files don't. -$(addprefix $(obj)/, $(obj-y)): $(obj)/%.gen.o: $(fwdir)/% +$(addprefix $(obj)/, $(firmware)): $(obj)/%.gen.o: $(fwdir)/% targets := $(patsubst $(obj)/%,%, \ $(shell find $(obj) -name \*.gen.S 2>/dev/null))
drivers/base/firmware_loader/builtin/main.c new file +95 -0
95 lines not on this page · raw message
drivers/base/firmware_loader/firmware.h +17 -0
@@ -151,6 +151,23 @@ static inline void fw_state_done(struct fw_priv *fw_priv)int assign_fw (struct firmware *fw,struct device *device); +#ifdef CONFIG_FW_LOADER_BUILTIN +bool firmware_is_builtin (const struct firmware *fw); +bool firmware_request_builtin_buf (struct firmware *fw,const char *name, +void *buf,size_t size); +#else +static inline bool firmware_is_builtin (const struct firmware *fw) +{ +return false; +} +static inline bool firmware_request_builtin_buf (struct firmware *fw, +const char *name, +void *buf,size_t size) +{ +return false; +} +#endif +#ifdef CONFIG_FW_LOADER_PAGED_BUF void fw_free_paged_buf (struct fw_priv *fw_priv);int fw_grow_paged_buf (struct fw_priv *fw_priv,int pages_needed);
drivers/base/firmware_loader/main.c +1 -77
90 lines not on this page · raw message
include/linux/firmware.h +11 -0
@@ -20,12 +20,15 @@ struct firmware {struct module ;struct device ; +#ifdef CONFIG_FW_LOADER_BUILTIN struct builtin_fw {char *name;void *data;unsigned long size; }; +bool firmware_request_builtin (struct firmware *fw,const char *name); +/* We have to play tricks here much like stringify() to get the __COUNTER__ macro to be expanded as we want it */ #define __fw_concat1 (x, y) x##y
@@ -38,6 +41,14 @@ struct builtin_fw { static const struct builtin_fw __fw_concat(__builtin_fw,__COUNTER__) \ __used __section(".builtin_fw") = { name, blob, size } +#else +static inline bool firmware_request_builtin(struct firmware *fw, + const char *name) +{ +return false; +} +#endif +#if defined(CONFIG_FW_LOADER ) || (defined(CONFIG_FW_LOADER_MODULE ) && defined(MODULE ))int request_firmware (const struct firmware **fw,const char *name,struct device *device);
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 6/14 firmware_loader: remove old DECLARE_BUILTIN_FIRMWARE()
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
This was never used upstream. Time to get rid of it. We don't carry around unused baggage.
--- include/linux/firmware.h | 13 ------------- 1 file changed, 13 deletions(-)
include/linux/firmware.h +0 -13
@@ -28,19 +28,6 @@ struct builtin_fw { };bool firmware_request_builtin (struct firmware *fw,const char *name); - -/* We have to play tricks here much like stringify() to get the -__COUNTER__ macro to be expanded as we want it */ -#define __fw_concat1 (x, y) x##y -#define __fw_concat (x, y) __fw_concat1(x, y) - -#define DECLARE_BUILTIN_FIRMWARE (name, blob) \ - DECLARE_BUILTIN_FIRMWARE_SIZE(name, &(blob), sizeof(blob)) - -#define DECLARE_BUILTIN_FIRMWARE_SIZE (name, blob, size) \ - static const struct builtin_fw __fw_concat(__builtin_fw,__COUNTER__) \ - __used __section(".builtin_fw") = { name, blob, size } -#else static inline bool firmware_request_builtin (struct firmware *fw,const char *name)
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 7/14 x86/microcode: Use the firmware_loader built-in API
In reply to Luis R. RodriguezFrom: Borislav Petkov <[email protected]>
The microcode loader has been looping through __start_builtin_fw down to __end_builtin_fw to look for possibly built-in firmware for microcode updates.
Now that the firmware loader code has exported an API for looping through the kernel's built-in firmware section, use it and drop the x86 implementation in favor.
--- arch/x86/include/asm/microcode.h | 3 --- arch/x86/kernel/cpu/microcode/amd.c | 14 ++++++++++---- arch/x86/kernel/cpu/microcode/core.c | 17 ----------------- arch/x86/kernel/cpu/microcode/intel.c | 9 ++++++++- 4 files changed, 18 insertions(+), 25 deletions(-)
arch/x86/include/asm/microcode.h +0 -3
@@ -130,14 +130,11 @@ static inline unsigned int x86_cpuid_family(void)extern void __init load_ucode_bsp (void );extern void load_ucode_ap (void );void reload_early_microcode (void ); -extern bool get_builtin_firmware (struct cpio_data *cd,const char *name);extern bool initrd_gone;#else static inline void __init load_ucode_bsp (void ) { }static inline void load_ucode_ap (void ) { }static inline void reload_early_microcode (void ) { } -static inline bool -get_builtin_firmware (struct cpio_data *cd,const char *name) {return false; }#endif #endif /* _ASM_X86_MICROCODE_H */
arch/x86/kernel/cpu/microcode/amd.c +10 -4
@@ -456,17 +456,23 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_pstatic bool get_builtin_microcode (struct cpio_data *cp,unsigned int family) { -#ifdef CONFIG_X86_64 char fw_name[36 ] ="amd-ucode/microcode_amd.bin" ; +struct firmware fw; + +if (IS_ENABLED (CONFIG_X86_32 )) +return false;if (family >=0x15 )snprintf (fw_name,sizeof (fw_name),"amd-ucode/microcode_amd_fam%.2xh.bin" , family); -return get_builtin_firmware (cp, fw_name); -#else +if (firmware_request_builtin (&fw, fw_name)) { + cp->size = fw.size; + cp->data = (void *)fw.data; +return true; + } +return false; -#endif }static void __load_ucode_amd (unsigned int cpuid_1_eax,struct cpio_data *ret)
arch/x86/kernel/cpu/microcode/core.c +0 -17
@@ -140,23 +140,6 @@ static bool __init check_loader_disabled_bsp(void)return *res; } -extern struct builtin_fw __start_builtin_fw[]; -extern struct builtin_fw __end_builtin_fw[]; - -bool get_builtin_firmware (struct cpio_data *cd,const char *name) -{ -struct builtin_fw *b_fw; - -for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { -if (!strcmp (name, b_fw->name)) { - cd->size = b_fw->size; - cd->data = b_fw->data; -return true; - } - } -return false; -} -void __init load_ucode_bsp (void ) {unsigned int cpuid_1_eax;
arch/x86/kernel/cpu/microcode/intel.c +8 -1
@@ -456,6 +456,7 @@ static void save_mc_for_early(struct ucode_cpu_info *uci, u8 *mc, unsigned int sstatic bool load_builtin_intel_microcode (struct cpio_data *cp) {unsigned int eax =1 , ebx, ecx =0 , edx; +struct firmware fw;char name[30 ];if (IS_ENABLED (CONFIG_X86_32 ))
@@ -466,7 +467,13 @@ static bool load_builtin_intel_microcode(struct cpio_data *cp)sprintf (name,"intel-ucode/%02x-%02x-%02x" ,x86_family (eax),x86_model (eax),x86_stepping (eax)); -return get_builtin_firmware (cp, name); +if (firmware_request_builtin (&fw, name)) { + cp->size = fw.size; + cp->data = (void *)fw.data; +return true; + } + +return false; }/*
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 8/14 firmware_loader: move struct builtin_fw to the only place used
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
Now that x86 doesn't abuse picking at internals to the firmware loader move out the built-in firmware struct to its only user.
--- drivers/base/firmware_loader/builtin/main.c | 6 ++++++ include/linux/firmware.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/base/firmware_loader/builtin/main.c +6 -0
@@ -4,6 +4,12 @@#include <linux/firmware.h> #include "../firmware.h" +struct builtin_fw { +char *name; +void *data; +unsigned long size; +}; +extern struct builtin_fw __start_builtin_fw[];extern struct builtin_fw __end_builtin_fw[];
include/linux/firmware.h +0 -6
@@ -21,12 +21,6 @@ struct module;struct device ;#ifdef CONFIG_FW_LOADER_BUILTIN -struct builtin_fw { -char *name; -void *data; -unsigned long size; -}; -bool firmware_request_builtin (struct firmware *fw,const char *name);#else static inline bool firmware_request_builtin(struct firmware *fw,
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 9/14 vmlinux.lds.h: wrap built-in firmware support under its kconfig symbol
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
The firmware loader built-in firmware support now has a kconfig symbol representing support for it. Use that to tuck away the sections for built-in firmware.
This ensures no oddball user tries to uses these sections without first enabling FW_LOADER_BUILTIN.
--- include/asm-generic/vmlinux.lds.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
include/asm-generic/vmlinux.lds.h +13 -7
@@ -470,13 +470,7 @@ __end_pci_fixups_suspend_late = .; \ } \ \ -/* Built-in firmware blobs */ \ - .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) ALIGN(8) { \ - __start_builtin_fw = .; \ - KEEP(*(.builtin_fw)) \ - __end_builtin_fw = .; \ - } \ - \ +FW_LOADER_BUILT_IN_DATA \ TRACEDATA \ \PRINTK_INDEX \
@@ -880,6 +874,18 @@#define ORC_UNWIND_TABLE #endif +/* Built-in firmware blobs */ +#ifdef CONFIG_FW_LOADER_BUILTIN +#define FW_LOADER_BUILT_IN_DATA \ + .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) ALIGN(8) { \ + __start_builtin_fw = .; \ + KEEP(*(.builtin_fw)) \ + __end_builtin_fw = .; \ + } +#else +#define FW_LOADER_BUILT_IN_DATA +#endif +#ifdef CONFIG_PM_TRACE #define TRACEDATA \ . = ALIGN(4); \
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 10/14 x86/build: Tuck away built-in firmware under its kconfig symbol
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
Now that it is clear that built-in firmware is only used when built-in firmware is enabled update x86 relocs to reflect that.
--- arch/x86/tools/relocs.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/tools/relocs.c +2 -0
@@ -63,7 +63,9 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { "(__parainstructions|__alt_instructions)(_end)?|" "(__iommu_table|__apicdrivers|__smp_locks)(_end)?|" "__(start|end)_pci_.*|" +#if CONFIG_FW_LOADER_BUILTIN "__(start|end)_builtin_fw|" +#endif"__(start|stop)___ksymtab(_gpl)?|" "__(start|stop)___kcrctab(_gpl)?|" "__(start|stop)___param|"
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 11/14 firmware_loader: rename EXTRA_FIRMWARE and EXTRA_FIRMWARE_DIR
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
Now that we've tied loose ends on the built-in firmware API, rename the kconfig symbols for it to reflect more that they are associated to the firmware_loader and to make it easier to understand what they are for.
--- .../driver-api/firmware/built-in-fw.rst | 6 +++--- Documentation/x86/microcode.rst | 6 +++--- arch/x86/Kconfig | 4 ++-- drivers/base/firmware_loader/Kconfig | 20 +++++++++++-------- drivers/base/firmware_loader/builtin/Makefile | 6 +++--- drivers/staging/media/av7110/Kconfig | 4 ++-- 6 files changed, 25 insertions(+), 21 deletions(-)
Documentation/driver-api/firmware/built-in-fw.rst +3 -3
@@ -9,11 +9,11 @@ directly. You can enable built-in firmware using the kernel configuration options: * CONFIG_FW_LOADER_BUILTIN - * CONFIG_EXTRA_FIRMWARE - * CONFIG_EXTRA_FIRMWARE_DIR + * CONFIG_FW_LOADER_BUILTIN_FILES + * CONFIG_FW_LOADER_BUILTIN_DIR There are a few reasons why you might want to consider building your firmware -into the kernel with CONFIG_EXTRA_FIRMWARE: +into the kernel with CONFIG_FW_LOADER_BUILTIN_FILES: * Speed * Firmware is needed for accessing the boot device, and the user doesn't
Documentation/x86/microcode.rst +3 -3
@@ -115,13 +115,13 @@ Builtin microcode The loader supports also loading of a builtin microcode supplied through the regular builtin firmware method using CONFIG_FW_LOADER_BUILTIN and -CONFIG_EXTRA_FIRMWARE. Only 64-bit is currently supported. +CONFIG_FW_LOADER_BUILTIN_FILES. Only 64-bit is currently supported. Here's an example:: CONFIG_FW_LOADER_BUILTIN=y - CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" - CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" + CONFIG_FW_LOADER_BUILTIN_FILES="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" + CONFIG_FW_LOADER_BUILTIN_DIR="/lib/firmware" This basically means, you have the following tree structure locally::
arch/x86/Kconfig +2 -2
@@ -1304,8 +1304,8 @@ config MICROCODE initrd for microcode blobs. In addition, you can build the microcode into the kernel. For that you - need to add the vendor-supplied microcode to the CONFIG_EXTRA_FIRMWARE - config option. + need to add the vendor-supplied microcode to the configuration option + CONFIG_FW_LOADER_BUILTIN_FILES config MICROCODE_INTEL bool "Intel microcode loading support"
drivers/base/firmware_loader/Kconfig +12 -8
@@ -22,7 +22,7 @@ config FW_LOADER You typically want this built-in (=y) but you can also enable this as a module, in which case the firmware_class module will be built. You also want to be sure to enable this built-in if you are going to - enable built-in firmware (CONFIG_EXTRA_FIRMWARE). + enable built-in firmware (CONFIG_FW_LOADER_BUILTIN_FILES). if FW_LOADER
@@ -48,18 +48,22 @@ config FW_LOADER_BUILTIN Support for built-in firmware is not supported if you are using the firmware loader as a module. -config EXTRA_FIRMWARE +config FW_LOADER_BUILTIN_FILES string "Build named firmware blobs into the kernel binary" depends on FW_LOADER_BUILTIN help This option is a string and takes the space-separated names of the firmware files -- the same names that appear in MODULE_FIRMWARE() and request_firmware() in the source. These files should exist under - the directory specified by the EXTRA_FIRMWARE_DIR option, which is + the directory specified by the FW_LOADER_BUILTIN_DIR option, which is /lib/firmware by default. - For example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin", copy - the usb8388.bin file into /lib/firmware, and build the kernel. Then + For example, you might have set: + + CONFIG_FW_LOADER_BUILTIN_FILES="usb8388.bin" + + After this you would copy the usb8388.bin file into directory + specified by FW_LOADER_BUILTIN_DIR and build the kernel. Then any request_firmware("usb8388.bin") will be satisfied internally inside the kernel without ever looking at your filesystem at runtime.
@@ -69,15 +73,15 @@ config EXTRA_FIRMWARE image since it combines both GPL and non-GPL work. You should consult a lawyer of your own before distributing such an image. -config EXTRA_FIRMWARE_DIR +config FW_LOADER_BUILTIN_DIR string "Directory with firmware to be built-in to the kernel" depends on FW_LOADER_BUILTIN default "/lib/firmware" help This option specifies the directory which the kernel build system will use to look for the firmware files which are going to be - built into the kernel using the space-separated EXTRA_FIRMWARE - entries. + built into the kernel using the space-separated + FW_LOADER_BUILTIN_FILES entries. config FW_LOADER_USER_HELPER bool "Enable the firmware sysfs fallback mechanism"
drivers/base/firmware_loader/builtin/Makefile +3 -3
@@ -1,12 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += main.o -# Create $(fwdir) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a +# Create $(fwdir) from $(CONFIG_FW_LOADER_BUILTIN_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree). -fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR)) +fwdir := $(subst $(quote),,$(CONFIG_FW_LOADER_BUILTIN_DIR)) fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) -firmware := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) +firmware := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_FW_LOADER_BUILTIN_FILES))) obj-y += $(firmware) FWNAME = $(patsubst $(obj)/%.gen.S,%,$@)
drivers/staging/media/av7110/Kconfig +2 -2
@@ -31,8 +31,8 @@ config DVB_AV7110 or /lib/firmware (depending on configuration of firmware hotplug). Alternatively, you can download the file and use the kernel's - EXTRA_FIRMWARE configuration option to build it into your - kernel image by adding the filename to the EXTRA_FIRMWARE + FW_LOADER_BUILTIN_FILES configuration option to build it into your + kernel image by adding the filename to the FW_LOADER_BUILTIN_FILES configuration option string. Say Y if you own such a card and want to use it.
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 12/14 firmware_loader: move builtin build helper to shared library
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
If we wanted to use a different directory for building target builtin firmware it is easier if we just have a shared library Makefile, and each target directory can then just include it and populate the respective needed variables. This reduces clutter, makes things easier to read, and also most importantly allows us to not have to try to magically adjust only one target kconfig symbol for built-in firmware files. Trying to do this can easily end up causing odd build issues if the user is not careful.
As an example issue, if we are going to try to extend the FW_LOADER_BUILTIN_FILES list and FW_LOADER_BUILTIN_DIR in case of a new test firmware builtin support currently our only option would be modify the defaults of each of these in case test firmware builtin support was enabled. Defaults however won't augment a prior setting, and so if FW_LOADER_BUILTIN_DIR="/lib/firmware" and you and want this to be changed to something like FW_LOADER_BUILTIN_DIR="drivers/base/firmware_loader/test-builtin" the change will not take effect as a prior build already had it set, and the build would fail. Trying to augment / append the variables in the Makefile just makes this very difficult to read.
Using a library let's us split up possible built-in targets so that the user does not have to be involved. This will be used in a subsequent patch which will add another user to this built-in firmware library Makefile and demo how to use it outside of the default FW_LOADER_BUILTIN_DIR and FW_LOADER_BUILTIN_FILES.
--- drivers/base/firmware_loader/builtin/Makefile | 34 ++----------------- .../base/firmware_loader/builtin/lib.Makefile | 32 +++++++++++++++++ 2 files changed, 34 insertions(+), 32 deletions(-) create mode 100644 drivers/base/firmware_loader/builtin/lib.Makefile
drivers/base/firmware_loader/builtin/Makefile +2 -32
@@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 +include $(srctree)/drivers/base/firmware_loader/builtin/lib.Makefile + obj-y += main.o # Create $(fwdir) from $(CONFIG_FW_LOADER_BUILTIN_DIR) -- if it doesn't have a
@@ -8,35 +10,3 @@ fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) firmware := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_FW_LOADER_BUILTIN_FILES))) obj-y += $(firmware) - -FWNAME = $(patsubst $(obj)/%.gen.S,%,$@) -FWSTR = $(subst $(comma),_,$(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME))))) -ASM_WORD = $(if $(CONFIG_64BIT),.quad,.long) -ASM_ALIGN = $(if $(CONFIG_64BIT),3,2) -PROGBITS = $(if $(CONFIG_ARM),%,@)progbits - -filechk_fwbin = \ - echo "/* Generated by $(src)/Makefile */" ;\ - echo " .section .rodata" ;\ - echo " .p2align 4" ;\ - echo "_fw_$(FWSTR)_bin:" ;\ - echo " .incbin \"$(fwdir)/$(FWNAME)\"" ;\ - echo "_fw_end:" ;\ - echo " .section .rodata.str,\"aMS\",$(PROGBITS),1" ;\ - echo " .p2align $(ASM_ALIGN)" ;\ - echo "_fw_$(FWSTR)_name:" ;\ - echo " .string \"$(FWNAME)\"" ;\ - echo " .section .builtin_fw,\"a\",$(PROGBITS)" ;\ - echo " .p2align $(ASM_ALIGN)" ;\ - echo " $(ASM_WORD) _fw_$(FWSTR)_name" ;\ - echo " $(ASM_WORD) _fw_$(FWSTR)_bin" ;\ - echo " $(ASM_WORD) _fw_end - _fw_$(FWSTR)_bin" - -$(obj)/%.gen.S: FORCE - $(call filechk,fwbin) - -# The .o files depend on the binaries directly; the .S files don't. -$(addprefix $(obj)/, $(firmware)): $(obj)/%.gen.o: $(fwdir)/% - -targets := $(patsubst $(obj)/%,%, \ - $(shell find $(obj) -name \*.gen.S 2>/dev/null))
drivers/base/firmware_loader/builtin/lib.Makefile new file +32 -0
@@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0 +FWNAME = $(patsubst $(obj)/%.gen.S,%,$@) +FWSTR = $(subst $(comma),_,$(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME))))) +ASM_WORD = $(if $(CONFIG_64BIT),.quad,.long) +ASM_ALIGN = $(if $(CONFIG_64BIT),3,2) +PROGBITS = $(if $(CONFIG_ARM),%,@)progbits + +filechk_fwbin = \ + echo "/* Generated by $(src)/Makefile */" ;\ + echo " .section .rodata" ;\ + echo " .p2align 4" ;\ + echo "_fw_$(FWSTR)_bin:" ;\ + echo " .incbin \"$(fwdir)/$(FWNAME)\"" ;\ + echo "_fw_end:" ;\ + echo " .section .rodata.str,\"aMS\",$(PROGBITS),1" ;\ + echo " .p2align $(ASM_ALIGN)" ;\ + echo "_fw_$(FWSTR)_name:" ;\ + echo " .string \"$(FWNAME)\"" ;\ + echo " .section .builtin_fw,\"a\",$(PROGBITS)" ;\ + echo " .p2align $(ASM_ALIGN)" ;\ + echo " $(ASM_WORD) _fw_$(FWSTR)_name" ;\ + echo " $(ASM_WORD) _fw_$(FWSTR)_bin" ;\ + echo " $(ASM_WORD) _fw_end - _fw_$(FWSTR)_bin" + +$(obj)/%.gen.S: FORCE + $(call filechk,fwbin) + +# The .o files depend on the binaries directly; the .S files don't. +$(addprefix $(obj)/, $(firmware)): $(obj)/%.gen.o: $(fwdir)/% + +targets := $(patsubst $(obj)/%,%, \ + $(shell find $(obj) -name \*.gen.S 2>/dev/null))
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 13/14 test_firmware: move a few test knobs out to its library
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
These will be used by other tests cases in other files so move them to the library.
--- .../testing/selftests/firmware/fw_filesystem.sh | 16 ---------------- tools/testing/selftests/firmware/fw_lib.sh | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-)
tools/testing/selftests/firmware/fw_filesystem.sh +0 -16
@@ -118,27 +118,11 @@ test_config_present() fi } -# Defaults : -# -# send_uevent: 1 -# sync_direct: 0 -# name: test-firmware.bin -# num_requests: 4 -config_reset() -{ - echo 1 > $DIR/reset -} - release_all_firmware() { echo 1 > $DIR/release_all_firmware } -config_set_name() -{ - echo -n $1 > $DIR/config_name -} - config_set_into_buf() { echo 1 > $DIR/config_into_buf
tools/testing/selftests/firmware/fw_lib.sh +17 -0
@@ -221,3 +221,20 @@ kconfig_has() fi fi } + +# Defaults : +# +# send_uevent: 1 +# sync_direct: 0 +# name: test-firmware.bin +# num_requests: 4 +config_reset() +{ + echo 1 > $DIR/reset +} + + +config_set_name() +{ + echo -n $1 > $DIR/config_name +}
Signature · 1 line
2.30.2
Luis R. Rodriguez
maintainerPATCH 14/14 test_firmware: add support for testing built-in firmware
In reply to Luis R. RodriguezFrom: Luis Chamberlain <[email protected]>
This adds some basic knobs to let us test built-in firmware support. We test to ensure built-in firmware is indeed used, and that it matches the contents we expect. Likewise we test that a file that should not be built-in was not present.
For older kernels with older test_firmware drivers (yes some folks do test selftests this way and we support it), the new built-in test will simply bail out early.
--- drivers/base/firmware_loader/Makefile | 1 + drivers/base/firmware_loader/builtin/Makefile | 1 + .../firmware_loader/test-builtin/.gitignore | 3 + .../firmware_loader/test-builtin/Makefile | 18 +++++ lib/Kconfig.debug | 34 +++++++++ lib/test_firmware.c | 52 +++++++++++++- .../testing/selftests/firmware/fw_builtin.sh | 69 +++++++++++++++++++ tools/testing/selftests/firmware/fw_lib.sh | 7 ++ .../selftests/firmware/fw_run_tests.sh | 2 + 9 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 drivers/base/firmware_loader/test-builtin/.gitignore create mode 100644 drivers/base/firmware_loader/test-builtin/Makefile create mode 100755 tools/testing/selftests/firmware/fw_builtin.sh
drivers/base/firmware_loader/Makefile +1 -0
@@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for the Linux firmware loader +obj-$(CONFIG_TEST_FIRMWARE_BUILTIN) += test-builtin/ obj-$(CONFIG_FW_LOADER_BUILTIN) += builtin/ obj-$(CONFIG_FW_LOADER_USER_HELPER) += fallback_table.o obj-$(CONFIG_FW_LOADER) += firmware_class.o
drivers/base/firmware_loader/builtin/Makefile +1 -0
@@ -2,6 +2,7 @@ include $(srctree)/drivers/base/firmware_loader/builtin/lib.Makefile obj-y += main.o +obj-$(CONFIG_TEST_BUILTIN_FIRMWARE) += test-builtin-firmware.bin.gen.o # Create $(fwdir) from $(CONFIG_FW_LOADER_BUILTIN_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree).
drivers/base/firmware_loader/test-builtin/.gitignore new file +3 -0
@@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +*.gen.S +*.bin
drivers/base/firmware_loader/test-builtin/Makefile new file +18 -0
@@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 +include $(srctree)/drivers/base/firmware_loader/builtin/lib.Makefile + +extra-y := test-builtin-firmware.bin +$(obj)/test-builtin-firmware.bin: FORCE + @$(kecho) " GEN $@" + @(set -e; \ + ( \ + echo 'ABCD0123'; \ + ) > $@) + +# Create $(fwdir) from $(CONFIG_TEST_FIRMWARE_BUILTIN_DIR) -- if it doesn't +# have a leading /, it's relative to $(srctree). +fwdir := $(subst $(quote),,$(CONFIG_TEST_FIRMWARE_BUILTIN_DIR)) +fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) + +firmware := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_TEST_FIRMWARE_BUILTIN_FILES))) +obj-y += $(firmware)
lib/Kconfig.debug +34 -0
@@ -2333,6 +2333,40 @@ config TEST_FIRMWARE If unsure, say N. +config TEST_FIRMWARE_BUILTIN + bool "Allow building built-in test firmware" + depends on TEST_FIRMWARE + select FW_LOADER_BUILTIN + help + If enabled, firmware will be built into to the kernel so that + loading it with the test_firmware driver can be tested. Disabling + this will just mean the test firmware scripts won't find any + built-in firmware. Enabling this will make the kernel generate the + file test-builtin-firmware.bin inside local directory + drivers/base/firmware_loader/test-builtin. This file will then + be available whenever the request firmware API is used. + + Enabling this functionlity essentially overrides the location where + you specify to find built-in firmware, and so should only be enabled + if you don't need to build firmware into your kernel for full + funcionality. + + This should be disabled on production kernels as otherwise you'll + end up with a test firmware stuck into your final kernel image and + with default built-in firmware support. + + If unsure, say N. + +config TEST_FIRMWARE_BUILTIN_FILES + string + depends on TEST_FIRMWARE_BUILTIN + default "test-builtin-firmware.bin" + +config TEST_FIRMWARE_BUILTIN_DIR + string + depends on TEST_FIRMWARE_BUILTIN + default "drivers/base/firmware_loader/test-builtin" + config TEST_SYSCTL tristate "sysctl test driver" depends on PROC_SYSCTL
lib/test_firmware.c +51 -1
94 lines not on this page · raw message
tools/testing/selftests/firmware/fw_builtin.sh new file +69 -0
69 lines not on this page · raw message
tools/testing/selftests/firmware/fw_lib.sh +7 -0
@@ -15,6 +15,10 @@ TEST_DIR=$(dirname $0) # To reproduce rename this to test-firmware.bin TEST_FIRMWARE_INTO_BUF_FILENAME=test-firmware-into-buf.bin +# We should use a different filename for built-in firmware otherwise +# we'd always have the file present. +TEST_FIRMWARE_BUILTIN_FILENAME=test-builtin-firmware.bin + # Kselftest framework requirement - SKIP code is 4. ksft_skip=4
@@ -63,6 +67,9 @@ check_setup() HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)" HAS_FW_LOADER_COMPRESS="$(kconfig_has CONFIG_FW_LOADER_COMPRESS=y)" + HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" + HAS_FW_LOADER_BUILTIN="$(kconfig_has CONFIG_FW_LOADER_BUILTIN=y)" + HAS_TEST_FIRMWARE_BUILTIN="$(kconfig_has CONFIG_TEST_FIRMWARE_BUILTIN=y)" PROC_FW_IGNORE_SYSFS_FALLBACK="0" PROC_FW_FORCE_SYSFS_FALLBACK="0"
tools/testing/selftests/firmware/fw_run_tests.sh +2 -0
@@ -65,6 +65,8 @@ echo "Running namespace test: " $TEST_DIR/fw_namespace $DIR/trigger_request echo "OK" +$TEST_DIR/fw_builtin.sh + if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then run_test_config_0001 run_test_config_0002
Signature · 1 line
2.30.2