]> xenbits.xensource.com Git - qemu-xen-4.1-testing.git/commitdiff
Fix vcpu hotplug bug: get correct vcpu_avail bitmap
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 18 Mar 2010 16:45:51 +0000 (16:45 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Thu, 18 Mar 2010 16:45:51 +0000 (16:45 +0000)
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@intel.com>
(This is [PATCH 2/2], the other half is in xen-unstable.hg)

hw/piix4acpi.c
i386-dm/helper2.c
vl.c
xen-config-host.h

index ccbdf84d7c87e511a7a2b2ded695ca50892054c1..fb905d1a615bb97670325f346be0b74d5d5868b7 100644 (file)
@@ -518,7 +518,7 @@ static void gpe_acpi_init(void)
     GPEState *s = &gpe_state;
     memset(s, 0, sizeof(GPEState));
     int i = 0, cpus = vcpus;
-    char *vcpumap = (char *)&vcpu_avail;
+    char *vcpumap = (char *)vcpu_avail;
 
     while (cpus > 0) {
         s->cpus_sts[i] = vcpumap[i];
index 090202b76a268acec6f5042be1097059d89a62ca..986df3c1210c7a7da306a862d6b094879b13ac74 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <xenctrl.h>
 #include <xen/hvm/ioreq.h>
+#include <xen/hvm/hvm_info_table.h>
 
 #include "cpu.h"
 #include "exec-all.h"
@@ -78,7 +79,9 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
 
 int domid = -1;
 int vcpus = 1;
-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 xc_handle = -1;
 
diff --git a/vl.c b/vl.c
index cb31e5ad466a5738c8612bbf9a1639ad99c3560c..30debd700664370842ca13743256486ffbd7e1d1 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -49,6 +49,8 @@
 
 #include "qemu-xen.h"
 
+#include <xen/hvm/hvm_info_table.h>
+
 #include <unistd.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -4704,6 +4706,53 @@ static void termsig_setup(void)
 
 #endif
 
+#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(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)
 {
 #ifdef CONFIG_GDBSTUB
@@ -5298,12 +5347,9 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_vcpus:
                 vcpus = atoi(optarg);
-                fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
                 break;
             case QEMU_OPTION_vcpu_avail:
-                vcpu_avail = atol(optarg);
-                fprintf(logfile, "qemu: the avail cpu bitmap is %lx\n",  
-                                  vcpu_avail);
+                vcpu_hex_str_to_bitmap(optarg);
                 break;
             case QEMU_OPTION_acpi:
                 acpi_enabled = 1;
index e3f546a32607b819541ac6b86105788339ca2b49..6db16d30c056b357bbd9e90f81251fa7568f9c26 100644 (file)
@@ -31,7 +31,7 @@ void main_loop_prepare(void);
 extern int xc_handle;
 extern int xen_pause_requested;
 extern int vcpus;
-extern uint64_t vcpu_avail;
+extern uint32_t vcpu_avail[];
 
 #ifdef CONFIG_STUBDOM
 #define bdrv_host_device bdrv_raw