aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2015-02-10 10:11:01 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-03-06 07:40:45 -0500
commit492d8642eaefbd47f6fb0e8265f058c02720e5c8 (patch)
tree7666f73258ebfb11cdab1050f5a82cd47d0f4593 /arch/s390/kvm
parenta9a846fd5c1723820c97cef56989ea14eea4b30e (diff)
KVM: s390: Forward PSW to next instruction for addressing exceptions
When the SIE exited by a DAT access exceptions which we can not resolve, the guest tried to access a page which is out of bounds and can not be paged-in. In this case we have to signal the bad access by injecting an address exception. However, address exceptions are either suppressing or terminating, i.e. the PSW has to point to the next instruction when the exception is delivered. Since the originating DAT access exception is nullifying, the PSW still points to the offending instruction instead, so we've got to forward the PSW to the next instruction. Having fixed this issue, we can now also enable the TPROT interpretation facility again which had been disabled because of this problem. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index f6579cfde2df..7ac40aa70cf8 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1148,8 +1148,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
1148 vcpu->arch.sie_block->eca |= 1; 1148 vcpu->arch.sie_block->eca |= 1;
1149 if (sclp_has_sigpif()) 1149 if (sclp_has_sigpif())
1150 vcpu->arch.sie_block->eca |= 0x10000000U; 1150 vcpu->arch.sie_block->eca |= 0x10000000U;
1151 vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE | 1151 vcpu->arch.sie_block->ictl |= ICTL_ISKE | ICTL_SSKE | ICTL_RRBE;
1152 ICTL_TPROT;
1153 1152
1154 if (kvm_s390_cmma_enabled(vcpu->kvm)) { 1153 if (kvm_s390_cmma_enabled(vcpu->kvm)) {
1155 rc = kvm_s390_vcpu_setup_cmma(vcpu); 1154 rc = kvm_s390_vcpu_setup_cmma(vcpu);
@@ -1726,6 +1725,31 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu)
1726 return 0; 1725 return 0;
1727} 1726}
1728 1727
1728static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu)
1729{
1730 psw_t *psw = &vcpu->arch.sie_block->gpsw;
1731 u8 opcode;
1732 int rc;
1733
1734 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
1735 trace_kvm_s390_sie_fault(vcpu);
1736
1737 /*
1738 * We want to inject an addressing exception, which is defined as a
1739 * suppressing or terminating exception. However, since we came here
1740 * by a DAT access exception, the PSW still points to the faulting
1741 * instruction since DAT exceptions are nullifying. So we've got
1742 * to look up the current opcode to get the length of the instruction
1743 * to be able to forward the PSW.
1744 */
1745 rc = read_guest(vcpu, psw->addr, &opcode, 1);
1746 if (rc)
1747 return kvm_s390_inject_prog_cond(vcpu, rc);
1748 psw->addr = __rewind_psw(*psw, -insn_length(opcode));
1749
1750 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
1751}
1752
1729static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) 1753static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
1730{ 1754{
1731 int rc = -1; 1755 int rc = -1;
@@ -1757,11 +1781,8 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
1757 } 1781 }
1758 } 1782 }
1759 1783
1760 if (rc == -1) { 1784 if (rc == -1)
1761 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); 1785 rc = vcpu_post_run_fault_in_sie(vcpu);
1762 trace_kvm_s390_sie_fault(vcpu);
1763 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
1764 }
1765 1786
1766 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); 1787 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
1767 1788