From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59228) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WxE9Y-0001rE-Ti for qemu-devel@nongnu.org; Wed, 18 Jun 2014 07:35:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WxE9P-0005Nm-Dj for qemu-devel@nongnu.org; Wed, 18 Jun 2014 07:35:44 -0400 Received: from e23smtp06.au.ibm.com ([202.81.31.148]:54237) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WxE9O-0005NI-Ld for qemu-devel@nongnu.org; Wed, 18 Jun 2014 07:35:35 -0400 Received: from /spool/local by e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 18 Jun 2014 21:35:30 +1000 Received: from d23relay03.au.ibm.com (d23relay03.au.ibm.com [9.190.235.21]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id 08C2F2CE8047 for ; Wed, 18 Jun 2014 21:35:27 +1000 (EST) Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97]) by d23relay03.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s5IBZ9Lg11862292 for ; Wed, 18 Jun 2014 21:35:11 +1000 Received: from d23av03.au.ibm.com (localhost [127.0.0.1]) by d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s5IBZO8A015283 for ; Wed, 18 Jun 2014 21:35:24 +1000 From: Alexey Kardashevskiy Date: Wed, 18 Jun 2014 21:35:21 +1000 Message-Id: <1403091321-31721-1-git-send-email-aik@ozlabs.ru> Subject: [Qemu-devel] [PATCH] vfio: Make BARs native endian List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Alexey Kardashevskiy , Alex Williamson , Alexander Graf , Nikunj A Dadhania Slow BAR access path is used when VFIO fails to mmap() BAR or TCG is used. Since this is just a transport between the guest and a device, there is no need to do endianness swapping. This changes BARs to use native endianness. Since non-ROM BARs were doing byte swapping, we need to remove it so does the patch. No change in behavior is expected though. ROM BARs were declared little endian but byte swapping was not implemented for them so they never actually worked on big endian systems. This fixes endiannes for ROM BARs: this declares them native endian and fixes access sizes. Signed-off-by: Alexey Kardashevskiy --- hw/misc/vfio.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 7437c2e..3eb3c71 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -1052,10 +1052,10 @@ static void vfio_bar_write(void *opaque, hwaddr addr, buf.byte = data; break; case 2: - buf.word = cpu_to_le16(data); + buf.word = data; break; case 4: - buf.dword = cpu_to_le32(data); + buf.dword = data; break; default: hw_error("vfio: unsupported write size, %d bytes", size); @@ -1112,10 +1112,10 @@ static uint64_t vfio_bar_read(void *opaque, data = buf.byte; break; case 2: - data = le16_to_cpu(buf.word); + data = buf.word; break; case 4: - data = le32_to_cpu(buf.dword); + data = buf.dword; break; default: hw_error("vfio: unsupported read size, %d bytes", size); @@ -1142,7 +1142,7 @@ static uint64_t vfio_bar_read(void *opaque, static const MemoryRegionOps vfio_bar_ops = { .read = vfio_bar_read, .write = vfio_bar_write, - .endianness = DEVICE_LITTLE_ENDIAN, + .endianness = DEVICE_NATIVE_ENDIAN, }; static void vfio_pci_load_rom(VFIODevice *vdev) @@ -1204,21 +1204,42 @@ static void vfio_pci_load_rom(VFIODevice *vdev) static uint64_t vfio_rom_read(void *opaque, hwaddr addr, unsigned size) { VFIODevice *vdev = opaque; - uint64_t val = ((uint64_t)1 << (size * 8)) - 1; + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + uint64_t qword; + } buf; + uint64_t data = 0; /* Load the ROM lazily when the guest tries to read it */ if (unlikely(!vdev->rom && !vdev->rom_read_failed)) { vfio_pci_load_rom(vdev); } - memcpy(&val, vdev->rom + addr, + memcpy(&buf, vdev->rom + addr, (addr < vdev->rom_size) ? MIN(size, vdev->rom_size - addr) : 0); + switch (size) { + case 1: + data = buf.byte; + break; + case 2: + data = buf.word; + break; + case 4: + data = buf.dword; + break; + default: + hw_error("vfio: unsupported read size, %d bytes", size); + break; + } + DPRINTF("%s(%04x:%02x:%02x.%x, 0x%"HWADDR_PRIx", 0x%x) = 0x%"PRIx64"\n", __func__, vdev->host.domain, vdev->host.bus, vdev->host.slot, - vdev->host.function, addr, size, val); + vdev->host.function, addr, size, data); - return val; + return data; } static void vfio_rom_write(void *opaque, hwaddr addr, @@ -1229,7 +1250,7 @@ static void vfio_rom_write(void *opaque, hwaddr addr, static const MemoryRegionOps vfio_rom_ops = { .read = vfio_rom_read, .write = vfio_rom_write, - .endianness = DEVICE_LITTLE_ENDIAN, + .endianness = DEVICE_NATIVE_ENDIAN, }; static bool vfio_blacklist_opt_rom(VFIODevice *vdev) -- 2.0.0