2008-09-18 22:27:29 +04:00
|
|
|
#ifndef FW_CFG_H
|
|
|
|
#define FW_CFG_H
|
|
|
|
|
2013-04-26 07:24:43 +04:00
|
|
|
#include "exec/hwaddr.h"
|
2018-08-17 18:59:10 +03:00
|
|
|
#include "standard-headers/linux/qemu_fw_cfg.h"
|
2017-07-14 12:40:08 +03:00
|
|
|
#include "hw/sysbus.h"
|
|
|
|
#include "sysemu/dma.h"
|
2020-09-03 23:43:22 +03:00
|
|
|
#include "qom/object.h"
|
2017-07-14 12:40:08 +03:00
|
|
|
|
|
|
|
#define TYPE_FW_CFG "fw_cfg"
|
|
|
|
#define TYPE_FW_CFG_IO "fw_cfg_io"
|
|
|
|
#define TYPE_FW_CFG_MEM "fw_cfg_mem"
|
2020-05-14 16:15:38 +03:00
|
|
|
#define TYPE_FW_CFG_DATA_GENERATOR_INTERFACE "fw_cfg-data-generator"
|
2017-07-14 12:40:08 +03:00
|
|
|
|
2020-09-16 21:25:19 +03:00
|
|
|
OBJECT_DECLARE_SIMPLE_TYPE(FWCfgState, FW_CFG)
|
|
|
|
OBJECT_DECLARE_SIMPLE_TYPE(FWCfgIoState, FW_CFG_IO)
|
|
|
|
OBJECT_DECLARE_SIMPLE_TYPE(FWCfgMemState, FW_CFG_MEM)
|
2013-04-26 07:24:43 +04:00
|
|
|
|
2020-09-03 23:43:22 +03:00
|
|
|
typedef struct FWCfgDataGeneratorClass FWCfgDataGeneratorClass;
|
2020-09-01 00:07:33 +03:00
|
|
|
DECLARE_CLASS_CHECKERS(FWCfgDataGeneratorClass, FW_CFG_DATA_GENERATOR,
|
2020-05-14 16:15:38 +03:00
|
|
|
TYPE_FW_CFG_DATA_GENERATOR_INTERFACE)
|
|
|
|
|
2020-09-03 23:43:22 +03:00
|
|
|
struct FWCfgDataGeneratorClass {
|
2020-05-14 16:15:38 +03:00
|
|
|
/*< private >*/
|
|
|
|
InterfaceClass parent_class;
|
|
|
|
/*< public >*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get_data:
|
|
|
|
* @obj: the object implementing this interface
|
|
|
|
* @errp: pointer to a NULL-initialized error object
|
|
|
|
*
|
2020-07-21 16:05:51 +03:00
|
|
|
* Returns: reference to a byte array containing the data on success,
|
|
|
|
* or NULL on error.
|
|
|
|
*
|
2020-05-14 16:15:38 +03:00
|
|
|
* The caller should release the reference when no longer
|
|
|
|
* required.
|
|
|
|
*/
|
|
|
|
GByteArray *(*get_data)(Object *obj, Error **errp);
|
2020-09-03 23:43:22 +03:00
|
|
|
};
|
2020-05-14 16:15:38 +03:00
|
|
|
|
2018-08-17 18:59:10 +03:00
|
|
|
typedef struct fw_cfg_file FWCfgFile;
|
2009-12-18 14:01:10 +03:00
|
|
|
|
2016-04-07 17:12:58 +03:00
|
|
|
#define FW_CFG_ORDER_OVERRIDE_VGA 70
|
|
|
|
#define FW_CFG_ORDER_OVERRIDE_NIC 80
|
|
|
|
#define FW_CFG_ORDER_OVERRIDE_USER 100
|
|
|
|
#define FW_CFG_ORDER_OVERRIDE_DEVICE 110
|
|
|
|
|
|
|
|
void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order);
|
|
|
|
void fw_cfg_reset_order_override(FWCfgState *fw_cfg);
|
|
|
|
|
2009-12-18 14:01:10 +03:00
|
|
|
typedef struct FWCfgFiles {
|
|
|
|
uint32_t count;
|
|
|
|
FWCfgFile f[];
|
|
|
|
} FWCfgFiles;
|
|
|
|
|
2018-08-17 18:59:10 +03:00
|
|
|
typedef struct fw_cfg_dma_access FWCfgDmaAccess;
|
2015-10-08 18:02:55 +03:00
|
|
|
|
2017-08-07 21:16:11 +03:00
|
|
|
typedef void (*FWCfgCallback)(void *opaque);
|
2017-09-11 19:59:23 +03:00
|
|
|
typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len);
|
2008-09-18 22:27:29 +04:00
|
|
|
|
2017-07-14 12:40:08 +03:00
|
|
|
struct FWCfgState {
|
|
|
|
/*< private >*/
|
|
|
|
SysBusDevice parent_obj;
|
|
|
|
/*< public >*/
|
|
|
|
|
|
|
|
uint16_t file_slots;
|
|
|
|
FWCfgEntry *entries[2];
|
|
|
|
int *entry_order;
|
|
|
|
FWCfgFiles *files;
|
|
|
|
uint16_t cur_entry;
|
|
|
|
uint32_t cur_offset;
|
|
|
|
Notifier machine_ready;
|
|
|
|
|
|
|
|
int fw_cfg_order_override;
|
|
|
|
|
|
|
|
bool dma_enabled;
|
|
|
|
dma_addr_t dma_addr;
|
|
|
|
AddressSpace *dma_as;
|
|
|
|
MemoryRegion dma_iomem;
|
2020-04-03 13:18:26 +03:00
|
|
|
|
|
|
|
/* restore during migration */
|
|
|
|
bool acpi_mr_restore;
|
|
|
|
uint64_t table_mr_size;
|
|
|
|
uint64_t linker_mr_size;
|
|
|
|
uint64_t rsdp_mr_size;
|
2017-07-14 12:40:08 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FWCfgIoState {
|
|
|
|
/*< private >*/
|
|
|
|
FWCfgState parent_obj;
|
|
|
|
/*< public >*/
|
|
|
|
|
|
|
|
MemoryRegion comb_iomem;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FWCfgMemState {
|
|
|
|
/*< private >*/
|
|
|
|
FWCfgState parent_obj;
|
|
|
|
/*< public >*/
|
|
|
|
|
|
|
|
MemoryRegion ctl_iomem, data_iomem;
|
|
|
|
uint32_t data_width;
|
|
|
|
MemoryRegionOps wide_data_ops;
|
|
|
|
};
|
|
|
|
|
2015-11-05 17:32:47 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_bytes:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @data: pointer to start of item data
|
|
|
|
* @len: size of item data
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item, available by selecting the given key, as a raw
|
|
|
|
* "blob" of the given size. The data referenced by the starting pointer
|
|
|
|
* is only linked, NOT copied, into the data structure of the fw_cfg device.
|
|
|
|
*/
|
2013-01-16 17:50:28 +04:00
|
|
|
void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
x86: return modified setup_data only if read as memory, not as file
If setup_data is being read into a specific memory location, then
generally the setup_data address parameter is read first, so that the
caller knows where to read it into. In that case, we should return
setup_data containing the absolute addresses that are hard coded and
determined a priori. This is the case when kernels are loaded by BIOS,
for example. In contrast, when setup_data is read as a file, then we
shouldn't modify setup_data, since the absolute address will be wrong by
definition. This is the case when OVMF loads the image.
This allows setup_data to be used like normal, without crashing when EFI
tries to use it.
(As a small development note, strangely, fw_cfg_add_file_callback() was
exported but fw_cfg_add_bytes_callback() wasn't, so this makes that
consistent.)
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Laurent Vivier <laurent@vivier.eu>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: Richard Henderson <richard.henderson@linaro.org>
Suggested-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Message-Id: <20220921093134.2936487-1-Jason@zx2c4.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-09-21 12:31:31 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_bytes_callback:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @select_cb: callback function when selecting
|
|
|
|
* @write_cb: callback function after a write
|
|
|
|
* @callback_opaque: argument to be passed into callback function
|
|
|
|
* @data: pointer to start of item data
|
|
|
|
* @len: size of item data
|
|
|
|
* @read_only: is file read only
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item, available by selecting the given key, as a raw
|
|
|
|
* "blob" of the given size. The data referenced by the starting pointer
|
|
|
|
* is only linked, NOT copied, into the data structure of the fw_cfg device.
|
|
|
|
*/
|
|
|
|
void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
|
|
|
|
FWCfgCallback select_cb,
|
|
|
|
FWCfgWriteCallback write_cb,
|
|
|
|
void *callback_opaque,
|
|
|
|
void *data, size_t len,
|
|
|
|
bool read_only);
|
|
|
|
|
x86: don't let decompressed kernel image clobber setup_data
The setup_data links are appended to the compressed kernel image. Since
the kernel image is typically loaded at 0x100000, setup_data lives at
`0x100000 + compressed_size`, which does not get relocated during the
kernel's boot process.
The kernel typically decompresses the image starting at address
0x1000000 (note: there's one more zero there than the compressed image
above). This usually is fine for most kernels.
However, if the compressed image is actually quite large, then
setup_data will live at a `0x100000 + compressed_size` that extends into
the decompressed zone at 0x1000000. In other words, if compressed_size
is larger than `0x1000000 - 0x100000`, then the decompression step will
clobber setup_data, resulting in crashes.
Visually, what happens now is that QEMU appends setup_data to the kernel
image:
kernel image setup_data
|--------------------------||----------------|
0x100000 0x100000+l1 0x100000+l1+l2
The problem is that this decompresses to 0x1000000 (one more zero). So
if l1 is > (0x1000000-0x100000), then this winds up looking like:
kernel image setup_data
|--------------------------||----------------|
0x100000 0x100000+l1 0x100000+l1+l2
d e c o m p r e s s e d k e r n e l
|-------------------------------------------------------------|
0x1000000 0x1000000+l3
The decompressed kernel seemingly overwriting the compressed kernel
image isn't a problem, because that gets relocated to a higher address
early on in the boot process, at the end of startup_64. setup_data,
however, stays in the same place, since those links are self referential
and nothing fixes them up. So the decompressed kernel clobbers it.
Fix this by appending setup_data to the cmdline blob rather than the
kernel image blob, which remains at a lower address that won't get
clobbered.
This could have been done by overwriting the initrd blob instead, but
that poses big difficulties, such as no longer being able to use memory
mapped files for initrd, hurting performance, and, more importantly, the
initrd address calculation is hard coded in qboot, and it always grows
down rather than up, which means lots of brittle semantics would have to
be changed around, incurring more complexity. In contrast, using cmdline
is simple and doesn't interfere with anything.
The microvm machine has a gross hack where it fiddles with fw_cfg data
after the fact. So this hack is updated to account for this appending,
by reserving some bytes.
Fixup-by: Michael S. Tsirkin <mst@redhat.com>
Cc: x86@kernel.org
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Message-Id: <20221230220725.618763-1-Jason@zx2c4.com>
Message-ID: <20230128061015-mutt-send-email-mst@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Eric Biggers <ebiggers@google.com>
Tested-by: Mathias Krause <minipli@grsecurity.net>
2022-12-31 01:07:25 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_read_bytes_ptr:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
*
|
|
|
|
* Reads an existing fw_cfg data pointer.
|
|
|
|
*/
|
|
|
|
void *fw_cfg_read_bytes_ptr(FWCfgState *s, uint16_t key);
|
|
|
|
|
2015-11-05 17:32:47 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_string:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: NUL-terminated ascii string
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item, available by selecting the given key. The item
|
|
|
|
* data will consist of a dynamically allocated copy of the provided string,
|
|
|
|
* including its NUL terminator.
|
|
|
|
*/
|
2013-01-16 17:50:24 +04:00
|
|
|
void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
2019-09-24 12:38:18 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_modify_string:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: NUL-terminated ascii string
|
|
|
|
*
|
|
|
|
* Replace the fw_cfg item available by selecting the given key. The new
|
|
|
|
* data will consist of a dynamically allocated copy of the provided string,
|
|
|
|
* including its NUL terminator. The data being replaced, assumed to have
|
|
|
|
* been dynamically allocated during an earlier call to either
|
|
|
|
* fw_cfg_add_string() or fw_cfg_modify_string(), is freed before returning.
|
|
|
|
*/
|
|
|
|
void fw_cfg_modify_string(FWCfgState *s, uint16_t key, const char *value);
|
|
|
|
|
2015-11-05 17:32:47 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_i16:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: 16-bit integer
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item, available by selecting the given key. The item
|
|
|
|
* data will consist of a dynamically allocated copy of the given 16-bit
|
|
|
|
* value, converted to little-endian representation.
|
|
|
|
*/
|
2013-01-16 17:50:23 +04:00
|
|
|
void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* fw_cfg_modify_i16:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: 16-bit integer
|
|
|
|
*
|
|
|
|
* Replace the fw_cfg item available by selecting the given key. The new
|
|
|
|
* data will consist of a dynamically allocated copy of the given 16-bit
|
|
|
|
* value, converted to little-endian representation. The data being replaced,
|
|
|
|
* assumed to have been dynamically allocated during an earlier call to
|
|
|
|
* either fw_cfg_add_i16() or fw_cfg_modify_i16(), is freed before returning.
|
|
|
|
*/
|
2015-06-08 21:10:44 +03:00
|
|
|
void fw_cfg_modify_i16(FWCfgState *s, uint16_t key, uint16_t value);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* fw_cfg_add_i32:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: 32-bit integer
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item, available by selecting the given key. The item
|
|
|
|
* data will consist of a dynamically allocated copy of the given 32-bit
|
|
|
|
* value, converted to little-endian representation.
|
|
|
|
*/
|
2013-01-16 17:50:23 +04:00
|
|
|
void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
2019-09-24 12:38:18 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_modify_i32:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: 32-bit integer
|
|
|
|
*
|
|
|
|
* Replace the fw_cfg item available by selecting the given key. The new
|
|
|
|
* data will consist of a dynamically allocated copy of the given 32-bit
|
|
|
|
* value, converted to little-endian representation. The data being replaced,
|
|
|
|
* assumed to have been dynamically allocated during an earlier call to
|
|
|
|
* either fw_cfg_add_i32() or fw_cfg_modify_i32(), is freed before returning.
|
|
|
|
*/
|
|
|
|
void fw_cfg_modify_i32(FWCfgState *s, uint16_t key, uint32_t value);
|
|
|
|
|
2015-11-05 17:32:47 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_i64:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: 64-bit integer
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item, available by selecting the given key. The item
|
|
|
|
* data will consist of a dynamically allocated copy of the given 64-bit
|
|
|
|
* value, converted to little-endian representation.
|
|
|
|
*/
|
2013-01-16 17:50:23 +04:00
|
|
|
void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
2019-09-24 12:38:18 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_modify_i64:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @key: selector key value for new fw_cfg item
|
|
|
|
* @value: 64-bit integer
|
|
|
|
*
|
|
|
|
* Replace the fw_cfg item available by selecting the given key. The new
|
|
|
|
* data will consist of a dynamically allocated copy of the given 64-bit
|
|
|
|
* value, converted to little-endian representation. The data being replaced,
|
|
|
|
* assumed to have been dynamically allocated during an earlier call to
|
|
|
|
* either fw_cfg_add_i64() or fw_cfg_modify_i64(), is freed before returning.
|
|
|
|
*/
|
|
|
|
void fw_cfg_modify_i64(FWCfgState *s, uint16_t key, uint64_t value);
|
|
|
|
|
2015-11-05 17:32:47 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_file:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @filename: name of new fw_cfg file item
|
|
|
|
* @data: pointer to start of item data
|
|
|
|
* @len: size of item data
|
|
|
|
*
|
|
|
|
* Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
|
|
|
|
* referenced by the starting pointer is only linked, NOT copied, into the
|
|
|
|
* data structure of the fw_cfg device.
|
|
|
|
* The next available (unused) selector key starting at FW_CFG_FILE_FIRST
|
|
|
|
* will be used; also, a new entry will be added to the file directory
|
|
|
|
* structure residing at key value FW_CFG_FILE_DIR, containing the item name,
|
|
|
|
* data size, and assigned selector key value.
|
|
|
|
*/
|
2013-01-16 17:50:28 +04:00
|
|
|
void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
|
|
|
|
size_t len);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* fw_cfg_add_file_callback:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @filename: name of new fw_cfg file item
|
2017-08-07 21:16:11 +03:00
|
|
|
* @select_cb: callback function when selecting
|
2017-09-11 19:59:23 +03:00
|
|
|
* @write_cb: callback function after a write
|
2015-11-05 17:32:47 +03:00
|
|
|
* @callback_opaque: argument to be passed into callback function
|
|
|
|
* @data: pointer to start of item data
|
|
|
|
* @len: size of item data
|
2017-01-12 21:24:14 +03:00
|
|
|
* @read_only: is file read only
|
2015-11-05 17:32:47 +03:00
|
|
|
*
|
|
|
|
* Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
|
|
|
|
* referenced by the starting pointer is only linked, NOT copied, into the
|
|
|
|
* data structure of the fw_cfg device.
|
|
|
|
* The next available (unused) selector key starting at FW_CFG_FILE_FIRST
|
|
|
|
* will be used; also, a new entry will be added to the file directory
|
|
|
|
* structure residing at key value FW_CFG_FILE_DIR, containing the item name,
|
|
|
|
* data size, and assigned selector key value.
|
|
|
|
* Additionally, set a callback function (and argument) to be called each
|
fw_cfg: amend callback behavior spec to once per select
Currently, the fw_cfg internal API specifies that if an item was set up
with a read callback, the callback must be run each time a byte is read
from the item. This behavior is both wasteful (most items do not have a
read callback set), and impractical for bulk transfers (e.g., DMA read).
At the time of this writing, the only items configured with a callback
are "/etc/table-loader", "/etc/acpi/tables", and "/etc/acpi/rsdp". They
all share the same callback functions: virt_acpi_build_update() on ARM
(in hw/arm/virt-acpi-build.c), and acpi_build_update() on i386 (in
hw/i386/acpi.c). Both of these callbacks are one-shot (i.e. they return
without doing anything at all after the first time they are invoked with
a given build_state; since build_state is also shared across all three
items mentioned above, the callback only ever runs *once*, the first
time either of the listed items is read).
This patch amends the specification for fw_cfg_add_file_callback() to
state that any available read callback will only be invoked once each
time the item is selected. This change has no practical effect on the
current behavior of QEMU, and it enables us to significantly optimize
the behavior of fw_cfg reads during guest firmware setup, eliminating
a large amount of redundant callback checks and invocations.
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Marc Marí <markmb@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-id: 1446733972-1602-3-git-send-email-somlo@cmu.edu
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2015-11-05 17:32:48 +03:00
|
|
|
* time this item is selected (by having its selector key either written to
|
|
|
|
* the fw_cfg control register, or passed to QEMU in FWCfgDmaAccess.control
|
|
|
|
* with FW_CFG_DMA_CTL_SELECT).
|
2015-11-05 17:32:47 +03:00
|
|
|
*/
|
2013-09-01 18:56:20 +04:00
|
|
|
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
2017-08-07 21:16:11 +03:00
|
|
|
FWCfgCallback select_cb,
|
2017-09-11 19:59:23 +03:00
|
|
|
FWCfgWriteCallback write_cb,
|
2017-08-07 21:16:11 +03:00
|
|
|
void *callback_opaque,
|
2017-01-12 21:24:14 +03:00
|
|
|
void *data, size_t len, bool read_only);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* fw_cfg_modify_file:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @filename: name of new fw_cfg file item
|
|
|
|
* @data: pointer to start of item data
|
|
|
|
* @len: size of item data
|
|
|
|
*
|
|
|
|
* Replace a NAMED fw_cfg item. If an existing item is found, its callback
|
|
|
|
* information will be cleared, and a pointer to its data will be returned
|
|
|
|
* to the caller, so that it may be freed if necessary. If an existing item
|
|
|
|
* is not found, this call defaults to fw_cfg_add_file(), and NULL is
|
|
|
|
* returned to the caller.
|
|
|
|
* In either case, the new item data is only linked, NOT copied, into the
|
|
|
|
* data structure of the fw_cfg device.
|
|
|
|
*
|
|
|
|
* Returns: pointer to old item's data, or NULL if old item does not exist.
|
|
|
|
*/
|
2014-10-07 12:00:08 +04:00
|
|
|
void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
|
|
|
|
size_t len);
|
2015-11-05 17:32:47 +03:00
|
|
|
|
2020-05-14 16:15:38 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_from_generator:
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
* @filename: name of new fw_cfg file item
|
|
|
|
* @gen_id: name of object implementing FW_CFG_DATA_GENERATOR interface
|
|
|
|
* @errp: pointer to a NULL initialized error object
|
|
|
|
*
|
|
|
|
* Add a new NAMED fw_cfg item with the content generated from the
|
|
|
|
* @gen_id object. The data generated by the @gen_id object is copied
|
|
|
|
* into the data structure of the fw_cfg device.
|
|
|
|
* The next available (unused) selector key starting at FW_CFG_FILE_FIRST
|
|
|
|
* will be used; also, a new entry will be added to the file directory
|
|
|
|
* structure residing at key value FW_CFG_FILE_DIR, containing the item name,
|
|
|
|
* data size, and assigned selector key value.
|
hw/nvram/fw_cfg: Let fw_cfg_add_from_generator() return boolean value
Commits b6d7e9b66f..a43770df5d simplified the error propagation.
Similarly to commit 6fd5bef10b "qom: Make functions taking Error**
return bool, not void", let fw_cfg_add_from_generator() return a
boolean value, not void.
This allow to simplify parse_fw_cfg() and fixes the error handling
issue reported by Coverity (CID 1430396):
In parse_fw_cfg():
Variable assigned once to a constant guards dead code.
Local variable local_err is assigned only once, to a constant
value, making it effectively constant throughout its scope.
If this is not the intent, examine the logic to see if there
is a missing assignment that would make local_err not remain
constant.
It's the call of fw_cfg_add_from_generator():
Error *local_err = NULL;
fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp);
if (local_err) {
error_propagate(errp, local_err);
return -1;
}
return 0;
If it fails, parse_fw_cfg() sets an error and returns 0, which is
wrong. Harmless, because the only caller passes &error_fatal.
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: Coverity CID 1430396: 'Constant' variable guards dead code (DEADCODE)
Fixes: 6552d87c48 ("softmmu/vl: Let -fw_cfg option take a 'gen_id' argument")
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200721131911.27380-3-philmd@redhat.com>
2020-07-20 15:20:15 +03:00
|
|
|
*
|
|
|
|
* Returns: %true on success, %false on error.
|
2020-05-14 16:15:38 +03:00
|
|
|
*/
|
hw/nvram/fw_cfg: Let fw_cfg_add_from_generator() return boolean value
Commits b6d7e9b66f..a43770df5d simplified the error propagation.
Similarly to commit 6fd5bef10b "qom: Make functions taking Error**
return bool, not void", let fw_cfg_add_from_generator() return a
boolean value, not void.
This allow to simplify parse_fw_cfg() and fixes the error handling
issue reported by Coverity (CID 1430396):
In parse_fw_cfg():
Variable assigned once to a constant guards dead code.
Local variable local_err is assigned only once, to a constant
value, making it effectively constant throughout its scope.
If this is not the intent, examine the logic to see if there
is a missing assignment that would make local_err not remain
constant.
It's the call of fw_cfg_add_from_generator():
Error *local_err = NULL;
fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp);
if (local_err) {
error_propagate(errp, local_err);
return -1;
}
return 0;
If it fails, parse_fw_cfg() sets an error and returns 0, which is
wrong. Harmless, because the only caller passes &error_fatal.
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: Coverity CID 1430396: 'Constant' variable guards dead code (DEADCODE)
Fixes: 6552d87c48 ("softmmu/vl: Let -fw_cfg option take a 'gen_id' argument")
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200721131911.27380-3-philmd@redhat.com>
2020-07-20 15:20:15 +03:00
|
|
|
bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename,
|
2020-05-14 16:15:38 +03:00
|
|
|
const char *gen_id, Error **errp);
|
|
|
|
|
2020-11-19 04:48:34 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_add_extra_pci_roots:
|
|
|
|
* @bus: main pci root bus to be scanned from
|
|
|
|
* @s: fw_cfg device being modified
|
|
|
|
*
|
|
|
|
* Add a new fw_cfg item...
|
|
|
|
*/
|
|
|
|
void fw_cfg_add_extra_pci_roots(PCIBus *bus, FWCfgState *s);
|
|
|
|
|
2015-10-08 18:02:55 +03:00
|
|
|
FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
|
|
|
|
AddressSpace *dma_as);
|
2014-12-22 15:11:35 +03:00
|
|
|
FWCfgState *fw_cfg_init_io(uint32_t iobase);
|
|
|
|
FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr);
|
2015-10-08 18:02:55 +03:00
|
|
|
FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
|
|
|
|
hwaddr data_addr, uint32_t data_width,
|
|
|
|
hwaddr dma_addr, AddressSpace *dma_as);
|
2008-09-18 22:27:29 +04:00
|
|
|
|
2013-05-30 17:07:58 +04:00
|
|
|
FWCfgState *fw_cfg_find(void);
|
2016-05-23 21:11:33 +03:00
|
|
|
bool fw_cfg_dma_enabled(void *opaque);
|
2013-05-30 17:07:58 +04:00
|
|
|
|
2019-04-22 16:49:41 +03:00
|
|
|
/**
|
|
|
|
* fw_cfg_arch_key_name:
|
|
|
|
*
|
|
|
|
* @key: The uint16 selector key.
|
|
|
|
*
|
|
|
|
* The key is architecture-specific (the FW_CFG_ARCH_LOCAL mask is expected
|
|
|
|
* to be set in the key).
|
|
|
|
*
|
|
|
|
* Returns: The stringified architecture-specific name if the selector
|
|
|
|
* refers to a well-known numerically defined item, or NULL on
|
|
|
|
* key lookup failure.
|
|
|
|
*/
|
|
|
|
const char *fw_cfg_arch_key_name(uint16_t key);
|
|
|
|
|
2022-10-04 12:23:49 +03:00
|
|
|
/**
|
|
|
|
* load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified
|
|
|
|
* by key.
|
|
|
|
* @fw_cfg: The firmware config instance to store the data in.
|
|
|
|
* @size_key: The firmware config key to store the size of the loaded
|
|
|
|
* data under, with fw_cfg_add_i32().
|
|
|
|
* @data_key: The firmware config key to store the loaded data under,
|
|
|
|
* with fw_cfg_add_bytes().
|
|
|
|
* @image_name: The name of the image file to load. If it is NULL, the
|
|
|
|
* function returns without doing anything.
|
|
|
|
* @try_decompress: Whether the image should be decompressed (gunzipped) before
|
|
|
|
* adding it to fw_cfg. If decompression fails, the image is
|
|
|
|
* loaded as-is.
|
|
|
|
*
|
|
|
|
* In case of failure, the function prints an error message to stderr and the
|
|
|
|
* process exits with status 1.
|
|
|
|
*/
|
|
|
|
void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
|
|
|
|
uint16_t data_key, const char *image_name,
|
|
|
|
bool try_decompress);
|
|
|
|
|
2008-09-18 22:27:29 +04:00
|
|
|
#endif
|