qemu/0219-hda-do-not-mix-output-and-input-stream-states-RHBZ-7.patch
Cole Robinson cd9d161514 CVE-2012-2652: Possible symlink attacks with -snapshot (bz 825697, bz 824919)
Fix systemtap tapsets (bz 831763)
Fix qmp response race caused by spice server bug (bz 744015)
Fix text mode screendumps (bz 819155)
Don't renable ksm on update (bz 815156)
Fix RPM install error on non-virt machines (bz 660629)
Obsolete openbios to fix upgrade dependency issues (bz 694802)
2012-07-29 21:15:19 -04:00

173 lines
6.3 KiB
Diff

From 51a747e171a66d0dc1e4b47c0238fb2e7fa6b118 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
Date: Tue, 25 Oct 2011 16:53:01 +0200
Subject: [PATCH] hda: do not mix output and input stream states, RHBZ #740493
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Windows 7 may use the same stream number for input and output.
Current code will confuse streams.
Changes since v1:
- keep running_compat[] for migration version 1
- add running_real[] for migration version 2
Signed-off-by: Marc-Andr? Lureau <marcandre.lureau@redhat.com>
Signed-off-by: malc <av1474@comtv.ru>
(cherry picked from commit ba43d28916c4f51c19bd7366089155ce81bee058)
Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
hw/hda-audio.c | 26 +++++++++++++++++++-------
hw/intel-hda.c | 9 +++++----
hw/intel-hda.h | 2 +-
3 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index c699d6f..9b089e6 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -466,7 +466,8 @@ struct HDAAudioState {
QEMUSoundCard card;
const desc_codec *desc;
HDAAudioStream st[4];
- bool running[16];
+ bool running_compat[16];
+ bool running_real[2 * 16];
/* properties */
uint32_t debug;
@@ -663,7 +664,7 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
st->channel = payload & 0x0f;
dprint(a, 2, "%s: stream %d, channel %d\n",
st->node->name, st->stream, st->channel);
- hda_audio_set_running(st, a->running[st->stream]);
+ hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
hda_codec_response(hda, true, 0);
break;
case AC_VERB_GET_CONV:
@@ -746,16 +747,20 @@ fail:
hda_codec_response(hda, true, 0);
}
-static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running)
+static void hda_audio_stream(HDACodecDevice *hda, uint32_t stnr, bool running, bool output)
{
HDAAudioState *a = DO_UPCAST(HDAAudioState, hda, hda);
int s;
- a->running[stnr] = running;
+ a->running_compat[stnr] = running;
+ a->running_real[output * 16 + stnr] = running;
for (s = 0; s < ARRAY_SIZE(a->st); s++) {
if (a->st[s].node == NULL) {
continue;
}
+ if (a->st[s].output != output) {
+ continue;
+ }
if (a->st[s].stream != stnr) {
continue;
}
@@ -837,6 +842,12 @@ static int hda_audio_post_load(void *opaque, int version)
int i;
dprint(a, 1, "%s\n", __FUNCTION__);
+ if (version == 1) {
+ /* assume running_compat[] is for output streams */
+ for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
+ a->running_real[16 + i] = a->running_compat[i];
+ }
+
for (i = 0; i < ARRAY_SIZE(a->st); i++) {
st = a->st + i;
if (st->node == NULL)
@@ -844,7 +855,7 @@ static int hda_audio_post_load(void *opaque, int version)
hda_codec_parse_fmt(st->format, &st->as);
hda_audio_setup(st);
hda_audio_set_amp(st);
- hda_audio_set_running(st, a->running[st->stream]);
+ hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);
}
return 0;
}
@@ -868,13 +879,14 @@ static const VMStateDescription vmstate_hda_audio_stream = {
static const VMStateDescription vmstate_hda_audio = {
.name = "hda-audio",
- .version_id = 1,
+ .version_id = 2,
.post_load = hda_audio_post_load,
.fields = (VMStateField []) {
VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
vmstate_hda_audio_stream,
HDAAudioStream),
- VMSTATE_BOOL_ARRAY(running, HDAAudioState, 16),
+ VMSTATE_BOOL_ARRAY(running_compat, HDAAudioState, 16),
+ VMSTATE_BOOL_ARRAY_V(running_real, HDAAudioState, 2 * 16, 2),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 7d02558..904e4fc 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -485,7 +485,7 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st)
st->bp = 0;
}
-static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running)
+static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output)
{
DeviceState *qdev;
HDACodecDevice *cdev;
@@ -493,7 +493,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn
QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
if (cdev->info->stream) {
- cdev->info->stream(cdev, stream, running);
+ cdev->info->stream(cdev, stream, running, output);
}
}
}
@@ -567,6 +567,7 @@ static void intel_hda_set_ics(IntelHDAState *d, const IntelHDAReg *reg, uint32_t
static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint32_t old)
{
+ bool output = reg->stream >= 4;
IntelHDAStream *st = d->st + reg->stream;
if (st->ctl & 0x01) {
@@ -582,11 +583,11 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3
dprint(d, 1, "st #%d: start %d (ring buf %d bytes)\n",
reg->stream, stnr, st->cbl);
intel_hda_parse_bdl(d, st);
- intel_hda_notify_codecs(d, stnr, true);
+ intel_hda_notify_codecs(d, stnr, true, output);
} else {
/* stop */
dprint(d, 1, "st #%d: stop %d\n", reg->stream, stnr);
- intel_hda_notify_codecs(d, stnr, false);
+ intel_hda_notify_codecs(d, stnr, false, output);
}
}
intel_hda_update_irq(d);
diff --git a/hw/intel-hda.h b/hw/intel-hda.h
index 4e44e38..65fd2a8 100644
--- a/hw/intel-hda.h
+++ b/hw/intel-hda.h
@@ -34,7 +34,7 @@ struct HDACodecDeviceInfo {
int (*init)(HDACodecDevice *dev);
int (*exit)(HDACodecDevice *dev);
void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data);
- void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running);
+ void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool output);
};
void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
--
1.7.11.2