Message ID | 20200214222658.12946-29-borntraeger@de.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: s390: Add support for protected VMs | expand |
On 14.02.20 23:26, Christian Borntraeger wrote: > From: Janosch Frank <frankja@linux.ibm.com> > > 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> > [borntraeger@de.ibm.com: patch merging, splitting, fixing] > Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> > --- > arch/s390/kvm/interrupt.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c > index 3e160d9a214f..7a10096fa204 100644 > --- a/arch/s390/kvm/interrupt.c > +++ b/arch/s390/kvm/interrupt.c > @@ -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,9 @@ 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); > > + if (kvm_s390_pv_is_protected(vcpu->kvm)) Can we actually ever have PER set, and what would happen if so? Shouldn't we also return -EINVAL? > + return __deliver_prog_pv(vcpu, pgm_info.code & ~PGM_PER); > + > switch (pgm_info.code & ~PGM_PER) { > case PGM_AFX_TRANSLATION: > case PGM_ASX_TRANSLATION: >
On 18.02.20 10:33, David Hildenbrand wrote: eliver_prog(struct kvm_vcpu *vcpu) >> { >> struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; >> @@ -856,6 +871,9 @@ 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); >> >> + if (kvm_s390_pv_is_protected(vcpu->kvm)) > > Can we actually ever have PER set, and what would happen if so? > Shouldn't we also return -EINVAL? The ultravisor would add a concurrent PER event if appropriate.
On 18.02.20 10:37, Christian Borntraeger wrote: > > > On 18.02.20 10:33, David Hildenbrand wrote: > eliver_prog(struct kvm_vcpu *vcpu) >>> { >>> struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; >>> @@ -856,6 +871,9 @@ 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); >>> >>> + if (kvm_s390_pv_is_protected(vcpu->kvm)) >> >> Can we actually ever have PER set, and what would happen if so? >> Shouldn't we also return -EINVAL? > > The ultravisor would add a concurrent PER event if appropriate. > Please add that to the patch description. Reviewed-by: David Hildenbrand <david@redhat.com>
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 3e160d9a214f..7a10096fa204 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -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,9 @@ 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); + if (kvm_s390_pv_is_protected(vcpu->kvm)) + return __deliver_prog_pv(vcpu, pgm_info.code & ~PGM_PER); + switch (pgm_info.code & ~PGM_PER) { case PGM_AFX_TRANSLATION: case PGM_ASX_TRANSLATION: