target/s390x: The MVCP and MVCS instructions are not privileged
The "MOVE TO PRIMARY/SECONDARY" instructions can also be called from problem state. We just should properly check whether the secondary-space access key is valid here, too, and inject a privileged program exception if it is invalid. Message-Id: <20221205125852.81848-1-thuth@redhat.com> Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
5e275ca6fb
commit
3ef473e52e
|
@ -353,8 +353,8 @@ DEF_HELPER_FLAGS_3(tprot, TCG_CALL_NO_WG, i32, env, i64, i64)
|
||||||
DEF_HELPER_2(iske, i64, env, i64)
|
DEF_HELPER_2(iske, i64, env, i64)
|
||||||
DEF_HELPER_3(sske, void, env, i64, i64)
|
DEF_HELPER_3(sske, void, env, i64, i64)
|
||||||
DEF_HELPER_2(rrbe, i32, env, i64)
|
DEF_HELPER_2(rrbe, i32, env, i64)
|
||||||
DEF_HELPER_4(mvcs, i32, env, i64, i64, i64)
|
DEF_HELPER_5(mvcs, i32, env, i64, i64, i64, i64)
|
||||||
DEF_HELPER_4(mvcp, i32, env, i64, i64, i64)
|
DEF_HELPER_5(mvcp, i32, env, i64, i64, i64, i64)
|
||||||
DEF_HELPER_4(sigp, i32, env, i64, i32, i32)
|
DEF_HELPER_4(sigp, i32, env, i64, i32, i32)
|
||||||
DEF_HELPER_FLAGS_2(sacf, TCG_CALL_NO_WG, void, env, i64)
|
DEF_HELPER_FLAGS_2(sacf, TCG_CALL_NO_WG, void, env, i64)
|
||||||
DEF_HELPER_FLAGS_4(idte, TCG_CALL_NO_RWG, void, env, i64, i64, i32)
|
DEF_HELPER_FLAGS_4(idte, TCG_CALL_NO_RWG, void, env, i64, i64, i32)
|
||||||
|
|
|
@ -1355,9 +1355,9 @@
|
||||||
E(0xb24b, LURA, RRE, Z, 0, ra2, new, r1_32, lura, 0, MO_TEUL, IF_PRIV)
|
E(0xb24b, LURA, RRE, Z, 0, ra2, new, r1_32, lura, 0, MO_TEUL, IF_PRIV)
|
||||||
E(0xb905, LURAG, RRE, Z, 0, ra2, r1, 0, lura, 0, MO_TEUQ, IF_PRIV)
|
E(0xb905, LURAG, RRE, Z, 0, ra2, r1, 0, lura, 0, MO_TEUQ, IF_PRIV)
|
||||||
/* MOVE TO PRIMARY */
|
/* MOVE TO PRIMARY */
|
||||||
F(0xda00, MVCP, SS_d, Z, la1, a2, 0, 0, mvcp, 0, IF_PRIV)
|
C(0xda00, MVCP, SS_d, Z, la1, a2, 0, 0, mvcp, 0)
|
||||||
/* MOVE TO SECONDARY */
|
/* MOVE TO SECONDARY */
|
||||||
F(0xdb00, MVCS, SS_d, Z, la1, a2, 0, 0, mvcs, 0, IF_PRIV)
|
C(0xdb00, MVCS, SS_d, Z, la1, a2, 0, 0, mvcs, 0)
|
||||||
/* PURGE TLB */
|
/* PURGE TLB */
|
||||||
F(0xb20d, PTLB, S, Z, 0, 0, 0, 0, ptlb, 0, IF_PRIV)
|
F(0xb20d, PTLB, S, Z, 0, 0, 0, 0, ptlb, 0, IF_PRIV)
|
||||||
/* RESET REFERENCE BIT EXTENDED */
|
/* RESET REFERENCE BIT EXTENDED */
|
||||||
|
|
|
@ -2295,7 +2295,8 @@ uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2)
|
||||||
return re >> 1;
|
return re >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
|
uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2,
|
||||||
|
uint64_t key)
|
||||||
{
|
{
|
||||||
const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
|
const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
|
||||||
S390Access srca, desta;
|
S390Access srca, desta;
|
||||||
|
@ -2310,6 +2311,10 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
|
||||||
s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
|
s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!psw_key_valid(env, (key >> 4) & 0xf)) {
|
||||||
|
s390_program_interrupt(env, PGM_PRIVILEGED, ra);
|
||||||
|
}
|
||||||
|
|
||||||
l = wrap_length32(env, l);
|
l = wrap_length32(env, l);
|
||||||
if (l > 256) {
|
if (l > 256) {
|
||||||
/* max 256 */
|
/* max 256 */
|
||||||
|
@ -2319,14 +2324,14 @@ uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Access key handling */
|
|
||||||
srca = access_prepare(env, a2, l, MMU_DATA_LOAD, MMU_PRIMARY_IDX, ra);
|
srca = access_prepare(env, a2, l, MMU_DATA_LOAD, MMU_PRIMARY_IDX, ra);
|
||||||
desta = access_prepare(env, a1, l, MMU_DATA_STORE, MMU_SECONDARY_IDX, ra);
|
desta = access_prepare(env, a1, l, MMU_DATA_STORE, MMU_SECONDARY_IDX, ra);
|
||||||
access_memmove(env, &desta, &srca, ra);
|
access_memmove(env, &desta, &srca, ra);
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
|
uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2,
|
||||||
|
uint64_t key)
|
||||||
{
|
{
|
||||||
const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
|
const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;
|
||||||
S390Access srca, desta;
|
S390Access srca, desta;
|
||||||
|
@ -2341,6 +2346,10 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
|
||||||
s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
|
s390_program_interrupt(env, PGM_SPECIAL_OP, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!psw_key_valid(env, (key >> 4) & 0xf)) {
|
||||||
|
s390_program_interrupt(env, PGM_PRIVILEGED, ra);
|
||||||
|
}
|
||||||
|
|
||||||
l = wrap_length32(env, l);
|
l = wrap_length32(env, l);
|
||||||
if (l > 256) {
|
if (l > 256) {
|
||||||
/* max 256 */
|
/* max 256 */
|
||||||
|
@ -2350,7 +2359,6 @@ uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Access key handling */
|
|
||||||
srca = access_prepare(env, a2, l, MMU_DATA_LOAD, MMU_SECONDARY_IDX, ra);
|
srca = access_prepare(env, a2, l, MMU_DATA_LOAD, MMU_SECONDARY_IDX, ra);
|
||||||
desta = access_prepare(env, a1, l, MMU_DATA_STORE, MMU_PRIMARY_IDX, ra);
|
desta = access_prepare(env, a1, l, MMU_DATA_STORE, MMU_PRIMARY_IDX, ra);
|
||||||
access_memmove(env, &desta, &srca, ra);
|
access_memmove(env, &desta, &srca, ra);
|
||||||
|
|
|
@ -3476,7 +3476,8 @@ static DisasJumpType op_mvcos(DisasContext *s, DisasOps *o)
|
||||||
static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
int r1 = get_field(s, l1);
|
int r1 = get_field(s, l1);
|
||||||
gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
|
int r3 = get_field(s, r3);
|
||||||
|
gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2, regs[r3]);
|
||||||
set_cc_static(s);
|
set_cc_static(s);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
@ -3484,7 +3485,8 @@ static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
|
||||||
static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o)
|
static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o)
|
||||||
{
|
{
|
||||||
int r1 = get_field(s, l1);
|
int r1 = get_field(s, l1);
|
||||||
gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
|
int r3 = get_field(s, r3);
|
||||||
|
gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2, regs[r3]);
|
||||||
set_cc_static(s);
|
set_cc_static(s);
|
||||||
return DISAS_NEXT;
|
return DISAS_NEXT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue