diff mbox series

[v3,03/12] KVM: s390: add the GIB and its related life-cyle functions

Message ID 20181128101943.155542-4-mimu@linux.ibm.com (mailing list archive)
State New, archived
Headers show
Series KVM: s390: make use of the GIB | expand

Commit Message

Michael Mueller Nov. 28, 2018, 10:19 a.m. UTC
The GIB (Guest Information Block) links the GISA of all guests
that have adapter interrupts pending. These interrupts cannot be
delivered because no vcpu of these guests is currently running in
SIE context. Instead, a GIB alert is issued on the host to schedule
these guests to run.

This mechanism allows to process adapter interrupts for currently
not running guests.

The GIB is created during host initialization and associated with
the Adapter Interruption Facility in case an Adapter Interruption
Virtualization Facility is available.

Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/include/asm/kvm_host.h | 10 ++++++++++
 arch/s390/kvm/interrupt.c        | 37 +++++++++++++++++++++++++++++++++++++
 arch/s390/kvm/kvm-s390.c         |  1 +
 arch/s390/kvm/kvm-s390.h         |  2 ++
 4 files changed, 50 insertions(+)

Comments

Cornelia Huck Nov. 28, 2018, 10:44 a.m. UTC | #1
On Wed, 28 Nov 2018 11:19:34 +0100
Michael Mueller <mimu@linux.ibm.com> wrote:

> The GIB (Guest Information Block) links the GISA of all guests
> that have adapter interrupts pending. These interrupts cannot be
> delivered because no vcpu of these guests is currently running in
> SIE context. Instead, a GIB alert is issued on the host to schedule
> these guests to run.
> 
> This mechanism allows to process adapter interrupts for currently
> not running guests.
> 
> The GIB is created during host initialization and associated with
> the Adapter Interruption Facility in case an Adapter Interruption
> Virtualization Facility is available.
> 
> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
> Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
> ---
>  arch/s390/include/asm/kvm_host.h | 10 ++++++++++
>  arch/s390/kvm/interrupt.c        | 37 +++++++++++++++++++++++++++++++++++++
>  arch/s390/kvm/kvm-s390.c         |  1 +
>  arch/s390/kvm/kvm-s390.h         |  2 ++
>  4 files changed, 50 insertions(+)
> 

> +int kvm_s390_gib_init(u8 nisc)
> +{
> +	if (!css_general_characteristics.aiv) {
> +		KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
> +		return 0;
> +	}
> +
> +	gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
> +	if (!gib) {
> +		KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);

Just noticed this... isn't the dbf torn down again if kvm init failed,
rendering this message inaccessible? Do we need different logging for
fatal errors?

(The code is not wrong, but this logging looks a bit useless.)

> +		return -ENOMEM;
> +	}
> +
> +	gib->nisc = nisc;
> +	if (chsc_sgib((u32)(u64)gib)) {
> +		KVM_EVENT(3, "gib 0x%pK AIV association failed", gib);
> +		free_page((unsigned long)gib);
> +		gib = NULL;
> +		return -EIO;
> +	}
> +
> +	KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
> +	return 0;
> +}
Michael Mueller Nov. 28, 2018, 12:27 p.m. UTC | #2
On 28.11.18 11:44, Cornelia Huck wrote:
> On Wed, 28 Nov 2018 11:19:34 +0100
> Michael Mueller <mimu@linux.ibm.com> wrote:
>
>> The GIB (Guest Information Block) links the GISA of all guests
>> that have adapter interrupts pending. These interrupts cannot be
>> delivered because no vcpu of these guests is currently running in
>> SIE context. Instead, a GIB alert is issued on the host to schedule
>> these guests to run.
>>
>> This mechanism allows to process adapter interrupts for currently
>> not running guests.
>>
>> The GIB is created during host initialization and associated with
>> the Adapter Interruption Facility in case an Adapter Interruption
>> Virtualization Facility is available.
>>
>> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
>> Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
>> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> ---
>>   arch/s390/include/asm/kvm_host.h | 10 ++++++++++
>>   arch/s390/kvm/interrupt.c        | 37 +++++++++++++++++++++++++++++++++++++
>>   arch/s390/kvm/kvm-s390.c         |  1 +
>>   arch/s390/kvm/kvm-s390.h         |  2 ++
>>   4 files changed, 50 insertions(+)
>>
>> +int kvm_s390_gib_init(u8 nisc)
>> +{
>> +	if (!css_general_characteristics.aiv) {
>> +		KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
>> +		return 0;
>> +	}
>> +
>> +	gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
>> +	if (!gib) {
>> +		KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);
> Just noticed this... isn't the dbf torn down again if kvm init failed,
> rendering this message inaccessible? Do we need different logging for
> fatal errors?
>
> (The code is not wrong, but this logging looks a bit useless.)

That's why I added the last sentence of the commit message. But it seems
a little more tricky dependent of the module being build into the kernel
or loaded.

When build-in, there is no indication that kvm_init() failed except the 
missing
/dev/kvm device. In the module load case, the s390dbf does not seem to be
able to recycle the /sys/.../kvm-trace/ directory. So the feature shall be
unregistered on kvm_init() failures.

There should be either an additional generic message from kvm_init()
displaying the rc of kvm_arch_init() or kernel messages of the failing
routines in kvm_arch_init().

Any opinions?

>
>> +		return -ENOMEM;
>> +	}
>> +
>> +	gib->nisc = nisc;
>> +	if (chsc_sgib((u32)(u64)gib)) {
>> +		KVM_EVENT(3, "gib 0x%pK AIV association failed", gib);
>> +		free_page((unsigned long)gib);
>> +		gib = NULL;
>> +		return -EIO;
>> +	}
>> +
>> +	KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
>> +	return 0;
>> +}
Pierre Morel Nov. 28, 2018, 12:59 p.m. UTC | #3
On 28/11/2018 13:27, Michael Mueller wrote:
> 
> 
> On 28.11.18 11:44, Cornelia Huck wrote:
>> On Wed, 28 Nov 2018 11:19:34 +0100
>> Michael Mueller <mimu@linux.ibm.com> wrote:
>>
>>> The GIB (Guest Information Block) links the GISA of all guests
>>> that have adapter interrupts pending. These interrupts cannot be
>>> delivered because no vcpu of these guests is currently running in
>>> SIE context. Instead, a GIB alert is issued on the host to schedule
>>> these guests to run.
>>>
>>> This mechanism allows to process adapter interrupts for currently
>>> not running guests.
>>>
>>> The GIB is created during host initialization and associated with
>>> the Adapter Interruption Facility in case an Adapter Interruption
>>> Virtualization Facility is available.
>>>
>>> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
>>> Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
>>> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
>>> ---
>>>   arch/s390/include/asm/kvm_host.h | 10 ++++++++++
>>>   arch/s390/kvm/interrupt.c        | 37 
>>> +++++++++++++++++++++++++++++++++++++
>>>   arch/s390/kvm/kvm-s390.c         |  1 +
>>>   arch/s390/kvm/kvm-s390.h         |  2 ++
>>>   4 files changed, 50 insertions(+)
>>>
>>> +int kvm_s390_gib_init(u8 nisc)
>>> +{
>>> +    if (!css_general_characteristics.aiv) {
>>> +        KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
>>> +        return 0;
>>> +    }
>>> +
>>> +    gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
>>> +    if (!gib) {
>>> +        KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);
>> Just noticed this... isn't the dbf torn down again if kvm init failed,
>> rendering this message inaccessible? Do we need different logging for
>> fatal errors?
>>
>> (The code is not wrong, but this logging looks a bit useless.)
> 
> That's why I added the last sentence of the commit message. But it seems
> a little more tricky dependent of the module being build into the kernel
> or loaded.
> 
> When build-in, there is no indication that kvm_init() failed except the 
> missing
> /dev/kvm device. In the module load case, the s390dbf does not seem to be
> able to recycle the /sys/.../kvm-trace/ directory. So the feature shall be
> unregistered on kvm_init() failures.
> 
> There should be either an additional generic message from kvm_init()
> displaying the rc of kvm_arch_init() or kernel messages of the failing
> routines in kvm_arch_init().
> 
> Any opinions?

Using the debugfs is for my opinion something we do when the subsystem 
is working.
I see no reason to use it to report initialization events.
Especially errors.

Why not use simply pr_xxx() to keep tracks in the syslog until 
initialization is done?

Regards,
Pierre

> 
>>
>>> +        return -ENOMEM;
>>> +    }
>>> +
>>> +    gib->nisc = nisc;
>>> +    if (chsc_sgib((u32)(u64)gib)) {
>>> +        KVM_EVENT(3, "gib 0x%pK AIV association failed", gib);
>>> +        free_page((unsigned long)gib);
>>> +        gib = NULL;
>>> +        return -EIO;
>>> +    }
>>> +
>>> +    KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
>>> +    return 0;
>>> +}
>
Cornelia Huck Nov. 28, 2018, 1:01 p.m. UTC | #4
On Wed, 28 Nov 2018 13:27:51 +0100
Michael Mueller <mimu@linux.ibm.com> wrote:

> On 28.11.18 11:44, Cornelia Huck wrote:
> > On Wed, 28 Nov 2018 11:19:34 +0100
> > Michael Mueller <mimu@linux.ibm.com> wrote:
> >  
> >> The GIB (Guest Information Block) links the GISA of all guests
> >> that have adapter interrupts pending. These interrupts cannot be
> >> delivered because no vcpu of these guests is currently running in
> >> SIE context. Instead, a GIB alert is issued on the host to schedule
> >> these guests to run.
> >>
> >> This mechanism allows to process adapter interrupts for currently
> >> not running guests.
> >>
> >> The GIB is created during host initialization and associated with
> >> the Adapter Interruption Facility in case an Adapter Interruption
> >> Virtualization Facility is available.
> >>
> >> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
> >> Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
> >> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
> >> ---
> >>   arch/s390/include/asm/kvm_host.h | 10 ++++++++++
> >>   arch/s390/kvm/interrupt.c        | 37 +++++++++++++++++++++++++++++++++++++
> >>   arch/s390/kvm/kvm-s390.c         |  1 +
> >>   arch/s390/kvm/kvm-s390.h         |  2 ++
> >>   4 files changed, 50 insertions(+)
> >>
> >> +int kvm_s390_gib_init(u8 nisc)
> >> +{
> >> +	if (!css_general_characteristics.aiv) {
> >> +		KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
> >> +		return 0;
> >> +	}
> >> +
> >> +	gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
> >> +	if (!gib) {
> >> +		KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);  
> > Just noticed this... isn't the dbf torn down again if kvm init failed,
> > rendering this message inaccessible? Do we need different logging for
> > fatal errors?
> >
> > (The code is not wrong, but this logging looks a bit useless.)  
> 
> That's why I added the last sentence of the commit message. But it seems
> a little more tricky dependent of the module being build into the kernel
> or loaded.
> 
> When build-in, there is no indication that kvm_init() failed except the 
> missing
> /dev/kvm device. In the module load case, the s390dbf does not seem to be
> able to recycle the /sys/.../kvm-trace/ directory. So the feature shall be
> unregistered on kvm_init() failures.

Having kvm as a module might actually be the more common case for
people using a distro.

> 
> There should be either an additional generic message from kvm_init()
> displaying the rc of kvm_arch_init() or kernel messages of the failing
> routines in kvm_arch_init().

I think the memory allocation problem is sufficiently reflected by
-ENOMEM (if you can't even get a single page, you're in trouble
anyway); the failed gib association probably should be logged into the
syslog (although it is unclear if the user can do anything about it).
David Hildenbrand Nov. 29, 2018, 1 p.m. UTC | #5
On 28.11.18 11:19, Michael Mueller wrote:
> The GIB (Guest Information Block) links the GISA of all guests
> that have adapter interrupts pending. These interrupts cannot be
> delivered because no vcpu of these guests is currently running in
> SIE context. Instead, a GIB alert is issued on the host to schedule
> these guests to run.
> 
> This mechanism allows to process adapter interrupts for currently
> not running guests.
> 
> The GIB is created during host initialization and associated with
> the Adapter Interruption Facility in case an Adapter Interruption
> Virtualization Facility is available.

kvm_s390_gib_init() is not called in this patch (however
kvm_s390_gib_destroy() is).

So either you are missing that in this patch or your patch description
is not completely right.

> 
> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
> Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
> ---
>  arch/s390/include/asm/kvm_host.h | 10 ++++++++++
>  arch/s390/kvm/interrupt.c        | 37 +++++++++++++++++++++++++++++++++++++
>  arch/s390/kvm/kvm-s390.c         |  1 +
>  arch/s390/kvm/kvm-s390.h         |  2 ++
>  4 files changed, 50 insertions(+)
> 
> diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
> index d5d24889c3bc..537e5e59f27e 100644
> --- a/arch/s390/include/asm/kvm_host.h
> +++ b/arch/s390/include/asm/kvm_host.h
> @@ -785,6 +785,15 @@ struct kvm_s390_gisa {
>  	};
>  };
>  
> +struct kvm_s390_gib {
> +	u32 alert_list_origin;
> +	u32 reserved01;
> +	u8:5;
> +	u8  nisc:3;
> +	u8  reserved03[3];
> +	u32 reserved04[5];
> +};
> +
>  /*
>   * sie_page2 has to be allocated as DMA because fac_list, crycb and
>   * gisa need 31bit addresses in the sie control block.
> @@ -838,6 +847,7 @@ struct kvm_arch{
>  	/* subset of available cpu features enabled by user space */
>  	DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS);
>  	struct kvm_s390_gisa *gisa;
> +	int gib_in_use;
>  };
>  
>  #define KVM_HVA_ERR_BAD		(-1UL)
> diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
> index fcb55b02990e..5d20a0ce8a30 100644
> --- a/arch/s390/kvm/interrupt.c
> +++ b/arch/s390/kvm/interrupt.c
> @@ -31,6 +31,8 @@
>  #define PFAULT_DONE 0x0680
>  #define VIRTIO_PARAM 0x0d00
>  
> +static struct kvm_s390_gib *gib;
> +
>  /* handle external calls via sigp interpretation facility */
>  static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id)
>  {
> @@ -2899,6 +2901,7 @@ void kvm_s390_gisa_init(struct kvm *kvm)
>  		kvm->arch.gisa = &kvm->arch.sie_page2->gisa;
>  		VM_EVENT(kvm, 3, "gisa 0x%pK initialized", kvm->arch.gisa);
>  		kvm_s390_gisa_clear(kvm);
> +		kvm->arch.gib_in_use = !!gib;
>  	}
>  }
>  
> @@ -2908,3 +2911,37 @@ void kvm_s390_gisa_destroy(struct kvm *kvm)
>  		return;
>  	kvm->arch.gisa = NULL;
>  }
> +
> +void kvm_s390_gib_destroy(void)
> +{
> +	if (!gib)
> +		return;
> +	chsc_sgib(0);
> +	free_page((unsigned long)gib);
> +	gib = NULL;
> +}
> +
> +int kvm_s390_gib_init(u8 nisc)
> +{
> +	if (!css_general_characteristics.aiv) {
> +		KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
> +		return 0;
> +	}
> +
> +	gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
> +	if (!gib) {
> +		KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);
> +		return -ENOMEM;
> +	}
> +
> +	gib->nisc = nisc;
> +	if (chsc_sgib((u32)(u64)gib)) {
> +		KVM_EVENT(3, "gib 0x%pK AIV association failed", gib);
> +		free_page((unsigned long)gib);
> +		gib = NULL;
> +		return -EIO;
> +	}
> +
> +	KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
> +	return 0;
> +}
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index d9635d21563f..96954871b6a2 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -444,6 +444,7 @@ int kvm_arch_init(void *opaque)
>  
>  void kvm_arch_exit(void)
>  {
> +	kvm_s390_gib_destroy();
>  	debug_unregister(kvm_s390_dbf);
>  }
>  
> diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
> index 1f6e36cdce0d..1a79105b0e9f 100644
> --- a/arch/s390/kvm/kvm-s390.h
> +++ b/arch/s390/kvm/kvm-s390.h
> @@ -381,6 +381,8 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu,
>  void kvm_s390_gisa_init(struct kvm *kvm);
>  void kvm_s390_gisa_clear(struct kvm *kvm);
>  void kvm_s390_gisa_destroy(struct kvm *kvm);
> +int kvm_s390_gib_init(u8 nisc);
> +void kvm_s390_gib_destroy(void);
>  
>  /* implemented in guestdbg.c */
>  void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu);
>
Michael Mueller Nov. 29, 2018, 2:37 p.m. UTC | #6
On 29.11.18 14:00, David Hildenbrand wrote:
> On 28.11.18 11:19, Michael Mueller wrote:
>> The GIB (Guest Information Block) links the GISA of all guests
>> that have adapter interrupts pending. These interrupts cannot be
>> delivered because no vcpu of these guests is currently running in
>> SIE context. Instead, a GIB alert is issued on the host to schedule
>> these guests to run.
>>
>> This mechanism allows to process adapter interrupts for currently
>> not running guests.
>>
>> The GIB is created during host initialization and associated with
>> the Adapter Interruption Facility in case an Adapter Interruption
>> Virtualization Facility is available.
> 
> kvm_s390_gib_init() is not called in this patch (however
> kvm_s390_gib_destroy() is).
> 
> So either you are missing that in this patch or your patch description
> is not completely right.

Hey, that sounds a little like pettifoggery... ;)

I will add a sentence like:

"The GIB initialization and thus the activation of the related code
will be done in an upcoming patch of this series."

Is is that you are asking for?


> 
>>
>> Signed-off-by: Michael Mueller <mimu@linux.ibm.com>
>> Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
>> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> ---
>>   arch/s390/include/asm/kvm_host.h | 10 ++++++++++
>>   arch/s390/kvm/interrupt.c        | 37 +++++++++++++++++++++++++++++++++++++
>>   arch/s390/kvm/kvm-s390.c         |  1 +
>>   arch/s390/kvm/kvm-s390.h         |  2 ++
>>   4 files changed, 50 insertions(+)
>>
>> diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
>> index d5d24889c3bc..537e5e59f27e 100644
>> --- a/arch/s390/include/asm/kvm_host.h
>> +++ b/arch/s390/include/asm/kvm_host.h
>> @@ -785,6 +785,15 @@ struct kvm_s390_gisa {
>>   	};
>>   };
>>   
>> +struct kvm_s390_gib {
>> +	u32 alert_list_origin;
>> +	u32 reserved01;
>> +	u8:5;
>> +	u8  nisc:3;
>> +	u8  reserved03[3];
>> +	u32 reserved04[5];
>> +};
>> +
>>   /*
>>    * sie_page2 has to be allocated as DMA because fac_list, crycb and
>>    * gisa need 31bit addresses in the sie control block.
>> @@ -838,6 +847,7 @@ struct kvm_arch{
>>   	/* subset of available cpu features enabled by user space */
>>   	DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS);
>>   	struct kvm_s390_gisa *gisa;
>> +	int gib_in_use;
>>   };
>>   
>>   #define KVM_HVA_ERR_BAD		(-1UL)
>> diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
>> index fcb55b02990e..5d20a0ce8a30 100644
>> --- a/arch/s390/kvm/interrupt.c
>> +++ b/arch/s390/kvm/interrupt.c
>> @@ -31,6 +31,8 @@
>>   #define PFAULT_DONE 0x0680
>>   #define VIRTIO_PARAM 0x0d00
>>   
>> +static struct kvm_s390_gib *gib;
>> +
>>   /* handle external calls via sigp interpretation facility */
>>   static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id)
>>   {
>> @@ -2899,6 +2901,7 @@ void kvm_s390_gisa_init(struct kvm *kvm)
>>   		kvm->arch.gisa = &kvm->arch.sie_page2->gisa;
>>   		VM_EVENT(kvm, 3, "gisa 0x%pK initialized", kvm->arch.gisa);
>>   		kvm_s390_gisa_clear(kvm);
>> +		kvm->arch.gib_in_use = !!gib;
>>   	}
>>   }
>>   
>> @@ -2908,3 +2911,37 @@ void kvm_s390_gisa_destroy(struct kvm *kvm)
>>   		return;
>>   	kvm->arch.gisa = NULL;
>>   }
>> +
>> +void kvm_s390_gib_destroy(void)
>> +{
>> +	if (!gib)
>> +		return;
>> +	chsc_sgib(0);
>> +	free_page((unsigned long)gib);
>> +	gib = NULL;
>> +}
>> +
>> +int kvm_s390_gib_init(u8 nisc)
>> +{
>> +	if (!css_general_characteristics.aiv) {
>> +		KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
>> +		return 0;
>> +	}
>> +
>> +	gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
>> +	if (!gib) {
>> +		KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	gib->nisc = nisc;
>> +	if (chsc_sgib((u32)(u64)gib)) {
>> +		KVM_EVENT(3, "gib 0x%pK AIV association failed", gib);
>> +		free_page((unsigned long)gib);
>> +		gib = NULL;
>> +		return -EIO;
>> +	}
>> +
>> +	KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
>> +	return 0;
>> +}
>> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
>> index d9635d21563f..96954871b6a2 100644
>> --- a/arch/s390/kvm/kvm-s390.c
>> +++ b/arch/s390/kvm/kvm-s390.c
>> @@ -444,6 +444,7 @@ int kvm_arch_init(void *opaque)
>>   
>>   void kvm_arch_exit(void)
>>   {
>> +	kvm_s390_gib_destroy();
>>   	debug_unregister(kvm_s390_dbf);
>>   }
>>   
>> diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
>> index 1f6e36cdce0d..1a79105b0e9f 100644
>> --- a/arch/s390/kvm/kvm-s390.h
>> +++ b/arch/s390/kvm/kvm-s390.h
>> @@ -381,6 +381,8 @@ int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu,
>>   void kvm_s390_gisa_init(struct kvm *kvm);
>>   void kvm_s390_gisa_clear(struct kvm *kvm);
>>   void kvm_s390_gisa_destroy(struct kvm *kvm);
>> +int kvm_s390_gib_init(u8 nisc);
>> +void kvm_s390_gib_destroy(void);
>>   
>>   /* implemented in guestdbg.c */
>>   void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu);
>>
> 
>
diff mbox series

Patch

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index d5d24889c3bc..537e5e59f27e 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -785,6 +785,15 @@  struct kvm_s390_gisa {
 	};
 };
 
+struct kvm_s390_gib {
+	u32 alert_list_origin;
+	u32 reserved01;
+	u8:5;
+	u8  nisc:3;
+	u8  reserved03[3];
+	u32 reserved04[5];
+};
+
 /*
  * sie_page2 has to be allocated as DMA because fac_list, crycb and
  * gisa need 31bit addresses in the sie control block.
@@ -838,6 +847,7 @@  struct kvm_arch{
 	/* subset of available cpu features enabled by user space */
 	DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS);
 	struct kvm_s390_gisa *gisa;
+	int gib_in_use;
 };
 
 #define KVM_HVA_ERR_BAD		(-1UL)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index fcb55b02990e..5d20a0ce8a30 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -31,6 +31,8 @@ 
 #define PFAULT_DONE 0x0680
 #define VIRTIO_PARAM 0x0d00
 
+static struct kvm_s390_gib *gib;
+
 /* handle external calls via sigp interpretation facility */
 static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id)
 {
@@ -2899,6 +2901,7 @@  void kvm_s390_gisa_init(struct kvm *kvm)
 		kvm->arch.gisa = &kvm->arch.sie_page2->gisa;
 		VM_EVENT(kvm, 3, "gisa 0x%pK initialized", kvm->arch.gisa);
 		kvm_s390_gisa_clear(kvm);
+		kvm->arch.gib_in_use = !!gib;
 	}
 }
 
@@ -2908,3 +2911,37 @@  void kvm_s390_gisa_destroy(struct kvm *kvm)
 		return;
 	kvm->arch.gisa = NULL;
 }
+
+void kvm_s390_gib_destroy(void)
+{
+	if (!gib)
+		return;
+	chsc_sgib(0);
+	free_page((unsigned long)gib);
+	gib = NULL;
+}
+
+int kvm_s390_gib_init(u8 nisc)
+{
+	if (!css_general_characteristics.aiv) {
+		KVM_EVENT(3, "%s", "gib not initialized, no AIV facility");
+		return 0;
+	}
+
+	gib = (struct kvm_s390_gib *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
+	if (!gib) {
+		KVM_EVENT(3, "gib 0x%pK memory allocation failed", gib);
+		return -ENOMEM;
+	}
+
+	gib->nisc = nisc;
+	if (chsc_sgib((u32)(u64)gib)) {
+		KVM_EVENT(3, "gib 0x%pK AIV association failed", gib);
+		free_page((unsigned long)gib);
+		gib = NULL;
+		return -EIO;
+	}
+
+	KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc);
+	return 0;
+}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index d9635d21563f..96954871b6a2 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -444,6 +444,7 @@  int kvm_arch_init(void *opaque)
 
 void kvm_arch_exit(void)
 {
+	kvm_s390_gib_destroy();
 	debug_unregister(kvm_s390_dbf);
 }
 
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 1f6e36cdce0d..1a79105b0e9f 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -381,6 +381,8 @@  int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu,
 void kvm_s390_gisa_init(struct kvm *kvm);
 void kvm_s390_gisa_clear(struct kvm *kvm);
 void kvm_s390_gisa_destroy(struct kvm *kvm);
+int kvm_s390_gib_init(u8 nisc);
+void kvm_s390_gib_destroy(void);
 
 /* implemented in guestdbg.c */
 void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu);