From patchwork Wed Nov 8 15:32:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 835858 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="cqhKza+X"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yX9Lp20WWz9s7c for ; Thu, 9 Nov 2017 02:33:47 +1100 (AEDT) Received: from localhost ([::1]:60462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eCSMK-0000SN-NK for incoming@patchwork.ozlabs.org; Wed, 08 Nov 2017 10:33:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34279) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eCSLX-0000PI-Ku for qemu-devel@nongnu.org; Wed, 08 Nov 2017 10:32:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eCSLR-00026U-F4 for qemu-devel@nongnu.org; Wed, 08 Nov 2017 10:32:55 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:54596) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eCSLR-00025i-70 for qemu-devel@nongnu.org; Wed, 08 Nov 2017 10:32:49 -0500 Received: by mail-wm0-x244.google.com with SMTP id r68so11663995wmr.3 for ; Wed, 08 Nov 2017 07:32:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RdjZVKDXF1lYZFRSoSg7iXRmw6zd1GpA/QRInYksgwQ=; b=cqhKza+XajA6MQu/EHGcDb6OkLDkFo3U/kL/BFyABy020R0YlDKbzMj2f9VwfDvnvg DdTzzfzzbIuVpi5fGAnUeYejLr+Q6IbSu3dtoGJQxM5tCosNNM1/HA4FdPYc/JRT4qYF Z8lT9OVJrbyonmbTYv5Sn1wZ+fgnyhOtUx++c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RdjZVKDXF1lYZFRSoSg7iXRmw6zd1GpA/QRInYksgwQ=; b=XJu1bR9PYuD/44MtI7ch2Pc2159ph2ylLxqDJmKeybcmFtAc2IjCrUefSI1vwSdDnu wWknV0C4MO1dZtRJyFDKDUsN44mePNjz5e/gax+jWQESdz6zJBaFwitSHI4cJ9zHDtWq rkw2zlMKbtPVtCtbB6f2cz7te6ODRMDVbpeiyF9FtF4gTrLTfs30Qpmxd4J954f0NJbD 6daRNSSH+k2hd/oOJlXp3FX4w+HUolIHAbYGTo0tGb7kcuVigd5NvOl6EVylPnDj+LzW kVULM7huQnlp4fd4Y+1xpxFtRYzNDONVoMveZt2/Rd3szIsuUuIwyq0SPy3dFrq/cbV6 nMww== X-Gm-Message-State: AJaThX7hJC1G0xIokjWXhkttlcrr7jjFHyZsEyCfXCgIWdp6T2g8+qaE MD9RGUdGN/akx0RxELXT/rczMA== X-Google-Smtp-Source: ABhQp+TnVHBglIzw2y527FYvzKqKw661d5LlVjFlyA3Jclk2PVfSKMgWBPxTrLb8tnEcv7IUjQRufg== X-Received: by 10.28.131.200 with SMTP id f191mr775322wmd.39.1510155167897; Wed, 08 Nov 2017 07:32:47 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id 89sm1383472wri.79.2017.11.08.07.32.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Nov 2017 07:32:46 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id B5F8F3E03B5; Wed, 8 Nov 2017 15:32:45 +0000 (GMT) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 8 Nov 2017 15:32:44 +0000 Message-Id: <20171108153245.20740-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171108153245.20740-1-alex.bennee@linaro.org> References: <20171108153245.20740-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PATCH v2 1/2] accel/tcg/translate-all: expand cpu_restore_state addr check X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Crosthwaite , qemu-devel@nongnu.org, qemu-arm@nongnu.org, Paolo Bonzini , =?utf-8?q?A?= =?utf-8?q?lex_Benn=C3=A9e?= , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We are still seeing signals during translation time when we walk over a page protection boundary. This expands the check to ensure the host PC is inside the code generation buffer. The original suggestion was to check versus tcg_ctx.code_gen_ptr but as we now segment the translation buffer we have to settle for just a general check for being inside. I've also fixed up the declaration to make it clear it can deal with invalid addresses. A later patch will fix up the call sites. Signed-off-by: Alex Bennée Reported-by: Peter Maydell Suggested-by: Paolo Bonzini Cc: Richard Henderson Reviewed-by: Laurent Vivier Reviewed-by: Richard Henderson --- v2: - add doc comment to exec-all.h - retaddr->host_pc - re-word comments on host_pc - simplify logic as per rth suggestion --- accel/tcg/translate-all.c | 52 ++++++++++++++++++++++++++--------------------- include/exec/exec-all.h | 11 ++++++++++ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 34c5e28d07..e7f0329a52 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -352,36 +352,42 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, return 0; } -bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr) +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) { TranslationBlock *tb; bool r = false; + uintptr_t check_offset; - /* A retaddr of zero is invalid so we really shouldn't have ended - * up here. The target code has likely forgotten to check retaddr - * != 0 before attempting to restore state. We return early to - * avoid blowing up on a recursive tb_lock(). The target must have - * previously survived a failed cpu_restore_state because - * tb_find_pc(0) would have failed anyway. It still should be - * fixed though. + /* The host_pc has to be in the region of current code buffer. If + * it is not we will not be able to resolve it here. The two cases + * where host_pc will not be correct are: + * + * - fault during translation (instruction fetch) + * - fault from helper (not using GETPC() macro) + * + * Either way we need return early to avoid blowing up on a + * recursive tb_lock() as we can't resolve it here. + * + * We are using unsigned arithmetic so if host_pc < + * tcg_init_ctx.code_gen_buffer check_offset will wrap to way + * above the code_gen_buffer_size */ - - if (!retaddr) { - return r; - } - - tb_lock(); - tb = tb_find_pc(retaddr); - if (tb) { - cpu_restore_state_from_tb(cpu, tb, retaddr); - if (tb->cflags & CF_NOCACHE) { - /* one-shot translation, invalidate it immediately */ - tb_phys_invalidate(tb, -1); - tb_remove(tb); + check_offset = host_pc - (uintptr_t) tcg_init_ctx.code_gen_buffer; + + if (check_offset < tcg_init_ctx.code_gen_buffer_size) { + tb_lock(); + tb = tb_find_pc(host_pc); + if (tb) { + cpu_restore_state_from_tb(cpu, tb, host_pc); + if (tb->cflags & CF_NOCACHE) { + /* one-shot translation, invalidate it immediately */ + tb_phys_invalidate(tb, -1); + tb_remove(tb); + } + r = true; } - r = true; + tb_unlock(); } - tb_unlock(); return r; } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 923ece3e9b..0f51c92adb 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -45,6 +45,17 @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb, target_ulong *data); void cpu_gen_init(void); + +/** + * cpu_restore_state: + * @cpu: the vCPU state is to be restore to + * @searched_pc: the host PC the fault occurred at + * @return: true if state was restored, false otherwise + * + * Attempt to restore the state for a fault occurring in translated + * code. If the searched_pc is not in translated code no state is + * restored and the function returns false. + */ bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc); void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);