s390x: protvirt: Move IO control structures over SIDA
For protected guests, we need to put the IO emulation results into the SIDA, so SIE will write them into the guest at the next entry. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Message-Id: <20200319131921.2367-14-frankja@linux.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
c10b708752
commit
fcc10c1470
@ -138,7 +138,9 @@ void ioinst_handle_msch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
return;
|
||||
}
|
||||
if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_read(cpu, addr, &schib, sizeof(schib));
|
||||
} else if (s390_cpu_virt_mem_read(cpu, addr, ar, &schib, sizeof(schib))) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return;
|
||||
}
|
||||
@ -195,7 +197,9 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, ra);
|
||||
return;
|
||||
}
|
||||
if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_read(cpu, addr, &orig_orb, sizeof(orb));
|
||||
} else if (s390_cpu_virt_mem_read(cpu, addr, ar, &orig_orb, sizeof(orb))) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return;
|
||||
}
|
||||
@ -231,14 +235,19 @@ void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
|
||||
cc = css_do_stcrw(&crw);
|
||||
/* 0 - crw stored, 1 - zeroes stored */
|
||||
|
||||
if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_write(cpu, addr, &crw, sizeof(crw));
|
||||
setcc(cpu, cc);
|
||||
} else {
|
||||
if (cc == 0) {
|
||||
/* Write failed: requeue CRW since STCRW is suppressing */
|
||||
css_undo_stcrw(&crw);
|
||||
if (s390_cpu_virt_mem_write(cpu, addr, ar, &crw, sizeof(crw)) == 0) {
|
||||
setcc(cpu, cc);
|
||||
} else {
|
||||
if (cc == 0) {
|
||||
/* Write failed: requeue CRW since STCRW is suppressing */
|
||||
css_undo_stcrw(&crw);
|
||||
}
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
}
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,6 +269,13 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
|
||||
}
|
||||
|
||||
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
|
||||
/*
|
||||
* The Ultravisor checks schid bit 16 to be one and bits 0-12
|
||||
* to be 0 and injects a operand exception itself.
|
||||
*
|
||||
* Hence we should never end up here.
|
||||
*/
|
||||
g_assert(!s390_is_pv());
|
||||
/*
|
||||
* As operand exceptions have a lower priority than access exceptions,
|
||||
* we check whether the memory area is writeable (injecting the
|
||||
@ -292,14 +308,17 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb,
|
||||
}
|
||||
}
|
||||
if (cc != 3) {
|
||||
if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
|
||||
sizeof(schib)) != 0) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_write(cpu, addr, &schib, sizeof(schib));
|
||||
} else if (s390_cpu_virt_mem_write(cpu, addr, ar, &schib,
|
||||
sizeof(schib)) != 0) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Access exceptions have a higher priority than cc3 */
|
||||
if (s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
|
||||
if (!s390_is_pv() &&
|
||||
s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib)) != 0) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return;
|
||||
}
|
||||
@ -336,7 +355,9 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
||||
}
|
||||
/* 0 - status pending, 1 - not status pending, 3 - not operational */
|
||||
if (cc != 3) {
|
||||
if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_write(cpu, addr, &irb, irb_len);
|
||||
} else if (s390_cpu_virt_mem_write(cpu, addr, ar, &irb, irb_len) != 0) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return -EFAULT;
|
||||
}
|
||||
@ -344,7 +365,8 @@ int ioinst_handle_tsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, uintptr_t ra)
|
||||
} else {
|
||||
irb_len = sizeof(irb) - sizeof(irb.emw);
|
||||
/* Access exceptions have a higher priority than cc3 */
|
||||
if (s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
|
||||
if (!s390_is_pv() &&
|
||||
s390_cpu_virt_mem_check_write(cpu, addr, ar, irb_len) != 0) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return -EFAULT;
|
||||
}
|
||||
@ -642,7 +664,9 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
|
||||
* present CHSC sub-handlers ... if we ever need more, we should take
|
||||
* care of req->len here first.
|
||||
*/
|
||||
if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_read(cpu, addr, buf, sizeof(ChscReq));
|
||||
} else if (s390_cpu_virt_mem_read(cpu, addr, reg, buf, sizeof(ChscReq))) {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
return;
|
||||
}
|
||||
@ -675,11 +699,16 @@ void ioinst_handle_chsc(S390CPU *cpu, uint32_t ipb, uintptr_t ra)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
|
||||
be16_to_cpu(res->len))) {
|
||||
if (s390_is_pv()) {
|
||||
s390_cpu_pv_mem_write(cpu, addr + len, res, be16_to_cpu(res->len));
|
||||
setcc(cpu, 0); /* Command execution complete */
|
||||
} else {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
if (!s390_cpu_virt_mem_write(cpu, addr + len, reg, res,
|
||||
be16_to_cpu(res->len))) {
|
||||
setcc(cpu, 0); /* Command execution complete */
|
||||
} else {
|
||||
s390_cpu_virt_mem_handle_exc(cpu, ra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user