Skip to content

Commit

Permalink
implement simple memory snapshot mechanismus
Browse files Browse the repository at this point in the history
Uses Copy on Write to make it posible to restore the memory state after a snapshot
was made. To restore all MemoryRegions created after the snapshot are removed.
  • Loading branch information
PhilippTakacs committed Jul 11, 2023
1 parent 065af19 commit 80bd825
Show file tree
Hide file tree
Showing 25 changed files with 302 additions and 52 deletions.
9 changes: 9 additions & 0 deletions include/uc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ typedef bool (*uc_write_mem_t)(AddressSpace *as, hwaddr addr,
typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf,
int len);

typedef MemoryRegion* (*uc_mem_cow_t)(struct uc_struct *uc,
MemoryRegion *current, hwaddr begin,
size_t size);

typedef void (*uc_args_void_t)(void *);

typedef void (*uc_args_uc_t)(struct uc_struct *);
Expand All @@ -102,6 +106,8 @@ typedef void (*uc_mem_unmap_t)(struct uc_struct *, MemoryRegion *mr);

typedef MemoryRegion *(*uc_memory_mapping_t)(struct uc_struct *, hwaddr addr);

typedef void (*uc_memory_filter_t)(MemoryRegion *, int32_t);

typedef void (*uc_readonly_mem_t)(MemoryRegion *mr, bool readonly);

typedef int (*uc_cpus_init)(struct uc_struct *, const char *);
Expand Down Expand Up @@ -267,6 +273,7 @@ struct uc_struct {

uc_write_mem_t write_mem;
uc_read_mem_t read_mem;
uc_mem_cow_t memory_cow;
uc_args_void_t release; // release resource when uc_close()
uc_args_uc_u64_t set_pc; // set PC for tracecode
uc_get_pc_t get_pc;
Expand All @@ -280,6 +287,7 @@ struct uc_struct {
uc_args_uc_ram_size_t memory_map;
uc_args_uc_ram_size_ptr_t memory_map_ptr;
uc_memory_mapping_t memory_mapping;
uc_memory_filter_t memory_filter_subregions;
uc_mem_unmap_t memory_unmap;
uc_readonly_mem_t readonly_mem;
uc_cpus_init cpus_init;
Expand Down Expand Up @@ -403,6 +411,7 @@ struct uc_struct {
PVOID seh_handle;
void *seh_closure;
#endif
int32_t snapshot_level;
};

// Metadata stub for the variable-size cpu context used with uc_context_*()
Expand Down
6 changes: 6 additions & 0 deletions include/unicorn/unicorn.h
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,12 @@ size_t uc_context_size(uc_engine *uc);
UNICORN_EXPORT
uc_err uc_context_free(uc_context *context);

UNICORN_EXPORT
uc_err uc_snapshot(uc_engine *uc);

UNICORN_EXPORT
uc_err uc_restore_latest_snapshot(uc_engine *uc);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 2 additions & 0 deletions qemu/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_aarch64
#define memory_map_io memory_map_io_aarch64
#define memory_map_ptr memory_map_ptr_aarch64
#define memory_cow memory_cow_aarch64
#define memory_unmap memory_unmap_aarch64
#define memory_free memory_free_aarch64
#define flatview_unref flatview_unref_aarch64
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_aarch64
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_aarch64
#define memory_region_find memory_region_find_aarch64
#define memory_region_filter_subregions memory_region_filter_subregions_aarch64
#define memory_listener_register memory_listener_register_aarch64
#define memory_listener_unregister memory_listener_unregister_aarch64
#define address_space_remove_listeners address_space_remove_listeners_aarch64
Expand Down
16 changes: 16 additions & 0 deletions qemu/accel/tcg/cputlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2155,6 +2155,22 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
}
}

if (uc->snapshot_level && mr->ram && mr->priority < uc->snapshot_level) {
mr = memory_cow(uc, mr, addr & TARGET_PAGE_MASK, TARGET_PAGE_SIZE);
if (!mr) {
uc->invalid_addr = paddr;
uc->invalid_error = UC_ERR_NOMEM;
cpu_exit(uc->cpu);
return;
}
/* refill tlb after CoW */
tlb_fill(env_cpu(env), paddr, size, MMU_DATA_STORE,
mmu_idx, retaddr);
index = tlb_index(env, mmu_idx, addr);
entry = tlb_entry(env, mmu_idx, addr);
tlb_addr = tlb_addr_write(entry);
}

/* Handle anything that isn't just a straight memory access. */
if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
CPUIOTLBEntry *iotlbentry;
Expand Down
2 changes: 2 additions & 0 deletions qemu/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_arm
#define memory_map_io memory_map_io_arm
#define memory_map_ptr memory_map_ptr_arm
#define memory_cow memory_cow_arm
#define memory_unmap memory_unmap_arm
#define memory_free memory_free_arm
#define flatview_unref flatview_unref_arm
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_arm
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_arm
#define memory_region_find memory_region_find_arm
#define memory_region_filter_subregions memory_region_filter_subregions_arm
#define memory_listener_register memory_listener_register_arm
#define memory_listener_unregister memory_listener_unregister_arm
#define address_space_remove_listeners address_space_remove_listeners_arm
Expand Down
29 changes: 29 additions & 0 deletions qemu/include/exec/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,35 @@ void memory_region_add_subregion(MemoryRegion *mr,
hwaddr offset,
MemoryRegion *subregion);

/**
* memory_region_add_subregion_overlap: Add a subregion to a container
* with overlap.
*
* Adds a subregion at @offset. The subregion may overlap with other
* subregions. Conflicts are resolved by having a higher @priority hide a
* lower @priority. Subregions without priority are taken as @priority 0.
* A region may only be added once as a subregion (unless removed with
* memory_region_del_subregion()); use memory_region_init_alias() if you
* want a region to be a subregion in multiple locations.
*
* @mr: the region to contain the new subregion; must be a container
* initialized with memory_region_init().
* @offset: the offset relative to @mr where @subregion is added.
* @subregion: the subregion to be added.
* @priority: used for resolving overlaps; highest priority wins.
*/
void memory_region_add_subregion_overlap(MemoryRegion *mr,
hwaddr offset,
MemoryRegion *subregion,
int priority);

/**
* memory_region_filter_subregions: filter subregios by priority.
*
* remove all subregions beginning by a specified subregion
*/
void memory_region_filter_subregions(MemoryRegion *mr, int32_t level);

/**
* memory_region_get_ram_addr: Get the ram address associated with a memory
* region
Expand Down
2 changes: 2 additions & 0 deletions qemu/m68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_m68k
#define memory_map_io memory_map_io_m68k
#define memory_map_ptr memory_map_ptr_m68k
#define memory_cow memory_cow_m68k
#define memory_unmap memory_unmap_m68k
#define memory_free memory_free_m68k
#define flatview_unref flatview_unref_m68k
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_m68k
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_m68k
#define memory_region_find memory_region_find_m68k
#define memory_region_filter_subregions memory_region_filter_subregions_m68k
#define memory_listener_register memory_listener_register_m68k
#define memory_listener_unregister memory_listener_unregister_m68k
#define address_space_remove_listeners address_space_remove_listeners_m68k
Expand Down
2 changes: 2 additions & 0 deletions qemu/mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_mips
#define memory_map_io memory_map_io_mips
#define memory_map_ptr memory_map_ptr_mips
#define memory_cow memory_cow_mips
#define memory_unmap memory_unmap_mips
#define memory_free memory_free_mips
#define flatview_unref flatview_unref_mips
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_mips
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_mips
#define memory_region_find memory_region_find_mips
#define memory_region_filter_subregions memory_region_filter_subregions_mips
#define memory_listener_register memory_listener_register_mips
#define memory_listener_unregister memory_listener_unregister_mips
#define address_space_remove_listeners address_space_remove_listeners_mips
Expand Down
2 changes: 2 additions & 0 deletions qemu/mips64.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_mips64
#define memory_map_io memory_map_io_mips64
#define memory_map_ptr memory_map_ptr_mips64
#define memory_cow memory_cow_mips64
#define memory_unmap memory_unmap_mips64
#define memory_free memory_free_mips64
#define flatview_unref flatview_unref_mips64
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_mips64
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_mips64
#define memory_region_find memory_region_find_mips64
#define memory_region_filter_subregions memory_region_filter_subregions_mips64
#define memory_listener_register memory_listener_register_mips64
#define memory_listener_unregister memory_listener_unregister_mips64
#define address_space_remove_listeners address_space_remove_listeners_mips64
Expand Down
2 changes: 2 additions & 0 deletions qemu/mips64el.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_mips64el
#define memory_map_io memory_map_io_mips64el
#define memory_map_ptr memory_map_ptr_mips64el
#define memory_cow memory_cow_mips64el
#define memory_unmap memory_unmap_mips64el
#define memory_free memory_free_mips64el
#define flatview_unref flatview_unref_mips64el
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_mips64el
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_mips64el
#define memory_region_find memory_region_find_mips64el
#define memory_region_filter_subregions memory_region_filter_subregions_mips64el
#define memory_listener_register memory_listener_register_mips64el
#define memory_listener_unregister memory_listener_unregister_mips64el
#define address_space_remove_listeners address_space_remove_listeners_mips64el
Expand Down
2 changes: 2 additions & 0 deletions qemu/mipsel.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_mipsel
#define memory_map_io memory_map_io_mipsel
#define memory_map_ptr memory_map_ptr_mipsel
#define memory_cow memory_cow_mipsel
#define memory_unmap memory_unmap_mipsel
#define memory_free memory_free_mipsel
#define flatview_unref flatview_unref_mipsel
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_mipsel
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_mipsel
#define memory_region_find memory_region_find_mipsel
#define memory_region_filter_subregions memory_region_filter_subregions_mipsel
#define memory_listener_register memory_listener_register_mipsel
#define memory_listener_unregister memory_listener_unregister_mipsel
#define address_space_remove_listeners address_space_remove_listeners_mipsel
Expand Down
2 changes: 2 additions & 0 deletions qemu/ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_ppc
#define memory_map_io memory_map_io_ppc
#define memory_map_ptr memory_map_ptr_ppc
#define memory_cow memory_cow_ppc
#define memory_unmap memory_unmap_ppc
#define memory_free memory_free_ppc
#define flatview_unref flatview_unref_ppc
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_ppc
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_ppc
#define memory_region_find memory_region_find_ppc
#define memory_region_filter_subregions memory_region_filter_subregions_ppc
#define memory_listener_register memory_listener_register_ppc
#define memory_listener_unregister memory_listener_unregister_ppc
#define address_space_remove_listeners address_space_remove_listeners_ppc
Expand Down
2 changes: 2 additions & 0 deletions qemu/ppc64.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_ppc64
#define memory_map_io memory_map_io_ppc64
#define memory_map_ptr memory_map_ptr_ppc64
#define memory_cow memory_cow_ppc64
#define memory_unmap memory_unmap_ppc64
#define memory_free memory_free_ppc64
#define flatview_unref flatview_unref_ppc64
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_ppc64
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_ppc64
#define memory_region_find memory_region_find_ppc64
#define memory_region_filter_subregions memory_region_filter_subregions_ppc64
#define memory_listener_register memory_listener_register_ppc64
#define memory_listener_unregister memory_listener_unregister_ppc64
#define address_space_remove_listeners address_space_remove_listeners_ppc64
Expand Down
2 changes: 2 additions & 0 deletions qemu/riscv32.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_riscv32
#define memory_map_io memory_map_io_riscv32
#define memory_map_ptr memory_map_ptr_riscv32
#define memory_cow memory_cow_riscv32
#define memory_unmap memory_unmap_riscv32
#define memory_free memory_free_riscv32
#define flatview_unref flatview_unref_riscv32
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_riscv32
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_riscv32
#define memory_region_find memory_region_find_riscv32
#define memory_region_filter_subregions memory_region_filter_subregions_riscv32
#define memory_listener_register memory_listener_register_riscv32
#define memory_listener_unregister memory_listener_unregister_riscv32
#define address_space_remove_listeners address_space_remove_listeners_riscv32
Expand Down
2 changes: 2 additions & 0 deletions qemu/riscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_riscv64
#define memory_map_io memory_map_io_riscv64
#define memory_map_ptr memory_map_ptr_riscv64
#define memory_cow memory_cow_riscv64
#define memory_unmap memory_unmap_riscv64
#define memory_free memory_free_riscv64
#define flatview_unref flatview_unref_riscv64
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_riscv64
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_riscv64
#define memory_region_find memory_region_find_riscv64
#define memory_region_filter_subregions memory_region_filter_subregions_riscv64
#define memory_listener_register memory_listener_register_riscv64
#define memory_listener_unregister memory_listener_unregister_riscv64
#define address_space_remove_listeners address_space_remove_listeners_riscv64
Expand Down
2 changes: 2 additions & 0 deletions qemu/s390x.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#define memory_map memory_map_s390x
#define memory_map_io memory_map_io_s390x
#define memory_map_ptr memory_map_ptr_s390x
#define memory_cow memory_cow_s390x
#define memory_unmap memory_unmap_s390x
#define memory_free memory_free_s390x
#define flatview_unref flatview_unref_s390x
Expand All @@ -144,6 +145,7 @@
#define memory_region_del_subregion memory_region_del_subregion_s390x
#define memory_region_add_subregion_overlap memory_region_add_subregion_overlap_s390x
#define memory_region_find memory_region_find_s390x
#define memory_region_filter_subregions memory_region_filter_subregions_s390x
#define memory_listener_register memory_listener_register_s390x
#define memory_listener_unregister memory_listener_unregister_s390x
#define address_space_remove_listeners address_space_remove_listeners_s390x
Expand Down
Loading

0 comments on commit 80bd825

Please sign in to comment.