[PATCH] cpu hotplug driver: userspace back end

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

 



Signed-off-by: Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>
---
 qemu/Makefile.target     |    2 +-
 qemu/hw/pc.c             |    4 +-
 qemu/hw/pc.h             |    3 +
 qemu/hw/virtio-hotplug.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++
 qemu/monitor.c           |   11 +++++
 qemu/qemu-kvm.h          |    2 +
 6 files changed, 131 insertions(+), 2 deletions(-)
 create mode 100644 qemu/hw/virtio-hotplug.c

diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index bb7be0f..4d5679a 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -464,7 +464,7 @@ VL_OBJS += rtl8139.o
 VL_OBJS+= hypercall.o
 
 # virtio devices
-VL_OBJS += virtio.o virtio-net.o virtio-blk.o
+VL_OBJS += virtio.o virtio-net.o virtio-blk.o virtio-hotplug.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 3972ab4..c9d8f89 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1029,7 +1029,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
         }
     }
 
-#define USE_HYPERCALL
+    virtio_hotplug_init(pci_bus);
+
+#undef USE_HYPERCALL
 #ifdef USE_HYPERCALL
     pci_hypercall_init(pci_bus);
 #endif
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index 7d1832f..3e2cfb4 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -151,6 +151,9 @@ void virtio_net_poll(void);
 void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
 		      BlockDriverState *bs);
 
+/* virtio-hotplug.c */
+void *virtio_hotplug_init(PCIBus *bus);
+
 /* extboot.c */
 
 void extboot_init(BlockDriverState *bs, int cmd);
diff --git a/qemu/hw/virtio-hotplug.c b/qemu/hw/virtio-hotplug.c
new file mode 100644
index 0000000..e51f26f
--- /dev/null
+++ b/qemu/hw/virtio-hotplug.c
@@ -0,0 +1,111 @@
+#include "virtio.h"
+#include "net.h"
+#include "pc.h"
+#include "sysemu.h"
+
+typedef struct VirtIOHotplug {
+    VirtIODevice vdev;
+    VirtQueue *cmd_vq;
+    int buffer_ready;
+    struct VirtIOHotplug *next;
+    int job_status;
+} VirtIOHotplug;
+
+typedef struct VirtioHotplugHdr {
+    uint8_t cmd;
+    uint8_t status;
+} VirtioHotplugHdr;
+
+VirtIOHotplug *virtio_hotplug;
+uint32_t attempt_buffer;
+
+#define VIRTIO_ID_HOTPLUG 4 /* arbitrary */
+
+#define CMD_CPU_SET 1
+
+static VirtIOHotplug *to_virtio_hotplug(VirtIODevice *vdev)
+{
+    return (VirtIOHotplug *)vdev;
+}
+
+static void virtio_hotplug_update_config(VirtIODevice *vdev, uint8_t *config)
+{
+    /* nothing to do */
+}
+
+static uint32_t virtio_hotplug_get_features(VirtIODevice *vdev)
+{
+    /* no features yet */
+    return 0;
+}
+
+static void virtio_hotplug_send(VirtIODevice *vdev, VirtQueue *vq, uint8_t cmd,
+    			const uint32_t arg)
+{
+    VirtQueueElement elem;
+    VirtioHotplugHdr *hdr;
+    uint32_t *data;
+
+    if (virtqueue_pop(vq, &elem) == 0) {
+        fprintf(stderr, "pop failure\n"); 
+        return;
+    }
+    
+    hdr = (void *)elem.in_sg[0].iov_base;
+    hdr->cmd = cmd;
+    
+    data = (int *)elem.in_sg[1].iov_base;
+    *data = arg;
+     
+    virtqueue_push(vq, &elem, sizeof(*hdr) + elem.in_sg[1].iov_len);
+    virtio_notify(vdev, vq);
+}
+
+int hotplug_send_cmd(int value)
+{
+   
+    if (!virtio_hotplug->buffer_ready) {
+        attempt_buffer = value;
+        return;
+    }
+
+    virtio_hotplug_send(&virtio_hotplug->vdev, virtio_hotplug->cmd_vq, 
+                        CMD_CPU_SET, value);
+
+    return 0;
+}
+
+/* TX */
+static void virtio_hotplug_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOHotplug *n = to_virtio_hotplug(vdev);
+
+    n->buffer_ready = 1;
+
+    if (attempt_buffer) {
+        uint32_t value = attempt_buffer;
+        attempt_buffer = 0;
+        hotplug_send_cmd(value);
+    }
+
+}
+
+void *virtio_hotplug_init(PCIBus *bus)
+{
+    VirtIOHotplug *n;
+
+    n = (VirtIOHotplug *)virtio_init_pci(bus, "virtio-hotplug", 0x2523, 0x2325,
+    			     0, VIRTIO_ID_HOTPLUG,
+    			     0xff, 0x80, 0x00,
+    			     6, sizeof(VirtIOHotplug));
+
+    n->vdev.update_config = virtio_hotplug_update_config;
+    n->vdev.get_features = virtio_hotplug_get_features;
+    n->cmd_vq = virtio_add_queue(&n->vdev, 128, virtio_hotplug_handle_cmd);
+
+    n->buffer_ready = 0;
+
+    virtio_hotplug = n;
+        
+    return &n->vdev;
+}
diff --git a/qemu/monitor.c b/qemu/monitor.c
index e03c473..f0c55c6 100644
--- a/qemu/monitor.c
+++ b/qemu/monitor.c
@@ -346,6 +346,16 @@ static void do_cpu_set(int index)
         term_printf("Invalid CPU index\n");
 }
 
+static void do_cpu_set_nr(int value)
+{
+    if ((value < 1)) {
+       term_printf("value out of range\n");
+       return;
+    }
+
+    hotplug_send_cmd(value);
+}
+
 static void do_info_jit(void)
 {
     dump_exec_info(NULL, monitor_fprintf);
@@ -1339,6 +1349,7 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "cpu_set", "i", do_cpu_set_nr, "value", "number of cpus in the guest" },
     { NULL, NULL, },
 };
 
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index e4aeb3a..6bf234d 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -48,6 +48,8 @@ void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write);
 int handle_tpr_access(void *opaque, int vcpu,
 			     uint64_t rip, int is_write);
 
+int hotplug_send_smd(int cpus);
+
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
 #define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8)
 
-- 
1.5.0.6

_______________________________________________
Virtualization mailing list
Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/virtualization

[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux