Browse Source
Farhan Ali's s390x host PCI support for the block/nvme.c driver. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmgcviUACgkQnKSrs4Gr c8hRswgAupxH5Zhx50F7GzwZyu9TCF2sphEPd2VuFVxze8Sg6mXnJq5BFTjv9IuC 0trPppfDyKFKujDk+FA3pl9bT45btm0xctNbFYNRS3HXrVUyMQLy73MlFF2twa5g U3uiX2d7DAYOdi5O1Cn3bhlByDh4qSko7YyUDFKio+WU57cdJxEd+pUqwyVXrU3E AMC2ZmJdKFGGC+tWxBIAuWNc5apq9yzbiywR8z62/Z2IC+Bym0RpvCbdklqcZb8O tpGxDKN8bY6s+hy1NZmA8eBA/iCiu6SUFmNpoe2vSwCFEk9R3gi+UNcuTVt3FaWO lgzoZSOelmI3JkF0UBqvKsPXt3fdJw== =KII7 -----END PGP SIGNATURE----- Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging Pull request Farhan Ali's s390x host PCI support for the block/nvme.c driver. # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmgcviUACgkQnKSrs4Gr # c8hRswgAupxH5Zhx50F7GzwZyu9TCF2sphEPd2VuFVxze8Sg6mXnJq5BFTjv9IuC # 0trPppfDyKFKujDk+FA3pl9bT45btm0xctNbFYNRS3HXrVUyMQLy73MlFF2twa5g # U3uiX2d7DAYOdi5O1Cn3bhlByDh4qSko7YyUDFKio+WU57cdJxEd+pUqwyVXrU3E # AMC2ZmJdKFGGC+tWxBIAuWNc5apq9yzbiywR8z62/Z2IC+Bym0RpvCbdklqcZb8O # tpGxDKN8bY6s+hy1NZmA8eBA/iCiu6SUFmNpoe2vSwCFEk9R3gi+UNcuTVt3FaWO # lgzoZSOelmI3JkF0UBqvKsPXt3fdJw== # =KII7 # -----END PGP SIGNATURE----- # gpg: Signature made Thu 08 May 2025 10:22:29 EDT # gpg: using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [ultimate] # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" [ultimate] # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * tag 'block-pull-request' of https://gitlab.com/stefanha/qemu: block/nvme: Use host PCI MMIO API include: Add a header to define host PCI MMIO functions util: Add functions for s390x mmio read/write Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>pull/291/head
5 changed files with 331 additions and 18 deletions
@ -0,0 +1,136 @@ |
|||
/*
|
|||
* API for host PCI MMIO accesses (e.g. Linux VFIO BARs) |
|||
* |
|||
* Copyright 2025 IBM Corp. |
|||
* Author(s): Farhan Ali <alifm@linux.ibm.com> |
|||
* |
|||
* SPDX-License-Identifier: GPL-2.0-or-later |
|||
*/ |
|||
|
|||
#ifndef HOST_PCI_MMIO_H |
|||
#define HOST_PCI_MMIO_H |
|||
|
|||
#include "qemu/bswap.h" |
|||
#include "qemu/s390x_pci_mmio.h" |
|||
|
|||
static inline uint8_t host_pci_ldub_p(const void *ioaddr) |
|||
{ |
|||
uint8_t ret = 0; |
|||
#ifdef __s390x__ |
|||
ret = s390x_pci_mmio_read_8(ioaddr); |
|||
#else |
|||
ret = ldub_p(ioaddr); |
|||
#endif |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
static inline uint16_t host_pci_lduw_le_p(const void *ioaddr) |
|||
{ |
|||
uint16_t ret = 0; |
|||
#ifdef __s390x__ |
|||
ret = le16_to_cpu(s390x_pci_mmio_read_16(ioaddr)); |
|||
#else |
|||
ret = lduw_le_p(ioaddr); |
|||
#endif |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
static inline uint32_t host_pci_ldl_le_p(const void *ioaddr) |
|||
{ |
|||
uint32_t ret = 0; |
|||
#ifdef __s390x__ |
|||
ret = le32_to_cpu(s390x_pci_mmio_read_32(ioaddr)); |
|||
#else |
|||
ret = ldl_le_p(ioaddr); |
|||
#endif |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
static inline uint64_t host_pci_ldq_le_p(const void *ioaddr) |
|||
{ |
|||
uint64_t ret = 0; |
|||
#ifdef __s390x__ |
|||
ret = le64_to_cpu(s390x_pci_mmio_read_64(ioaddr)); |
|||
#else |
|||
ret = ldq_le_p(ioaddr); |
|||
#endif |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
static inline void host_pci_stb_p(void *ioaddr, uint8_t val) |
|||
{ |
|||
#ifdef __s390x__ |
|||
s390x_pci_mmio_write_8(ioaddr, val); |
|||
#else |
|||
stb_p(ioaddr, val); |
|||
#endif |
|||
} |
|||
|
|||
static inline void host_pci_stw_le_p(void *ioaddr, uint16_t val) |
|||
{ |
|||
#ifdef __s390x__ |
|||
s390x_pci_mmio_write_16(ioaddr, cpu_to_le16(val)); |
|||
#else |
|||
stw_le_p(ioaddr, val); |
|||
#endif |
|||
} |
|||
|
|||
static inline void host_pci_stl_le_p(void *ioaddr, uint32_t val) |
|||
{ |
|||
#ifdef __s390x__ |
|||
s390x_pci_mmio_write_32(ioaddr, cpu_to_le32(val)); |
|||
#else |
|||
stl_le_p(ioaddr, val); |
|||
#endif |
|||
} |
|||
|
|||
static inline void host_pci_stq_le_p(void *ioaddr, uint64_t val) |
|||
{ |
|||
#ifdef __s390x__ |
|||
s390x_pci_mmio_write_64(ioaddr, cpu_to_le64(val)); |
|||
#else |
|||
stq_le_p(ioaddr, val); |
|||
#endif |
|||
} |
|||
|
|||
static inline uint64_t host_pci_ldn_le_p(const void *ioaddr, int sz) |
|||
{ |
|||
switch (sz) { |
|||
case 1: |
|||
return host_pci_ldub_p(ioaddr); |
|||
case 2: |
|||
return host_pci_lduw_le_p(ioaddr); |
|||
case 4: |
|||
return host_pci_ldl_le_p(ioaddr); |
|||
case 8: |
|||
return host_pci_ldq_le_p(ioaddr); |
|||
default: |
|||
g_assert_not_reached(); |
|||
} |
|||
} |
|||
|
|||
static inline void host_pci_stn_le_p(void *ioaddr, int sz, uint64_t v) |
|||
{ |
|||
switch (sz) { |
|||
case 1: |
|||
host_pci_stb_p(ioaddr, v); |
|||
break; |
|||
case 2: |
|||
host_pci_stw_le_p(ioaddr, v); |
|||
break; |
|||
case 4: |
|||
host_pci_stl_le_p(ioaddr, v); |
|||
break; |
|||
case 8: |
|||
host_pci_stq_le_p(ioaddr, v); |
|||
break; |
|||
default: |
|||
g_assert_not_reached(); |
|||
} |
|||
} |
|||
|
|||
#endif |
|||
@ -0,0 +1,24 @@ |
|||
/*
|
|||
* s390x PCI MMIO definitions |
|||
* |
|||
* Copyright 2025 IBM Corp. |
|||
* Author(s): Farhan Ali <alifm@linux.ibm.com> |
|||
* |
|||
* SPDX-License-Identifier: GPL-2.0-or-later |
|||
*/ |
|||
#ifndef S390X_PCI_MMIO_H |
|||
#define S390X_PCI_MMIO_H |
|||
|
|||
#ifdef __s390x__ |
|||
uint8_t s390x_pci_mmio_read_8(const void *ioaddr); |
|||
uint16_t s390x_pci_mmio_read_16(const void *ioaddr); |
|||
uint32_t s390x_pci_mmio_read_32(const void *ioaddr); |
|||
uint64_t s390x_pci_mmio_read_64(const void *ioaddr); |
|||
|
|||
void s390x_pci_mmio_write_8(void *ioaddr, uint8_t val); |
|||
void s390x_pci_mmio_write_16(void *ioaddr, uint16_t val); |
|||
void s390x_pci_mmio_write_32(void *ioaddr, uint32_t val); |
|||
void s390x_pci_mmio_write_64(void *ioaddr, uint64_t val); |
|||
#endif /* __s390x__ */ |
|||
|
|||
#endif /* S390X_PCI_MMIO_H */ |
|||
@ -0,0 +1,146 @@ |
|||
/*
|
|||
* s390x PCI MMIO definitions |
|||
* |
|||
* Copyright 2025 IBM Corp. |
|||
* Author(s): Farhan Ali <alifm@linux.ibm.com> |
|||
* |
|||
* SPDX-License-Identifier: GPL-2.0-or-later |
|||
*/ |
|||
|
|||
#include "qemu/osdep.h" |
|||
#include <sys/syscall.h> |
|||
#include "qemu/s390x_pci_mmio.h" |
|||
#include "elf.h" |
|||
|
|||
union register_pair { |
|||
unsigned __int128 pair; |
|||
struct { |
|||
uint64_t even; |
|||
uint64_t odd; |
|||
}; |
|||
}; |
|||
|
|||
static bool is_mio_supported; |
|||
|
|||
static __attribute__((constructor)) void check_is_mio_supported(void) |
|||
{ |
|||
is_mio_supported = !!(qemu_getauxval(AT_HWCAP) & HWCAP_S390_PCI_MIO); |
|||
} |
|||
|
|||
static uint64_t s390x_pcilgi(const void *ioaddr, size_t len) |
|||
{ |
|||
union register_pair ioaddr_len = { .even = (uint64_t)ioaddr, |
|||
.odd = len }; |
|||
uint64_t val; |
|||
int cc; |
|||
|
|||
asm volatile( |
|||
/* pcilgi */ |
|||
".insn rre,0xb9d60000,%[val],%[ioaddr_len]\n" |
|||
"ipm %[cc]\n" |
|||
"srl %[cc],28\n" |
|||
: [cc] "=d"(cc), [val] "=d"(val), |
|||
[ioaddr_len] "+d"(ioaddr_len.pair) :: "cc"); |
|||
|
|||
if (cc) { |
|||
val = -1ULL; |
|||
} |
|||
|
|||
return val; |
|||
} |
|||
|
|||
static void s390x_pcistgi(void *ioaddr, uint64_t val, size_t len) |
|||
{ |
|||
union register_pair ioaddr_len = {.even = (uint64_t)ioaddr, .odd = len}; |
|||
|
|||
asm volatile ( |
|||
/* pcistgi */ |
|||
".insn rre,0xb9d40000,%[val],%[ioaddr_len]\n" |
|||
: [ioaddr_len] "+d" (ioaddr_len.pair) |
|||
: [val] "d" (val) |
|||
: "cc", "memory"); |
|||
} |
|||
|
|||
uint8_t s390x_pci_mmio_read_8(const void *ioaddr) |
|||
{ |
|||
uint8_t val = 0; |
|||
|
|||
if (is_mio_supported) { |
|||
val = s390x_pcilgi(ioaddr, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_read, ioaddr, &val, sizeof(val)); |
|||
} |
|||
return val; |
|||
} |
|||
|
|||
uint16_t s390x_pci_mmio_read_16(const void *ioaddr) |
|||
{ |
|||
uint16_t val = 0; |
|||
|
|||
if (is_mio_supported) { |
|||
val = s390x_pcilgi(ioaddr, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_read, ioaddr, &val, sizeof(val)); |
|||
} |
|||
return val; |
|||
} |
|||
|
|||
uint32_t s390x_pci_mmio_read_32(const void *ioaddr) |
|||
{ |
|||
uint32_t val = 0; |
|||
|
|||
if (is_mio_supported) { |
|||
val = s390x_pcilgi(ioaddr, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_read, ioaddr, &val, sizeof(val)); |
|||
} |
|||
return val; |
|||
} |
|||
|
|||
uint64_t s390x_pci_mmio_read_64(const void *ioaddr) |
|||
{ |
|||
uint64_t val = 0; |
|||
|
|||
if (is_mio_supported) { |
|||
val = s390x_pcilgi(ioaddr, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_read, ioaddr, &val, sizeof(val)); |
|||
} |
|||
return val; |
|||
} |
|||
|
|||
void s390x_pci_mmio_write_8(void *ioaddr, uint8_t val) |
|||
{ |
|||
if (is_mio_supported) { |
|||
s390x_pcistgi(ioaddr, val, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_write, ioaddr, &val, sizeof(val)); |
|||
} |
|||
} |
|||
|
|||
void s390x_pci_mmio_write_16(void *ioaddr, uint16_t val) |
|||
{ |
|||
if (is_mio_supported) { |
|||
s390x_pcistgi(ioaddr, val, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_write, ioaddr, &val, sizeof(val)); |
|||
} |
|||
} |
|||
|
|||
void s390x_pci_mmio_write_32(void *ioaddr, uint32_t val) |
|||
{ |
|||
if (is_mio_supported) { |
|||
s390x_pcistgi(ioaddr, val, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_write, ioaddr, &val, sizeof(val)); |
|||
} |
|||
} |
|||
|
|||
void s390x_pci_mmio_write_64(void *ioaddr, uint64_t val) |
|||
{ |
|||
if (is_mio_supported) { |
|||
s390x_pcistgi(ioaddr, val, sizeof(val)); |
|||
} else { |
|||
syscall(__NR_s390_pci_mmio_write, ioaddr, &val, sizeof(val)); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue