Commit 96c1606b33a64ea6d5e1a988f9eb234a58947002

Authored by Alexander Graf
Committed by Anthony Liguori
1 parent 1c7936e3

Use Little Endian for Dirty Log

We currently use host endian long types to store information
in the dirty bitmap.

This works reasonably well on Little Endian targets, because the
u32 after the first contains the next 32 bits. On Big Endian this
breaks completely though, forcing us to be inventive here.

So Ben suggested to always use Little Endian, which looks reasonable.

We only have dirty bitmap implemented in Little Endian targets so far
and since PowerPC would be the first Big Endian platform, we can just
as well switch to Little Endian always with little effort without
breaking existing targets.

This is the userspace part of the patch. It shouldn't change anything
for existing targets, but help PowerPC.

It replaces my older patch called "Use 64bit pointer for dirty log".

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 1 changed file with 7 additions and 4 deletions
kvm-all.c
@@ -304,6 +304,11 @@ int kvm_set_migration_log(int enable) @@ -304,6 +304,11 @@ int kvm_set_migration_log(int enable)
304 return 0; 304 return 0;
305 } 305 }
306 306
  307 +static int test_le_bit(unsigned long nr, unsigned char *addr)
  308 +{
  309 + return (addr[nr >> 3] >> (nr & 7)) & 1;
  310 +}
  311 +
307 /** 312 /**
308 * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space 313 * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
309 * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty(). 314 * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty().
@@ -357,12 +362,10 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, @@ -357,12 +362,10 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
357 for (phys_addr = mem->start_addr, addr = mem->phys_offset; 362 for (phys_addr = mem->start_addr, addr = mem->phys_offset;
358 phys_addr < mem->start_addr + mem->memory_size; 363 phys_addr < mem->start_addr + mem->memory_size;
359 phys_addr += TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { 364 phys_addr += TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
360 - uint64_t *bitmap = (uint64_t *)d.dirty_bitmap; 365 + unsigned char *bitmap = (unsigned char *)d.dirty_bitmap;
361 unsigned nr = (phys_addr - mem->start_addr) >> TARGET_PAGE_BITS; 366 unsigned nr = (phys_addr - mem->start_addr) >> TARGET_PAGE_BITS;
362 - unsigned word = nr / (sizeof(*bitmap) * 8);  
363 - unsigned bit = nr % (sizeof(*bitmap) * 8);  
364 367
365 - if ((bitmap[word] >> bit) & 1) { 368 + if (test_le_bit(nr, bitmap)) {
366 cpu_physical_memory_set_dirty(addr); 369 cpu_physical_memory_set_dirty(addr);
367 } else if (r < 0) { 370 } else if (r < 0) {
368 /* When our KVM implementation doesn't know about dirty logging 371 /* When our KVM implementation doesn't know about dirty logging