1 #ifndef RAMLIST_H 2 #define RAMLIST_H 3 4 #include "qemu/queue.h" 5 #include "qemu/thread.h" 6 #include "qemu/rcu.h" 7 #include "qemu/rcu_queue.h" 8 9 typedef struct RAMBlockNotifier RAMBlockNotifier; 10 11 #define DIRTY_MEMORY_VGA 0 12 #define DIRTY_MEMORY_CODE 1 13 #define DIRTY_MEMORY_MIGRATION 2 14 #define DIRTY_MEMORY_NUM 3 /* num of dirty bits */ 15 16 /* The dirty memory bitmap is split into fixed-size blocks to allow growth 17 * under RCU. The bitmap for a block can be accessed as follows: 18 * 19 * rcu_read_lock(); 20 * 21 * DirtyMemoryBlocks *blocks = 22 * atomic_rcu_read(&ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); 23 * 24 * ram_addr_t idx = (addr >> TARGET_PAGE_BITS) / DIRTY_MEMORY_BLOCK_SIZE; 25 * unsigned long *block = blocks.blocks[idx]; 26 * ...access block bitmap... 27 * 28 * rcu_read_unlock(); 29 * 30 * Remember to check for the end of the block when accessing a range of 31 * addresses. Move on to the next block if you reach the end. 32 * 33 * Organization into blocks allows dirty memory to grow (but not shrink) under 34 * RCU. When adding new RAMBlocks requires the dirty memory to grow, a new 35 * DirtyMemoryBlocks array is allocated with pointers to existing blocks kept 36 * the same. Other threads can safely access existing blocks while dirty 37 * memory is being grown. When no threads are using the old DirtyMemoryBlocks 38 * anymore it is freed by RCU (but the underlying blocks stay because they are 39 * pointed to from the new DirtyMemoryBlocks). 40 */ 41 #define DIRTY_MEMORY_BLOCK_SIZE ((ram_addr_t)256 * 1024 * 8) 42 typedef struct { 43 struct rcu_head rcu; 44 unsigned long *blocks[]; 45 } DirtyMemoryBlocks; 46 47 typedef struct RAMList { 48 QemuMutex mutex; 49 RAMBlock *mru_block; 50 /* RCU-enabled, writes protected by the ramlist lock. */ 51 QLIST_HEAD(, RAMBlock) blocks; 52 DirtyMemoryBlocks *dirty_memory[DIRTY_MEMORY_NUM]; 53 uint32_t version; 54 QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers; 55 } RAMList; 56 extern RAMList ram_list; 57 58 /* Should be holding either ram_list.mutex, or the RCU lock. */ 59 #define RAMBLOCK_FOREACH(block) \ 60 QLIST_FOREACH_RCU(block, &ram_list.blocks, next) 61 62 void qemu_mutex_lock_ramlist(void); 63 void qemu_mutex_unlock_ramlist(void); 64 65 struct RAMBlockNotifier { 66 void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size); 67 void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size); 68 QLIST_ENTRY(RAMBlockNotifier) next; 69 }; 70 71 void ram_block_notifier_add(RAMBlockNotifier *n); 72 void ram_block_notifier_remove(RAMBlockNotifier *n); 73 void ram_block_notify_add(void *host, size_t size); 74 void ram_block_notify_remove(void *host, size_t size); 75 76 void ram_block_dump(Monitor *mon); 77 78 #endif /* RAMLIST_H */ 79