handle some errors properly so avoid exit() during initialization. this fixes issue #237

This commit is contained in:
Nguyen Anh Quynh 2015-11-12 01:43:41 +08:00
parent 116d96692d
commit 2f297bdd3a
38 changed files with 203 additions and 125 deletions

View file

@ -58,6 +58,7 @@ module Common =
let UC_ERR_WRITE_UNALIGNED = 17 let UC_ERR_WRITE_UNALIGNED = 17
let UC_ERR_FETCH_UNALIGNED = 18 let UC_ERR_FETCH_UNALIGNED = 18
let UC_ERR_HOOK_EXIST = 19 let UC_ERR_HOOK_EXIST = 19
let UC_ERR_RESOURCE = 20
let UC_MEM_READ = 16 let UC_MEM_READ = 16
let UC_MEM_WRITE = 17 let UC_MEM_WRITE = 17
let UC_MEM_FETCH = 18 let UC_MEM_FETCH = 18

View file

@ -53,6 +53,7 @@ const (
ERR_WRITE_UNALIGNED = 17 ERR_WRITE_UNALIGNED = 17
ERR_FETCH_UNALIGNED = 18 ERR_FETCH_UNALIGNED = 18
ERR_HOOK_EXIST = 19 ERR_HOOK_EXIST = 19
ERR_RESOURCE = 20
MEM_READ = 16 MEM_READ = 16
MEM_WRITE = 17 MEM_WRITE = 17
MEM_FETCH = 18 MEM_FETCH = 18

View file

@ -55,6 +55,7 @@ public interface UnicornConst {
public static final int UC_ERR_WRITE_UNALIGNED = 17; public static final int UC_ERR_WRITE_UNALIGNED = 17;
public static final int UC_ERR_FETCH_UNALIGNED = 18; public static final int UC_ERR_FETCH_UNALIGNED = 18;
public static final int UC_ERR_HOOK_EXIST = 19; public static final int UC_ERR_HOOK_EXIST = 19;
public static final int UC_ERR_RESOURCE = 20;
public static final int UC_MEM_READ = 16; public static final int UC_MEM_READ = 16;
public static final int UC_MEM_WRITE = 17; public static final int UC_MEM_WRITE = 17;
public static final int UC_MEM_FETCH = 18; public static final int UC_MEM_FETCH = 18;

View file

@ -51,6 +51,7 @@ UC_ERR_READ_UNALIGNED = 16
UC_ERR_WRITE_UNALIGNED = 17 UC_ERR_WRITE_UNALIGNED = 17
UC_ERR_FETCH_UNALIGNED = 18 UC_ERR_FETCH_UNALIGNED = 18
UC_ERR_HOOK_EXIST = 19 UC_ERR_HOOK_EXIST = 19
UC_ERR_RESOURCE = 20
UC_MEM_READ = 16 UC_MEM_READ = 16
UC_MEM_WRITE = 17 UC_MEM_WRITE = 17
UC_MEM_FETCH = 18 UC_MEM_FETCH = 18

View file

@ -36,6 +36,7 @@ typedef bool (*uc_read_mem_t)(AddressSpace *as, hwaddr addr, uint8_t *buf, int l
typedef void (*uc_args_void_t)(void*); typedef void (*uc_args_void_t)(void*);
typedef void (*uc_args_uc_t)(struct uc_struct*); typedef void (*uc_args_uc_t)(struct uc_struct*);
typedef int (*uc_args_int_uc_t)(struct uc_struct*);
typedef bool (*uc_args_tcg_enable_t)(struct uc_struct*); typedef bool (*uc_args_tcg_enable_t)(struct uc_struct*);
@ -91,7 +92,8 @@ struct uc_struct {
uc_args_uc_u64_t set_pc; // set PC for tracecode uc_args_uc_u64_t set_pc; // set PC for tracecode
uc_args_int_t stop_interrupt; // check if the interrupt should stop emulation uc_args_int_t stop_interrupt; // check if the interrupt should stop emulation
uc_args_uc_t init_arch, pause_all_vcpus, vm_start, cpu_exec_init_all; uc_args_uc_t init_arch, pause_all_vcpus, cpu_exec_init_all;
uc_args_int_uc_t vm_start;
uc_args_tcg_enable_t tcg_enabled; uc_args_tcg_enable_t tcg_enabled;
uc_args_uc_long_t tcg_exec_init; uc_args_uc_long_t tcg_exec_init;
uc_args_uc_ram_size_t memory_map; uc_args_uc_ram_size_t memory_map;

View file

@ -125,6 +125,7 @@ typedef enum uc_err {
UC_ERR_WRITE_UNALIGNED, // Unaligned write UC_ERR_WRITE_UNALIGNED, // Unaligned write
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
UC_ERR_HOOK_EXIST, // hook for this event already existed UC_ERR_HOOK_EXIST, // hook for this event already existed
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
} uc_err; } uc_err;

View file

@ -37,16 +37,19 @@ static bool cpu_can_run(CPUState *cpu);
static void cpu_handle_guest_debug(CPUState *cpu); static void cpu_handle_guest_debug(CPUState *cpu);
static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env); static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env);
static bool tcg_exec_all(struct uc_struct* uc); static bool tcg_exec_all(struct uc_struct* uc);
static void qemu_tcg_init_vcpu(CPUState *cpu); static int qemu_tcg_init_vcpu(CPUState *cpu);
static void *qemu_tcg_cpu_thread_fn(void *arg); static void *qemu_tcg_cpu_thread_fn(void *arg);
void vm_start(struct uc_struct* uc) int vm_start(struct uc_struct* uc)
{ {
resume_all_vcpus(uc); if (resume_all_vcpus(uc)) {
return -1;
}
//sleep(3);
// kick off TCG thread // kick off TCG thread
qemu_mutex_unlock_iothread(uc); qemu_mutex_unlock_iothread(uc);
return 0;
} }
bool cpu_is_stopped(CPUState *cpu) bool cpu_is_stopped(CPUState *cpu)
@ -78,7 +81,7 @@ void pause_all_vcpus(struct uc_struct *uc)
} }
void resume_all_vcpus(struct uc_struct *uc) int resume_all_vcpus(struct uc_struct *uc)
{ {
CPUState *cpu; CPUState *cpu;
@ -93,7 +96,8 @@ void resume_all_vcpus(struct uc_struct *uc)
CPU_FOREACH(cpu) { CPU_FOREACH(cpu) {
cpu->created = true; cpu->created = true;
cpu->halted = 0; cpu->halted = 0;
qemu_init_vcpu(cpu); if (qemu_init_vcpu(cpu))
return -1;
} }
qemu_mutex_lock_iothread(uc); qemu_mutex_lock_iothread(uc);
} }
@ -103,18 +107,21 @@ void resume_all_vcpus(struct uc_struct *uc)
CPU_FOREACH(cpu) { CPU_FOREACH(cpu) {
cpu_resume(cpu); cpu_resume(cpu);
} }
return 0;
} }
void qemu_init_vcpu(CPUState *cpu) int qemu_init_vcpu(CPUState *cpu)
{ {
cpu->nr_cores = smp_cores; cpu->nr_cores = smp_cores;
cpu->nr_threads = smp_threads; cpu->nr_threads = smp_threads;
cpu->stopped = true; cpu->stopped = true;
cpu->uc->tcg_cpu_thread = NULL; cpu->uc->tcg_cpu_thread = NULL;
if (tcg_enabled(cpu->uc)) { if (tcg_enabled(cpu->uc))
qemu_tcg_init_vcpu(cpu); return qemu_tcg_init_vcpu(cpu);
}
return 0;
} }
@ -133,7 +140,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
} }
qemu_cond_signal(&uc->qemu_cpu_cond); qemu_cond_signal(&uc->qemu_cpu_cond);
/* wait for initial kick-off after machine start */ /* wait for initial kick-off after machine start */
while (QTAILQ_FIRST(&uc->cpus)->stopped) { while (QTAILQ_FIRST(&uc->cpus)->stopped) {
qemu_cond_wait(uc->tcg_halt_cond, &uc->qemu_global_mutex); qemu_cond_wait(uc->tcg_halt_cond, &uc->qemu_global_mutex);
@ -170,7 +176,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* For temporary buffers for forming a name */ /* For temporary buffers for forming a name */
#define VCPU_THREAD_NAME_SIZE 16 #define VCPU_THREAD_NAME_SIZE 16
static void qemu_tcg_init_vcpu(CPUState *cpu) static int qemu_tcg_init_vcpu(CPUState *cpu)
{ {
struct uc_struct *uc = cpu->uc; struct uc_struct *uc = cpu->uc;
char thread_name[VCPU_THREAD_NAME_SIZE]; char thread_name[VCPU_THREAD_NAME_SIZE];
@ -185,8 +191,9 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
uc->tcg_halt_cond = cpu->halt_cond; uc->tcg_halt_cond = cpu->halt_cond;
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
cpu->cpu_index); cpu->cpu_index);
qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, if (qemu_thread_create(uc, cpu->thread, thread_name, qemu_tcg_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE); cpu, QEMU_THREAD_JOINABLE))
return -1;
#ifdef _WIN32 #ifdef _WIN32
cpu->hThread = qemu_thread_get_handle(cpu->thread); cpu->hThread = qemu_thread_get_handle(cpu->thread);
#endif #endif
@ -198,6 +205,8 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
cpu->thread = uc->tcg_cpu_thread; cpu->thread = uc->tcg_cpu_thread;
cpu->halt_cond = uc->tcg_halt_cond; cpu->halt_cond = uc->tcg_halt_cond;
} }
return 0;
} }
static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env) static int tcg_cpu_exec(struct uc_struct *uc, CPUArchState *env)

View file

@ -17,10 +17,12 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
static void tosa_init(struct uc_struct *uc, MachineState *machine) static int tosa_init(struct uc_struct *uc, MachineState *machine)
{ {
//cpu_arm_init(uc, "pxa255"); //cpu_arm_init(uc, "pxa255");
cpu_arm_init(uc, "cortex-a15"); // FIXME cpu_arm_init(uc, "cortex-a15"); // FIXME
return 0;
} }
void tosa_machine_init(struct uc_struct *uc) void tosa_machine_init(struct uc_struct *uc)

View file

@ -36,7 +36,7 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
static void machvirt_init(struct uc_struct *uc, MachineState *machine) static int machvirt_init(struct uc_struct *uc, MachineState *machine)
{ {
const char *cpu_model = machine->cpu_model; const char *cpu_model = machine->cpu_model;
int n; int n;
@ -51,12 +51,14 @@ static void machvirt_init(struct uc_struct *uc, MachineState *machine)
if (!oc) { if (!oc) {
fprintf(stderr, "Unable to find CPU definition\n"); fprintf(stderr, "Unable to find CPU definition\n");
exit(1); return -1;
} }
cpuobj = object_new(uc, object_class_get_name(oc)); cpuobj = object_new(uc, object_class_get_name(oc));
object_property_set_bool(uc, cpuobj, true, "realized", NULL); object_property_set_bool(uc, cpuobj, true, "realized", NULL);
} }
return 0;
} }
void machvirt_machine_init(struct uc_struct *uc) void machvirt_machine_init(struct uc_struct *uc)

View file

@ -155,7 +155,7 @@ static bool device_get_realized(struct uc_struct *uc, Object *obj, Error **errp)
return dev->realized; return dev->realized;
} }
static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, Error **errp) static int device_set_realized(struct uc_struct *uc, Object *obj, bool value, Error **errp)
{ {
DeviceState *dev = DEVICE(uc, obj); DeviceState *dev = DEVICE(uc, obj);
DeviceClass *dc = DEVICE_GET_CLASS(uc, dev); DeviceClass *dc = DEVICE_GET_CLASS(uc, dev);
@ -164,7 +164,7 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
if (dev->hotplugged && !dc->hotpluggable) { if (dev->hotplugged && !dc->hotpluggable) {
error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj)); error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
return; return -1;
} }
if (value && !dev->realized) { if (value && !dev->realized) {
@ -181,7 +181,8 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
#endif #endif
if (dc->realize) { if (dc->realize) {
dc->realize(uc, dev, &local_err); if (dc->realize(uc, dev, &local_err))
return -1;
} }
if (local_err != NULL) { if (local_err != NULL) {
@ -222,7 +223,7 @@ static void device_set_realized(struct uc_struct *uc, Object *obj, bool value, E
} }
dev->realized = value; dev->realized = value;
return; return 0;
child_realize_fail: child_realize_fail:
QLIST_FOREACH(bus, &dev->child_bus, sibling) { QLIST_FOREACH(bus, &dev->child_bus, sibling) {
@ -237,7 +238,7 @@ post_realize_fail:
fail: fail:
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
static void device_initfn(struct uc_struct *uc, Object *obj, void *opaque) static void device_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View file

@ -104,7 +104,7 @@ static X86CPU *pc_new_cpu(struct uc_struct *uc, const char *cpu_model, int64_t a
} }
object_property_set_int(uc, OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_int(uc, OBJECT(cpu), apic_id, "apic-id", &local_err);
object_property_set_bool(uc, OBJECT(cpu), true, "realized", &local_err); object_property_set_bool(uc, OBJECT(cpu), true, "realized", &local_err); // qq
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
@ -114,7 +114,7 @@ static X86CPU *pc_new_cpu(struct uc_struct *uc, const char *cpu_model, int64_t a
return cpu; return cpu;
} }
void pc_cpus_init(struct uc_struct *uc, const char *cpu_model) int pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
{ {
int i; int i;
Error *error = NULL; Error *error = NULL;
@ -129,13 +129,15 @@ void pc_cpus_init(struct uc_struct *uc, const char *cpu_model)
} }
for (i = 0; i < smp_cpus; i++) { for (i = 0; i < smp_cpus; i++) {
uc->cpu = pc_new_cpu(uc, cpu_model, x86_cpu_apic_id_from_index(i), &error); uc->cpu = pc_new_cpu(uc, cpu_model, x86_cpu_apic_id_from_index(i), &error); // qq
if (error) { if (error) {
//error_report("%s", error_get_pretty(error)); //error_report("%s", error_get_pretty(error));
error_free(error); error_free(error);
exit(1); return -1;
} }
} }
return 0;
} }
static void pc_machine_initfn(struct uc_struct *uc, Object *obj, void *opaque) static void pc_machine_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View file

@ -36,14 +36,14 @@
#define GIGABYTE_ALIGN true #define GIGABYTE_ALIGN true
/* PC hardware initialisation */ /* PC hardware initialisation */
static void pc_init1(struct uc_struct *uc, MachineState *machine) static int pc_init1(struct uc_struct *uc, MachineState *machine)
{ {
pc_cpus_init(uc, machine->cpu_model); return pc_cpus_init(uc, machine->cpu_model);
} }
static void pc_init_pci(struct uc_struct *uc, MachineState *machine) static int pc_init_pci(struct uc_struct *uc, MachineState *machine)
{ {
pc_init1(uc, machine); return pc_init1(uc, machine);
} }
#define PC_I440FX_MACHINE_OPTIONS \ #define PC_I440FX_MACHINE_OPTIONS \

View file

@ -186,8 +186,9 @@ static void apic_post_load(APICCommonState *s)
} }
} }
static void apic_realize(struct uc_struct *uc, DeviceState *dev, Error **errp) static int apic_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
return 0;
} }
static void apic_class_init(struct uc_struct *uc, ObjectClass *klass, void *data) static void apic_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)

View file

@ -196,7 +196,7 @@ static void apic_reset_common(struct uc_struct *uc, DeviceState *dev)
} }
} }
static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **errp) static int apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
APICCommonState *s = APIC_COMMON(uc, dev); APICCommonState *s = APIC_COMMON(uc, dev);
APICCommonClass *info; APICCommonClass *info;
@ -204,7 +204,7 @@ static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **
if (uc->apic_no >= MAX_APICS) { if (uc->apic_no >= MAX_APICS) {
error_setg(errp, "%s initialization failed.", error_setg(errp, "%s initialization failed.",
object_get_typename(OBJECT(dev))); object_get_typename(OBJECT(dev)));
return; return -1;
} }
s->idx = uc->apic_no++; s->idx = uc->apic_no++;
@ -225,6 +225,8 @@ static void apic_common_realize(struct uc_struct *uc, DeviceState *dev, Error **
if (uc->apic_report_tpr_access && info->enable_tpr_reporting) { if (uc->apic_report_tpr_access && info->enable_tpr_reporting) {
info->enable_tpr_reporting(s, true); info->enable_tpr_reporting(s, true);
} }
return 0;
} }
static void apic_common_class_init(struct uc_struct *uc, ObjectClass *klass, void *data) static void apic_common_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)

View file

@ -16,7 +16,7 @@
/* Board init. */ /* Board init. */
static void dummy_m68k_init(struct uc_struct *uc, MachineState *machine) static int dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
{ {
const char *cpu_model = machine->cpu_model; const char *cpu_model = machine->cpu_model;
CPUM68KState *env; CPUM68KState *env;
@ -27,12 +27,14 @@ static void dummy_m68k_init(struct uc_struct *uc, MachineState *machine)
env = cpu_init(uc, cpu_model); env = cpu_init(uc, cpu_model);
if (!env) { if (!env) {
fprintf(stderr, "Unable to find m68k CPU definition\n"); fprintf(stderr, "Unable to find m68k CPU definition\n");
exit(1); return -1;
} }
/* Initialize CPU registers. */ /* Initialize CPU registers. */
env->vbr = 0; env->vbr = 0;
env->pc = 0; env->pc = 0;
return 0;
} }
void dummy_m68k_machine_init(struct uc_struct *uc) void dummy_m68k_machine_init(struct uc_struct *uc)

View file

@ -20,7 +20,7 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
static void mips_r4k_init(struct uc_struct *uc, MachineState *machine) static int mips_r4k_init(struct uc_struct *uc, MachineState *machine)
{ {
const char *cpu_model = machine->cpu_model; const char *cpu_model = machine->cpu_model;
MIPSCPU *cpu; MIPSCPU *cpu;
@ -38,8 +38,10 @@ static void mips_r4k_init(struct uc_struct *uc, MachineState *machine)
cpu = cpu_mips_init(uc, cpu_model); cpu = cpu_mips_init(uc, cpu_model);
if (cpu == NULL) { if (cpu == NULL) {
fprintf(stderr, "Unable to find CPU definition\n"); fprintf(stderr, "Unable to find CPU definition\n");
exit(1); return -1;
} }
return 0;
} }
void mips_machine_init(struct uc_struct *uc) void mips_machine_init(struct uc_struct *uc)

View file

@ -33,7 +33,7 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
static void leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine) static int leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
{ {
const char *cpu_model = machine->cpu_model; const char *cpu_model = machine->cpu_model;
SPARCCPU *cpu; SPARCCPU *cpu;
@ -46,10 +46,12 @@ static void leon3_generic_hw_init(struct uc_struct *uc, MachineState *machine)
cpu = cpu_sparc_init(uc, cpu_model); cpu = cpu_sparc_init(uc, cpu_model);
if (cpu == NULL) { if (cpu == NULL) {
fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n"); fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
exit(1); return -1;
} }
cpu_sparc_set_id(&cpu->env, 0); cpu_sparc_set_id(&cpu->env, 0);
return 0;
} }
void leon3_machine_init(struct uc_struct *uc) void leon3_machine_init(struct uc_struct *uc)

View file

@ -30,7 +30,7 @@
/* Sun4u hardware initialisation */ /* Sun4u hardware initialisation */
static void sun4u_init(struct uc_struct *uc, MachineState *machine) static int sun4u_init(struct uc_struct *uc, MachineState *machine)
{ {
const char *cpu_model = machine->cpu_model; const char *cpu_model = machine->cpu_model;
SPARCCPU *cpu; SPARCCPU *cpu;
@ -41,8 +41,10 @@ static void sun4u_init(struct uc_struct *uc, MachineState *machine)
cpu = cpu_sparc_init(uc, cpu_model); cpu = cpu_sparc_init(uc, cpu_model);
if (cpu == NULL) { if (cpu == NULL) {
fprintf(stderr, "Unable to find Sparc CPU definition\n"); fprintf(stderr, "Unable to find Sparc CPU definition\n");
exit(1); return -1;
} }
return 0;
} }
void sun4u_machine_init(struct uc_struct *uc) void sun4u_machine_init(struct uc_struct *uc)

View file

@ -9,7 +9,7 @@
#include "qom/object.h" #include "qom/object.h"
#include "uc_priv.h" #include "uc_priv.h"
typedef void QEMUMachineInitFunc(struct uc_struct *uc, MachineState *ms); typedef int QEMUMachineInitFunc(struct uc_struct *uc, MachineState *ms);
typedef void QEMUMachineResetFunc(void); typedef void QEMUMachineResetFunc(void);
@ -54,7 +54,7 @@ struct MachineClass {
const char *family; /* NULL iff @name identifies a standalone machtype */ const char *family; /* NULL iff @name identifies a standalone machtype */
const char *name; const char *name;
void (*init)(struct uc_struct *uc, MachineState *state); int (*init)(struct uc_struct *uc, MachineState *state);
void (*reset)(void); void (*reset)(void);
int max_cpus; int max_cpus;

View file

@ -34,7 +34,7 @@ typedef struct PCMachineClass PCMachineClass;
#define PC_MACHINE_CLASS(klass) \ #define PC_MACHINE_CLASS(klass) \
OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE) OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
void pc_cpus_init(struct uc_struct *uc, const char *cpu_model); int pc_cpus_init(struct uc_struct *uc, const char *cpu_model);
FWCfgState *pc_memory_init(MachineState *machine, FWCfgState *pc_memory_init(MachineState *machine,
MemoryRegion *system_memory, MemoryRegion *system_memory,

View file

@ -32,7 +32,7 @@ typedef enum DeviceCategory {
typedef int (*qdev_initfn)(DeviceState *dev); typedef int (*qdev_initfn)(DeviceState *dev);
typedef int (*qdev_event)(DeviceState *dev); typedef int (*qdev_event)(DeviceState *dev);
typedef void (*qdev_resetfn)(DeviceState *dev); typedef void (*qdev_resetfn)(DeviceState *dev);
typedef void (*DeviceRealize)(struct uc_struct *uc, DeviceState *dev, Error **errp); typedef int (*DeviceRealize)(struct uc_struct *uc, DeviceState *dev, Error **errp);
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp); typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
typedef void (*BusRealize)(BusState *bus, Error **errp); typedef void (*BusRealize)(BusState *bus, Error **errp);
typedef void (*BusUnrealize)(BusState *bus, Error **errp); typedef void (*BusUnrealize)(BusState *bus, Error **errp);

View file

@ -53,7 +53,8 @@ void qemu_event_wait(QemuEvent *ev);
void qemu_event_destroy(QemuEvent *ev); void qemu_event_destroy(QemuEvent *ev);
struct uc_struct; struct uc_struct;
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, // return -1 on error, 0 on success
int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
void *(*start_routine)(void *), void *(*start_routine)(void *),
void *arg, int mode); void *arg, int mode);
void *qemu_thread_join(QemuThread *thread); void *qemu_thread_join(QemuThread *thread);

View file

@ -582,7 +582,7 @@ void cpu_resume(CPUState *cpu);
* *
* Initializes a vCPU. * Initializes a vCPU.
*/ */
void qemu_init_vcpu(CPUState *cpu); int qemu_init_vcpu(CPUState *cpu);
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ #define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ #define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */

View file

@ -304,6 +304,11 @@ typedef void (ObjectPropertyAccessor)(struct uc_struct *uc, Object *obj,
void *opaque, void *opaque,
const char *name, const char *name,
Error **errp); Error **errp);
typedef int (ObjectPropertySetAccessor)(struct uc_struct *uc, Object *obj,
struct Visitor *v,
void *opaque,
const char *name,
Error **errp);
/** /**
* ObjectPropertyResolve: * ObjectPropertyResolve:
@ -342,7 +347,7 @@ typedef struct ObjectProperty
gchar *type; gchar *type;
gchar *description; gchar *description;
ObjectPropertyAccessor *get; ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set; ObjectPropertySetAccessor *set;
ObjectPropertyResolve *resolve; ObjectPropertyResolve *resolve;
ObjectPropertyRelease *release; ObjectPropertyRelease *release;
void *opaque; void *opaque;
@ -799,7 +804,7 @@ void object_unref(struct uc_struct *uc, Object *obj);
ObjectProperty *object_property_add(Object *obj, const char *name, ObjectProperty *object_property_add(Object *obj, const char *name,
const char *type, const char *type,
ObjectPropertyAccessor *get, ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set, ObjectPropertySetAccessor *set,
ObjectPropertyRelease *release, ObjectPropertyRelease *release,
void *opaque, Error **errp); void *opaque, Error **errp);
@ -1168,7 +1173,7 @@ void object_property_add_link(Object *obj, const char *name,
*/ */
void object_property_add_str(Object *obj, const char *name, void object_property_add_str(Object *obj, const char *name,
char *(*get)(struct uc_struct *uc, Object *, Error **), char *(*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, const char *, Error **), int (*set)(struct uc_struct *uc, Object *, const char *, Error **),
Error **errp); Error **errp);
/** /**
@ -1184,7 +1189,7 @@ void object_property_add_str(Object *obj, const char *name,
*/ */
void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name, void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name,
bool (*get)(struct uc_struct *uc, Object *, Error **), bool (*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, bool, Error **), int (*set)(struct uc_struct *uc, Object *, bool, Error **),
Error **errp); Error **errp);
/** /**

View file

@ -5,7 +5,7 @@ struct uc_struct;
/* cpus.c */ /* cpus.c */
void qemu_init_cpu_loop(struct uc_struct*); void qemu_init_cpu_loop(struct uc_struct*);
void resume_all_vcpus(struct uc_struct*); int resume_all_vcpus(struct uc_struct*);
void pause_all_vcpus(struct uc_struct*); void pause_all_vcpus(struct uc_struct*);
void cpu_stop_current(struct uc_struct*); void cpu_stop_current(struct uc_struct*);

View file

@ -17,7 +17,7 @@ typedef struct vm_change_state_entry VMChangeStateEntry;
#define VMRESET_SILENT false #define VMRESET_SILENT false
#define VMRESET_REPORT true #define VMRESET_REPORT true
void vm_start(struct uc_struct*); int vm_start(struct uc_struct*);
void qemu_system_reset_request(struct uc_struct*); void qemu_system_reset_request(struct uc_struct*);
void qemu_system_shutdown_request(void); void qemu_system_shutdown_request(void);

View file

@ -216,13 +216,15 @@ static void cpu_common_parse_features(CPUState *cpu, char *features,
} }
} }
static void cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int cpu_common_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
CPUState *cpu = CPU(dev); CPUState *cpu = CPU(dev);
if (dev->hotplugged) { if (dev->hotplugged) {
cpu_resume(cpu); cpu_resume(cpu);
} }
return 0;
} }
static void cpu_common_initfn(struct uc_struct *uc, Object *obj, void *opaque) static void cpu_common_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View file

@ -716,7 +716,7 @@ void object_unref(struct uc_struct *uc, Object *obj)
ObjectProperty * ObjectProperty *
object_property_add(Object *obj, const char *name, const char *type, object_property_add(Object *obj, const char *name, const char *type,
ObjectPropertyAccessor *get, ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set, ObjectPropertySetAccessor *set,
ObjectPropertyRelease *release, ObjectPropertyRelease *release,
void *opaque, Error **errp) void *opaque, Error **errp)
{ {
@ -826,7 +826,8 @@ void object_property_set(struct uc_struct *uc, Object *obj, Visitor *v, const ch
if (!prop->set) { if (!prop->set) {
error_set(errp, QERR_PERMISSION_DENIED); error_set(errp, QERR_PERMISSION_DENIED);
} else { } else {
prop->set(uc, obj, v, prop->opaque, name, errp); if (prop->set(uc, obj, v, prop->opaque, name, errp))
error_set(errp, QERR_UNDEFINED_ERROR);
} }
} }
@ -1169,7 +1170,7 @@ static Object *object_resolve_link(struct uc_struct *uc, Object *obj, const char
return target; return target;
} }
static void object_set_link_property(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int object_set_link_property(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
Error *local_err = NULL; Error *local_err = NULL;
@ -1188,18 +1189,20 @@ static void object_set_link_property(struct uc_struct *uc, Object *obj, Visitor
g_free(path); g_free(path);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
prop->check(obj, name, new_target, &local_err); prop->check(obj, name, new_target, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
object_ref(new_target); object_ref(new_target);
*child = new_target; *child = new_target;
object_unref(uc, old_target); object_unref(uc, old_target);
return 0;
} }
static Object *object_resolve_link_property(struct uc_struct *uc, Object *parent, void *opaque, const gchar *part) static Object *object_resolve_link_property(struct uc_struct *uc, Object *parent, void *opaque, const gchar *part)
@ -1410,7 +1413,7 @@ Object *object_resolve_path(struct uc_struct *uc, const char *path, bool *ambigu
typedef struct StringProperty typedef struct StringProperty
{ {
char *(*get)(struct uc_struct *uc, Object *, Error **); char *(*get)(struct uc_struct *uc, Object *, Error **);
void (*set)(struct uc_struct *uc, Object *, const char *, Error **); int (*set)(struct uc_struct *uc, Object *, const char *, Error **);
} StringProperty; } StringProperty;
static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1426,7 +1429,7 @@ static void property_get_str(struct uc_struct *uc, Object *obj, Visitor *v, void
} }
} }
static void property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
StringProperty *prop = opaque; StringProperty *prop = opaque;
@ -1436,11 +1439,13 @@ static void property_set_str(struct uc_struct *uc, Object *obj, Visitor *v, void
visit_type_str(v, &value, name, &local_err); visit_type_str(v, &value, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
prop->set(uc, obj, value, errp); prop->set(uc, obj, value, errp);
g_free(value); g_free(value);
return 0;
} }
static void property_release_str(struct uc_struct *uc, Object *obj, const char *name, static void property_release_str(struct uc_struct *uc, Object *obj, const char *name,
@ -1452,7 +1457,7 @@ static void property_release_str(struct uc_struct *uc, Object *obj, const char *
void object_property_add_str(Object *obj, const char *name, void object_property_add_str(Object *obj, const char *name,
char *(*get)(struct uc_struct *uc, Object *, Error **), char *(*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, const char *, Error **), int (*set)(struct uc_struct *uc, Object *, const char *, Error **),
Error **errp) Error **errp)
{ {
Error *local_err = NULL; Error *local_err = NULL;
@ -1475,7 +1480,7 @@ void object_property_add_str(Object *obj, const char *name,
typedef struct BoolProperty typedef struct BoolProperty
{ {
bool (*get)(struct uc_struct *uc, Object *, Error **); bool (*get)(struct uc_struct *uc, Object *, Error **);
void (*set)(struct uc_struct *uc, Object *, bool, Error **); int (*set)(struct uc_struct *uc, Object *, bool, Error **);
} BoolProperty; } BoolProperty;
static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1488,7 +1493,7 @@ static void property_get_bool(struct uc_struct *uc, Object *obj, Visitor *v, voi
visit_type_bool(v, &value, name, errp); visit_type_bool(v, &value, name, errp);
} }
static void property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
BoolProperty *prop = opaque; BoolProperty *prop = opaque;
@ -1498,10 +1503,10 @@ static void property_set_bool(struct uc_struct *uc, Object *obj, Visitor *v, voi
visit_type_bool(v, &value, name, &local_err); visit_type_bool(v, &value, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
prop->set(uc, obj, value, errp); return prop->set(uc, obj, value, errp);
} }
static void property_release_bool(struct uc_struct *uc, Object *obj, const char *name, static void property_release_bool(struct uc_struct *uc, Object *obj, const char *name,
@ -1513,7 +1518,7 @@ static void property_release_bool(struct uc_struct *uc, Object *obj, const char
void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name, void object_property_add_bool(struct uc_struct *uc, Object *obj, const char *name,
bool (*get)(struct uc_struct *uc, Object *, Error **), bool (*get)(struct uc_struct *uc, Object *, Error **),
void (*set)(struct uc_struct *uc, Object *, bool, Error **), int (*set)(struct uc_struct *uc, Object *, bool, Error **),
Error **errp) Error **errp)
{ {
Error *local_err = NULL; Error *local_err = NULL;
@ -1611,12 +1616,14 @@ static void property_get_alias(struct uc_struct *uc, Object *obj, struct Visitor
object_property_get(uc, prop->target_obj, v, prop->target_name, errp); object_property_get(uc, prop->target_obj, v, prop->target_name, errp);
} }
static void property_set_alias(struct uc_struct *uc, Object *obj, struct Visitor *v, void *opaque, static int property_set_alias(struct uc_struct *uc, Object *obj, struct Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
AliasProperty *prop = opaque; AliasProperty *prop = opaque;
object_property_set(uc, prop->target_obj, v, prop->target_name, errp); object_property_set(uc, prop->target_obj, v, prop->target_name, errp);
return 0;
} }
static Object *property_resolve_alias(struct uc_struct *uc, Object *obj, void *opaque, static Object *property_resolve_alias(struct uc_struct *uc, Object *obj, void *opaque,

View file

@ -21,7 +21,7 @@ void object_property_set_qobject(struct uc_struct *uc, Object *obj, QObject *val
{ {
QmpInputVisitor *mi; QmpInputVisitor *mi;
mi = qmp_input_visitor_new(value); mi = qmp_input_visitor_new(value);
object_property_set(uc, obj, qmp_input_get_visitor(mi), name, errp); object_property_set(uc, obj, qmp_input_get_visitor(mi), name, errp); // qq
qmp_input_visitor_cleanup(mi); qmp_input_visitor_cleanup(mi);
} }

View file

@ -329,7 +329,7 @@ static void arm_cpu_finalizefn(struct uc_struct *uc, Object *obj, void *opaque)
g_hash_table_destroy(cpu->cp_regs); g_hash_table_destroy(cpu->cp_regs);
} }
static void arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev); CPUState *cs = CPU(dev);
ARMCPU *cpu = ARM_CPU(uc, dev); ARMCPU *cpu = ARM_CPU(uc, dev);
@ -399,6 +399,8 @@ static void arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
cpu_reset(cs); cpu_reset(cs);
acc->parent_realize(uc, dev, errp); acc->parent_realize(uc, dev, errp);
return 0;
} }
static ObjectClass *arm_cpu_class_by_name(struct uc_struct *uc, const char *cpu_model) static ObjectClass *arm_cpu_class_by_name(struct uc_struct *uc, const char *cpu_model)

View file

@ -1162,7 +1162,7 @@ static void x86_cpuid_version_get_family(struct uc_struct *uc, Object *obj, Visi
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, errp);
} }
static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
@ -1175,12 +1175,12 @@ static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visi
visit_type_int(v, &value, name, &local_err); visit_type_int(v, &value, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
if (value < min || value > max) { if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "", error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max); name ? name : "null", value, min, max);
return; return -1;
} }
env->cpuid_version &= ~0xff00f00; env->cpuid_version &= ~0xff00f00;
@ -1189,6 +1189,8 @@ static void x86_cpuid_version_set_family(struct uc_struct *uc, Object *obj, Visi
} else { } else {
env->cpuid_version |= value << 8; env->cpuid_version |= value << 8;
} }
return 0;
} }
static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1203,7 +1205,7 @@ static void x86_cpuid_version_get_model(struct uc_struct *uc, Object *obj, Visit
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, errp);
} }
static void x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
@ -1216,16 +1218,18 @@ static void x86_cpuid_version_set_model(struct uc_struct *uc, Object *obj, Visit
visit_type_int(v, &value, name, &local_err); visit_type_int(v, &value, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
if (value < min || value > max) { if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "", error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max); name ? name : "null", value, min, max);
return; return -1;
} }
env->cpuid_version &= ~0xf00f0; env->cpuid_version &= ~0xf00f0;
env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16); env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
return 0;
} }
static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Visitor *v, static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
@ -1240,7 +1244,7 @@ static void x86_cpuid_version_get_stepping(struct uc_struct *uc, Object *obj, Vi
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, errp);
} }
static void x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Visitor *v, static int x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Visitor *v,
void *opaque, const char *name, void *opaque, const char *name,
Error **errp) Error **errp)
{ {
@ -1254,16 +1258,18 @@ static void x86_cpuid_version_set_stepping(struct uc_struct *uc, Object *obj, Vi
visit_type_int(v, &value, name, &local_err); visit_type_int(v, &value, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
if (value < min || value > max) { if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "", error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max); name ? name : "null", value, min, max);
return; return -1;
} }
env->cpuid_version &= ~0xf; env->cpuid_version &= ~0xf;
env->cpuid_version |= value & 0xf; env->cpuid_version |= value & 0xf;
return 0;
} }
static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1274,12 +1280,14 @@ static void x86_cpuid_get_level(struct uc_struct *uc, Object *obj, Visitor *v, v
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp); visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
} }
static void x86_cpuid_set_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int x86_cpuid_set_level(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
visit_type_uint32(v, &cpu->env.cpuid_level, name, errp); visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
return 0;
} }
static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1290,12 +1298,14 @@ static void x86_cpuid_get_xlevel(struct uc_struct *uc, Object *obj, Visitor *v,
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp); visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
} }
static void x86_cpuid_set_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int x86_cpuid_set_xlevel(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp); visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
return 0;
} }
static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **errp) static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **errp)
@ -1310,7 +1320,7 @@ static char *x86_cpuid_get_vendor(struct uc_struct *uc, Object *obj, Error **err
return value; return value;
} }
static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *value, static int x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *value,
Error **errp) Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
@ -1320,7 +1330,7 @@ static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *
if (strlen(value) != CPUID_VENDOR_SZ) { if (strlen(value) != CPUID_VENDOR_SZ) {
error_set(errp, QERR_PROPERTY_VALUE_BAD, "", error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
"vendor", value); "vendor", value);
return; return -1;
} }
env->cpuid_vendor1 = 0; env->cpuid_vendor1 = 0;
@ -1331,6 +1341,8 @@ static void x86_cpuid_set_vendor(struct uc_struct *uc, Object *obj, const char *
env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i); env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i); env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
} }
return 0;
} }
static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **errp) static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **errp)
@ -1348,7 +1360,7 @@ static char *x86_cpuid_get_model_id(struct uc_struct *uc, Object *obj, Error **e
return value; return value;
} }
static void x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char *model_id, static int x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char *model_id,
Error **errp) Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
@ -1368,6 +1380,8 @@ static void x86_cpuid_set_model_id(struct uc_struct *uc, Object *obj, const char
} }
env->cpuid_model[i >> 2] |= c << (8 * (i & 3)); env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
} }
return 0;
} }
static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1380,7 +1394,7 @@ static void x86_cpuid_get_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, errp);
} }
static void x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
@ -1392,15 +1406,17 @@ static void x86_cpuid_set_tsc_freq(struct uc_struct *uc, Object *obj, Visitor *v
visit_type_int(v, &value, name, &local_err); visit_type_int(v, &value, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
if (value < min || value > max) { if (value < min || value > max) {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "", error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
name ? name : "null", value, min, max); name ? name : "null", value, min, max);
return; return -1;
} }
cpu->env.tsc_khz = value / 1000; cpu->env.tsc_khz = value / 1000;
return 0;
} }
static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
@ -1412,7 +1428,7 @@ static void x86_cpuid_get_apic_id(struct uc_struct *uc, Object *obj, Visitor *v,
visit_type_int(v, &value, name, errp); visit_type_int(v, &value, name, errp);
} }
static void x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque, static int x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp) const char *name, Error **errp)
{ {
X86CPU *cpu = X86_CPU(uc, obj); X86CPU *cpu = X86_CPU(uc, obj);
@ -1425,26 +1441,28 @@ static void x86_cpuid_set_apic_id(struct uc_struct *uc, Object *obj, Visitor *v,
if (dev->realized) { if (dev->realized) {
error_setg(errp, "Attempt to set property '%s' on '%s' after " error_setg(errp, "Attempt to set property '%s' on '%s' after "
"it was realized", name, object_get_typename(obj)); "it was realized", name, object_get_typename(obj));
return; return -1;
} }
visit_type_int(v, &value, name, &error); visit_type_int(v, &value, name, &error);
if (error) { if (error) {
error_propagate(errp, error); error_propagate(errp, error);
return; return -1;
} }
if (value < min || value > max) { if (value < min || value > max) {
error_setg(errp, "Property %s.%s doesn't take value %" PRId64 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
" (minimum: %" PRId64 ", maximum: %" PRId64 ")" , " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
object_get_typename(obj), name, value, min, max); object_get_typename(obj), name, value, min, max);
return; return -1;
} }
if ((value != cpu->env.cpuid_apic_id) && cpu_exists(uc, value)) { if ((value != cpu->env.cpuid_apic_id) && cpu_exists(uc, value)) {
error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value); error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
return; return -1;
} }
cpu->env.cpuid_apic_id = value; cpu->env.cpuid_apic_id = value;
return 0;
} }
/* Generic getter for "feature-words" and "filtered-features" properties */ /* Generic getter for "feature-words" and "filtered-features" properties */
@ -2249,7 +2267,7 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
#define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \ #define IS_AMD_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && \
(env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \ (env)->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && \
(env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3) (env)->cpuid_vendor3 == CPUID_VENDOR_AMD_3)
static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev); CPUState *cs = CPU(dev);
X86CPU *cpu = X86_CPU(uc, dev); X86CPU *cpu = X86_CPU(uc, dev);
@ -2270,7 +2288,6 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
& CPUID_EXT2_AMD_ALIASES); & CPUID_EXT2_AMD_ALIASES);
} }
if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) { if (x86_cpu_filter_features(cpu) && cpu->enforce_cpuid) {
error_setg(&local_err, error_setg(&local_err,
"TCG doesn't support requested features"); "TCG doesn't support requested features");
@ -2289,7 +2306,8 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
#endif #endif
mce_init(cpu); mce_init(cpu);
qemu_init_vcpu(cs); if (qemu_init_vcpu(cs))
return -1;
x86_cpu_apic_realize(cpu, &local_err); x86_cpu_apic_realize(cpu, &local_err);
if (local_err != NULL) { if (local_err != NULL) {
@ -2301,8 +2319,10 @@ static void x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **er
out: out:
if (local_err != NULL) { if (local_err != NULL) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return -1;
} }
return 0;
} }
/* Enables contiguous-apic-ID mode, for compatibility */ /* Enables contiguous-apic-ID mode, for compatibility */

View file

@ -146,7 +146,7 @@ static const M68kCPUInfo m68k_cpus[] = {
{ .name = "any", .instance_init = any_cpu_initfn }, { .name = "any", .instance_init = any_cpu_initfn },
}; };
static void m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev); CPUState *cs = CPU(dev);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(uc, dev); M68kCPUClass *mcc = M68K_CPU_GET_CLASS(uc, dev);
@ -155,6 +155,8 @@ static void m68k_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **e
qemu_init_vcpu(cs); qemu_init_vcpu(cs);
mcc->parent_realize(cs->uc, dev, errp); mcc->parent_realize(cs->uc, dev, errp);
return 0;
} }
static void m68k_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) static void m68k_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View file

@ -92,7 +92,7 @@ static void mips_cpu_reset(CPUState *s)
cpu_state_reset(env); cpu_state_reset(env);
} }
static void mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
CPUState *cs = CPU(dev); CPUState *cs = CPU(dev);
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(uc, dev); MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(uc, dev);
@ -101,6 +101,8 @@ static void mips_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **e
qemu_init_vcpu(cs); qemu_init_vcpu(cs);
mcc->parent_realize(uc, dev, errp); mcc->parent_realize(uc, dev, errp);
return 0;
} }
static void mips_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) static void mips_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View file

@ -783,7 +783,7 @@ static bool sparc_cpu_has_work(CPUState *cs)
cpu_interrupts_enabled(env); cpu_interrupts_enabled(env);
} }
static void sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp) static int sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **errp)
{ {
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(uc, dev); SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(uc, dev);
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
@ -798,6 +798,8 @@ static void sparc_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **
qemu_init_vcpu(CPU(dev)); qemu_init_vcpu(CPU(dev));
scc->parent_realize(uc, dev, errp); scc->parent_realize(uc, dev, errp);
return 0;
} }
static void sparc_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) static void sparc_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)

View file

@ -29,8 +29,8 @@
static void error_exit(int err, const char *msg) static void error_exit(int err, const char *msg)
{ {
fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); // fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
abort(); // abort();
} }
void qemu_mutex_init(QemuMutex *mutex) void qemu_mutex_init(QemuMutex *mutex)
@ -389,7 +389,7 @@ void qemu_event_wait(QemuEvent *ev)
} }
} }
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
void *(*start_routine)(void*), void *(*start_routine)(void*),
void *arg, int mode) void *arg, int mode)
{ {
@ -397,20 +397,16 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
int err; int err;
pthread_attr_t attr; pthread_attr_t attr;
#if 0
static int count = 0;
count++;
printf(">>> create thread %u\n", count);
#endif
err = pthread_attr_init(&attr); err = pthread_attr_init(&attr);
if (err) { if (err) {
error_exit(err, __func__); error_exit(err, __func__);
return -1;
} }
if (mode == QEMU_THREAD_DETACHED) { if (mode == QEMU_THREAD_DETACHED) {
err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (err) { if (err) {
error_exit(err, __func__); error_exit(err, __func__);
return -1;
} }
} }
@ -418,12 +414,16 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
sigfillset(&set); sigfillset(&set);
pthread_sigmask(SIG_SETMASK, &set, &oldset); pthread_sigmask(SIG_SETMASK, &set, &oldset);
err = pthread_create(&thread->thread, &attr, start_routine, arg); err = pthread_create(&thread->thread, &attr, start_routine, arg);
if (err) if (err) {
error_exit(err, __func__); error_exit(err, __func__);
return -1;
}
pthread_sigmask(SIG_SETMASK, &oldset, NULL); pthread_sigmask(SIG_SETMASK, &oldset, NULL);
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
return 0;
} }
void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread) void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread)

View file

@ -27,7 +27,7 @@ static void error_exit(int err, const char *msg)
NULL, err, 0, (LPTSTR)&pstr, 2, NULL); NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
fprintf(stderr, "qemu: %s: %s\n", msg, pstr); fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
LocalFree(pstr); LocalFree(pstr);
abort(); //abort();
} }
void qemu_mutex_init(QemuMutex *mutex) void qemu_mutex_init(QemuMutex *mutex)
@ -326,7 +326,7 @@ void *qemu_thread_join(QemuThread *thread)
return ret; return ret;
} }
void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name, int qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *name,
void *(*start_routine)(void *), void *(*start_routine)(void *),
void *arg, int mode) void *arg, int mode)
{ {
@ -350,9 +350,13 @@ void qemu_thread_create(struct uc_struct *uc, QemuThread *thread, const char *na
data, 0, &thread->tid); data, 0, &thread->tid);
if (!hThread) { if (!hThread) {
error_exit(GetLastError(), __func__); error_exit(GetLastError(), __func__);
return -1;
} }
CloseHandle(hThread); CloseHandle(hThread);
thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data; thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data;
return 0;
} }
void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread) void qemu_thread_get_self(struct uc_struct *uc, QemuThread *thread)

View file

@ -94,8 +94,6 @@ int machine_initialize(struct uc_struct *uc)
MachineClass *machine_class; MachineClass *machine_class;
MachineState *current_machine; MachineState *current_machine;
//printf(">>> starting machine initialize\n");
module_call_init(uc, MODULE_INIT_QOM); module_call_init(uc, MODULE_INIT_QOM);
register_types_object(uc); register_types_object(uc);
machine_register_types(uc); machine_register_types(uc);
@ -115,11 +113,8 @@ int machine_initialize(struct uc_struct *uc)
return -2; return -2;
} }
// printf("222\n");
current_machine = MACHINE(uc, object_new(uc, object_class_get_name( current_machine = MACHINE(uc, object_new(uc, object_class_get_name(
OBJECT_CLASS(machine_class)))); OBJECT_CLASS(machine_class))));
//object_property_add_child(object_get_root(), "machine",
// OBJECT(current_machine), &error_abort);
current_machine->uc = uc; current_machine->uc = uc;
uc->cpu_exec_init_all(uc); uc->cpu_exec_init_all(uc);
@ -129,14 +124,10 @@ int machine_initialize(struct uc_struct *uc)
qemu_init_cpu_loop(uc); qemu_init_cpu_loop(uc);
qemu_mutex_lock_iothread(uc); qemu_mutex_lock_iothread(uc);
//cpu_ticks_init();
// printf("333\n");
current_machine->cpu_model = NULL; current_machine->cpu_model = NULL;
machine_class->init(uc, current_machine);
//printf(">>> ending machine initialize\n"); return machine_class->init(uc, current_machine);
return 0;
} }
void qemu_system_reset_request(struct uc_struct* uc) void qemu_system_reset_request(struct uc_struct* uc)

10
uc.c
View file

@ -97,6 +97,8 @@ const char *uc_strerror(uc_err code)
return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)"; return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)";
case UC_ERR_HOOK_EXIST: case UC_ERR_HOOK_EXIST:
return "Hook for this type event already exists (UC_ERR_HOOK_EXIST)"; return "Hook for this type event already exists (UC_ERR_HOOK_EXIST)";
case UC_ERR_RESOURCE:
return "Insufficient resource (UC_ERR_RESOURCE)";
} }
} }
@ -235,7 +237,8 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
return UC_ERR_ARCH; return UC_ERR_ARCH;
} }
machine_initialize(uc); if (machine_initialize(uc))
return UC_ERR_RESOURCE;
*result = uc; *result = uc;
@ -502,7 +505,10 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
uc->addr_end = until; uc->addr_end = until;
uc->vm_start(uc); if (uc->vm_start(uc)) {
return UC_ERR_RESOURCE;
}
if (timeout) if (timeout)
enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds enable_emu_timer(uc, timeout * 1000); // microseconds -> nanoseconds
uc->pause_all_vcpus(uc); uc->pause_all_vcpus(uc);