From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46105) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YWX3a-0007bM-2U for qemu-devel@nongnu.org; Fri, 13 Mar 2015 17:23:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YWX3W-0001WQ-R0 for qemu-devel@nongnu.org; Fri, 13 Mar 2015 17:23:46 -0400 Received: from e06smtp15.uk.ibm.com ([195.75.94.111]:33227) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YWX3W-0001WF-HB for qemu-devel@nongnu.org; Fri, 13 Mar 2015 17:23:42 -0400 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 13 Mar 2015 21:23:40 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 513A117D8056 for ; Fri, 13 Mar 2015 21:24:02 +0000 (GMT) Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t2DLNdtY62455968 for ; Fri, 13 Mar 2015 21:23:39 GMT Received: from d06av01.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t2DLNdkx026133 for ; Fri, 13 Mar 2015 15:23:39 -0600 From: Greg Kurz Date: Fri, 13 Mar 2015 22:23:37 +0100 Message-ID: <20150313212337.31142.3991.stgit@bahia.local> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] kvm: fix ioeventfd endianness on bi-endian architectures List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini KVM expects host endian values. Hosts that don't use the default endianness need to negate the swap performed in adjust_endianness(). Suggested-by: Paolo Bonzini Signed-off-by: Greg Kurz --- kvm-all.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index cbedc25..1adfef4 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -527,13 +527,33 @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension) return ret; } +static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size) +{ +#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) + /* The kernel expects ioeventfd values in HOST_WORDS_BIGENDIAN + * endianness, but the memory core hands them in target endianness. + * For example, PPC is always treated as big-endian even if running + * on KVM and on PPC64LE. Correct here. + */ + switch(size) { + case 2: + val = bswap16(val); + break; + case 4: + val = bswap32(val); + break; + } +#endif + return val; +} + static int kvm_set_ioeventfd_mmio(int fd, hwaddr addr, uint32_t val, bool assign, uint32_t size, bool datamatch) { int ret; struct kvm_ioeventfd iofd; - iofd.datamatch = datamatch ? val : 0; + iofd.datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0; iofd.addr = addr; iofd.len = size; iofd.flags = 0; @@ -563,7 +583,7 @@ static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val, bool assign, uint32_t size, bool datamatch) { struct kvm_ioeventfd kick = { - .datamatch = datamatch ? val : 0, + .datamatch = datamatch ? adjust_ioeventfd_endianness(val, size) : 0, .addr = addr, .flags = KVM_IOEVENTFD_FLAG_PIO, .len = size,