From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:34819) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TMInK-0006lY-Un for qemu-devel@nongnu.org; Thu, 11 Oct 2012 09:27:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TMInI-0008R1-Fs for qemu-devel@nongnu.org; Thu, 11 Oct 2012 09:27:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35573) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TMInI-0008Qv-5l for qemu-devel@nongnu.org; Thu, 11 Oct 2012 09:27:20 -0400 From: Avi Kivity Date: Thu, 11 Oct 2012 15:26:58 +0200 Message-Id: <1349962023-560-3-git-send-email-avi@redhat.com> In-Reply-To: <1349962023-560-1-git-send-email-avi@redhat.com> References: <1349962023-560-1-git-send-email-avi@redhat.com> Subject: [Qemu-devel] [RFC v1 2/7] 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, Blue Swirl , Anthony Liguori , "Michael S. Tsirkin" , Alex Williamson , liu ping fan , Paolo Bonzini 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. Signed-off-by: Avi Kivity --- exec.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 4bc79fb..328753d 100644 --- a/exec.c +++ b/exec.c @@ -2272,10 +2272,23 @@ static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *sec section_index); } +static MemoryRegionSection limit(MemoryRegionSection section) +{ + unsigned practical_as_bits = MIN(TARGET_PHYS_ADDR_SPACE_BITS, 62); + target_phys_addr_t as_limit; + + as_limit = (target_phys_addr_t)1 << practical_as_bits; + + section.size = MIN(section.offset_within_address_space + section.size, as_limit) + - 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)) { -- 1.7.12