diff mbox series

[PULL,1/6] audio/hda: create millisecond timers that handle IO

Message ID 20180625131253.11218-2-kraxel@redhat.com
State New
Headers show
Series [PULL,1/6] audio/hda: create millisecond timers that handle IO | expand

Commit Message

Gerd Hoffmann June 25, 2018, 1:12 p.m. UTC
Currently, the HDA device tries to sync itself with the QEMU audio
backend by waiting for the guest driver to handle buffer completion
interrupts. This causes the backend to often read too much data from the
device, as well as running out of data whenever the guest takes too long
to handle the interrupt.

According to the HDA specification, the guest is also not required to
use interrupts, but can also sync itself by polling the LPIB registers.

This patch will introduce high frequency (1000Hz) timers that interface
with the device and allow for much smoother emulation of the LPIB
registers. Since the timing is now provided by these timers, the need
to wait for buffer completion interrupts also ceases.

Signed-off-by: Martin Schrodt <martin@schrodt.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20180622111200.30561-2-kraxel@redhat.com
Message-id: 20171015184033.2951-3-martin@schrodt.org

[ kraxel: keep old code for compatibility with older qemu versions,
          add property to switch code paths at runtime ]
[ kraxel: new code is disabled by default, use-timer=on enables it ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/audio/hda-codec.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++-----
 hw/audio/intel-hda.c |   7 --
 2 files changed, 237 insertions(+), 33 deletions(-)

Comments

Max Reitz June 26, 2018, 7:55 p.m. UTC | #1
On 2018-06-25 15:12, Gerd Hoffmann wrote:
> Currently, the HDA device tries to sync itself with the QEMU audio
> backend by waiting for the guest driver to handle buffer completion
> interrupts. This causes the backend to often read too much data from the
> device, as well as running out of data whenever the guest takes too long
> to handle the interrupt.
> 
> According to the HDA specification, the guest is also not required to
> use interrupts, but can also sync itself by polling the LPIB registers.
> 
> This patch will introduce high frequency (1000Hz) timers that interface
> with the device and allow for much smoother emulation of the LPIB
> registers. Since the timing is now provided by these timers, the need
> to wait for buffer completion interrupts also ceases.
> 
> Signed-off-by: Martin Schrodt <martin@schrodt.org>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Message-id: 20180622111200.30561-2-kraxel@redhat.com
> Message-id: 20171015184033.2951-3-martin@schrodt.org
> 
> [ kraxel: keep old code for compatibility with older qemu versions,
>           add property to switch code paths at runtime ]
> [ kraxel: new code is disabled by default, use-timer=on enables it ]
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/audio/hda-codec.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++-----
>  hw/audio/intel-hda.c |   7 --
>  2 files changed, 237 insertions(+), 33 deletions(-)

This patch breaks compilation on clang with -m32 for me, because I
apparently I don't have 64 bit atomics there.  Should there be
CONFIG_ATOMIC64 guards and handling for when that isn't defined?

Max
Gerd Hoffmann June 27, 2018, 6:51 a.m. UTC | #2
> > Signed-off-by: Martin Schrodt <martin@schrodt.org>
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> > Message-id: 20180622111200.30561-2-kraxel@redhat.com
> > Message-id: 20171015184033.2951-3-martin@schrodt.org
> > 
> > [ kraxel: keep old code for compatibility with older qemu versions,
> >           add property to switch code paths at runtime ]
> > [ kraxel: new code is disabled by default, use-timer=on enables it ]
> > 
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> > ---
> >  hw/audio/hda-codec.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++-----
> >  hw/audio/intel-hda.c |   7 --
> >  2 files changed, 237 insertions(+), 33 deletions(-)
> 
> This patch breaks compilation on clang with -m32 for me, because I
> apparently I don't have 64 bit atomics there.  Should there be
> CONFIG_ATOMIC64 guards and handling for when that isn't defined?

Given the code runs under big qemu lock anyway the atomics are not
needed, so we could drop just them.  I left them in nevertheless because

  (a) we might want try run the code in a thread instead of using a timer, and
  (b) I was too lazy to rewrite the code to drop the atomics.

I'd prefer to keep option (a) ...

Using int32_t instead of int64_t for rpos and wpos would be another way.
Also not that great because they will wrap then after playing sound for
roughly 6 hours.

Using int32_t on 32bit hosts only (or depending on CONFIG_ATOMIC64) is
bad too because rpos and wpos are in vmstate, so the live migration
stream format changes.

Hmm.

Drop support for 32bit hosts in qemu?

cheers,
  Gerd
Thomas Huth June 27, 2018, 7:24 a.m. UTC | #3
On 27.06.2018 08:51, Gerd Hoffmann wrote:
>>> Signed-off-by: Martin Schrodt <martin@schrodt.org>
>>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>>> Message-id: 20180622111200.30561-2-kraxel@redhat.com
>>> Message-id: 20171015184033.2951-3-martin@schrodt.org
>>>
>>> [ kraxel: keep old code for compatibility with older qemu versions,
>>>           add property to switch code paths at runtime ]
>>> [ kraxel: new code is disabled by default, use-timer=on enables it ]
>>>
>>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>>> ---
>>>  hw/audio/hda-codec.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++-----
>>>  hw/audio/intel-hda.c |   7 --
>>>  2 files changed, 237 insertions(+), 33 deletions(-)
>>
>> This patch breaks compilation on clang with -m32 for me, because I
>> apparently I don't have 64 bit atomics there.  Should there be
>> CONFIG_ATOMIC64 guards and handling for when that isn't defined?
> 
> Given the code runs under big qemu lock anyway the atomics are not
> needed, so we could drop just them.  I left them in nevertheless because
> 
>   (a) we might want try run the code in a thread instead of using a timer, and
>   (b) I was too lazy to rewrite the code to drop the atomics.
> 
> I'd prefer to keep option (a) ...
> 
> Using int32_t instead of int64_t for rpos and wpos would be another way.
> Also not that great because they will wrap then after playing sound for
> roughly 6 hours.
> 
> Using int32_t on 32bit hosts only (or depending on CONFIG_ATOMIC64) is
> bad too because rpos and wpos are in vmstate, so the live migration
> stream format changes.
> 
> Hmm.
> 
> Drop support for 32bit hosts in qemu?

I guess the only way to answer that question reliably is to send a patch
to mark 32-bit hosts as deprecated...

Anyway, you still have got to fix that problem with -m32 now somehow
since we certainly can not drop 32-bit immediately.

 Thomas
Markus Armbruster June 27, 2018, 7:57 a.m. UTC | #4
Thomas Huth <thuth@redhat.com> writes:

> On 27.06.2018 08:51, Gerd Hoffmann wrote:
[...]
>> Drop support for 32bit hosts in qemu?
>
> I guess the only way to answer that question reliably is to send a patch
> to mark 32-bit hosts as deprecated...
>
> Anyway, you still have got to fix that problem with -m32 now somehow
> since we certainly can not drop 32-bit immediately.

We certainly can if we want to.

Our formal deprecation policy codifies our compromise between the need
to evolve QEMU and the need of its users for stable external interfaces.

"Compiles on host X" is also a need, but it's a different one.
Evidence: "Supported build platforms" has its own appendix, separate
from "Deprecated features".  It's mum on 32-bit hosts.

I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
feature deprecation policy does not apply.

Is QEMU still useful on 32-bit hosts?  Honest question!
Thomas Huth June 27, 2018, 8:09 a.m. UTC | #5
On 27.06.2018 09:57, Markus Armbruster wrote:
> Thomas Huth <thuth@redhat.com> writes:
> 
>> On 27.06.2018 08:51, Gerd Hoffmann wrote:
> [...]
>>> Drop support for 32bit hosts in qemu?
>>
>> I guess the only way to answer that question reliably is to send a patch
>> to mark 32-bit hosts as deprecated...
>>
>> Anyway, you still have got to fix that problem with -m32 now somehow
>> since we certainly can not drop 32-bit immediately.
> 
> We certainly can if we want to.
> 
> Our formal deprecation policy codifies our compromise between the need
> to evolve QEMU and the need of its users for stable external interfaces.
> 
> "Compiles on host X" is also a need, but it's a different one.
> Evidence: "Supported build platforms" has its own appendix, separate
> from "Deprecated features".  It's mum on 32-bit hosts.

Theoretically I'd agree, but actually it's more than that: If we drop
support for 32-bit hosts, we could also drop the qemu-system-i386,
qemu-system-ppc and qemu-system-arm targets, since qemu-system-x86_64,
qemu-system-ppc64 and qemu-system-aarch64 are a clear superset of these.
But that would also mean a change of the user interface, since the name
of the executable changes, and at least for ppc, there are also subtle
differences (different default machine type, different default CPU types).

 Thomas
BALATON Zoltan June 27, 2018, 8:15 a.m. UTC | #6
On Wed, 27 Jun 2018, Markus Armbruster wrote:
> Thomas Huth <thuth@redhat.com> writes:
>> On 27.06.2018 08:51, Gerd Hoffmann wrote:
> [...]
>>> Drop support for 32bit hosts in qemu?
>>
>> I guess the only way to answer that question reliably is to send a patch
>> to mark 32-bit hosts as deprecated...
>>
>> Anyway, you still have got to fix that problem with -m32 now somehow
>> since we certainly can not drop 32-bit immediately.
>
> We certainly can if we want to.
>
> Our formal deprecation policy codifies our compromise between the need
> to evolve QEMU and the need of its users for stable external interfaces.
>
> "Compiles on host X" is also a need, but it's a different one.
> Evidence: "Supported build platforms" has its own appendix, separate
> from "Deprecated features".  It's mum on 32-bit hosts.
>
> I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
> feature deprecation policy does not apply.
>
> Is QEMU still useful on 32-bit hosts?  Honest question!

I guess it depends on what 32-bit hosts you consider. If you look at only 
x86 vs. x86_64 then probably x86 is not that important any more but for 
some embedded systems/SoCs 32bit might still be common and QEMU useful for 
those (also as host not only emulated).

Another option might be to not support audio/hda on 32bit hosts. It's not 
nice either but a lot nicer than dropping support for 32bit hosts 
alltogether to fix a problem in device emulation. The nicest would of 
course be fixing the device emulation to work on all supported platform.

Regards,
BALATON Zoltan
Gerd Hoffmann June 27, 2018, 8:52 a.m. UTC | #7
Hi,

> > Is QEMU still useful on 32-bit hosts?  Honest question!
> 
> I guess it depends on what 32-bit hosts you consider. If you look at only
> x86 vs. x86_64 then probably x86 is not that important any more but for some
> embedded systems/SoCs 32bit might still be common and QEMU useful for those
> (also as host not only emulated).

Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
slow.  And all the arm architecture improvements to support kvm better
are for aarch64 only.

> Another option might be to not support audio/hda on 32bit hosts. It's not
> nice either but a lot nicer than dropping support for 32bit hosts
> alltogether to fix a problem in device emulation.

But it also is not useful and a waste of resources to maintain 32bit
host compatibility if nobody actually uses that ...

For me testbuilds are the only reason to compile qemu for 32bit hosts.
Since years.

cheers,
  Gerd
Gerd Hoffmann June 27, 2018, 8:56 a.m. UTC | #8
Hi,

> > "Compiles on host X" is also a need, but it's a different one.
> > Evidence: "Supported build platforms" has its own appendix, separate
> > from "Deprecated features".  It's mum on 32-bit hosts.
> 
> Theoretically I'd agree, but actually it's more than that: If we drop
> support for 32-bit hosts, we could also drop the qemu-system-i386,
> qemu-system-ppc and qemu-system-arm targets, since qemu-system-x86_64,
> qemu-system-ppc64 and qemu-system-aarch64 are a clear superset of these.
> But that would also mean a change of the user interface, since the name
> of the executable changes, and at least for ppc, there are also subtle
> differences (different default machine type, different default CPU types).

We don't have to do it all at once though.  We could drop 32bit host
support now and figure how to handle qemu-system-i386 & friends later.

Just removing them would be one option.  Or have them check the
executable name and pick defaults based on that, so we can just symlink
qemu-system-ppc to qemu-system-ppc64.

cheers,
  Gerd
Thomas Huth June 27, 2018, 9:09 a.m. UTC | #9
On 27.06.2018 10:52, Gerd Hoffmann wrote:
>   Hi,
> 
>>> Is QEMU still useful on 32-bit hosts?  Honest question!
>>
>> I guess it depends on what 32-bit hosts you consider. If you look at only
>> x86 vs. x86_64 then probably x86 is not that important any more but for some
>> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>> (also as host not only emulated).
> 
> Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
> slow.  And all the arm architecture improvements to support kvm better
> are for aarch64 only.
> 
>> Another option might be to not support audio/hda on 32bit hosts. It's not
>> nice either but a lot nicer than dropping support for 32bit hosts
>> alltogether to fix a problem in device emulation.
> 
> But it also is not useful and a waste of resources to maintain 32bit
> host compatibility if nobody actually uses that ...
> 
> For me testbuilds are the only reason to compile qemu for 32bit hosts.
> Since years.

Well, while that's true for you, me and likely most of us developers,
you can not know whether this is also true for all users of qemu. Thus
this needs to be announced first for a couple of releases so that people
have a chance to speak up whether they still need this or not. As
mentioned earlier, embedded devices are often still 32-bit and I know
that there really are people who use QEMU on embedded devices.

But I think we could at least announce now already that we intend to
drop support for 32-bit hosts in the future (maybe not in 2 releases
already, but, let's say in 2020? 2020 is already the EOL of Python 2, so
that will rule out a bunch of other legacy hosts, too).

 Thomas
Peter Maydell June 27, 2018, 10:49 a.m. UTC | #10
On 27 June 2018 at 09:52, Gerd Hoffmann <kraxel@redhat.com> wrote:
>   Hi,
>
>> > Is QEMU still useful on 32-bit hosts?  Honest question!
>>
>> I guess it depends on what 32-bit hosts you consider. If you look at only
>> x86 vs. x86_64 then probably x86 is not that important any more but for some
>> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>> (also as host not only emulated).

I would generally agree with this. For x86 32-bit is probably
droppable, but for non-x86 the situation is much less clear.

> Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
> slow.  And all the arm architecture improvements to support kvm better
> are for aarch64 only.

Cubietruck (a Cortex-A7) is a pretty slow 32-bit Arm core.

Ask again in a couple of years :-)

thanks
-- PMM
Alex Bennée June 27, 2018, 11:08 a.m. UTC | #11
Thomas Huth <thuth@redhat.com> writes:

> On 27.06.2018 09:57, Markus Armbruster wrote:
>> Thomas Huth <thuth@redhat.com> writes:
>>
>>> On 27.06.2018 08:51, Gerd Hoffmann wrote:
>> [...]
>>>> Drop support for 32bit hosts in qemu?
>>>
>>> I guess the only way to answer that question reliably is to send a patch
>>> to mark 32-bit hosts as deprecated...
>>>
>>> Anyway, you still have got to fix that problem with -m32 now somehow
>>> since we certainly can not drop 32-bit immediately.
>>
>> We certainly can if we want to.
>>
>> Our formal deprecation policy codifies our compromise between the need
>> to evolve QEMU and the need of its users for stable external interfaces.
>>
>> "Compiles on host X" is also a need, but it's a different one.
>> Evidence: "Supported build platforms" has its own appendix, separate
>> from "Deprecated features".  It's mum on 32-bit hosts.
>
> Theoretically I'd agree, but actually it's more than that: If we drop
> support for 32-bit hosts, we could also drop the qemu-system-i386,
> qemu-system-ppc and qemu-system-arm targets, since qemu-system-x86_64,
> qemu-system-ppc64 and qemu-system-aarch64 are a clear superset of
> these.

Hmm not quite - not building on HOST != not wanting to run GUEST

While I'm unlikely to build on a 32 bit ARM system I run 32 bit guests
all the time.

> But that would also mean a change of the user interface, since the name
> of the executable changes, and at least for ppc, there are also subtle
> differences (different default machine type, different default CPU types).
>
>  Thomas


--
Alex Bennée
Dr. David Alan Gilbert June 27, 2018, 11:09 a.m. UTC | #12
* Peter Maydell (peter.maydell@linaro.org) wrote:
> On 27 June 2018 at 09:52, Gerd Hoffmann <kraxel@redhat.com> wrote:
> >   Hi,
> >
> >> > Is QEMU still useful on 32-bit hosts?  Honest question!
> >>
> >> I guess it depends on what 32-bit hosts you consider. If you look at only
> >> x86 vs. x86_64 then probably x86 is not that important any more but for some
> >> embedded systems/SoCs 32bit might still be common and QEMU useful for those
> >> (also as host not only emulated).
> 
> I would generally agree with this. For x86 32-bit is probably
> droppable, but for non-x86 the situation is much less clear.
> 
> > Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
> > slow.  And all the arm architecture improvements to support kvm better
> > are for aarch64 only.
> 
> Cubietruck (a Cortex-A7) is a pretty slow 32-bit Arm core.
> 
> Ask again in a couple of years :-)

How about dropping support for 32 bit hosts that don't have
64bit atomics?
That should be a much smaller set.

Dave

> thanks
> -- PMM
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Daniel P. Berrangé June 27, 2018, 11:09 a.m. UTC | #13
On Wed, Jun 27, 2018 at 09:57:09AM +0200, Markus Armbruster wrote:
> Thomas Huth <thuth@redhat.com> writes:
> 
> > On 27.06.2018 08:51, Gerd Hoffmann wrote:
> [...]
> >> Drop support for 32bit hosts in qemu?
> >
> > I guess the only way to answer that question reliably is to send a patch
> > to mark 32-bit hosts as deprecated...
> >
> > Anyway, you still have got to fix that problem with -m32 now somehow
> > since we certainly can not drop 32-bit immediately.
> 
> We certainly can if we want to.
> 
> Our formal deprecation policy codifies our compromise between the need
> to evolve QEMU and the need of its users for stable external interfaces.
> 
> "Compiles on host X" is also a need, but it's a different one.
> Evidence: "Supported build platforms" has its own appendix, separate
> from "Deprecated features".  It's mum on 32-bit hosts.

It is silent on host architecture coverage in general in fact. It was
only really focusing on operating systems and so any arch coverage is
at best inferred from what those OS target. Fedora covers 32-bit & 64-bit
arches for example, so you could take that to imply we need to support
both in QEMU.

It is fuzzier though because while Peter has good OS coverage for his
merge testing, I don't think he has full host arch coverage for everything
that downstreams expect QEMU to build on ?

> I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
> feature deprecation policy does not apply.
> 
> Is QEMU still useful on 32-bit hosts?  Honest question!

That answer varies depending on what you're using QEMU for I think. It
could be that people see tools like qemu-img/qemu-nbd as useful even
if they don't use system emulators. And of course userspace emulators
are enough distinct use case.

IMHO as long as distros are shipping 32-bit support, it is reasonable
to assume there will be people who find QEMU useful to some degree.

Personally I don't have any need for 32-bit hosts, but clearly some
people do since otherwise distros would  have killed their 32-bit
arches already.

Regards,
Daniel
Thomas Huth June 27, 2018, 11:09 a.m. UTC | #14
On 27.06.2018 13:08, Alex Bennée wrote:
> 
> Thomas Huth <thuth@redhat.com> writes:
> 
>> On 27.06.2018 09:57, Markus Armbruster wrote:
>>> Thomas Huth <thuth@redhat.com> writes:
>>>
>>>> On 27.06.2018 08:51, Gerd Hoffmann wrote:
>>> [...]
>>>>> Drop support for 32bit hosts in qemu?
>>>>
>>>> I guess the only way to answer that question reliably is to send a patch
>>>> to mark 32-bit hosts as deprecated...
>>>>
>>>> Anyway, you still have got to fix that problem with -m32 now somehow
>>>> since we certainly can not drop 32-bit immediately.
>>>
>>> We certainly can if we want to.
>>>
>>> Our formal deprecation policy codifies our compromise between the need
>>> to evolve QEMU and the need of its users for stable external interfaces.
>>>
>>> "Compiles on host X" is also a need, but it's a different one.
>>> Evidence: "Supported build platforms" has its own appendix, separate
>>> from "Deprecated features".  It's mum on 32-bit hosts.
>>
>> Theoretically I'd agree, but actually it's more than that: If we drop
>> support for 32-bit hosts, we could also drop the qemu-system-i386,
>> qemu-system-ppc and qemu-system-arm targets, since qemu-system-x86_64,
>> qemu-system-ppc64 and qemu-system-aarch64 are a clear superset of
>> these.
> 
> Hmm not quite - not building on HOST != not wanting to run GUEST
> 
> While I'm unlikely to build on a 32 bit ARM system I run 32 bit guests
> all the time.

But you can also run 32-bit ARM guests with qemu-system-aarch64, can't you?

 Thomas
Gerd Hoffmann June 27, 2018, 11:13 a.m. UTC | #15
Hi,

> Given the code runs under big qemu lock anyway the atomics are not
> needed, so we could drop just them.  I left them in nevertheless because
> 
>   (a) we might want try run the code in a thread instead of using a timer, and
>   (b) I was too lazy to rewrite the code to drop the atomics.
> 
> I'd prefer to keep option (a) ...

Well, experimented with that a bit. 

As long as the core audio system runs using qemu timers too moving to a
thread doesn't buy us much as any latency spikes in qemu will hit us no
matter what.

So, that point is moot.  I'll go drop the atomics.

cheers,
  Gerd
Eric Blake June 27, 2018, 12:21 p.m. UTC | #16
On 06/27/2018 01:51 AM, Gerd Hoffmann wrote:
>>> Signed-off-by: Martin Schrodt <martin@schrodt.org>
>>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>>> Message-id: 20180622111200.30561-2-kraxel@redhat.com
>>> Message-id: 20171015184033.2951-3-martin@schrodt.org
>>>
>>> [ kraxel: keep old code for compatibility with older qemu versions,
>>>            add property to switch code paths at runtime ]
>>> [ kraxel: new code is disabled by default, use-timer=on enables it ]
>>>
>>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>>> ---
>>>   hw/audio/hda-codec.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++-----
>>>   hw/audio/intel-hda.c |   7 --
>>>   2 files changed, 237 insertions(+), 33 deletions(-)
>>
>> This patch breaks compilation on clang with -m32 for me, because I
>> apparently I don't have 64 bit atomics there.  Should there be
>> CONFIG_ATOMIC64 guards and handling for when that isn't defined?
> 
> Given the code runs under big qemu lock anyway the atomics are not
> needed, so we could drop just them.  I left them in nevertheless because
> 
>    (a) we might want try run the code in a thread instead of using a timer, and
>    (b) I was too lazy to rewrite the code to drop the atomics.
> 
> I'd prefer to keep option (a) ...

what about option (c): figure out how to use util/stats64.c which is a 
way of getting 64-bit atomic math even on 32-bit hosts?
Juan Quintela June 27, 2018, 1:02 p.m. UTC | #17
Markus Armbruster <armbru@redhat.com> wrote:
> Thomas Huth <thuth@redhat.com> writes:
>
>> On 27.06.2018 08:51, Gerd Hoffmann wrote:
> [...]
>>> Drop support for 32bit hosts in qemu?
>>
>> I guess the only way to answer that question reliably is to send a patch
>> to mark 32-bit hosts as deprecated...
>>
>> Anyway, you still have got to fix that problem with -m32 now somehow
>> since we certainly can not drop 32-bit immediately.
>
> We certainly can if we want to.
>
> Our formal deprecation policy codifies our compromise between the need
> to evolve QEMU and the need of its users for stable external interfaces.
>
> "Compiles on host X" is also a need, but it's a different one.
> Evidence: "Supported build platforms" has its own appendix, separate
> from "Deprecated features".  It's mum on 32-bit hosts.
>
> I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
> feature deprecation policy does not apply.
>
> Is QEMU still useful on 32-bit hosts?  Honest question!

At least require 32bits architectures/compilers able to use 64bit
atomics.  That leaves us with x86 (depending on compiler).  And there
haven't been 32bit x86 hosts since .....

Later, Juan.
Alex Bennée June 27, 2018, 1:03 p.m. UTC | #18
Daniel P. Berrangé <berrange@redhat.com> writes:

> On Wed, Jun 27, 2018 at 09:57:09AM +0200, Markus Armbruster wrote:
>> Thomas Huth <thuth@redhat.com> writes:
>>
>> > On 27.06.2018 08:51, Gerd Hoffmann wrote:
>> [...]
>> >> Drop support for 32bit hosts in qemu?
>> >
>> > I guess the only way to answer that question reliably is to send a patch
>> > to mark 32-bit hosts as deprecated...
>> >
>> > Anyway, you still have got to fix that problem with -m32 now somehow
>> > since we certainly can not drop 32-bit immediately.
>>
>> We certainly can if we want to.
>>
>> Our formal deprecation policy codifies our compromise between the need
>> to evolve QEMU and the need of its users for stable external interfaces.
>>
>> "Compiles on host X" is also a need, but it's a different one.
>> Evidence: "Supported build platforms" has its own appendix, separate
>> from "Deprecated features".  It's mum on 32-bit hosts.
>
> It is silent on host architecture coverage in general in fact. It was
> only really focusing on operating systems and so any arch coverage is
> at best inferred from what those OS target. Fedora covers 32-bit & 64-bit
> arches for example, so you could take that to imply we need to support
> both in QEMU.
>
> It is fuzzier though because while Peter has good OS coverage for his
> merge testing, I don't think he has full host arch coverage for everything
> that downstreams expect QEMU to build on ?

We do however have cross build infrastructure for all tcg/foo backends.
They are run by the shippable CI framework (which is how I noticed):

  https://app.shippable.com/github/qemu/qemu/runs?branchName=master

Once we have the changes made to the wiki I'd like to use:

  https://wiki.qemu.org/Template:CIStatus

In a few choice places on the wiki, including the front page, for better
visibility.

>> I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
>> feature deprecation policy does not apply.
>>
>> Is QEMU still useful on 32-bit hosts?  Honest question!
>
> That answer varies depending on what you're using QEMU for I think. It
> could be that people see tools like qemu-img/qemu-nbd as useful even
> if they don't use system emulators. And of course userspace emulators
> are enough distinct use case.
>
> IMHO as long as distros are shipping 32-bit support, it is reasonable
> to assume there will be people who find QEMU useful to some degree.
>
> Personally I don't have any need for 32-bit hosts, but clearly some
> people do since otherwise distros would  have killed their 32-bit
> arches already.

I know of at least one kernel developer who uses qemu-system-aarch64 on
their 32 bit ARM Chromebook to test their 64 bit code. Next time I see
them I'll see if they are still using it.

My feeling is although probably not widespread it certainly can be handy.

>
> Regards,
> Daniel


--
Alex Bennée
Alex Bennée June 27, 2018, 1:08 p.m. UTC | #19
Dr. David Alan Gilbert <dgilbert@redhat.com> writes:

> * Peter Maydell (peter.maydell@linaro.org) wrote:
>> On 27 June 2018 at 09:52, Gerd Hoffmann <kraxel@redhat.com> wrote:
>> >   Hi,
>> >
>> >> > Is QEMU still useful on 32-bit hosts?  Honest question!
>> >>
>> >> I guess it depends on what 32-bit hosts you consider. If you look at only
>> >> x86 vs. x86_64 then probably x86 is not that important any more but for some
>> >> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>> >> (also as host not only emulated).
>>
>> I would generally agree with this. For x86 32-bit is probably
>> droppable, but for non-x86 the situation is much less clear.
>>
>> > Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
>> > slow.  And all the arm architecture improvements to support kvm better
>> > are for aarch64 only.
>>
>> Cubietruck (a Cortex-A7) is a pretty slow 32-bit Arm core.
>>
>> Ask again in a couple of years :-)
>
> How about dropping support for 32 bit hosts that don't have
> 64bit atomics?
> That should be a much smaller set.

Seems a bit harsh - we don't support MTTCG if you don't have big enough
atomics, but we don't drop TCG support completely. And in fact in the
case in point I don't think you could trigger a bug with emulation being
single threaded and all.

>
> Dave
>
>> thanks
>> -- PMM
>>


--
Alex Bennée
Alex Bennée June 27, 2018, 1:09 p.m. UTC | #20
Alex Bennée <alex.bennee@linaro.org> writes:

> Dr. David Alan Gilbert <dgilbert@redhat.com> writes:
>
>> * Peter Maydell (peter.maydell@linaro.org) wrote:
>>> On 27 June 2018 at 09:52, Gerd Hoffmann <kraxel@redhat.com> wrote:
>>> >   Hi,
>>> >
>>> >> > Is QEMU still useful on 32-bit hosts?  Honest question!
>>> >>
>>> >> I guess it depends on what 32-bit hosts you consider. If you look at only
>>> >> x86 vs. x86_64 then probably x86 is not that important any more but for some
>>> >> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>>> >> (also as host not only emulated).
>>>
>>> I would generally agree with this. For x86 32-bit is probably
>>> droppable, but for non-x86 the situation is much less clear.
>>>
>>> > Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
>>> > slow.  And all the arm architecture improvements to support kvm better
>>> > are for aarch64 only.
>>>
>>> Cubietruck (a Cortex-A7) is a pretty slow 32-bit Arm core.
>>>
>>> Ask again in a couple of years :-)
>>
>> How about dropping support for 32 bit hosts that don't have
>> 64bit atomics?
>> That should be a much smaller set.
>
> Seems a bit harsh - we don't support MTTCG if you don't have big enough
> atomics, but we don't drop TCG support completely. And in fact in the
> case in point I don't think you could trigger a bug with emulation being
> single threaded and all.

I should point out that is what TCG_OVERSIZED_GUEST is defined for.

--
Alex Bennée
Daniel P. Berrangé June 27, 2018, 1:11 p.m. UTC | #21
On Wed, Jun 27, 2018 at 03:02:48PM +0200, Juan Quintela wrote:
> Markus Armbruster <armbru@redhat.com> wrote:
> > Thomas Huth <thuth@redhat.com> writes:
> >
> >> On 27.06.2018 08:51, Gerd Hoffmann wrote:
> > [...]
> >>> Drop support for 32bit hosts in qemu?
> >>
> >> I guess the only way to answer that question reliably is to send a patch
> >> to mark 32-bit hosts as deprecated...
> >>
> >> Anyway, you still have got to fix that problem with -m32 now somehow
> >> since we certainly can not drop 32-bit immediately.
> >
> > We certainly can if we want to.
> >
> > Our formal deprecation policy codifies our compromise between the need
> > to evolve QEMU and the need of its users for stable external interfaces.
> >
> > "Compiles on host X" is also a need, but it's a different one.
> > Evidence: "Supported build platforms" has its own appendix, separate
> > from "Deprecated features".  It's mum on 32-bit hosts.
> >
> > I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
> > feature deprecation policy does not apply.
> >
> > Is QEMU still useful on 32-bit hosts?  Honest question!
> 
> At least require 32bits architectures/compilers able to use 64bit
> atomics.  That leaves us with x86 (depending on compiler).  And there
> haven't been 32bit x86 hosts since .....

....the most recent machine you bought, since the Intel ME is running
on some kind of i486-like CPU behind the back of your main CPU ;-P

Regards,
Daniel
Paolo Bonzini June 27, 2018, 1:15 p.m. UTC | #22
On 27/06/2018 13:13, Gerd Hoffmann wrote:
>   Hi,
> 
>> Given the code runs under big qemu lock anyway the atomics are not
>> needed, so we could drop just them.  I left them in nevertheless because
>>
>>   (a) we might want try run the code in a thread instead of using a timer, and
>>   (b) I was too lazy to rewrite the code to drop the atomics.
>>
>> I'd prefer to keep option (a) ...
> 
> Well, experimented with that a bit. 
> 
> As long as the core audio system runs using qemu timers too moving to a
> thread doesn't buy us much as any latency spikes in qemu will hit us no
> matter what.
> 
> So, that point is moot.  I'll go drop the atomics.

Try stat64.  It should work just fine as it's made exactly for this kind
of simple counter.

Paolo
Philippe Mathieu-Daudé June 27, 2018, 1:33 p.m. UTC | #23
On 06/27/2018 06:09 AM, Thomas Huth wrote:
> On 27.06.2018 10:52, Gerd Hoffmann wrote:
>>   Hi,
>>
>>>> Is QEMU still useful on 32-bit hosts?  Honest question!
>>>
>>> I guess it depends on what 32-bit hosts you consider. If you look at only
>>> x86 vs. x86_64 then probably x86 is not that important any more but for some
>>> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>>> (also as host not only emulated).
>>
>> Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
>> slow.  And all the arm architecture improvements to support kvm better
>> are for aarch64 only.
>>
>>> Another option might be to not support audio/hda on 32bit hosts. It's not
>>> nice either but a lot nicer than dropping support for 32bit hosts
>>> alltogether to fix a problem in device emulation.
>>
>> But it also is not useful and a waste of resources to maintain 32bit
>> host compatibility if nobody actually uses that ...
>>
>> For me testbuilds are the only reason to compile qemu for 32bit hosts.
>> Since years.
> 
> Well, while that's true for you, me and likely most of us developers,
> you can not know whether this is also true for all users of qemu. Thus
> this needs to be announced first for a couple of releases so that people
> have a chance to speak up whether they still need this or not. As
> mentioned earlier, embedded devices are often still 32-bit and I know
> that there really are people who use QEMU on embedded devices.
> 
> But I think we could at least announce now already that we intend to
> drop support for 32-bit hosts in the future (maybe not in 2 releases
> already, but, let's say in 2020? 2020 is already the EOL of Python 2, so
> that will rule out a bunch of other legacy hosts, too).

linux-user is certainly widely used on ARMv6 / ARMv7.

Known user cases:

- run ARMv7 binaries on ARMv6
- run armhf binaries on armel
- run x86-64 binaries on ARMv7
Philippe Mathieu-Daudé June 27, 2018, 1:38 p.m. UTC | #24
On 06/27/2018 10:03 AM, Alex Bennée wrote:
> 
> Daniel P. Berrangé <berrange@redhat.com> writes:
> 
>> On Wed, Jun 27, 2018 at 09:57:09AM +0200, Markus Armbruster wrote:
>>> Thomas Huth <thuth@redhat.com> writes:
>>>
>>>> On 27.06.2018 08:51, Gerd Hoffmann wrote:
>>> [...]
>>>>> Drop support for 32bit hosts in qemu?
>>>>
>>>> I guess the only way to answer that question reliably is to send a patch
>>>> to mark 32-bit hosts as deprecated...
>>>>
>>>> Anyway, you still have got to fix that problem with -m32 now somehow
>>>> since we certainly can not drop 32-bit immediately.
>>>
>>> We certainly can if we want to.
>>>
>>> Our formal deprecation policy codifies our compromise between the need
>>> to evolve QEMU and the need of its users for stable external interfaces.
>>>
>>> "Compiles on host X" is also a need, but it's a different one.
>>> Evidence: "Supported build platforms" has its own appendix, separate
>>> from "Deprecated features".  It's mum on 32-bit hosts.
>>
>> It is silent on host architecture coverage in general in fact. It was
>> only really focusing on operating systems and so any arch coverage is
>> at best inferred from what those OS target. Fedora covers 32-bit & 64-bit
>> arches for example, so you could take that to imply we need to support
>> both in QEMU.
>>
>> It is fuzzier though because while Peter has good OS coverage for his
>> merge testing, I don't think he has full host arch coverage for everything
>> that downstreams expect QEMU to build on ?
> 
> We do however have cross build infrastructure for all tcg/foo backends.
> They are run by the shippable CI framework (which is how I noticed):
> 
>   https://app.shippable.com/github/qemu/qemu/runs?branchName=master

FWIW we can also build ppc32 again (with the apt-fake kludge although).

> 
> Once we have the changes made to the wiki I'd like to use:
> 
>   https://wiki.qemu.org/Template:CIStatus
> 
> In a few choice places on the wiki, including the front page, for better
> visibility.
> 
>>> I'm not saying we *should* drop 32-bit hosts immediately.  Only that the
>>> feature deprecation policy does not apply.
>>>
>>> Is QEMU still useful on 32-bit hosts?  Honest question!
>>
>> That answer varies depending on what you're using QEMU for I think. It
>> could be that people see tools like qemu-img/qemu-nbd as useful even
>> if they don't use system emulators. And of course userspace emulators
>> are enough distinct use case.
>>
>> IMHO as long as distros are shipping 32-bit support, it is reasonable
>> to assume there will be people who find QEMU useful to some degree.
>>
>> Personally I don't have any need for 32-bit hosts, but clearly some
>> people do since otherwise distros would  have killed their 32-bit
>> arches already.
> 
> I know of at least one kernel developer who uses qemu-system-aarch64 on
> their 32 bit ARM Chromebook to test their 64 bit code. Next time I see
> them I'll see if they are still using it.
> 
> My feeling is although probably not widespread it certainly can be handy.
> 
>>
>> Regards,
>> Daniel
> 
> 
> --
> Alex Bennée
>
Laurent Vivier June 27, 2018, 3:41 p.m. UTC | #25
Le 27/06/2018 à 15:33, Philippe Mathieu-Daudé a écrit :
> On 06/27/2018 06:09 AM, Thomas Huth wrote:
>> On 27.06.2018 10:52, Gerd Hoffmann wrote:
>>>   Hi,
>>>
>>>>> Is QEMU still useful on 32-bit hosts?  Honest question!
>>>>
>>>> I guess it depends on what 32-bit hosts you consider. If you look at only
>>>> x86 vs. x86_64 then probably x86 is not that important any more but for some
>>>> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>>>> (also as host not only emulated).
>>>
>>> Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
>>> slow.  And all the arm architecture improvements to support kvm better
>>> are for aarch64 only.
>>>
>>>> Another option might be to not support audio/hda on 32bit hosts. It's not
>>>> nice either but a lot nicer than dropping support for 32bit hosts
>>>> alltogether to fix a problem in device emulation.
>>>
>>> But it also is not useful and a waste of resources to maintain 32bit
>>> host compatibility if nobody actually uses that ...
>>>
>>> For me testbuilds are the only reason to compile qemu for 32bit hosts.
>>> Since years.
>>
>> Well, while that's true for you, me and likely most of us developers,
>> you can not know whether this is also true for all users of qemu. Thus
>> this needs to be announced first for a couple of releases so that people
>> have a chance to speak up whether they still need this or not. As
>> mentioned earlier, embedded devices are often still 32-bit and I know
>> that there really are people who use QEMU on embedded devices.
>>
>> But I think we could at least announce now already that we intend to
>> drop support for 32-bit hosts in the future (maybe not in 2 releases
>> already, but, let's say in 2020? 2020 is already the EOL of Python 2, so
>> that will rule out a bunch of other legacy hosts, too).
> 
> linux-user is certainly widely used on ARMv6 / ARMv7.
> 
> Known user cases:
> 
> - run ARMv7 binaries on ARMv6
> - run armhf binaries on armel
> - run x86-64 binaries on ARMv7
> 

I run i386 binaries on ARMv6.

I use it to run i386 printer driver on my raspberry Pi B+.
Brother doesn't provide the binary for ARM, neither the source.

Thanks,
Laurent
Dr. David Alan Gilbert June 27, 2018, 6:44 p.m. UTC | #26
* Laurent Vivier (laurent@vivier.eu) wrote:
> Le 27/06/2018 à 15:33, Philippe Mathieu-Daudé a écrit :
> > On 06/27/2018 06:09 AM, Thomas Huth wrote:
> >> On 27.06.2018 10:52, Gerd Hoffmann wrote:
> >>>   Hi,
> >>>
> >>>>> Is QEMU still useful on 32-bit hosts?  Honest question!
> >>>>
> >>>> I guess it depends on what 32-bit hosts you consider. If you look at only
> >>>> x86 vs. x86_64 then probably x86 is not that important any more but for some
> >>>> embedded systems/SoCs 32bit might still be common and QEMU useful for those
> >>>> (also as host not only emulated).
> >>>
> >>> Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
> >>> slow.  And all the arm architecture improvements to support kvm better
> >>> are for aarch64 only.
> >>>
> >>>> Another option might be to not support audio/hda on 32bit hosts. It's not
> >>>> nice either but a lot nicer than dropping support for 32bit hosts
> >>>> alltogether to fix a problem in device emulation.
> >>>
> >>> But it also is not useful and a waste of resources to maintain 32bit
> >>> host compatibility if nobody actually uses that ...
> >>>
> >>> For me testbuilds are the only reason to compile qemu for 32bit hosts.
> >>> Since years.
> >>
> >> Well, while that's true for you, me and likely most of us developers,
> >> you can not know whether this is also true for all users of qemu. Thus
> >> this needs to be announced first for a couple of releases so that people
> >> have a chance to speak up whether they still need this or not. As
> >> mentioned earlier, embedded devices are often still 32-bit and I know
> >> that there really are people who use QEMU on embedded devices.
> >>
> >> But I think we could at least announce now already that we intend to
> >> drop support for 32-bit hosts in the future (maybe not in 2 releases
> >> already, but, let's say in 2020? 2020 is already the EOL of Python 2, so
> >> that will rule out a bunch of other legacy hosts, too).
> > 
> > linux-user is certainly widely used on ARMv6 / ARMv7.
> > 
> > Known user cases:
> > 
> > - run ARMv7 binaries on ARMv6
> > - run armhf binaries on armel
> > - run x86-64 binaries on ARMv7
> > 
> 
> I run i386 binaries on ARMv6.

Do you know if that model has the 64bit atomics (ldrexd/strexd)?

Dave

> I use it to run i386 printer driver on my raspberry Pi B+.
> Brother doesn't provide the binary for ARM, neither the source.
> 
> Thanks,
> Laurent
> 
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Laurent Vivier June 27, 2018, 7:55 p.m. UTC | #27
Le 27/06/2018 à 20:44, Dr. David Alan Gilbert a écrit :
> * Laurent Vivier (laurent@vivier.eu) wrote:
>> Le 27/06/2018 à 15:33, Philippe Mathieu-Daudé a écrit :
>>> On 06/27/2018 06:09 AM, Thomas Huth wrote:
>>>> On 27.06.2018 10:52, Gerd Hoffmann wrote:
>>>>>   Hi,
>>>>>
>>>>>>> Is QEMU still useful on 32-bit hosts?  Honest question!
>>>>>>
>>>>>> I guess it depends on what 32-bit hosts you consider. If you look at only
>>>>>> x86 vs. x86_64 then probably x86 is not that important any more but for some
>>>>>> embedded systems/SoCs 32bit might still be common and QEMU useful for those
>>>>>> (also as host not only emulated).
>>>>>
>>>>> Well.  I've used kvm with an 32bit arm soc (cubietruck).  It's very
>>>>> slow.  And all the arm architecture improvements to support kvm better
>>>>> are for aarch64 only.
>>>>>
>>>>>> Another option might be to not support audio/hda on 32bit hosts. It's not
>>>>>> nice either but a lot nicer than dropping support for 32bit hosts
>>>>>> alltogether to fix a problem in device emulation.
>>>>>
>>>>> But it also is not useful and a waste of resources to maintain 32bit
>>>>> host compatibility if nobody actually uses that ...
>>>>>
>>>>> For me testbuilds are the only reason to compile qemu for 32bit hosts.
>>>>> Since years.
>>>>
>>>> Well, while that's true for you, me and likely most of us developers,
>>>> you can not know whether this is also true for all users of qemu. Thus
>>>> this needs to be announced first for a couple of releases so that people
>>>> have a chance to speak up whether they still need this or not. As
>>>> mentioned earlier, embedded devices are often still 32-bit and I know
>>>> that there really are people who use QEMU on embedded devices.
>>>>
>>>> But I think we could at least announce now already that we intend to
>>>> drop support for 32-bit hosts in the future (maybe not in 2 releases
>>>> already, but, let's say in 2020? 2020 is already the EOL of Python 2, so
>>>> that will rule out a bunch of other legacy hosts, too).
>>>
>>> linux-user is certainly widely used on ARMv6 / ARMv7.
>>>
>>> Known user cases:
>>>
>>> - run ARMv7 binaries on ARMv6
>>> - run armhf binaries on armel
>>> - run x86-64 binaries on ARMv7
>>>
>>
>> I run i386 binaries on ARMv6.
> 
> Do you know if that model has the 64bit atomics (ldrexd/strexd)?

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489e/Cihbghef.html

"ARM LDREXB, LDREXH, LDREXD, STREXB, STREXD, and STREXH are available in
ARMv6K and above."

Laurent
Peter Maydell June 29, 2018, 8:19 a.m. UTC | #28
On 25 June 2018 at 14:12, Gerd Hoffmann <kraxel@redhat.com> wrote:
> Currently, the HDA device tries to sync itself with the QEMU audio
> backend by waiting for the guest driver to handle buffer completion
> interrupts. This causes the backend to often read too much data from the
> device, as well as running out of data whenever the guest takes too long
> to handle the interrupt.
>
> According to the HDA specification, the guest is also not required to
> use interrupts, but can also sync itself by polling the LPIB registers.
>
> This patch will introduce high frequency (1000Hz) timers that interface
> with the device and allow for much smoother emulation of the LPIB
> registers. Since the timing is now provided by these timers, the need
> to wait for buffer completion interrupts also ceases.

> +static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
> +{
> +    return 2 * st->as.nchannels * st->as.freq;
> +}

Hi; Coverity warns about this expression because the
multiplication is done as a 32-bit multiply and the
result is returned as a 64-bit (CID 1393631). As usual,
a suitable cast would fix it.

thanks
-- PMM
Eric Blake June 29, 2018, 3:11 p.m. UTC | #29
On 06/29/2018 03:19 AM, Peter Maydell wrote:
> On 25 June 2018 at 14:12, Gerd Hoffmann <kraxel@redhat.com> wrote:
>> Currently, the HDA device tries to sync itself with the QEMU audio
>> backend by waiting for the guest driver to handle buffer completion
>> interrupts. This causes the backend to often read too much data from the
>> device, as well as running out of data whenever the guest takes too long
>> to handle the interrupt.
>>
>> According to the HDA specification, the guest is also not required to
>> use interrupts, but can also sync itself by polling the LPIB registers.
>>
>> This patch will introduce high frequency (1000Hz) timers that interface
>> with the device and allow for much smoother emulation of the LPIB
>> registers. Since the timing is now provided by these timers, the need
>> to wait for buffer completion interrupts also ceases.
> 
>> +static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
>> +{
>> +    return 2 * st->as.nchannels * st->as.freq;
>> +}
> 
> Hi; Coverity warns about this expression because the
> multiplication is done as a 32-bit multiply and the
> result is returned as a 64-bit (CID 1393631). As usual,
> a suitable cast would fix it.

Said suitable cast might look best written without parentheses, as in:

return 2LL * st->as.nchannels * st->as.freq;
diff mbox series

Patch

diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index e8aa7842e6..c62e78c859 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -18,6 +18,7 @@ 
  */
 
 #include "qemu/osdep.h"
+#include "qemu/atomic.h"
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
 #include "intel-hda.h"
@@ -126,6 +127,11 @@  static void hda_codec_parse_fmt(uint32_t format, struct audsettings *as)
 #define   PARAM nomixemu
 #include  "hda-codec-common.h"
 
+#define HDA_TIMER_TICKS (SCALE_MS)
+#define MAX_CORR (SCALE_US * 100)
+#define B_SIZE sizeof(st->buf)
+#define B_MASK (sizeof(st->buf) - 1)
+
 /* -------------------------------------------------------------------------- */
 
 static const char *fmt2name[] = {
@@ -154,8 +160,13 @@  struct HDAAudioStream {
         SWVoiceIn *in;
         SWVoiceOut *out;
     } voice;
-    uint8_t buf[HDA_BUFFER_SIZE];
-    uint32_t bpos;
+    uint8_t compat_buf[HDA_BUFFER_SIZE];
+    uint32_t compat_bpos;
+    uint8_t buf[8192]; /* size must be power of two */
+    int64_t rpos;
+    int64_t wpos;
+    QEMUTimer *buft;
+    int64_t buft_start;
 };
 
 #define TYPE_HDA_AUDIO "hda-audio"
@@ -174,55 +185,201 @@  struct HDAAudioState {
     /* properties */
     uint32_t debug;
     bool     mixer;
+    bool     use_timer;
 };
 
+static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
+{
+    return 2 * st->as.nchannels * st->as.freq;
+}
+
+static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
+{
+    int64_t corr =
+        NANOSECONDS_PER_SECOND * target_pos / hda_bytes_per_second(st);
+    if (corr > MAX_CORR) {
+        corr = MAX_CORR;
+    } else if (corr < -MAX_CORR) {
+        corr = -MAX_CORR;
+    }
+    atomic_fetch_add(&st->buft_start, corr);
+}
+
+static void hda_audio_input_timer(void *opaque)
+{
+    HDAAudioStream *st = opaque;
+
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+    int64_t buft_start = atomic_fetch_add(&st->buft_start, 0);
+    int64_t wpos = atomic_fetch_add(&st->wpos, 0);
+    int64_t rpos = atomic_fetch_add(&st->rpos, 0);
+
+    int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
+                          / NANOSECONDS_PER_SECOND;
+    wanted_rpos &= -4; /* IMPORTANT! clip to frames */
+
+    if (wanted_rpos <= rpos) {
+        /* we already transmitted the data */
+        goto out_timer;
+    }
+
+    int64_t to_transfer = audio_MIN(wpos - rpos, wanted_rpos - rpos);
+    while (to_transfer) {
+        uint32_t start = (rpos & B_MASK);
+        uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
+        int rc = hda_codec_xfer(
+                &st->state->hda, st->stream, false, st->buf + start, chunk);
+        if (!rc) {
+            break;
+        }
+        rpos += chunk;
+        to_transfer -= chunk;
+        atomic_fetch_add(&st->rpos, chunk);
+    }
+
+out_timer:
+
+    if (st->running) {
+        timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
+    }
+}
+
 static void hda_audio_input_cb(void *opaque, int avail)
 {
     HDAAudioStream *st = opaque;
+
+    int64_t wpos = atomic_fetch_add(&st->wpos, 0);
+    int64_t rpos = atomic_fetch_add(&st->rpos, 0);
+
+    int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), avail);
+
+    hda_timer_sync_adjust(st, -((wpos - rpos) + to_transfer - (B_SIZE >> 1)));
+
+    while (to_transfer) {
+        uint32_t start = (uint32_t) (wpos & B_MASK);
+        uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
+        uint32_t read = AUD_read(st->voice.in, st->buf + start, chunk);
+        wpos += read;
+        to_transfer -= read;
+        atomic_fetch_add(&st->wpos, read);
+        if (chunk != read) {
+            break;
+        }
+    }
+}
+
+static void hda_audio_output_timer(void *opaque)
+{
+    HDAAudioStream *st = opaque;
+
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+    int64_t buft_start = atomic_fetch_add(&st->buft_start, 0);
+    int64_t wpos = atomic_fetch_add(&st->wpos, 0);
+    int64_t rpos = atomic_fetch_add(&st->rpos, 0);
+
+    int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
+                          / NANOSECONDS_PER_SECOND;
+    wanted_wpos &= -4; /* IMPORTANT! clip to frames */
+
+    if (wanted_wpos <= wpos) {
+        /* we already received the data */
+        goto out_timer;
+    }
+
+    int64_t to_transfer = audio_MIN(B_SIZE - (wpos - rpos), wanted_wpos - wpos);
+    while (to_transfer) {
+        uint32_t start = (wpos & B_MASK);
+        uint32_t chunk = audio_MIN(B_SIZE - start, to_transfer);
+        int rc = hda_codec_xfer(
+                &st->state->hda, st->stream, true, st->buf + start, chunk);
+        if (!rc) {
+            break;
+        }
+        wpos += chunk;
+        to_transfer -= chunk;
+        atomic_fetch_add(&st->wpos, chunk);
+    }
+
+out_timer:
+
+    if (st->running) {
+        timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
+    }
+}
+
+static void hda_audio_output_cb(void *opaque, int avail)
+{
+    HDAAudioStream *st = opaque;
+
+    int64_t wpos = atomic_fetch_add(&st->wpos, 0);
+    int64_t rpos = atomic_fetch_add(&st->rpos, 0);
+
+    int64_t to_transfer = audio_MIN(wpos - rpos, avail);
+
+    hda_timer_sync_adjust(st, (wpos - rpos) - to_transfer - (B_SIZE >> 1));
+
+    while (to_transfer) {
+        uint32_t start = (uint32_t) (rpos & B_MASK);
+        uint32_t chunk = (uint32_t) audio_MIN(B_SIZE - start, to_transfer);
+        uint32_t written = AUD_write(st->voice.out, st->buf + start, chunk);
+        rpos += written;
+        to_transfer -= written;
+        atomic_fetch_add(&st->rpos, written);
+        if (chunk != written) {
+            break;
+        }
+    }
+}
+
+static void hda_audio_compat_input_cb(void *opaque, int avail)
+{
+    HDAAudioStream *st = opaque;
     int recv = 0;
     int len;
     bool rc;
 
-    while (avail - recv >= sizeof(st->buf)) {
-        if (st->bpos != sizeof(st->buf)) {
-            len = AUD_read(st->voice.in, st->buf + st->bpos,
-                           sizeof(st->buf) - st->bpos);
-            st->bpos += len;
+    while (avail - recv >= sizeof(st->compat_buf)) {
+        if (st->compat_bpos != sizeof(st->compat_buf)) {
+            len = AUD_read(st->voice.in, st->compat_buf + st->compat_bpos,
+                           sizeof(st->compat_buf) - st->compat_bpos);
+            st->compat_bpos += len;
             recv += len;
-            if (st->bpos != sizeof(st->buf)) {
+            if (st->compat_bpos != sizeof(st->compat_buf)) {
                 break;
             }
         }
         rc = hda_codec_xfer(&st->state->hda, st->stream, false,
-                            st->buf, sizeof(st->buf));
+                            st->compat_buf, sizeof(st->compat_buf));
         if (!rc) {
             break;
         }
-        st->bpos = 0;
+        st->compat_bpos = 0;
     }
 }
 
-static void hda_audio_output_cb(void *opaque, int avail)
+static void hda_audio_compat_output_cb(void *opaque, int avail)
 {
     HDAAudioStream *st = opaque;
     int sent = 0;
     int len;
     bool rc;
 
-    while (avail - sent >= sizeof(st->buf)) {
-        if (st->bpos == sizeof(st->buf)) {
+    while (avail - sent >= sizeof(st->compat_buf)) {
+        if (st->compat_bpos == sizeof(st->compat_buf)) {
             rc = hda_codec_xfer(&st->state->hda, st->stream, true,
-                                st->buf, sizeof(st->buf));
+                                st->compat_buf, sizeof(st->compat_buf));
             if (!rc) {
                 break;
             }
-            st->bpos = 0;
+            st->compat_bpos = 0;
         }
-        len = AUD_write(st->voice.out, st->buf + st->bpos,
-                        sizeof(st->buf) - st->bpos);
-        st->bpos += len;
+        len = AUD_write(st->voice.out, st->compat_buf + st->compat_bpos,
+                        sizeof(st->compat_buf) - st->compat_bpos);
+        st->compat_bpos += len;
         sent += len;
-        if (st->bpos != sizeof(st->buf)) {
+        if (st->compat_bpos != sizeof(st->compat_buf)) {
             break;
         }
     }
@@ -239,6 +396,17 @@  static void hda_audio_set_running(HDAAudioStream *st, bool running)
     st->running = running;
     dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name,
            st->running ? "on" : "off", st->stream);
+    if (st->state->use_timer) {
+        if (running) {
+            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+            st->rpos = 0;
+            st->wpos = 0;
+            st->buft_start = now;
+            timer_mod_anticipate_ns(st->buft, now + HDA_TIMER_TICKS);
+        } else {
+            timer_del(st->buft);
+        }
+    }
     if (st->output) {
         AUD_set_active_out(st->voice.out, st->running);
     } else {
@@ -274,6 +442,9 @@  static void hda_audio_set_amp(HDAAudioStream *st)
 
 static void hda_audio_setup(HDAAudioStream *st)
 {
+    bool use_timer = st->state->use_timer;
+    audio_callback_fn cb;
+
     if (st->node == NULL) {
         return;
     }
@@ -283,13 +454,25 @@  static void hda_audio_setup(HDAAudioStream *st)
            fmt2name[st->as.fmt], st->as.freq);
 
     if (st->output) {
+        if (use_timer) {
+            cb = hda_audio_output_cb;
+            st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                    hda_audio_output_timer, st);
+        } else {
+            cb = hda_audio_compat_output_cb;
+        }
         st->voice.out = AUD_open_out(&st->state->card, st->voice.out,
-                                     st->node->name, st,
-                                     hda_audio_output_cb, &st->as);
+                                     st->node->name, st, cb, &st->as);
     } else {
+        if (use_timer) {
+            cb = hda_audio_input_cb;
+            st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                    hda_audio_input_timer, st);
+        } else {
+            cb = hda_audio_compat_input_cb;
+        }
         st->voice.in = AUD_open_in(&st->state->card, st->voice.in,
-                                   st->node->name, st,
-                                   hda_audio_input_cb, &st->as);
+                                   st->node->name, st, cb, &st->as);
     }
 }
 
@@ -505,7 +688,7 @@  static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
                 /* unmute output by default */
                 st->gain_left = QEMU_HDA_AMP_STEPS;
                 st->gain_right = QEMU_HDA_AMP_STEPS;
-                st->bpos = sizeof(st->buf);
+                st->compat_bpos = sizeof(st->compat_buf);
                 st->output = true;
             } else {
                 st->output = false;
@@ -532,6 +715,9 @@  static void hda_audio_exit(HDACodecDevice *hda)
         if (st->node == NULL) {
             continue;
         }
+        if (a->use_timer) {
+            timer_del(st->buft);
+        }
         if (st->output) {
             AUD_close_out(&a->card, st->voice.out);
         } else {
@@ -581,6 +767,26 @@  static void hda_audio_reset(DeviceState *dev)
     }
 }
 
+static bool vmstate_hda_audio_stream_buf_needed(void *opaque)
+{
+    HDAAudioStream *st = opaque;
+    return st->state->use_timer;
+}
+
+static const VMStateDescription vmstate_hda_audio_stream_buf = {
+    .name = "hda-audio-stream/buffer",
+    .version_id = 1,
+    .needed = vmstate_hda_audio_stream_buf_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_BUFFER(buf, HDAAudioStream),
+        VMSTATE_INT64(rpos, HDAAudioStream),
+        VMSTATE_INT64(wpos, HDAAudioStream),
+        VMSTATE_TIMER_PTR(buft, HDAAudioStream),
+        VMSTATE_INT64(buft_start, HDAAudioStream),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_hda_audio_stream = {
     .name = "hda-audio-stream",
     .version_id = 1,
@@ -592,9 +798,13 @@  static const VMStateDescription vmstate_hda_audio_stream = {
         VMSTATE_UINT32(gain_right, HDAAudioStream),
         VMSTATE_BOOL(mute_left, HDAAudioStream),
         VMSTATE_BOOL(mute_right, HDAAudioStream),
-        VMSTATE_UINT32(bpos, HDAAudioStream),
-        VMSTATE_BUFFER(buf, HDAAudioStream),
+        VMSTATE_UINT32(compat_bpos, HDAAudioStream),
+        VMSTATE_BUFFER(compat_buf, HDAAudioStream),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription * []) {
+        &vmstate_hda_audio_stream_buf,
+        NULL
     }
 };
 
@@ -615,6 +825,7 @@  static const VMStateDescription vmstate_hda_audio = {
 static Property hda_audio_properties[] = {
     DEFINE_PROP_UINT32("debug", HDAAudioState, debug,   0),
     DEFINE_PROP_BOOL("mixer", HDAAudioState, mixer,  true),
+    DEFINE_PROP_BOOL("use-timer", HDAAudioState, use_timer, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 948268afd8..23a2cf6484 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -407,13 +407,6 @@  static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
     if (st->bpl == NULL) {
         return false;
     }
-    if (st->ctl & (1 << 26)) {
-        /*
-         * Wait with the next DMA xfer until the guest
-         * has acked the buffer completion interrupt
-         */
-        return false;
-    }
 
     left = len;
     s = st->bentries;