cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (3113B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Builtin firmware support */
      3
      4#include <linux/firmware.h>
      5#include "../firmware.h"
      6
      7/* Only if FW_LOADER=y */
      8#ifdef CONFIG_FW_LOADER
      9
     10struct builtin_fw {
     11	char *name;
     12	void *data;
     13	unsigned long size;
     14};
     15
     16extern struct builtin_fw __start_builtin_fw[];
     17extern struct builtin_fw __end_builtin_fw[];
     18
     19static bool fw_copy_to_prealloc_buf(struct firmware *fw,
     20				    void *buf, size_t size)
     21{
     22	if (!buf)
     23		return true;
     24	if (size < fw->size)
     25		return false;
     26	memcpy(buf, fw->data, fw->size);
     27	return true;
     28}
     29
     30/**
     31 * firmware_request_builtin() - load builtin firmware
     32 * @fw: pointer to firmware struct
     33 * @name: name of firmware file
     34 *
     35 * Some use cases in the kernel have a requirement so that no memory allocator
     36 * is involved as these calls take place early in boot process. An example is
     37 * the x86 CPU microcode loader. In these cases all the caller wants is to see
     38 * if the firmware was built-in and if so use it right away. This can be used
     39 * for such cases.
     40 *
     41 * This looks for the firmware in the built-in kernel. Only if the kernel was
     42 * built-in with the firmware you are looking for will this return successfully.
     43 *
     44 * Callers of this API do not need to use release_firmware() as the pointer to
     45 * the firmware is expected to be provided locally on the stack of the caller.
     46 **/
     47bool firmware_request_builtin(struct firmware *fw, const char *name)
     48{
     49	struct builtin_fw *b_fw;
     50
     51	if (!fw)
     52		return false;
     53
     54	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
     55		if (strcmp(name, b_fw->name) == 0) {
     56			fw->size = b_fw->size;
     57			fw->data = b_fw->data;
     58			return true;
     59		}
     60	}
     61
     62	return false;
     63}
     64EXPORT_SYMBOL_NS_GPL(firmware_request_builtin, TEST_FIRMWARE);
     65
     66/**
     67 * firmware_request_builtin_buf() - load builtin firmware into optional buffer
     68 * @fw: pointer to firmware struct
     69 * @name: name of firmware file
     70 * @buf: If set this lets you use a pre-allocated buffer so that the built-in
     71 *	firmware into is copied into. This field can be NULL. It is used by
     72 *	callers such as request_firmware_into_buf() and
     73 *	request_partial_firmware_into_buf()
     74 * @size: if buf was provided, the max size of the allocated buffer available.
     75 *	If the built-in firmware does not fit into the pre-allocated @buf this
     76 *	call will fail.
     77 *
     78 * This looks for the firmware in the built-in kernel. Only if the kernel was
     79 * built-in with the firmware you are looking for will this call possibly
     80 * succeed. If you passed a @buf the firmware will be copied into it *iff* the
     81 * built-in firmware fits into the pre-allocated buffer size specified in
     82 * @size.
     83 *
     84 * This caller is to be used internally by the firmware_loader only.
     85 **/
     86bool firmware_request_builtin_buf(struct firmware *fw, const char *name,
     87				  void *buf, size_t size)
     88{
     89	if (!firmware_request_builtin(fw, name))
     90		return false;
     91
     92	return fw_copy_to_prealloc_buf(fw, buf, size);
     93}
     94
     95bool firmware_is_builtin(const struct firmware *fw)
     96{
     97	struct builtin_fw *b_fw;
     98
     99	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++)
    100		if (fw->data == b_fw->data)
    101			return true;
    102
    103	return false;
    104}
    105
    106#endif