Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/m…
…st/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>
  • Loading branch information
Stefan Hajnoczi committed Dec 4, 2023
2 parents 019f8c1 + 95e1019 commit 173e828
Show file tree
Hide file tree
Showing 16 changed files with 152 additions and 49 deletions.
10 changes: 10 additions & 0 deletions hw/acpi/erst.c
Expand Up @@ -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();
Expand All @@ -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,
Expand All @@ -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);

Expand Down
41 changes: 27 additions & 14 deletions hw/audio/hda-codec.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions hw/audio/virtio-snd-pci.c
Expand Up @@ -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)
Expand Down
43 changes: 25 additions & 18 deletions hw/audio/virtio-snd.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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,
Expand Down
8 changes: 3 additions & 5 deletions hw/block/vhost-user-blk.c
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
15 changes: 12 additions & 3 deletions hw/i386/x86.c
Expand Up @@ -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.");
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions hw/pci/msix.c
Expand Up @@ -648,6 +648,7 @@ int msix_set_vector_notifiers(PCIDevice *dev,
}
dev->msix_vector_use_notifier = NULL;
dev->msix_vector_release_notifier = NULL;
dev->msix_vector_poll_notifier = NULL;
return ret;
}

Expand Down
1 change: 0 additions & 1 deletion hw/pci/pcie_sriov.c
Expand Up @@ -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);
Expand Down
19 changes: 18 additions & 1 deletion hw/scsi/vhost-user-scsi.c
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion hw/virtio/vhost-user-gpio.c
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions hw/virtio/virtio-iommu.c
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion hw/virtio/virtio.c
Expand Up @@ -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));
}

Expand Down

0 comments on commit 173e828

Please sign in to comment.