virtio: revert config interrupt changes
Lots of fallout from config interrupt changes. Author wants to rework the patches. Let's revert quickly so others don't suffer meanwhile. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmHcnzAPHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRpPQEH/2Kwx1xc8P3U4UULco1VlQ//mC0l0QBJTVpt qrt0HFEmXvO8G//ybWeqiwGO88aZ4oaskQN4JxnqJ+QmRp8VA7XDM1QyH6lNdIzt tT0xay5QXn/fOZIPwzRYJMqnvrei2mkeIIT60E9BBqVL/c+r3bHGkzmE1sFBSE14 k/el3le/FJ7eaxU8WnddoIxjKmc9R6xpno96TRiAphdsI7OizHvaMYJ4swE+yQ21 UHoZkkrJxE3RV7t99CQXHAA2FZIjVtPOegro0t+7a1/EqxRtKkuUJIJSpFWThbWf I95BGx8m8g+sDqUYSf6wLR57PQLcOUC1aQqP5N1bptAmyKgR+1I= =yQ3c -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging virtio: revert config interrupt changes Lots of fallout from config interrupt changes. Author wants to rework the patches. Let's revert quickly so others don't suffer meanwhile. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Mon 10 Jan 2022 21:03:44 GMT # 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: Revert "virtio: introduce macro IRTIO_CONFIG_IRQ_IDX" Revert "virtio-pci: decouple notifier from interrupt process" Revert "virtio-pci: decouple the single vector from the interrupt process" Revert "vhost: introduce new VhostOps vhost_set_config_call" Revert "vhost-vdpa: add support for config interrupt" Revert "virtio: add support for configure interrupt" Revert "vhost: add support for configure interrupt" Revert "virtio-net: add support for configure interrupt" Revert "virtio-mmio: add support for configure interrupt" Revert "virtio-pci: add support for configure interrupt" Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
bf99e0ec9a
@ -485,9 +485,6 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
|
|||||||
{
|
{
|
||||||
VhostUserGPU *g = VHOST_USER_GPU(vdev);
|
VhostUserGPU *g = VHOST_USER_GPU(vdev);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return vhost_virtqueue_pending(&g->vhost->dev, idx);
|
return vhost_virtqueue_pending(&g->vhost->dev, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,9 +493,6 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
|
|||||||
{
|
{
|
||||||
VhostUserGPU *g = VHOST_USER_GPU(vdev);
|
VhostUserGPU *g = VHOST_USER_GPU(vdev);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
|
vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,12 +101,3 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vhost_net_config_pending(VHostNetState *net)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
@ -457,15 +457,6 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
|
|||||||
vhost_virtqueue_mask(&net->dev, dev, idx, mask);
|
vhost_virtqueue_mask(&net->dev, dev, idx, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vhost_net_config_pending(VHostNetState *net)
|
|
||||||
{
|
|
||||||
return vhost_config_pending(&net->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask)
|
|
||||||
{
|
|
||||||
vhost_config_mask(&net->dev, dev, mask);
|
|
||||||
}
|
|
||||||
VHostNetState *get_vhost_net(NetClientState *nc)
|
VHostNetState *get_vhost_net(NetClientState *nc)
|
||||||
{
|
{
|
||||||
VHostNetState *vhost_net = 0;
|
VHostNetState *vhost_net = 0;
|
||||||
|
@ -3168,9 +3168,6 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
|
|||||||
VirtIONet *n = VIRTIO_NET(vdev);
|
VirtIONet *n = VIRTIO_NET(vdev);
|
||||||
NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
|
NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
|
||||||
assert(n->vhost_started);
|
assert(n->vhost_started);
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return vhost_net_config_pending(get_vhost_net(nc->peer));
|
|
||||||
}
|
|
||||||
return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
|
return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3180,11 +3177,8 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
|
|||||||
VirtIONet *n = VIRTIO_NET(vdev);
|
VirtIONet *n = VIRTIO_NET(vdev);
|
||||||
NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
|
NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx));
|
||||||
assert(n->vhost_started);
|
assert(n->vhost_started);
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
|
||||||
vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask);
|
vdev, idx, mask);
|
||||||
return;
|
|
||||||
}
|
|
||||||
vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
|
static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
|
||||||
|
@ -53,7 +53,6 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI
|
|||||||
vhost_vdpa_set_owner(void *dev) "dev: %p"
|
vhost_vdpa_set_owner(void *dev) "dev: %p"
|
||||||
vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
|
vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
|
||||||
vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
|
vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
|
||||||
vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d"
|
|
||||||
|
|
||||||
# virtio.c
|
# virtio.c
|
||||||
virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
|
virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
|
||||||
|
@ -161,9 +161,6 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx,
|
|||||||
{
|
{
|
||||||
VHostUserFS *fs = VHOST_USER_FS(vdev);
|
VHostUserFS *fs = VHOST_USER_FS(vdev);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
|
vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +168,6 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx)
|
|||||||
{
|
{
|
||||||
VHostUserFS *fs = VHOST_USER_FS(vdev);
|
VHostUserFS *fs = VHOST_USER_FS(vdev);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return vhost_virtqueue_pending(&fs->vhost_dev, idx);
|
return vhost_virtqueue_pending(&fs->vhost_dev, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,12 +734,6 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
|
|||||||
trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
|
trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
|
||||||
return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
|
return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
|
||||||
}
|
}
|
||||||
static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
|
|
||||||
int fd)
|
|
||||||
{
|
|
||||||
trace_vhost_vdpa_set_config_call(dev, fd);
|
|
||||||
return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, &fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vhost_vdpa_get_features(struct vhost_dev *dev,
|
static int vhost_vdpa_get_features(struct vhost_dev *dev,
|
||||||
uint64_t *features)
|
uint64_t *features)
|
||||||
@ -810,5 +804,4 @@ const VhostOps vdpa_ops = {
|
|||||||
.vhost_get_device_id = vhost_vdpa_get_device_id,
|
.vhost_get_device_id = vhost_vdpa_get_device_id,
|
||||||
.vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
|
.vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
|
||||||
.vhost_force_iommu = vhost_vdpa_force_iommu,
|
.vhost_force_iommu = vhost_vdpa_force_iommu,
|
||||||
.vhost_set_config_call = vhost_vdpa_set_config_call,
|
|
||||||
};
|
};
|
||||||
|
@ -125,9 +125,6 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx,
|
|||||||
{
|
{
|
||||||
VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
|
VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask);
|
vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,9 +133,6 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev,
|
|||||||
{
|
{
|
||||||
VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
|
VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return vhost_virtqueue_pending(&vvc->vhost_dev, idx);
|
return vhost_virtqueue_pending(&vvc->vhost_dev, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1554,67 +1554,6 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vhost_config_pending(struct vhost_dev *hdev)
|
|
||||||
{
|
|
||||||
assert(hdev->vhost_ops);
|
|
||||||
if ((hdev->started == false) ||
|
|
||||||
(hdev->vhost_ops->vhost_set_config_call == NULL)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventNotifier *notifier =
|
|
||||||
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
|
|
||||||
return event_notifier_test_and_clear(notifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int r;
|
|
||||||
EventNotifier *notifier =
|
|
||||||
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
|
|
||||||
EventNotifier *config_notifier = &vdev->config_notifier;
|
|
||||||
assert(hdev->vhost_ops);
|
|
||||||
|
|
||||||
if ((hdev->started == false) ||
|
|
||||||
(hdev->vhost_ops->vhost_set_config_call == NULL)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mask) {
|
|
||||||
assert(vdev->use_guest_notifier_mask);
|
|
||||||
fd = event_notifier_get_fd(notifier);
|
|
||||||
} else {
|
|
||||||
fd = event_notifier_get_fd(config_notifier);
|
|
||||||
}
|
|
||||||
r = hdev->vhost_ops->vhost_set_config_call(hdev, fd);
|
|
||||||
if (r < 0) {
|
|
||||||
VHOST_OPS_DEBUG(r, "vhost_set_config_call failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vhost_stop_config_intr(struct vhost_dev *dev)
|
|
||||||
{
|
|
||||||
int fd = -1;
|
|
||||||
assert(dev->vhost_ops);
|
|
||||||
if (dev->vhost_ops->vhost_set_config_call) {
|
|
||||||
dev->vhost_ops->vhost_set_config_call(dev, fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vhost_start_config_intr(struct vhost_dev *dev)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(dev->vhost_ops);
|
|
||||||
int fd = event_notifier_get_fd(&dev->vdev->config_notifier);
|
|
||||||
if (dev->vhost_ops->vhost_set_config_call) {
|
|
||||||
r = dev->vhost_ops->vhost_set_config_call(dev, fd);
|
|
||||||
if (!r) {
|
|
||||||
event_notifier_set(&dev->vdev->config_notifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
|
uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
|
||||||
uint64_t features)
|
uint64_t features)
|
||||||
{
|
{
|
||||||
@ -1827,16 +1766,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = event_notifier_init(
|
|
||||||
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0);
|
|
||||||
if (r < 0) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
event_notifier_test_and_clear(
|
|
||||||
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
|
|
||||||
if (!vdev->use_guest_notifier_mask) {
|
|
||||||
vhost_config_mask(hdev, vdev, true);
|
|
||||||
}
|
|
||||||
if (hdev->log_enabled) {
|
if (hdev->log_enabled) {
|
||||||
uint64_t log_base;
|
uint64_t log_base;
|
||||||
|
|
||||||
@ -1869,7 +1798,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
|
|||||||
vhost_device_iotlb_miss(hdev, vq->used_phys, true);
|
vhost_device_iotlb_miss(hdev, vq->used_phys, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vhost_start_config_intr(hdev);
|
|
||||||
return 0;
|
return 0;
|
||||||
fail_log:
|
fail_log:
|
||||||
vhost_log_put(hdev, false);
|
vhost_log_put(hdev, false);
|
||||||
@ -1895,9 +1823,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
|
|||||||
|
|
||||||
/* should only be called after backend is connected */
|
/* should only be called after backend is connected */
|
||||||
assert(hdev->vhost_ops);
|
assert(hdev->vhost_ops);
|
||||||
event_notifier_test_and_clear(
|
|
||||||
&hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
|
|
||||||
event_notifier_test_and_clear(&vdev->config_notifier);
|
|
||||||
|
|
||||||
if (hdev->vhost_ops->vhost_dev_start) {
|
if (hdev->vhost_ops->vhost_dev_start) {
|
||||||
hdev->vhost_ops->vhost_dev_start(hdev, false);
|
hdev->vhost_ops->vhost_dev_start(hdev, false);
|
||||||
@ -1915,7 +1840,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
|
|||||||
}
|
}
|
||||||
memory_listener_unregister(&hdev->iommu_listener);
|
memory_listener_unregister(&hdev->iommu_listener);
|
||||||
}
|
}
|
||||||
vhost_stop_config_intr(hdev);
|
|
||||||
vhost_log_put(hdev, true);
|
vhost_log_put(hdev, true);
|
||||||
hdev->started = false;
|
hdev->started = false;
|
||||||
hdev->vdev = NULL;
|
hdev->vdev = NULL;
|
||||||
|
@ -948,9 +948,6 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx,
|
|||||||
|
|
||||||
assert(vcrypto->vhost_started);
|
assert(vcrypto->vhost_started);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
|
cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,9 +958,6 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx)
|
|||||||
|
|
||||||
assert(vcrypto->vhost_started);
|
assert(vcrypto->vhost_started);
|
||||||
|
|
||||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
|
return cryptodev_vhost_virtqueue_pending(vdev, queue, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,30 +673,7 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign)
|
|
||||||
{
|
|
||||||
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
|
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
|
||||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
|
||||||
bool with_irqfd = false;
|
|
||||||
EventNotifier *notifier = virtio_config_get_guest_notifier(vdev);
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
if (assign) {
|
|
||||||
r = event_notifier_init(notifier, 0);
|
|
||||||
if (r < 0) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
|
|
||||||
} else {
|
|
||||||
virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
|
|
||||||
event_notifier_cleanup(notifier);
|
|
||||||
}
|
|
||||||
if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
|
|
||||||
vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
|
static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
|
||||||
bool assign)
|
bool assign)
|
||||||
{
|
{
|
||||||
@ -718,10 +695,6 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
|
|||||||
goto assign_error;
|
goto assign_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = virtio_mmio_set_config_guest_notifier(d, assign);
|
|
||||||
if (r < 0) {
|
|
||||||
goto assign_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -677,6 +677,7 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
|
static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
|
||||||
|
unsigned int queue_no,
|
||||||
unsigned int vector)
|
unsigned int vector)
|
||||||
{
|
{
|
||||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||||
@ -703,160 +704,112 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
|
static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
|
||||||
EventNotifier *n,
|
unsigned int queue_no,
|
||||||
unsigned int vector)
|
unsigned int vector)
|
||||||
{
|
{
|
||||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||||
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
|
VirtQueue *vq = virtio_get_queue(vdev, queue_no);
|
||||||
|
EventNotifier *n = virtio_queue_get_guest_notifier(vq);
|
||||||
return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
|
return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
|
static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
|
||||||
EventNotifier *n ,
|
unsigned int queue_no,
|
||||||
unsigned int vector)
|
unsigned int vector)
|
||||||
{
|
{
|
||||||
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
|
VirtQueue *vq = virtio_get_queue(vdev, queue_no);
|
||||||
|
EventNotifier *n = virtio_queue_get_guest_notifier(vq);
|
||||||
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
|
ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
}
|
}
|
||||||
static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
|
|
||||||
EventNotifier **n, unsigned int *vector)
|
|
||||||
{
|
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
|
||||||
VirtQueue *vq;
|
|
||||||
|
|
||||||
if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
*n = virtio_config_get_guest_notifier(vdev);
|
|
||||||
*vector = vdev->config_vector;
|
|
||||||
} else {
|
|
||||||
if (!virtio_queue_get_num(vdev, queue_no)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*vector = virtio_queue_vector(vdev, queue_no);
|
|
||||||
vq = virtio_get_queue(vdev, queue_no);
|
|
||||||
*n = virtio_queue_get_guest_notifier(vq);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no)
|
|
||||||
{
|
|
||||||
unsigned int vector;
|
|
||||||
int ret;
|
|
||||||
EventNotifier *n;
|
|
||||||
PCIDevice *dev = &proxy->pci_dev;
|
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
|
||||||
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
|
||||||
|
|
||||||
ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
|
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (vector >= msix_nr_vectors_allocated(dev)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto undo;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If guest supports masking, set up irqfd now.
|
|
||||||
* Otherwise, delay until unmasked in the frontend.
|
|
||||||
*/
|
|
||||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
|
||||||
ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
|
|
||||||
if (ret < 0) {
|
|
||||||
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
|
||||||
goto undo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
undo:
|
|
||||||
|
|
||||||
vector = virtio_queue_vector(vdev, queue_no);
|
|
||||||
if (vector >= msix_nr_vectors_allocated(dev)) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
|
||||||
ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
|
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
kvm_virtio_pci_irqfd_release(proxy, n, vector);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
|
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
|
||||||
{
|
{
|
||||||
int queue_no;
|
|
||||||
int ret = 0;
|
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
|
||||||
|
|
||||||
for (queue_no = 0; queue_no < nvqs; queue_no++) {
|
|
||||||
if (!virtio_queue_get_num(vdev, queue_no)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ret = kvm_virtio_pci_vector_use_one(proxy, queue_no);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
|
|
||||||
{
|
|
||||||
return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy,
|
|
||||||
int queue_no)
|
|
||||||
{
|
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
|
||||||
unsigned int vector;
|
|
||||||
EventNotifier *n;
|
|
||||||
int ret;
|
|
||||||
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
|
||||||
PCIDevice *dev = &proxy->pci_dev;
|
PCIDevice *dev = &proxy->pci_dev;
|
||||||
|
|
||||||
ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector);
|
|
||||||
if (ret < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (vector >= msix_nr_vectors_allocated(dev)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
|
||||||
kvm_virtio_pci_irqfd_release(proxy, n, vector);
|
|
||||||
}
|
|
||||||
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
|
|
||||||
{
|
|
||||||
int queue_no;
|
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
|
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||||
|
unsigned int vector;
|
||||||
|
int ret, queue_no;
|
||||||
|
|
||||||
for (queue_no = 0; queue_no < nvqs; queue_no++) {
|
for (queue_no = 0; queue_no < nvqs; queue_no++) {
|
||||||
if (!virtio_queue_get_num(vdev, queue_no)) {
|
if (!virtio_queue_get_num(vdev, queue_no)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
kvm_virtio_pci_vector_release_one(proxy, queue_no);
|
vector = virtio_queue_vector(vdev, queue_no);
|
||||||
|
if (vector >= msix_nr_vectors_allocated(dev)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto undo;
|
||||||
|
}
|
||||||
|
/* If guest supports masking, set up irqfd now.
|
||||||
|
* Otherwise, delay until unmasked in the frontend.
|
||||||
|
*/
|
||||||
|
if (vdev->use_guest_notifier_mask && 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);
|
||||||
|
goto undo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
undo:
|
||||||
|
while (--queue_no >= 0) {
|
||||||
|
vector = virtio_queue_vector(vdev, queue_no);
|
||||||
|
if (vector >= msix_nr_vectors_allocated(dev)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||||
|
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
|
||||||
|
}
|
||||||
|
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
|
||||||
|
{
|
||||||
|
PCIDevice *dev = &proxy->pci_dev;
|
||||||
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
|
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)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
vector = virtio_queue_vector(vdev, queue_no);
|
||||||
|
if (vector >= msix_nr_vectors_allocated(dev)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* If guest supports masking, clean up irqfd now.
|
||||||
|
* Otherwise, it was cleaned when masked in the frontend.
|
||||||
|
*/
|
||||||
|
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||||
|
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
|
||||||
|
}
|
||||||
|
kvm_virtio_pci_vq_vector_release(proxy, vector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
|
static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
|
||||||
{
|
|
||||||
kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
|
|
||||||
unsigned int queue_no,
|
unsigned int queue_no,
|
||||||
unsigned int vector,
|
unsigned int vector,
|
||||||
MSIMessage msg,
|
MSIMessage msg)
|
||||||
EventNotifier *n)
|
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||||
|
VirtQueue *vq = virtio_get_queue(vdev, queue_no);
|
||||||
|
EventNotifier *n = virtio_queue_get_guest_notifier(vq);
|
||||||
VirtIOIRQFD *irqfd;
|
VirtIOIRQFD *irqfd;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -883,15 +836,14 @@ static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
|
|||||||
event_notifier_set(n);
|
event_notifier_set(n);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
|
ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy,
|
static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
|
||||||
unsigned int queue_no,
|
unsigned int queue_no,
|
||||||
unsigned int vector,
|
unsigned int vector)
|
||||||
EventNotifier *n)
|
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||||
@ -902,7 +854,7 @@ static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy,
|
|||||||
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
|
||||||
k->guest_notifier_mask(vdev, queue_no, true);
|
k->guest_notifier_mask(vdev, queue_no, true);
|
||||||
} else {
|
} else {
|
||||||
kvm_virtio_pci_irqfd_release(proxy, n, vector);
|
kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,7 +864,6 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
|
|||||||
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
|
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
|
VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
|
||||||
EventNotifier *n;
|
|
||||||
int ret, index, unmasked = 0;
|
int ret, index, unmasked = 0;
|
||||||
|
|
||||||
while (vq) {
|
while (vq) {
|
||||||
@ -921,8 +872,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index < proxy->nvqs_with_notifiers) {
|
if (index < proxy->nvqs_with_notifiers) {
|
||||||
n = virtio_queue_get_guest_notifier(vq);
|
ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
|
||||||
ret = virtio_pci_one_vector_unmask(proxy, index, vector, msg, n);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto undo;
|
goto undo;
|
||||||
}
|
}
|
||||||
@ -930,24 +880,15 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
|
|||||||
}
|
}
|
||||||
vq = virtio_vector_next_queue(vq);
|
vq = virtio_vector_next_queue(vq);
|
||||||
}
|
}
|
||||||
/* unmask config intr */
|
|
||||||
n = virtio_config_get_guest_notifier(vdev);
|
|
||||||
ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector,
|
|
||||||
msg, n);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto undo_config;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
undo_config:
|
|
||||||
n = virtio_config_get_guest_notifier(vdev);
|
|
||||||
virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n);
|
|
||||||
undo:
|
undo:
|
||||||
vq = virtio_vector_first_queue(vdev, vector);
|
vq = virtio_vector_first_queue(vdev, vector);
|
||||||
while (vq && unmasked >= 0) {
|
while (vq && unmasked >= 0) {
|
||||||
index = virtio_get_queue_index(vq);
|
index = virtio_get_queue_index(vq);
|
||||||
if (index < proxy->nvqs_with_notifiers) {
|
if (index < proxy->nvqs_with_notifiers) {
|
||||||
n = virtio_queue_get_guest_notifier(vq);
|
virtio_pci_vq_vector_mask(proxy, index, vector);
|
||||||
virtio_pci_one_vector_mask(proxy, index, vector, n);
|
|
||||||
--unmasked;
|
--unmasked;
|
||||||
}
|
}
|
||||||
vq = virtio_vector_next_queue(vq);
|
vq = virtio_vector_next_queue(vq);
|
||||||
@ -960,22 +901,18 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
|
|||||||
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
|
VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
|
VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
|
||||||
EventNotifier *n;
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
while (vq) {
|
while (vq) {
|
||||||
index = virtio_get_queue_index(vq);
|
index = virtio_get_queue_index(vq);
|
||||||
n = virtio_queue_get_guest_notifier(vq);
|
|
||||||
if (!virtio_queue_get_num(vdev, index)) {
|
if (!virtio_queue_get_num(vdev, index)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index < proxy->nvqs_with_notifiers) {
|
if (index < proxy->nvqs_with_notifiers) {
|
||||||
virtio_pci_one_vector_mask(proxy, index, vector, n);
|
virtio_pci_vq_vector_mask(proxy, index, vector);
|
||||||
}
|
}
|
||||||
vq = virtio_vector_next_queue(vq);
|
vq = virtio_vector_next_queue(vq);
|
||||||
}
|
}
|
||||||
n = virtio_config_get_guest_notifier(vdev);
|
|
||||||
virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_pci_vector_poll(PCIDevice *dev,
|
static void virtio_pci_vector_poll(PCIDevice *dev,
|
||||||
@ -988,17 +925,19 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
|
|||||||
int queue_no;
|
int queue_no;
|
||||||
unsigned int vector;
|
unsigned int vector;
|
||||||
EventNotifier *notifier;
|
EventNotifier *notifier;
|
||||||
int ret;
|
VirtQueue *vq;
|
||||||
|
|
||||||
for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
|
for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
|
||||||
ret = virtio_pci_get_notifier(proxy, queue_no, ¬ifier, &vector);
|
if (!virtio_queue_get_num(vdev, queue_no)) {
|
||||||
if (ret < 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
vector = virtio_queue_vector(vdev, queue_no);
|
||||||
if (vector < vector_start || vector >= vector_end ||
|
if (vector < vector_start || vector >= vector_end ||
|
||||||
!msix_is_masked(dev, vector)) {
|
!msix_is_masked(dev, vector)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
vq = virtio_get_queue(vdev, queue_no);
|
||||||
|
notifier = virtio_queue_get_guest_notifier(vq);
|
||||||
if (k->guest_notifier_pending) {
|
if (k->guest_notifier_pending) {
|
||||||
if (k->guest_notifier_pending(vdev, queue_no)) {
|
if (k->guest_notifier_pending(vdev, queue_no)) {
|
||||||
msix_set_pending(dev, vector);
|
msix_set_pending(dev, vector);
|
||||||
@ -1007,34 +946,6 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
|
|||||||
msix_set_pending(dev, vector);
|
msix_set_pending(dev, vector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* poll the config intr */
|
|
||||||
ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, ¬ifier,
|
|
||||||
&vector);
|
|
||||||
if (ret < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (vector < vector_start || vector >= vector_end ||
|
|
||||||
!msix_is_masked(dev, vector)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (k->guest_notifier_pending) {
|
|
||||||
if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) {
|
|
||||||
msix_set_pending(dev, vector);
|
|
||||||
}
|
|
||||||
} else if (event_notifier_test_and_clear(notifier)) {
|
|
||||||
msix_set_pending(dev, vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
|
|
||||||
int n, bool assign,
|
|
||||||
bool with_irqfd)
|
|
||||||
{
|
|
||||||
if (n == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
|
|
||||||
} else {
|
|
||||||
virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
|
static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
|
||||||
@ -1043,25 +954,17 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
|
|||||||
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
|
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
|
||||||
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
|
||||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||||
VirtQueue *vq = NULL;
|
VirtQueue *vq = virtio_get_queue(vdev, n);
|
||||||
EventNotifier *notifier = NULL;
|
EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
|
||||||
|
|
||||||
if (n == VIRTIO_CONFIG_IRQ_IDX) {
|
|
||||||
notifier = virtio_config_get_guest_notifier(vdev);
|
|
||||||
} else {
|
|
||||||
vq = virtio_get_queue(vdev, n);
|
|
||||||
notifier = virtio_queue_get_guest_notifier(vq);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (assign) {
|
if (assign) {
|
||||||
int r = event_notifier_init(notifier, 0);
|
int r = event_notifier_init(notifier, 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, true, with_irqfd);
|
virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
|
||||||
} else {
|
} else {
|
||||||
virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, false,
|
virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
|
||||||
with_irqfd);
|
|
||||||
event_notifier_cleanup(notifier);
|
event_notifier_cleanup(notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1103,7 +1006,6 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
|
|||||||
msix_unset_vector_notifiers(&proxy->pci_dev);
|
msix_unset_vector_notifiers(&proxy->pci_dev);
|
||||||
if (proxy->vector_irqfd) {
|
if (proxy->vector_irqfd) {
|
||||||
kvm_virtio_pci_vector_release(proxy, nvqs);
|
kvm_virtio_pci_vector_release(proxy, nvqs);
|
||||||
kvm_virtio_pci_vector_config_release(proxy);
|
|
||||||
g_free(proxy->vector_irqfd);
|
g_free(proxy->vector_irqfd);
|
||||||
proxy->vector_irqfd = NULL;
|
proxy->vector_irqfd = NULL;
|
||||||
}
|
}
|
||||||
@ -1119,11 +1021,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
|
|||||||
goto assign_error;
|
goto assign_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, assign,
|
|
||||||
with_irqfd);
|
|
||||||
if (r < 0) {
|
|
||||||
goto config_assign_error;
|
|
||||||
}
|
|
||||||
/* Must set vector notifier after guest notifier has been assigned */
|
/* Must set vector notifier after guest notifier has been assigned */
|
||||||
if ((with_irqfd || k->guest_notifier_mask) && assign) {
|
if ((with_irqfd || k->guest_notifier_mask) && assign) {
|
||||||
if (with_irqfd) {
|
if (with_irqfd) {
|
||||||
@ -1132,14 +1030,11 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
|
|||||||
msix_nr_vectors_allocated(&proxy->pci_dev));
|
msix_nr_vectors_allocated(&proxy->pci_dev));
|
||||||
r = kvm_virtio_pci_vector_use(proxy, nvqs);
|
r = kvm_virtio_pci_vector_use(proxy, nvqs);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto config_assign_error;
|
goto assign_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = kvm_virtio_pci_vector_config_use(proxy);
|
r = msix_set_vector_notifiers(&proxy->pci_dev,
|
||||||
if (r < 0) {
|
virtio_pci_vector_unmask,
|
||||||
goto config_error;
|
|
||||||
}
|
|
||||||
r = msix_set_vector_notifiers(&proxy->pci_dev, virtio_pci_vector_unmask,
|
|
||||||
virtio_pci_vector_mask,
|
virtio_pci_vector_mask,
|
||||||
virtio_pci_vector_poll);
|
virtio_pci_vector_poll);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -1154,11 +1049,7 @@ notifiers_error:
|
|||||||
assert(assign);
|
assert(assign);
|
||||||
kvm_virtio_pci_vector_release(proxy, nvqs);
|
kvm_virtio_pci_vector_release(proxy, nvqs);
|
||||||
}
|
}
|
||||||
config_error:
|
|
||||||
kvm_virtio_pci_vector_config_release(proxy);
|
|
||||||
config_assign_error:
|
|
||||||
virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, !assign,
|
|
||||||
with_irqfd);
|
|
||||||
assign_error:
|
assign_error:
|
||||||
/* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
|
/* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
|
||||||
assert(assign);
|
assert(assign);
|
||||||
|
@ -251,7 +251,5 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t);
|
|||||||
* @fixed_queues.
|
* @fixed_queues.
|
||||||
*/
|
*/
|
||||||
unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
|
unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
|
||||||
void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
|
|
||||||
int n, bool assign,
|
|
||||||
bool with_irqfd);
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3494,14 +3494,7 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
|
|||||||
virtio_irq(vq);
|
virtio_irq(vq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void virtio_config_guest_notifier_read(EventNotifier *n)
|
|
||||||
{
|
|
||||||
VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
|
|
||||||
|
|
||||||
if (event_notifier_test_and_clear(n)) {
|
|
||||||
virtio_notify_config(vdev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
|
void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||||
bool with_irqfd)
|
bool with_irqfd)
|
||||||
{
|
{
|
||||||
@ -3518,23 +3511,6 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
|
|
||||||
bool assign, bool with_irqfd)
|
|
||||||
{
|
|
||||||
EventNotifier *n;
|
|
||||||
n = &vdev->config_notifier;
|
|
||||||
if (assign && !with_irqfd) {
|
|
||||||
event_notifier_set_handler(n, virtio_config_guest_notifier_read);
|
|
||||||
} else {
|
|
||||||
event_notifier_set_handler(n, NULL);
|
|
||||||
}
|
|
||||||
if (!assign) {
|
|
||||||
/* Test and clear notifier before closing it,*/
|
|
||||||
/* in case poll callback didn't have time to run. */
|
|
||||||
virtio_config_guest_notifier_read(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
|
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
|
||||||
{
|
{
|
||||||
return &vq->guest_notifier;
|
return &vq->guest_notifier;
|
||||||
@ -3608,11 +3584,6 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
|
|||||||
return &vq->host_notifier;
|
return &vq->host_notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev)
|
|
||||||
{
|
|
||||||
return &vdev->config_notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
|
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
|
||||||
{
|
{
|
||||||
vq->host_notifier_enabled = enabled;
|
vq->host_notifier_enabled = enabled;
|
||||||
|
@ -126,8 +126,6 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id);
|
|||||||
|
|
||||||
typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
|
typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
|
||||||
|
|
||||||
typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
|
|
||||||
int fd);
|
|
||||||
typedef struct VhostOps {
|
typedef struct VhostOps {
|
||||||
VhostBackendType backend_type;
|
VhostBackendType backend_type;
|
||||||
vhost_backend_init vhost_backend_init;
|
vhost_backend_init vhost_backend_init;
|
||||||
@ -173,7 +171,6 @@ typedef struct VhostOps {
|
|||||||
vhost_vq_get_addr_op vhost_vq_get_addr;
|
vhost_vq_get_addr_op vhost_vq_get_addr;
|
||||||
vhost_get_device_id_op vhost_get_device_id;
|
vhost_get_device_id_op vhost_get_device_id;
|
||||||
vhost_force_iommu_op vhost_force_iommu;
|
vhost_force_iommu_op vhost_force_iommu;
|
||||||
vhost_set_config_call_op vhost_set_config_call;
|
|
||||||
} VhostOps;
|
} VhostOps;
|
||||||
|
|
||||||
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
|
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
|
||||||
|
@ -29,7 +29,6 @@ struct vhost_virtqueue {
|
|||||||
unsigned long long used_phys;
|
unsigned long long used_phys;
|
||||||
unsigned used_size;
|
unsigned used_size;
|
||||||
EventNotifier masked_notifier;
|
EventNotifier masked_notifier;
|
||||||
EventNotifier masked_config_notifier;
|
|
||||||
struct vhost_dev *dev;
|
struct vhost_dev *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,7 +37,6 @@ typedef unsigned long vhost_log_chunk_t;
|
|||||||
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
|
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
|
||||||
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
|
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
|
||||||
#define VHOST_INVALID_FEATURE_BIT (0xff)
|
#define VHOST_INVALID_FEATURE_BIT (0xff)
|
||||||
#define VHOST_QUEUE_NUM_CONFIG_INR 0
|
|
||||||
|
|
||||||
struct vhost_log {
|
struct vhost_log {
|
||||||
unsigned long long size;
|
unsigned long long size;
|
||||||
@ -118,8 +116,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
|
|||||||
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
|
void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
|
||||||
int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
|
int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
|
||||||
void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
|
void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
|
||||||
bool vhost_config_pending(struct vhost_dev *hdev);
|
|
||||||
void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask);
|
|
||||||
|
|
||||||
/* Test and clear masked event pending status.
|
/* Test and clear masked event pending status.
|
||||||
* Should be called after unmask to avoid losing events.
|
* Should be called after unmask to avoid losing events.
|
||||||
|
@ -67,9 +67,6 @@ typedef struct VirtQueueElement
|
|||||||
|
|
||||||
#define VIRTIO_NO_VECTOR 0xffff
|
#define VIRTIO_NO_VECTOR 0xffff
|
||||||
|
|
||||||
/* special index value used internally for config irqs */
|
|
||||||
#define VIRTIO_CONFIG_IRQ_IDX -1
|
|
||||||
|
|
||||||
#define TYPE_VIRTIO_DEVICE "virtio-device"
|
#define TYPE_VIRTIO_DEVICE "virtio-device"
|
||||||
OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
|
OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE)
|
||||||
|
|
||||||
@ -111,7 +108,6 @@ struct VirtIODevice
|
|||||||
bool use_guest_notifier_mask;
|
bool use_guest_notifier_mask;
|
||||||
AddressSpace *dma_as;
|
AddressSpace *dma_as;
|
||||||
QLIST_HEAD(, VirtQueue) *vector_queues;
|
QLIST_HEAD(, VirtQueue) *vector_queues;
|
||||||
EventNotifier config_notifier;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VirtioDeviceClass {
|
struct VirtioDeviceClass {
|
||||||
@ -314,14 +310,11 @@ uint16_t virtio_get_queue_index(VirtQueue *vq);
|
|||||||
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
|
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
|
||||||
void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
|
void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||||
bool with_irqfd);
|
bool with_irqfd);
|
||||||
void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
|
|
||||||
bool assign, bool with_irqfd);
|
|
||||||
int virtio_device_start_ioeventfd(VirtIODevice *vdev);
|
int virtio_device_start_ioeventfd(VirtIODevice *vdev);
|
||||||
int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
|
int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
|
||||||
void virtio_device_release_ioeventfd(VirtIODevice *vdev);
|
void virtio_device_release_ioeventfd(VirtIODevice *vdev);
|
||||||
bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
|
bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
|
||||||
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
|
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
|
||||||
EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev);
|
|
||||||
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
|
void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
|
||||||
void virtio_queue_host_notifier_read(EventNotifier *n);
|
void virtio_queue_host_notifier_read(EventNotifier *n);
|
||||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||||
|
@ -39,8 +39,6 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data,
|
|||||||
bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
|
bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
|
||||||
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
|
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
|
||||||
int idx, bool mask);
|
int idx, bool mask);
|
||||||
bool vhost_net_config_pending(VHostNetState *net);
|
|
||||||
void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask);
|
|
||||||
int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
|
int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
|
||||||
VHostNetState *get_vhost_net(NetClientState *nc);
|
VHostNetState *get_vhost_net(NetClientState *nc);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user