Commit 44977a8f authored by Richard Henderson's avatar Richard Henderson
Browse files

target/s390x: Diagnose specification exception for atomics



All of the interlocked access facility instructions raise a
specification exception for unaligned accesses.  Do this by
using the (previously unused) unaligned_access hook.

Reviewed-by: default avatarAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent 190b2422
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -430,6 +430,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
    cc->write_elf64_note = s390_cpu_write_elf64_note;
    cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
    cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
    cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
#endif
    cc->disas_set_info = s390_cpu_disas_set_info;

+3 −0
Original line number Diff line number Diff line
@@ -480,6 +480,9 @@ int s390_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,

#ifndef CONFIG_USER_ONLY
void do_restart_interrupt(CPUS390XState *env);
void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                                   MMUAccessType access_type,
                                   int mmu_idx, uintptr_t retaddr);

static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb,
                                       uint8_t *ar)
+16 −0
Original line number Diff line number Diff line
@@ -718,4 +718,20 @@ void s390x_cpu_debug_excp_handler(CPUState *cs)
        cpu_loop_exit_noexc(cs);
    }
}

/* Unaligned accesses are only diagnosed with MO_ALIGN.  At the moment,
   this is only for the atomic operations, for which we want to raise a
   specification exception.  */
void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                                   MMUAccessType access_type,
                                   int mmu_idx, uintptr_t retaddr)
{
    S390CPU *cpu = S390_CPU(cs);
    CPUS390XState *env = &cpu->env;

    if (retaddr) {
        cpu_restore_state(cs, retaddr);
    }
    program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER);
}
#endif /* CONFIG_USER_ONLY */