mirror of
https://github.com/qemu/qemu.git
synced 2024-11-26 21:33:40 +08:00
s390x/sclp: Add missing checks to SCLP handler
If the 51 most significant bits of the SCCB address are zero or equal to the prefix, we should throw an specification exception, too. Also moved the check for privileged mode to sclp_service_call() to have all program checks in one place now. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
a0fa2cb8cc
commit
6e25280216
@ -107,7 +107,7 @@ static void sclp_execute(SCCB *sccb, uint32_t code)
|
||||
}
|
||||
}
|
||||
|
||||
int sclp_service_call(uint64_t sccb, uint32_t code)
|
||||
int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
|
||||
{
|
||||
int r = 0;
|
||||
SCCB work_sccb;
|
||||
@ -115,11 +115,16 @@ int sclp_service_call(uint64_t sccb, uint32_t code)
|
||||
hwaddr sccb_len = sizeof(SCCB);
|
||||
|
||||
/* first some basic checks on program checks */
|
||||
if (env->psw.mask & PSW_MASK_PSTATE) {
|
||||
r = -PGM_PRIVILEGED;
|
||||
goto out;
|
||||
}
|
||||
if (cpu_physical_memory_is_io(sccb)) {
|
||||
r = -PGM_ADDRESSING;
|
||||
goto out;
|
||||
}
|
||||
if (sccb & ~0x7ffffff8ul) {
|
||||
if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
|
||||
|| (sccb & ~0x7ffffff8UL) != 0) {
|
||||
r = -PGM_SPECIFICATION;
|
||||
goto out;
|
||||
}
|
||||
|
@ -963,7 +963,7 @@ struct sysib_322 {
|
||||
void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr);
|
||||
int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
|
||||
target_ulong *raddr, int *flags);
|
||||
int sclp_service_call(uint64_t sccb, uint32_t code);
|
||||
int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
|
||||
uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
|
||||
uint64_t vr);
|
||||
|
||||
|
@ -445,14 +445,10 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
|
||||
int r = 0;
|
||||
|
||||
cpu_synchronize_state(CPU(cpu));
|
||||
if (env->psw.mask & PSW_MASK_PSTATE) {
|
||||
enter_pgmcheck(cpu, PGM_PRIVILEGED);
|
||||
return 0;
|
||||
}
|
||||
sccb = env->regs[ipbh0 & 0xf];
|
||||
code = env->regs[(ipbh0 & 0xf0) >> 4];
|
||||
|
||||
r = sclp_service_call(sccb, code);
|
||||
r = sclp_service_call(env, sccb, code);
|
||||
if (r < 0) {
|
||||
enter_pgmcheck(cpu, -r);
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
|
||||
/* SCLP service call */
|
||||
uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
|
||||
{
|
||||
int r = sclp_service_call(r1, r2);
|
||||
int r = sclp_service_call(env, r1, r2);
|
||||
if (r < 0) {
|
||||
program_interrupt(env, -r, 4);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user