From patchwork Thu Apr 23 20:24:05 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 19687 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n3NKOCq5012919 for ; Thu, 23 Apr 2009 20:24:12 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752957AbZDWUYL (ORCPT ); Thu, 23 Apr 2009 16:24:11 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752839AbZDWUYK (ORCPT ); Thu, 23 Apr 2009 16:24:10 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]:51254 "EHLO fmmailgate01.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752645AbZDWUYI (ORCPT ); Thu, 23 Apr 2009 16:24:08 -0400 Received: from smtp07.web.de (fmsmtp07.dlan.cinetic.de [172.20.5.215]) by fmmailgate01.web.de (Postfix) with ESMTP id 5000A100854EC; Thu, 23 Apr 2009 22:24:06 +0200 (CEST) Received: from [88.65.38.201] (helo=[192.168.1.123]) by smtp07.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #277) id 1Lx5So-0002iU-00; Thu, 23 Apr 2009 22:24:06 +0200 Message-ID: <49F0CE65.4050005@web.de> Date: Thu, 23 Apr 2009 22:24:05 +0200 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Avi Kivity CC: kvm-devel Subject: [PATCH] kvm-userspace: Make PC speaker emulation aware of in-kernel PIT X-Enigmail-Version: 0.95.7 X-Sender: jan.kiszka@web.de X-Provags-ID: V01U2FsdGVkX1+MRUYDiGo81vlfyZX96elhT2PDer5T+OLf6t8p F8d2C8uboggPyDKGXD+QI1k76VUgpJ6MK6S5NXIKYUhKK1fTE5 885euACvE= Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When using the in-kernel PIT the speaker emulation has to synchronize the PIT state with KVM. Enhance the existing speaker sound device and allow it to take over port 0x61 by using KVM_CREATE_PIT_NOSPKR when available. This unbreaks -soundhw pcspk in KVM mode. Signed-off-by: Jan Kiszka --- libkvm/libkvm-x86.c | 13 +++++++++++++ qemu/hw/pcspk.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c index 2fc4fce..03b1939 100644 --- a/libkvm/libkvm-x86.c +++ b/libkvm/libkvm-x86.c @@ -59,6 +59,19 @@ int kvm_create_pit(kvm_context_t kvm) kvm->pit_in_kernel = 0; if (!kvm->no_pit_creation) { +#ifdef KVM_CAP_PIT_NOSPKR + r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_PIT_NOSPKR); + if (r > 0) { + r = ioctl(kvm->vm_fd, KVM_CREATE_PIT_NOSPKR); + if (r >= 0) { + kvm->pit_in_kernel = 1; + return 0; + } else { + fprintf(stderr, "Create kernel PIC irqchip failed\n"); + return r; + } + } +#endif r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_PIT); if (r > 0) { r = ioctl(kvm->vm_fd, KVM_CREATE_PIT); diff --git a/qemu/hw/pcspk.c b/qemu/hw/pcspk.c index ec1d0c6..4752518 100644 --- a/qemu/hw/pcspk.c +++ b/qemu/hw/pcspk.c @@ -27,6 +27,8 @@ #include "isa.h" #include "audio/audio.h" #include "qemu-timer.h" +#include "i8254.h" +#include "qemu-kvm.h" #define PCSPK_BUF_LEN 1792 #define PCSPK_SAMPLE_RATE 32000 @@ -71,7 +73,15 @@ static void pcspk_callback(void *opaque, int free) { PCSpkState *s = opaque; unsigned int n; +#ifdef USE_KVM_PIT + struct kvm_pit_state pit_state; + if (kvm_enabled() && qemu_kvm_pit_in_kernel()) { + kvm_get_pit(kvm_context, &pit_state); + s->pit->channels[2].mode = pit_state.channels[2].mode; + s->pit->channels[2].count = pit_state.channels[2].count; + } +#endif if (pit_get_mode(s->pit, 2) != 3) return; @@ -120,7 +130,17 @@ static uint32_t pcspk_ioport_read(void *opaque, uint32_t addr) { PCSpkState *s = opaque; int out; - +#ifdef USE_KVM_PIT + struct kvm_pit_state pit_state; + + if (kvm_enabled() && qemu_kvm_pit_in_kernel()) { + kvm_get_pit(kvm_context, &pit_state); + s->pit->channels[2].mode = pit_state.channels[2].mode; + s->pit->channels[2].count = pit_state.channels[2].count; + s->pit->channels[2].count_load_time = pit_state.channels[2].count_load_time; + s->pit->channels[2].gate = pit_state.channels[2].gate; + } +#endif s->dummy_refresh_clock ^= (1 << 4); out = pit_get_out(s->pit, 2, qemu_get_clock(vm_clock)) << 5; @@ -131,7 +151,17 @@ static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val) { PCSpkState *s = opaque; const int gate = val & 1; - +#ifdef USE_KVM_PIT + struct kvm_pit_state pit_state; + + if (kvm_enabled() && qemu_kvm_pit_in_kernel()) { + kvm_get_pit(kvm_context, &pit_state); + s->pit->channels[2].mode = pit_state.channels[2].mode; + s->pit->channels[2].count = pit_state.channels[2].count; + s->pit->channels[2].count_load_time = pit_state.channels[2].count_load_time; + s->pit->channels[2].gate = pit_state.channels[2].gate; + } +#endif s->data_on = (val >> 1) & 1; pit_set_gate(s->pit, 2, gate); if (s->voice) { @@ -139,6 +169,15 @@ static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val) s->play_pos = 0; AUD_set_active_out(s->voice, gate & s->data_on); } +#ifdef USE_KVM_PIT + if (kvm_enabled() && qemu_kvm_pit_in_kernel()) { + pit_state.channels[2].mode = s->pit->channels[2].mode; + pit_state.channels[2].count = s->pit->channels[2].count; + pit_state.channels[2].count_load_time = s->pit->channels[2].count_load_time; + pit_state.channels[2].gate = s->pit->channels[2].gate; + kvm_set_pit(kvm_context, &pit_state); + } +#endif } void pcspk_init(PITState *pit)