From: "Luis R. Rodriguez" <mcgrof@kernel.org>
To: gregkh@linuxfoundation.org
Cc: bp@suse.de, akpm@linux-foundation.org, josh@joshtriplett.org,
rishabhb@codeaurora.org, kubakici@wp.pl, maco@android.com,
david.brown@linaro.org, bjorn.andersson@linaro.org,
linux-wireless@vger.kernel.org, keescook@chromium.org,
shuah@kernel.org, mfuzzey@parkeon.com, zohar@linux.vnet.ibm.com,
dhowells@redhat.com, pali.rohar@gmail.com, tiwai@suse.de,
arend.vanspriel@broadcom.com, zajec5@gmail.com, nbroeking@me.com,
broonie@kernel.org, dmitry.torokhov@gmail.com,
dwmw2@infradead.org, torvalds@linux-foundation.org,
Abhay_Salunke@dell.com, jewalt@lgsinnovations.com,
cantabile.desu@gmail.com, ast@fb.com, andresx7@gmail.com,
dan.rue@linaro.org, brendanhiggins@google.com,
yzaikin@google.com, sfr@canb.auug.org.au, rdunlap@infradead.org,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Luis Chamberlain <mcgrof@kernel.org>
Subject: [PATCH 05/14] firmware_loader: formalize built-in firmware API
Date: Fri, 17 Sep 2021 11:22:17 -0700 [thread overview]
Message-ID: <20210917182226.3532898-6-mcgrof@kernel.org> (raw)
In-Reply-To: <20210917182226.3532898-1-mcgrof@kernel.org>
From: Luis Chamberlain <mcgrof@kernel.org>
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.
Reviewed-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
---
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
diff --git a/drivers/base/firmware_loader/builtin/Makefile b/drivers/base/firmware_loader/builtin/Makefile
index 101754ad48d9..eb4be452062a 100644
--- a/drivers/base/firmware_loader/builtin/Makefile
+++ b/drivers/base/firmware_loader/builtin/Makefile
@@ -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))
diff --git a/drivers/base/firmware_loader/builtin/main.c b/drivers/base/firmware_loader/builtin/main.c
new file mode 100644
index 000000000000..2af0e58f3f9f
--- /dev/null
+++ b/drivers/base/firmware_loader/builtin/main.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Builtin firmware support */
+
+#include <linux/firmware.h>
+#include "../firmware.h"
+
+extern struct builtin_fw __start_builtin_fw[];
+extern struct builtin_fw __end_builtin_fw[];
+
+static bool fw_copy_to_prealloc_buf(struct firmware *fw,
+ void *buf, size_t size)
+{
+ if (!buf)
+ return true;
+ if (size < fw->size)
+ return false;
+ memcpy(buf, fw->data, fw->size);
+ return true;
+}
+
+/**
+ * firmware_request_builtin() - load builtin firmware
+ * @fw: pointer to firmware struct
+ * @name: name of firmware file
+ *
+ * Some use cases in the kernel have a requirement so that no memory allocator
+ * is involved as these calls take place early in boot process. An example is
+ * the x86 CPU microcode loader. In these cases all the caller wants is to see
+ * if the firmware was built-in and if so use it right away. This can be used
+ * for such cases.
+ *
+ * This looks for the firmware in the built-in kernel. Only if the kernel was
+ * built-in with the firmware you are looking for will this return successfully.
+ *
+ * Callers of this API do not need to use release_firmware() as the pointer to
+ * the firmware is expected to be provided locally on the stack of the caller.
+ **/
+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;
+ fw->data = b_fw->data;
+ return true;
+ }
+ }
+
+ return false;
+}
+EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, TEST_FIRMWARE);
+
+/**
+ * firmware_request_builtin_buf() - load builtin firmware into optional buffer
+ * @fw: pointer to firmware struct
+ * @name: name of firmware file
+ * @buf: If set this lets you use a pre-allocated buffer so that the built-in
+ * firmware into is copied into. This field can be NULL. It is used by
+ * callers such as request_firmware_into_buf() and
+ * request_partial_firmware_into_buf()
+ * @size: if buf was provided, the max size of the allocated buffer available.
+ * If the built-in firmware does not fit into the pre-allocated @buf this
+ * call will fail.
+ *
+ * This looks for the firmware in the built-in kernel. Only if the kernel was
+ * built-in with the firmware you are looking for will this call possibly
+ * succeed. If you passed a @buf the firmware will be copied into it *iff* the
+ * built-in firmware fits into the pre-allocated buffer size specified in
+ * @size.
+ *
+ * This caller is to be used internally by the firmware_loader only.
+ **/
+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);
+}
+
+bool firmware_is_builtin(const struct firmware *fw)
+{
+ struct builtin_fw *b_fw;
+
+ for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++)
+ if (fw->data == b_fw->data)
+ return true;
+
+ return false;
+}
diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h
index a3014e9e2c85..7e38827ad006 100644
--- a/drivers/base/firmware_loader/firmware.h
+++ b/drivers/base/firmware_loader/firmware.h
@@ -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);
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index 45075c7f9290..94d1789a233e 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -93,82 +93,6 @@ DEFINE_MUTEX(fw_lock);
static struct firmware_cache fw_cache;
-/* Builtin firmware support */
-
-#ifdef CONFIG_FW_LOADER_BUILTIN
-
-extern struct builtin_fw __start_builtin_fw[];
-extern struct builtin_fw __end_builtin_fw[];
-
-static bool fw_copy_to_prealloc_buf(struct firmware *fw,
- void *buf, size_t size)
-{
- if (!buf)
- return true;
- if (size < fw->size)
- return false;
- memcpy(buf, fw->data, fw->size);
- return true;
-}
-
-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;
- fw->data = b_fw->data;
- 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;
-
- for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++)
- if (fw->data == b_fw->data)
- return true;
-
- return false;
-}
-
-#else
-
-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;
-}
-
-static inline bool fw_is_builtin_firmware(const struct firmware *fw)
-{
- return false;
-}
-#endif
-
static void fw_state_init(struct fw_priv *fw_priv)
{
struct fw_state *fw_st = &fw_priv->fw_st;
@@ -1068,7 +992,7 @@ EXPORT_SYMBOL(request_partial_firmware_into_buf);
void release_firmware(const struct firmware *fw)
{
if (fw) {
- if (!fw_is_builtin_firmware(fw))
+ if (!firmware_is_builtin(fw))
firmware_free_data(fw);
kfree(fw);
}
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index 25109192cebe..29d17a05ead6 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -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);
--
2.30.2
next prev parent reply other threads:[~2021-09-17 18:23 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-17 18:22 [PATCH 00/14] firmware_loader: built-in API and make x86 use it Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 01/14] firmware_loader: fix pre-allocated buf built-in firmware use Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 02/14] firmware_loader: split built-in firmware call Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 03/14] firmware_loader: add a sanity check for firmware_request_builtin() Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 04/14] firmware_loader: add built-in firmware kconfig entry Luis R. Rodriguez
2021-10-05 14:30 ` Greg KH
2021-10-11 17:35 ` Luis Chamberlain
2021-10-11 17:46 ` Greg KH
2021-10-11 22:30 ` Luis Chamberlain
2021-10-18 21:00 ` Luis Chamberlain
2021-10-19 6:16 ` Greg KH
2021-10-19 15:52 ` Luis Chamberlain
2021-09-17 18:22 ` Luis R. Rodriguez [this message]
2021-09-17 18:22 ` [PATCH 06/14] firmware_loader: remove old DECLARE_BUILTIN_FIRMWARE() Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 07/14] x86/microcode: Use the firmware_loader built-in API Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 08/14] firmware_loader: move struct builtin_fw to the only place used Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 09/14] vmlinux.lds.h: wrap built-in firmware support under its kconfig symbol Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 10/14] x86/build: Tuck away built-in firmware " Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 11/14] firmware_loader: rename EXTRA_FIRMWARE and EXTRA_FIRMWARE_DIR Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 12/14] firmware_loader: move builtin build helper to shared library Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 13/14] test_firmware: move a few test knobs out to its library Luis R. Rodriguez
2021-09-17 18:22 ` [PATCH 14/14] test_firmware: add support for testing built-in firmware Luis R. Rodriguez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210917182226.3532898-6-mcgrof@kernel.org \
--to=mcgrof@kernel.org \
--cc=Abhay_Salunke@dell.com \
--cc=akpm@linux-foundation.org \
--cc=andresx7@gmail.com \
--cc=arend.vanspriel@broadcom.com \
--cc=ast@fb.com \
--cc=bjorn.andersson@linaro.org \
--cc=bp@suse.de \
--cc=brendanhiggins@google.com \
--cc=broonie@kernel.org \
--cc=cantabile.desu@gmail.com \
--cc=dan.rue@linaro.org \
--cc=david.brown@linaro.org \
--cc=dhowells@redhat.com \
--cc=dmitry.torokhov@gmail.com \
--cc=dwmw2@infradead.org \
--cc=gregkh@linuxfoundation.org \
--cc=jewalt@lgsinnovations.com \
--cc=josh@joshtriplett.org \
--cc=keescook@chromium.org \
--cc=kubakici@wp.pl \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=maco@android.com \
--cc=mfuzzey@parkeon.com \
--cc=nbroeking@me.com \
--cc=pali.rohar@gmail.com \
--cc=rdunlap@infradead.org \
--cc=rishabhb@codeaurora.org \
--cc=sfr@canb.auug.org.au \
--cc=shuah@kernel.org \
--cc=tiwai@suse.de \
--cc=torvalds@linux-foundation.org \
--cc=yzaikin@google.com \
--cc=zajec5@gmail.com \
--cc=zohar@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).