From f865f4fe293db1dfdfbb2e03963d0c6a25a398cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 13 Dec 2017 13:38:42 +0100 Subject: [PATCH 11/41] fw_cfg: add write callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Marc-André Lureau Message-id: <20171213133912.26176-12-marcandre.lureau@redhat.com> Patchwork-id: 78361 O-Subject: [RHEL-7.5 qemu-kvm PATCH v3 11/41] fw_cfg: add write callback Bugzilla: 1411490 RH-Acked-by: Laszlo Ersek RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Miroslav Rezanina Reintroduce the write callback that was removed when write support was removed in commit 023e3148567ac898c7258138f8e86c3c2bb40d07. Contrary to the previous callback implementation, the write_cb callback is called whenever a write happened, so handlers must be ready to handle partial write as necessary. Signed-off-by: Marc-André Lureau Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin (cherry picked from commit 5f9252f7cc12c5cec1b3c6695aca02eb52ea7acc) RHEL: major conflict due to API changes, but minor functional changes. Signed-off-by: Marc-André Lureau Signed-off-by: Miroslav Rezanina --- hw/core/loader.c | 2 +- hw/nvram/fw_cfg.c | 32 ++++++++++++++++++++------------ include/hw/nvram/fw_cfg.h | 8 ++++++-- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index c824bc2..5a15449 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -700,7 +700,7 @@ void *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, + fw_callback, NULL, callback_opaque, data, rom->romsize, read_only); } return data; diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index a7bc98e..616c782 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -54,6 +54,7 @@ typedef struct FWCfgEntry { uint8_t *data; void *callback_opaque; FWCfgReadCallback read_callback; + FWCfgWriteCallback write_cb; } FWCfgEntry; struct FWCfgState { @@ -365,6 +366,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s) dma_memory_read(s->dma, dma.address, &e->data[s->cur_offset], len)) { dma.control |= FW_CFG_DMA_CTL_ERROR; + } else if (e->write_cb) { + e->write_cb(e->callback_opaque, s->cur_offset, len); } } @@ -556,11 +559,12 @@ static const VMStateDescription vmstate_fw_cfg = { } }; -static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key, - FWCfgReadCallback callback, - void *callback_opaque, - void *data, size_t len, - bool read_only) +static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key, + FWCfgReadCallback callback, + FWCfgWriteCallback write_cb, + void *callback_opaque, + void *data, size_t len, + bool read_only) { int arch = !!(key & FW_CFG_ARCH_LOCAL); @@ -572,13 +576,14 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key, s->entries[arch][key].data = data; s->entries[arch][key].len = (uint32_t)len; s->entries[arch][key].read_callback = callback; + s->entries[arch][key].write_cb = write_cb; s->entries[arch][key].callback_opaque = callback_opaque; s->entries[arch][key].allow_write = !read_only; } void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) { - fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len, true); + fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, true); } void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value) @@ -616,8 +621,11 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value) } void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, - FWCfgReadCallback callback, void *callback_opaque, - void *data, size_t len, bool read_only) + FWCfgReadCallback callback, + FWCfgWriteCallback write_cb, + void *callback_opaque, + void *data, size_t len, + bool read_only) { int i, index; size_t dsize; @@ -641,9 +649,9 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, } } - fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index, - callback, callback_opaque, data, len, - read_only); + fw_cfg_add_bytes_callback(s, FW_CFG_FILE_FIRST + index, + callback, write_cb, callback_opaque, data, len, + read_only); s->files->f[index].size = cpu_to_be32(len); s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index); @@ -655,7 +663,7 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data, size_t len) { - fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len, true); + fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true); } static void fw_cfg_machine_ready(struct Notifier *n, void *data) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 76fc787..a77ab84 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -73,6 +73,7 @@ typedef struct FWCfgDmaAccess { typedef void (*FWCfgCallback)(void *opaque, uint8_t *data); typedef void (*FWCfgReadCallback)(void *opaque, uint32_t offset); +typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len); void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len); void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value); @@ -82,8 +83,11 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value); void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data, size_t len); void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, - FWCfgReadCallback callback, void *callback_opaque, - void *data, size_t len, bool read_only); + FWCfgReadCallback callback, + FWCfgWriteCallback write_cb, + void *callback_opaque, + void *data, size_t len, + bool read_only); FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, hwaddr crl_addr, hwaddr data_addr); FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase, -- 1.8.3.1