From mboxrd@z Thu Jan 1 00:00:00 1970 From: Anthony PERARD Subject: [PATCH 2/4] Fix vcpu hotplug bug: get correct vcpu_avail bitmap Date: Fri, 31 May 2013 17:33:11 +0100 Message-ID: <1370017993-13437-3-git-send-email-anthony.perard@citrix.com> References: <1370017993-13437-1-git-send-email-anthony.perard@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1370017993-13437-1-git-send-email-anthony.perard@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Xen Devel Cc: "Liu, Jinsong" , Ian Jackson , Stefano Stabellini , Anthony PERARD List-Id: xen-devel@lists.xenproject.org From: Ian Jackson 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 (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 --- 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 + //#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