cpu_synchronize_state() is a little unreadable since the 'modified'
argument isn't self-explanatory. Simplify it by making it always
synchronize the kernel state into qemu, and automatically flush the
registers back to the kernel if they've been synchronized on this
exit.
Signed-off-by: Avi Kivity <[email protected]>
Signed-off-by: Anthony Liguori <[email protected]>
{
CPUState *env = opaque;
{
CPUState *env = opaque;
- cpu_synchronize_state(env, 0);
+ cpu_synchronize_state(env);
qemu_put_be32s(f, &env->halted);
qemu_put_be32s(f, &env->interrupt_request);
qemu_put_be32s(f, &env->halted);
qemu_put_be32s(f, &env->interrupt_request);
{
CPUState *env = opaque;
{
CPUState *env = opaque;
+ cpu_synchronize_state(env);
if (version_id != CPU_COMMON_SAVE_VERSION)
return -EINVAL;
if (version_id != CPU_COMMON_SAVE_VERSION)
return -EINVAL;
version_id is increased. */
env->interrupt_request &= ~0x01;
tlb_flush(env, 1);
version_id is increased. */
env->interrupt_request &= ~0x01;
tlb_flush(env, 1);
- cpu_synchronize_state(env, 1);
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
{
#if defined(TARGET_I386)
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
{
#if defined(TARGET_I386)
+ cpu_synchronize_state(s->c_cpu);
- cpu_synchronize_state(s->c_cpu, 1);
#elif defined (TARGET_PPC)
s->c_cpu->nip = pc;
#elif defined (TARGET_SPARC)
#elif defined (TARGET_PPC)
s->c_cpu->nip = pc;
#elif defined (TARGET_SPARC)
- cpu_synchronize_state(s->g_cpu, 0);
+ cpu_synchronize_state(s->g_cpu);
len = 0;
for (addr = 0; addr < num_g_regs; addr++) {
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
len = 0;
for (addr = 0; addr < num_g_regs; addr++) {
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
put_packet(s, buf);
break;
case 'G':
put_packet(s, buf);
break;
case 'G':
+ cpu_synchronize_state(s->g_cpu);
registers = mem_buf;
len = strlen(p) / 2;
hextomem((uint8_t *)registers, p, len);
registers = mem_buf;
len = strlen(p) / 2;
hextomem((uint8_t *)registers, p, len);
len -= reg_size;
registers += reg_size;
}
len -= reg_size;
registers += reg_size;
}
- cpu_synchronize_state(s->g_cpu, 1);
put_packet(s, "OK");
break;
case 'm':
put_packet(s, "OK");
break;
case 'm':
thread = strtoull(p+16, (char **)&p, 16);
env = find_cpu(thread);
if (env != NULL) {
thread = strtoull(p+16, (char **)&p, 16);
env = find_cpu(thread);
if (env != NULL) {
- cpu_synchronize_state(env, 0);
+ cpu_synchronize_state(env);
len = snprintf((char *)mem_buf, sizeof(mem_buf),
"CPU#%d [%s]", env->cpu_index,
env->halted ? "halted " : "running");
len = snprintf((char *)mem_buf, sizeof(mem_buf),
"CPU#%d [%s]", env->cpu_index,
env->halted ? "halted " : "running");
static void apic_reset(void *opaque)
{
APICState *s = opaque;
static void apic_reset(void *opaque)
{
APICState *s = opaque;
- int bsp = cpu_is_bsp(s->cpu_env);
+ cpu_synchronize_state(s->cpu_env);
+
+ bsp = cpu_is_bsp(s->cpu_env);
s->apicbase = 0xfee00000 |
(bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
s->apicbase = 0xfee00000 |
(bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
*/
s->lvt[APIC_LVT_LINT0] = 0x700;
}
*/
s->lvt[APIC_LVT_LINT0] = 0x700;
}
-
- cpu_synchronize_state(s->cpu_env, 1);
}
static CPUReadMemoryFunc * const apic_mem_read[3] = {
}
static CPUReadMemoryFunc * const apic_mem_read[3] = {
KVMSlot slots[32];
int fd;
int vmfd;
KVMSlot slots[32];
int fd;
int vmfd;
int coalesced_mmio;
int broken_set_mem_region;
int migration_log;
int coalesced_mmio;
int broken_set_mem_region;
int migration_log;
+void kvm_cpu_synchronize_state(CPUState *env)
+{
+ if (!env->kvm_state->regs_modified) {
+ kvm_arch_get_registers(env);
+ env->kvm_state->regs_modified = 1;
+ }
+}
+
int kvm_cpu_exec(CPUState *env)
{
struct kvm_run *run = env->kvm_run;
int kvm_cpu_exec(CPUState *env)
{
struct kvm_run *run = env->kvm_run;
+ if (env->kvm_state->regs_modified) {
+ kvm_arch_put_registers(env);
+ env->kvm_state->regs_modified = 0;
+ }
+
kvm_arch_pre_run(env, run);
ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
kvm_arch_post_run(env, run);
kvm_arch_pre_run(env, run);
ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
kvm_arch_post_run(env, run);
uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
int reg);
uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
int reg);
+void kvm_cpu_synchronize_state(CPUState *env);
/* generic hooks - to be moved/refactored once there are more users */
/* generic hooks - to be moved/refactored once there are more users */
-static inline void cpu_synchronize_state(CPUState *env, int modified)
+static inline void cpu_synchronize_state(CPUState *env)
- if (modified)
- kvm_arch_put_registers(env);
- else
- kvm_arch_get_registers(env);
+ kvm_cpu_synchronize_state(env);
if (!cur_mon->mon_cpu) {
mon_set_cpu(0);
}
if (!cur_mon->mon_cpu) {
mon_set_cpu(0);
}
- cpu_synchronize_state(cur_mon->mon_cpu, 0);
+ cpu_synchronize_state(cur_mon->mon_cpu);
return cur_mon->mon_cpu;
}
return cur_mon->mon_cpu;
}
mon_get_cpu();
for(env = first_cpu; env != NULL; env = env->next_cpu) {
mon_get_cpu();
for(env = first_cpu; env != NULL; env = env->next_cpu) {
- cpu_synchronize_state(env, 0);
+ cpu_synchronize_state(env);
monitor_printf(mon, "%c CPU #%d:",
(env == mon->mon_cpu) ? '*' : ' ',
env->cpu_index);
monitor_printf(mon, "%c CPU #%d:",
(env == mon->mon_cpu) ? '*' : ' ',
env->cpu_index);
int32_t pending_irq;
int i, bit;
int32_t pending_irq;
int i, bit;
- cpu_synchronize_state(env, 0);
+ cpu_synchronize_state(env);
for(i = 0; i < CPU_NB_REGS; i++)
qemu_put_betls(f, &env->regs[i]);
for(i = 0; i < CPU_NB_REGS; i++)
qemu_put_betls(f, &env->regs[i]);
int32_t a20_mask;
int32_t pending_irq;
int32_t a20_mask;
int32_t pending_irq;
+ cpu_synchronize_state(env);
if (version_id < 3 || version_id > CPU_SAVE_VERSION)
return -EINVAL;
for(i = 0; i < CPU_NB_REGS; i++)
if (version_id < 3 || version_id > CPU_SAVE_VERSION)
return -EINVAL;
for(i = 0; i < CPU_NB_REGS; i++)
/* XXX: compute redundant hflags bits */
env->hflags = hflags;
tlb_flush(env, 1);
/* XXX: compute redundant hflags bits */
env->hflags = hflags;
tlb_flush(env, 1);
- cpu_synchronize_state(env, 1);
CPUState *env = (CPUState *)opaque;
unsigned int i, j;
CPUState *env = (CPUState *)opaque;
unsigned int i, j;
- cpu_synchronize_state(env, 0);
+ cpu_synchronize_state(env);
for (i = 0; i < 32; i++)
qemu_put_betls(f, &env->gpr[i]);
for (i = 0; i < 32; i++)
qemu_put_betls(f, &env->gpr[i]);
CPUState *env = (CPUState *)opaque;
unsigned int i, j;
CPUState *env = (CPUState *)opaque;
unsigned int i, j;
+ cpu_synchronize_state(env);
+
for (i = 0; i < 32; i++)
qemu_get_betls(f, &env->gpr[i]);
#if !defined(TARGET_PPC64)
for (i = 0; i < 32; i++)
qemu_get_betls(f, &env->gpr[i]);
#if !defined(TARGET_PPC64)
qemu_get_sbe32s(f, &env->mmu_idx);
qemu_get_sbe32s(f, &env->power_mode);
qemu_get_sbe32s(f, &env->mmu_idx);
qemu_get_sbe32s(f, &env->power_mode);
- cpu_synchronize_state(env, 1);
-