From patchwork Sun Nov 4 06:51:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 196981 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C02862C00C8 for ; Sun, 4 Nov 2012 17:52:22 +1100 (EST) Received: from localhost ([::1]:36736 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TUu4B-0007uM-Ua for incoming@patchwork.ozlabs.org; Sun, 04 Nov 2012 01:52:19 -0500 Received: from eggs.gnu.org ([208.118.235.92]:53048) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TUu45-0007uG-Fv for qemu-devel@nongnu.org; Sun, 04 Nov 2012 01:52:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TUu44-0001JX-8c for qemu-devel@nongnu.org; Sun, 04 Nov 2012 01:52:13 -0500 Received: from mout.web.de ([212.227.17.11]:57519) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TUu43-0001JP-Tx for qemu-devel@nongnu.org; Sun, 04 Nov 2012 01:52:12 -0500 Received: from mchn199C.mchp.siemens.de ([95.157.56.37]) by smtp.web.de (mrweb003) with ESMTPSA (Nemesis) id 0MZlNu-1Tn8Uz0Oas-00LVIl; Sun, 04 Nov 2012 07:51:53 +0100 Message-ID: <50961086.4000704@web.de> Date: Sun, 04 Nov 2012 07:51:50 +0100 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Blue Swirl , qemu-devel X-Enigmail-Version: 1.4.5 X-Provags-ID: V02:K0:3hc2f8LoCSuE1hJRNTcYAzee7z/9RJLkIeKucgCvmRr rXyjGDTxjve1aoiCRkJY/rpgQOMaTcnnf/XH1GziE20C8AuvY7 cvszr6OhS+2q3kz3WMz858OJcbshqiuXwo9Oc/4GJivpR/nX+U /0A3wUMRig1BOoR9kPa0JEVfaF1JXhbt/Rj3Dp2QZTy2mB0vsU kArKuwjGJ9eIFf2S5WleQ== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 212.227.17.11 Cc: =?ISO-8859-1?Q?Herv=E9_Poussineau?= , David Gibson Subject: [Qemu-devel] [PATCH] kvmvapic: Fix TB invalidation after instruction patching 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: Jan Kiszka Since 0b57e287, cpu_memory_rw_debug already triggers a TB invalidation. As it doesn't (and cannot) set is_cpu_write_access=1 but "consumes" the currently executed TB, the tb_invalidate_phys_page_range call from patch_instruction didn't work anymore. Fix this by open-coding the required bits to restore the CPU state from the current TB position before patching and resume execution on the patched instruction afterward. Signed-off-by: Jan Kiszka Tested-by: HervĂ© Poussineau --- I see no better way ATM. hw/kvmvapic.c | 20 ++++++++++++++++---- 1 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c index dc111ee..e7ab3cc 100644 --- a/hw/kvmvapic.c +++ b/hw/kvmvapic.c @@ -384,10 +384,13 @@ static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip, static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong ip) { - hwaddr paddr; VAPICHandlers *handlers; uint8_t opcode[2]; uint32_t imm32; + TranslationBlock *current_tb; + target_ulong current_pc; + target_ulong current_cs_base; + int current_flags; if (smp_cpus == 1) { handlers = &s->rom_state.up; @@ -395,6 +398,13 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i handlers = &s->rom_state.mp; } + if (!kvm_enabled()) { + current_tb = tb_find_pc(env->mem_io_pc); + cpu_restore_state(current_tb, env, env->mem_io_pc); + cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, + ¤t_flags); + } + pause_all_vcpus(); cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0); @@ -430,9 +440,11 @@ static void patch_instruction(VAPICROMState *s, CPUX86State *env, target_ulong i resume_all_vcpus(); - paddr = cpu_get_phys_page_debug(env, ip); - paddr += ip & ~TARGET_PAGE_MASK; - tb_invalidate_phys_page_range(paddr, paddr + 1, 1); + if (!kvm_enabled()) { + env->current_tb = NULL; + tb_gen_code(env, current_pc, current_cs_base, current_flags, 1); + cpu_resume_from_signal(env, NULL); + } } void vapic_report_tpr_access(DeviceState *dev, void *cpu, target_ulong ip,