qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Gerd Hoffmann <kraxel@redhat.com>, Marc Zyngier <marc.zyngier@arm.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Alexander Graf <agraf@suse.de>,
	qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] selecting VIRTIO_INPUT and VIRTIO_VGA
Date: Sun, 26 Jul 2015 11:31:10 +0200	[thread overview]
Message-ID: <55B4A8DE.8060503@redhat.com> (raw)
In-Reply-To: <1437817799.15305.22.camel@redhat.com>

On 07/25/15 11:49, Gerd Hoffmann wrote:
>   Hi,
> 
>>> I agree. Also, as far as I understood Marc, his hope was that the fix to 
>>> halfway working VGA emulation would be virtio-gpu.
> 
> Note we have both virtio-vga and virtio-gpu-pci.  virtio-vga has vga
> compatibility built-in, otherwise the two are identical.  virtio-gpu-pci
> is enabled along with all other virtio drivers, so arm + aarch64 have
> that already.
> 
>> 2) Use the fact that there is actually hardly any legacy for ARM VMs,
>> and embrace paravirtualized devices entirely. We do it for disks,
>> network interfaces. Why not display? Why not input?
> 
> We have both now (qemu 2.4+, linux 4.1+ for input, linux 4.2+ for gpu).
> Works just fine on arm (tcg tested).  aarch64 not yet (with vanilla
> upstream linux kernel) due to lack of generic pci host support.
> 
>> Using VGA makes sense on x86 because this is a standard on that
>> platform. Every system has one. You can't expect the same thing on ARM
>> (evil persons would even say that you can't expect anything at all). So
>> let's take this opportunity to use the best tool for the job. Virtio
>> fits that bill pretty well apparently.
> 
> Big question is (a) whenever we need a firmware framebuffer and (b) how
> to implement that best.
> 
> virtio-vga/virtio-gpu-pci in paravirt (native) mode requires the guest
> explicitly request screen updates.  There is no dirty page tracking, and
> guest writes to memory do *not* magically appear on the screen.  I don't
> think implementing a EFI driver for that is going to fly.

The EFI_GRAPHICS_OUTPUT_PROTOCOL structure has a function pointer member
called Blt:

  Blt -- Software abstraction to draw on the video device’s frame
         buffer.
  [...]
         Blt a rectangle of pixels on the graphics screen. Blt stands
         for BLock Transfer.

And, one of the enumeration constants that are possible for the
EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode->Info->PixelFormat field is:

  PixelBltOnly -- This mode does not support a physical frame buffer.

Therefore, strictly for working before ExitBootServices(), a UEFI_DRIVER
module could be implemented that exposed a "blit-only" interface. I have
never tested if the higher level graphics stack in edk2 would work with
that; I guess it might. And, if we force all display accesses through
Blt(), then all the necessary virtio stuff could be done in there, I guess.

The problem is however runtime OS support, after ExitBootServices().
Take for example Windows 8 or Linux (without specific video drivers) on
a UEFI system. The respective boot loader or stub (launched as a UEFI
application) is smart enough to save the framebuffer characteristics for
the OS, *if* there is a physical framebuffer, and then the OS can use a
generic "efifb" driver, directly accessing the video RAM. For Windows 8
and later, this was the only way to have graphics when booting on top of
OVMF, at least until Vadim Rozenfeld completed the QXL WDDM driver.

In brief: PixelBltOnly would be *probably* okay until
ExitBootServices(), but without a physical frame buffer, UEFI operating
systems without native virtio-gpu-pci drivers could not display graphics.

(Recall Windows 7, and the VBE shim we came up with for it -- if the OS
doesn't have graphics after ExitBootServices(), either because the OS is
broken (Windows 7) or because the display is PixelBltOnly, then it can't
even be installed. You can select storage drivers mid-installation
(which runs after ExitBootServices()), but not video.)

> virtio-vga in vga-compat mode uses a framebuffer with the usual dirty
> tracking logic in pci bar 0 (simliar to stdvga).  Which is exactly the
> thing causing the cache coherency issues on aarch64 if I understand
> things correctly.

Yes. :(

> Programming (modesetting) works without legacy vga io
> ports, you can use the mmio regs in pci bar 1 instead (applies to both
> virtio-vga and stdvga btw), and QemuVideoDxe actually uses the mmio bar.

True.

But, as a side point, let me talk a bit about the outb() function in
OvmfPkg/QemuVideoDxe/Driver.c. It (very correctly for a UEFI_DRIVER
module!) uses PciIo->Io.Write() to write to IO ports.

Now, the PciIo protocol implementation is platform independent. In
practice it forwards IO space accesses to the EFI_PCI_ROOT_BRIDGE_IO
protocol. And *that* one is platform-dependent.

For x86 virtual machines, those accesses are turned into IO port
accesses. However, the EFI_PCI_ROOT_BRIDGE_IO implementation in
ArmVirtPkg/PciHostBridgeDxe/, which is built into AAVMF and runs on the
"virt" machtype, maps the IO space and the IO port accesses to a special
(fake) MMIO range of 64K "ports".

In QEMU this memory region corresponds to VIRT_PCIE_PIO, in
"hw/arm/virt.c". See create_pcie():

    hwaddr base_pio = vbi->memmap[VIRT_PCIE_PIO].base;

    ...

    /* Map IO port space */
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);

This range is advertized in the DTB that QEMU exports to AAVMF, which is
how AAVMF knows how to do the translation.

I believe such an emulated IO space was necessary for most QEMU device
models in the first place (I guess quite a few of them must have a hard
IO space dependency). Now that it's there, we can drive it from AAVMF.
(Whether the IO space emulation is temporary or here to stay in QEMU, I
don't know.)

Anyhow, this wall of text is just to say: *if* QemuVideoDxe, built for
AAVMF, had to fall back to legacy VGA IO ports, for whatever reason, it
would be capable of that. The PciIo->Io.Write() accesses made in
QemuVideoDxe would be "diverted" by ArmVirtPkg/PciHostBridgeDxe to the
special MMIO range. (Are abstractions awesome or what?! :))

Thanks
Laszlo

  reply	other threads:[~2015-07-26  9:31 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-11 17:55 [Qemu-devel] selecting VIRTIO_INPUT and VIRTIO_VGA Paolo Bonzini
2015-07-13  7:32 ` Gerd Hoffmann
2015-07-13 10:15   ` Paolo Bonzini
2015-07-13 11:45     ` Gerd Hoffmann
2015-07-13 11:49       ` Paolo Bonzini
2015-07-20 18:52         ` Laszlo Ersek
2015-07-20 19:06     ` Laszlo Ersek
2015-07-21 12:08       ` Alexander Graf
2015-07-21 12:48         ` Laszlo Ersek
2015-07-21 12:51         ` Marc Zyngier
2015-07-25  9:49           ` Gerd Hoffmann
2015-07-26  9:31             ` Laszlo Ersek [this message]
2015-07-26 10:17               ` Peter Maydell
2015-07-26 10:40                 ` Peter Maydell
2015-07-26 11:22                 ` Laszlo Ersek
2015-07-27  7:52             ` Marc Zyngier

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=55B4A8DE.8060503@redhat.com \
    --to=lersek@redhat.com \
    --cc=agraf@suse.de \
    --cc=ard.biesheuvel@linaro.org \
    --cc=kraxel@redhat.com \
    --cc=marc.zyngier@arm.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).