Skip to content

Commit e88a579

Browse files
committed
Merge tag 'pull-request-2025-03-07' of https://gitlab.com/thuth/qemu into staging
* Bug fixes and some small improvements for functional tests * Improve performance of s390x PCI passthrough devices with relaxed translation # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmfK3dsRHHRodXRoQHJl # ZGhhdC5jb20ACgkQLtnXdP5wLbUfDQ/8CopnzCKGKFhyM5skrHbhDbUVbul6yV4L # kIOo7N8OlrNcQB90bj+Udy+mUANHjkmSiBa5lJ/78ej4DFS6CxeVgrl1fSEl36xn # GjWDwSUiN8pG1O4YtnDqWVTBieGSzbkQr1jHgpeAnvv08s+TtmudP1T8IznWU2v9 # FqD78SdebZ0Kua+ksBgMxwkHd6VMw13vsu6KuT9VBhie40LcDrFOuG8RDz/qo4IO # Yg9s1Bqcy7Wa4+0ldMXS1plSdIqJBtVc/HDTg1QwH994b4Lvr7ffrFZmuVcd2dbE # XKQ5jAMOYZqWdlXszkyd8moYGhmevCkQlALhpnbHixnfakfFYX0wTiJB6oCthFQ0 # It0J/ntNsCmJiIHNbPLzsJ1pE5+ureRnGbxVe05n+zfm8MaXL6s4nSdZzHyp8n43 # UZQqVzK55Q34K9O0qoUdCdBCjMKS9v5u95jjJo8+nc8sJoeQTssOoiixwB/E4y21 # 9qSh7CbDjQK4zwuzQ7jKD603zAJH6ivvsHXlMBMXJFBiSMCAoQQ1vyou6yRHswRr # gLHDwiWUx8SX8ckbbJ/+Zo9+T8JBMvC5hNYG8VoAtlTQusG4bHSbKdPNNH0eHsEp # f7RlZPRizkcK3w0Nj+u4kXdnnex3QLLSgnyAYq7zEl6V+mho8KqaBezkO7wQDHZy # +GW5ignQ1Gs= # =CyiZ # -----END PGP SIGNATURE----- # gpg: Signature made Fri 07 Mar 2025 19:51:55 HKT # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "[email protected]" # gpg: Good signature from "Thomas Huth <[email protected]>" [full] # gpg: aka "Thomas Huth <[email protected]>" [full] # gpg: aka "Thomas Huth <[email protected]>" [full] # gpg: aka "Thomas Huth <[email protected]>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2025-03-07' of https://gitlab.com/thuth/qemu: s390x/pci: indicate QEMU supports relaxed translation for passthrough s390x/pci: add support for guests that request direct mapping MAINTAINERS: Add docs/devel/testing/functional.rst to the functional section doc: add missing 'Asset' type in function test doc tests/functional/test_virtio_balloon: Only use KVM for running this test tests/functional: fix race in virtio balloon test tests/functional: Increase the timeout of the mips64el_replay test tests/functional/test_mips_malta: Add a network test via the pcnet NIC tests/functional: Move the code for testing HTTP downloads to a common function tests/functional: stop output from zstd command when uncompressing tests/functional: drop unused 'get_tag' method tests/functional: skip memaddr tests on 32-bit builds tests/functional: reduce tuxrun maxmem to work on 32-bit hosts tests/functional: set 'qemu_bin' as an object level field tests/functional: remove unused 'bin_prefix' variable Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents cfadd79 + d9b5dfc commit e88a579

18 files changed

+197
-60
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4236,6 +4236,7 @@ Functional testing framework
42364236
M: Thomas Huth <[email protected]>
42374237
R: Philippe Mathieu-Daudé <[email protected]>
42384238
R: Daniel P. Berrange <[email protected]>
4239+
F: docs/devel/testing/functional.rst
42394240
F: tests/functional/qemu_test/
42404241

42414242
Windows Hosted Continuous Integration

docs/devel/testing/functional.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ QEMU binary selection
173173
^^^^^^^^^^^^^^^^^^^^^
174174

175175
The QEMU binary used for the ``self.vm`` QEMUMachine instance will
176-
primarily depend on the value of the ``qemu_bin`` class attribute.
176+
primarily depend on the value of the ``qemu_bin`` instance attribute.
177177
If it is not explicitly set by the test code, its default value will
178178
be the result the QEMU_TEST_QEMU_BINARY environment variable.
179179

@@ -251,7 +251,7 @@ Many functional tests download assets (e.g. Linux kernels, initrds,
251251
firmware images, etc.) from the internet to be able to run tests with
252252
them. This imposes additional challenges to the test framework.
253253

254-
First there is the the problem that some people might not have an
254+
First there is the problem that some people might not have an
255255
unconstrained internet connection, so such tests should not be run by
256256
default when running ``make check``. To accomplish this situation,
257257
the tests that download files should only be added to the "thorough"
@@ -274,7 +274,9 @@ the tests are run. This pre-caching is done with the qemu_test.Asset
274274
class. To use it in your test, declare an asset in your test class with
275275
its URL and SHA256 checksum like this::
276276

277-
ASSET_somename = (
277+
from qemu_test import Asset
278+
279+
ASSET_somename = Asset(
278280
('https://www.qemu.org/assets/images/qemu_head_200.png'),
279281
'34b74cad46ea28a2966c1d04e102510daf1fd73e6582b6b74523940d5da029dd')
280282

hw/s390x/s390-pci-bus.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "hw/s390x/s390-pci-inst.h"
1919
#include "hw/s390x/s390-pci-kvm.h"
2020
#include "hw/s390x/s390-pci-vfio.h"
21+
#include "hw/s390x/s390-virtio-ccw.h"
22+
#include "hw/boards.h"
2123
#include "hw/pci/pci_bus.h"
2224
#include "hw/qdev-properties.h"
2325
#include "hw/pci/pci_bridge.h"
@@ -724,12 +726,42 @@ void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
724726
g_free(name);
725727
}
726728

729+
void s390_pci_iommu_direct_map_enable(S390PCIIOMMU *iommu)
730+
{
731+
MachineState *ms = MACHINE(qdev_get_machine());
732+
S390CcwMachineState *s390ms = S390_CCW_MACHINE(ms);
733+
734+
/*
735+
* For direct-mapping we must map the entire guest address space. Rather
736+
* than using an iommu, create a memory region alias that maps GPA X to
737+
* IOVA X + SDMA. VFIO will handle pinning via its memory listener.
738+
*/
739+
g_autofree char *name = g_strdup_printf("iommu-dm-s390-%04x",
740+
iommu->pbdev->uid);
741+
742+
iommu->dm_mr = g_malloc0(sizeof(*iommu->dm_mr));
743+
memory_region_init_alias(iommu->dm_mr, OBJECT(&iommu->mr), name,
744+
get_system_memory(), 0,
745+
s390_get_memory_limit(s390ms));
746+
iommu->enabled = true;
747+
memory_region_add_subregion(&iommu->mr, iommu->pbdev->zpci_fn.sdma,
748+
iommu->dm_mr);
749+
}
750+
727751
void s390_pci_iommu_disable(S390PCIIOMMU *iommu)
728752
{
729753
iommu->enabled = false;
730754
g_hash_table_remove_all(iommu->iotlb);
731-
memory_region_del_subregion(&iommu->mr, MEMORY_REGION(&iommu->iommu_mr));
732-
object_unparent(OBJECT(&iommu->iommu_mr));
755+
if (iommu->dm_mr) {
756+
memory_region_del_subregion(&iommu->mr, iommu->dm_mr);
757+
object_unparent(OBJECT(iommu->dm_mr));
758+
g_free(iommu->dm_mr);
759+
iommu->dm_mr = NULL;
760+
} else {
761+
memory_region_del_subregion(&iommu->mr,
762+
MEMORY_REGION(&iommu->iommu_mr));
763+
object_unparent(OBJECT(&iommu->iommu_mr));
764+
}
733765
}
734766

735767
static void s390_pci_iommu_free(S390pciState *s, PCIBus *bus, int32_t devfn)
@@ -1145,6 +1177,7 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
11451177
/* Always intercept emulated devices */
11461178
pbdev->interp = false;
11471179
pbdev->forwarding_assist = false;
1180+
pbdev->rtr_avail = false;
11481181
}
11491182

11501183
if (s390_pci_msix_init(pbdev) && !pbdev->interp) {
@@ -1511,6 +1544,8 @@ static const Property s390_pci_device_properties[] = {
15111544
DEFINE_PROP_BOOL("interpret", S390PCIBusDevice, interp, true),
15121545
DEFINE_PROP_BOOL("forwarding-assist", S390PCIBusDevice, forwarding_assist,
15131546
true),
1547+
DEFINE_PROP_BOOL("relaxed-translation", S390PCIBusDevice, rtr_avail,
1548+
true),
15141549
};
15151550

15161551
static const VMStateDescription s390_pci_device_vmstate = {

hw/s390x/s390-pci-inst.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "exec/memory.h"
1717
#include "qemu/error-report.h"
1818
#include "system/hw_accel.h"
19+
#include "hw/boards.h"
1920
#include "hw/pci/pci_device.h"
2021
#include "hw/s390x/s390-pci-inst.h"
2122
#include "hw/s390x/s390-pci-bus.h"
@@ -1008,17 +1009,25 @@ static int reg_ioat(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib,
10081009
}
10091010

10101011
/* currently we only support designation type 1 with translation */
1011-
if (!(dt == ZPCI_IOTA_RTTO && t)) {
1012+
if (t && dt != ZPCI_IOTA_RTTO) {
10121013
error_report("unsupported ioat dt %d t %d", dt, t);
10131014
s390_program_interrupt(env, PGM_OPERAND, ra);
10141015
return -EINVAL;
1016+
} else if (!t && !pbdev->rtr_avail) {
1017+
error_report("relaxed translation not allowed");
1018+
s390_program_interrupt(env, PGM_OPERAND, ra);
1019+
return -EINVAL;
10151020
}
10161021

10171022
iommu->pba = pba;
10181023
iommu->pal = pal;
10191024
iommu->g_iota = g_iota;
10201025

1021-
s390_pci_iommu_enable(iommu);
1026+
if (t) {
1027+
s390_pci_iommu_enable(iommu);
1028+
} else {
1029+
s390_pci_iommu_direct_map_enable(iommu);
1030+
}
10221031

10231032
return 0;
10241033
}

hw/s390x/s390-pci-vfio.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,28 @@ static void s390_pci_read_base(S390PCIBusDevice *pbdev,
131131
/* Store function type separately for type-specific behavior */
132132
pbdev->pft = cap->pft;
133133

134+
/*
135+
* If the device is a passthrough ISM device, disallow relaxed
136+
* translation.
137+
*/
138+
if (pbdev->pft == ZPCI_PFT_ISM) {
139+
pbdev->rtr_avail = false;
140+
}
141+
134142
/*
135143
* If appropriate, reduce the size of the supported DMA aperture reported
136-
* to the guest based upon the vfio DMA limit.
144+
* to the guest based upon the vfio DMA limit. This is applicable for
145+
* devices that are guaranteed to not use relaxed translation. If the
146+
* device is capable of relaxed translation then we must advertise the
147+
* full aperture. In this case, if translation is used then we will
148+
* rely on the vfio DMA limit counting and use RPCIT CC1 / status 16
149+
* to request that the guest free DMA mappings as necessary.
137150
*/
138-
vfio_size = pbdev->iommu->max_dma_limit << TARGET_PAGE_BITS;
139-
if (vfio_size > 0 && vfio_size < cap->end_dma - cap->start_dma + 1) {
140-
pbdev->zpci_fn.edma = cap->start_dma + vfio_size - 1;
151+
if (!pbdev->rtr_avail) {
152+
vfio_size = pbdev->iommu->max_dma_limit << TARGET_PAGE_BITS;
153+
if (vfio_size > 0 && vfio_size < cap->end_dma - cap->start_dma + 1) {
154+
pbdev->zpci_fn.edma = cap->start_dma + vfio_size - 1;
155+
}
141156
}
142157
}
143158

@@ -223,8 +238,11 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev,
223238
pbdev->pci_group = s390_group_create(pbdev->zpci_fn.pfgid, start_gid);
224239

225240
resgrp = &pbdev->pci_group->zpci_group;
241+
if (pbdev->rtr_avail) {
242+
resgrp->fr |= CLP_RSP_QPCIG_MASK_RTR;
243+
}
226244
if (cap->flags & VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH) {
227-
resgrp->fr = 1;
245+
resgrp->fr |= CLP_RSP_QPCIG_MASK_REFRESH;
228246
}
229247
resgrp->dasm = cap->dasm;
230248
resgrp->msia = cap->msi_addr;

hw/s390x/s390-virtio-ccw.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,8 +936,13 @@ static void ccw_machine_9_2_instance_options(MachineState *machine)
936936

937937
static void ccw_machine_9_2_class_options(MachineClass *mc)
938938
{
939+
static GlobalProperty compat[] = {
940+
{ TYPE_S390_PCI_DEVICE, "relaxed-translation", "off", },
941+
};
942+
939943
ccw_machine_10_0_class_options(mc);
940944
compat_props_add(mc->compat_props, hw_compat_9_2, hw_compat_9_2_len);
945+
compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
941946
}
942947
DEFINE_CCW_MACHINE(9, 2);
943948

include/hw/s390x/s390-pci-bus.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ struct S390PCIIOMMU {
277277
AddressSpace as;
278278
MemoryRegion mr;
279279
IOMMUMemoryRegion iommu_mr;
280+
MemoryRegion *dm_mr;
280281
bool enabled;
281282
uint64_t g_iota;
282283
uint64_t pba;
@@ -362,6 +363,7 @@ struct S390PCIBusDevice {
362363
bool interp;
363364
bool forwarding_assist;
364365
bool aif;
366+
bool rtr_avail;
365367
QTAILQ_ENTRY(S390PCIBusDevice) link;
366368
};
367369

@@ -389,6 +391,7 @@ int pci_chsc_sei_nt2_have_event(void);
389391
void s390_pci_sclp_configure(SCCB *sccb);
390392
void s390_pci_sclp_deconfigure(SCCB *sccb);
391393
void s390_pci_iommu_enable(S390PCIIOMMU *iommu);
394+
void s390_pci_iommu_direct_map_enable(S390PCIIOMMU *iommu);
392395
void s390_pci_iommu_disable(S390PCIIOMMU *iommu);
393396
void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid,
394397
uint64_t faddr, uint32_t e);

include/hw/s390x/s390-pci-clp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ typedef struct ClpRspQueryPciGrp {
158158
#define CLP_RSP_QPCIG_MASK_NOI 0xfff
159159
uint16_t i;
160160
uint8_t version;
161+
#define CLP_RSP_QPCIG_MASK_RTR 0x20
161162
#define CLP_RSP_QPCIG_MASK_FRAME 0x2
162163
#define CLP_RSP_QPCIG_MASK_REFRESH 0x1
163164
uint8_t fr;

tests/functional/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ test_timeouts = {
3636
'intel_iommu': 300,
3737
'mips_malta' : 120,
3838
'mipsel_replay' : 480,
39+
'mips64el_replay' : 180,
3940
'netdev_ethtool' : 180,
4041
'ppc_40p' : 240,
4142
'ppc64_hv' : 1000,

tests/functional/qemu_test/linuxkernel.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
# This work is licensed under the terms of the GNU GPL, version 2 or
44
# later. See the COPYING file in the top-level directory.
55

6+
import hashlib
7+
import urllib.request
8+
9+
from .cmd import wait_for_console_pattern, exec_command_and_wait_for_pattern
610
from .testcase import QemuSystemTest
7-
from .cmd import wait_for_console_pattern
11+
from .utils import get_usernet_hostfwd_port
812

913

1014
class LinuxKernelTest(QemuSystemTest):
@@ -26,3 +30,23 @@ def launch_kernel(self, kernel, initrd=None, dtb=None, console_index=0,
2630
self.vm.launch()
2731
if wait_for:
2832
self.wait_for_console_pattern(wait_for)
33+
34+
def check_http_download(self, filename, hashsum, guestport=8080,
35+
pythoncmd='python3 -m http.server'):
36+
exec_command_and_wait_for_pattern(self,
37+
f'{pythoncmd} {guestport} & sleep 1',
38+
f'Serving HTTP on 0.0.0.0 port {guestport}')
39+
hl = hashlib.sha256()
40+
hostport = get_usernet_hostfwd_port(self.vm)
41+
url = f'http://localhost:{hostport}{filename}'
42+
self.log.info(f'Downloading {url} ...')
43+
with urllib.request.urlopen(url) as response:
44+
while True:
45+
chunk = response.read(1 << 20)
46+
if not chunk:
47+
break
48+
hl.update(chunk)
49+
50+
digest = hl.hexdigest()
51+
self.log.info(f'sha256sum of download is {digest}.')
52+
self.assertEqual(digest, hashsum)

0 commit comments

Comments
 (0)