From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39048) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzkLb-0006X4-Bg for qemu-devel@nongnu.org; Tue, 02 Jun 2015 07:27:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YzkLY-0003OV-OG for qemu-devel@nongnu.org; Tue, 02 Jun 2015 07:27:07 -0400 Received: from hall.aurel32.net ([2001:bc8:30d7:101::1]:59990) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzkLY-0003Nb-GM for qemu-devel@nongnu.org; Tue, 02 Jun 2015 07:27:04 -0400 From: Aurelien Jarno Date: Tue, 2 Jun 2015 13:26:51 +0200 Message-Id: <1433244411-9693-6-git-send-email-aurelien@aurel32.net> In-Reply-To: <1433244411-9693-1-git-send-email-aurelien@aurel32.net> References: <1433244411-9693-1-git-send-email-aurelien@aurel32.net> Subject: [Qemu-devel] [PATCH RFC 5/5] target-s390x: use softmmu host addr function for mvcp/mvcs List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Alexander Graf , Yongbok Kim , Paolo Bonzini , Leon Alrae , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Aurelien Jarno , Richard Henderson mvcp and mvcs helper get access to the physical memory by a call to mmu_translate for the virtual to real conversion and then using ldb_phys and stb_phys to physically access the data. In practice this is quite slow because it bypasses the QEMU softmmu TLB and because stb_phys calls try to invalidate the corresponding memory for each access. Instead use the new softmmu guest virtual address to host address conversion and call memcpy, taking care of not crossing page boundaries. As we pass the return address, we can skip saving the registers in the TCG code, a page fault trigger code retranslation instead. This improves the boot time of a guest by a factor 2. Cc: Alexander Graf Cc: Richard Henderson Signed-off-by: Aurelien Jarno --- target-s390x/mem_helper.c | 44 +++++++++++++++----------------------------- target-s390x/translate.c | 2 -- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c index f34f2e1..0efb780 100644 --- a/target-s390x/mem_helper.c +++ b/target-s390x/mem_helper.c @@ -1026,40 +1026,26 @@ uint32_t HELPER(csp)(CPUS390XState *env, uint32_t r1, uint64_t r2) return cc; } -static uint32_t mvc_asc(CPUS390XState *env, int64_t l, uint64_t a1, - uint64_t mode1, uint64_t a2, uint64_t mode2) +static uint32_t mvc_asc(CPUS390XState *env, uint64_t l, uint64_t a1, + int idx1, uint64_t a2, int idx2, uintptr_t retaddr) { - CPUState *cs = CPU(s390_env_get_cpu(env)); - target_ulong src, dest; - int flags, cc = 0, i; + int cc = 0; - if (!l) { - return 0; - } else if (l > 256) { + if (l > 256) { /* max 256 */ l = 256; cc = 3; } - if (mmu_translate(env, a1, 1, mode1, &dest, &flags, true)) { - cpu_loop_exit(CPU(s390_env_get_cpu(env))); - } - dest |= a1 & ~TARGET_PAGE_MASK; - - if (mmu_translate(env, a2, 0, mode2, &src, &flags, true)) { - cpu_loop_exit(CPU(s390_env_get_cpu(env))); - } - src |= a2 & ~TARGET_PAGE_MASK; - - /* XXX replace w/ memcpy */ - for (i = 0; i < l; i++) { - /* XXX be more clever */ - if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) || - (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) { - mvc_asc(env, l - i, a1 + i, mode1, a2 + i, mode2); - break; - } - stb_phys(cs->as, dest + i, ldub_phys(cs->as, src + i)); + while (l > 0) { + void *src = tlb_vaddr_to_host_fill(env, a2, MMU_DATA_LOAD, idx2, retaddr); + void *dest = tlb_vaddr_to_host_fill(env, a1, MMU_DATA_STORE, idx1, retaddr); + int len = adj_len_to_page(l, a1); + len = adj_len_to_page(len, a2); + memcpy(dest, src, len); + l -= len; + a1 += len; + a2 += len; } return cc; @@ -1070,7 +1056,7 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n", __func__, l, a1, a2); - return mvc_asc(env, l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY); + return mvc_asc(env, l, a1, MMU_SECONDARY_IDX, a2, MMU_PRIMARY_IDX, GETPC()); } uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) @@ -1078,7 +1064,7 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2) HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n", __func__, l, a1, a2); - return mvc_asc(env, l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY); + return mvc_asc(env, l, a1, MMU_PRIMARY_IDX, a2, MMU_SECONDARY_IDX, GETPC()); } /* invalidate pte */ diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 2cfffc4..ac92b47 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -2793,7 +2793,6 @@ static ExitStatus op_mvcp(DisasContext *s, DisasOps *o) { int r1 = get_field(s->fields, l1); check_privileged(s); - potential_page_fault(s); gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2); set_cc_static(s); return NO_EXIT; @@ -2803,7 +2802,6 @@ static ExitStatus op_mvcs(DisasContext *s, DisasOps *o) { int r1 = get_field(s->fields, l1); check_privileged(s); - potential_page_fault(s); gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2); set_cc_static(s); return NO_EXIT; -- 2.1.4