aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/book3s.c16
-rw-r--r--arch/powerpc/kvm/booke.c5
-rw-r--r--arch/powerpc/kvm/emulate.c3
3 files changed, 23 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 241795bdf34c..fd3ad6c7f355 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -151,6 +151,13 @@ static int kvmppc_book3s_vec2irqprio(unsigned int vec)
151 return prio; 151 return prio;
152} 152}
153 153
154static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
155 unsigned int vec)
156{
157 clear_bit(kvmppc_book3s_vec2irqprio(vec),
158 &vcpu->arch.pending_exceptions);
159}
160
154void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec) 161void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
155{ 162{
156 vcpu->stat.queue_intr++; 163 vcpu->stat.queue_intr++;
@@ -178,6 +185,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
178 return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions); 185 return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
179} 186}
180 187
188void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
189{
190 kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
191}
192
181void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 193void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
182 struct kvm_interrupt *irq) 194 struct kvm_interrupt *irq)
183{ 195{
@@ -275,7 +287,9 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
275#endif 287#endif
276 priority = __ffs(*pending); 288 priority = __ffs(*pending);
277 while (priority <= (sizeof(unsigned int) * 8)) { 289 while (priority <= (sizeof(unsigned int) * 8)) {
278 if (kvmppc_book3s_irqprio_deliver(vcpu, priority)) { 290 if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
291 (priority != BOOK3S_IRQPRIO_DECREMENTER)) {
292 /* DEC interrupts get cleared by mtdec */
279 clear_bit(priority, &vcpu->arch.pending_exceptions); 293 clear_bit(priority, &vcpu->arch.pending_exceptions);
280 break; 294 break;
281 } 295 }
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 06f5a9ecc42c..d8b63420acf8 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -97,6 +97,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
97 return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions); 97 return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
98} 98}
99 99
100void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
101{
102 clear_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
103}
104
100void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 105void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
101 struct kvm_interrupt *irq) 106 struct kvm_interrupt *irq)
102{ 107{
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 4a9ac6640fad..303457b2f52a 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -83,6 +83,9 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
83 83
84 pr_debug("mtDEC: %x\n", vcpu->arch.dec); 84 pr_debug("mtDEC: %x\n", vcpu->arch.dec);
85#ifdef CONFIG_PPC64 85#ifdef CONFIG_PPC64
86 /* mtdec lowers the interrupt line when positive. */
87 kvmppc_core_dequeue_dec(vcpu);
88
86 /* POWER4+ triggers a dec interrupt if the value is < 0 */ 89 /* POWER4+ triggers a dec interrupt if the value is < 0 */
87 if (vcpu->arch.dec & 0x80000000) { 90 if (vcpu->arch.dec & 0x80000000) {
88 hrtimer_try_to_cancel(&vcpu->arch.dec_timer); 91 hrtimer_try_to_cancel(&vcpu->arch.dec_timer);