From patchwork Thu Mar 24 21:56:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: sergey.fedorov@linaro.org X-Patchwork-Id: 601823 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qWL1r3hSFz9s1h for ; Fri, 25 Mar 2016 08:59:28 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b=GUGSr7DI; dkim-atps=neutral Received: from localhost ([::1]:52973 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajDHq-0003cH-RT for incoming@patchwork.ozlabs.org; Thu, 24 Mar 2016 17:59:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45335) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajDGA-0008VL-2q for qemu-devel@nongnu.org; Thu, 24 Mar 2016 17:57:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ajDG8-0008Sh-MC for qemu-devel@nongnu.org; Thu, 24 Mar 2016 17:57:42 -0400 Received: from mail-lf0-x235.google.com ([2a00:1450:4010:c07::235]:32988) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ajDG8-0008SZ-A0 for qemu-devel@nongnu.org; Thu, 24 Mar 2016 17:57:40 -0400 Received: by mail-lf0-x235.google.com with SMTP id o73so44674678lfe.0 for ; Thu, 24 Mar 2016 14:57:40 -0700 (PDT) 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=EgL8iPMdNBXXeEJsoH2JjMlg4TTmZkPsl8gCigUprAc=; b=GUGSr7DITDg1SmnhQAPicegBW5eSfMgFj34txkAHxeziKMyDtfCPhGRAzC0ChkDNQk MQqWpz+a5B6lIJ5DSTYetlEq4UXS7XFNJn4dFHPesXUSSWHOnvSIFtUFFvykQNaFtIHO 8jEULzpYbU64SNyzdFmkrYmFWRTkQdPCDyYUg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EgL8iPMdNBXXeEJsoH2JjMlg4TTmZkPsl8gCigUprAc=; b=eTmEwhZ3BXuCyI56Y91hnwxAzD+asz4Mx05AOyyyJ2LE/Taug+VlNOAqsdhPV/dazU lvAQWygyCi4E3s+ONul78B4wwGuBzrP04goRgadbtKzczkknz3ZacZyf/zDaespx7E5p LLUL5wlAPMW2IOUstZw/3tBdcCc3hPZv6K6X0ViHoBaKo9hXggGciqSsbUGbbQUTH1Jj IQu+H25YRsehP9u5C+Zaubb7hIT4YTfdCeC/ExMiUDQifSb1yjpZgRudReu96IIrigyQ j0R6VYi+Qn6pGNuVrySuNsHP6d24Fx6D1wu58hUhn1l+H8u1GJtiMq4Irw6g7vInFbhe UYog== X-Gm-Message-State: AD7BkJJXyzbA7rvHGU78iSpnhFWYVlIZ+/RYfNRsZF/NPZtuh7WoLV6SzYjCMKF6YwaHq/CS X-Received: by 10.25.207.76 with SMTP id f73mr4640564lfg.11.1458856659520; Thu, 24 Mar 2016 14:57:39 -0700 (PDT) Received: from sergey-laptop.Dlink (broadband-46-188-121-115.2com.net. [46.188.121.115]) by smtp.gmail.com with ESMTPSA id a14sm1547144lfe.7.2016.03.24.14.57.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 24 Mar 2016 14:57:38 -0700 (PDT) From: sergey.fedorov@linaro.org To: qemu-devel@nongnu.org Date: Fri, 25 Mar 2016 00:56:42 +0300 Message-Id: <1458856607-3275-4-git-send-email-sergey.fedorov@linaro.org> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1458856607-3275-1-git-send-email-sergey.fedorov@linaro.org> References: <1458856607-3275-1-git-send-email-sergey.fedorov@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:4010:c07::235 Cc: Sergey Fedorov , Peter Crosthwaite , Paolo Bonzini , Sergey Fedorov , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson Subject: [Qemu-devel] [PATCH v2 3/8] tcg: Rearrange tb_link_page() to avoid forward declaration 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: Sergey Fedorov Signed-off-by: Sergey Fedorov Signed-off-by: Sergey Fedorov Reviewed-by: Alex Bennée --- translate-all.c | 204 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 101 insertions(+), 103 deletions(-) diff --git a/translate-all.c b/translate-all.c index 374e8bc4944b..e54afb89e414 100644 --- a/translate-all.c +++ b/translate-all.c @@ -153,8 +153,6 @@ void tb_lock_reset(void) #endif } -static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, - tb_page_addr_t phys_page2); static TranslationBlock *tb_find_pc(uintptr_t tc_ptr); void cpu_gen_init(void) @@ -1051,6 +1049,107 @@ static void build_page_bitmap(PageDesc *p) } } +/* add the tb in the target page and protect it if necessary + * + * Called with mmap_lock held for user-mode emulation. + */ +static inline void tb_alloc_page(TranslationBlock *tb, + unsigned int n, tb_page_addr_t page_addr) +{ + PageDesc *p; +#ifndef CONFIG_USER_ONLY + bool page_already_protected; +#endif + + tb->page_addr[n] = page_addr; + p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1); + tb->page_next[n] = p->first_tb; +#ifndef CONFIG_USER_ONLY + page_already_protected = p->first_tb != NULL; +#endif + p->first_tb = (TranslationBlock *)((uintptr_t)tb | n); + invalidate_page_bitmap(p); + +#if defined(CONFIG_USER_ONLY) + if (p->flags & PAGE_WRITE) { + target_ulong addr; + PageDesc *p2; + int prot; + + /* force the host page as non writable (writes will have a + page fault + mprotect overhead) */ + page_addr &= qemu_host_page_mask; + prot = 0; + for (addr = page_addr; addr < page_addr + qemu_host_page_size; + addr += TARGET_PAGE_SIZE) { + + p2 = page_find(addr >> TARGET_PAGE_BITS); + if (!p2) { + continue; + } + prot |= p2->flags; + p2->flags &= ~PAGE_WRITE; + } + mprotect(g2h(page_addr), qemu_host_page_size, + (prot & PAGE_BITS) & ~PAGE_WRITE); +#ifdef DEBUG_TB_INVALIDATE + printf("protecting code page: 0x" TARGET_FMT_lx "\n", + page_addr); +#endif + } +#else + /* if some code is already present, then the pages are already + protected. So we handle the case where only the first TB is + allocated in a physical page */ + if (!page_already_protected) { + tlb_protect_code(page_addr); + } +#endif +} + +/* add a new TB and link it to the physical page tables. phys_page2 is + * (-1) to indicate that only one page contains the TB. + * + * Called with mmap_lock held for user-mode emulation. + */ +static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, + tb_page_addr_t phys_page2) +{ + unsigned int h; + TranslationBlock **ptb; + + /* add in the physical hash table */ + h = tb_phys_hash_func(phys_pc); + ptb = &tcg_ctx.tb_ctx.tb_phys_hash[h]; + tb->phys_hash_next = *ptb; + *ptb = tb; + + /* add in the page list */ + tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK); + if (phys_page2 != -1) { + tb_alloc_page(tb, 1, phys_page2); + } else { + tb->page_addr[1] = -1; + } + + assert(((uintptr_t)tb & 3) == 0); + tb->jmp_list_first = (uintptr_t)tb | 2; + tb->jmp_list_next[0] = (uintptr_t)NULL; + tb->jmp_list_next[1] = (uintptr_t)NULL; + + /* init original jump addresses */ + if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) { + tb_reset_jump(tb, 0); + } + if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) { + tb_reset_jump(tb, 1); + } + +#ifdef DEBUG_TB_CHECK + tb_page_check(); +#endif +} + /* Called with mmap_lock held for user mode emulation. */ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, @@ -1407,107 +1506,6 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr, } #endif -/* add the tb in the target page and protect it if necessary - * - * Called with mmap_lock held for user-mode emulation. - */ -static inline void tb_alloc_page(TranslationBlock *tb, - unsigned int n, tb_page_addr_t page_addr) -{ - PageDesc *p; -#ifndef CONFIG_USER_ONLY - bool page_already_protected; -#endif - - tb->page_addr[n] = page_addr; - p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1); - tb->page_next[n] = p->first_tb; -#ifndef CONFIG_USER_ONLY - page_already_protected = p->first_tb != NULL; -#endif - p->first_tb = (TranslationBlock *)((uintptr_t)tb | n); - invalidate_page_bitmap(p); - -#if defined(CONFIG_USER_ONLY) - if (p->flags & PAGE_WRITE) { - target_ulong addr; - PageDesc *p2; - int prot; - - /* force the host page as non writable (writes will have a - page fault + mprotect overhead) */ - page_addr &= qemu_host_page_mask; - prot = 0; - for (addr = page_addr; addr < page_addr + qemu_host_page_size; - addr += TARGET_PAGE_SIZE) { - - p2 = page_find(addr >> TARGET_PAGE_BITS); - if (!p2) { - continue; - } - prot |= p2->flags; - p2->flags &= ~PAGE_WRITE; - } - mprotect(g2h(page_addr), qemu_host_page_size, - (prot & PAGE_BITS) & ~PAGE_WRITE); -#ifdef DEBUG_TB_INVALIDATE - printf("protecting code page: 0x" TARGET_FMT_lx "\n", - page_addr); -#endif - } -#else - /* if some code is already present, then the pages are already - protected. So we handle the case where only the first TB is - allocated in a physical page */ - if (!page_already_protected) { - tlb_protect_code(page_addr); - } -#endif -} - -/* add a new TB and link it to the physical page tables. phys_page2 is - * (-1) to indicate that only one page contains the TB. - * - * Called with mmap_lock held for user-mode emulation. - */ -static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, - tb_page_addr_t phys_page2) -{ - unsigned int h; - TranslationBlock **ptb; - - /* add in the physical hash table */ - h = tb_phys_hash_func(phys_pc); - ptb = &tcg_ctx.tb_ctx.tb_phys_hash[h]; - tb->phys_hash_next = *ptb; - *ptb = tb; - - /* add in the page list */ - tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK); - if (phys_page2 != -1) { - tb_alloc_page(tb, 1, phys_page2); - } else { - tb->page_addr[1] = -1; - } - - assert(((uintptr_t)tb & 3) == 0); - tb->jmp_list_first = (uintptr_t)tb | 2; - tb->jmp_list_next[0] = (uintptr_t)NULL; - tb->jmp_list_next[1] = (uintptr_t)NULL; - - /* init original jump addresses */ - if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) { - tb_reset_jump(tb, 0); - } - if (tb->jmp_reset_offset[1] != TB_JMP_RESET_OFFSET_INVALID) { - tb_reset_jump(tb, 1); - } - -#ifdef DEBUG_TB_CHECK - tb_page_check(); -#endif -} - /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < tb[1].tc_ptr. Return NULL if not found */ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)