From: "Marc Marí" <markmb@redhat.com>
To: Stefan Hajnoczi <stefanha@gmail.com>
Cc: Drew <drjones@redhat.com>, "Gabriel L. Somlo" <somlo@cmu.edu>,
qemu-devel@nongnu.org, Kevin O'Connor <kevin@koconnor.net>,
Gerd Hoffmann <kraxel@redhat.com>, Laszlo <lersek@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v4 3/7] Implement fw_cfg DMA interface
Date: Tue, 6 Oct 2015 16:54:24 +0200 [thread overview]
Message-ID: <20151006165424.42126747@markmb_rh> (raw)
In-Reply-To: <20151006144453.GA28347@stefanha-thinkpad.redhat.com>
On Tue, 6 Oct 2015 15:44:53 +0100
Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Thu, Oct 01, 2015 at 02:16:55PM +0200, Marc Marí wrote:
> > @@ -292,6 +307,119 @@ static void fw_cfg_data_mem_write(void
> > *opaque, hwaddr addr, } while (i);
> > }
> >
> > +static void fw_cfg_dma_transfer(FWCfgState *s)
> > +{
> > + dma_addr_t len;
> > + FWCfgDmaAccess dma;
> > + int arch;
> > + FWCfgEntry *e;
> > + int read;
> > + dma_addr_t dma_addr;
> > +
> > + /* Reset the address before the next access */
> > + dma_addr = s->dma_addr;
> > + s->dma_addr = 0;
> > +
> > + dma.address = ldq_be_dma(s->dma_as,
> > + dma_addr + offsetof(FWCfgDmaAccess,
> > address));
> > + dma.length = ldl_be_dma(s->dma_as,
> > + dma_addr + offsetof(FWCfgDmaAccess,
> > length));
> > + dma.control = ldl_be_dma(s->dma_as,
> > + dma_addr + offsetof(FWCfgDmaAccess,
> > control));
>
> ldq_be_dma() doesn't report errors. If dma_addr is invalid the return
> value could be anything. Memory corruption inside the guest is
> possible if the address/length/control values happen to cause a
> memory read operation!
>
> Instead, please use:
>
> if (dma_memory_read(s->dma_as, dma_addr, &dma, sizeof(dma))) {
> stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess,
> control), FW_CFG_DMA_CTL_ERROR);
> return;
> }
>
> dma.address = be64_to_cpu(dma.address);
> dma.length = be32_to_cpu(dma.length);
> dma.control = be32_to_cpu(dma.control);
>
> > +
> > + if (dma.control & FW_CFG_DMA_CTL_SELECT) {
> > + fw_cfg_select(s, dma.control >> 16);
> > + }
> > +
> > + arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
> > + e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
> > +
> > + if (dma.control & FW_CFG_DMA_CTL_READ) {
> > + read = 1;
> > + } else if (dma.control & FW_CFG_DMA_CTL_SKIP) {
> > + read = 0;
> > + } else {
> > + dma.length = 0;
> > + }
> > +
> > + dma.control = 0;
> > +
> > + while (dma.length > 0 && !(dma.control &
> > FW_CFG_DMA_CTL_ERROR)) {
> > + if (s->cur_entry == FW_CFG_INVALID || !e->data ||
> > + s->cur_offset >= e->len) {
> > + len = dma.length;
> > +
> > + /* If the access is not a read access, it will be a
> > skip access,
> > + * tested before.
> > + */
> > + if (read) {
> > + if (dma_memory_set(s->dma_as, dma.address, 0,
> > len)) {
> > + dma.control |= FW_CFG_DMA_CTL_ERROR;
> > + }
> > + }
> > +
> > + } else {
> > + if (dma.length <= (e->len - s->cur_offset)) {
> > + len = dma.length;
> > + } else {
> > + len = (e->len - s->cur_offset);
> > + }
> > +
> > + if (e->read_callback) {
> > + e->read_callback(e->callback_opaque,
> > s->cur_offset);
> > + }
> > +
> > + /* If the access is not a read access, it will be a
> > skip access,
> > + * tested before.
> > + */
> > + if (read) {
> > + if (dma_memory_write(s->dma_as, dma.address,
> > + &e->data[s->cur_offset], len))
> > {
> > + dma.control |= FW_CFG_DMA_CTL_ERROR;
> > + }
> > + }
> > +
> > + s->cur_offset += len;
> > + }
> > +
> > + dma.address += len;
> > + dma.length -= len;
>
> I thought these fields are written back to guest memory? For example,
> so the guest knows how many bytes were read before the error occurred.
This was proposed here:
http://lists.gnu.org/archive/html/qemu-devel/2015-08/msg04001.html
I also don't see much benefit into knowing how many bytes were read. If
the guest is trying to read an invalid entry or past the end of that
entry, the memory will be filled with zeros. The only moment when an
error would be reported is when there's some problem in the mapping.
And this problem is bad enough to just abort the whole operation.
Regards
Marc
next prev parent reply other threads:[~2015-10-06 14:54 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-01 12:14 [Qemu-devel] QEMU fw_cfg DMA interface Marc Marí
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 0/7] " Marc Marí
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 1/7] fw_cfg: document fw_cfg_modify_iXX() update functions Marc Marí
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 2/7] fw_cfg DMA interface documentation Marc Marí
2015-10-01 14:41 ` Laszlo Ersek
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 3/7] Implement fw_cfg DMA interface Marc Marí
2015-10-01 14:36 ` Laszlo Ersek
2015-10-01 15:52 ` Marc Marí
2015-10-01 17:18 ` Peter Maydell
2015-10-01 19:20 ` Laszlo Ersek
2015-10-06 14:44 ` Stefan Hajnoczi
2015-10-06 14:53 ` Peter Maydell
2015-10-08 9:07 ` Stefan Hajnoczi
2015-10-08 10:01 ` Marc Marí
2015-10-06 14:54 ` Marc Marí [this message]
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 4/7] Enable fw_cfg DMA interface for ARM Marc Marí
2015-10-01 14:42 ` Laszlo Ersek
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 5/7] Enable fw_cfg DMA interface for x86 Marc Marí
2015-10-01 14:48 ` Laszlo Ersek
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 6/7] Make the kernel image in the fw_cfg DMA interface bootable Marc Marí
2015-10-01 15:25 ` Laszlo Ersek
2015-10-01 16:02 ` Kevin O'Connor
2015-10-01 16:10 ` Laszlo Ersek
2015-10-01 18:15 ` Marc Marí
2015-10-02 8:16 ` Gerd Hoffmann
2015-10-02 8:24 ` Marc Marí
2015-10-02 9:01 ` Gerd Hoffmann
2015-10-02 11:47 ` Laszlo Ersek
2015-10-02 12:07 ` Gerd Hoffmann
2015-10-02 13:25 ` Laszlo Ersek
2015-10-02 13:30 ` Laszlo Ersek
2015-10-03 0:05 ` Jordan Justen
2015-10-02 13:38 ` Kevin O'Connor
2015-10-05 9:18 ` Gerd Hoffmann
2015-10-02 8:09 ` Gerd Hoffmann
2015-10-02 13:40 ` Kevin O'Connor
2015-10-02 13:50 ` Laszlo Ersek
2015-10-02 15:24 ` Daniel P. Berrange
2015-10-05 9:26 ` Gerd Hoffmann
2015-10-01 12:16 ` [Qemu-devel] [PATCH v4 7/7] fw_cfg: Define a static signature to be returned on DMA port reads Marc Marí
2015-10-01 16:07 ` Laszlo Ersek
2015-10-01 17:02 ` Kevin O'Connor
2015-10-01 17:17 ` Laszlo Ersek
2015-10-01 13:19 ` [Qemu-devel] [PATCH v4 0/7] fw_cfg DMA interface Kevin O'Connor
2015-10-01 16:03 ` [Qemu-devel] QEMU " Eric Blake
2015-10-01 16:11 ` Eric Blake
2015-10-01 16:19 ` Laszlo Ersek
2015-10-01 16:17 ` Laszlo Ersek
2015-10-01 16:21 ` Eric Blake
2015-10-01 16:34 ` Laszlo Ersek
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=20151006165424.42126747@markmb_rh \
--to=markmb@redhat.com \
--cc=drjones@redhat.com \
--cc=kevin@koconnor.net \
--cc=kraxel@redhat.com \
--cc=lersek@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=somlo@cmu.edu \
--cc=stefanha@gmail.com \
/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).