From patchwork Thu Dec 14 17:09:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 848689 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yyL1g5NgRz9sBZ for ; Fri, 15 Dec 2017 04:20:55 +1100 (AEDT) Received: from localhost ([::1]:42178 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePXBl-0007Cy-Pl for incoming@patchwork.ozlabs.org; Thu, 14 Dec 2017 12:20:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55257) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ePX2w-0000PO-6f for qemu-devel@nongnu.org; Thu, 14 Dec 2017 12:11:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ePX2v-0007MY-4N for qemu-devel@nongnu.org; Thu, 14 Dec 2017 12:11:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60550) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ePX2u-0007LF-S7; Thu, 14 Dec 2017 12:11:45 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0AB77C047B94; Thu, 14 Dec 2017 17:11:44 +0000 (UTC) Received: from localhost (ovpn-117-12.ams2.redhat.com [10.36.117.12]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B8DD07C011; Thu, 14 Dec 2017 17:11:41 +0000 (UTC) From: Cornelia Huck To: peter.maydell@linaro.org Date: Thu, 14 Dec 2017 18:09:40 +0100 Message-Id: <20171214171004.25058-23-cohuck@redhat.com> In-Reply-To: <20171214171004.25058-1-cohuck@redhat.com> References: <20171214171004.25058-1-cohuck@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 14 Dec 2017 17:11:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 22/46] s390x/pci: factor out endianess conversion X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, david@redhat.com, Cornelia Huck , Pierre Morel , agraf@suse.de, qemu-devel@nongnu.org, borntraeger@de.ibm.com, qemu-s390x@nongnu.org, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Pierre Morel There are two places where the same endianness conversion is done. Let's factor this out into a static function. Note that the conversion must always be done for data in a register: The S390 BE guest converted date to le before issuing the instruction. After interception in a BE host: ZPCI VFIO using pwrite must make the conversion back for the BE kernel. Kernel will do BE to le translation when loading the register for the real instruction. After interception in a le host: TCG stores a BE register in le, swapping bytes. But since the data in the register was already le it is now BE ZPCI VFIO must convert it to le before writing to the PCI memory. In both cases ZPCI VFIO must swap the bytes from the register. Signed-off-by: Pierre Morel Reviewed-by: Yi Min Zhao Message-Id: <1512046530-17773-2-git-send-email-pmorel@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck --- hw/s390x/s390-pci-inst.c | 58 ++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 6f41083244..cb84d209e0 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -318,6 +318,36 @@ out: return 0; } +/** + * Swap data contained in s390x big endian registers to little endian + * PCI bars. + * + * @ptr: a pointer to a uint64_t data field + * @len: the length of the valid data, must be 1,2,4 or 8 + */ +static int zpci_endian_swap(uint64_t *ptr, uint8_t len) +{ + uint64_t data = *ptr; + + switch (len) { + case 1: + break; + case 2: + data = bswap16(data); + break; + case 4: + data = bswap32(data); + break; + case 8: + data = bswap64(data); + break; + default: + return -EINVAL; + } + *ptr = data; + return 0; +} + int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) { CPUS390XState *env = &cpu->env; @@ -389,19 +419,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) data = pci_host_config_read_common( pbdev->pdev, offset, pci_config_size(pbdev->pdev), len); - switch (len) { - case 1: - break; - case 2: - data = bswap16(data); - break; - case 4: - data = bswap32(data); - break; - case 8: - data = bswap64(data); - break; - default: + if (zpci_endian_swap(&data, len)) { s390_program_interrupt(env, PGM_OPERAND, 4, ra); return 0; } @@ -504,19 +522,7 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) s390_program_interrupt(env, PGM_OPERAND, 4, ra); return 0; } - switch (len) { - case 1: - break; - case 2: - data = bswap16(data); - break; - case 4: - data = bswap32(data); - break; - case 8: - data = bswap64(data); - break; - default: + if (zpci_endian_swap(&data, len)) { s390_program_interrupt(env, PGM_OPERAND, 4, ra); return 0; }