Revision d17b5288
b/arch_init.c | ||
---|---|---|
108 | 108 |
static ram_addr_t current_addr = 0; |
109 | 109 |
ram_addr_t saved_addr = current_addr; |
110 | 110 |
ram_addr_t addr = 0; |
111 |
uint64_t total_ram = ram_bytes_total(); |
|
111 | 112 |
int bytes_sent = 0; |
112 | 113 |
|
113 |
while (addr < ram_list.last_offset) {
|
|
114 |
while (addr < total_ram) {
|
|
114 | 115 |
if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) { |
115 | 116 |
uint8_t *p; |
116 | 117 |
|
... | ... | |
133 | 134 |
break; |
134 | 135 |
} |
135 | 136 |
addr += TARGET_PAGE_SIZE; |
136 |
current_addr = (saved_addr + addr) % ram_list.last_offset;
|
|
137 |
current_addr = (saved_addr + addr) % total_ram;
|
|
137 | 138 |
} |
138 | 139 |
|
139 | 140 |
return bytes_sent; |
... | ... | |
145 | 146 |
{ |
146 | 147 |
ram_addr_t addr; |
147 | 148 |
ram_addr_t count = 0; |
149 |
uint64_t total_ram = ram_bytes_total(); |
|
148 | 150 |
|
149 |
for (addr = 0; addr < ram_list.last_offset; addr += TARGET_PAGE_SIZE) {
|
|
151 |
for (addr = 0; addr < total_ram; addr += TARGET_PAGE_SIZE) {
|
|
150 | 152 |
if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) { |
151 | 153 |
count++; |
152 | 154 |
} |
... | ... | |
167 | 169 |
|
168 | 170 |
uint64_t ram_bytes_total(void) |
169 | 171 |
{ |
170 |
return ram_list.last_offset; |
|
172 |
RAMBlock *block; |
|
173 |
uint64_t total = 0; |
|
174 |
|
|
175 |
QLIST_FOREACH(block, &ram_list.blocks, next) |
|
176 |
total += block->length; |
|
177 |
|
|
178 |
return total; |
|
171 | 179 |
} |
172 | 180 |
|
173 | 181 |
int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) |
... | ... | |
188 | 196 |
} |
189 | 197 |
|
190 | 198 |
if (stage == 1) { |
199 |
uint64_t total_ram = ram_bytes_total(); |
|
191 | 200 |
bytes_transferred = 0; |
192 | 201 |
|
193 | 202 |
/* Make sure all dirty bits are set */ |
194 |
for (addr = 0; addr < ram_list.last_offset; addr += TARGET_PAGE_SIZE) {
|
|
203 |
for (addr = 0; addr < total_ram; addr += TARGET_PAGE_SIZE) {
|
|
195 | 204 |
if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) { |
196 | 205 |
cpu_physical_memory_set_dirty(addr); |
197 | 206 |
} |
... | ... | |
200 | 209 |
/* Enable dirty memory tracking */ |
201 | 210 |
cpu_physical_memory_set_dirty_tracking(1); |
202 | 211 |
|
203 |
qemu_put_be64(f, ram_list.last_offset | RAM_SAVE_FLAG_MEM_SIZE);
|
|
212 |
qemu_put_be64(f, total_ram | RAM_SAVE_FLAG_MEM_SIZE);
|
|
204 | 213 |
} |
205 | 214 |
|
206 | 215 |
bytes_transferred_last = bytes_transferred; |
... | ... | |
259 | 268 |
addr &= TARGET_PAGE_MASK; |
260 | 269 |
|
261 | 270 |
if (flags & RAM_SAVE_FLAG_MEM_SIZE) { |
262 |
if (addr != ram_list.last_offset) {
|
|
271 |
if (addr != ram_bytes_total()) {
|
|
263 | 272 |
return -EINVAL; |
264 | 273 |
} |
265 | 274 |
} |
b/cpu-all.h | ||
---|---|---|
870 | 870 |
|
871 | 871 |
typedef struct RAMList { |
872 | 872 |
uint8_t *phys_dirty; |
873 |
ram_addr_t last_offset; |
|
874 | 873 |
QLIST_HEAD(ram, RAMBlock) blocks; |
875 | 874 |
} RAMList; |
876 | 875 |
extern RAMList ram_list; |
b/exec.c | ||
---|---|---|
2767 | 2767 |
} |
2768 | 2768 |
#endif |
2769 | 2769 |
|
2770 |
static ram_addr_t find_ram_offset(ram_addr_t size) |
|
2771 |
{ |
|
2772 |
RAMBlock *block; |
|
2773 |
ram_addr_t last = 0; |
|
2774 |
|
|
2775 |
QLIST_FOREACH(block, &ram_list.blocks, next) |
|
2776 |
last = MAX(last, block->offset + block->length); |
|
2777 |
|
|
2778 |
return last; |
|
2779 |
} |
|
2780 |
|
|
2770 | 2781 |
ram_addr_t qemu_ram_alloc(ram_addr_t size) |
2771 | 2782 |
{ |
2772 | 2783 |
RAMBlock *new_block; |
... | ... | |
2800 | 2811 |
madvise(new_block->host, size, MADV_MERGEABLE); |
2801 | 2812 |
#endif |
2802 | 2813 |
} |
2803 |
new_block->offset = ram_list.last_offset;
|
|
2814 |
new_block->offset = find_ram_offset(size);
|
|
2804 | 2815 |
new_block->length = size; |
2805 | 2816 |
|
2806 | 2817 |
QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); |
2807 | 2818 |
|
2808 | 2819 |
ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty, |
2809 |
(ram_list.last_offset + size) >> TARGET_PAGE_BITS);
|
|
2810 |
memset(ram_list.phys_dirty + (ram_list.last_offset >> TARGET_PAGE_BITS),
|
|
2820 |
(new_block->offset + size) >> TARGET_PAGE_BITS);
|
|
2821 |
memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
|
|
2811 | 2822 |
0xff, size >> TARGET_PAGE_BITS); |
2812 | 2823 |
|
2813 |
ram_list.last_offset += size; |
|
2814 |
|
|
2815 | 2824 |
if (kvm_enabled()) |
2816 | 2825 |
kvm_setup_guest_memory(new_block->host, size); |
2817 | 2826 |
|
Also available in: Unified diff