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-----

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>
This commit is contained in:
Stefan Hajnoczi 2023-12-04 08:02:37 -05:00
commit 173e828064
16 changed files with 152 additions and 49 deletions

View File

@ -947,6 +947,7 @@ static const VMStateDescription erst_vmstate = {
static void erst_realizefn(PCIDevice *pci_dev, Error **errp) static void erst_realizefn(PCIDevice *pci_dev, Error **errp)
{ {
ERRP_GUARD();
ERSTDeviceState *s = ACPIERST(pci_dev); ERSTDeviceState *s = ACPIERST(pci_dev);
trace_acpi_erst_realizefn_in(); 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 */ /* HostMemoryBackend size will be multiple of PAGE_SIZE */
s->storage_size = object_property_get_int(OBJECT(s->hostmem), "size", errp); s->storage_size = object_property_get_int(OBJECT(s->hostmem), "size", errp);
if (*errp) {
return;
}
/* Initialize backend storage and record_count */ /* Initialize backend storage and record_count */
check_erst_backend_storage(s, errp); check_erst_backend_storage(s, errp);
if (*errp) {
return;
}
/* BAR 0: Programming registers */ /* BAR 0: Programming registers */
memory_region_init_io(&s->iomem_mr, OBJECT(pci_dev), &erst_reg_ops, s, 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), memory_region_init_ram(&s->exchange_mr, OBJECT(pci_dev),
"erst.exchange", "erst.exchange",
le32_to_cpu(s->header->record_size), errp); le32_to_cpu(s->header->record_size), errp);
if (*errp) {
return;
}
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
&s->exchange_mr); &s->exchange_mr);

View File

@ -22,6 +22,7 @@
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "intel-hda.h" #include "intel-hda.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "qemu/host-utils.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "intel-hda-defs.h" #include "intel-hda-defs.h"
#include "audio/audio.h" #include "audio/audio.h"
@ -189,9 +190,9 @@ struct HDAAudioState {
bool use_timer; 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) 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 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 wpos = st->wpos;
int64_t rpos = st->rpos; int64_t rpos = st->rpos;
int64_t wanted_rpos;
int64_t wanted_rpos = hda_bytes_per_second(st) * (now - buft_start) if (uptime <= 0) {
/ NANOSECONDS_PER_SECOND; /* 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 */ wanted_rpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_rpos <= rpos) { 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 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 wpos = st->wpos;
int64_t rpos = st->rpos; int64_t rpos = st->rpos;
int64_t wanted_wpos;
int64_t wanted_wpos = hda_bytes_per_second(st) * (now - buft_start) if (uptime <= 0) {
/ NANOSECONDS_PER_SECOND; /* wanted_wpos <= 0 */
goto out_timer;
}
wanted_wpos = muldiv64(uptime, hda_bytes_per_second(st),
NANOSECONDS_PER_SECOND);
wanted_wpos &= -4; /* IMPORTANT! clip to frames */ wanted_wpos &= -4; /* IMPORTANT! clip to frames */
if (wanted_wpos <= wpos) { if (wanted_wpos <= wpos) {
@ -855,10 +868,10 @@ static Property hda_audio_properties[] = {
static void hda_audio_init_output(HDACodecDevice *hda, Error **errp) static void hda_audio_init_output(HDACodecDevice *hda, Error **errp)
{ {
HDAAudioState *a = HDA_AUDIO(hda); HDAAudioState *a = HDA_AUDIO(hda);
const struct desc_codec *desc = &output_nomixemu; const struct desc_codec *desc = &output_mixemu;
if (!a->mixer) { if (!a->mixer) {
desc = &output_mixemu; desc = &output_nomixemu;
} }
hda_audio_init(hda, desc, errp); 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) static void hda_audio_init_duplex(HDACodecDevice *hda, Error **errp)
{ {
HDAAudioState *a = HDA_AUDIO(hda); HDAAudioState *a = HDA_AUDIO(hda);
const struct desc_codec *desc = &duplex_nomixemu; const struct desc_codec *desc = &duplex_mixemu;
if (!a->mixer) { if (!a->mixer) {
desc = &duplex_mixemu; desc = &duplex_nomixemu;
} }
hda_audio_init(hda, desc, errp); 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) static void hda_audio_init_micro(HDACodecDevice *hda, Error **errp)
{ {
HDAAudioState *a = HDA_AUDIO(hda); HDAAudioState *a = HDA_AUDIO(hda);
const struct desc_codec *desc = &micro_nomixemu; const struct desc_codec *desc = &micro_mixemu;
if (!a->mixer) { if (!a->mixer) {
desc = &micro_mixemu; desc = &micro_nomixemu;
} }
hda_audio_init(hda, desc, errp); hda_audio_init(hda, desc, errp);

View File

@ -47,12 +47,14 @@ static void virtio_snd_pci_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass); VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);
PCIDeviceClass *pcidevklass = PCI_DEVICE_CLASS(klass);
device_class_set_props(dc, virtio_snd_pci_properties); device_class_set_props(dc, virtio_snd_pci_properties);
dc->desc = "Virtio Sound"; dc->desc = "Virtio Sound";
set_bit(DEVICE_CATEGORY_SOUND, dc->categories); set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
vpciklass->realize = virtio_snd_pci_realize; vpciklass->realize = virtio_snd_pci_realize;
pcidevklass->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
} }
static void virtio_snd_pci_instance_init(Object *obj) static void virtio_snd_pci_instance_init(Object *obj)

View File

@ -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_process_cmdq(VirtIOSound *s);
static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream); static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream);
static void virtio_snd_pcm_in_cb(void *data, int available); 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) static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8)
| BIT(VIRTIO_SND_PCM_FMT_U8) | 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 }; virtio_snd_pcm_set_params default_params = { 0 };
uint32_t status; 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); trace_virtio_snd_realize(vsnd);
vsnd->pcm = g_new0(VirtIOSoundPCM, 1); /* check number of jacks and streams */
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 */
if (vsnd->snd_conf.jacks > 8) { if (vsnd->snd_conf.jacks > 8) {
error_setg(errp, error_setg(errp,
"Invalid number of jacks: %"PRIu32, "Invalid number of jacks: %"PRIu32,
@ -1102,7 +1089,22 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
return; 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 */ /* set default params for all streams */
default_params.features = 0; default_params.features = 0;
@ -1128,16 +1130,21 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
error_setg(errp, error_setg(errp,
"Can't initialize stream params, device responded with %s.", "Can't initialize stream params, device responded with %s.",
print_code(status)); print_code(status));
return; goto error_cleanup;
} }
status = virtio_snd_pcm_prepare(vsnd, i); status = virtio_snd_pcm_prepare(vsnd, i);
if (status != cpu_to_le32(VIRTIO_SND_S_OK)) { if (status != cpu_to_le32(VIRTIO_SND_S_OK)) {
error_setg(errp, error_setg(errp,
"Can't prepare streams, device responded with %s.", "Can't prepare streams, device responded with %s.",
print_code(status)); print_code(status));
return; goto error_cleanup;
} }
} }
return;
error_cleanup:
virtio_snd_unrealize(dev);
} }
static inline void return_tx_buffer(VirtIOSoundPCMStream *stream, static inline void return_tx_buffer(VirtIOSoundPCMStream *stream,

View File

@ -326,7 +326,6 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
if (s->connected) { if (s->connected) {
return 0; return 0;
} }
s->connected = true;
s->dev.num_queues = s->num_queues; s->dev.num_queues = s->num_queues;
s->dev.nvqs = 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; return ret;
} }
s->connected = true;
/* restore vhost state */ /* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) { if (virtio_device_started(vdev, vdev->status)) {
ret = vhost_user_blk_start(vdev, errp); ret = vhost_user_blk_start(vdev, errp);
if (ret < 0) {
return ret;
}
} }
return 0; return ret;
} }
static void vhost_user_blk_disconnect(DeviceState *dev) static void vhost_user_blk_disconnect(DeviceState *dev)

View File

@ -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 * Can we support APIC ID 255 or higher? With KVM, that requires
* both in-kernel lapic and X2APIC userspace API. * 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())) { (!kvm_irqchip_in_kernel() || !kvm_enable_x2apic())) {
error_report("current -smp configuration requires kernel " error_report("current -smp configuration requires kernel "
"irqchip and X2APIC API support."); "irqchip and X2APIC API support.");
@ -418,8 +422,13 @@ void x86_cpu_pre_plug(HotplugHandler *hotplug_dev,
} }
cpu->thread_id = topo_ids.smt_id; 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"); error_setg(errp, "kernel doesn't allow setting HyperV VP_INDEX");
return; return;
} }

View File

@ -648,6 +648,7 @@ undo:
} }
dev->msix_vector_use_notifier = NULL; dev->msix_vector_use_notifier = NULL;
dev->msix_vector_release_notifier = NULL; dev->msix_vector_release_notifier = NULL;
dev->msix_vector_poll_notifier = NULL;
return ret; return ret;
} }

View File

@ -178,7 +178,6 @@ static void register_vfs(PCIDevice *dev)
num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF); num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF);
dev->exp.sriov_pf.vf = g_new(PCIDevice *, num_vfs); 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), trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), num_vfs); PCI_FUNC(dev->devfn), num_vfs);

View File

@ -147,7 +147,6 @@ static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
if (s->connected) { if (s->connected) {
return 0; return 0;
} }
s->connected = true;
vsc->dev.num_queues = vs->conf.num_queues; vsc->dev.num_queues = vs->conf.num_queues;
vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + 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; return ret;
} }
s->connected = true;
/* restore vhost state */ /* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) { if (virtio_device_started(vdev, vdev->status)) {
ret = vhost_user_scsi_start(s, errp); ret = vhost_user_scsi_start(s, errp);
@ -359,6 +360,20 @@ static Property vhost_user_scsi_properties[] = {
DEFINE_PROP_END_OF_LIST(), 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 = { static const VMStateDescription vmstate_vhost_scsi = {
.name = "virtio-scsi", .name = "virtio-scsi",
.minimum_version_id = 1, .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_config = vhost_scsi_common_set_config;
vdc->set_status = vhost_user_scsi_set_status; vdc->set_status = vhost_user_scsi_set_status;
fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path; 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) static void vhost_user_scsi_instance_init(Object *obj)

View File

@ -229,7 +229,6 @@ static int vu_gpio_connect(DeviceState *dev, Error **errp)
if (gpio->connected) { if (gpio->connected) {
return 0; return 0;
} }
gpio->connected = true;
vhost_dev_set_config_notifier(vhost_dev, &gpio_ops); vhost_dev_set_config_notifier(vhost_dev, &gpio_ops);
gpio->vhost_user.supports_config = true; gpio->vhost_user.supports_config = true;
@ -243,6 +242,8 @@ static int vu_gpio_connect(DeviceState *dev, Error **errp)
return ret; return ret;
} }
gpio->connected = true;
/* restore vhost state */ /* restore vhost state */
if (virtio_device_started(vdev, vdev->status)) { if (virtio_device_started(vdev, vdev->status)) {
vu_gpio_start(vdev); vu_gpio_start(vdev);

View File

@ -698,9 +698,6 @@ static int virtio_iommu_probe(VirtIOIOMMU *s,
} }
sdev = container_of(iommu_mr, IOMMUDevice, iommu_mr); sdev = container_of(iommu_mr, IOMMUDevice, iommu_mr);
if (!sdev) {
return -EINVAL;
}
count = virtio_iommu_fill_resv_mem_prop(sdev, ep_id, buf, free); count = virtio_iommu_fill_resv_mem_prop(sdev, ep_id, buf, free);
if (count < 0) { if (count < 0) {

View File

@ -2137,7 +2137,7 @@ void virtio_reset(void *opaque)
vdev->device_endian = virtio_default_endian(); vdev->device_endian = virtio_default_endian();
} }
if (vdev->vhost_started) { if (vdev->vhost_started && k->get_vhost) {
vhost_reset_device(k->get_vhost(vdev)); vhost_reset_device(k->get_vhost(vdev));
} }

View File

@ -779,6 +779,16 @@ static inline int platform_does_not_support_system(const char *command)
} }
#endif /* !HAVE_SYSTEM_FUNCTION */ #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -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_OPENPTY', cc.has_function('openpty', dependencies: util))
config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 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_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() if rbd.found()
config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS', config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
cc.has_function('rbd_namespace_exists', cc.has_function('rbd_namespace_exists',

View File

@ -112,6 +112,7 @@ static const char *iasl;
#endif #endif
static int verbosity_level; static int verbosity_level;
static GArray *load_expected_aml(test_data *data);
static bool compare_signature(const AcpiSdtTable *sdt, const char *signature) 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) static void dump_aml_files(test_data *data, bool rebuild)
{ {
AcpiSdtTable *sdt; AcpiSdtTable *sdt, *exp_sdt;
GError *error = NULL; GError *error = NULL;
gchar *aml_file = NULL; gchar *aml_file = NULL;
test_data exp_data = {};
gint fd; gint fd;
ssize_t ret; ssize_t ret;
int i; int i;
exp_data.tables = load_expected_aml(data);
for (i = 0; i < data->tables->len; ++i) { for (i = 0; i < data->tables->len; ++i) {
const char *ext = data->variant ? data->variant : ""; const char *ext = data->variant ? data->variant : "";
sdt = &g_array_index(data->tables, AcpiSdtTable, i); sdt = &g_array_index(data->tables, AcpiSdtTable, i);
exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i);
g_assert(sdt->aml); g_assert(sdt->aml);
g_assert(exp_sdt->aml);
if (rebuild) { if (rebuild) {
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
sdt->aml, ext); 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, fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
if (fd < 0) { if (fd < 0) {

View File

@ -18,6 +18,32 @@
#define CONNECTION_TIMEOUT 120 #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) \ #define EXPECT_STATE(q, e, t) \
do { \ do { \
char *resp = NULL; \ char *resp = NULL; \
@ -31,7 +57,7 @@ do { \
if (g_str_equal(resp, e)) { \ if (g_str_equal(resp, e)) { \
break; \ break; \
} \ } \
} while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \ } while (g_test_timer_elapsed() < connection_timeout()); \
g_assert_cmpstr(resp, ==, e); \ g_assert_cmpstr(resp, ==, e); \
g_free(resp); \ g_free(resp); \
} while (0) } while (0)