From: Jan Kiszka <jan.kiszka@web.de>
To: Avi Kivity <avi@redhat.com>
Cc: kvm-devel <kvm@vger.kernel.org>
Subject: [PATCH] kvm-userspace: Make PC speaker emulation aware of in-kernel PIT
Date: Thu, 23 Apr 2009 22:24:05 +0200 [thread overview]
Message-ID: <49F0CE65.4050005@web.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 4145 bytes --]
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 <jan.kiszka@siemens.com>
---
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)
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
next reply other threads:[~2009-04-23 20:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-23 20:24 Jan Kiszka [this message]
2009-04-25 0:13 ` [PATCH] kvm-userspace: Make PC speaker emulation aware of in-kernel PIT Marcelo Tosatti
2009-04-25 13:08 ` Anthony Liguori
2009-04-25 16:28 ` Jan Kiszka
2009-04-25 19:59 ` Anthony Liguori
2009-04-27 13:00 ` Sheng Yang
2009-04-28 4:44 ` David S. Ahern
2009-04-28 7:02 ` Dor Laor
2009-04-27 22:32 ` Marcelo Tosatti
2009-05-04 9:34 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49F0CE65.4050005@web.de \
--to=jan.kiszka@web.de \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.