Commit c5a7392c authored by David Hildenbrand's avatar David Hildenbrand Committed by Cornelia Huck
Browse files

s390x/tcg: Provide probe_write_access helper



Instead of checking e.g. the first access on every touched page, we should
check the actual access, otherwise we might get false positives when Low
Address Protection (LAP) is active. As probe_write() can only deal with
accesses to one page, we have to loop.

Use i64 for the length, although not needed - easier to reuse
TCG temps we already have in the translation functions where this will
be used. Also allow it to be used from other helpers.

Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20190307121539.12842-28-david@redhat.com>
[CH: add missing page_check_range()]
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent a2338cfb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ DEF_HELPER_4(cu42, i32, env, i32, i32, i32)
DEF_HELPER_5(msa, i32, env, i32, i32, i32, i32)
DEF_HELPER_FLAGS_1(stpt, TCG_CALL_NO_RWG, i64, env)
DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env)
DEF_HELPER_FLAGS_3(probe_write_access, TCG_CALL_NO_WG, void, env, i64, i64)

/* === Vector Support Instructions === */
DEF_HELPER_FLAGS_4(vll, TCG_CALL_NO_WG, void, env, ptr, i64, i64)
+2 −0
Original line number Diff line number Diff line
@@ -349,6 +349,8 @@ void ioinst_handle_sal(S390CPU *cpu, uint64_t reg1, uintptr_t ra);

/* mem_helper.c */
target_ulong mmu_real2abs(CPUS390XState *env, target_ulong raddr);
void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
                        uintptr_t ra);


/* mmu_helper.c */
+26 −0
Original line number Diff line number Diff line
@@ -2623,3 +2623,29 @@ uint32_t HELPER(cu42)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t m3)
    return convert_unicode(env, r1, r2, m3, GETPC(),
                           decode_utf32, encode_utf16);
}

void probe_write_access(CPUS390XState *env, uint64_t addr, uint64_t len,
                        uintptr_t ra)
{
#ifdef CONFIG_USER_ONLY
    if (!h2g_valid(addr) || !h2g_valid(addr + len - 1) ||
        page_check_range(addr, len, PAGE_WRITE) < 0) {
        s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
    }
#else
    /* test the actual access, not just any access to the page due to LAP */
    while (len) {
        const uint64_t pagelen = -(addr | -TARGET_PAGE_MASK);
        const uint64_t curlen = MIN(pagelen, len);

        probe_write(env, addr, curlen, cpu_mmu_index(env, false), ra);
        addr = wrap_address(env, addr + curlen);
        len -= curlen;
    }
#endif
}

void HELPER(probe_write_access)(CPUS390XState *env, uint64_t addr, uint64_t len)
{
    probe_write_access(env, addr, len, GETPC());
}