Revert "Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging"
This reverts commit b8a173b25c887a606681fc35a46702c164d5b2d0, reversing changes made to 5de090464f1ec5360c4f30faa01d8a9f8826cd58. (I applied this pull request when I should not have done so, and am now immediately reverting it.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									b8a173b25c
								
							
						
					
					
						commit
						0856579cac
					
				
							
								
								
									
										35
									
								
								hw/i386/pc.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								hw/i386/pc.c
									
									
									
									
									
								
							@ -25,8 +25,6 @@
 | 
				
			|||||||
#include "hw/i386/pc.h"
 | 
					#include "hw/i386/pc.h"
 | 
				
			||||||
#include "hw/char/serial.h"
 | 
					#include "hw/char/serial.h"
 | 
				
			||||||
#include "hw/i386/apic.h"
 | 
					#include "hw/i386/apic.h"
 | 
				
			||||||
#include "hw/i386/topology.h"
 | 
					 | 
				
			||||||
#include "sysemu/cpus.h"
 | 
					 | 
				
			||||||
#include "hw/block/fdc.h"
 | 
					#include "hw/block/fdc.h"
 | 
				
			||||||
#include "hw/ide.h"
 | 
					#include "hw/ide.h"
 | 
				
			||||||
#include "hw/pci/pci.h"
 | 
					#include "hw/pci/pci.h"
 | 
				
			||||||
@ -631,39 +629,6 @@ bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t *length)
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Enables contiguous-apic-ID mode, for compatibility */
 | 
					 | 
				
			||||||
static bool compat_apic_id_mode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void enable_compat_apic_id_mode(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    compat_apic_id_mode = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Calculates initial APIC ID for a specific CPU index
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Currently we need to be able to calculate the APIC ID from the CPU index
 | 
					 | 
				
			||||||
 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
 | 
					 | 
				
			||||||
 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
 | 
					 | 
				
			||||||
 * all CPUs up to max_cpus.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint32_t correct_id;
 | 
					 | 
				
			||||||
    static bool warned;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
 | 
					 | 
				
			||||||
    if (compat_apic_id_mode) {
 | 
					 | 
				
			||||||
        if (cpu_index != correct_id && !warned) {
 | 
					 | 
				
			||||||
            error_report("APIC IDs set in compatibility mode, "
 | 
					 | 
				
			||||||
                         "CPU topology won't match the configuration");
 | 
					 | 
				
			||||||
            warned = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return cpu_index;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        return correct_id;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Calculates the limit to CPU APIC ID values
 | 
					/* Calculates the limit to CPU APIC ID values
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function returns the limit for the APIC ID value, so that all
 | 
					 * This function returns the limit for the APIC ID value, so that all
 | 
				
			||||||
 | 
				
			|||||||
@ -3453,17 +3453,10 @@ CPUArchState *cpu_copy(CPUArchState *env)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    CPUState *cpu = ENV_GET_CPU(env);
 | 
					    CPUState *cpu = ENV_GET_CPU(env);
 | 
				
			||||||
    CPUArchState *new_env = cpu_init(cpu_model);
 | 
					    CPUArchState *new_env = cpu_init(cpu_model);
 | 
				
			||||||
    CPUState *new_cpu;
 | 
					    CPUState *new_cpu = ENV_GET_CPU(new_env);
 | 
				
			||||||
    CPUBreakpoint *bp;
 | 
					    CPUBreakpoint *bp;
 | 
				
			||||||
    CPUWatchpoint *wp;
 | 
					    CPUWatchpoint *wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!new_env) {
 | 
					 | 
				
			||||||
        fprintf(stderr, "cpu_copy: Failed to create new CPU\n");
 | 
					 | 
				
			||||||
        exit(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    new_cpu = ENV_GET_CPU(new_env);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Reset non arch specific state */
 | 
					    /* Reset non arch specific state */
 | 
				
			||||||
    cpu_reset(new_cpu);
 | 
					    cpu_reset(new_cpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -93,7 +93,6 @@ typedef struct X86CPU {
 | 
				
			|||||||
    bool expose_kvm;
 | 
					    bool expose_kvm;
 | 
				
			||||||
    bool migratable;
 | 
					    bool migratable;
 | 
				
			||||||
    bool host_features;
 | 
					    bool host_features;
 | 
				
			||||||
    int64_t apic_id;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* if true the CPUID code directly forward host cache leaves to the guest */
 | 
					    /* if true the CPUID code directly forward host cache leaves to the guest */
 | 
				
			||||||
    bool cache_info_passthrough;
 | 
					    bool cache_info_passthrough;
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,7 @@
 | 
				
			|||||||
#include "sysemu/kvm.h"
 | 
					#include "sysemu/kvm.h"
 | 
				
			||||||
#include "sysemu/cpus.h"
 | 
					#include "sysemu/cpus.h"
 | 
				
			||||||
#include "kvm_i386.h"
 | 
					#include "kvm_i386.h"
 | 
				
			||||||
 | 
					#include "topology.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "qemu/option.h"
 | 
					#include "qemu/option.h"
 | 
				
			||||||
#include "qemu/config-file.h"
 | 
					#include "qemu/config-file.h"
 | 
				
			||||||
@ -1689,7 +1690,7 @@ static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
 | 
				
			|||||||
                                  const char *name, Error **errp)
 | 
					                                  const char *name, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    X86CPU *cpu = X86_CPU(obj);
 | 
					    X86CPU *cpu = X86_CPU(obj);
 | 
				
			||||||
    int64_t value = cpu->apic_id;
 | 
					    int64_t value = cpu->env.cpuid_apic_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    visit_type_int(v, &value, name, errp);
 | 
					    visit_type_int(v, &value, name, errp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1722,11 +1723,11 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((value != cpu->apic_id) && cpu_exists(value)) {
 | 
					    if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
 | 
				
			||||||
        error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
 | 
					        error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    cpu->apic_id = value;
 | 
					    cpu->env.cpuid_apic_id = value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Generic getter for "feature-words" and "filtered-features" properties */
 | 
					/* Generic getter for "feature-words" and "filtered-features" properties */
 | 
				
			||||||
@ -1910,18 +1911,33 @@ static void x86_cpu_parse_featurestr(CPUState *cs, char *features,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Print all cpuid feature names in featureset
 | 
					/* generate a composite string into buf of all cpuid names in featureset
 | 
				
			||||||
 | 
					 * selected by fbits.  indicate truncation at bufsize in the event of overflow.
 | 
				
			||||||
 | 
					 * if flags, suppress names undefined in featureset.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void listflags(FILE *f, fprintf_function print, const char **featureset)
 | 
					static void listflags(char *buf, int bufsize, uint32_t fbits,
 | 
				
			||||||
 | 
					                      const char **featureset, uint32_t flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int bit;
 | 
					    const char **p = &featureset[31];
 | 
				
			||||||
    bool first = true;
 | 
					    char *q, *b, bit;
 | 
				
			||||||
 | 
					    int nc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (bit = 0; bit < 32; bit++) {
 | 
					    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
 | 
				
			||||||
        if (featureset[bit]) {
 | 
					    *buf = '\0';
 | 
				
			||||||
            print(f, "%s%s", first ? "" : " ", featureset[bit]);
 | 
					    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
 | 
				
			||||||
            first = false;
 | 
					        if (fbits & 1 << bit && (*p || !flags)) {
 | 
				
			||||||
 | 
					            if (*p)
 | 
				
			||||||
 | 
					                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
 | 
				
			||||||
 | 
					            if (bufsize <= nc) {
 | 
				
			||||||
 | 
					                if (b) {
 | 
				
			||||||
 | 
					                    memcpy(b, "...", sizeof("..."));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            q += nc;
 | 
				
			||||||
 | 
					            bufsize -= nc;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1947,9 +1963,8 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 | 
				
			|||||||
    for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
 | 
					    for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
 | 
				
			||||||
        FeatureWordInfo *fw = &feature_word_info[i];
 | 
					        FeatureWordInfo *fw = &feature_word_info[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        (*cpu_fprintf)(f, "  ");
 | 
					        listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
 | 
				
			||||||
        listflags(f, cpu_fprintf, fw->feat_names);
 | 
					        (*cpu_fprintf)(f, "  %s\n", buf);
 | 
				
			||||||
        (*cpu_fprintf)(f, "\n");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2134,35 +2149,27 @@ out:
 | 
				
			|||||||
    return cpu;
 | 
					    return cpu;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPUX86State *cpu_x86_init_user(const char *cpu_model)
 | 
					X86CPU *cpu_x86_init(const char *cpu_model)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Error *error = NULL;
 | 
					    Error *error = NULL;
 | 
				
			||||||
    X86CPU *cpu;
 | 
					    X86CPU *cpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu = cpu_x86_create(cpu_model, NULL, &error);
 | 
					    cpu = cpu_x86_create(cpu_model, NULL, &error);
 | 
				
			||||||
    if (error) {
 | 
					    if (error) {
 | 
				
			||||||
        goto error;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object_property_set_int(OBJECT(cpu), CPU(cpu)->cpu_index, "apic-id",
 | 
					 | 
				
			||||||
                            &error);
 | 
					 | 
				
			||||||
    if (error) {
 | 
					 | 
				
			||||||
        goto error;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object_property_set_bool(OBJECT(cpu), true, "realized", &error);
 | 
					    object_property_set_bool(OBJECT(cpu), true, "realized", &error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
    if (error) {
 | 
					    if (error) {
 | 
				
			||||||
        goto error;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return &cpu->env;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
error:
 | 
					 | 
				
			||||||
        error_report_err(error);
 | 
					        error_report_err(error);
 | 
				
			||||||
        if (cpu != NULL) {
 | 
					        if (cpu != NULL) {
 | 
				
			||||||
            object_unref(OBJECT(cpu));
 | 
					            object_unref(OBJECT(cpu));
 | 
				
			||||||
 | 
					            cpu = NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    return NULL;
 | 
					    }
 | 
				
			||||||
 | 
					    return cpu;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
 | 
					static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
 | 
				
			||||||
@ -2220,6 +2227,14 @@ void x86_cpudef_setup(void)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
 | 
				
			||||||
 | 
					                             uint32_t *ecx, uint32_t *edx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    *ebx = env->cpuid_vendor1;
 | 
				
			||||||
 | 
					    *edx = env->cpuid_vendor2;
 | 
				
			||||||
 | 
					    *ecx = env->cpuid_vendor3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
 | 
					void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
 | 
				
			||||||
                   uint32_t *eax, uint32_t *ebx,
 | 
					                   uint32_t *eax, uint32_t *ebx,
 | 
				
			||||||
                   uint32_t *ecx, uint32_t *edx)
 | 
					                   uint32_t *ecx, uint32_t *edx)
 | 
				
			||||||
@ -2253,14 +2268,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
 | 
				
			|||||||
    switch(index) {
 | 
					    switch(index) {
 | 
				
			||||||
    case 0:
 | 
					    case 0:
 | 
				
			||||||
        *eax = env->cpuid_level;
 | 
					        *eax = env->cpuid_level;
 | 
				
			||||||
        *ebx = env->cpuid_vendor1;
 | 
					        get_cpuid_vendor(env, ebx, ecx, edx);
 | 
				
			||||||
        *edx = env->cpuid_vendor2;
 | 
					 | 
				
			||||||
        *ecx = env->cpuid_vendor3;
 | 
					 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
        *eax = env->cpuid_version;
 | 
					        *eax = env->cpuid_version;
 | 
				
			||||||
        *ebx = (cpu->apic_id << 24) |
 | 
					        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
 | 
				
			||||||
               8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
 | 
					 | 
				
			||||||
        *ecx = env->features[FEAT_1_ECX];
 | 
					        *ecx = env->features[FEAT_1_ECX];
 | 
				
			||||||
        *edx = env->features[FEAT_1_EDX];
 | 
					        *edx = env->features[FEAT_1_EDX];
 | 
				
			||||||
        if (cs->nr_cores * cs->nr_threads > 1) {
 | 
					        if (cs->nr_cores * cs->nr_threads > 1) {
 | 
				
			||||||
@ -2449,9 +2461,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
 | 
				
			|||||||
         * So dont set it here for Intel to make Linux guests happy.
 | 
					         * So dont set it here for Intel to make Linux guests happy.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        if (cs->nr_cores * cs->nr_threads > 1) {
 | 
					        if (cs->nr_cores * cs->nr_threads > 1) {
 | 
				
			||||||
            if (env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1 ||
 | 
					            uint32_t tebx, tecx, tedx;
 | 
				
			||||||
                env->cpuid_vendor2 != CPUID_VENDOR_INTEL_2 ||
 | 
					            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
 | 
				
			||||||
                env->cpuid_vendor3 != CPUID_VENDOR_INTEL_3) {
 | 
					            if (tebx != CPUID_VENDOR_INTEL_1 ||
 | 
				
			||||||
 | 
					                tedx != CPUID_VENDOR_INTEL_2 ||
 | 
				
			||||||
 | 
					                tecx != CPUID_VENDOR_INTEL_3) {
 | 
				
			||||||
                *ecx |= 1 << 1;    /* CmpLegacy bit */
 | 
					                *ecx |= 1 << 1;    /* CmpLegacy bit */
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -2707,6 +2721,7 @@ static void mce_init(X86CPU *cpu)
 | 
				
			|||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
 | 
					static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    CPUX86State *env = &cpu->env;
 | 
				
			||||||
    DeviceState *dev = DEVICE(cpu);
 | 
					    DeviceState *dev = DEVICE(cpu);
 | 
				
			||||||
    APICCommonState *apic;
 | 
					    APICCommonState *apic;
 | 
				
			||||||
    const char *apic_type = "apic";
 | 
					    const char *apic_type = "apic";
 | 
				
			||||||
@ -2725,7 +2740,7 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    object_property_add_child(OBJECT(cpu), "apic",
 | 
					    object_property_add_child(OBJECT(cpu), "apic",
 | 
				
			||||||
                              OBJECT(cpu->apic_state), NULL);
 | 
					                              OBJECT(cpu->apic_state), NULL);
 | 
				
			||||||
    qdev_prop_set_uint8(cpu->apic_state, "id", cpu->apic_id);
 | 
					    qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
 | 
				
			||||||
    /* TODO: convert to link<> */
 | 
					    /* TODO: convert to link<> */
 | 
				
			||||||
    apic = APIC_COMMON(cpu->apic_state);
 | 
					    apic = APIC_COMMON(cpu->apic_state);
 | 
				
			||||||
    apic->cpu = cpu;
 | 
					    apic->cpu = cpu;
 | 
				
			||||||
@ -2765,11 +2780,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
 | 
				
			|||||||
    Error *local_err = NULL;
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
    static bool ht_warned;
 | 
					    static bool ht_warned;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cpu->apic_id < 0) {
 | 
					 | 
				
			||||||
        error_setg(errp, "apic-id property was not initialized properly");
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
 | 
					    if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
 | 
				
			||||||
        env->cpuid_level = 7;
 | 
					        env->cpuid_level = 7;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -2834,6 +2844,39 @@ out:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Enables contiguous-apic-ID mode, for compatibility */
 | 
				
			||||||
 | 
					static bool compat_apic_id_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void enable_compat_apic_id_mode(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    compat_apic_id_mode = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Calculates initial APIC ID for a specific CPU index
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Currently we need to be able to calculate the APIC ID from the CPU index
 | 
				
			||||||
 | 
					 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
 | 
				
			||||||
 | 
					 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
 | 
				
			||||||
 | 
					 * all CPUs up to max_cpus.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t correct_id;
 | 
				
			||||||
 | 
					    static bool warned;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
 | 
				
			||||||
 | 
					    if (compat_apic_id_mode) {
 | 
				
			||||||
 | 
					        if (cpu_index != correct_id && !warned) {
 | 
				
			||||||
 | 
					            error_report("APIC IDs set in compatibility mode, "
 | 
				
			||||||
 | 
					                         "CPU topology won't match the configuration");
 | 
				
			||||||
 | 
					            warned = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return cpu_index;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return correct_id;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void x86_cpu_initfn(Object *obj)
 | 
					static void x86_cpu_initfn(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUState *cs = CPU(obj);
 | 
					    CPUState *cs = CPU(obj);
 | 
				
			||||||
@ -2880,7 +2923,7 @@ static void x86_cpu_initfn(Object *obj)
 | 
				
			|||||||
                        NULL, NULL, (void *)cpu->filtered_features, NULL);
 | 
					                        NULL, NULL, (void *)cpu->filtered_features, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
 | 
					    cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
 | 
				
			||||||
    cpu->apic_id = -1;
 | 
					    env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
 | 
					    x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2894,8 +2937,9 @@ static void x86_cpu_initfn(Object *obj)
 | 
				
			|||||||
static int64_t x86_cpu_get_arch_id(CPUState *cs)
 | 
					static int64_t x86_cpu_get_arch_id(CPUState *cs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    X86CPU *cpu = X86_CPU(cs);
 | 
					    X86CPU *cpu = X86_CPU(cs);
 | 
				
			||||||
 | 
					    CPUX86State *env = &cpu->env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return cpu->apic_id;
 | 
					    return env->cpuid_apic_id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool x86_cpu_get_paging_enabled(const CPUState *cs)
 | 
					static bool x86_cpu_get_paging_enabled(const CPUState *cs)
 | 
				
			||||||
 | 
				
			|||||||
@ -944,6 +944,7 @@ typedef struct CPUX86State {
 | 
				
			|||||||
    uint32_t cpuid_version;
 | 
					    uint32_t cpuid_version;
 | 
				
			||||||
    FeatureWordArray features;
 | 
					    FeatureWordArray features;
 | 
				
			||||||
    uint32_t cpuid_model[12];
 | 
					    uint32_t cpuid_model[12];
 | 
				
			||||||
 | 
					    uint32_t cpuid_apic_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* MTRRs */
 | 
					    /* MTRRs */
 | 
				
			||||||
    uint64_t mtrr_fixed[11];
 | 
					    uint64_t mtrr_fixed[11];
 | 
				
			||||||
@ -981,6 +982,7 @@ typedef struct CPUX86State {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "cpu-qom.h"
 | 
					#include "cpu-qom.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					X86CPU *cpu_x86_init(const char *cpu_model);
 | 
				
			||||||
X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
 | 
					X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
 | 
				
			||||||
                       Error **errp);
 | 
					                       Error **errp);
 | 
				
			||||||
int cpu_x86_exec(CPUX86State *s);
 | 
					int cpu_x86_exec(CPUX86State *s);
 | 
				
			||||||
@ -1169,9 +1171,14 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 | 
				
			|||||||
# define PHYS_ADDR_MASK 0xfffffffffLL
 | 
					# define PHYS_ADDR_MASK 0xfffffffffLL
 | 
				
			||||||
# endif
 | 
					# endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* CPU creation function for *-user */
 | 
					static inline CPUX86State *cpu_init(const char *cpu_model)
 | 
				
			||||||
CPUX86State *cpu_x86_init_user(const char *cpu_model);
 | 
					{
 | 
				
			||||||
#define cpu_init cpu_x86_init_user
 | 
					    X86CPU *cpu = cpu_x86_init(cpu_model);
 | 
				
			||||||
 | 
					    if (cpu == NULL) {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return &cpu->env;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define cpu_exec cpu_x86_exec
 | 
					#define cpu_exec cpu_x86_exec
 | 
				
			||||||
#define cpu_gen_code cpu_x86_gen_code
 | 
					#define cpu_gen_code cpu_x86_gen_code
 | 
				
			||||||
 | 
				
			|||||||
@ -430,7 +430,7 @@ static void cpu_update_state(void *opaque, int running, RunState state)
 | 
				
			|||||||
unsigned long kvm_arch_vcpu_id(CPUState *cs)
 | 
					unsigned long kvm_arch_vcpu_id(CPUState *cs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    X86CPU *cpu = X86_CPU(cs);
 | 
					    X86CPU *cpu = X86_CPU(cs);
 | 
				
			||||||
    return cpu->apic_id;
 | 
					    return cpu->env.cpuid_apic_id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef KVM_CPUID_SIGNATURE_NEXT
 | 
					#ifndef KVM_CPUID_SIGNATURE_NEXT
 | 
				
			||||||
 | 
				
			|||||||
@ -21,8 +21,8 @@
 | 
				
			|||||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 * THE SOFTWARE.
 | 
					 * THE SOFTWARE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#ifndef HW_I386_TOPOLOGY_H
 | 
					#ifndef TARGET_I386_TOPOLOGY_H
 | 
				
			||||||
#define HW_I386_TOPOLOGY_H
 | 
					#define TARGET_I386_TOPOLOGY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* This file implements the APIC-ID-based CPU topology enumeration logic,
 | 
					/* This file implements the APIC-ID-based CPU topology enumeration logic,
 | 
				
			||||||
 * documented at the following document:
 | 
					 * documented at the following document:
 | 
				
			||||||
@ -131,4 +131,4 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_cores,
 | 
				
			|||||||
    return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
 | 
					    return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* HW_I386_TOPOLOGY_H */
 | 
					#endif /* TARGET_I386_TOPOLOGY_H */
 | 
				
			||||||
@ -239,6 +239,8 @@ $(test-obj-y): QEMU_INCLUDES += -Itests
 | 
				
			|||||||
QEMU_CFLAGS += -I$(SRC_PATH)/tests
 | 
					QEMU_CFLAGS += -I$(SRC_PATH)/tests
 | 
				
			||||||
qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o
 | 
					qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tests/check-qint$(EXESUF): tests/check-qint.o libqemuutil.a
 | 
					tests/check-qint$(EXESUF): tests/check-qint.o libqemuutil.a
 | 
				
			||||||
tests/check-qstring$(EXESUF): tests/check-qstring.o libqemuutil.a
 | 
					tests/check-qstring$(EXESUF): tests/check-qstring.o libqemuutil.a
 | 
				
			||||||
tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a
 | 
					tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <glib.h>
 | 
					#include <glib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "hw/i386/topology.h"
 | 
					#include "topology.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void test_topo_bits(void)
 | 
					static void test_topo_bits(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user