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

[Xen-devel] [PATCH 2/4] Fix vcpu hotplug bug: get correct vcpu_avail bitmap



From: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>

Currently qemu has a bug: When maxvcpus > 64, qemu will get wrong
vcpu bitmap (s->cpus_sts[i]) since it only get bitmap from a long variable.

This patch, cooperate with another xend python patch, is to fix this bug.
This patch get hex string from xend, transfer it to correct vcpu_avail bitmap
which saved at an uint32_t array.

Signed-off-By: Liu, Jinsong <jinsong.liu@xxxxxxxxx>
(This is [PATCH 2/2], the other half is in xen-unstable.hg)

Port from qemu-xen-traditionnal to qemu-xen.

Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 hw/acpi_piix4.c |  3 +--
 sysemu.h        |  1 +
 vl.c            | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index c73dc7c..bc7b454 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -637,12 +637,11 @@ static void gpe_cpus_writeb(void *opaque, uint32_t addr, 
uint32_t val)
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
 
-extern uint64_t vcpu_avail;
 static PIIX4PMState *acpi_state;
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
     int i = 0, cpus = max_cpus;
-    char *vcpumap = (char *)&vcpu_avail;
+    char *vcpumap = (char *)vcpu_avail;
 
     while (cpus > 0) {
         s->cpus_sts[i] = vcpumap[i];
diff --git a/sysemu.h b/sysemu.h
index ed7b264..5789158 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -113,6 +113,7 @@ extern int alt_grab;
 extern int ctrl_grab;
 extern int smp_cpus;
 extern int max_cpus;
+extern uint32_t vcpu_avail[];
 extern int cursor_hide;
 extern int graphic_rotate;
 extern int no_quit;
diff --git a/vl.c b/vl.c
index 27ae6c1..2ff1093 100644
--- a/vl.c
+++ b/vl.c
@@ -170,6 +170,8 @@ int main(int argc, char **argv)
 #include "ui/qemu-spice.h"
 #include "qapi/string-input-visitor.h"
 
+#include <xen/hvm/hvm_info_table.h>
+
 //#define DEBUG_NET
 //#define DEBUG_SLIRP
 
@@ -207,7 +209,9 @@ int win2k_install_hack = 0;
 int singlestep = 0;
 int smp_cpus = 1;
 int max_cpus = 0;
-uint64_t vcpu_avail = 1;
+/* use 32b array to record whatever vcpu number bitmap */
+/* do not use 64b array to avoid underflow/overflow when strtol */
+uint32_t vcpu_avail[(HVM_MAX_VCPUS + 31)/32] = {0};
 int smp_cores = 1;
 int smp_threads = 1;
 #ifdef CONFIG_VNC
@@ -2525,6 +2529,53 @@ static int object_create(QemuOpts *opts, void *opaque)
     return 0;
 }
 
+#define STEP   8   /* 8 characters fill uint32_t bitmap */
+#define SPACE  8   /* space for non-hex characters in vcpu str */
+#define MAX_VCPU_STR_LEN    ((HVM_MAX_VCPUS + 3)/4 + SPACE)
+static int hex_legal(char a)
+{
+    return  ((a >= '0' && a <= '9') ||
+             (a >= 'a' && a <= 'f') ||
+             (a >= 'A' && a <= 'F'));
+}
+
+static void vcpu_hex_str_to_bitmap(const char *optarg)
+{
+    char str[MAX_VCPU_STR_LEN + 1] = {'\0'};
+    char *pstr;
+    int length;
+    int step = STEP;
+    int i,j = 0;
+
+    length = strlen(optarg);
+    if(length > MAX_VCPU_STR_LEN)
+        exit(EXIT_FAILURE);
+    strncpy(str, optarg, MAX_VCPU_STR_LEN);
+
+    pstr = ((str[1] == 'x') || (str[1] == 'X')) ?
+             str + 2 : str;
+    length = strlen(pstr);
+
+    for(i = 0; i < length; i++)
+        if(hex_legal(pstr[i]))
+            str[j++] = pstr[i];
+    str[j] = '\0';
+    length = strlen(str);
+
+    i = 0;
+    while(length > 0) {
+        char vcpustr[STEP + SPACE] = {'\0'};
+        int start = ((length - step) > 0) ? length - step : 0;
+        int size  = ((length - step) > 0) ? step : length;
+        memcpy(vcpustr, str + start, size);
+        errno = 0;
+        vcpu_avail[i++] = strtol(vcpustr, NULL, 16);
+        if(errno)
+            exit(EXIT_FAILURE);
+        length -= step;
+    }
+}
+
 int main(int argc, char **argv, char **envp)
 {
     int i;
@@ -3304,9 +3355,7 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_vcpu_avail:
-                vcpu_avail = atol(optarg);
-                fprintf(stderr, "qemu: the avail cpu bitmap is %lx\n",
-                        vcpu_avail);
+                vcpu_hex_str_to_bitmap(optarg);
                 break;
            case QEMU_OPTION_vnc:
 #ifdef CONFIG_VNC
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.