From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:44963) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UfvPA-0002Lr-PF for qemu-devel@nongnu.org; Fri, 24 May 2013 13:03:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UfvP4-00018A-RN for qemu-devel@nongnu.org; Fri, 24 May 2013 13:03:48 -0400 Received: from mail-ee0-f45.google.com ([74.125.83.45]:52524) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UfvP4-00017s-Kx for qemu-devel@nongnu.org; Fri, 24 May 2013 13:03:42 -0400 Received: by mail-ee0-f45.google.com with SMTP id l10so2722222eei.4 for ; Fri, 24 May 2013 10:03:42 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Fri, 24 May 2013 19:03:05 +0200 Message-Id: <1369414987-8839-14-git-send-email-pbonzini@redhat.com> In-Reply-To: <1369414987-8839-1-git-send-email-pbonzini@redhat.com> References: <1369414987-8839-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 13/15] memory: limit sections in the radix tree to the actual address space size List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Avi Kivity From: Avi Kivity The radix tree is statically sized to fit TARGET_PHYS_ADDR_SPACE_BITS. If a larger memory region is registered, it will overflow. Fix by limiting any section in the radix tree to the supported size. This problem was not observed earlier since artificial regions (containers and aliases) are eliminated by the memory core, leaving only device regions which have reasonable sizes. An IOMMU however cannot be eliminated by the memory core, and may have an artificial size. Reviewed-by: Peter Maydell Signed-off-by: Avi Kivity [ Fail the build if TARGET_PHYS_ADDR_SPACE_BITS is too large - Paolo ] Signed-off-by: Paolo Bonzini --- exec.c | 13 ++++++++++++- include/exec/memory.h | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 8562fca..3fdca46 100644 --- a/exec.c +++ b/exec.c @@ -775,10 +775,21 @@ static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *sec section_index); } +QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > MAX_PHYS_ADDR_SPACE_BITS) + +static MemoryRegionSection limit(MemoryRegionSection section) +{ + section.size = MIN(section.offset_within_address_space + section.size, + MAX_PHYS_ADDR + 1) + - section.offset_within_address_space; + + return section; +} + static void mem_add(MemoryListener *listener, MemoryRegionSection *section) { AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener); - MemoryRegionSection now = *section, remain = *section; + MemoryRegionSection now = limit(*section), remain = limit(*section); if ((now.offset_within_address_space & ~TARGET_PAGE_MASK) || (now.size < TARGET_PAGE_SIZE)) { diff --git a/include/exec/memory.h b/include/exec/memory.h index 91be2a3..fdf55fe 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -26,6 +26,9 @@ #include "exec/ioport.h" #include "qemu/int128.h" +#define MAX_PHYS_ADDR_SPACE_BITS 62 +#define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1) + typedef struct MemoryRegionOps MemoryRegionOps; typedef struct MemoryRegionPortio MemoryRegionPortio; typedef struct MemoryRegionMmio MemoryRegionMmio; -- 1.8.1.4