Merge remote-tracking branch 'afaerber/qom-cpu' into staging

# By Andreas Färber (12) and others
# Via Andreas Färber
* afaerber/qom-cpu:
  spapr_rtas: Abstract rtas_start_cpu() with qemu_get_cpu()
  spapr_rtas: Abstract rtas_query_cpu_stopped_state() with qemu_get_cpu()
  memory_mapping: Improve qemu_get_guest_memory_mapping() error reporting
  dump: Abstract dump_init() with cpu_synchronize_all_states()
  cpu: Change default for CPUClass::get_paging_enabled()
  dump: Drop qmp_dump_guest_memory() stub and build for all targets
  memory_mapping: Drop qemu_get_memory_mapping() stub
  cpu: Turn cpu_get_memory_mapping() into a CPUState hook
  memory_mapping: Move MemoryMappingList typedef to qemu/typedefs.h
  cpu: Turn cpu_paging_enabled() into a CPUState hook
  monitor: Simplify do_inject_mce() with qemu_get_cpu()
  target-i386: cpu: Fix potential buffer overrun in get_register_name_32()
  target-i386: Set level=4 on Conroe/Penryn/Nehalem
  target-i386: Update model values on Conroe/Penryn/Nehalem CPU models
  pc: Create pc-*-1.6 machine-types
  pc: Fix crash when attempting to hotplug CPU with negative ID
  dump: Move stubs into libqemustub.a
This commit is contained in:
Anthony Liguori 2013-06-14 07:51:30 -05:00
commit 5f13731f8c
21 changed files with 185 additions and 130 deletions

View File

@ -63,8 +63,6 @@ all: $(PROGS) stap
CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
CONFIG_NO_GET_MEMORY_MAPPING = $(if $(subst n,,$(CONFIG_HAVE_GET_MEMORY_MAPPING)),n,y)
CONFIG_NO_CORE_DUMP = $(if $(subst n,,$(CONFIG_HAVE_CORE_DUMP)),n,y)
#########################################################
# cpu emulator library
@ -111,10 +109,8 @@ obj-y += hw/
obj-$(CONFIG_FDT) += device_tree.o
obj-$(CONFIG_KVM) += kvm-all.o
obj-y += memory.o savevm.o cputlb.o
obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o
obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o
obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o
obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o
obj-y += memory_mapping.o
obj-y += dump.o
LIBS+=$(libs_softmmu)
# xen support

8
configure vendored
View File

@ -4280,19 +4280,11 @@ case "$target_arch2" in
fi
fi
esac
case "$target_arch2" in
i386|x86_64)
echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak
esac
if test "$target_bigendian" = "yes" ; then
echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
fi
if test "$target_softmmu" = "yes" ; then
echo "CONFIG_SOFTMMU=y" >> $config_target_mak
case "$target_arch2" in
i386|x86_64)
echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
esac
fi
if test "$target_user_only" = "yes" ; then
echo "CONFIG_USER_ONLY=y" >> $config_target_mak

12
dump.c
View File

@ -21,6 +21,7 @@
#include "sysemu/dump.h"
#include "sysemu/sysemu.h"
#include "sysemu/memory_mapping.h"
#include "sysemu/cpus.h"
#include "qapi/error.h"
#include "qmp-commands.h"
@ -706,6 +707,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
{
CPUArchState *env;
int nr_cpus;
Error *err = NULL;
int ret;
if (runstate_is_running()) {
@ -731,12 +733,12 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
* If the target architecture is not supported, cpu_get_dump_info() will
* return -1.
*
* if we use kvm, we should synchronize the register before we get dump
* If we use KVM, we should synchronize the registers before we get dump
* info.
*/
cpu_synchronize_all_states();
nr_cpus = 0;
for (env = first_cpu; env != NULL; env = env->next_cpu) {
cpu_synchronize_state(env);
nr_cpus++;
}
@ -756,7 +758,11 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
/* get memory mapping */
memory_mapping_list_init(&s->list);
if (paging) {
qemu_get_guest_memory_mapping(&s->list);
qemu_get_guest_memory_mapping(&s->list, &err);
if (err != NULL) {
error_propagate(errp, err);
goto cleanup;
}
} else {
qemu_get_guest_simple_memory_mapping(&s->list);
}

View File

@ -991,7 +991,6 @@ server will ask the spice/vnc client to automatically reconnect using the
new parameters (if specified) once the vm migration finished successfully.
ETEXI
#if defined(CONFIG_HAVE_CORE_DUMP)
{
.name = "dump-guest-memory",
.args_type = "paging:-p,filename:F,begin:i?,length:i?",
@ -1015,7 +1014,6 @@ gdb.
length: the memory size, in bytes. It's optional, and should be specified
with begin together.
ETEXI
#endif
{
.name = "snapshot_blkdev",

View File

@ -927,6 +927,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
DeviceState *icc_bridge;
int64_t apic_id = x86_cpu_apic_id_from_index(id);
if (id < 0) {
error_setg(errp, "Invalid CPU id: %" PRIi64, id);
return;
}
if (cpu_exists(apic_id)) {
error_setg(errp, "Unable to add CPU: %" PRIi64
", it already exists", id);

View File

@ -327,8 +327,8 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
}
#endif
static QEMUMachine pc_i440fx_machine_v1_5 = {
.name = "pc-i440fx-1.5",
static QEMUMachine pc_i440fx_machine_v1_6 = {
.name = "pc-i440fx-1.6",
.alias = "pc",
.desc = "Standard PC (i440FX + PIIX, 1996)",
.init = pc_init_pci,
@ -338,6 +338,19 @@ static QEMUMachine pc_i440fx_machine_v1_5 = {
DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_i440fx_machine_v1_5 = {
.name = "pc-i440fx-1.5",
.desc = "Standard PC (i440FX + PIIX, 1996)",
.init = pc_init_pci,
.hot_add_cpu = pc_hot_add_cpu,
.max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_5,
{ /* end of list */ }
},
DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_i440fx_machine_v1_4 = {
.name = "pc-i440fx-1.4",
.desc = "Standard PC (i440FX + PIIX, 1996)",
@ -735,6 +748,7 @@ static QEMUMachine xenfv_machine = {
static void pc_machine_init(void)
{
qemu_register_machine(&pc_i440fx_machine_v1_6);
qemu_register_machine(&pc_i440fx_machine_v1_5);
qemu_register_machine(&pc_i440fx_machine_v1_4);
qemu_register_machine(&pc_machine_v1_3);

View File

@ -215,8 +215,8 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
pc_q35_init(args);
}
static QEMUMachine pc_q35_machine_v1_5 = {
.name = "pc-q35-1.5",
static QEMUMachine pc_q35_machine_v1_6 = {
.name = "pc-q35-1.6",
.alias = "q35",
.desc = "Standard PC (Q35 + ICH9, 2009)",
.init = pc_q35_init,
@ -225,6 +225,19 @@ static QEMUMachine pc_q35_machine_v1_5 = {
DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_q35_machine_v1_5 = {
.name = "pc-q35-1.5",
.desc = "Standard PC (Q35 + ICH9, 2009)",
.init = pc_q35_init,
.hot_add_cpu = pc_hot_add_cpu,
.max_cpus = 255,
.compat_props = (GlobalProperty[]) {
PC_COMPAT_1_5,
{ /* end of list */ }
},
DEFAULT_MACHINE_OPTIONS,
};
static QEMUMachine pc_q35_machine_v1_4 = {
.name = "pc-q35-1.4",
.desc = "Standard PC (Q35 + ICH9, 2009)",
@ -239,6 +252,7 @@ static QEMUMachine pc_q35_machine_v1_4 = {
static void pc_q35_machine_init(void)
{
qemu_register_machine(&pc_q35_machine_v1_6);
qemu_register_machine(&pc_q35_machine_v1_5);
qemu_register_machine(&pc_q35_machine_v1_4);
}

View File

@ -130,7 +130,6 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
uint32_t nret, target_ulong rets)
{
target_ulong id;
CPUPPCState *env;
CPUState *cpu;
if (nargs != 1 || nret != 2) {
@ -139,12 +138,8 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
}
id = rtas_ld(args, 0);
for (env = first_cpu; env; env = env->next_cpu) {
cpu = CPU(ppc_env_get_cpu(env));
if (cpu->cpu_index != id) {
continue;
}
cpu = qemu_get_cpu(id);
if (cpu != NULL) {
if (cpu->halted) {
rtas_st(rets, 1, 0);
} else {
@ -165,8 +160,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
uint32_t nret, target_ulong rets)
{
target_ulong id, start, r3;
CPUState *cpu;
CPUPPCState *env;
CPUState *cs;
if (nargs != 3 || nret != 1) {
rtas_st(rets, 0, -3);
@ -177,14 +171,12 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
start = rtas_ld(args, 1);
r3 = rtas_ld(args, 2);
for (env = first_cpu; env; env = env->next_cpu) {
cpu = CPU(ppc_env_get_cpu(env));
cs = qemu_get_cpu(id);
if (cs != NULL) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
if (cpu->cpu_index != id) {
continue;
}
if (!cpu->halted) {
if (!cs->halted) {
rtas_st(rets, 0, -1);
return;
}
@ -197,9 +189,9 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
env->nip = start;
env->gpr[3] = r3;
cpu->halted = 0;
cs->halted = 0;
qemu_cpu_kick(cpu);
qemu_cpu_kick(cs);
rtas_st(rets, 0, 0);
return;

View File

@ -185,7 +185,35 @@ int pvpanic_init(ISABus *bus);
int e820_add_entry(uint64_t, uint64_t, uint32_t);
#define PC_COMPAT_1_5 \
{\
.driver = "Conroe-" TYPE_X86_CPU,\
.property = "model",\
.value = stringify(2),\
},{\
.driver = "Conroe-" TYPE_X86_CPU,\
.property = "level",\
.value = stringify(2),\
},{\
.driver = "Penryn-" TYPE_X86_CPU,\
.property = "model",\
.value = stringify(2),\
},{\
.driver = "Penryn-" TYPE_X86_CPU,\
.property = "level",\
.value = stringify(2),\
},{\
.driver = "Nehalem-" TYPE_X86_CPU,\
.property = "model",\
.value = stringify(2),\
},{\
.driver = "Nehalem-" TYPE_X86_CPU,\
.property = "level",\
.value = stringify(2),\
}
#define PC_COMPAT_1_4 \
PC_COMPAT_1_5, \
{\
.driver = "scsi-hd",\
.property = "discard_granularity",\

View File

@ -22,6 +22,8 @@ typedef struct AddressSpace AddressSpace;
typedef struct MemoryRegion MemoryRegion;
typedef struct MemoryRegionSection MemoryRegionSection;
typedef struct MemoryMappingList MemoryMappingList;
typedef struct NICInfo NICInfo;
typedef struct HCIInfo HCIInfo;
typedef struct AudioState AudioState;

View File

@ -23,6 +23,7 @@
#include <signal.h>
#include "hw/qdev-core.h"
#include "qemu/thread.h"
#include "qemu/typedefs.h"
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
@ -48,6 +49,8 @@ typedef struct CPUState CPUState;
* @reset: Callback to reset the #CPUState to its initial state.
* @do_interrupt: Callback for interrupt handling.
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
* @get_memory_mapping: Callback for obtaining the memory mappings.
* @vmsd: State description for migration.
*
* Represents a CPU family or model.
@ -62,6 +65,9 @@ typedef struct CPUClass {
void (*reset)(CPUState *cpu);
void (*do_interrupt)(CPUState *cpu);
int64_t (*get_arch_id)(CPUState *cpu);
bool (*get_paging_enabled)(const CPUState *cpu);
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
Error **errp);
const struct VMStateDescription *vmsd;
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
@ -137,6 +143,23 @@ struct CPUState {
uint32_t halted; /* used by alpha, cris, ppc TCG */
};
/**
* cpu_paging_enabled:
* @cpu: The CPU whose state is to be inspected.
*
* Returns: %true if paging is enabled, %false otherwise.
*/
bool cpu_paging_enabled(const CPUState *cpu);
/**
* cpu_get_memory_mapping:
* @cpu: The CPU whose memory mappings are to be obtained.
* @list: Where to write the memory mappings to.
* @errp: Pointer for reporting an #Error.
*/
void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
Error **errp);
/**
* cpu_write_elf64_note:
* @f: pointer to a function that writes memory to a file

View File

@ -15,6 +15,7 @@
#define MEMORY_MAPPING_H
#include "qemu/queue.h"
#include "qemu/typedefs.h"
/* The physical and virtual address in the memory mapping are contiguous. */
typedef struct MemoryMapping {
@ -24,14 +25,11 @@ typedef struct MemoryMapping {
QTAILQ_ENTRY(MemoryMapping) next;
} MemoryMapping;
typedef struct MemoryMappingList {
struct MemoryMappingList {
unsigned int num;
MemoryMapping *last_mapping;
QTAILQ_HEAD(, MemoryMapping) head;
} MemoryMappingList;
int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env);
bool cpu_paging_enabled(CPUArchState *env);
};
/*
* add or merge the memory region [phys_addr, phys_addr + length) into the
@ -47,13 +45,7 @@ void memory_mapping_list_free(MemoryMappingList *list);
void memory_mapping_list_init(MemoryMappingList *list);
/*
* Return value:
* 0: success
* -1: failed
* -2: unsupported
*/
int qemu_get_guest_memory_mapping(MemoryMappingList *list);
void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
/* get guest's memory mapping without do paging(virtual address is 0). */
void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list);

View File

@ -1,33 +0,0 @@
/*
* QEMU memory mapping
*
* Copyright Fujitsu, Corp. 2011, 2012
*
* Authors:
* Wen Congyang <wency@cn.fujitsu.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#include "cpu.h"
#include "exec/cpu-all.h"
#include "sysemu/memory_mapping.h"
int qemu_get_guest_memory_mapping(MemoryMappingList *list)
{
return -2;
}
int cpu_get_memory_mapping(MemoryMappingList *list,
CPUArchState *env)
{
return -1;
}
bool cpu_paging_enabled(CPUArchState *env)
{
return true;
}

View File

@ -170,7 +170,7 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
CPUArchState *env;
for (env = start_cpu; env != NULL; env = env->next_cpu) {
if (cpu_paging_enabled(env)) {
if (cpu_paging_enabled(ENV_GET_CPU(env))) {
return env;
}
}
@ -178,22 +178,23 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
return NULL;
}
int qemu_get_guest_memory_mapping(MemoryMappingList *list)
void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
{
CPUArchState *env, *first_paging_enabled_cpu;
RAMBlock *block;
ram_addr_t offset, length;
int ret;
first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
if (first_paging_enabled_cpu) {
for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
ret = cpu_get_memory_mapping(list, env);
if (ret < 0) {
return -1;
Error *err = NULL;
cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
if (err) {
error_propagate(errp, err);
return;
}
}
return 0;
return;
}
/*
@ -205,8 +206,6 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list)
length = block->length;
create_new_memory_mapping(list, offset, offset, length);
}
return 0;
}
void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)

View File

@ -2013,7 +2013,6 @@ static void do_acl_remove(Monitor *mon, const QDict *qdict)
static void do_inject_mce(Monitor *mon, const QDict *qdict)
{
X86CPU *cpu;
CPUX86State *cenv;
CPUState *cs;
int cpu_index = qdict_get_int(qdict, "cpu_index");
int bank = qdict_get_int(qdict, "bank");
@ -2026,14 +2025,11 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict)
if (qdict_get_try_bool(qdict, "broadcast", 0)) {
flags |= MCE_INJECT_BROADCAST;
}
for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
cpu = x86_env_get_cpu(cenv);
cs = CPU(cpu);
if (cs->cpu_index == cpu_index) {
cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
flags);
break;
}
cs = qemu_get_cpu(cpu_index);
if (cs != NULL) {
cpu = X86_CPU(cs);
cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
flags);
}
}
#endif

View File

@ -50,6 +50,33 @@ bool cpu_exists(int64_t id)
return data.found;
}
bool cpu_paging_enabled(const CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
return cc->get_paging_enabled(cpu);
}
static bool cpu_common_get_paging_enabled(const CPUState *cpu)
{
return false;
}
void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
Error **errp)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
return cc->get_memory_mapping(cpu, list, errp);
}
static void cpu_common_get_memory_mapping(CPUState *cpu,
MemoryMappingList *list,
Error **errp)
{
error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
}
/* CPU hot-plug notifiers */
static NotifierList cpu_added_notifiers =
NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
@ -176,6 +203,8 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->class_by_name = cpu_common_class_by_name;
k->reset = cpu_common_reset;
k->get_arch_id = cpu_common_get_arch_id;
k->get_paging_enabled = cpu_common_get_paging_enabled;
k->get_memory_mapping = cpu_common_get_memory_mapping;
k->write_elf32_qemunote = cpu_common_write_elf32_qemunote;
k->write_elf32_note = cpu_common_write_elf32_note;
k->write_elf64_qemunote = cpu_common_write_elf64_qemunote;

View File

@ -2,6 +2,7 @@ stub-obj-y += arch-query-cpu-def.o
stub-obj-y += clock-warp.o
stub-obj-y += cpu-get-clock.o
stub-obj-y += cpu-get-icount.o
stub-obj-y += dump.o
stub-obj-y += fdset-add-fd.o
stub-obj-y += fdset-find-fd.o
stub-obj-y += fdset-get-fd.o

View File

@ -16,14 +16,6 @@
#include "qapi/qmp/qerror.h"
#include "qmp-commands.h"
/* we need this function in hmp.c */
void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
int64_t begin, bool has_length, int64_t length,
Error **errp)
{
error_set(errp, QERR_UNSUPPORTED);
}
int cpu_get_dump_info(ArchDumpInfo *info)
{
return -1;

View File

@ -239,11 +239,15 @@ static void walk_pml4e(MemoryMappingList *list,
}
#endif
int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
void x86_cpu_get_memory_mapping(CPUState *cs, MemoryMappingList *list,
Error **errp)
{
if (!cpu_paging_enabled(env)) {
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
if (!cpu_paging_enabled(cs)) {
/* paging is disabled */
return 0;
return;
}
if (env->cr[4] & CR4_PAE_MASK) {
@ -269,11 +273,5 @@ int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)
pse = !!(env->cr[4] & CR4_PSE_MASK);
walk_pde2(list, pde_addr, env->a20_mask, pse);
}
return 0;
}
bool cpu_paging_enabled(CPUArchState *env)
{
return env->cr[0] & CR0_PG_MASK;
}

View File

@ -98,4 +98,7 @@ int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
void *opaque);
void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
Error **errp);
#endif

View File

@ -221,7 +221,7 @@ X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
const char *get_register_name_32(unsigned int reg)
{
if (reg > CPU_NB_REGS32) {
if (reg >= CPU_NB_REGS32) {
return NULL;
}
return x86_reg_info_32[reg].name;
@ -669,10 +669,10 @@ static x86_def_t builtin_x86_defs[] = {
},
{
.name = "Conroe",
.level = 2,
.level = 4,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 2,
.model = 15,
.stepping = 3,
.features[FEAT_1_EDX] =
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
@ -691,10 +691,10 @@ static x86_def_t builtin_x86_defs[] = {
},
{
.name = "Penryn",
.level = 2,
.level = 4,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 2,
.model = 23,
.stepping = 3,
.features[FEAT_1_EDX] =
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
@ -714,10 +714,10 @@ static x86_def_t builtin_x86_defs[] = {
},
{
.name = "Nehalem",
.level = 2,
.level = 4,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
.model = 2,
.model = 26,
.stepping = 3,
.features[FEAT_1_EDX] =
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
@ -2505,6 +2505,13 @@ static int64_t x86_cpu_get_arch_id(CPUState *cs)
return env->cpuid_apic_id;
}
static bool x86_cpu_get_paging_enabled(const CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
return cpu->env.cr[0] & CR0_PG_MASK;
}
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
{
X86CPUClass *xcc = X86_CPU_CLASS(oc);
@ -2519,15 +2526,16 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->reset = x86_cpu_reset;
cc->do_interrupt = x86_cpu_do_interrupt;
cc->get_arch_id = x86_cpu_get_arch_id;
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
#ifndef CONFIG_USER_ONLY
cc->get_memory_mapping = x86_cpu_get_memory_mapping;
cc->write_elf64_note = x86_cpu_write_elf64_note;
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
cc->write_elf32_note = x86_cpu_write_elf32_note;
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
#endif
cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
cc->get_arch_id = x86_cpu_get_arch_id;
}
static const TypeInfo x86_cpu_type_info = {