Skip to contentSkip to conversation

Patch "MIPS: KVM: Fix timer IRQ race when writing CP0_Compare" has been added to the 4.5-stable tree

PATCH [email protected] 1 participant 1 message May 30, 2016

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

MIPS: KVM: Fix timer IRQ race when writing CP0_Compare

to the 4.5-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:
mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch
and it can be found in the queue-4.5 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 b45bacd2d048f405c7760e5cc9b60dd67708734f Mon Sep 17 00:00:00 2001

From: James Hogan <[email protected]>
Date: Fri, 22 Apr 2016 10:38:46 +0100
Subject: MIPS: KVM: Fix timer IRQ race when writing CP0_Compare
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

From: James Hogan <[email protected]>

commit b45bacd2d048f405c7760e5cc9b60dd67708734f upstream.

Writing CP0_Compare clears the timer interrupt pending bit (CP0_Cause.TI), but this wasn't being done atomically. If a timer interrupt raced with the write of the guest CP0_Compare, the timer interrupt could end up being pending even though the new CP0_Compare is nowhere near CP0_Count.

We were already updating the hrtimer expiry with kvm_mips_update_hrtimer(), which used both kvm_mips_freeze_hrtimer() and kvm_mips_resume_hrtimer(). Close the race window by expanding out kvm_mips_update_hrtimer(), and clearing CP0_Cause.TI and setting CP0_Compare between the freeze and resume. Since the pending timer interrupt should not be cleared when CP0_Compare is written via the KVM user API, an ack argument is added to distinguish the source of the write.

Fixes e30492bbe95a ("MIPS: KVM: Rewrite count/compare timer emulation")
Cc Paolo Bonzini <[email protected]>
Cc "Radim Krčmář" <[email protected]>
Cc Ralf Baechle <[email protected]>
---
 arch/mips/include/asm/kvm_host.h |    2 -
 arch/mips/kvm/emulate.c          |   61 +++++++++++++++++----------------------
 arch/mips/kvm/trap_emul.c        |    2 -
 3 files changed, 29 insertions(+), 36 deletions(-)
arch/mips/include/asm/kvm_host.h +1 -1
@@ -747,7 +747,7 @@ extern enum emulation_result kvm_mips_co
 
 uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu);
 void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count);
-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare);
+void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack);
 void kvm_mips_init_count(struct kvm_vcpu *vcpu);
 int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl);
 int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume);
arch/mips/kvm/emulate.c +27 -34

91 lines not on this page · raw message

arch/mips/kvm/trap_emul.c +1 -1
@@ -546,7 +546,7 @@ static int kvm_trap_emul_set_one_reg(str
 		kvm_mips_write_count(vcpu, v);
 		break;
 	case KVM_REG_MIPS_CP0_COMPARE:
-		kvm_mips_write_compare(vcpu, v);
+		kvm_mips_write_compare(vcpu, v, false);
 		break;
 	case KVM_REG_MIPS_CP0_CAUSE:
 		/*

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

queue-4.5/signal-move-generic-copy_siginfo-to-signal.h.patch queue-4.5/mips-kvm-fix-timer-irq-race-when-writing-cp0_compare.patch queue-4.5/mips-kvm-fix-timer-irq-race-when-freezing-timer.patch