From patchwork Tue Jul 23 15:49:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Riku Voipio X-Patchwork-Id: 261112 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CC52B2C00AC for ; Wed, 24 Jul 2013 01:53:48 +1000 (EST) Received: from localhost ([::1]:58258 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1euI-0002qB-1h for incoming@patchwork.ozlabs.org; Tue, 23 Jul 2013 11:53:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57609) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1eqC-0005OY-M4 for qemu-devel@nongnu.org; Tue, 23 Jul 2013 11:49:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V1epz-0001aj-B9 for qemu-devel@nongnu.org; Tue, 23 Jul 2013 11:49:32 -0400 Received: from afflict.kos.to ([92.243.29.197]:45192) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1epz-0001aP-5i for qemu-devel@nongnu.org; Tue, 23 Jul 2013 11:49:19 -0400 Received: from kos.to (a91-156-63-85.elisa-laajakaista.fi [91.156.63.85]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by afflict.kos.to (Postfix) with ESMTPSA id A3CB42654F for ; Tue, 23 Jul 2013 17:49:17 +0200 (CEST) Received: from voipio (uid 1000) (envelope-from voipio@kos.to) id 5e081c by kos.to (DragonFly Mail Agent); Tue, 23 Jul 2013 18:49:14 +0300 From: riku.voipio@linaro.org To: qemu-devel@nongnu.org Date: Tue, 23 Jul 2013 18:49:07 +0300 Message-Id: <732f9e89a1c737f738c445ff24929a1bc137d1a9.1374593203.git.riku.voipio@linaro.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 92.243.29.197 Cc: Alexander Graf Subject: [Qemu-devel] [PULL 17/21] linux-user: fix segmentation fault passing with h2g(x) != x X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Alexander Graf When forwarding a segmentation fault into the guest process, we were passing the host's address directly into the guest process's signal descriptor. That obviously confused the guest process, since it didn't know what to make of the (usually 32-bit truncated) address. Passing in h2g(address) makes the guest process a lot happier. To make the code more obvious, introduce a h2g_nocheck() macro that does the same as h2g(), but allows us to convert addresses that may be outside of guest mapped range into the guest's view of address space. This fixes java running in arm-linux-user for me. Signed-off-by: Alexander Graf Signed-off-by: Riku Voipio --- include/exec/cpu-all.h | 8 ++++++-- user-exec.c | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 5084202..f1cde97 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -209,11 +209,15 @@ extern unsigned long reserved_va; }) #endif -#define h2g(x) ({ \ +#define h2g_nocheck(x) ({ \ unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \ + (abi_ulong)__ret; \ +}) + +#define h2g(x) ({ \ /* Check if given address fits target address space */ \ assert(h2g_valid(x)); \ - (abi_ulong)__ret; \ + h2g_nocheck(x); \ }) #define saddr(x) g2h(x) diff --git a/user-exec.c b/user-exec.c index d45ca8e..82bfa66 100644 --- a/user-exec.c +++ b/user-exec.c @@ -95,6 +95,10 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, return 1; } + /* Convert forcefully to guest address space, invalid addresses + are still valid segv ones */ + address = h2g_nocheck(address); + env = current_cpu->env_ptr; /* see if it is an MMU fault */ ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);