acpi,virtio,pc: bugfixes
Fix bug in ACPI which were tripping up guests. Fix a use-after-free with hotplug of virtio devices. Block ability to create legacy devices which shouldn't have been there in the first place. Fix migration error handling with balloon. Drop some dead code in virtio. vtd emulation fixup. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAl8YK/4PHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRpCE4H/1+15xjUiKD0sxnvPdKezbDhtAW0YPY/cHC0 KJRWFDbK/+cl9ZkJQBqUXASV3KWnjSKjQrVph6vtg8huqhhDsnha1JGgamhOa9tC 7rH8RkMA6nUF/su8xnkNyNBfG2lHk6ETyKvvTtuLHzjbkzWd6OYtaQAQJTYI6TVB aY+MCIT7xfucsL6JaHA8BTccOOjz7pxc6dL4NsQCR3cZkwTtB9JOE5UwgM3IyNP/ DcbFyVUDkXYtlpKU/xO+ZICbxCNsZmHzpnV8KJ07vyJdAhL1hRAayMkNG4xLzW0n f/ZMlJna5jDP3fRqgVvu8XbY3TcCx1XOBD9ebH5E6hvhWnp8oHI= =SJjI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging acpi,virtio,pc: bugfixes Fix bug in ACPI which were tripping up guests. Fix a use-after-free with hotplug of virtio devices. Block ability to create legacy devices which shouldn't have been there in the first place. Fix migration error handling with balloon. Drop some dead code in virtio. vtd emulation fixup. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Wed 22 Jul 2020 13:07:26 BST # 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 * remotes/mst/tags/for_upstream: virtio-pci: Changed vdev to proxy for VirtIO PCI BAR callbacks. intel_iommu: Use correct shift for 256 bits qi descriptor virtio: verify that legacy support is not accidentally on virtio: list legacy-capable devices virtio-balloon: Replace free page hinting references to 'report' with 'hint' virtio-balloon: Add locking to prevent possible race when starting hinting virtio-balloon: Prevent guest from starting a report when we didn't request one virtio: Drop broken and superfluous object_property_set_link() acpi: accept byte and word access to core ACPI registers Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8ffa52c20d
@ -458,7 +458,8 @@ static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
static const MemoryRegionOps acpi_pm_evt_ops = {
|
||||
.read = acpi_pm_evt_read,
|
||||
.write = acpi_pm_evt_write,
|
||||
.valid.min_access_size = 2,
|
||||
.impl.min_access_size = 2,
|
||||
.valid.min_access_size = 1,
|
||||
.valid.max_access_size = 2,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
@ -527,7 +528,8 @@ static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
static const MemoryRegionOps acpi_pm_tmr_ops = {
|
||||
.read = acpi_pm_tmr_read,
|
||||
.write = acpi_pm_tmr_write,
|
||||
.valid.min_access_size = 4,
|
||||
.impl.min_access_size = 4,
|
||||
.valid.min_access_size = 1,
|
||||
.valid.max_access_size = 4,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
@ -599,7 +601,8 @@ static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
static const MemoryRegionOps acpi_pm_cnt_ops = {
|
||||
.read = acpi_pm_cnt_read,
|
||||
.write = acpi_pm_cnt_write,
|
||||
.valid.min_access_size = 2,
|
||||
.impl.min_access_size = 2,
|
||||
.valid.min_access_size = 1,
|
||||
.valid.max_access_size = 2,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
@ -2549,6 +2549,11 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
|
||||
/* Try to fetch and process more Invalidation Descriptors */
|
||||
static void vtd_fetch_inv_desc(IntelIOMMUState *s)
|
||||
{
|
||||
int qi_shift;
|
||||
|
||||
/* Refer to 10.4.23 of VT-d spec 3.0 */
|
||||
qi_shift = s->iq_dw ? VTD_IQH_QH_SHIFT_5 : VTD_IQH_QH_SHIFT_4;
|
||||
|
||||
trace_vtd_inv_qi_fetch();
|
||||
|
||||
if (s->iq_tail >= s->iq_size) {
|
||||
@ -2567,7 +2572,7 @@ static void vtd_fetch_inv_desc(IntelIOMMUState *s)
|
||||
}
|
||||
/* Must update the IQH_REG in time */
|
||||
vtd_set_quad_raw(s, DMAR_IQH_REG,
|
||||
(((uint64_t)(s->iq_head)) << VTD_IQH_QH_SHIFT) &
|
||||
(((uint64_t)(s->iq_head)) << qi_shift) &
|
||||
VTD_IQH_QH_MASK);
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +230,8 @@
|
||||
#define VTD_IQA_DW_MASK 0x800
|
||||
|
||||
/* IQH_REG */
|
||||
#define VTD_IQH_QH_SHIFT 4
|
||||
#define VTD_IQH_QH_SHIFT_4 4
|
||||
#define VTD_IQH_QH_SHIFT_5 5
|
||||
#define VTD_IQH_QH_MASK 0x7fff0ULL
|
||||
|
||||
/* ICS_REG */
|
||||
|
@ -23,9 +23,6 @@ static void virtio_ccw_crypto_realize(VirtioCcwDevice *ccw_dev, Error **errp)
|
||||
if (!qdev_realize(vdev, BUS(&ccw_dev->bus), errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
object_property_set_link(OBJECT(vdev), "cryptodev",
|
||||
OBJECT(dev->vdev.conf.cryptodev), NULL);
|
||||
}
|
||||
|
||||
static void virtio_ccw_crypto_instance_init(Object *obj)
|
||||
|
@ -24,9 +24,6 @@ static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp)
|
||||
if (!qdev_realize(vdev, BUS(&ccw_dev->bus), errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
object_property_set_link(OBJECT(dev), "rng", OBJECT(dev->vdev.conf.rng),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void virtio_ccw_rng_instance_init(Object *obj)
|
||||
|
@ -1121,6 +1121,12 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp)
|
||||
dev->max_rev = 0;
|
||||
}
|
||||
|
||||
if (!virtio_ccw_rev_max(dev) && !virtio_legacy_allowed(vdev)) {
|
||||
error_setg(errp, "Invalid value of property max_rev "
|
||||
"(is %d expected >= 1)", virtio_ccw_rev_max(dev));
|
||||
return;
|
||||
}
|
||||
|
||||
if (virtio_get_num_queues(vdev) > VIRTIO_QUEUE_MAX) {
|
||||
error_setg(errp, "The number of virtqueues %d "
|
||||
"exceeds virtio limit %d", n,
|
||||
|
@ -526,21 +526,22 @@ static bool get_free_page_hints(VirtIOBalloon *dev)
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
if (id == dev->free_page_report_cmd_id) {
|
||||
dev->free_page_report_status = FREE_PAGE_REPORT_S_START;
|
||||
if (dev->free_page_hint_status == FREE_PAGE_HINT_S_REQUESTED &&
|
||||
id == dev->free_page_hint_cmd_id) {
|
||||
dev->free_page_hint_status = FREE_PAGE_HINT_S_START;
|
||||
} else {
|
||||
/*
|
||||
* Stop the optimization only when it has started. This
|
||||
* avoids a stale stop sign for the previous command.
|
||||
*/
|
||||
if (dev->free_page_report_status == FREE_PAGE_REPORT_S_START) {
|
||||
dev->free_page_report_status = FREE_PAGE_REPORT_S_STOP;
|
||||
if (dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
|
||||
dev->free_page_hint_status = FREE_PAGE_HINT_S_STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->in_num) {
|
||||
if (dev->free_page_report_status == FREE_PAGE_REPORT_S_START) {
|
||||
if (dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
|
||||
qemu_guest_free_page_hint(elem->in_sg[0].iov_base,
|
||||
elem->in_sg[0].iov_len);
|
||||
}
|
||||
@ -566,11 +567,11 @@ static void virtio_ballloon_get_free_page_hints(void *opaque)
|
||||
qemu_mutex_unlock(&dev->free_page_lock);
|
||||
virtio_notify(vdev, vq);
|
||||
/*
|
||||
* Start to poll the vq once the reporting started. Otherwise, continue
|
||||
* Start to poll the vq once the hinting started. Otherwise, continue
|
||||
* only when there are entries on the vq, which need to be given back.
|
||||
*/
|
||||
} while (continue_to_get_hints ||
|
||||
dev->free_page_report_status == FREE_PAGE_REPORT_S_START);
|
||||
dev->free_page_hint_status == FREE_PAGE_HINT_S_START);
|
||||
virtio_queue_set_notification(vq, 1);
|
||||
}
|
||||
|
||||
@ -591,14 +592,18 @@ static void virtio_balloon_free_page_start(VirtIOBalloon *s)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->free_page_report_cmd_id == UINT_MAX) {
|
||||
s->free_page_report_cmd_id =
|
||||
VIRTIO_BALLOON_FREE_PAGE_REPORT_CMD_ID_MIN;
|
||||
qemu_mutex_lock(&s->free_page_lock);
|
||||
|
||||
if (s->free_page_hint_cmd_id == UINT_MAX) {
|
||||
s->free_page_hint_cmd_id =
|
||||
VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN;
|
||||
} else {
|
||||
s->free_page_report_cmd_id++;
|
||||
s->free_page_hint_cmd_id++;
|
||||
}
|
||||
|
||||
s->free_page_report_status = FREE_PAGE_REPORT_S_REQUESTED;
|
||||
s->free_page_hint_status = FREE_PAGE_HINT_S_REQUESTED;
|
||||
qemu_mutex_unlock(&s->free_page_lock);
|
||||
|
||||
virtio_notify_config(vdev);
|
||||
}
|
||||
|
||||
@ -606,18 +611,18 @@ static void virtio_balloon_free_page_stop(VirtIOBalloon *s)
|
||||
{
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(s);
|
||||
|
||||
if (s->free_page_report_status != FREE_PAGE_REPORT_S_STOP) {
|
||||
if (s->free_page_hint_status != FREE_PAGE_HINT_S_STOP) {
|
||||
/*
|
||||
* The lock also guarantees us that the
|
||||
* virtio_ballloon_get_free_page_hints exits after the
|
||||
* free_page_report_status is set to S_STOP.
|
||||
* free_page_hint_status is set to S_STOP.
|
||||
*/
|
||||
qemu_mutex_lock(&s->free_page_lock);
|
||||
/*
|
||||
* The guest hasn't done the reporting, so host sends a notification
|
||||
* to the guest to actively stop the reporting.
|
||||
* The guest isn't done hinting, so send a notification
|
||||
* to the guest to actively stop the hinting.
|
||||
*/
|
||||
s->free_page_report_status = FREE_PAGE_REPORT_S_STOP;
|
||||
s->free_page_hint_status = FREE_PAGE_HINT_S_STOP;
|
||||
qemu_mutex_unlock(&s->free_page_lock);
|
||||
virtio_notify_config(vdev);
|
||||
}
|
||||
@ -627,20 +632,20 @@ static void virtio_balloon_free_page_done(VirtIOBalloon *s)
|
||||
{
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(s);
|
||||
|
||||
if (s->free_page_report_status != FREE_PAGE_REPORT_S_DONE) {
|
||||
if (s->free_page_hint_status != FREE_PAGE_HINT_S_DONE) {
|
||||
/* See virtio_balloon_free_page_stop() */
|
||||
qemu_mutex_lock(&s->free_page_lock);
|
||||
s->free_page_report_status = FREE_PAGE_REPORT_S_DONE;
|
||||
s->free_page_hint_status = FREE_PAGE_HINT_S_DONE;
|
||||
qemu_mutex_unlock(&s->free_page_lock);
|
||||
virtio_notify_config(vdev);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
virtio_balloon_free_page_report_notify(NotifierWithReturn *n, void *data)
|
||||
virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
|
||||
{
|
||||
VirtIOBalloon *dev = container_of(n, VirtIOBalloon,
|
||||
free_page_report_notify);
|
||||
free_page_hint_notify);
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||
PrecopyNotifyData *pnd = data;
|
||||
|
||||
@ -698,7 +703,7 @@ static size_t virtio_balloon_config_size(VirtIOBalloon *s)
|
||||
if (virtio_has_feature(features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
|
||||
return offsetof(struct virtio_balloon_config, poison_val);
|
||||
}
|
||||
return offsetof(struct virtio_balloon_config, free_page_report_cmd_id);
|
||||
return offsetof(struct virtio_balloon_config, free_page_hint_cmd_id);
|
||||
}
|
||||
|
||||
static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
|
||||
@ -710,14 +715,14 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
|
||||
config.actual = cpu_to_le32(dev->actual);
|
||||
config.poison_val = cpu_to_le32(dev->poison_val);
|
||||
|
||||
if (dev->free_page_report_status == FREE_PAGE_REPORT_S_REQUESTED) {
|
||||
config.free_page_report_cmd_id =
|
||||
cpu_to_le32(dev->free_page_report_cmd_id);
|
||||
} else if (dev->free_page_report_status == FREE_PAGE_REPORT_S_STOP) {
|
||||
config.free_page_report_cmd_id =
|
||||
if (dev->free_page_hint_status == FREE_PAGE_HINT_S_REQUESTED) {
|
||||
config.free_page_hint_cmd_id =
|
||||
cpu_to_le32(dev->free_page_hint_cmd_id);
|
||||
} else if (dev->free_page_hint_status == FREE_PAGE_HINT_S_STOP) {
|
||||
config.free_page_hint_cmd_id =
|
||||
cpu_to_le32(VIRTIO_BALLOON_CMD_ID_STOP);
|
||||
} else if (dev->free_page_report_status == FREE_PAGE_REPORT_S_DONE) {
|
||||
config.free_page_report_cmd_id =
|
||||
} else if (dev->free_page_hint_status == FREE_PAGE_HINT_S_DONE) {
|
||||
config.free_page_hint_cmd_id =
|
||||
cpu_to_le32(VIRTIO_BALLOON_CMD_ID_DONE);
|
||||
}
|
||||
|
||||
@ -830,14 +835,14 @@ static int virtio_balloon_post_load_device(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_virtio_balloon_free_page_report = {
|
||||
static const VMStateDescription vmstate_virtio_balloon_free_page_hint = {
|
||||
.name = "virtio-balloon-device/free-page-report",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = virtio_balloon_free_page_support,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(free_page_report_cmd_id, VirtIOBalloon),
|
||||
VMSTATE_UINT32(free_page_report_status, VirtIOBalloon),
|
||||
VMSTATE_UINT32(free_page_hint_cmd_id, VirtIOBalloon),
|
||||
VMSTATE_UINT32(free_page_hint_status, VirtIOBalloon),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
@ -864,7 +869,7 @@ static const VMStateDescription vmstate_virtio_balloon_device = {
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription * []) {
|
||||
&vmstate_virtio_balloon_free_page_report,
|
||||
&vmstate_virtio_balloon_free_page_hint,
|
||||
&vmstate_virtio_balloon_page_poison,
|
||||
NULL
|
||||
}
|
||||
@ -903,7 +908,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
|
||||
VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
|
||||
s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE,
|
||||
virtio_balloon_handle_free_page_vq);
|
||||
precopy_add_notifier(&s->free_page_report_notify);
|
||||
precopy_add_notifier(&s->free_page_hint_notify);
|
||||
|
||||
object_ref(OBJECT(s->iothread));
|
||||
s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread),
|
||||
@ -927,7 +932,7 @@ static void virtio_balloon_device_unrealize(DeviceState *dev)
|
||||
qemu_bh_delete(s->free_page_bh);
|
||||
object_unref(OBJECT(s->iothread));
|
||||
virtio_balloon_free_page_stop(s);
|
||||
precopy_remove_notifier(&s->free_page_report_notify);
|
||||
precopy_remove_notifier(&s->free_page_hint_notify);
|
||||
}
|
||||
balloon_stats_destroy_timer(s);
|
||||
qemu_remove_balloon_handler(s);
|
||||
@ -999,8 +1004,8 @@ static void virtio_balloon_instance_init(Object *obj)
|
||||
|
||||
qemu_mutex_init(&s->free_page_lock);
|
||||
qemu_cond_init(&s->free_page_cond);
|
||||
s->free_page_report_cmd_id = VIRTIO_BALLOON_FREE_PAGE_REPORT_CMD_ID_MIN;
|
||||
s->free_page_report_notify.notify = virtio_balloon_free_page_report_notify;
|
||||
s->free_page_hint_cmd_id = VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN;
|
||||
s->free_page_hint_notify.notify = virtio_balloon_free_page_hint_notify;
|
||||
|
||||
object_property_add(obj, "guest-stats", "guest statistics",
|
||||
balloon_stats_get_all, NULL, NULL, s);
|
||||
|
@ -57,8 +57,6 @@ static void virtio_crypto_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
if (!qdev_realize(vdev, BUS(&vpci_dev->bus), errp)) {
|
||||
return;
|
||||
}
|
||||
object_property_set_link(OBJECT(vcrypto), "cryptodev",
|
||||
OBJECT(vcrypto->vdev.conf.cryptodev), NULL);
|
||||
}
|
||||
|
||||
static void virtio_crypto_pci_class_init(ObjectClass *klass, void *data)
|
||||
|
@ -1333,11 +1333,12 @@ static uint64_t virtio_pci_notify_read(void *opaque, hwaddr addr,
|
||||
static void virtio_pci_notify_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
VirtIODevice *vdev = opaque;
|
||||
VirtIOPCIProxy *proxy = VIRTIO_PCI(DEVICE(vdev)->parent_bus->parent);
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||
|
||||
unsigned queue = addr / virtio_pci_queue_mem_mult(proxy);
|
||||
|
||||
if (queue < VIRTIO_QUEUE_MAX) {
|
||||
if (vdev != NULL && queue < VIRTIO_QUEUE_MAX) {
|
||||
virtio_queue_notify(vdev, queue);
|
||||
}
|
||||
}
|
||||
@ -1345,10 +1346,12 @@ static void virtio_pci_notify_write(void *opaque, hwaddr addr,
|
||||
static void virtio_pci_notify_write_pio(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
VirtIODevice *vdev = opaque;
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||
|
||||
unsigned queue = val;
|
||||
|
||||
if (queue < VIRTIO_QUEUE_MAX) {
|
||||
if (vdev != NULL && queue < VIRTIO_QUEUE_MAX) {
|
||||
virtio_queue_notify(vdev, queue);
|
||||
}
|
||||
}
|
||||
@ -1372,9 +1375,14 @@ static void virtio_pci_isr_write(void *opaque, hwaddr addr,
|
||||
static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
VirtIODevice *vdev = opaque;
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||
uint64_t val = 0;
|
||||
|
||||
if (vdev == NULL) {
|
||||
return val;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
val = virtio_config_modern_readb(vdev, addr);
|
||||
@ -1392,7 +1400,13 @@ static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
|
||||
static void virtio_pci_device_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
VirtIODevice *vdev = opaque;
|
||||
VirtIOPCIProxy *proxy = opaque;
|
||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||
|
||||
if (vdev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
virtio_config_modern_writeb(vdev, addr, val);
|
||||
@ -1469,19 +1483,19 @@ static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy)
|
||||
|
||||
memory_region_init_io(&proxy->device.mr, OBJECT(proxy),
|
||||
&device_ops,
|
||||
virtio_bus_get_device(&proxy->bus),
|
||||
proxy,
|
||||
"virtio-pci-device",
|
||||
proxy->device.size);
|
||||
|
||||
memory_region_init_io(&proxy->notify.mr, OBJECT(proxy),
|
||||
¬ify_ops,
|
||||
virtio_bus_get_device(&proxy->bus),
|
||||
proxy,
|
||||
"virtio-pci-notify",
|
||||
proxy->notify.size);
|
||||
|
||||
memory_region_init_io(&proxy->notify_pio.mr, OBJECT(proxy),
|
||||
¬ify_pio_ops,
|
||||
virtio_bus_get_device(&proxy->bus),
|
||||
proxy,
|
||||
"virtio-pci-notify-pio",
|
||||
proxy->notify_pio.size);
|
||||
}
|
||||
@ -1581,6 +1595,10 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
|
||||
}
|
||||
|
||||
if (legacy) {
|
||||
if (!virtio_legacy_allowed(vdev)) {
|
||||
error_setg(errp, "device is modern-only, use disable-legacy=on");
|
||||
return;
|
||||
}
|
||||
if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
|
||||
error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by"
|
||||
" neither legacy nor transitional device");
|
||||
|
@ -38,9 +38,6 @@ static void virtio_rng_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
if (!qdev_realize(vdev, BUS(&vpci_dev->bus), errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
object_property_set_link(OBJECT(vrng), "rng", OBJECT(vrng->vdev.conf.rng),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "standard-headers/linux/virtio_ids.h"
|
||||
|
||||
/*
|
||||
* The alignment to use between consumer and producer parts of vring.
|
||||
@ -3279,6 +3280,30 @@ void virtio_init(VirtIODevice *vdev, const char *name,
|
||||
vdev->use_guest_notifier_mask = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only devices that have already been around prior to defining the virtio
|
||||
* standard support legacy mode; this includes devices not specified in the
|
||||
* standard. All newer devices conform to the virtio standard only.
|
||||
*/
|
||||
bool virtio_legacy_allowed(VirtIODevice *vdev)
|
||||
{
|
||||
switch (vdev->device_id) {
|
||||
case VIRTIO_ID_NET:
|
||||
case VIRTIO_ID_BLOCK:
|
||||
case VIRTIO_ID_CONSOLE:
|
||||
case VIRTIO_ID_RNG:
|
||||
case VIRTIO_ID_BALLOON:
|
||||
case VIRTIO_ID_RPMSG:
|
||||
case VIRTIO_ID_SCSI:
|
||||
case VIRTIO_ID_9P:
|
||||
case VIRTIO_ID_RPROC_SERIAL:
|
||||
case VIRTIO_ID_CAIF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
|
||||
{
|
||||
return vdev->vq[n].vring.desc;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define VIRTIO_BALLOON(obj) \
|
||||
OBJECT_CHECK(VirtIOBalloon, (obj), TYPE_VIRTIO_BALLOON)
|
||||
|
||||
#define VIRTIO_BALLOON_FREE_PAGE_REPORT_CMD_ID_MIN 0x80000000
|
||||
#define VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN 0x80000000
|
||||
|
||||
typedef struct virtio_balloon_stat VirtIOBalloonStat;
|
||||
|
||||
@ -33,20 +33,20 @@ typedef struct virtio_balloon_stat_modern {
|
||||
uint64_t val;
|
||||
} VirtIOBalloonStatModern;
|
||||
|
||||
enum virtio_balloon_free_page_report_status {
|
||||
FREE_PAGE_REPORT_S_STOP = 0,
|
||||
FREE_PAGE_REPORT_S_REQUESTED = 1,
|
||||
FREE_PAGE_REPORT_S_START = 2,
|
||||
FREE_PAGE_REPORT_S_DONE = 3,
|
||||
enum virtio_balloon_free_page_hint_status {
|
||||
FREE_PAGE_HINT_S_STOP = 0,
|
||||
FREE_PAGE_HINT_S_REQUESTED = 1,
|
||||
FREE_PAGE_HINT_S_START = 2,
|
||||
FREE_PAGE_HINT_S_DONE = 3,
|
||||
};
|
||||
|
||||
typedef struct VirtIOBalloon {
|
||||
VirtIODevice parent_obj;
|
||||
VirtQueue *ivq, *dvq, *svq, *free_page_vq, *reporting_vq;
|
||||
uint32_t free_page_report_status;
|
||||
uint32_t free_page_hint_status;
|
||||
uint32_t num_pages;
|
||||
uint32_t actual;
|
||||
uint32_t free_page_report_cmd_id;
|
||||
uint32_t free_page_hint_cmd_id;
|
||||
uint64_t stats[VIRTIO_BALLOON_S_NR];
|
||||
VirtQueueElement *stats_vq_elem;
|
||||
size_t stats_vq_offset;
|
||||
@ -55,7 +55,7 @@ typedef struct VirtIOBalloon {
|
||||
QEMUBH *free_page_bh;
|
||||
/*
|
||||
* Lock to synchronize threads to access the free page reporting related
|
||||
* fields (e.g. free_page_report_status).
|
||||
* fields (e.g. free_page_hint_status).
|
||||
*/
|
||||
QemuMutex free_page_lock;
|
||||
QemuCond free_page_cond;
|
||||
@ -64,7 +64,7 @@ typedef struct VirtIOBalloon {
|
||||
* stopped.
|
||||
*/
|
||||
bool block_iothread;
|
||||
NotifierWithReturn free_page_report_notify;
|
||||
NotifierWithReturn free_page_hint_notify;
|
||||
int64_t stats_last_update;
|
||||
int64_t stats_poll_interval;
|
||||
uint32_t host_features;
|
||||
|
@ -396,4 +396,6 @@ static inline bool virtio_device_disabled(VirtIODevice *vdev)
|
||||
return unlikely(vdev->disabled || vdev->broken);
|
||||
}
|
||||
|
||||
bool virtio_legacy_allowed(VirtIODevice *vdev);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user