Skip to contentSkip to conversation

Patch "KVM: s390: fix handling of write errors in the tpi handler" has been added to the 4.0-stable tree

PATCH [email protected] 1 participant 1 message May 2, 2015

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

KVM: s390: fix handling of write errors in the tpi handler

to the 4.0-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
kvm-s390-fix-handling-of-write-errors-in-the-tpi-handler.patch
and it can be found in the queue-4.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 261520dcfcba93ca5dfe671b88ffab038cd940c8 Mon Sep 17 00:00:00 2001

From: David Hildenbrand <[email protected]>
Date: Wed, 4 Feb 2015 15:53:42 +0100
Subject: KVM: s390: fix handling of write errors in the tpi handler

From: David Hildenbrand <[email protected]>

commit 261520dcfcba93ca5dfe671b88ffab038cd940c8 upstream.

If the I/O interrupt could not be written to the guest provided area (e.g. access exception), a program exception was injected into the guest but "inti" wasn't freed, therefore resulting in a memory leak.

In addition, the I/O interrupt wasn't reinjected. Therefore the dequeued interrupt is lost.

This patch fixes the problem while cleaning up the function and making the cc and rc logic easier to handle.

---
 arch/s390/kvm/priv.c |   40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)
arch/s390/kvm/priv.c +23 -17
@@ -229,18 +229,19 @@ static int handle_tpi(struct kvm_vcpu *v
 	struct kvm_s390_interrupt_info *inti;
 	unsigned long len;
 	u32 tpi_data[3];
-	int cc, rc;
+	int rc;
 	u64 addr;
 
-	rc = 0;
 	addr = kvm_s390_get_base_disp_s(vcpu);
 	if (addr & 3)
 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
-	cc = 0;
+
 	inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->arch.sie_block->gcr[6], 0);
-	if (!inti)
-		goto no_interrupt;
-	cc = 1;
+	if (!inti) {
+		kvm_s390_set_psw_cc(vcpu, 0);
+		return 0;
+	}
+
 	tpi_data[0] = inti->io.subchannel_id << 16 | inti->io.subchannel_nr;
 	tpi_data[1] = inti->io.io_int_parm;
 	tpi_data[2] = inti->io.io_int_word;
@@ -251,30 +252,35 @@ static int handle_tpi(struct kvm_vcpu *v
 		 */
 		len = sizeof(tpi_data) - 4;
 		rc = write_guest(vcpu, addr, &tpi_data, len);
-		if (rc)
-			return kvm_s390_inject_prog_cond(vcpu, rc);
+		if (rc) {
+			rc = kvm_s390_inject_prog_cond(vcpu, rc);
+			goto reinject_interrupt;
+		}
 	} else {
 		/*
 		 * Store the three-word I/O interruption code into
 		 * the appropriate lowcore area.
 		 */
 		len = sizeof(tpi_data);
-		if (write_guest_lc(vcpu, __LC_SUBCHANNEL_ID, &tpi_data, len))
+		if (write_guest_lc(vcpu, __LC_SUBCHANNEL_ID, &tpi_data, len)) {
+			/* failed writes to the low core are not recoverable */
 			rc = -EFAULT;
+			goto reinject_interrupt;
+		}
 	}
+
+	/* irq was successfully handed to the guest */
+	kfree(inti);
+	kvm_s390_set_psw_cc(vcpu, 1);
+	return 0;
+reinject_interrupt:
 	/*
 	 * If we encounter a problem storing the interruption code, the
 	 * instruction is suppressed from the guest's view: reinject the
 	 * interrupt.
 	 */
-	if (!rc)
-		kfree(inti);
-	else
-		kvm_s390_reinject_io_int(vcpu->kvm, inti);
-no_interrupt:
-	/* Set condition code and we're done. */
-	if (!rc)
-		kvm_s390_set_psw_cc(vcpu, cc);
+	kvm_s390_reinject_io_int(vcpu->kvm, inti);
+	/* don't set the cc, a pgm irq was injected or we drop to user space */
 	return rc ? -EFAULT : 0;
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.0/kvm-s390-zero-out-current-vmdb-of-stsi-before-including-level3-data.patch queue-4.0/kvm-s390-reinjection-of-irqs-can-fail-in-the-tpi-handler.patch queue-4.0/kvm-s390-fix-get_all_floating_irqs.patch queue-4.0/kvm-s390-fix-handling-of-write-errors-in-the-tpi-handler.patch