diff options
Diffstat (limited to 'arch/s390/kvm/kvm-s390.c')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 35 |
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 | ||
1728 | static 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 | |||
1729 | static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) | 1753 | static 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 | ||