aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm.h5
-rw-r--r--arch/x86/kvm/i8254.c4
-rw-r--r--arch/x86/kvm/i8254.h1
-rw-r--r--arch/x86/kvm/x86.c21
4 files changed, 31 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 32eb96c7ca27..54bcf2281526 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -233,4 +233,9 @@ struct kvm_guest_debug_arch {
233struct kvm_pit_state { 233struct kvm_pit_state {
234 struct kvm_pit_channel_state channels[3]; 234 struct kvm_pit_channel_state channels[3];
235}; 235};
236
237struct kvm_reinject_control {
238 __u8 pit_reinject;
239 __u8 reserved[31];
240};
236#endif /* _ASM_X86_KVM_H */ 241#endif /* _ASM_X86_KVM_H */
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 72bd275a9b5c..528daadeba49 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -201,6 +201,9 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
201 if (!atomic_inc_and_test(&pt->pending)) 201 if (!atomic_inc_and_test(&pt->pending))
202 set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests); 202 set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
203 203
204 if (!pt->reinject)
205 atomic_set(&pt->pending, 1);
206
204 if (vcpu0 && waitqueue_active(&vcpu0->wq)) 207 if (vcpu0 && waitqueue_active(&vcpu0->wq))
205 wake_up_interruptible(&vcpu0->wq); 208 wake_up_interruptible(&vcpu0->wq);
206 209
@@ -580,6 +583,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
580 pit_state->irq_ack_notifier.gsi = 0; 583 pit_state->irq_ack_notifier.gsi = 0;
581 pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq; 584 pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
582 kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier); 585 kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
586 pit_state->pit_timer.reinject = true;
583 mutex_unlock(&pit->pit_state.lock); 587 mutex_unlock(&pit->pit_state.lock);
584 588
585 kvm_pit_reset(pit); 589 kvm_pit_reset(pit);
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index 4178022b97aa..76959c4b500e 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -9,6 +9,7 @@ struct kvm_kpit_timer {
9 s64 period; /* unit: ns */ 9 s64 period; /* unit: ns */
10 s64 scheduled; 10 s64 scheduled;
11 atomic_t pending; 11 atomic_t pending;
12 bool reinject;
12}; 13};
13 14
14struct kvm_kpit_channel_state { 15struct kvm_kpit_channel_state {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c3fbe8c55c13..a1f14611f4b9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -993,6 +993,7 @@ int kvm_dev_ioctl_check_extension(long ext)
993 case KVM_CAP_NOP_IO_DELAY: 993 case KVM_CAP_NOP_IO_DELAY:
994 case KVM_CAP_MP_STATE: 994 case KVM_CAP_MP_STATE:
995 case KVM_CAP_SYNC_MMU: 995 case KVM_CAP_SYNC_MMU:
996 case KVM_CAP_REINJECT_CONTROL:
996 r = 1; 997 r = 1;
997 break; 998 break;
998 case KVM_CAP_COALESCED_MMIO: 999 case KVM_CAP_COALESCED_MMIO:
@@ -1728,6 +1729,15 @@ static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
1728 return r; 1729 return r;
1729} 1730}
1730 1731
1732static int kvm_vm_ioctl_reinject(struct kvm *kvm,
1733 struct kvm_reinject_control *control)
1734{
1735 if (!kvm->arch.vpit)
1736 return -ENXIO;
1737 kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject;
1738 return 0;
1739}
1740
1731/* 1741/*
1732 * Get (and clear) the dirty memory log for a memory slot. 1742 * Get (and clear) the dirty memory log for a memory slot.
1733 */ 1743 */
@@ -1925,6 +1935,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
1925 r = 0; 1935 r = 0;
1926 break; 1936 break;
1927 } 1937 }
1938 case KVM_REINJECT_CONTROL: {
1939 struct kvm_reinject_control control;
1940 r = -EFAULT;
1941 if (copy_from_user(&control, argp, sizeof(control)))
1942 goto out;
1943 r = kvm_vm_ioctl_reinject(kvm, &control);
1944 if (r)
1945 goto out;
1946 r = 0;
1947 break;
1948 }
1928 default: 1949 default:
1929 ; 1950 ;
1930 } 1951 }