From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: [PATCH v3] kvm: x86: Allow PIT emulation without speaker port Date: Thu, 14 May 2009 22:42:53 +0200 Message-ID: <4A0C824D.7000502@web.de> References: <4A0924FF.7030008@web.de> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig8806941ACB90CDD8A1CA70D6" Cc: kvm-devel To: Avi Kivity Return-path: Received: from fmmailgate03.web.de ([217.72.192.234]:58059 "EHLO fmmailgate03.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754689AbZENUoD (ORCPT ); Thu, 14 May 2009 16:44:03 -0400 In-Reply-To: <4A0924FF.7030008@web.de> Sender: kvm-owner@vger.kernel.org List-ID: This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig8806941ACB90CDD8A1CA70D6 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable 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. Changes in v3: - increase padding in kvm_pit_config to 64 bytes (as requested by Avi) Changes in v2: - Use extensible KVM_CREATE_PIT2 Signed-off-by: Jan Kiszka --- arch/x86/kvm/i8254.c | 14 ++++++++------ arch/x86/kvm/i8254.h | 2 +- arch/x86/kvm/x86.c | 12 +++++++++++- include/linux/kvm.h | 10 ++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 4d6f0d2..584e3d3 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_noti= fier *kimn, bool mask) } } =20 -struct kvm_pit *kvm_create_pit(struct kvm *kvm) +struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags) { 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 =3D pit; kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev); =20 - pit->speaker_dev.read =3D speaker_ioport_read; - pit->speaker_dev.write =3D speaker_ioport_write; - pit->speaker_dev.in_range =3D speaker_in_range; - pit->speaker_dev.private =3D pit; - kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev); + if (flags & KVM_PIT_SPEAKER_DUMMY) { + pit->speaker_dev.read =3D speaker_ioport_read; + pit->speaker_dev.write =3D speaker_ioport_write; + pit->speaker_dev.in_range =3D speaker_in_range; + pit->speaker_dev.private =3D pit; + kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev); + } =20 kvm->arch.vpit =3D pit; pit->kvm =3D kvm; diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index bbd863f..b267018 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h @@ -50,7 +50,7 @@ struct kvm_pit { =20 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, u32 flags); void kvm_free_pit(struct kvm *kvm); void kvm_pit_reset(struct kvm_pit *pit); =20 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 44e87a5..c6e7896 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_PIT2: r =3D 1; break; case KVM_CAP_COALESCED_MMIO: @@ -1829,6 +1830,7 @@ long kvm_arch_vm_ioctl(struct file *filp, union { struct kvm_pit_state ps; struct kvm_memory_alias alias; + struct kvm_pit_config pit_config; } u; =20 switch (ioctl) { @@ -1889,12 +1891,20 @@ long kvm_arch_vm_ioctl(struct file *filp, } break; case KVM_CREATE_PIT: + u.pit_config.flags =3D KVM_PIT_SPEAKER_DUMMY; + goto create_pit; + case KVM_CREATE_PIT2: + r =3D -EFAULT; + if (copy_from_user(&u.pit_config, argp, + sizeof(struct kvm_pit_config))) + goto out; + create_pit: mutex_lock(&kvm->lock); r =3D -EEXIST; if (kvm->arch.vpit) goto create_pit_unlock; r =3D -ENOMEM; - kvm->arch.vpit =3D kvm_create_pit(kvm); + kvm->arch.vpit =3D kvm_create_pit(kvm, u.pit_config.flags); if (kvm->arch.vpit) r =3D 0; create_pit_unlock: diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 3db5d8d..5575409 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -70,6 +70,14 @@ struct kvm_irqchip { } chip; }; =20 +/* for KVM_CREATE_PIT2 */ +struct kvm_pit_config { + __u32 flags; + __u32 pad[15]; +}; + +#define KVM_PIT_SPEAKER_DUMMY 1 + #define KVM_EXIT_UNKNOWN 0 #define KVM_EXIT_EXCEPTION 1 #define KVM_EXIT_IO 2 @@ -415,6 +423,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_PIT2 31 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 @@ -498,6 +507,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_PIT2 _IOW(KVMIO, 0x76, struct kvm_pit_config) =20 /* * ioctls for vcpu fds --------------enig8806941ACB90CDD8A1CA70D6 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iEYEARECAAYFAkoMgk0ACgkQniDOoMHTA+m5XQCffx9ZCL9/wCxzLc4VnmjlAWav UAEAn1expeZUEGmfUscdX9J4pbx/LhCq =Z+Y1 -----END PGP SIGNATURE----- --------------enig8806941ACB90CDD8A1CA70D6--