[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC 5/5] target-s390x: use softmmu host addr functio
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH RFC 5/5] target-s390x: use softmmu host addr function for mvcp/mvcs |
Date: |
Tue, 2 Jun 2015 13:26:51 +0200 |
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 <address@hidden>
Cc: Richard Henderson <address@hidden>
Signed-off-by: Aurelien Jarno <address@hidden>
---
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
- [Qemu-devel] [PATCH RFC 0/5] softmmu and s390x memory helper improvements, Aurelien Jarno, 2015/06/02
- [Qemu-devel] [PATCH RFC 4/5] target-s390x: function to adjust the length wrt page boundary, Aurelien Jarno, 2015/06/02
- [Qemu-devel] [PATCH RFC 1/5] target-s390x: add a cpu_mmu_idx_to_asc function., Aurelien Jarno, 2015/06/02
- [Qemu-devel] [PATCH RFC 2/5] target-390x: support non current ASC in s390_cpu_handle_mmu_fault, Aurelien Jarno, 2015/06/02
- [Qemu-devel] [PATCH RFC 5/5] target-s390x: use softmmu host addr function for mvcp/mvcs,
Aurelien Jarno <=
- [Qemu-devel] [PATCH RFC 3/5] softmmu: add a tlb_vaddr_to_host_fill function, Aurelien Jarno, 2015/06/02
- Re: [Qemu-devel] [PATCH RFC 3/5] softmmu: add a tlb_vaddr_to_host_fill function, Richard Henderson, 2015/06/02