mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-06-16 02:15:47 +00:00
kvm tools: Convert virtio devices to use IRQ registry
Instead of using static IRQ/device data, register the device upon initialization and use the assign parameters when issuing IRQs. Clean up static definitions of IRQs. Signed-off-by: Sasha Levin <levinsasha928@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
@@ -16,25 +16,4 @@
|
||||
#define PCI_SUBSYSTEM_ID_VIRTIO_CONSOLE 0x0003
|
||||
#define PCI_SUBSYSTEM_ID_VIRTIO_RNG 0x0004
|
||||
|
||||
enum {
|
||||
PCI_VIRTIO_BLK_DEVNUM = 10,
|
||||
PCI_VIRTIO_CONSOLE_DEVNUM = 2,
|
||||
PCI_VIRTIO_NET_DEVNUM = 3,
|
||||
PCI_VIRTIO_RNG_DEVNUM = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
VIRTIO_BLK_PIN = 1,
|
||||
VIRTIO_CONSOLE_PIN = 2,
|
||||
VIRTIO_NET_PIN = 3,
|
||||
VIRTIO_RNG_PIN = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
VIRTIO_RNG_IRQ = 11,
|
||||
VIRTIO_CONSOLE_IRQ = 13,
|
||||
VIRTIO_NET_IRQ = 14,
|
||||
VIRTIO_BLK_IRQ = 15,
|
||||
};
|
||||
|
||||
#endif /* VIRTIO_PCI_DEV_H_ */
|
||||
|
||||
+11
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "kvm/virtio-pci.h"
|
||||
#include "kvm/virtio-pci-dev.h"
|
||||
|
||||
#include "kvm/irq.h"
|
||||
#include "kvm/disk-image.h"
|
||||
#include "kvm/virtio.h"
|
||||
#include "kvm/ioport.h"
|
||||
@@ -103,7 +103,7 @@ static bool virtio_blk_pci_io_in(struct kvm *self, u16 port, void *data, int siz
|
||||
break;
|
||||
case VIRTIO_PCI_ISR:
|
||||
ioport__write8(data, 0x1);
|
||||
kvm__irq_line(self, VIRTIO_BLK_IRQ + bdev->idx, 0);
|
||||
kvm__irq_line(self, bdev->pci_device.irq_line, 0);
|
||||
break;
|
||||
case VIRTIO_MSI_CONFIG_VECTOR:
|
||||
ioport__write16(data, bdev->config_vector);
|
||||
@@ -167,7 +167,7 @@ static void virtio_blk_do_io(struct kvm *kvm, void *param)
|
||||
while (virt_queue__available(vq))
|
||||
virtio_blk_do_io_request(kvm, bdev, vq);
|
||||
|
||||
kvm__irq_line(kvm, VIRTIO_BLK_IRQ + bdev->idx, 1);
|
||||
kvm__irq_line(kvm, bdev->pci_device.irq_line, 1);
|
||||
}
|
||||
|
||||
static bool virtio_blk_pci_io_out(struct kvm *self, u16 port, void *data, int size, u32 count)
|
||||
@@ -257,6 +257,7 @@ static int virtio_blk_find_empty_dev(void)
|
||||
void virtio_blk__init(struct kvm *self, struct disk_image *disk)
|
||||
{
|
||||
u16 blk_dev_base_addr;
|
||||
u8 dev, pin, line;
|
||||
struct blk_dev *bdev;
|
||||
int new_dev_idx;
|
||||
|
||||
@@ -291,12 +292,16 @@ void virtio_blk__init(struct kvm *self, struct disk_image *disk)
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_BLK,
|
||||
.bar[0] = blk_dev_base_addr | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
.irq_pin = VIRTIO_BLK_PIN,
|
||||
.irq_line = VIRTIO_BLK_IRQ + new_dev_idx,
|
||||
},
|
||||
};
|
||||
|
||||
pci__register(&bdev->pci_device, PCI_VIRTIO_BLK_DEVNUM + new_dev_idx);
|
||||
if (irq__register_device(PCI_DEVICE_ID_VIRTIO_BLK, &dev, &pin, &line) < 0)
|
||||
return;
|
||||
|
||||
bdev->pci_device.irq_pin = pin;
|
||||
bdev->pci_device.irq_line = line;
|
||||
|
||||
pci__register(&bdev->pci_device, dev);
|
||||
|
||||
ioport__register(blk_dev_base_addr, &virtio_blk_io_ops, IOPORT_VIRTIO_BLK_SIZE);
|
||||
}
|
||||
|
||||
+23
-17
@@ -10,6 +10,7 @@
|
||||
#include "kvm/kvm.h"
|
||||
#include "kvm/pci.h"
|
||||
#include "kvm/threadpool.h"
|
||||
#include "kvm/irq.h"
|
||||
|
||||
#include <linux/virtio_console.h>
|
||||
#include <linux/virtio_ring.h>
|
||||
@@ -28,6 +29,17 @@
|
||||
#define VIRTIO_CONSOLE_RX_QUEUE 0
|
||||
#define VIRTIO_CONSOLE_TX_QUEUE 1
|
||||
|
||||
static struct pci_device_header virtio_console_pci_device = {
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
|
||||
.header_type = PCI_HEADER_TYPE_NORMAL,
|
||||
.revision_id = 0,
|
||||
.class = 0x078000,
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_CONSOLE,
|
||||
.bar[0] = IOPORT_VIRTIO_CONSOLE | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
};
|
||||
|
||||
struct con_dev {
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
@@ -73,7 +85,7 @@ static void virtio_console__inject_interrupt_callback(struct kvm *self, void *pa
|
||||
head = virt_queue__get_iov(vq, iov, &out, &in, self);
|
||||
len = term_getc_iov(CONSOLE_VIRTIO, iov, in);
|
||||
virt_queue__set_used_elem(vq, head, len);
|
||||
kvm__irq_line(self, VIRTIO_CONSOLE_IRQ, 1);
|
||||
kvm__irq_line(self, virtio_console_pci_device.irq_line, 1);
|
||||
}
|
||||
|
||||
mutex_unlock(&cdev.mutex);
|
||||
@@ -128,7 +140,7 @@ static bool virtio_console_pci_io_in(struct kvm *self, u16 port, void *data, int
|
||||
break;
|
||||
case VIRTIO_PCI_ISR:
|
||||
ioport__write8(data, 0x1);
|
||||
kvm__irq_line(self, VIRTIO_CONSOLE_IRQ, 0);
|
||||
kvm__irq_line(self, virtio_console_pci_device.irq_line, 0);
|
||||
break;
|
||||
case VIRTIO_MSI_CONFIG_VECTOR:
|
||||
ioport__write16(data, cdev.config_vector);
|
||||
@@ -158,7 +170,7 @@ static void virtio_console_handle_callback(struct kvm *self, void *param)
|
||||
virt_queue__set_used_elem(vq, head, len);
|
||||
}
|
||||
|
||||
kvm__irq_line(self, VIRTIO_CONSOLE_IRQ, 1);
|
||||
kvm__irq_line(self, virtio_console_pci_device.irq_line, 1);
|
||||
}
|
||||
|
||||
static bool virtio_console_pci_io_out(struct kvm *self, u16 port, void *data, int size, u32 count)
|
||||
@@ -222,21 +234,15 @@ static struct ioport_operations virtio_console_io_ops = {
|
||||
.io_out = virtio_console_pci_io_out,
|
||||
};
|
||||
|
||||
static struct pci_device_header virtio_console_pci_device = {
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
|
||||
.header_type = PCI_HEADER_TYPE_NORMAL,
|
||||
.revision_id = 0,
|
||||
.class = 0x078000,
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_CONSOLE,
|
||||
.bar[0] = IOPORT_VIRTIO_CONSOLE | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
.irq_pin = VIRTIO_CONSOLE_PIN,
|
||||
.irq_line = VIRTIO_CONSOLE_IRQ,
|
||||
};
|
||||
|
||||
void virtio_console__init(struct kvm *self)
|
||||
{
|
||||
pci__register(&virtio_console_pci_device, PCI_VIRTIO_CONSOLE_DEVNUM);
|
||||
u8 dev, line, pin;
|
||||
|
||||
if (irq__register_device(PCI_DEVICE_ID_VIRTIO_CONSOLE, &dev, &pin, &line) < 0)
|
||||
return;
|
||||
|
||||
virtio_console_pci_device.irq_pin = pin;
|
||||
virtio_console_pci_device.irq_line = line;
|
||||
pci__register(&virtio_console_pci_device, dev);
|
||||
ioport__register(IOPORT_VIRTIO_CONSOLE, &virtio_console_io_ops, IOPORT_VIRTIO_CONSOLE_SIZE);
|
||||
}
|
||||
|
||||
+23
-17
@@ -8,6 +8,7 @@
|
||||
#include "kvm/util.h"
|
||||
#include "kvm/kvm.h"
|
||||
#include "kvm/pci.h"
|
||||
#include "kvm/irq.h"
|
||||
|
||||
#include <linux/virtio_net.h>
|
||||
#include <linux/if_tun.h>
|
||||
@@ -26,6 +27,17 @@
|
||||
#define VIRTIO_NET_RX_QUEUE 0
|
||||
#define VIRTIO_NET_TX_QUEUE 1
|
||||
|
||||
static struct pci_device_header virtio_net_pci_device = {
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_NET,
|
||||
.header_type = PCI_HEADER_TYPE_NORMAL,
|
||||
.revision_id = 0,
|
||||
.class = 0x020000,
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_NET,
|
||||
.bar[0] = IOPORT_VIRTIO_NET | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
};
|
||||
|
||||
struct net_device {
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
@@ -91,7 +103,7 @@ static void *virtio_net_rx_thread(void *p)
|
||||
virt_queue__set_used_elem(vq, head, len);
|
||||
|
||||
/* We should interrupt guest right now, otherwise latency is huge. */
|
||||
virt_queue__trigger_irq(vq, VIRTIO_NET_IRQ, &net_device.isr, self);
|
||||
virt_queue__trigger_irq(vq, virtio_net_pci_device.irq_line, &net_device.isr, self);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -125,7 +137,7 @@ static void *virtio_net_tx_thread(void *p)
|
||||
virt_queue__set_used_elem(vq, head, len);
|
||||
}
|
||||
|
||||
virt_queue__trigger_irq(vq, VIRTIO_NET_IRQ, &net_device.isr, self);
|
||||
virt_queue__trigger_irq(vq, virtio_net_pci_device.irq_line, &net_device.isr, self);
|
||||
|
||||
}
|
||||
|
||||
@@ -179,7 +191,7 @@ static bool virtio_net_pci_io_in(struct kvm *self, u16 port, void *data, int siz
|
||||
break;
|
||||
case VIRTIO_PCI_ISR:
|
||||
ioport__write8(data, net_device.isr);
|
||||
kvm__irq_line(self, VIRTIO_NET_IRQ, VIRTIO_IRQ_LOW);
|
||||
kvm__irq_line(self, virtio_net_pci_device.irq_line, VIRTIO_IRQ_LOW);
|
||||
net_device.isr = VIRTIO_IRQ_LOW;
|
||||
break;
|
||||
case VIRTIO_MSI_CONFIG_VECTOR:
|
||||
@@ -270,19 +282,6 @@ static struct ioport_operations virtio_net_io_ops = {
|
||||
.io_out = virtio_net_pci_io_out,
|
||||
};
|
||||
|
||||
static struct pci_device_header virtio_net_pci_device = {
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_NET,
|
||||
.header_type = PCI_HEADER_TYPE_NORMAL,
|
||||
.revision_id = 0,
|
||||
.class = 0x020000,
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_NET,
|
||||
.bar[0] = IOPORT_VIRTIO_NET | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
.irq_pin = VIRTIO_NET_PIN,
|
||||
.irq_line = VIRTIO_NET_IRQ,
|
||||
};
|
||||
|
||||
static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
|
||||
{
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
@@ -384,7 +383,14 @@ static void virtio_net__io_thread_init(struct kvm *self)
|
||||
void virtio_net__init(const struct virtio_net_parameters *params)
|
||||
{
|
||||
if (virtio_net__tap_init(params)) {
|
||||
pci__register(&virtio_net_pci_device, PCI_VIRTIO_NET_DEVNUM);
|
||||
u8 dev, line, pin;
|
||||
|
||||
if (irq__register_device(PCI_DEVICE_ID_VIRTIO_NET, &dev, &pin, &line) < 0)
|
||||
return;
|
||||
|
||||
virtio_net_pci_device.irq_pin = pin;
|
||||
virtio_net_pci_device.irq_line = line;
|
||||
pci__register(&virtio_net_pci_device, dev);
|
||||
ioport__register(IOPORT_VIRTIO_NET, &virtio_net_io_ops, IOPORT_VIRTIO_NET_SIZE);
|
||||
|
||||
virtio_net__io_thread_init(params->self);
|
||||
|
||||
+28
-22
@@ -11,6 +11,7 @@
|
||||
#include "kvm/kvm.h"
|
||||
#include "kvm/pci.h"
|
||||
#include "kvm/threadpool.h"
|
||||
#include "kvm/irq.h"
|
||||
|
||||
#include <linux/virtio_ring.h>
|
||||
#include <linux/virtio_rng.h>
|
||||
@@ -23,15 +24,26 @@
|
||||
#define NUM_VIRT_QUEUES 1
|
||||
#define VIRTIO_RNG_QUEUE_SIZE 128
|
||||
|
||||
static struct pci_device_header virtio_rng_pci_device = {
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_RNG,
|
||||
.header_type = PCI_HEADER_TYPE_NORMAL,
|
||||
.revision_id = 0,
|
||||
.class = 0x010000,
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_RNG,
|
||||
.bar[0] = IOPORT_VIRTIO_RNG | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
};
|
||||
|
||||
struct rng_dev {
|
||||
u8 status;
|
||||
u16 config_vector;
|
||||
int fd;
|
||||
u8 status;
|
||||
u16 config_vector;
|
||||
int fd;
|
||||
|
||||
/* virtio queue */
|
||||
u16 queue_selector;
|
||||
struct virt_queue vqs[NUM_VIRT_QUEUES];
|
||||
void *jobs[NUM_VIRT_QUEUES];
|
||||
u16 queue_selector;
|
||||
struct virt_queue vqs[NUM_VIRT_QUEUES];
|
||||
void *jobs[NUM_VIRT_QUEUES];
|
||||
};
|
||||
|
||||
static struct rng_dev rdev;
|
||||
@@ -61,7 +73,7 @@ static bool virtio_rng_pci_io_in(struct kvm *kvm, u16 port, void *data, int size
|
||||
break;
|
||||
case VIRTIO_PCI_ISR:
|
||||
ioport__write8(data, 0x1);
|
||||
kvm__irq_line(kvm, VIRTIO_RNG_IRQ, 0);
|
||||
kvm__irq_line(kvm, virtio_rng_pci_device.irq_line, 0);
|
||||
break;
|
||||
case VIRTIO_MSI_CONFIG_VECTOR:
|
||||
ioport__write16(data, rdev.config_vector);
|
||||
@@ -94,7 +106,7 @@ static void virtio_rng_do_io(struct kvm *kvm, void *param)
|
||||
|
||||
while (virt_queue__available(vq)) {
|
||||
virtio_rng_do_io_request(kvm, vq);
|
||||
kvm__irq_line(kvm, VIRTIO_RNG_IRQ, 1);
|
||||
kvm__irq_line(kvm, virtio_rng_pci_device.irq_line, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,26 +163,20 @@ static struct ioport_operations virtio_rng_io_ops = {
|
||||
.io_out = virtio_rng_pci_io_out,
|
||||
};
|
||||
|
||||
static struct pci_device_header virtio_rng_pci_device = {
|
||||
.vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.device_id = PCI_DEVICE_ID_VIRTIO_RNG,
|
||||
.header_type = PCI_HEADER_TYPE_NORMAL,
|
||||
.revision_id = 0,
|
||||
.class = 0x010000,
|
||||
.subsys_vendor_id = PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
|
||||
.subsys_id = PCI_SUBSYSTEM_ID_VIRTIO_RNG,
|
||||
.bar[0] = IOPORT_VIRTIO_RNG | PCI_BASE_ADDRESS_SPACE_IO,
|
||||
.irq_pin = VIRTIO_RNG_PIN,
|
||||
.irq_line = VIRTIO_RNG_IRQ,
|
||||
};
|
||||
|
||||
void virtio_rng__init(struct kvm *kvm)
|
||||
{
|
||||
u8 pin, line, dev;
|
||||
|
||||
rdev.fd = open("/dev/urandom", O_RDONLY);
|
||||
if (rdev.fd < 0)
|
||||
die("Failed initializing RNG");
|
||||
|
||||
pci__register(&virtio_rng_pci_device, PCI_VIRTIO_RNG_DEVNUM);
|
||||
if (irq__register_device(PCI_DEVICE_ID_VIRTIO_RNG, &dev, &pin, &line) < 0)
|
||||
return;
|
||||
|
||||
virtio_rng_pci_device.irq_pin = pin;
|
||||
virtio_rng_pci_device.irq_line = line;
|
||||
pci__register(&virtio_rng_pci_device, dev);
|
||||
|
||||
ioport__register(IOPORT_VIRTIO_RNG, &virtio_rng_io_ops, IOPORT_VIRTIO_RNG_SIZE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user