diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/kvm.h | 5 | ||||
-rw-r--r-- | arch/x86/kvm/i8254.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/i8254.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 21 |
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 { | |||
233 | struct kvm_pit_state { | 233 | struct kvm_pit_state { |
234 | struct kvm_pit_channel_state channels[3]; | 234 | struct kvm_pit_channel_state channels[3]; |
235 | }; | 235 | }; |
236 | |||
237 | struct 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 | ||
14 | struct kvm_kpit_channel_state { | 15 | struct 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 | ||
1732 | static 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 | } |