[RFC] QEMU: Balloon support for device assignment

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Eran Borovik <borove@xxxxxxxxxx>

This patch adds modifications to allow correct
balloon operation when a virtual guest uses a direct assigned device.
The modifications include a new interface between qemu and kvm to allow
mapping and unmapping the pages from the IOMMU as well as pinning and unpinning as needed.

Signed-off-by: Eran Borovik <borove@xxxxxxxxxx>
---
 hw/virtio-balloon.c     |   13 ++++++++++---
 kvm/include/linux/kvm.h |    2 ++
 kvm/libkvm/libkvm.h     |    4 ++++
 qemu-kvm.c              |   10 ++++++++++
 qemu-kvm.h              |    4 ++++
 5 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 3792012..337f717 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -132,6 +132,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
                                     elem.out_sg, elem.out_num) == 4) {
             ram_addr_t pa;
             ram_addr_t addr;
+	    bool deflate;
 
             pa = (ram_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT;
             offset += 4;
@@ -139,12 +140,18 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
             addr = cpu_get_physical_page_desc(pa);
             if ((addr & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
                 continue;
+	    deflate = !!(vq == s->dvq);
+#	    ifdef KVM_CAP_DEVICE_ASSIGNMENT
+	    if (deflate)
+		kvm_map_pfn(NULL, pfn);
+	    else
+		kvm_unmap_pfn(NULL, pfn);
+#	    endif
 
             /* Using qemu_get_ram_ptr is bending the rules a bit, but
                should be OK because we only want a single page.  */
-            balloon_page(qemu_get_ram_ptr(addr), !!(vq == s->dvq));
-        }
-
+	    balloon_page(qemu_get_ram_ptr(addr), deflate);
+	}
         virtqueue_push(vq, &elem, offset);
         virtio_notify(vdev, vq);
     }
diff --git a/kvm/include/linux/kvm.h b/kvm/include/linux/kvm.h
index 6485981..90f7723 100644
--- a/kvm/include/linux/kvm.h
+++ b/kvm/include/linux/kvm.h
@@ -595,6 +595,8 @@ struct kvm_clock_data {
 					struct kvm_userspace_memory_region)
 #define KVM_SET_TSS_ADDR          _IO(KVMIO,   0x47)
 #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO,  0x48, __u64)
+#define KVM_IOMMU_UNMAP_PAGE  _IOW(KVMIO, 0x49, __u64)
+#define KVM_IOMMU_MAP_PAGE  _IOW(KVMIO, 0x50, __u64)
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP        _IO(KVMIO,   0x60)
 #define KVM_IRQ_LINE              _IOW(KVMIO,  0x61, struct kvm_irq_level)
diff --git a/kvm/libkvm/libkvm.h b/kvm/libkvm/libkvm.h
index 4821a1e..7fa83b5 100644
--- a/kvm/libkvm/libkvm.h
+++ b/kvm/libkvm/libkvm.h
@@ -714,6 +714,10 @@ int kvm_s390_store_status(kvm_context_t kvm, int slot, unsigned long addr);
 int kvm_assign_pci_device(kvm_context_t kvm,
 			  struct kvm_assigned_pci_dev *assigned_dev);
 
+int kvm_deflate_pfn(kvm_context_t kvm, uint32_t pfn);
+
+int kvm_inflate_pfn(kvm_context_t kvm, uint32_t pfn);
+
 /*!
  * \brief Assign IRQ for an assigned device
  *
diff --git a/qemu-kvm.c b/qemu-kvm.c
index a305907..a5ca029 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1081,6 +1081,16 @@ static int kvm_old_assign_irq(kvm_context_t kvm,
     return kvm_vm_ioctl(kvm_state, KVM_ASSIGN_IRQ, assigned_irq);
 }
 
+int kvm_unmap_pfn(kvm_context_t kvm, uint32_t pfn)
+{
+       return kvm_vm_ioctl(kvm_state, KVM_IOMMU_UNMAP_PAGE, pfn);
+}
+
+int kvm_map_pfn(kvm_context_t kvm, uint32_t pfn)
+{
+       return kvm_vm_ioctl(kvm_state, KVM_IOMMU_MAP_PAGE, pfn);
+}
+
 #ifdef KVM_CAP_ASSIGN_DEV_IRQ
 int kvm_assign_irq(kvm_context_t kvm, struct kvm_assigned_irq *assigned_irq)
 {
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 6b3e5a1..861c336 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -691,6 +691,10 @@ int kvm_s390_store_status(kvm_context_t kvm, int slot, unsigned long addr);
 int kvm_assign_pci_device(kvm_context_t kvm,
                           struct kvm_assigned_pci_dev *assigned_dev);
 
+int kvm_unmap_pfn(kvm_context_t kvm, uint32_t pfn);
+
+int kvm_map_pfn(kvm_context_t kvm, uint32_t pfn);
+
 /*!
  * \brief Assign IRQ for an assigned device
  *
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux