kvm: Simplify cpu_synchronize_state()
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 <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
09aaa1602f
commit
4c0960c0c4
4
exec.c
4
exec.c
@ -519,7 +519,7 @@ static void cpu_common_save(QEMUFile *f, void *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);
|
||||
@ -529,6 +529,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
CPUState *env = opaque;
|
||||
|
||||
cpu_synchronize_state(env);
|
||||
if (version_id != CPU_COMMON_SAVE_VERSION)
|
||||
return -EINVAL;
|
||||
|
||||
@ -538,7 +539,6 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
|
||||
version_id is increased. */
|
||||
env->interrupt_request &= ~0x01;
|
||||
tlb_flush(env, 1);
|
||||
cpu_synchronize_state(env, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1568,8 +1568,8 @@ static void gdb_breakpoint_remove_all(void)
|
||||
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
|
||||
{
|
||||
#if defined(TARGET_I386)
|
||||
cpu_synchronize_state(s->c_cpu);
|
||||
s->c_cpu->eip = pc;
|
||||
cpu_synchronize_state(s->c_cpu, 1);
|
||||
#elif defined (TARGET_PPC)
|
||||
s->c_cpu->nip = pc;
|
||||
#elif defined (TARGET_SPARC)
|
||||
@ -1755,7 +1755,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
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);
|
||||
@ -1765,6 +1765,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
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);
|
||||
@ -1773,7 +1774,6 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
len -= reg_size;
|
||||
registers += reg_size;
|
||||
}
|
||||
cpu_synchronize_state(s->g_cpu, 1);
|
||||
put_packet(s, "OK");
|
||||
break;
|
||||
case 'm':
|
||||
@ -1929,7 +1929,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
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");
|
||||
|
@ -936,8 +936,11 @@ static const VMStateDescription vmstate_apic = {
|
||||
static void apic_reset(void *opaque)
|
||||
{
|
||||
APICState *s = opaque;
|
||||
int bsp = cpu_is_bsp(s->cpu_env);
|
||||
int bsp;
|
||||
|
||||
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;
|
||||
|
||||
@ -952,8 +955,6 @@ static void apic_reset(void *opaque)
|
||||
*/
|
||||
s->lvt[APIC_LVT_LINT0] = 0x700;
|
||||
}
|
||||
|
||||
cpu_synchronize_state(s->cpu_env, 1);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const apic_mem_read[3] = {
|
||||
|
14
kvm-all.c
14
kvm-all.c
@ -57,6 +57,7 @@ struct KVMState
|
||||
KVMSlot slots[32];
|
||||
int fd;
|
||||
int vmfd;
|
||||
int regs_modified;
|
||||
int coalesced_mmio;
|
||||
int broken_set_mem_region;
|
||||
int migration_log;
|
||||
@ -576,6 +577,14 @@ static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
@ -590,6 +599,11 @@ int kvm_cpu_exec(CPUState *env)
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
8
kvm.h
8
kvm.h
@ -128,16 +128,14 @@ int kvm_check_extension(KVMState *s, unsigned int extension);
|
||||
|
||||
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 */
|
||||
|
||||
static inline void cpu_synchronize_state(CPUState *env, int modified)
|
||||
static inline void cpu_synchronize_state(CPUState *env)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
if (modified)
|
||||
kvm_arch_put_registers(env);
|
||||
else
|
||||
kvm_arch_get_registers(env);
|
||||
kvm_cpu_synchronize_state(env);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ static CPUState *mon_get_cpu(void)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ static void do_info_cpus(Monitor *mon)
|
||||
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);
|
||||
|
@ -32,7 +32,7 @@ void cpu_save(QEMUFile *f, void *opaque)
|
||||
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]);
|
||||
@ -206,6 +206,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
|
||||
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++)
|
||||
@ -380,6 +381,5 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
|
||||
/* XXX: compute redundant hflags bits */
|
||||
env->hflags = hflags;
|
||||
tlb_flush(env, 1);
|
||||
cpu_synchronize_state(env, 1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ void cpu_save(QEMUFile *f, void *opaque)
|
||||
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]);
|
||||
@ -96,6 +96,8 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
|
||||
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)
|
||||
@ -177,7 +179,5 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
|
||||
qemu_get_sbe32s(f, &env->mmu_idx);
|
||||
qemu_get_sbe32s(f, &env->power_mode);
|
||||
|
||||
cpu_synchronize_state(env, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user