aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-12-04 08:02:37 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2023-12-04 08:02:37 -0500
commit173e8280643ad3b7221b12a8deafce826f5e7efb (patch)
treed8bb8b3ec5b4348743f5f0bdd62ac33a7e742ac4
parent019f8c19df054fe14f18495bb95571c10cc0bf69 (diff)
parent95e1019a4a9b4b6e2caeb3fd392525e522a747db (diff)
downloadqemu-173e8280643ad3b7221b12a8deafce826f5e7efb.zip
qemu-173e8280643ad3b7221b12a8deafce826f5e7efb.tar.gz
qemu-173e8280643ad3b7221b12a8deafce826f5e7efb.tar.bz2
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pc,pci: features, cleanups, fixes misc fixes, cleanups Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmVrmhwPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRp/XsH/05hHtQqO+EnKSAW5SEwZnlLfzDcajVVPIkT # h6Yf6ahHNf4hG1qqa2CICqJtDAOQYamO128QjZdQxsnYejwBmZ/oG//neWh6qLPV # Hp4AaKV2MjKRQZPNblnrGUirxkSWSTqIONXp4FsVVpKOKW9IX5f9tH6nyFAqXWX7 # KzNY/3KD1CVSwAV1+hY2c6OzWVdTSJykPRocfB0jTYY1RygI0t57Hiq7v8AliGAx # 7ktSJFD9MBr+4Un7CQZWp24eyrL77j8U+YQRlPVYupkmQyuXHPdBr4RruHcGupIy # GeIvbkX1mTCEfOd/HFQ1X41hpf8AEyZjjq2SOEBncIRWY6EhSio= # =opjy # -----END PGP SIGNATURE----- # gpg: Signature made Sat 02 Dec 2023 15:57:00 EST # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: vhost-user-scsi: free the inflight area when reset vhost-user: fix the reconnect error msix: unset PCIDevice::msix_vector_poll_notifier in rollback virtio-iommu: Remove useless !sdev check in virtio_iommu_probe() hw/i386: fix short-circuit logic with non-optimizing builds hw/acpi/erst: Do not ignore Error* in realize handler pcie_sriov: Remove g_new assertion virtio-sound: add realize() error cleanup path virtio-snd: check AUD_register_card return value hw/audio/hda-codec: reenable the audio mixer hw/audio/hda-codec: fix multiplication overflow hw/audio/virtio-snd-pci: fix the PCI class code tests/acpi/bios-tables-test: do not write new blobs unless there are changes netdev: set timeout depending on loadavg osdep: add getloadavg Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--hw/acpi/erst.c10
-rw-r--r--hw/audio/hda-codec.c41
-rw-r--r--hw/audio/virtio-snd-pci.c2
-rw-r--r--hw/audio/virtio-snd.c43
-rw-r--r--hw/block/vhost-user-blk.c8
-rw-r--r--hw/i386/x86.c15
-rw-r--r--hw/pci/msix.c1
-rw-r--r--hw/pci/pcie_sriov.c1
-rw-r--r--hw/scsi/vhost-user-scsi.c19
-rw-r--r--hw/virtio/vhost-user-gpio.c3
-rw-r--r--hw/virtio/virtio-iommu.c3
-rw-r--r--hw/virtio/virtio.c2
-rw-r--r--include/qemu/osdep.h10
-rw-r--r--meson.build1
-rw-r--r--tests/qtest/bios-tables-test.c14
-rw-r--r--tests/qtest/netdev-socket.c28
16 files changed, 152 insertions, 49 deletions
diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
index 35007d8..ba751dc 100644
--- a/hw/acpi/erst.c
+++ b/hw/acpi/erst.c
@@ -947,6 +947,7 @@ static const VMStateDescription erst_vmstate = {
static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
{
+ ERRP_GUARD();
ERSTDeviceState *s = ACPIERST(pci_dev);
trace_acpi_erst_realizefn_in();
@@ -964,9 +965,15 @@ static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
/* HostMemoryBackend size will be multiple of PAGE_SIZE */
s->storage_size = object_property_get_int(OBJECT(s->hostmem), "size", errp);
+ if (*errp) {
+ return;
+ }
/* Initialize backend storage and record_count */
check_erst_backend_storage(s, errp);
+ if (*errp) {
+ return;
+ }
/* BAR 0: Programming registers */
memory_region_init_io(&s->iomem_mr, OBJECT(pci_dev), &erst_reg_ops, s,
@@ -977,6 +984,9 @@ static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
memory_region_init_ram(&s->exchange_mr, OBJECT(pci_dev),
"erst.exchange",
le32_to_cpu(s->header->record_size), errp);
+ if (*errp) {
+ return;
+ }
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
&s->exchange_mr);
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index b9ad1f4..0bc20d4 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -22,6 +22,7 @@
#include "hw/qdev-properties.h"
#include "intel-hda.h"
#include "migration/vmstate.h"
+#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "intel-hda-defs.h"
#include "audio/audio.h"
@@ -189,9 +190,9 @@ struct HDAAudioState {
bool use_timer;
};
-static inline int64_t hda_bytes_per_second(HDAAudioStream *st)
+static inline uint32_t hda_bytes_per_second(HDAAudioStream *st)
{
- return 2LL * st->as.nchannels * st->as.freq;
+ return 2 * (uint32_t)st->as.nchannels * (uint32_t)st->as.freq;
}
static inline void hda_timer_sync_adjust(HDAAudioStream *st, int64_t target_pos)
@@ -222,12 +223,18 @@ static void hda_audio_input_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t buft_start = st->buft_start;
+ int64_t uptime = now - st->buft_start;
int64_t wpos = st->wpos;
int64_t rpos = st->rpos;
+ int64_t wanted_rpos;
- int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start)
- / NANOSECONDS_PER_SECOND;
+ if (uptime <= 0) {
+ /* wanted_rpos <= 0 */
+ goto out_timer;
+ }
+
+ wanted_rpos = muldiv64(uptime, hda_bytes_per_second(st),
+ NANOSECONDS_PER_SECOND);
wanted_rpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_rpos <= rpos) {
@@ -286,12 +293,18 @@ static void hda_audio_output_timer(void *opaque)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int64_t buft_start = st->buft_start;
+ int64_t uptime = now - st->buft_start;
int64_t wpos = st->wpos;
int64_t rpos = st->rpos;
+ int64_t wanted_wpos;
+
+ if (uptime <= 0) {
+ /* wanted_wpos <= 0 */
+ goto out_timer;
+ }
- int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start)
- / NANOSECONDS_PER_SECOND;
+ wanted_wpos = muldiv64(uptime, hda_bytes_per_second(st),
+ NANOSECONDS_PER_SECOND);
wanted_wpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_wpos <= wpos) {
@@ -855,10 +868,10 @@ static Property hda_audio_properties[] = {
static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
- const struct desc_codec *desc = &output_nomixemu;
+ const struct desc_codec *desc = &output_mixemu;
if (!a->mixer) {
- desc = &output_mixemu;
+ desc = &output_nomixemu;
}
hda_audio_init(hda, desc, errp);
@@ -867,10 +880,10 @@ static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
- const struct desc_codec *desc = &duplex_nomixemu;
+ const struct desc_codec *desc = &duplex_mixemu;
if (!a->mixer) {
- desc = &duplex_mixemu;
+ desc = &duplex_nomixemu;
}
hda_audio_init(hda, desc, errp);
@@ -879,10 +892,10 @@ static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
static void hda_audio_init_micro(HDACodecDevice *hda, Error **errp)
{
HDAAudioState *a = HDA_AUDIO(hda);
- const struct desc_codec *desc = &micro_nomixemu;
+ const struct desc_codec *desc = &micro_mixemu;
if (!a->mixer) {
- desc = &micro_mixemu;
+ desc = &micro_nomixemu;
}
hda_audio_init(hda, desc, errp);
diff --git a/hw/audio/virtio-snd-pci.c b/hw/audio/virtio-snd-pci.c
index 0f92e07..ab58c64 100644
--- a/hw/audio/virtio-snd-pci.c
+++ b/hw/audio/virtio-snd-pci.c
@@ -47,12 +47,14 @@ static void virtio_snd_pci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);
+ PCIDeviceClass *pcidevklass = PCI_DEVICE_CLASS(klass);
device_class_set_props(dc, virtio_snd_pci_properties);
dc->desc = "Virtio Sound";
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
vpciklass->realize = virtio_snd_pci_realize;
+ pcidevklass->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
}
static void virtio_snd_pci_instance_init(Object *obj)
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 2fe966e..3c9f94e 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -36,6 +36,7 @@ static void virtio_snd_pcm_out_cb(void *data, int available);
static void virtio_snd_process_cmdq(VirtIOSound *s);
static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream);
static void virtio_snd_pcm_in_cb(void *data, int available);
+static void virtio_snd_unrealize(DeviceState *dev);
static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8)
| BIT(VIRTIO_SND_PCM_FMT_U8)
@@ -1065,23 +1066,9 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
virtio_snd_pcm_set_params default_params = { 0 };
uint32_t status;
- vsnd->pcm = NULL;
- vsnd->vmstate =
- qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
-
trace_virtio_snd_realize(vsnd);
- vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
- vsnd->pcm->snd = vsnd;
- vsnd->pcm->streams =
- g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
- vsnd->pcm->pcm_params =
- g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
-
- virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
- virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
-
- /* set number of jacks and streams */
+ /* check number of jacks and streams */
if (vsnd->snd_conf.jacks > 8) {
error_setg(errp,
"Invalid number of jacks: %"PRIu32,
@@ -1102,7 +1089,22 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
return;
}
- AUD_register_card("virtio-sound", &vsnd->card, errp);
+ if (!AUD_register_card("virtio-sound", &vsnd->card, errp)) {
+ return;
+ }
+
+ vsnd->vmstate =
+ qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
+
+ vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
+ vsnd->pcm->snd = vsnd;
+ vsnd->pcm->streams =
+ g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
+ vsnd->pcm->pcm_params =
+ g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
+
+ virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
+ virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
/* set default params for all streams */
default_params.features = 0;
@@ -1128,16 +1130,21 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
error_setg(errp,
"Can't initialize stream params, device responded with %s.",
print_code(status));
- return;
+ goto error_cleanup;
}
status = virtio_snd_pcm_prepare(vsnd, i);
if (status != cpu_to_le32(VIRTIO_SND_S_OK)) {
error_setg(errp,
"Can't prepare streams, device responded with %s.",
print_code(status));
- return;
+ goto error_cleanup;
}
}
+
+ return;
+
+error_cleanup:
+ virtio_snd_unrealize(dev);
}
static inline void return_tx_buffer(VirtIOSoundPCMStream *stream,
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 818b833..2863d80 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -326,7 +326,6 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
if (s->connected) {
return 0;
}
- s->connected = true;
s->dev.num_queues = s->num_queues;
s->dev.nvqs = s->num_queues;
@@ -343,15 +342,14 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
return ret;
}
+ s->connected = true;
+
/* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) {
ret = vhost_user_blk_start(vdev, errp);
- if (ret < 0) {
- return ret;
- }
}
- return 0;
+ return ret;
}
static void vhost_user_blk_disconnect(DeviceState *dev)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index b3d0548..2b6291a 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -131,8 +131,12 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version)
/*
* Can we support APIC ID 255 or higher? With KVM, that requires
* both in-kernel lapic and X2APIC userspace API.
+ *
+ * kvm_enabled() must go first to ensure that kvm_* references are
+ * not emitted for the linker to consume (kvm_enabled() is
+ * a literal `0` in configurations where kvm_* aren't defined)
*/
- if (x86ms->apic_id_limit > 255 && kvm_enabled() &&
+ if (kvm_enabled() && x86ms->apic_id_limit > 255 &&
(!kvm_irqchip_in_kernel() || !kvm_enable_x2apic())) {
error_report("current -smp configuration requires kernel "
"irqchip and X2APIC API support.");
@@ -418,8 +422,13 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
}
cpu->thread_id = topo_ids.smt_id;
- if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) &&
- kvm_enabled() && !kvm_hv_vpindex_settable()) {
+ /*
+ * kvm_enabled() must go first to ensure that kvm_* references are
+ * not emitted for the linker to consume (kvm_enabled() is
+ * a literal `0` in configurations where kvm_* aren't defined)
+ */
+ if (kvm_enabled() && hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) &&
+ !kvm_hv_vpindex_settable()) {
error_setg(errp, "kernel doesn't allow setting HyperV VP_INDEX");
return;
}
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index ab8869d..cd817f4 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -648,6 +648,7 @@ undo:
}
dev->msix_vector_use_notifier = NULL;
dev->msix_vector_release_notifier = NULL;
+ dev->msix_vector_poll_notifier = NULL;
return ret;
}
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 5ef8950..a1fe65f 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -178,7 +178,6 @@ static void register_vfs(PCIDevice *dev)
num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
dev->exp.sriov_pf.vf = g_new(PCIDevice *, num_vfs);
- assert(dev->exp.sriov_pf.vf);
trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), num_vfs);
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 4486500c..780f105 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -147,7 +147,6 @@ static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
if (s->connected) {
return 0;
}
- s->connected = true;
vsc->dev.num_queues = vs->conf.num_queues;
vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
@@ -161,6 +160,8 @@ static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
return ret;
}
+ s->connected = true;
+
/* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) {
ret = vhost_user_scsi_start(s, errp);
@@ -359,6 +360,20 @@ static Property vhost_user_scsi_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static void vhost_user_scsi_reset(VirtIODevice *vdev)
+{
+ VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
+ VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+
+ vhost_dev_free_inflight(vsc->inflight);
+}
+
+static struct vhost_dev *vhost_user_scsi_get_vhost(VirtIODevice *vdev)
+{
+ VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev);
+ return &vsc->dev;
+}
+
static const VMStateDescription vmstate_vhost_scsi = {
.name = "virtio-scsi",
.minimum_version_id = 1,
@@ -384,6 +399,8 @@ static void vhost_user_scsi_class_init(ObjectClass *klass, void *data)
vdc->set_config = vhost_scsi_common_set_config;
vdc->set_status = vhost_user_scsi_set_status;
fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path;
+ vdc->reset = vhost_user_scsi_reset;
+ vdc->get_vhost = vhost_user_scsi_get_vhost;
}
static void vhost_user_scsi_instance_init(Object *obj)
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index aff2d7e..a83437a 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -229,7 +229,6 @@ static int vu_gpio_connect(DeviceState *dev, Error **errp)
if (gpio->connected) {
return 0;
}
- gpio->connected = true;
vhost_dev_set_config_notifier(vhost_dev, &gpio_ops);
gpio->vhost_user.supports_config = true;
@@ -243,6 +242,8 @@ static int vu_gpio_connect(DeviceState *dev, Error **errp)
return ret;
}
+ gpio->connected = true;
+
/* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) {
vu_gpio_start(vdev);
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 89fb576..9d463ef 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -698,9 +698,6 @@ static int virtio_iommu_probe(VirtIOIOMMU *s,
}
sdev = container_of(iommu_mr, IOMMUDevice, iommu_mr);
- if (!sdev) {
- return -EINVAL;
- }
count = virtio_iommu_fill_resv_mem_prop(sdev, ep_id, buf, free);
if (count < 0) {
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index e510557..3a160f8 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2137,7 +2137,7 @@ void virtio_reset(void *opaque)
vdev->device_endian = virtio_default_endian();
}
- if (vdev->vhost_started) {
+ if (vdev->vhost_started && k->get_vhost) {
vhost_reset_device(k->get_vhost(vdev));
}
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 475a1c6..d30ba73 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -779,6 +779,16 @@ static inline int platform_does_not_support_system(const char *command)
}
#endif /* !HAVE_SYSTEM_FUNCTION */
+/**
+ * If the load average was unobtainable, -1 is returned
+ */
+#ifndef HAVE_GETLOADAVG_FUNCTION
+static inline int getloadavg(double loadavg[], int nelem)
+{
+ return -1;
+}
+#endif /* !HAVE_GETLOADAVG_FUNCTION */
+
#ifdef __cplusplus
}
#endif
diff --git a/meson.build b/meson.build
index ec01f8b..d2c4c2a 100644
--- a/meson.build
+++ b/meson.build
@@ -2293,6 +2293,7 @@ config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
+config_host_data.set('HAVE_GETLOADAVG_FUNCTION', cc.has_function('getloadavg', prefix: '#include <stdlib.h>'))
if rbd.found()
config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
cc.has_function('rbd_namespace_exists',
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 71af5cf..fe6a9a8 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -112,6 +112,7 @@ static const char *iasl;
#endif
static int verbosity_level;
+static GArray *load_expected_aml(test_data *data);
static bool compare_signature(const AcpiSdtTable *sdt, const char *signature)
{
@@ -244,21 +245,32 @@ static void test_acpi_fadt_table(test_data *data)
static void dump_aml_files(test_data *data, bool rebuild)
{
- AcpiSdtTable *sdt;
+ AcpiSdtTable *sdt, *exp_sdt;
GError *error = NULL;
gchar *aml_file = NULL;
+ test_data exp_data = {};
gint fd;
ssize_t ret;
int i;
+ exp_data.tables = load_expected_aml(data);
for (i = 0; i < data->tables->len; ++i) {
const char *ext = data->variant ? data->variant : "";
sdt = &g_array_index(data->tables, AcpiSdtTable, i);
+ exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i);
g_assert(sdt->aml);
+ g_assert(exp_sdt->aml);
if (rebuild) {
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
sdt->aml, ext);
+ if (!g_file_test(aml_file, G_FILE_TEST_EXISTS) &&
+ sdt->aml_len == exp_sdt->aml_len &&
+ !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) {
+ /* identical tables, no need to write new files */
+ g_free(aml_file);
+ continue;
+ }
fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
if (fd < 0) {
diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
index 7ba1eff..bb99d08 100644
--- a/tests/qtest/netdev-socket.c
+++ b/tests/qtest/netdev-socket.c
@@ -18,6 +18,32 @@
#define CONNECTION_TIMEOUT 120
+static double connection_timeout(void)
+{
+ double load;
+ int ret = getloadavg(&load, 1);
+
+ /*
+ * If we can't get load data, or load is low because we just started
+ * running, assume load of 1 (we are alone in this system).
+ */
+ if (ret < 1 || load < 1.0) {
+ load = 1.0;
+ }
+ /*
+ * No one wants to wait more than 10 minutes for this test. Higher load?
+ * Too bad.
+ */
+ if (load > 10.0) {
+ fprintf(stderr, "Warning: load %f higher than 10 - test might timeout\n",
+ load);
+ load = 10.0;
+ }
+
+ /* if load is high increase timeout as we might not get a chance to run */
+ return load * CONNECTION_TIMEOUT;
+}
+
#define EXPECT_STATE(q, e, t) \
do { \
char *resp = NULL; \
@@ -31,7 +57,7 @@ do { \
if (g_str_equal(resp, e)) { \
break; \
} \
- } while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \
+ } while (g_test_timer_elapsed() < connection_timeout()); \
g_assert_cmpstr(resp, ==, e); \
g_free(resp); \
} while (0)