From baf2d5bfbac015b27f4db74feab235e167df0c84 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 12 Jan 2017 19:24:14 +0100 Subject: fw-cfg: support writeable blobs Useful to send guest data back to QEMU. Changes from Laszlo Ersek : - rebase the patch from Michael Tsirkin's original postings at [1] and [2] to the following patches: - loader: Allow a custom AddressSpace when loading ROMs - loader: Add AddressSpace loading support to uImages - loader: fix handling of custom address spaces when adding ROM blobs - reject such writes immediately that would exceed the end of the array, rather than performing a partial write before setting the error bit: see the (len != dma.length) condition - document the write interface [1] http://lists.nongnu.org/archive/html/qemu-devel/2016-02/msg04968.html [2] http://lists.nongnu.org/archive/html/qemu-devel/2016-03/msg02735.html Cc: "Gabriel L. Somlo" Cc: "Michael S. Tsirkin" Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Michael Walle Cc: Paolo Bonzini Cc: Peter Maydell Cc: Shannon Zhao Cc: qemu-arm@nongnu.org Signed-off-by: Michael S. Tsirkin Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Acked-by: Gabriel Somlo Tested-by: Gabriel Somlo Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Eduardo Habkost --- hw/core/loader.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'hw/core/loader.c') diff --git a/hw/core/loader.c b/hw/core/loader.c index 45742494e6..ee5abd6eb7 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -853,7 +853,7 @@ static void fw_cfg_resized(const char *id, uint64_t length, void *host) } } -static void *rom_set_mr(Rom *rom, Object *owner, const char *name) +static void *rom_set_mr(Rom *rom, Object *owner, const char *name, bool ro) { void *data; @@ -862,7 +862,7 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name) rom->datasize, rom->romsize, fw_cfg_resized, &error_fatal); - memory_region_set_readonly(rom->mr, true); + memory_region_set_readonly(rom->mr, ro); vmstate_register_ram_global(rom->mr); data = memory_region_get_ram_ptr(rom->mr); @@ -942,7 +942,7 @@ int rom_add_file(const char *file, const char *fw_dir, snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); if ((!option_rom || mc->option_rom_has_mr) && mc->rom_file_has_mr) { - data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); + data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, true); } else { data = rom->data; } @@ -979,7 +979,7 @@ err: MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len, size_t max_len, hwaddr addr, const char *fw_file_name, FWCfgReadCallback fw_callback, void *callback_opaque, - AddressSpace *as) + AddressSpace *as, bool read_only) { MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); Rom *rom; @@ -998,10 +998,14 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len, char devpath[100]; void *data; - snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); + if (read_only) { + snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); + } else { + snprintf(devpath, sizeof(devpath), "/ram@%s", fw_file_name); + } if (mc->rom_file_has_mr) { - data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); + data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, read_only); mr = rom->mr; } else { data = rom->data; @@ -1009,7 +1013,7 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len, fw_cfg_add_file_callback(fw_cfg, fw_file_name, fw_callback, callback_opaque, - data, rom->datasize); + data, rom->datasize, read_only); } return mr; } -- cgit 1.4.1