]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: s390: protvirt: Add program exception injection
authorJanosch Frank <frankja@linux.ibm.com>
Mon, 27 May 2019 07:32:51 +0000 (09:32 +0200)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 27 Feb 2020 18:47:12 +0000 (19:47 +0100)
Only two program exceptions can be injected for a protected guest:
specification and operand.

For both, a code needs to be specified in the interrupt injection
control of the state description, as the guest prefix page is not
accessible to KVM for such guests.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
[borntraeger@de.ibm.com: patch merging, splitting, fixing]
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/kvm/interrupt.c

index 145cccd498d79734a01ef9ece93dcd16b741d4e0..028167d6eacdd53fddfc7ada3952a90f3884deed 100644 (file)
@@ -836,6 +836,21 @@ static int __must_check __deliver_external_call(struct kvm_vcpu *vcpu)
        return rc ? -EFAULT : 0;
 }
 
+static int __deliver_prog_pv(struct kvm_vcpu *vcpu, u16 code)
+{
+       switch (code) {
+       case PGM_SPECIFICATION:
+               vcpu->arch.sie_block->iictl = IICTL_CODE_SPECIFICATION;
+               break;
+       case PGM_OPERAND:
+               vcpu->arch.sie_block->iictl = IICTL_CODE_OPERAND;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
 {
        struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
@@ -856,6 +871,10 @@ static int __must_check __deliver_prog(struct kvm_vcpu *vcpu)
        trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
                                         pgm_info.code, 0);
 
+       /* PER is handled by the ultravisor */
+       if (kvm_s390_pv_cpu_is_protected(vcpu))
+               return __deliver_prog_pv(vcpu, pgm_info.code & ~PGM_PER);
+
        switch (pgm_info.code & ~PGM_PER) {
        case PGM_AFX_TRANSLATION:
        case PGM_ASX_TRANSLATION: