From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: Re: [PATCH] kvm-userspace: Make PC speaker emulation aware of in-kernel PIT Date: Mon, 04 May 2009 12:34:31 +0300 Message-ID: <49FEB6A7.4060306@redhat.com> References: <49F0CE65.4050005@web.de> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit Cc: kvm-devel To: Jan Kiszka Return-path: Received: from mx2.redhat.com ([66.187.237.31]:56728 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751215AbZEDJfF (ORCPT ); Mon, 4 May 2009 05:35:05 -0400 In-Reply-To: <49F0CE65.4050005@web.de> Sender: kvm-owner@vger.kernel.org List-ID: Jan Kiszka wrote: > 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. > > 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) > > Please extract those bits into functions. -- Do not meddle in the internals of kernels, for they are subtle and quick to panic.