mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
target/s390x/tcg: Fix and improve the SACF instruction
The SET ADDRESS SPACE CONTROL FAST instruction is not privileged, it can be used from problem space, too. Just the switching to the home address space is privileged and should still generate a privilege exception. This bug is e.g. causing programs like Java that use the "getcpu" vdso kernel function to crash (see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=990417#26 ). While we're at it, also check if DAT is not enabled. In that case the instruction is supposed to generate a special operation exception. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/655 Message-Id: <20221201184443.136355-1-thuth@redhat.com> Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
0f0a9e4e5c
commit
21be74a9a5
|
@ -487,6 +487,10 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
|
|||
{
|
||||
HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
|
||||
|
||||
if (!(env->psw.mask & PSW_MASK_DAT)) {
|
||||
tcg_s390_program_interrupt(env, PGM_SPECIAL_OP, GETPC());
|
||||
}
|
||||
|
||||
switch (a1 & 0xf00) {
|
||||
case 0x000:
|
||||
env->psw.mask &= ~PSW_MASK_ASC;
|
||||
|
@ -497,6 +501,9 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
|
|||
env->psw.mask |= PSW_ASC_SECONDARY;
|
||||
break;
|
||||
case 0x300:
|
||||
if ((env->psw.mask & PSW_MASK_PSTATE) != 0) {
|
||||
tcg_s390_program_interrupt(env, PGM_PRIVILEGED, GETPC());
|
||||
}
|
||||
env->psw.mask &= ~PSW_MASK_ASC;
|
||||
env->psw.mask |= PSW_ASC_HOME;
|
||||
break;
|
||||
|
|
|
@ -1365,7 +1365,7 @@
|
|||
/* SERVICE CALL LOGICAL PROCESSOR (PV hypercall) */
|
||||
F(0xb220, SERVC, RRE, Z, r1_o, r2_o, 0, 0, servc, 0, IF_PRIV | IF_IO)
|
||||
/* SET ADDRESS SPACE CONTROL FAST */
|
||||
F(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0, IF_PRIV)
|
||||
C(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0)
|
||||
/* SET CLOCK */
|
||||
F(0xb204, SCK, S, Z, 0, m2_64a, 0, 0, sck, 0, IF_PRIV | IF_IO)
|
||||
/* SET CLOCK COMPARATOR */
|
||||
|
|
Loading…
Reference in a new issue