From 65394ad98b2da40f50fb3d379187754dfa549daa Mon Sep 17 00:00:00 2001 Message-Id: <65394ad98b2da40f50fb3d379187754dfa549daa.1378124219.git.minovotn@redhat.com> In-Reply-To: References: From: Stefan Hajnoczi Date: Tue, 27 Aug 2013 14:44:35 +0200 Subject: [PATCH 3/3] Fix off-by-one error in page_l1_map() RH-Author: Stefan Hajnoczi Message-id: <1377614675-20743-1-git-send-email-stefanha@redhat.com> Patchwork-id: 53801 O-Subject: [RHEL-6.5 qemu-kvm PATCH] Fix off-by-one error in page_l1_map() Bugzilla: 996791 RH-Acked-by: Paolo Bonzini RH-Acked-by: Juan Quintela RH-Acked-by: Laszlo Ersek Bugzilla: 996791 Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=6215029 Upstream-status: RHEL-only From: David Gibson Fix off-by-one error in page_l1_map() page_l1_map() is supposed to return NULL for addresses beyond those covered by the l1_map[] array (2^20 pages / 4G of memory). However, the test for this uses > instead of >= meaning that for an address exactly on the boundary of the covered area, instead of returning NULL it will return a bogus value from beyond the end of the l1_map[] array. This patch fixes it. Signed-off-by: David Gibson David Gibson debugged a qemu-kvm crash where a virtio buffer at 0x100000000 (4 GB) is being unmapped. The problem is that cpu_physical_memory_unmap() calls tb_invalidate_phys_page_range() where page_l1_map() returns a pointer one beyond the end of l1_map[]. page_l1_map() should return NULL when the address is outside l1_map[]. Upstream the memory API reimplemented the code correctly. Therefore this patch is RHEL-only. Signed-off-by: Stefan Hajnoczi --- exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Signed-off-by: Michal Novotny --- exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec.c b/exec.c index d8544aa..df5a98b 100644 --- a/exec.c +++ b/exec.c @@ -294,7 +294,7 @@ static inline PageDesc **page_l1_map(target_ulong index) #if TARGET_LONG_BITS > 32 /* Host memory outside guest VM. For 32-bit targets we have already excluded high addresses. */ - if (index > ((target_ulong)L2_SIZE * L1_SIZE)) + if (index >= ((target_ulong)L2_SIZE * L1_SIZE)) return NULL; #endif return &l1_map[index >> L2_BITS]; -- 1.7.11.7