From patchwork Sat Oct 20 07:05:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: YeongKyoon Lee X-Patchwork-Id: 192904 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 46FC12C0093 for ; Sat, 20 Oct 2012 18:06:23 +1100 (EST) Received: from localhost ([::1]:39511 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TPT8X-00065Z-C4 for incoming@patchwork.ozlabs.org; Sat, 20 Oct 2012 03:06:21 -0400 Received: from eggs.gnu.org ([208.118.235.92]:54496) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TPT8D-0005nE-QN for qemu-devel@nongnu.org; Sat, 20 Oct 2012 03:06:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TPT8B-0002jy-HB for qemu-devel@nongnu.org; Sat, 20 Oct 2012 03:06:01 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:50125) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TPT8B-0002eq-7A for qemu-devel@nongnu.org; Sat, 20 Oct 2012 03:05:59 -0400 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MC600EH1JPOFH10@mailout4.samsung.com> for qemu-devel@nongnu.org; Sat, 20 Oct 2012 16:05:56 +0900 (KST) X-AuditID: cbfee61b-b7fd46d0000046e0-c1-50824d54c7aa Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id E2.8B.18144.45D42805; Sat, 20 Oct 2012 16:05:56 +0900 (KST) Received: from localhost.localdomain ([182.198.1.3]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MC600C8VJPQ8200@mmp1.samsung.com> for qemu-devel@nongnu.org; Sat, 20 Oct 2012 16:05:56 +0900 (KST) From: Yeongkyoon Lee To: qemu-devel@nongnu.org Date: Sat, 20 Oct 2012 16:05:42 +0900 Message-id: <1350716743-2812-3-git-send-email-yeongkyoon.lee@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1350716743-2812-1-git-send-email-yeongkyoon.lee@samsung.com> References: <1350716743-2812-1-git-send-email-yeongkyoon.lee@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrEJMWRmVeSWpSXmKPExsVy+t9jAd0Q36YAg5/3OSyO9+5gcWD0eHJt M1MAYxSXTUpqTmZZapG+XQJXxsk3t5kLWgwrVh1vZ2pg7FbpYuTkkBAwkdiy5yEjhC0mceHe erYuRi4OIYFFjBK72/awQDjzmCTedexkAaliEzCUmHn+CROILSIgKfG76zQziM0skCdx7Oh6 MFtYoFTix/GF7CA2i4CqxLHpr8F6eQU8JT5c3w60gQNom4LEnEk2IGFOAS+Jdd/6wY4QAirZ OXMH6wRG3gWMDKsYRVMLkguKk9JzjfSKE3OLS/PS9ZLzczcxgn3+THoH46oGi0OMAhyMSjy8 En2NAUKsiWXFlbmHGCU4mJVEeJcuAgrxpiRWVqUW5ccXleakFh9ilOZgURLnbfZICRASSE8s Sc1OTS1ILYLJMnFwSjUwBhjs+9Z8a01ZZeSv/5v8zjzIvaz0pCjsyJV735d/9QrcwqkVv07v 8+wrToVPdhwvCLEMkzAwLlNVuTwtxF42aG7Qke31bcFNsiEx34ziT3PODcnasqhLekt5eXto vcoOFqZDm14F/T3Ytd5U7M7CqNerLRdzZP9zurwof7n+nYdsB8+fWvdFSYmlOCPRUIu5qDgR AMtD+9r1AQAA X-detected-operating-system: by eggs.gnu.org: Solaris 10 (1203?) X-Received-From: 203.254.224.34 Cc: blauwirbel@gmail.com, Yeongkyoon Lee , aurelien@aurel32.net, rth@twiddle.net Subject: [Qemu-devel] [RESEND PATCH v6 2/3] tcg: Add extended GETPC mechanism for MMU helpers with ldst optimization 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 Add GETPC_EXT which is used by MMU helpers to selectively calculate the code address of accessing guest memory when called from a qemu_ld/st optimized code or a C function. Currently, it supports only i386 and x86-64 hosts. Signed-off-by: Yeongkyoon Lee --- exec-all.h | 36 ++++++++++++++++++++++++++++++++++++ exec.c | 11 +++++++++++ softmmu_template.h | 16 ++++++++-------- 3 files changed, 55 insertions(+), 8 deletions(-) -- 1.7.5.4 diff --git a/exec-all.h b/exec-all.h index 6516da0..9eda604 100644 --- a/exec-all.h +++ b/exec-all.h @@ -311,6 +311,42 @@ extern uintptr_t tci_tb_ptr; # define GETPC() ((uintptr_t)__builtin_return_address(0) - 1) #endif +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) +/* qemu_ld/st optimization split code generation to fast and slow path, thus, + it needs special handling for an MMU helper which is called from the slow + path, to get the fast path's pc without any additional argument. + It uses a tricky solution which embeds the fast path pc into the slow path. + + Code flow in slow path: + (1) pre-process + (2) call MMU helper + (3) jump to (5) + (4) fast path information (implementation specific) + (5) post-process (e.g. stack adjust) + (6) jump to corresponding code of the next of fast path + */ +# if defined(__i386__) || defined(__x86_64__) +/* To avoid broken disassembling, long jmp is used for embedding fast path pc, + so that the destination is the next code of fast path, though this jmp is + never executed. + + call MMU helper + jmp POST_PROC (2byte) <- GETRA() + jmp NEXT_CODE (5byte) + POST_PROCESS ... <- GETRA() + 7 + */ +# define GETRA() ((uintptr_t)__builtin_return_address(0)) +# define GETPC_LDST() ((uintptr_t)(GETRA() + 7 + \ + *(int32_t *)((void *)GETRA() + 3) - 1)) +# else +# error "CONFIG_QEMU_LDST_OPTIMIZATION needs GETPC_LDST() implementation!" +# endif +bool is_tcg_gen_code(uintptr_t pc_ptr); +# define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC()) +#else +# define GETPC_EXT() GETPC() +#endif + #if !defined(CONFIG_USER_ONLY) struct MemoryRegion *iotlb_to_region(target_phys_addr_t index); diff --git a/exec.c b/exec.c index 7899042..8a825a9 100644 --- a/exec.c +++ b/exec.c @@ -1379,6 +1379,17 @@ void tb_link_page(TranslationBlock *tb, mmap_unlock(); } +#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU) +/* check whether the give addr is in TCG generated code buffer or not */ +bool is_tcg_gen_code(uintptr_t tc_ptr) +{ + /* This can be called during code generation, code_gen_buffer_max_size + is used instead of code_gen_ptr for upper boundary checking */ + return (tc_ptr >= (uintptr_t)code_gen_buffer && + tc_ptr < (uintptr_t)(code_gen_buffer + code_gen_buffer_max_size)); +} +#endif + /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < tb[1].tc_ptr. Return NULL if not found */ TranslationBlock *tb_find_pc(uintptr_t tc_ptr) diff --git a/softmmu_template.h b/softmmu_template.h index e2490f0..d23de8c 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -111,13 +111,13 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - retaddr = GETPC(); + retaddr = GETPC_EXT(); ioaddr = env->iotlb[mmu_idx][index]; res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { /* slow unaligned access (it spans two pages or IO) */ do_unaligned_access: - retaddr = GETPC(); + retaddr = GETPC_EXT(); #ifdef ALIGNED_ONLY do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); #endif @@ -128,7 +128,7 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, uintptr_t addend; #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { - retaddr = GETPC(); + retaddr = GETPC_EXT(); do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } #endif @@ -138,7 +138,7 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr, } } else { /* the page is not in the TLB : fill it */ - retaddr = GETPC(); + retaddr = GETPC_EXT(); #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); @@ -257,12 +257,12 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - retaddr = GETPC(); + retaddr = GETPC_EXT(); ioaddr = env->iotlb[mmu_idx][index]; glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { do_unaligned_access: - retaddr = GETPC(); + retaddr = GETPC_EXT(); #ifdef ALIGNED_ONLY do_unaligned_access(env, addr, 1, mmu_idx, retaddr); #endif @@ -273,7 +273,7 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, uintptr_t addend; #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { - retaddr = GETPC(); + retaddr = GETPC_EXT(); do_unaligned_access(env, addr, 1, mmu_idx, retaddr); } #endif @@ -283,7 +283,7 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, } } else { /* the page is not in the TLB : fill it */ - retaddr = GETPC(); + retaddr = GETPC_EXT(); #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) do_unaligned_access(env, addr, 1, mmu_idx, retaddr);