Re: [RFCv2 16/37] KVM: s390: protvirt: Add SCLP interrupt handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon,  3 Feb 2020 08:19:36 -0500
Christian Borntraeger <borntraeger@xxxxxxxxxx> wrote:

> The sclp interrupt is kind of special. The ultravisor polices that we
> do not inject and sclp interrupt with payload if no sccb is outstanding.
> On the other hand we have "asynchronous" event interrupts, e.g. for
> console input.
> We separate both variants into sclp interrupt and sclp event interrupt.
> The sclp interrupt is masked until a previous servc instruction has
> finished (sie exit 108).
> 
> Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx>
> ---
>  arch/s390/include/asm/kvm_host.h |  6 ++-
>  arch/s390/kvm/intercept.c        | 25 +++++++++
>  arch/s390/kvm/interrupt.c        | 92 ++++++++++++++++++++++++++------
>  arch/s390/kvm/kvm-s390.c         |  2 +
>  4 files changed, 108 insertions(+), 17 deletions(-)
> 

> diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
> index 4b3fbbde1674..c22214967214 100644
> --- a/arch/s390/kvm/intercept.c
> +++ b/arch/s390/kvm/intercept.c
> @@ -444,8 +444,33 @@ static int handle_operexc(struct kvm_vcpu *vcpu)
>  	return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
>  }
>  
> +static int handle_pv_sclp(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
> +
> +	spin_lock(&fi->lock);
> +	/*
> +	 * 2 cases:
> +	 * a: an sccb answering interrupt was already pending or in flight.
> +	 *    As the sccb value is not used we can simply set some more bits
> +	 *    and make sure that we deliver something

The sccb value is not used because the firmware handles this?

> +	 * b: an error sccb interrupt needs to be injected so we also inject
> +	 *    something and let firmware do the right thing.
> +	 * This makes sure, that both errors and real sccb returns will only
> +	 * be delivered when we are unmasked.

What makes this sure? That we only unmask here?

> +	 */
> +	fi->srv_signal.ext_params |= 0x43000;
> +	set_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs);
> +	clear_bit(IRQ_PEND_EXT_SERVICE, &fi->masked_irqs);
> +	spin_unlock(&fi->lock);
> +	return 0;
> +}
> +
>  static int handle_pv_not(struct kvm_vcpu *vcpu)
>  {
> +	if (vcpu->arch.sie_block->ipa == 0xb220)
> +		return handle_pv_sclp(vcpu);
> +
>  	return handle_instruction(vcpu);
>  }
>  




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux