Commit 174dd4f8 authored by Michael Mueller's avatar Michael Mueller Committed by Christian Borntraeger

KVM: s390: kvm_s390_gisa_clear() now clears the IPM only

Function kvm_s390_gisa_clear() now clears the Interruption
Pending Mask of the GISA asap. If the GISA is in the alert
list at this time it stays in the list but is removed by
process_gib_alert_list().
Signed-off-by: default avatarMichael Mueller <mimu@linux.ibm.com>
Acked-by: default avatarHalil Pasic <pasic@linux.ibm.com>
Reviewed-by: default avatarPierre Morel <pmorel@linux.ibm.com>
Message-Id: <20190131085247.13826-13-mimu@linux.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 6cff2e10
...@@ -249,6 +249,25 @@ static inline int gisa_set_iam(struct kvm_s390_gisa *gisa, u8 iam) ...@@ -249,6 +249,25 @@ static inline int gisa_set_iam(struct kvm_s390_gisa *gisa, u8 iam)
return 0; return 0;
} }
/**
* gisa_clear_ipm - clear the GISA interruption pending mask
*
* @gisa: gisa to operate on
*
* Clear the IPM atomically with the next alert address and the IAM
* of the GISA unconditionally. All three fields are located in the
* first long word of the GISA.
*/
static inline void gisa_clear_ipm(struct kvm_s390_gisa *gisa)
{
u64 word, _word;
do {
word = READ_ONCE(gisa->u64.word[0]);
_word = word & ~(0xffUL << 24);
} while (cmpxchg(&gisa->u64.word[0], word, _word) != word);
}
static inline void gisa_set_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gisc) static inline void gisa_set_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gisc)
{ {
set_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa); set_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
...@@ -2926,8 +2945,7 @@ void kvm_s390_gisa_clear(struct kvm *kvm) ...@@ -2926,8 +2945,7 @@ void kvm_s390_gisa_clear(struct kvm *kvm)
if (!gi->origin) if (!gi->origin)
return; return;
memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); gisa_clear_ipm(gi->origin);
gi->origin->next_alert = (u32)(u64)gi->origin;
VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin); VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin);
} }
...@@ -2940,7 +2958,8 @@ void kvm_s390_gisa_init(struct kvm *kvm) ...@@ -2940,7 +2958,8 @@ void kvm_s390_gisa_init(struct kvm *kvm)
gi->origin = &kvm->arch.sie_page2->gisa; gi->origin = &kvm->arch.sie_page2->gisa;
gi->alert.mask = 0; gi->alert.mask = 0;
spin_lock_init(&gi->alert.ref_lock); spin_lock_init(&gi->alert.ref_lock);
kvm_s390_gisa_clear(kvm); memset(gi->origin, 0, sizeof(struct kvm_s390_gisa));
gi->origin->next_alert = (u32)(u64)gi->origin;
VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin); VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment