@@ -193,29 +193,14 @@ typedef struct GuestPhysListener {
193
193
MemoryListener listener ;
194
194
} GuestPhysListener ;
195
195
196
- static void guest_phys_blocks_region_add ( MemoryListener * listener ,
196
+ static void guest_phys_block_add_section ( GuestPhysListener * g ,
197
197
MemoryRegionSection * section )
198
198
{
199
- GuestPhysListener * g ;
200
- uint64_t section_size ;
201
- hwaddr target_start , target_end ;
202
- uint8_t * host_addr ;
203
- GuestPhysBlock * predecessor ;
204
-
205
- /* we only care about RAM */
206
- if (!memory_region_is_ram (section -> mr ) ||
207
- memory_region_is_ram_device (section -> mr ) ||
208
- memory_region_is_nonvolatile (section -> mr )) {
209
- return ;
210
- }
211
-
212
- g = container_of (listener , GuestPhysListener , listener );
213
- section_size = int128_get64 (section -> size );
214
- target_start = section -> offset_within_address_space ;
215
- target_end = target_start + section_size ;
216
- host_addr = memory_region_get_ram_ptr (section -> mr ) +
217
- section -> offset_within_region ;
218
- predecessor = NULL ;
199
+ const hwaddr target_start = section -> offset_within_address_space ;
200
+ const hwaddr target_end = target_start + int128_get64 (section -> size );
201
+ uint8_t * host_addr = memory_region_get_ram_ptr (section -> mr ) +
202
+ section -> offset_within_region ;
203
+ GuestPhysBlock * predecessor = NULL ;
219
204
220
205
/* find continuity in guest physical address space */
221
206
if (!QTAILQ_EMPTY (& g -> list -> head )) {
@@ -229,7 +214,8 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
229
214
230
215
/* we want continuity in both guest-physical and host-virtual memory */
231
216
if (predecessor -> target_end < target_start ||
232
- predecessor -> host_addr + predecessor_size != host_addr ) {
217
+ predecessor -> host_addr + predecessor_size != host_addr ||
218
+ predecessor -> mr != section -> mr ) {
233
219
predecessor = NULL ;
234
220
}
235
221
}
@@ -260,6 +246,40 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
260
246
#endif
261
247
}
262
248
249
+ static int guest_phys_ram_populate_cb (MemoryRegionSection * section ,
250
+ void * opaque )
251
+ {
252
+ GuestPhysListener * g = opaque ;
253
+
254
+ guest_phys_block_add_section (g , section );
255
+ return 0 ;
256
+ }
257
+
258
+ static void guest_phys_blocks_region_add (MemoryListener * listener ,
259
+ MemoryRegionSection * section )
260
+ {
261
+ GuestPhysListener * g = container_of (listener , GuestPhysListener , listener );
262
+
263
+ /* we only care about RAM */
264
+ if (!memory_region_is_ram (section -> mr ) ||
265
+ memory_region_is_ram_device (section -> mr ) ||
266
+ memory_region_is_nonvolatile (section -> mr )) {
267
+ return ;
268
+ }
269
+
270
+ /* for special sparse regions, only add populated parts */
271
+ if (memory_region_has_ram_discard_manager (section -> mr )) {
272
+ RamDiscardManager * rdm ;
273
+
274
+ rdm = memory_region_get_ram_discard_manager (section -> mr );
275
+ ram_discard_manager_replay_populated (rdm , section ,
276
+ guest_phys_ram_populate_cb , g );
277
+ return ;
278
+ }
279
+
280
+ guest_phys_block_add_section (g , section );
281
+ }
282
+
263
283
void guest_phys_blocks_append (GuestPhysBlockList * list )
264
284
{
265
285
GuestPhysListener g = { 0 };
0 commit comments