[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 1/7] s390x/pci: factor out endianess conversion
From: |
Pierre Morel |
Subject: |
[Qemu-devel] [PATCH v4 1/7] s390x/pci: factor out endianess conversion |
Date: |
Thu, 30 Nov 2017 13:55:24 +0100 |
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 <address@hidden>
Reviewed-by: Yi Min Zhao <address@hidden>
---
hw/s390x/s390-pci-inst.c | 59 +++++++++++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 26 deletions(-)
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 8e088f3..3e1f1a0 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -314,6 +314,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)
{
CPUS390XState *env = &cpu->env;
@@ -385,19 +415,7 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t
r2)
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)) {
program_interrupt(env, PGM_OPERAND, 4);
return 0;
}
@@ -500,19 +518,8 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t
r2)
program_interrupt(env, PGM_OPERAND, 4);
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)) {
program_interrupt(env, PGM_OPERAND, 4);
return 0;
}
--
2.7.4
- [Qemu-devel] [PATCH v4 0/7] s390x/pci: Improve zPCI to cover more cases, Pierre Morel, 2017/11/30
- [Qemu-devel] [PATCH v4 1/7] s390x/pci: factor out endianess conversion,
Pierre Morel <=
- [Qemu-devel] [PATCH v4 2/7] s390x/pci: rework PCI STORE, Pierre Morel, 2017/11/30
- [Qemu-devel] [PATCH v4 3/7] s390x/pci: rework PCI LOAD, Pierre Morel, 2017/11/30
- [Qemu-devel] [PATCH v4 4/7] s390x/pci: rework PCI STORE BLOCK, Pierre Morel, 2017/11/30
- [Qemu-devel] [PATCH v4 6/7] s390x/pci: move the memory region write from pcistg, Pierre Morel, 2017/11/30
- [Qemu-devel] [PATCH v4 7/7] s390x/pci: search for subregion inside the BARs, Pierre Morel, 2017/11/30
- [Qemu-devel] [PATCH v4 5/7] s390x/pci: move the memory region read from pcilg, Pierre Morel, 2017/11/30