mirror of https://gitlab.com/qemu-project/qemu
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_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
|
||||||
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
|
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
|
||||||
CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),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
|
# cpu emulator library
|
||||||
|
@ -111,10 +109,8 @@ obj-y += hw/
|
||||||
obj-$(CONFIG_FDT) += device_tree.o
|
obj-$(CONFIG_FDT) += device_tree.o
|
||||||
obj-$(CONFIG_KVM) += kvm-all.o
|
obj-$(CONFIG_KVM) += kvm-all.o
|
||||||
obj-y += memory.o savevm.o cputlb.o
|
obj-y += memory.o savevm.o cputlb.o
|
||||||
obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o
|
obj-y += memory_mapping.o
|
||||||
obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o
|
obj-y += dump.o
|
||||||
obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o
|
|
||||||
obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o
|
|
||||||
LIBS+=$(libs_softmmu)
|
LIBS+=$(libs_softmmu)
|
||||||
|
|
||||||
# xen support
|
# xen support
|
||||||
|
|
|
@ -4280,19 +4280,11 @@ case "$target_arch2" in
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
esac
|
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
|
if test "$target_bigendian" = "yes" ; then
|
||||||
echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
|
echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
|
||||||
fi
|
fi
|
||||||
if test "$target_softmmu" = "yes" ; then
|
if test "$target_softmmu" = "yes" ; then
|
||||||
echo "CONFIG_SOFTMMU=y" >> $config_target_mak
|
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
|
fi
|
||||||
if test "$target_user_only" = "yes" ; then
|
if test "$target_user_only" = "yes" ; then
|
||||||
echo "CONFIG_USER_ONLY=y" >> $config_target_mak
|
echo "CONFIG_USER_ONLY=y" >> $config_target_mak
|
||||||
|
|
12
dump.c
12
dump.c
|
@ -21,6 +21,7 @@
|
||||||
#include "sysemu/dump.h"
|
#include "sysemu/dump.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "sysemu/memory_mapping.h"
|
#include "sysemu/memory_mapping.h"
|
||||||
|
#include "sysemu/cpus.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qmp-commands.h"
|
#include "qmp-commands.h"
|
||||||
|
|
||||||
|
@ -706,6 +707,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
||||||
{
|
{
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
int nr_cpus;
|
int nr_cpus;
|
||||||
|
Error *err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (runstate_is_running()) {
|
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
|
* If the target architecture is not supported, cpu_get_dump_info() will
|
||||||
* return -1.
|
* 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.
|
* info.
|
||||||
*/
|
*/
|
||||||
|
cpu_synchronize_all_states();
|
||||||
nr_cpus = 0;
|
nr_cpus = 0;
|
||||||
for (env = first_cpu; env != NULL; env = env->next_cpu) {
|
for (env = first_cpu; env != NULL; env = env->next_cpu) {
|
||||||
cpu_synchronize_state(env);
|
|
||||||
nr_cpus++;
|
nr_cpus++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,7 +758,11 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
||||||
/* get memory mapping */
|
/* get memory mapping */
|
||||||
memory_mapping_list_init(&s->list);
|
memory_mapping_list_init(&s->list);
|
||||||
if (paging) {
|
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 {
|
} else {
|
||||||
qemu_get_guest_simple_memory_mapping(&s->list);
|
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.
|
new parameters (if specified) once the vm migration finished successfully.
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
#if defined(CONFIG_HAVE_CORE_DUMP)
|
|
||||||
{
|
{
|
||||||
.name = "dump-guest-memory",
|
.name = "dump-guest-memory",
|
||||||
.args_type = "paging:-p,filename:F,begin:i?,length:i?",
|
.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
|
length: the memory size, in bytes. It's optional, and should be specified
|
||||||
with begin together.
|
with begin together.
|
||||||
ETEXI
|
ETEXI
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
.name = "snapshot_blkdev",
|
.name = "snapshot_blkdev",
|
||||||
|
|
|
@ -927,6 +927,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
|
||||||
DeviceState *icc_bridge;
|
DeviceState *icc_bridge;
|
||||||
int64_t apic_id = x86_cpu_apic_id_from_index(id);
|
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)) {
|
if (cpu_exists(apic_id)) {
|
||||||
error_setg(errp, "Unable to add CPU: %" PRIi64
|
error_setg(errp, "Unable to add CPU: %" PRIi64
|
||||||
", it already exists", id);
|
", it already exists", id);
|
||||||
|
|
|
@ -327,8 +327,8 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static QEMUMachine pc_i440fx_machine_v1_5 = {
|
static QEMUMachine pc_i440fx_machine_v1_6 = {
|
||||||
.name = "pc-i440fx-1.5",
|
.name = "pc-i440fx-1.6",
|
||||||
.alias = "pc",
|
.alias = "pc",
|
||||||
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
||||||
.init = pc_init_pci,
|
.init = pc_init_pci,
|
||||||
|
@ -338,6 +338,19 @@ static QEMUMachine pc_i440fx_machine_v1_5 = {
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
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 = {
|
static QEMUMachine pc_i440fx_machine_v1_4 = {
|
||||||
.name = "pc-i440fx-1.4",
|
.name = "pc-i440fx-1.4",
|
||||||
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
||||||
|
@ -735,6 +748,7 @@ static QEMUMachine xenfv_machine = {
|
||||||
|
|
||||||
static void pc_machine_init(void)
|
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_5);
|
||||||
qemu_register_machine(&pc_i440fx_machine_v1_4);
|
qemu_register_machine(&pc_i440fx_machine_v1_4);
|
||||||
qemu_register_machine(&pc_machine_v1_3);
|
qemu_register_machine(&pc_machine_v1_3);
|
||||||
|
|
|
@ -215,8 +215,8 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
|
||||||
pc_q35_init(args);
|
pc_q35_init(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_q35_machine_v1_5 = {
|
static QEMUMachine pc_q35_machine_v1_6 = {
|
||||||
.name = "pc-q35-1.5",
|
.name = "pc-q35-1.6",
|
||||||
.alias = "q35",
|
.alias = "q35",
|
||||||
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
||||||
.init = pc_q35_init,
|
.init = pc_q35_init,
|
||||||
|
@ -225,6 +225,19 @@ static QEMUMachine pc_q35_machine_v1_5 = {
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
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 = {
|
static QEMUMachine pc_q35_machine_v1_4 = {
|
||||||
.name = "pc-q35-1.4",
|
.name = "pc-q35-1.4",
|
||||||
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
||||||
|
@ -239,6 +252,7 @@ static QEMUMachine pc_q35_machine_v1_4 = {
|
||||||
|
|
||||||
static void pc_q35_machine_init(void)
|
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_5);
|
||||||
qemu_register_machine(&pc_q35_machine_v1_4);
|
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)
|
uint32_t nret, target_ulong rets)
|
||||||
{
|
{
|
||||||
target_ulong id;
|
target_ulong id;
|
||||||
CPUPPCState *env;
|
|
||||||
CPUState *cpu;
|
CPUState *cpu;
|
||||||
|
|
||||||
if (nargs != 1 || nret != 2) {
|
if (nargs != 1 || nret != 2) {
|
||||||
|
@ -139,12 +138,8 @@ static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
|
||||||
}
|
}
|
||||||
|
|
||||||
id = rtas_ld(args, 0);
|
id = rtas_ld(args, 0);
|
||||||
for (env = first_cpu; env; env = env->next_cpu) {
|
cpu = qemu_get_cpu(id);
|
||||||
cpu = CPU(ppc_env_get_cpu(env));
|
if (cpu != NULL) {
|
||||||
if (cpu->cpu_index != id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu->halted) {
|
if (cpu->halted) {
|
||||||
rtas_st(rets, 1, 0);
|
rtas_st(rets, 1, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -165,8 +160,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
|
||||||
uint32_t nret, target_ulong rets)
|
uint32_t nret, target_ulong rets)
|
||||||
{
|
{
|
||||||
target_ulong id, start, r3;
|
target_ulong id, start, r3;
|
||||||
CPUState *cpu;
|
CPUState *cs;
|
||||||
CPUPPCState *env;
|
|
||||||
|
|
||||||
if (nargs != 3 || nret != 1) {
|
if (nargs != 3 || nret != 1) {
|
||||||
rtas_st(rets, 0, -3);
|
rtas_st(rets, 0, -3);
|
||||||
|
@ -177,14 +171,12 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
|
||||||
start = rtas_ld(args, 1);
|
start = rtas_ld(args, 1);
|
||||||
r3 = rtas_ld(args, 2);
|
r3 = rtas_ld(args, 2);
|
||||||
|
|
||||||
for (env = first_cpu; env; env = env->next_cpu) {
|
cs = qemu_get_cpu(id);
|
||||||
cpu = CPU(ppc_env_get_cpu(env));
|
if (cs != NULL) {
|
||||||
|
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||||
|
CPUPPCState *env = &cpu->env;
|
||||||
|
|
||||||
if (cpu->cpu_index != id) {
|
if (!cs->halted) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cpu->halted) {
|
|
||||||
rtas_st(rets, 0, -1);
|
rtas_st(rets, 0, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -197,9 +189,9 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
|
||||||
env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
|
env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
|
||||||
env->nip = start;
|
env->nip = start;
|
||||||
env->gpr[3] = r3;
|
env->gpr[3] = r3;
|
||||||
cpu->halted = 0;
|
cs->halted = 0;
|
||||||
|
|
||||||
qemu_cpu_kick(cpu);
|
qemu_cpu_kick(cs);
|
||||||
|
|
||||||
rtas_st(rets, 0, 0);
|
rtas_st(rets, 0, 0);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -185,7 +185,35 @@ int pvpanic_init(ISABus *bus);
|
||||||
|
|
||||||
int e820_add_entry(uint64_t, uint64_t, uint32_t);
|
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 \
|
#define PC_COMPAT_1_4 \
|
||||||
|
PC_COMPAT_1_5, \
|
||||||
{\
|
{\
|
||||||
.driver = "scsi-hd",\
|
.driver = "scsi-hd",\
|
||||||
.property = "discard_granularity",\
|
.property = "discard_granularity",\
|
||||||
|
|
|
@ -22,6 +22,8 @@ typedef struct AddressSpace AddressSpace;
|
||||||
typedef struct MemoryRegion MemoryRegion;
|
typedef struct MemoryRegion MemoryRegion;
|
||||||
typedef struct MemoryRegionSection MemoryRegionSection;
|
typedef struct MemoryRegionSection MemoryRegionSection;
|
||||||
|
|
||||||
|
typedef struct MemoryMappingList MemoryMappingList;
|
||||||
|
|
||||||
typedef struct NICInfo NICInfo;
|
typedef struct NICInfo NICInfo;
|
||||||
typedef struct HCIInfo HCIInfo;
|
typedef struct HCIInfo HCIInfo;
|
||||||
typedef struct AudioState AudioState;
|
typedef struct AudioState AudioState;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "hw/qdev-core.h"
|
#include "hw/qdev-core.h"
|
||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
|
#include "qemu/typedefs.h"
|
||||||
|
|
||||||
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
|
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.
|
* @reset: Callback to reset the #CPUState to its initial state.
|
||||||
* @do_interrupt: Callback for interrupt handling.
|
* @do_interrupt: Callback for interrupt handling.
|
||||||
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
|
* @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.
|
* @vmsd: State description for migration.
|
||||||
*
|
*
|
||||||
* Represents a CPU family or model.
|
* Represents a CPU family or model.
|
||||||
|
@ -62,6 +65,9 @@ typedef struct CPUClass {
|
||||||
void (*reset)(CPUState *cpu);
|
void (*reset)(CPUState *cpu);
|
||||||
void (*do_interrupt)(CPUState *cpu);
|
void (*do_interrupt)(CPUState *cpu);
|
||||||
int64_t (*get_arch_id)(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;
|
const struct VMStateDescription *vmsd;
|
||||||
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||||
|
@ -137,6 +143,23 @@ struct CPUState {
|
||||||
uint32_t halted; /* used by alpha, cris, ppc TCG */
|
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:
|
* cpu_write_elf64_note:
|
||||||
* @f: pointer to a function that writes memory to a file
|
* @f: pointer to a function that writes memory to a file
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#define MEMORY_MAPPING_H
|
#define MEMORY_MAPPING_H
|
||||||
|
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
|
#include "qemu/typedefs.h"
|
||||||
|
|
||||||
/* The physical and virtual address in the memory mapping are contiguous. */
|
/* The physical and virtual address in the memory mapping are contiguous. */
|
||||||
typedef struct MemoryMapping {
|
typedef struct MemoryMapping {
|
||||||
|
@ -24,14 +25,11 @@ typedef struct MemoryMapping {
|
||||||
QTAILQ_ENTRY(MemoryMapping) next;
|
QTAILQ_ENTRY(MemoryMapping) next;
|
||||||
} MemoryMapping;
|
} MemoryMapping;
|
||||||
|
|
||||||
typedef struct MemoryMappingList {
|
struct MemoryMappingList {
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
MemoryMapping *last_mapping;
|
MemoryMapping *last_mapping;
|
||||||
QTAILQ_HEAD(, MemoryMapping) head;
|
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
|
* 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);
|
void memory_mapping_list_init(MemoryMappingList *list);
|
||||||
|
|
||||||
/*
|
void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
|
||||||
* Return value:
|
|
||||||
* 0: success
|
|
||||||
* -1: failed
|
|
||||||
* -2: unsupported
|
|
||||||
*/
|
|
||||||
int qemu_get_guest_memory_mapping(MemoryMappingList *list);
|
|
||||||
|
|
||||||
/* get guest's memory mapping without do paging(virtual address is 0). */
|
/* get guest's memory mapping without do paging(virtual address is 0). */
|
||||||
void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list);
|
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;
|
CPUArchState *env;
|
||||||
|
|
||||||
for (env = start_cpu; env != NULL; env = env->next_cpu) {
|
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;
|
return env;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,22 +178,23 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
|
||||||
return NULL;
|
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;
|
CPUArchState *env, *first_paging_enabled_cpu;
|
||||||
RAMBlock *block;
|
RAMBlock *block;
|
||||||
ram_addr_t offset, length;
|
ram_addr_t offset, length;
|
||||||
int ret;
|
|
||||||
|
|
||||||
first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
|
first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
|
||||||
if (first_paging_enabled_cpu) {
|
if (first_paging_enabled_cpu) {
|
||||||
for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
|
for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
|
||||||
ret = cpu_get_memory_mapping(list, env);
|
Error *err = NULL;
|
||||||
if (ret < 0) {
|
cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
|
||||||
return -1;
|
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;
|
length = block->length;
|
||||||
create_new_memory_mapping(list, offset, offset, length);
|
create_new_memory_mapping(list, offset, offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)
|
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)
|
static void do_inject_mce(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
X86CPU *cpu;
|
X86CPU *cpu;
|
||||||
CPUX86State *cenv;
|
|
||||||
CPUState *cs;
|
CPUState *cs;
|
||||||
int cpu_index = qdict_get_int(qdict, "cpu_index");
|
int cpu_index = qdict_get_int(qdict, "cpu_index");
|
||||||
int bank = qdict_get_int(qdict, "bank");
|
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)) {
|
if (qdict_get_try_bool(qdict, "broadcast", 0)) {
|
||||||
flags |= MCE_INJECT_BROADCAST;
|
flags |= MCE_INJECT_BROADCAST;
|
||||||
}
|
}
|
||||||
for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
|
cs = qemu_get_cpu(cpu_index);
|
||||||
cpu = x86_env_get_cpu(cenv);
|
if (cs != NULL) {
|
||||||
cs = CPU(cpu);
|
cpu = X86_CPU(cs);
|
||||||
if (cs->cpu_index == cpu_index) {
|
cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
|
||||||
cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
|
flags);
|
||||||
flags);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
29
qom/cpu.c
29
qom/cpu.c
|
@ -50,6 +50,33 @@ bool cpu_exists(int64_t id)
|
||||||
return data.found;
|
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 */
|
/* CPU hot-plug notifiers */
|
||||||
static NotifierList cpu_added_notifiers =
|
static NotifierList cpu_added_notifiers =
|
||||||
NOTIFIER_LIST_INITIALIZER(cpu_add_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->class_by_name = cpu_common_class_by_name;
|
||||||
k->reset = cpu_common_reset;
|
k->reset = cpu_common_reset;
|
||||||
k->get_arch_id = cpu_common_get_arch_id;
|
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_qemunote = cpu_common_write_elf32_qemunote;
|
||||||
k->write_elf32_note = cpu_common_write_elf32_note;
|
k->write_elf32_note = cpu_common_write_elf32_note;
|
||||||
k->write_elf64_qemunote = cpu_common_write_elf64_qemunote;
|
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 += clock-warp.o
|
||||||
stub-obj-y += cpu-get-clock.o
|
stub-obj-y += cpu-get-clock.o
|
||||||
stub-obj-y += cpu-get-icount.o
|
stub-obj-y += cpu-get-icount.o
|
||||||
|
stub-obj-y += dump.o
|
||||||
stub-obj-y += fdset-add-fd.o
|
stub-obj-y += fdset-add-fd.o
|
||||||
stub-obj-y += fdset-find-fd.o
|
stub-obj-y += fdset-find-fd.o
|
||||||
stub-obj-y += fdset-get-fd.o
|
stub-obj-y += fdset-get-fd.o
|
||||||
|
|
|
@ -16,14 +16,6 @@
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qmp-commands.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)
|
int cpu_get_dump_info(ArchDumpInfo *info)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
|
@ -239,11 +239,15 @@ static void walk_pml4e(MemoryMappingList *list,
|
||||||
}
|
}
|
||||||
#endif
|
#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 */
|
/* paging is disabled */
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env->cr[4] & CR4_PAE_MASK) {
|
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);
|
pse = !!(env->cr[4] & CR4_PSE_MASK);
|
||||||
walk_pde2(list, pde_addr, env->a20_mask, pse);
|
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,
|
int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
|
void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -221,7 +221,7 @@ X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
|
||||||
|
|
||||||
const char *get_register_name_32(unsigned int reg)
|
const char *get_register_name_32(unsigned int reg)
|
||||||
{
|
{
|
||||||
if (reg > CPU_NB_REGS32) {
|
if (reg >= CPU_NB_REGS32) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return x86_reg_info_32[reg].name;
|
return x86_reg_info_32[reg].name;
|
||||||
|
@ -669,10 +669,10 @@ static x86_def_t builtin_x86_defs[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Conroe",
|
.name = "Conroe",
|
||||||
.level = 2,
|
.level = 4,
|
||||||
.vendor = CPUID_VENDOR_INTEL,
|
.vendor = CPUID_VENDOR_INTEL,
|
||||||
.family = 6,
|
.family = 6,
|
||||||
.model = 2,
|
.model = 15,
|
||||||
.stepping = 3,
|
.stepping = 3,
|
||||||
.features[FEAT_1_EDX] =
|
.features[FEAT_1_EDX] =
|
||||||
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
||||||
|
@ -691,10 +691,10 @@ static x86_def_t builtin_x86_defs[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Penryn",
|
.name = "Penryn",
|
||||||
.level = 2,
|
.level = 4,
|
||||||
.vendor = CPUID_VENDOR_INTEL,
|
.vendor = CPUID_VENDOR_INTEL,
|
||||||
.family = 6,
|
.family = 6,
|
||||||
.model = 2,
|
.model = 23,
|
||||||
.stepping = 3,
|
.stepping = 3,
|
||||||
.features[FEAT_1_EDX] =
|
.features[FEAT_1_EDX] =
|
||||||
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
||||||
|
@ -714,10 +714,10 @@ static x86_def_t builtin_x86_defs[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Nehalem",
|
.name = "Nehalem",
|
||||||
.level = 2,
|
.level = 4,
|
||||||
.vendor = CPUID_VENDOR_INTEL,
|
.vendor = CPUID_VENDOR_INTEL,
|
||||||
.family = 6,
|
.family = 6,
|
||||||
.model = 2,
|
.model = 26,
|
||||||
.stepping = 3,
|
.stepping = 3,
|
||||||
.features[FEAT_1_EDX] =
|
.features[FEAT_1_EDX] =
|
||||||
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
|
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;
|
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)
|
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
X86CPUClass *xcc = X86_CPU_CLASS(oc);
|
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->reset = x86_cpu_reset;
|
||||||
|
|
||||||
cc->do_interrupt = x86_cpu_do_interrupt;
|
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
|
#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_note = x86_cpu_write_elf64_note;
|
||||||
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
|
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
|
||||||
cc->write_elf32_note = x86_cpu_write_elf32_note;
|
cc->write_elf32_note = x86_cpu_write_elf32_note;
|
||||||
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
|
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
|
||||||
#endif
|
#endif
|
||||||
cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
|
cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
|
||||||
|
|
||||||
cc->get_arch_id = x86_cpu_get_arch_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo x86_cpu_type_info = {
|
static const TypeInfo x86_cpu_type_info = {
|
||||||
|
|
Loading…
Reference in New Issue