From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: Re: [PATCH 13/23] kvm: convert to MemoryListener API Date: Sun, 15 Jan 2012 11:49:09 +0100 Message-ID: <4F12AF25.9050506@web.de> References: <1324304024-11220-1-git-send-email-avi@redhat.com> <1324304024-11220-14-git-send-email-avi@redhat.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig9E5B52259BF9B6934B3290E6" Return-path: In-Reply-To: <1324304024-11220-14-git-send-email-avi@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org Sender: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org To: Avi Kivity Cc: xen-devel@lists.xensource.com, "Michael S. Tsirkin" , qemu-devel@nongnu.org, kvm@vger.kernel.org, Stefano Stabellini List-Id: xen-devel@lists.xenproject.org This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig9E5B52259BF9B6934B3290E6 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable On 2011-12-19 15:13, Avi Kivity wrote: > Drop the use of cpu_register_phys_memory_client() in favour of the new > MemoryListener API. The new API simplifies the caller, since there is = no > need to deal with splitting and merging slots; however this is not expl= oited > in this patch. This breaks graphical grub1 with cirrus-vga in KVM mode. Dunno why yet. Jan >=20 > Signed-off-by: Avi Kivity > --- > kvm-all.c | 107 ++++++++++++++++++++++++++++++++++++++++-------------= -------- > 1 files changed, 70 insertions(+), 37 deletions(-) >=20 > diff --git a/kvm-all.c b/kvm-all.c > index 4f58ae8..138e0a2 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -27,6 +27,7 @@ > #include "gdbstub.h" > #include "kvm.h" > #include "bswap.h" > +#include "memory.h" > =20 > /* This check must be after config-host.h is included */ > #ifdef CONFIG_EVENTFD > @@ -289,16 +290,28 @@ static int kvm_dirty_pages_log_change(target_phys= _addr_t phys_addr, > return kvm_slot_dirty_pages_log_change(mem, log_dirty); > } > =20 > -static int kvm_log_start(CPUPhysMemoryClient *client, > - target_phys_addr_t phys_addr, ram_addr_t size= ) > +static void kvm_log_start(MemoryListener *listener, > + MemoryRegionSection *section) > { > - return kvm_dirty_pages_log_change(phys_addr, size, true); > + int r; > + > + r =3D kvm_dirty_pages_log_change(section->offset_within_address_sp= ace, > + section->size, true); > + if (r < 0) { > + abort(); > + } > } > =20 > -static int kvm_log_stop(CPUPhysMemoryClient *client, > - target_phys_addr_t phys_addr, ram_addr_t size)= > +static void kvm_log_stop(MemoryListener *listener, > + MemoryRegionSection *section) > { > - return kvm_dirty_pages_log_change(phys_addr, size, false); > + int r; > + > + r =3D kvm_dirty_pages_log_change(section->offset_within_address_sp= ace, > + section->size, false); > + if (r < 0) { > + abort(); > + } > } > =20 > static int kvm_set_migration_log(int enable) > @@ -519,13 +532,15 @@ static int kvm_check_many_ioeventfds(void) > return NULL; > } > =20 > -static void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t= size, > - ram_addr_t phys_offset, bool log_dirty) > +static void kvm_set_phys_mem(MemoryRegionSection *section, bool add) > { > KVMState *s =3D kvm_state; > - ram_addr_t flags =3D phys_offset & ~TARGET_PAGE_MASK; > KVMSlot *mem, old; > int err; > + MemoryRegion *mr =3D section->mr; > + bool log_dirty =3D memory_region_is_logging(mr); > + target_phys_addr_t start_addr =3D section->offset_within_address_s= pace; > + ram_addr_t size =3D section->size; > void *ram =3D NULL; > =20 > /* kvm works in page size chunks, but the function may be called > @@ -533,20 +548,19 @@ static void kvm_set_phys_mem(target_phys_addr_t s= tart_addr, ram_addr_t size, > size =3D TARGET_PAGE_ALIGN(size); > start_addr =3D TARGET_PAGE_ALIGN(start_addr); > =20 > - /* KVM does not support read-only slots */ > - phys_offset &=3D ~IO_MEM_ROM; > - > - if ((phys_offset & ~TARGET_PAGE_MASK) =3D=3D IO_MEM_RAM) { > - ram =3D qemu_safe_ram_ptr(phys_offset); > + if (!memory_region_is_ram(mr)) { > + return; > } > =20 > + ram =3D memory_region_get_ram_ptr(mr) + section->offset_within_reg= ion; > + > while (1) { > mem =3D kvm_lookup_overlapping_slot(s, start_addr, start_addr = + size); > if (!mem) { > break; > } > =20 > - if (flags < IO_MEM_UNASSIGNED && start_addr >=3D mem->start_ad= dr && > + if (add && start_addr >=3D mem->start_addr && > (start_addr + size <=3D mem->start_addr + mem->memory_size= ) && > (ram - start_addr =3D=3D mem->ram - mem->start_addr)) { > /* The new slot fits into the existing one and comes with > @@ -575,8 +589,7 @@ static void kvm_set_phys_mem(target_phys_addr_t sta= rt_addr, ram_addr_t size, > * slot comes around later, we will fail (not seen in practice= so far) > * - and actually require a recent KVM version. */ > if (s->broken_set_mem_region && > - old.start_addr =3D=3D start_addr && old.memory_size < size= && > - flags < IO_MEM_UNASSIGNED) { > + old.start_addr =3D=3D start_addr && old.memory_size < size= && add) { > mem =3D kvm_alloc_slot(s); > mem->memory_size =3D old.memory_size; > mem->start_addr =3D old.start_addr; > @@ -591,7 +604,6 @@ static void kvm_set_phys_mem(target_phys_addr_t sta= rt_addr, ram_addr_t size, > } > =20 > start_addr +=3D old.memory_size; > - phys_offset +=3D old.memory_size; > ram +=3D old.memory_size; > size -=3D old.memory_size; > continue; > @@ -642,8 +654,7 @@ static void kvm_set_phys_mem(target_phys_addr_t sta= rt_addr, ram_addr_t size, > if (!size) { > return; > } > - /* KVM does not need to know about this memory */ > - if (flags >=3D IO_MEM_UNASSIGNED) { > + if (!add) { > return; > } > mem =3D kvm_alloc_slot(s); > @@ -660,33 +671,55 @@ static void kvm_set_phys_mem(target_phys_addr_t s= tart_addr, ram_addr_t size, > } > } > =20 > -static void kvm_client_set_memory(struct CPUPhysMemoryClient *client, > - target_phys_addr_t start_addr, > - ram_addr_t size, ram_addr_t phys_off= set, > - bool log_dirty) > +static void kvm_region_add(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > + kvm_set_phys_mem(section, true); > +} > + > +static void kvm_region_del(MemoryListener *listener, > + MemoryRegionSection *section) > { > - kvm_set_phys_mem(start_addr, size, phys_offset, log_dirty); > + kvm_set_phys_mem(section, false); > +} > + > +static void kvm_log_sync(MemoryListener *listener, > + MemoryRegionSection *section) > +{ > + target_phys_addr_t start =3D section->offset_within_address_space;= > + target_phys_addr_t end =3D start + section->size; > + int r; > + > + r =3D kvm_physical_sync_dirty_bitmap(start, end); > + if (r < 0) { > + abort(); > + } > } > =20 > -static int kvm_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *cl= ient, > - target_phys_addr_t start_addr,= > - target_phys_addr_t end_addr) > +static void kvm_log_global_start(struct MemoryListener *listener) > { > - return kvm_physical_sync_dirty_bitmap(start_addr, end_addr); > + int r; > + > + r =3D kvm_set_migration_log(1); > + assert(r >=3D 0); > } > =20 > -static int kvm_client_migration_log(struct CPUPhysMemoryClient *client= , > - int enable) > +static void kvm_log_global_stop(struct MemoryListener *listener) > { > - return kvm_set_migration_log(enable); > + int r; > + > + r =3D kvm_set_migration_log(0); > + assert(r >=3D 0); > } > =20 > -static CPUPhysMemoryClient kvm_cpu_phys_memory_client =3D { > - .set_memory =3D kvm_client_set_memory, > - .sync_dirty_bitmap =3D kvm_client_sync_dirty_bitmap, > - .migration_log =3D kvm_client_migration_log, > +static MemoryListener kvm_memory_listener =3D { > + .region_add =3D kvm_region_add, > + .region_del =3D kvm_region_del, > .log_start =3D kvm_log_start, > .log_stop =3D kvm_log_stop, > + .log_sync =3D kvm_log_sync, > + .log_global_start =3D kvm_log_global_start, > + .log_global_stop =3D kvm_log_global_stop, > }; > =20 > static void kvm_handle_interrupt(CPUState *env, int mask) > @@ -794,7 +827,7 @@ int kvm_init(void) > } > =20 > kvm_state =3D s; > - cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client); > + memory_listener_register(&kvm_memory_listener); > =20 > s->many_ioeventfds =3D kvm_check_many_ioeventfds(); > =20 --------------enig9E5B52259BF9B6934B3290E6 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk8SryUACgkQitSsb3rl5xTmKwCfYW4Lm847iwxApUYsijIFwkGf ED8AoOPhwyGzWmzHoFkAKKjvcnCHaE1g =PH0P -----END PGP SIGNATURE----- --------------enig9E5B52259BF9B6934B3290E6--