target/s390x: implement local-TLB-clearing in IPTE

And at the same time make IPTE SMP aware.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Message-Id: <20170531220129.27724-4-aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Aurelien Jarno 2017-06-01 00:01:02 +02:00 committed by Richard Henderson
parent 8a4719f527
commit 1f58720c5f
3 changed files with 19 additions and 10 deletions

View File

@ -111,7 +111,7 @@ DEF_HELPER_4(mvcs, i32, env, i64, i64, i64)
DEF_HELPER_4(mvcp, i32, env, i64, i64, i64)
DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
DEF_HELPER_FLAGS_2(sacf, TCG_CALL_NO_WG, void, env, i64)
DEF_HELPER_FLAGS_3(ipte, TCG_CALL_NO_RWG, void, env, i64, i64)
DEF_HELPER_FLAGS_4(ipte, TCG_CALL_NO_RWG, void, env, i64, i64, i32)
DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_1(purge, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_2(lra, i64, env, i64)

View File

@ -1073,17 +1073,16 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
}
/* invalidate pte */
void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr)
void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr,
uint32_t m4)
{
CPUState *cs = CPU(s390_env_get_cpu(env));
uint64_t page = vaddr & TARGET_PAGE_MASK;
uint64_t pte_addr, pte;
/* XXX broadcast to other CPUs */
/* Compute the page table entry address */
pte_addr = (pto & _SEGMENT_ENTRY_ORIGIN);
pte_addr += (vaddr & _VADDR_PX) >> 9;
pte_addr += (vaddr & VADDR_PX) >> 9;
/* Mark the page table entry as invalid */
pte = ldq_phys(cs->as, pte_addr);
@ -1092,13 +1091,19 @@ void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr)
/* XXX we exploit the fact that Linux passes the exact virtual
address here - it's not obliged to! */
tlb_flush_page(cs, page);
/* XXX: the LC bit should be considered as 0 if the local-TLB-clearing
facility is not installed. */
if (m4 & 1) {
tlb_flush_page(cs, page);
} else {
tlb_flush_page_all_cpus_synced(cs, page);
}
/* XXX 31-bit hack */
if (page & 0x80000000) {
tlb_flush_page(cs, page & ~0x80000000);
if (m4 & 1) {
tlb_flush_page(cs, page ^ 0x80000000);
} else {
tlb_flush_page(cs, page | 0x80000000);
tlb_flush_page_all_cpus_synced(cs, page ^ 0x80000000);
}
}

View File

@ -2357,8 +2357,12 @@ static ExitStatus op_ipm(DisasContext *s, DisasOps *o)
#ifndef CONFIG_USER_ONLY
static ExitStatus op_ipte(DisasContext *s, DisasOps *o)
{
TCGv_i32 m4;
check_privileged(s);
gen_helper_ipte(cpu_env, o->in1, o->in2);
m4 = tcg_const_i32(get_field(s->fields, m4));
gen_helper_ipte(cpu_env, o->in1, o->in2, m4);
tcg_temp_free_i32(m4);
return NO_EXIT;
}