From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Hildenbrand Subject: [PATCH v1 2/6] kvm: factor out alignment of memory section Date: Mon, 11 Sep 2017 19:49:29 +0200 Message-ID: <20170911174933.20789-3-david@redhat.com> References: <20170911174933.20789-1-david@redhat.com> Cc: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , kvm@vger.kernel.org, david@redhat.com To: qemu-devel@nongnu.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:51410 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751022AbdIKRtm (ORCPT ); Mon, 11 Sep 2017 13:49:42 -0400 In-Reply-To: <20170911174933.20789-1-david@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: Factor it out, so we can reuse it later. Signed-off-by: David Hildenbrand --- accel/kvm/kvm-all.c | 59 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 985b179ab6..e0d100bd30 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -190,6 +190,36 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml, } /* + * Calculate and align the start address and the size of the section. + * Return the size. If the size is 0, the aligned section is empty. + */ +static hwaddr kvm_align_section(MemoryRegionSection *section, + hwaddr *start) +{ + hwaddr size = int128_get64(section->size); + hwaddr delta; + + *start = section->offset_within_address_space; + + /* kvm works in page size chunks, but the function may be called + with sub-page size and unaligned start address. Pad the start + address to next and truncate size to previous page boundary. */ + delta = qemu_real_host_page_size - (*start & ~qemu_real_host_page_mask); + delta &= ~qemu_real_host_page_mask; + *start += delta; + if (delta > size) { + return 0; + } + size -= delta; + size &= qemu_real_host_page_mask; + if (*start & ~qemu_real_host_page_mask) { + return 0; + } + + return size; +} + +/* * Find overlapping slot with lowest start address */ static KVMSlot *kvm_lookup_overlapping_slot(KVMMemoryListener *kml, @@ -700,25 +730,8 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, int err; MemoryRegion *mr = section->mr; bool writeable = !mr->readonly && !mr->rom_device; - hwaddr start_addr = section->offset_within_address_space; - ram_addr_t size = int128_get64(section->size); - void *ram = NULL; - unsigned delta; - - /* kvm works in page size chunks, but the function may be called - with sub-page size and unaligned start address. Pad the start - address to next and truncate size to previous page boundary. */ - delta = qemu_real_host_page_size - (start_addr & ~qemu_real_host_page_mask); - delta &= ~qemu_real_host_page_mask; - if (delta > size) { - return; - } - start_addr += delta; - size -= delta; - size &= qemu_real_host_page_mask; - if (!size || (start_addr & ~qemu_real_host_page_mask)) { - return; - } + hwaddr start_addr, size; + void *ram; if (!memory_region_is_ram(mr)) { if (writeable || !kvm_readonly_mem_allowed) { @@ -730,7 +743,13 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, } } - ram = memory_region_get_ram_ptr(mr) + section->offset_within_region + delta; + size = kvm_align_section(section, &start_addr); + if (!size) { + return; + } + + ram = memory_region_get_ram_ptr(mr) + section->offset_within_region + + (section->offset_within_address_space - start_addr); while (1) { mem = kvm_lookup_overlapping_slot(kml, start_addr, start_addr + size); -- 2.13.5 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49125) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drSq8-0000kJ-CP for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:49:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drSq7-00088n-Eh for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:49:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57622) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drSq7-00087p-5f for qemu-devel@nongnu.org; Mon, 11 Sep 2017 13:49:43 -0400 From: David Hildenbrand Date: Mon, 11 Sep 2017 19:49:29 +0200 Message-Id: <20170911174933.20789-3-david@redhat.com> In-Reply-To: <20170911174933.20789-1-david@redhat.com> References: <20170911174933.20789-1-david@redhat.com> Subject: [Qemu-devel] [PATCH v1 2/6] kvm: factor out alignment of memory section List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , kvm@vger.kernel.org, david@redhat.com Factor it out, so we can reuse it later. Signed-off-by: David Hildenbrand --- accel/kvm/kvm-all.c | 59 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 985b179ab6..e0d100bd30 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -190,6 +190,36 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml, } /* + * Calculate and align the start address and the size of the section. + * Return the size. If the size is 0, the aligned section is empty. + */ +static hwaddr kvm_align_section(MemoryRegionSection *section, + hwaddr *start) +{ + hwaddr size = int128_get64(section->size); + hwaddr delta; + + *start = section->offset_within_address_space; + + /* kvm works in page size chunks, but the function may be called + with sub-page size and unaligned start address. Pad the start + address to next and truncate size to previous page boundary. */ + delta = qemu_real_host_page_size - (*start & ~qemu_real_host_page_mask); + delta &= ~qemu_real_host_page_mask; + *start += delta; + if (delta > size) { + return 0; + } + size -= delta; + size &= qemu_real_host_page_mask; + if (*start & ~qemu_real_host_page_mask) { + return 0; + } + + return size; +} + +/* * Find overlapping slot with lowest start address */ static KVMSlot *kvm_lookup_overlapping_slot(KVMMemoryListener *kml, @@ -700,25 +730,8 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, int err; MemoryRegion *mr = section->mr; bool writeable = !mr->readonly && !mr->rom_device; - hwaddr start_addr = section->offset_within_address_space; - ram_addr_t size = int128_get64(section->size); - void *ram = NULL; - unsigned delta; - - /* kvm works in page size chunks, but the function may be called - with sub-page size and unaligned start address. Pad the start - address to next and truncate size to previous page boundary. */ - delta = qemu_real_host_page_size - (start_addr & ~qemu_real_host_page_mask); - delta &= ~qemu_real_host_page_mask; - if (delta > size) { - return; - } - start_addr += delta; - size -= delta; - size &= qemu_real_host_page_mask; - if (!size || (start_addr & ~qemu_real_host_page_mask)) { - return; - } + hwaddr start_addr, size; + void *ram; if (!memory_region_is_ram(mr)) { if (writeable || !kvm_readonly_mem_allowed) { @@ -730,7 +743,13 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, } } - ram = memory_region_get_ram_ptr(mr) + section->offset_within_region + delta; + size = kvm_align_section(section, &start_addr); + if (!size) { + return; + } + + ram = memory_region_get_ram_ptr(mr) + section->offset_within_region + + (section->offset_within_address_space - start_addr); while (1) { mem = kvm_lookup_overlapping_slot(kml, start_addr, start_addr + size); -- 2.13.5