Commit a8a358bf authored by Andre Przywara's avatar Andre Przywara Committed by Anthony Liguori
Browse files

allow overriding of CPUID level on command line



The CPUID level determines how many CPUID leafs are exposed to the guest.
Some features (like multi-core) cannot be propagated without the proper
level, but guests maybe confused by bogus entries in some leafs.
So add level= and xlevel= to the list of -cpu options to allow the user to
override the default settings. While at it, merge unnecessary local
variables into one and allow hexadecimal arguments.

Signed-off-by: default avatarAndre Przywara <andre.przywara@amd.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 400281af
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -349,7 +349,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
    char *featurestr, *name = strtok(s, ",");
    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
    int family = -1, model = -1, stepping = -1;
    uint32_t numvalue;

    def = NULL;
    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
@@ -381,28 +381,47 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
            *val = 0; val++;
            if (!strcmp(featurestr, "family")) {
                char *err;
                family = strtol(val, &err, 10);
                if (!*val || *err || family < 0) {
                numvalue = strtoul(val, &err, 0);
                if (!*val || *err) {
                    fprintf(stderr, "bad numerical value %s\n", val);
                    goto error;
                }
                x86_cpu_def->family = family;
                x86_cpu_def->family = numvalue;
            } else if (!strcmp(featurestr, "model")) {
                char *err;
                model = strtol(val, &err, 10);
                if (!*val || *err || model < 0 || model > 0xff) {
                numvalue = strtoul(val, &err, 0);
                if (!*val || *err || numvalue > 0xff) {
                    fprintf(stderr, "bad numerical value %s\n", val);
                    goto error;
                }
                x86_cpu_def->model = model;
                x86_cpu_def->model = numvalue;
            } else if (!strcmp(featurestr, "stepping")) {
                char *err;
                stepping = strtol(val, &err, 10);
                if (!*val || *err || stepping < 0 || stepping > 0xf) {
                numvalue = strtoul(val, &err, 0);
                if (!*val || *err || numvalue > 0xf) {
                    fprintf(stderr, "bad numerical value %s\n", val);
                    goto error;
                }
                x86_cpu_def->stepping = stepping;
                x86_cpu_def->stepping = numvalue ;
            } else if (!strcmp(featurestr, "level")) {
                char *err;
                numvalue = strtoul(val, &err, 0);
                if (!*val || *err) {
                    fprintf(stderr, "bad numerical value %s\n", val);
                    goto error;
                }
                x86_cpu_def->level = numvalue;
            } else if (!strcmp(featurestr, "xlevel")) {
                char *err;
                numvalue = strtoul(val, &err, 0);
                if (!*val || *err) {
                    fprintf(stderr, "bad numerical value %s\n", val);
                    goto error;
                }
                if (numvalue < 0x80000000) {
                	numvalue += 0x80000000;
                }
                x86_cpu_def->xlevel = numvalue;
            } else if (!strcmp(featurestr, "vendor")) {
                if (strlen(val) != 12) {
                    fprintf(stderr, "vendor string must be 12 chars long\n");