mirror of https://github.com/xemu-project/xemu.git
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:
commit
5f13731f8c
|
@ -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
|
||||
|
|
|
@ -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
12
dump.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",\
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
14
monitor.c
14
monitor.c
|
@ -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
|
||||
|
|
29
qom/cpu.c
29
qom/cpu.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue