From: Liu Ping Fan <pingfank@xxxxxxxxxxxxxxxxxx> PhysMap contain the flatview and radix-tree view, they are snapshot of system topology and should be consistent. With PhysMap, we can swap the pointer when updating and achieve the atomic. Signed-off-by: Liu Ping Fan <pingfank@xxxxxxxxxxxxxxxxxx> --- exec.c | 8 -------- memory.c | 33 --------------------------------- memory.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/exec.c b/exec.c index 0e29ef9..01b91b0 100644 --- a/exec.c +++ b/exec.c @@ -156,8 +156,6 @@ typedef struct PageDesc { #endif /* Size of the L2 (and L3, etc) page tables. */ -#define L2_BITS 10 -#define L2_SIZE (1 << L2_BITS) #define P_L2_LEVELS \ (((TARGET_PHYS_ADDR_SPACE_BITS - TARGET_PAGE_BITS - 1) / L2_BITS) + 1) @@ -185,7 +183,6 @@ uintptr_t qemu_host_page_mask; static void *l1_map[V_L1_SIZE]; #if !defined(CONFIG_USER_ONLY) -typedef struct PhysPageEntry PhysPageEntry; static MemoryRegionSection *phys_sections; static unsigned phys_sections_nb, phys_sections_nb_alloc; @@ -194,11 +191,6 @@ static uint16_t phys_section_notdirty; static uint16_t phys_section_rom; static uint16_t phys_section_watch; -struct PhysPageEntry { - uint16_t is_leaf : 1; - /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */ - uint16_t ptr : 15; -}; /* Simple allocator for PhysPageEntry nodes */ static PhysPageEntry (*phys_map_nodes)[L2_SIZE]; diff --git a/memory.c b/memory.c index 2eaa2fc..c7f2cfd 100644 --- a/memory.c +++ b/memory.c @@ -31,17 +31,6 @@ static bool global_dirty_log = false; static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners = QTAILQ_HEAD_INITIALIZER(memory_listeners); -typedef struct AddrRange AddrRange; - -/* - * Note using signed integers limits us to physical addresses at most - * 63 bits wide. They are needed for negative offsetting in aliases - * (large MemoryRegion::alias_offset). - */ -struct AddrRange { - Int128 start; - Int128 size; -}; static AddrRange addrrange_make(Int128 start, Int128 size) { @@ -197,28 +186,6 @@ static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a, && !memory_region_ioeventfd_before(b, a); } -typedef struct FlatRange FlatRange; -typedef struct FlatView FlatView; - -/* Range of memory in the global map. Addresses are absolute. */ -struct FlatRange { - MemoryRegion *mr; - target_phys_addr_t offset_in_region; - AddrRange addr; - uint8_t dirty_log_mask; - bool readable; - bool readonly; -}; - -/* Flattened global view of current active memory hierarchy. Kept in sorted - * order. - */ -struct FlatView { - FlatRange *ranges; - unsigned nr; - unsigned nr_allocated; -}; - typedef struct AddressSpace AddressSpace; typedef struct AddressSpaceOps AddressSpaceOps; diff --git a/memory.h b/memory.h index 740f018..357edd8 100644 --- a/memory.h +++ b/memory.h @@ -29,12 +29,72 @@ #include "qemu-thread.h" #include "qemu/reclaimer.h" +typedef struct AddrRange AddrRange; +typedef struct FlatRange FlatRange; +typedef struct FlatView FlatView; +typedef struct PhysPageEntry PhysPageEntry; +typedef struct PhysMap PhysMap; +typedef struct MemoryRegionSection MemoryRegionSection; typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionLifeOps MemoryRegionLifeOps; typedef struct MemoryRegion MemoryRegion; typedef struct MemoryRegionPortio MemoryRegionPortio; typedef struct MemoryRegionMmio MemoryRegionMmio; +/* + * Note using signed integers limits us to physical addresses at most + * 63 bits wide. They are needed for negative offsetting in aliases + * (large MemoryRegion::alias_offset). + */ +struct AddrRange { + Int128 start; + Int128 size; +}; + +/* Range of memory in the global map. Addresses are absolute. */ +struct FlatRange { + MemoryRegion *mr; + target_phys_addr_t offset_in_region; + AddrRange addr; + uint8_t dirty_log_mask; + bool readable; + bool readonly; +}; + +/* Flattened global view of current active memory hierarchy. Kept in sorted + * order. + */ +struct FlatView { + FlatRange *ranges; + unsigned nr; + unsigned nr_allocated; +}; + +struct PhysPageEntry { + uint16_t is_leaf:1; + /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */ + uint16_t ptr:15; +}; + +#define L2_BITS 10 +#define L2_SIZE (1 << L2_BITS) +/* This is a multi-level map on the physical address space. + The bottom level has pointers to MemoryRegionSections. */ +struct PhysMap { + Atomic ref; + PhysPageEntry root; + PhysPageEntry (*phys_map_nodes)[L2_SIZE]; + unsigned phys_map_nodes_nb; + unsigned phys_map_nodes_nb_alloc; + + MemoryRegionSection *phys_sections; + unsigned phys_sections_nb; + unsigned phys_sections_nb_alloc; + + /* FlatView */ + FlatView views[2]; +}; + /* Must match *_DIRTY_FLAGS in cpu-all.h. To be replaced with dynamic * registration. */ @@ -167,8 +227,6 @@ struct MemoryRegionPortio { #define PORTIO_END_OF_LIST() { } -typedef struct MemoryRegionSection MemoryRegionSection; - /** * MemoryRegionSection: describes a fragment of a #MemoryRegion * -- 1.7.4.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html