diff mbox

kvm: x86: Allow PIT emulation without speaker port

Message ID 49F0CE5A.8040405@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka April 23, 2009, 8:23 p.m. UTC
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_PIT_NOSPKR which is simply
KVM_CREATE_PIT without registration of the speaker_dev.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

 arch/x86/kvm/i8254.c |   14 ++++++++------
 arch/x86/kvm/i8254.h |    2 +-
 arch/x86/kvm/x86.c   |    9 ++++++++-
 include/linux/kvm.h  |    2 ++
 4 files changed, 19 insertions(+), 8 deletions(-)

Comments

Avi Kivity May 4, 2009, 9:32 a.m. UTC | #1
Jan Kiszka wrote:
> 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_PIT_NOSPKR which is simply
> KVM_CREATE_PIT without registration of the speaker_dev.
>
>   

Nothing wrong with the patch, but let's make it a little more forward 
looking.  Have a CREATE_PIT2 (or something) which accepts a structure 
with a flags field and some padding.  Define the first flag as speaker 
in kernel vs speaker in userspace.

This would allow us to hack the PIT some more in the future if we find 
we need too.
diff mbox

Patch

diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 4d6f0d2..683d2ef 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -560,7 +560,7 @@  static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
 	}
 }
 
-struct kvm_pit *kvm_create_pit(struct kvm *kvm)
+struct kvm_pit *kvm_create_pit(struct kvm *kvm, int speaker_support)
 {
 	struct kvm_pit *pit;
 	struct kvm_kpit_state *pit_state;
@@ -586,11 +586,13 @@  struct kvm_pit *kvm_create_pit(struct kvm *kvm)
 	pit->dev.private = pit;
 	kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
 
-	pit->speaker_dev.read = speaker_ioport_read;
-	pit->speaker_dev.write = speaker_ioport_write;
-	pit->speaker_dev.in_range = speaker_in_range;
-	pit->speaker_dev.private = pit;
-	kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev);
+	if (speaker_support) {
+		pit->speaker_dev.read = speaker_ioport_read;
+		pit->speaker_dev.write = speaker_ioport_write;
+		pit->speaker_dev.in_range = speaker_in_range;
+		pit->speaker_dev.private = pit;
+		kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev);
+	}
 
 	kvm->arch.vpit = pit;
 	pit->kvm = kvm;
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index bbd863f..20589b3 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -50,7 +50,7 @@  struct kvm_pit {
 
 void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
 void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val);
-struct kvm_pit *kvm_create_pit(struct kvm *kvm);
+struct kvm_pit *kvm_create_pit(struct kvm *kvm, int speaker_support);
 void kvm_free_pit(struct kvm *kvm);
 void kvm_pit_reset(struct kvm_pit *pit);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c033f63..e0919bf 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1026,6 +1026,7 @@  int kvm_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_REINJECT_CONTROL:
 	case KVM_CAP_IRQ_INJECT_STATUS:
 	case KVM_CAP_ASSIGN_DEV_IRQ:
+	case KVM_CAP_PIT_NOSPKR:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -1803,6 +1804,7 @@  long kvm_arch_vm_ioctl(struct file *filp,
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
+	int speaker;
 	int r = -EINVAL;
 	/*
 	 * This union makes it completely explicit to gcc-3.x
@@ -1872,12 +1874,17 @@  long kvm_arch_vm_ioctl(struct file *filp,
 		}
 		break;
 	case KVM_CREATE_PIT:
+		speaker = 1;
+		goto create_pit;
+	case KVM_CREATE_PIT_NOSPKR:
+		speaker = 0;
+	create_pit:
 		mutex_lock(&kvm->lock);
 		r = -EEXIST;
 		if (kvm->arch.vpit)
 			goto create_pit_unlock;
 		r = -ENOMEM;
-		kvm->arch.vpit = kvm_create_pit(kvm);
+		kvm->arch.vpit = kvm_create_pit(kvm, speaker);
 		if (kvm->arch.vpit)
 			r = 0;
 	create_pit_unlock:
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 3db5d8d..7a452f4 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -415,6 +415,7 @@  struct kvm_trace_rec {
 #define KVM_CAP_ASSIGN_DEV_IRQ 29
 /* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */
 #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30
+#define KVM_CAP_PIT_NOSPKR 31
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -498,6 +499,7 @@  struct kvm_irq_routing {
 #define KVM_ASSIGN_SET_MSIX_ENTRY \
 			_IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry)
 #define KVM_DEASSIGN_DEV_IRQ       _IOW(KVMIO, 0x75, struct kvm_assigned_irq)
+#define KVM_CREATE_PIT_NOSPKR	  _IO(KVMIO,  0x76)
 
 /*
  * ioctls for vcpu fds