aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio')
-rw-r--r--hw/virtio/virtio-balloon.c4
-rw-r--r--hw/virtio/virtio-pci.c41
-rw-r--r--hw/virtio/virtio-rng.c2
-rw-r--r--hw/virtio/virtio.c43
4 files changed, 52 insertions, 38 deletions
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 76e32ceef8..95fb3b06be 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -344,10 +344,6 @@ static int virtio_balloon_device_init(VirtIODevice *vdev)
virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON, 8);
- vdev->get_config = virtio_balloon_get_config;
- vdev->set_config = virtio_balloon_set_config;
- vdev->get_features = virtio_balloon_get_features;
-
ret = qemu_add_balloon_handler(virtio_balloon_to_target,
virtio_balloon_stat, s);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index c87ec104be..a624b03e69 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -267,10 +267,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
switch (addr) {
case VIRTIO_PCI_GUEST_FEATURES:
- /* Guest does not negotiate properly? We have to assume nothing. */
- if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
- val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
- }
+ /* Guest does not negotiate properly? We have to assume nothing. */
+ if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
+ val = virtio_bus_get_vdev_bad_features(&proxy->bus);
+ }
virtio_set_features(vdev, val);
break;
case VIRTIO_PCI_QUEUE_PFN:
@@ -535,6 +535,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
{
PCIDevice *dev = &proxy->pci_dev;
VirtIODevice *vdev = proxy->vdev;
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
unsigned int vector;
int ret, queue_no;
MSIMessage msg;
@@ -555,7 +556,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
/* If guest supports masking, set up irqfd now.
* Otherwise, delay until unmasked in the frontend.
*/
- if (proxy->vdev->guest_notifier_mask) {
+ if (k->guest_notifier_mask) {
ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
if (ret < 0) {
kvm_virtio_pci_vq_vector_release(proxy, vector);
@@ -571,7 +572,7 @@ undo:
if (vector >= msix_nr_vectors_allocated(dev)) {
continue;
}
- if (proxy->vdev->guest_notifier_mask) {
+ if (k->guest_notifier_mask) {
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
kvm_virtio_pci_vq_vector_release(proxy, vector);
@@ -585,6 +586,7 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
VirtIODevice *vdev = proxy->vdev;
unsigned int vector;
int queue_no;
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
for (queue_no = 0; queue_no < nvqs; queue_no++) {
if (!virtio_queue_get_num(vdev, queue_no)) {
@@ -597,7 +599,7 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
/* If guest supports masking, clean up irqfd now.
* Otherwise, it was cleaned when masked in the frontend.
*/
- if (proxy->vdev->guest_notifier_mask) {
+ if (k->guest_notifier_mask) {
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
kvm_virtio_pci_vq_vector_release(proxy, vector);
@@ -609,6 +611,7 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
unsigned int vector,
MSIMessage msg)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
EventNotifier *n = virtio_queue_get_guest_notifier(vq);
VirtIOIRQFD *irqfd;
@@ -627,11 +630,11 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
/* If guest supports masking, irqfd is already setup, unmask it.
* Otherwise, set it up now.
*/
- if (proxy->vdev->guest_notifier_mask) {
- proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, false);
+ if (k->guest_notifier_mask) {
+ k->guest_notifier_mask(proxy->vdev, queue_no, false);
/* Test after unmasking to avoid losing events. */
- if (proxy->vdev->guest_notifier_pending &&
- proxy->vdev->guest_notifier_pending(proxy->vdev, queue_no)) {
+ if (k->guest_notifier_pending &&
+ k->guest_notifier_pending(proxy->vdev, queue_no)) {
event_notifier_set(n);
}
} else {
@@ -644,11 +647,13 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
unsigned int queue_no,
unsigned int vector)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(proxy->vdev);
+
/* If guest supports masking, keep irqfd but mask it.
* Otherwise, clean it up now.
*/
- if (proxy->vdev->guest_notifier_mask) {
- proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, true);
+ if (k->guest_notifier_mask) {
+ k->guest_notifier_mask(proxy->vdev, queue_no, true);
} else {
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
}
@@ -708,6 +713,7 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
{
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
VirtIODevice *vdev = proxy->vdev;
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
int queue_no;
unsigned int vector;
EventNotifier *notifier;
@@ -724,8 +730,8 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
}
vq = virtio_get_queue(vdev, queue_no);
notifier = virtio_queue_get_guest_notifier(vq);
- if (vdev->guest_notifier_pending) {
- if (vdev->guest_notifier_pending(vdev, queue_no)) {
+ if (k->guest_notifier_pending) {
+ if (k->guest_notifier_pending(vdev, queue_no)) {
msix_set_pending(dev, vector);
}
} else if (event_notifier_test_and_clear(notifier)) {
@@ -765,6 +771,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
{
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
VirtIODevice *vdev = proxy->vdev;
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
int r, n;
bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
kvm_msi_via_irqfd_enabled();
@@ -779,7 +786,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
proxy->nvqs_with_notifiers = nvqs;
/* Must unset vector notifier while guest notifier is still assigned */
- if ((proxy->vector_irqfd || vdev->guest_notifier_mask) && !assign) {
+ if ((proxy->vector_irqfd || k->guest_notifier_mask) && !assign) {
msix_unset_vector_notifiers(&proxy->pci_dev);
if (proxy->vector_irqfd) {
kvm_virtio_pci_vector_release(proxy, nvqs);
@@ -801,7 +808,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
}
/* Must set vector notifier after guest notifier has been assigned */
- if ((with_irqfd || vdev->guest_notifier_mask) && assign) {
+ if ((with_irqfd || k->guest_notifier_mask) && assign) {
if (with_irqfd) {
proxy->vector_irqfd =
g_malloc0(sizeof(*proxy->vector_irqfd) *
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 96e807539b..82d7a7436a 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -169,8 +169,6 @@ static int virtio_rng_device_init(VirtIODevice *vdev)
vrng->vq = virtio_add_queue(vdev, 8, handle_input);
- vdev->get_features = get_features;
-
assert(vrng->conf.max_bytes <= INT64_MAX);
vrng->quota_remaining = vrng->conf.max_bytes;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 1c2282c54f..de54b41917 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -519,10 +519,11 @@ void virtio_update_irq(VirtIODevice *vdev)
void virtio_set_status(VirtIODevice *vdev, uint8_t val)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
trace_virtio_set_status(vdev, val);
- if (vdev->set_status) {
- vdev->set_status(vdev, val);
+ if (k->set_status) {
+ k->set_status(vdev, val);
}
vdev->status = val;
}
@@ -530,12 +531,14 @@ void virtio_set_status(VirtIODevice *vdev, uint8_t val)
void virtio_reset(void *opaque)
{
VirtIODevice *vdev = opaque;
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
int i;
virtio_set_status(vdev, 0);
- if (vdev->reset)
- vdev->reset(vdev);
+ if (k->reset) {
+ k->reset(vdev);
+ }
vdev->guest_features = 0;
vdev->queue_sel = 0;
@@ -559,9 +562,10 @@ void virtio_reset(void *opaque)
uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint8_t val;
- vdev->get_config(vdev, vdev->config);
+ k->get_config(vdev, vdev->config);
if (addr > (vdev->config_len - sizeof(val)))
return (uint32_t)-1;
@@ -572,9 +576,10 @@ uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint16_t val;
- vdev->get_config(vdev, vdev->config);
+ k->get_config(vdev, vdev->config);
if (addr > (vdev->config_len - sizeof(val)))
return (uint32_t)-1;
@@ -585,9 +590,10 @@ uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint32_t val;
- vdev->get_config(vdev, vdev->config);
+ k->get_config(vdev, vdev->config);
if (addr > (vdev->config_len - sizeof(val)))
return (uint32_t)-1;
@@ -598,6 +604,7 @@ uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint8_t val = data;
if (addr > (vdev->config_len - sizeof(val)))
@@ -605,12 +612,14 @@ void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
stb_p(vdev->config + addr, val);
- if (vdev->set_config)
- vdev->set_config(vdev, vdev->config);
+ if (k->set_config) {
+ k->set_config(vdev, vdev->config);
+ }
}
void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint16_t val = data;
if (addr > (vdev->config_len - sizeof(val)))
@@ -618,12 +627,14 @@ void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
stw_p(vdev->config + addr, val);
- if (vdev->set_config)
- vdev->set_config(vdev, vdev->config);
+ if (k->set_config) {
+ k->set_config(vdev, vdev->config);
+ }
}
void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint32_t val = data;
if (addr > (vdev->config_len - sizeof(val)))
@@ -631,8 +642,9 @@ void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
stl_p(vdev->config + addr, val);
- if (vdev->set_config)
- vdev->set_config(vdev, vdev->config);
+ if (k->set_config) {
+ k->set_config(vdev, vdev->config);
+ }
}
void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr)
@@ -810,13 +822,14 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
int virtio_set_features(VirtIODevice *vdev, uint32_t val)
{
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
uint32_t supported_features =
vdev->binding->get_features(vdev->binding_opaque);
bool bad = (val & ~supported_features) != 0;
val &= supported_features;
- if (vdev->set_features) {
- vdev->set_features(vdev, val);
+ if (k->set_features) {
+ k->set_features(vdev, val);
}
vdev->guest_features = val;
return bad ? -1 : 0;