From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40411) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZC4vU-00063M-K6 for qemu-devel@nongnu.org; Mon, 06 Jul 2015 07:51:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZC4vQ-00079C-Hw for qemu-devel@nongnu.org; Mon, 06 Jul 2015 07:51:08 -0400 Received: from mail-vn0-f53.google.com ([209.85.216.53]:37577) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZC4vQ-00078x-Di for qemu-devel@nongnu.org; Mon, 06 Jul 2015 07:51:04 -0400 Received: by vnav203 with SMTP id v203so4105215vna.4 for ; Mon, 06 Jul 2015 04:51:03 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <20150706132538-mutt-send-email-mst@redhat.com> References: <20150702205556-mutt-send-email-mst@redhat.com> <55958AE2.1020600@redhat.com> <20150704230256-mutt-send-email-mst@redhat.com> <559A3246.7020103@redhat.com> <20150706105048-mutt-send-email-mst@redhat.com> <559A4067.3060109@redhat.com> <20150706120539-mutt-send-email-mst@redhat.com> <20150706125811-mutt-send-email-mst@redhat.com> <20150706132538-mutt-send-email-mst@redhat.com> From: Peter Maydell Date: Mon, 6 Jul 2015 12:50:43 +0100 Message-ID: Content-Type: text/plain; charset=UTF-8 Subject: Re: [Qemu-devel] [PATCH] virtio-pci: implement cfg capability List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Michael S. Tsirkin" Cc: Paolo Bonzini , =?UTF-8?Q?Herv=C3=A9_Poussineau?= , QEMU Developers On 6 July 2015 at 11:31, Michael S. Tsirkin wrote: > On Mon, Jul 06, 2015 at 11:04:24AM +0100, Peter Maydell wrote: >> On 6 July 2015 at 11:03, Michael S. Tsirkin wrote: >> > On Mon, Jul 06, 2015 at 10:11:18AM +0100, Peter Maydell wrote: >> >> But address_space_rw() is just the "memcpy bytes to the >> >> target's memory" operation -- if you have a pile of bytes >> >> then there are no endianness concerns. If you don't have >> >> a pile of bytes then you need to know the structure of >> >> the data you're DMAing around, and you should probably >> >> have a loop doing things with the specify-the-width functions. >> >> > Absolutely. But what if DMA happens to target another device >> > and not memory? Device needs some endian-ness so it needs >> > to be converted to that. >> >> Yes, and address_space_rw() already deals with conversion to >> that device's specified endianness. > Yes, but incorrectly if target endian != host endian. > For example, LE target and LE device on BE host. Having walked through the code, got confused, talked to bonzini on IRC about it and got unconfused again, I believe we do get this correct. * address_space_rw() takes a pointer to a pile of bytes * if the destination is RAM, we just memcpy them (because guest RAM is also a pile of bytes) * if the destination is a device, then we read a value out of the pile of bytes at whatever width the target device can handle. The functions we use for this are ldl_q/ldl_p/etc, which do "load target endianness" (ie "interpret this set of 4 bytes as if it were an integer in the target-endianness") because the API of memory_region_dispatch_write() is that it takes a uint64_t data whose contents are the value to write in target endianness order. (This is regrettably undocumented.) * memory_region_dispatch_write() then calls adjust_endianness(), converting a target-endian value to the endianness the device says it requires * we then call the device's read/write functions, whose API is that they get a value in the endianness they asked for. > IO callbacks always get a native endian format so they expect to get > byte 0 of the buffer in MSB on this host. IO callbacks get the format they asked for (which might be BE, LE or target endianness). They will get byte 0 of the buffer in the MSB if they said they were BE devices (or if they said they were target-endian on a BE target). thanks -- PMM