aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2009-05-14 16:42:53 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:32:41 -0400
commitc5ff41ce66382d657a76bc06ba252d848826950f (patch)
tree4b7bc3674faa6259b1e6b07fc616b17dcf281d98
parent721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3 (diff)
KVM: Allow PIT emulation without speaker port
The in-kernel speaker emulation is only a dummy and also unneeded from the performance point of view. Rather, it takes user space support to generate sound output on the host, e.g. console beeps. To allow this, introduce KVM_CREATE_PIT2 which controls in-kernel speaker port emulation via a flag passed along the new IOCTL. It also leaves room for future extensions of the PIT configuration interface. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/kvm/i8254.c14
-rw-r--r--arch/x86/kvm/i8254.h2
-rw-r--r--arch/x86/kvm/x86.c12
-rw-r--r--include/linux/kvm.h12
4 files changed, 32 insertions, 8 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 21f68e00524f..0990bc9aac1f 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -563,7 +563,7 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
563 } 563 }
564} 564}
565 565
566struct kvm_pit *kvm_create_pit(struct kvm *kvm) 566struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
567{ 567{
568 struct kvm_pit *pit; 568 struct kvm_pit *pit;
569 struct kvm_kpit_state *pit_state; 569 struct kvm_kpit_state *pit_state;
@@ -589,11 +589,13 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
589 pit->dev.private = pit; 589 pit->dev.private = pit;
590 kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev); 590 kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
591 591
592 pit->speaker_dev.read = speaker_ioport_read; 592 if (flags & KVM_PIT_SPEAKER_DUMMY) {
593 pit->speaker_dev.write = speaker_ioport_write; 593 pit->speaker_dev.read = speaker_ioport_read;
594 pit->speaker_dev.in_range = speaker_in_range; 594 pit->speaker_dev.write = speaker_ioport_write;
595 pit->speaker_dev.private = pit; 595 pit->speaker_dev.in_range = speaker_in_range;
596 kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev); 596 pit->speaker_dev.private = pit;
597 kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev);
598 }
597 599
598 kvm->arch.vpit = pit; 600 kvm->arch.vpit = pit;
599 pit->kvm = kvm; 601 pit->kvm = kvm;
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index bbd863ff60b7..b2670180f225 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -50,7 +50,7 @@ struct kvm_pit {
50 50
51void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); 51void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
52void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val); 52void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val);
53struct kvm_pit *kvm_create_pit(struct kvm *kvm); 53struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags);
54void kvm_free_pit(struct kvm *kvm); 54void kvm_free_pit(struct kvm *kvm);
55void kvm_pit_reset(struct kvm_pit *pit); 55void kvm_pit_reset(struct kvm_pit *pit);
56 56
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 15f39fc08ece..5eb3b8dd74b8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1127,6 +1127,7 @@ int kvm_dev_ioctl_check_extension(long ext)
1127 case KVM_CAP_IRQ_INJECT_STATUS: 1127 case KVM_CAP_IRQ_INJECT_STATUS:
1128 case KVM_CAP_ASSIGN_DEV_IRQ: 1128 case KVM_CAP_ASSIGN_DEV_IRQ:
1129 case KVM_CAP_IRQFD: 1129 case KVM_CAP_IRQFD:
1130 case KVM_CAP_PIT2:
1130 r = 1; 1131 r = 1;
1131 break; 1132 break;
1132 case KVM_CAP_COALESCED_MMIO: 1133 case KVM_CAP_COALESCED_MMIO:
@@ -2038,6 +2039,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
2038 union { 2039 union {
2039 struct kvm_pit_state ps; 2040 struct kvm_pit_state ps;
2040 struct kvm_memory_alias alias; 2041 struct kvm_memory_alias alias;
2042 struct kvm_pit_config pit_config;
2041 } u; 2043 } u;
2042 2044
2043 switch (ioctl) { 2045 switch (ioctl) {
@@ -2098,12 +2100,20 @@ long kvm_arch_vm_ioctl(struct file *filp,
2098 } 2100 }
2099 break; 2101 break;
2100 case KVM_CREATE_PIT: 2102 case KVM_CREATE_PIT:
2103 u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
2104 goto create_pit;
2105 case KVM_CREATE_PIT2:
2106 r = -EFAULT;
2107 if (copy_from_user(&u.pit_config, argp,
2108 sizeof(struct kvm_pit_config)))
2109 goto out;
2110 create_pit:
2101 mutex_lock(&kvm->lock); 2111 mutex_lock(&kvm->lock);
2102 r = -EEXIST; 2112 r = -EEXIST;
2103 if (kvm->arch.vpit) 2113 if (kvm->arch.vpit)
2104 goto create_pit_unlock; 2114 goto create_pit_unlock;
2105 r = -ENOMEM; 2115 r = -ENOMEM;
2106 kvm->arch.vpit = kvm_create_pit(kvm); 2116 kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags);
2107 if (kvm->arch.vpit) 2117 if (kvm->arch.vpit)
2108 r = 0; 2118 r = 0;
2109 create_pit_unlock: 2119 create_pit_unlock:
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 8f53f24e5274..65df6f5e2b98 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -70,6 +70,14 @@ struct kvm_irqchip {
70 } chip; 70 } chip;
71}; 71};
72 72
73/* for KVM_CREATE_PIT2 */
74struct kvm_pit_config {
75 __u32 flags;
76 __u32 pad[15];
77};
78
79#define KVM_PIT_SPEAKER_DUMMY 1
80
73#define KVM_EXIT_UNKNOWN 0 81#define KVM_EXIT_UNKNOWN 0
74#define KVM_EXIT_EXCEPTION 1 82#define KVM_EXIT_EXCEPTION 1
75#define KVM_EXIT_IO 2 83#define KVM_EXIT_IO 2
@@ -419,6 +427,9 @@ struct kvm_trace_rec {
419#define KVM_CAP_MCE 31 427#define KVM_CAP_MCE 31
420#endif 428#endif
421#define KVM_CAP_IRQFD 32 429#define KVM_CAP_IRQFD 32
430#ifdef __KVM_HAVE_PIT
431#define KVM_CAP_PIT2 33
432#endif
422 433
423#ifdef KVM_CAP_IRQ_ROUTING 434#ifdef KVM_CAP_IRQ_ROUTING
424 435
@@ -525,6 +536,7 @@ struct kvm_irqfd {
525 _IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry) 536 _IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry)
526#define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq) 537#define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq)
527#define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd) 538#define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd)
539#define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config)
528 540
529/* 541/*
530 * ioctls for vcpu fds 542 * ioctls for vcpu fds