diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 85f0186a..33870583 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_aarch64 #define memory_region_dispatch_read1 memory_region_dispatch_read1_aarch64 #define memory_region_dispatch_write memory_region_dispatch_write_aarch64 +#define memory_region_do_writeback memory_region_do_writeback_aarch64 #define memory_region_escape_name memory_region_escape_name_aarch64 #define memory_region_finalize memory_region_finalize_aarch64 #define memory_region_find memory_region_find_aarch64 @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_aarch64 #define qemu_clock_ptr qemu_clock_ptr_aarch64 #define qemu_clocks qemu_clocks_aarch64 +#define qemu_fdatasync qemu_fdatasync_aarch64 #define qemu_get_cpu qemu_get_cpu_aarch64 #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_aarch64 #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_aarch64 @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_aarch64 #define qemu_ram_block_by_name qemu_ram_block_by_name_aarch64 #define qemu_ram_block_from_host qemu_ram_block_from_host_aarch64 +#define qemu_ram_block_writeback qemu_ram_block_writeback_aarch64 #define qemu_ram_foreach_block qemu_ram_foreach_block_aarch64 #define qemu_ram_free qemu_ram_free_aarch64 #define qemu_ram_get_idstr qemu_ram_get_idstr_aarch64 @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_aarch64 #define qemu_ram_setup_dump qemu_ram_setup_dump_aarch64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_aarch64 +#define qemu_ram_writeback qemu_ram_writeback_aarch64 #define qemu_st_helpers qemu_st_helpers_aarch64 #define qemu_strnlen qemu_strnlen_aarch64 #define qemu_strsep qemu_strsep_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 4a53ae94..56b854b8 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_aarch64eb #define memory_region_dispatch_read1 memory_region_dispatch_read1_aarch64eb #define memory_region_dispatch_write memory_region_dispatch_write_aarch64eb +#define memory_region_do_writeback memory_region_do_writeback_aarch64eb #define memory_region_escape_name memory_region_escape_name_aarch64eb #define memory_region_finalize memory_region_finalize_aarch64eb #define memory_region_find memory_region_find_aarch64eb @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_aarch64eb #define qemu_clock_ptr qemu_clock_ptr_aarch64eb #define qemu_clocks qemu_clocks_aarch64eb +#define qemu_fdatasync qemu_fdatasync_aarch64eb #define qemu_get_cpu qemu_get_cpu_aarch64eb #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_aarch64eb #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_aarch64eb @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_aarch64eb #define qemu_ram_block_by_name qemu_ram_block_by_name_aarch64eb #define qemu_ram_block_from_host qemu_ram_block_from_host_aarch64eb +#define qemu_ram_block_writeback qemu_ram_block_writeback_aarch64eb #define qemu_ram_foreach_block qemu_ram_foreach_block_aarch64eb #define qemu_ram_free qemu_ram_free_aarch64eb #define qemu_ram_get_idstr qemu_ram_get_idstr_aarch64eb @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_aarch64eb #define qemu_ram_setup_dump qemu_ram_setup_dump_aarch64eb #define qemu_ram_unset_idstr qemu_ram_unset_idstr_aarch64eb +#define qemu_ram_writeback qemu_ram_writeback_aarch64eb #define qemu_st_helpers qemu_st_helpers_aarch64eb #define qemu_strnlen qemu_strnlen_aarch64eb #define qemu_strsep qemu_strsep_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index e86d8096..088eaf9e 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_arm #define memory_region_dispatch_read1 memory_region_dispatch_read1_arm #define memory_region_dispatch_write memory_region_dispatch_write_arm +#define memory_region_do_writeback memory_region_do_writeback_arm #define memory_region_escape_name memory_region_escape_name_arm #define memory_region_finalize memory_region_finalize_arm #define memory_region_find memory_region_find_arm @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_arm #define qemu_clock_ptr qemu_clock_ptr_arm #define qemu_clocks qemu_clocks_arm +#define qemu_fdatasync qemu_fdatasync_arm #define qemu_get_cpu qemu_get_cpu_arm #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_arm #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_arm @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_arm #define qemu_ram_block_by_name qemu_ram_block_by_name_arm #define qemu_ram_block_from_host qemu_ram_block_from_host_arm +#define qemu_ram_block_writeback qemu_ram_block_writeback_arm #define qemu_ram_foreach_block qemu_ram_foreach_block_arm #define qemu_ram_free qemu_ram_free_arm #define qemu_ram_get_idstr qemu_ram_get_idstr_arm @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_arm #define qemu_ram_setup_dump qemu_ram_setup_dump_arm #define qemu_ram_unset_idstr qemu_ram_unset_idstr_arm +#define qemu_ram_writeback qemu_ram_writeback_arm #define qemu_st_helpers qemu_st_helpers_arm #define qemu_strnlen qemu_strnlen_arm #define qemu_strsep qemu_strsep_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 532e4cad..b7e1cc07 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_armeb #define memory_region_dispatch_read1 memory_region_dispatch_read1_armeb #define memory_region_dispatch_write memory_region_dispatch_write_armeb +#define memory_region_do_writeback memory_region_do_writeback_armeb #define memory_region_escape_name memory_region_escape_name_armeb #define memory_region_finalize memory_region_finalize_armeb #define memory_region_find memory_region_find_armeb @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_armeb #define qemu_clock_ptr qemu_clock_ptr_armeb #define qemu_clocks qemu_clocks_armeb +#define qemu_fdatasync qemu_fdatasync_armeb #define qemu_get_cpu qemu_get_cpu_armeb #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_armeb #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_armeb @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_armeb #define qemu_ram_block_by_name qemu_ram_block_by_name_armeb #define qemu_ram_block_from_host qemu_ram_block_from_host_armeb +#define qemu_ram_block_writeback qemu_ram_block_writeback_armeb #define qemu_ram_foreach_block qemu_ram_foreach_block_armeb #define qemu_ram_free qemu_ram_free_armeb #define qemu_ram_get_idstr qemu_ram_get_idstr_armeb @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_armeb #define qemu_ram_setup_dump qemu_ram_setup_dump_armeb #define qemu_ram_unset_idstr qemu_ram_unset_idstr_armeb +#define qemu_ram_writeback qemu_ram_writeback_armeb #define qemu_st_helpers qemu_st_helpers_armeb #define qemu_strnlen qemu_strnlen_armeb #define qemu_strsep qemu_strsep_armeb diff --git a/qemu/exec.c b/qemu/exec.c index 0aced085..c1d5279b 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -1341,6 +1341,40 @@ int qemu_ram_resize(struct uc_struct *uc, RAMBlock *block, ram_addr_t newsize, E return 0; } +/* + * Trigger sync on the given ram block for range [start, start + length] + * with the backing store if one is available. + * Otherwise no-op. + * @Note: this is supposed to be a synchronous op. + */ +void qemu_ram_writeback(struct uc_struct *uc, RAMBlock *block, ram_addr_t start, ram_addr_t length) +{ + void *addr = ramblock_ptr(block, start); + + /* The requested range should fit in within the block range */ + g_assert((start + length) <= block->used_length); + +#ifdef CONFIG_LIBPMEM + /* The lack of support for pmem should not block the sync */ + if (ramblock_is_pmem(block)) { + pmem_persist(addr, length); + return; + } +#endif + if (block->fd >= 0) { + /** + * Case there is no support for PMEM or the memory has not been + * specified as persistent (or is not one) - use the msync. + * Less optimal but still achieves the same goal + */ + if (qemu_msync(uc, addr, length, block->fd)) { + //warn_report("%s: failed to sync memory range: start: " + // RAM_ADDR_FMT " length: " RAM_ADDR_FMT, + // __func__, start, length); + } + } +} + static void ram_block_add(struct uc_struct *uc, RAMBlock *new_block, Error **errp) { RAMBlock *block; diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 08c3b4c0..60f484bd 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2030,6 +2030,7 @@ symbols = ( 'memory_region_dispatch_read', 'memory_region_dispatch_read1', 'memory_region_dispatch_write', + 'memory_region_do_writeback', 'memory_region_escape_name', 'memory_region_finalize', 'memory_region_find', @@ -2390,6 +2391,7 @@ symbols = ( 'qemu_clock_get_us', 'qemu_clock_ptr', 'qemu_clocks', + 'qemu_fdatasync', 'qemu_get_cpu', 'qemu_get_guest_memory_mapping', 'qemu_get_guest_simple_memory_mapping', @@ -2411,6 +2413,7 @@ symbols = ( 'qemu_ram_alloc_resizeable', 'qemu_ram_block_by_name', 'qemu_ram_block_from_host', + 'qemu_ram_block_writeback', 'qemu_ram_foreach_block', 'qemu_ram_free', 'qemu_ram_get_idstr', @@ -2420,6 +2423,7 @@ symbols = ( 'qemu_ram_resize', 'qemu_ram_setup_dump', 'qemu_ram_unset_idstr', + 'qemu_ram_writeback', 'qemu_st_helpers', 'qemu_strnlen', 'qemu_strsep', diff --git a/qemu/include/exec/memory.h b/qemu/include/exec/memory.h index 0e99eddf..459eb51d 100644 --- a/qemu/include/exec/memory.h +++ b/qemu/include/exec/memory.h @@ -742,6 +742,13 @@ MemoryRegion *memory_region_from_host(struct uc_struct *uc, void *ptr, ram_addr_ */ void *memory_region_get_ram_ptr(MemoryRegion *mr); +/** + * memory_region_do_writeback: Trigger writeback for selected address range + * [addr, addr + size] + * + */ +void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size); + /** * memory_region_set_readonly: Turn a memory region read-only (or read-write) * diff --git a/qemu/include/exec/ram_addr.h b/qemu/include/exec/ram_addr.h index a0af6aee..44de062a 100644 --- a/qemu/include/exec/ram_addr.h +++ b/qemu/include/exec/ram_addr.h @@ -65,6 +65,14 @@ void qemu_ram_free(struct uc_struct *c, ram_addr_t addr); int qemu_ram_resize(struct uc_struct *c, RAMBlock *block, ram_addr_t newsize, Error **errp); +void qemu_ram_writeback(struct uc_struct *uc, RAMBlock *block, ram_addr_t start, ram_addr_t length); + +/* Clear whole block of mem */ +static inline void qemu_ram_block_writeback(struct uc_struct *uc, RAMBlock *block) +{ + qemu_ram_writeback(uc, block, 0, block->used_length); +} + #define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1) #define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE)) diff --git a/qemu/include/qemu/cutils.h b/qemu/include/qemu/cutils.h index 0a7201fd..ffb849fc 100644 --- a/qemu/include/qemu/cutils.h +++ b/qemu/include/qemu/cutils.h @@ -2,6 +2,7 @@ #define QEMU_CUTILS_H #include "qemu/fprintf-fn.h" +#include "uc_priv.h" /** * pstrcpy: @@ -122,6 +123,10 @@ int qemu_strnlen(const char *s, int max_len); * Returns: the pointer originally in @input. */ char *qemu_strsep(char **input, const char *delim); + +int qemu_fdatasync(int fd); +int qemu_msync(struct uc_struct *uc, void *addr, size_t length, int fd); + int qemu_strtoi(const char *nptr, const char **endptr, int base, int *result); int qemu_strtoui(const char *nptr, const char **endptr, int base, diff --git a/qemu/m68k.h b/qemu/m68k.h index 064601ee..27dc87f4 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_m68k #define memory_region_dispatch_read1 memory_region_dispatch_read1_m68k #define memory_region_dispatch_write memory_region_dispatch_write_m68k +#define memory_region_do_writeback memory_region_do_writeback_m68k #define memory_region_escape_name memory_region_escape_name_m68k #define memory_region_finalize memory_region_finalize_m68k #define memory_region_find memory_region_find_m68k @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_m68k #define qemu_clock_ptr qemu_clock_ptr_m68k #define qemu_clocks qemu_clocks_m68k +#define qemu_fdatasync qemu_fdatasync_m68k #define qemu_get_cpu qemu_get_cpu_m68k #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_m68k #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_m68k @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_m68k #define qemu_ram_block_by_name qemu_ram_block_by_name_m68k #define qemu_ram_block_from_host qemu_ram_block_from_host_m68k +#define qemu_ram_block_writeback qemu_ram_block_writeback_m68k #define qemu_ram_foreach_block qemu_ram_foreach_block_m68k #define qemu_ram_free qemu_ram_free_m68k #define qemu_ram_get_idstr qemu_ram_get_idstr_m68k @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_m68k #define qemu_ram_setup_dump qemu_ram_setup_dump_m68k #define qemu_ram_unset_idstr qemu_ram_unset_idstr_m68k +#define qemu_ram_writeback qemu_ram_writeback_m68k #define qemu_st_helpers qemu_st_helpers_m68k #define qemu_strnlen qemu_strnlen_m68k #define qemu_strsep qemu_strsep_m68k diff --git a/qemu/memory.c b/qemu/memory.c index c302bc88..24ac79bd 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -1617,6 +1617,17 @@ int memory_region_get_fd(MemoryRegion *mr) return fd; } +void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size) +{ + /* + * Might be extended case needed to cover + * different types of memory regions + */ + if (mr->ram_block && mr->dirty_log_mask) { + qemu_ram_writeback(mr->uc, mr->ram_block, addr, size); + } +} + void *memory_region_get_ram_ptr(MemoryRegion *mr) { void *ptr; diff --git a/qemu/mips.h b/qemu/mips.h index c39bd536..435f0c83 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_mips #define memory_region_dispatch_read1 memory_region_dispatch_read1_mips #define memory_region_dispatch_write memory_region_dispatch_write_mips +#define memory_region_do_writeback memory_region_do_writeback_mips #define memory_region_escape_name memory_region_escape_name_mips #define memory_region_finalize memory_region_finalize_mips #define memory_region_find memory_region_find_mips @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_mips #define qemu_clock_ptr qemu_clock_ptr_mips #define qemu_clocks qemu_clocks_mips +#define qemu_fdatasync qemu_fdatasync_mips #define qemu_get_cpu qemu_get_cpu_mips #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_mips #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_mips @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mips #define qemu_ram_block_by_name qemu_ram_block_by_name_mips #define qemu_ram_block_from_host qemu_ram_block_from_host_mips +#define qemu_ram_block_writeback qemu_ram_block_writeback_mips #define qemu_ram_foreach_block qemu_ram_foreach_block_mips #define qemu_ram_free qemu_ram_free_mips #define qemu_ram_get_idstr qemu_ram_get_idstr_mips @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_mips #define qemu_ram_setup_dump qemu_ram_setup_dump_mips #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mips +#define qemu_ram_writeback qemu_ram_writeback_mips #define qemu_st_helpers qemu_st_helpers_mips #define qemu_strnlen qemu_strnlen_mips #define qemu_strsep qemu_strsep_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index b8f1bf87..282228f1 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_mips64 #define memory_region_dispatch_read1 memory_region_dispatch_read1_mips64 #define memory_region_dispatch_write memory_region_dispatch_write_mips64 +#define memory_region_do_writeback memory_region_do_writeback_mips64 #define memory_region_escape_name memory_region_escape_name_mips64 #define memory_region_finalize memory_region_finalize_mips64 #define memory_region_find memory_region_find_mips64 @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_mips64 #define qemu_clock_ptr qemu_clock_ptr_mips64 #define qemu_clocks qemu_clocks_mips64 +#define qemu_fdatasync qemu_fdatasync_mips64 #define qemu_get_cpu qemu_get_cpu_mips64 #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_mips64 #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_mips64 @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mips64 #define qemu_ram_block_by_name qemu_ram_block_by_name_mips64 #define qemu_ram_block_from_host qemu_ram_block_from_host_mips64 +#define qemu_ram_block_writeback qemu_ram_block_writeback_mips64 #define qemu_ram_foreach_block qemu_ram_foreach_block_mips64 #define qemu_ram_free qemu_ram_free_mips64 #define qemu_ram_get_idstr qemu_ram_get_idstr_mips64 @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_mips64 #define qemu_ram_setup_dump qemu_ram_setup_dump_mips64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mips64 +#define qemu_ram_writeback qemu_ram_writeback_mips64 #define qemu_st_helpers qemu_st_helpers_mips64 #define qemu_strnlen qemu_strnlen_mips64 #define qemu_strsep qemu_strsep_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 4bc359b9..f0f08b3e 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_mips64el #define memory_region_dispatch_read1 memory_region_dispatch_read1_mips64el #define memory_region_dispatch_write memory_region_dispatch_write_mips64el +#define memory_region_do_writeback memory_region_do_writeback_mips64el #define memory_region_escape_name memory_region_escape_name_mips64el #define memory_region_finalize memory_region_finalize_mips64el #define memory_region_find memory_region_find_mips64el @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_mips64el #define qemu_clock_ptr qemu_clock_ptr_mips64el #define qemu_clocks qemu_clocks_mips64el +#define qemu_fdatasync qemu_fdatasync_mips64el #define qemu_get_cpu qemu_get_cpu_mips64el #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_mips64el #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_mips64el @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mips64el #define qemu_ram_block_by_name qemu_ram_block_by_name_mips64el #define qemu_ram_block_from_host qemu_ram_block_from_host_mips64el +#define qemu_ram_block_writeback qemu_ram_block_writeback_mips64el #define qemu_ram_foreach_block qemu_ram_foreach_block_mips64el #define qemu_ram_free qemu_ram_free_mips64el #define qemu_ram_get_idstr qemu_ram_get_idstr_mips64el @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_mips64el #define qemu_ram_setup_dump qemu_ram_setup_dump_mips64el #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mips64el +#define qemu_ram_writeback qemu_ram_writeback_mips64el #define qemu_st_helpers qemu_st_helpers_mips64el #define qemu_strnlen qemu_strnlen_mips64el #define qemu_strsep qemu_strsep_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index b6bdbc28..b69aec56 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_mipsel #define memory_region_dispatch_read1 memory_region_dispatch_read1_mipsel #define memory_region_dispatch_write memory_region_dispatch_write_mipsel +#define memory_region_do_writeback memory_region_do_writeback_mipsel #define memory_region_escape_name memory_region_escape_name_mipsel #define memory_region_finalize memory_region_finalize_mipsel #define memory_region_find memory_region_find_mipsel @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_mipsel #define qemu_clock_ptr qemu_clock_ptr_mipsel #define qemu_clocks qemu_clocks_mipsel +#define qemu_fdatasync qemu_fdatasync_mipsel #define qemu_get_cpu qemu_get_cpu_mipsel #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_mipsel #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_mipsel @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_mipsel #define qemu_ram_block_by_name qemu_ram_block_by_name_mipsel #define qemu_ram_block_from_host qemu_ram_block_from_host_mipsel +#define qemu_ram_block_writeback qemu_ram_block_writeback_mipsel #define qemu_ram_foreach_block qemu_ram_foreach_block_mipsel #define qemu_ram_free qemu_ram_free_mipsel #define qemu_ram_get_idstr qemu_ram_get_idstr_mipsel @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_mipsel #define qemu_ram_setup_dump qemu_ram_setup_dump_mipsel #define qemu_ram_unset_idstr qemu_ram_unset_idstr_mipsel +#define qemu_ram_writeback qemu_ram_writeback_mipsel #define qemu_st_helpers qemu_st_helpers_mipsel #define qemu_strnlen qemu_strnlen_mipsel #define qemu_strsep qemu_strsep_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 75fd4d97..ffde9000 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_powerpc #define memory_region_dispatch_read1 memory_region_dispatch_read1_powerpc #define memory_region_dispatch_write memory_region_dispatch_write_powerpc +#define memory_region_do_writeback memory_region_do_writeback_powerpc #define memory_region_escape_name memory_region_escape_name_powerpc #define memory_region_finalize memory_region_finalize_powerpc #define memory_region_find memory_region_find_powerpc @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_powerpc #define qemu_clock_ptr qemu_clock_ptr_powerpc #define qemu_clocks qemu_clocks_powerpc +#define qemu_fdatasync qemu_fdatasync_powerpc #define qemu_get_cpu qemu_get_cpu_powerpc #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_powerpc #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_powerpc @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_powerpc #define qemu_ram_block_by_name qemu_ram_block_by_name_powerpc #define qemu_ram_block_from_host qemu_ram_block_from_host_powerpc +#define qemu_ram_block_writeback qemu_ram_block_writeback_powerpc #define qemu_ram_foreach_block qemu_ram_foreach_block_powerpc #define qemu_ram_free qemu_ram_free_powerpc #define qemu_ram_get_idstr qemu_ram_get_idstr_powerpc @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_powerpc #define qemu_ram_setup_dump qemu_ram_setup_dump_powerpc #define qemu_ram_unset_idstr qemu_ram_unset_idstr_powerpc +#define qemu_ram_writeback qemu_ram_writeback_powerpc #define qemu_st_helpers qemu_st_helpers_powerpc #define qemu_strnlen qemu_strnlen_powerpc #define qemu_strsep qemu_strsep_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 8ec16e59..0fa3fd41 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_riscv32 #define memory_region_dispatch_read1 memory_region_dispatch_read1_riscv32 #define memory_region_dispatch_write memory_region_dispatch_write_riscv32 +#define memory_region_do_writeback memory_region_do_writeback_riscv32 #define memory_region_escape_name memory_region_escape_name_riscv32 #define memory_region_finalize memory_region_finalize_riscv32 #define memory_region_find memory_region_find_riscv32 @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_riscv32 #define qemu_clock_ptr qemu_clock_ptr_riscv32 #define qemu_clocks qemu_clocks_riscv32 +#define qemu_fdatasync qemu_fdatasync_riscv32 #define qemu_get_cpu qemu_get_cpu_riscv32 #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_riscv32 #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_riscv32 @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_riscv32 #define qemu_ram_block_by_name qemu_ram_block_by_name_riscv32 #define qemu_ram_block_from_host qemu_ram_block_from_host_riscv32 +#define qemu_ram_block_writeback qemu_ram_block_writeback_riscv32 #define qemu_ram_foreach_block qemu_ram_foreach_block_riscv32 #define qemu_ram_free qemu_ram_free_riscv32 #define qemu_ram_get_idstr qemu_ram_get_idstr_riscv32 @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_riscv32 #define qemu_ram_setup_dump qemu_ram_setup_dump_riscv32 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_riscv32 +#define qemu_ram_writeback qemu_ram_writeback_riscv32 #define qemu_st_helpers qemu_st_helpers_riscv32 #define qemu_strnlen qemu_strnlen_riscv32 #define qemu_strsep qemu_strsep_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 1428708d..45377cfb 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_riscv64 #define memory_region_dispatch_read1 memory_region_dispatch_read1_riscv64 #define memory_region_dispatch_write memory_region_dispatch_write_riscv64 +#define memory_region_do_writeback memory_region_do_writeback_riscv64 #define memory_region_escape_name memory_region_escape_name_riscv64 #define memory_region_finalize memory_region_finalize_riscv64 #define memory_region_find memory_region_find_riscv64 @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_riscv64 #define qemu_clock_ptr qemu_clock_ptr_riscv64 #define qemu_clocks qemu_clocks_riscv64 +#define qemu_fdatasync qemu_fdatasync_riscv64 #define qemu_get_cpu qemu_get_cpu_riscv64 #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_riscv64 #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_riscv64 @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_riscv64 #define qemu_ram_block_by_name qemu_ram_block_by_name_riscv64 #define qemu_ram_block_from_host qemu_ram_block_from_host_riscv64 +#define qemu_ram_block_writeback qemu_ram_block_writeback_riscv64 #define qemu_ram_foreach_block qemu_ram_foreach_block_riscv64 #define qemu_ram_free qemu_ram_free_riscv64 #define qemu_ram_get_idstr qemu_ram_get_idstr_riscv64 @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_riscv64 #define qemu_ram_setup_dump qemu_ram_setup_dump_riscv64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_riscv64 +#define qemu_ram_writeback qemu_ram_writeback_riscv64 #define qemu_st_helpers qemu_st_helpers_riscv64 #define qemu_strnlen qemu_strnlen_riscv64 #define qemu_strsep qemu_strsep_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index b9281093..3d210f1e 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_sparc #define memory_region_dispatch_read1 memory_region_dispatch_read1_sparc #define memory_region_dispatch_write memory_region_dispatch_write_sparc +#define memory_region_do_writeback memory_region_do_writeback_sparc #define memory_region_escape_name memory_region_escape_name_sparc #define memory_region_finalize memory_region_finalize_sparc #define memory_region_find memory_region_find_sparc @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_sparc #define qemu_clock_ptr qemu_clock_ptr_sparc #define qemu_clocks qemu_clocks_sparc +#define qemu_fdatasync qemu_fdatasync_sparc #define qemu_get_cpu qemu_get_cpu_sparc #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_sparc #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_sparc @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_sparc #define qemu_ram_block_by_name qemu_ram_block_by_name_sparc #define qemu_ram_block_from_host qemu_ram_block_from_host_sparc +#define qemu_ram_block_writeback qemu_ram_block_writeback_sparc #define qemu_ram_foreach_block qemu_ram_foreach_block_sparc #define qemu_ram_free qemu_ram_free_sparc #define qemu_ram_get_idstr qemu_ram_get_idstr_sparc @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_sparc #define qemu_ram_setup_dump qemu_ram_setup_dump_sparc #define qemu_ram_unset_idstr qemu_ram_unset_idstr_sparc +#define qemu_ram_writeback qemu_ram_writeback_sparc #define qemu_st_helpers qemu_st_helpers_sparc #define qemu_strnlen qemu_strnlen_sparc #define qemu_strsep qemu_strsep_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 8497c938..ea54d204 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_sparc64 #define memory_region_dispatch_read1 memory_region_dispatch_read1_sparc64 #define memory_region_dispatch_write memory_region_dispatch_write_sparc64 +#define memory_region_do_writeback memory_region_do_writeback_sparc64 #define memory_region_escape_name memory_region_escape_name_sparc64 #define memory_region_finalize memory_region_finalize_sparc64 #define memory_region_find memory_region_find_sparc64 @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_sparc64 #define qemu_clock_ptr qemu_clock_ptr_sparc64 #define qemu_clocks qemu_clocks_sparc64 +#define qemu_fdatasync qemu_fdatasync_sparc64 #define qemu_get_cpu qemu_get_cpu_sparc64 #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_sparc64 #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_sparc64 @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_sparc64 #define qemu_ram_block_by_name qemu_ram_block_by_name_sparc64 #define qemu_ram_block_from_host qemu_ram_block_from_host_sparc64 +#define qemu_ram_block_writeback qemu_ram_block_writeback_sparc64 #define qemu_ram_foreach_block qemu_ram_foreach_block_sparc64 #define qemu_ram_free qemu_ram_free_sparc64 #define qemu_ram_get_idstr qemu_ram_get_idstr_sparc64 @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_sparc64 #define qemu_ram_setup_dump qemu_ram_setup_dump_sparc64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_sparc64 +#define qemu_ram_writeback qemu_ram_writeback_sparc64 #define qemu_st_helpers qemu_st_helpers_sparc64 #define qemu_strnlen qemu_strnlen_sparc64 #define qemu_strsep qemu_strsep_sparc64 diff --git a/qemu/util/cutils.c b/qemu/util/cutils.c index 199ad3b1..6e6845e5 100644 --- a/qemu/util/cutils.c +++ b/qemu/util/cutils.c @@ -26,6 +26,9 @@ #include "qemu/host-utils.h" #include "qemu/cutils.h" #include +#include + +#include "uc_priv.h" void strpadcpy(char *buf, int buf_size, const char *str, char pad) { @@ -554,3 +557,57 @@ int qemu_strtod_finite(const char *nptr, const char **endptr, double *result) } return ret; } + +/* + * Make sure data goes on disk, but if possible do not bother to + * write out the inode just for timestamp updates. + * + * Unfortunately even in 2009 many operating systems do not support + * fdatasync and have to fall back to fsync. + */ +int qemu_fdatasync(int fd) +{ +#ifdef CONFIG_FDATASYNC + return fdatasync(fd); +#else + return fsync(fd); +#endif +} + +/** + * Sync changes made to the memory mapped file back to the backing + * storage. For POSIX compliant systems this will fallback + * to regular msync call. Otherwise it will trigger whole file sync + * (including the metadata case there is no support to skip that otherwise) + * + * @addr - start of the memory area to be synced + * @length - length of the are to be synced + * @fd - file descriptor for the file to be synced + * (mandatory only for POSIX non-compliant systems) + */ +int qemu_msync(struct uc_struct *uc, void *addr, size_t length, int fd) +{ +#ifdef CONFIG_POSIX + size_t align_mask = ~(uc->qemu_real_host_page_size - 1); + + /** + * There are no strict reqs as per the length of mapping + * to be synced. Still the length needs to follow the address + * alignment changes. Additionally - round the size to the multiple + * of PAGE_SIZE + */ + length += ((uintptr_t)addr & (uc->qemu_real_host_page_size - 1)); + length = (length + ~align_mask) & align_mask; + + addr = (void *)((uintptr_t)addr & align_mask); + + return msync(addr, length, MS_SYNC); +#else /* CONFIG_POSIX */ + /** + * Perform the sync based on the file descriptor + * The sync range will most probably be wider than the one + * requested - but it will still get the job done + */ + return qemu_fdatasync(fd); +#endif /* CONFIG_POSIX */ +} diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 2898138b..d654ff56 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2024,6 +2024,7 @@ #define memory_region_dispatch_read memory_region_dispatch_read_x86_64 #define memory_region_dispatch_read1 memory_region_dispatch_read1_x86_64 #define memory_region_dispatch_write memory_region_dispatch_write_x86_64 +#define memory_region_do_writeback memory_region_do_writeback_x86_64 #define memory_region_escape_name memory_region_escape_name_x86_64 #define memory_region_finalize memory_region_finalize_x86_64 #define memory_region_find memory_region_find_x86_64 @@ -2384,6 +2385,7 @@ #define qemu_clock_get_us qemu_clock_get_us_x86_64 #define qemu_clock_ptr qemu_clock_ptr_x86_64 #define qemu_clocks qemu_clocks_x86_64 +#define qemu_fdatasync qemu_fdatasync_x86_64 #define qemu_get_cpu qemu_get_cpu_x86_64 #define qemu_get_guest_memory_mapping qemu_get_guest_memory_mapping_x86_64 #define qemu_get_guest_simple_memory_mapping qemu_get_guest_simple_memory_mapping_x86_64 @@ -2405,6 +2407,7 @@ #define qemu_ram_alloc_resizeable qemu_ram_alloc_resizeable_x86_64 #define qemu_ram_block_by_name qemu_ram_block_by_name_x86_64 #define qemu_ram_block_from_host qemu_ram_block_from_host_x86_64 +#define qemu_ram_block_writeback qemu_ram_block_writeback_x86_64 #define qemu_ram_foreach_block qemu_ram_foreach_block_x86_64 #define qemu_ram_free qemu_ram_free_x86_64 #define qemu_ram_get_idstr qemu_ram_get_idstr_x86_64 @@ -2414,6 +2417,7 @@ #define qemu_ram_resize qemu_ram_resize_x86_64 #define qemu_ram_setup_dump qemu_ram_setup_dump_x86_64 #define qemu_ram_unset_idstr qemu_ram_unset_idstr_x86_64 +#define qemu_ram_writeback qemu_ram_writeback_x86_64 #define qemu_st_helpers qemu_st_helpers_x86_64 #define qemu_strnlen qemu_strnlen_x86_64 #define qemu_strsep qemu_strsep_x86_64