aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mueller <mimu@linux.ibm.com>2019-01-31 03:52:43 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2019-02-05 08:29:23 -0500
commit174dd4f88875f6ebad7ad1dff3c3e9530a1e3506 (patch)
tree902380fb92bb86a8c76b36f1d2da3ae855106f91
parent6cff2e1046015f2729f6cb68be1c999c4a9b259f (diff)
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: Michael Mueller <mimu@linux.ibm.com> Acked-by: Halil Pasic <pasic@linux.ibm.com> Reviewed-by: Pierre Morel <pmorel@linux.ibm.com> Message-Id: <20190131085247.13826-13-mimu@linux.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--arch/s390/kvm/interrupt.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 040745b23224..9faaa8f96fc3 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -249,6 +249,25 @@ static inline int gisa_set_iam(struct kvm_s390_gisa *gisa, u8 iam)
249 return 0; 249 return 0;
250} 250}
251 251
252/**
253 * gisa_clear_ipm - clear the GISA interruption pending mask
254 *
255 * @gisa: gisa to operate on
256 *
257 * Clear the IPM atomically with the next alert address and the IAM
258 * of the GISA unconditionally. All three fields are located in the
259 * first long word of the GISA.
260 */
261static inline void gisa_clear_ipm(struct kvm_s390_gisa *gisa)
262{
263 u64 word, _word;
264
265 do {
266 word = READ_ONCE(gisa->u64.word[0]);
267 _word = word & ~(0xffUL << 24);
268 } while (cmpxchg(&gisa->u64.word[0], word, _word) != word);
269}
270
252static inline void gisa_set_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gisc) 271static inline void gisa_set_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gisc)
253{ 272{
254 set_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa); 273 set_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
@@ -2926,8 +2945,7 @@ void kvm_s390_gisa_clear(struct kvm *kvm)
2926 2945
2927 if (!gi->origin) 2946 if (!gi->origin)
2928 return; 2947 return;
2929 memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); 2948 gisa_clear_ipm(gi->origin);
2930 gi->origin->next_alert = (u32)(u64)gi->origin;
2931 VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin); 2949 VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin);
2932} 2950}
2933 2951
@@ -2940,7 +2958,8 @@ void kvm_s390_gisa_init(struct kvm *kvm)
2940 gi->origin = &kvm->arch.sie_page2->gisa; 2958 gi->origin = &kvm->arch.sie_page2->gisa;
2941 gi->alert.mask = 0; 2959 gi->alert.mask = 0;
2942 spin_lock_init(&gi->alert.ref_lock); 2960 spin_lock_init(&gi->alert.ref_lock);
2943 kvm_s390_gisa_clear(kvm); 2961 memset(gi->origin, 0, sizeof(struct kvm_s390_gisa));
2962 gi->origin->next_alert = (u32)(u64)gi->origin;
2944 VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin); 2963 VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin);
2945} 2964}
2946 2965