Merge remote branch 'qemu-kvm/uq/master' into staging-tmp
This commit is contained in:
commit
8217d94586
|
@ -915,6 +915,8 @@ void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
|
||||||
|
|
||||||
void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
|
void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
|
||||||
|
|
||||||
|
void qemu_flush_coalesced_mmio_buffer(void);
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
/* host CPU ticks (if available) */
|
/* host CPU ticks (if available) */
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,7 @@ typedef struct CPUWatchpoint {
|
||||||
const char *cpu_model_str; \
|
const char *cpu_model_str; \
|
||||||
struct KVMState *kvm_state; \
|
struct KVMState *kvm_state; \
|
||||||
struct kvm_run *kvm_run; \
|
struct kvm_run *kvm_run; \
|
||||||
int kvm_fd;
|
int kvm_fd; \
|
||||||
|
int kvm_vcpu_dirty;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
6
exec.c
6
exec.c
|
@ -2415,6 +2415,12 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
|
||||||
kvm_uncoalesce_mmio_region(addr, size);
|
kvm_uncoalesce_mmio_region(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qemu_flush_coalesced_mmio_buffer(void)
|
||||||
|
{
|
||||||
|
if (kvm_enabled())
|
||||||
|
kvm_flush_coalesced_mmio_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
ram_addr_t qemu_ram_alloc(ram_addr_t size)
|
ram_addr_t qemu_ram_alloc(ram_addr_t size)
|
||||||
{
|
{
|
||||||
RAMBlock *new_block;
|
RAMBlock *new_block;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "isa.h"
|
#include "isa.h"
|
||||||
#include "pc.h"
|
#include "pc.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
#include "kvm.h"
|
||||||
|
|
||||||
//#define VMPORT_DEBUG
|
//#define VMPORT_DEBUG
|
||||||
|
|
||||||
|
@ -58,6 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
|
||||||
unsigned char command;
|
unsigned char command;
|
||||||
uint32_t eax;
|
uint32_t eax;
|
||||||
|
|
||||||
|
cpu_synchronize_state(env);
|
||||||
|
|
||||||
eax = env->regs[R_EAX];
|
eax = env->regs[R_EAX];
|
||||||
if (eax != VMPORT_MAGIC)
|
if (eax != VMPORT_MAGIC)
|
||||||
return eax;
|
return eax;
|
||||||
|
|
36
kvm-all.c
36
kvm-all.c
|
@ -57,8 +57,10 @@ struct KVMState
|
||||||
KVMSlot slots[32];
|
KVMSlot slots[32];
|
||||||
int fd;
|
int fd;
|
||||||
int vmfd;
|
int vmfd;
|
||||||
int regs_modified;
|
|
||||||
int coalesced_mmio;
|
int coalesced_mmio;
|
||||||
|
#ifdef KVM_CAP_COALESCED_MMIO
|
||||||
|
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
|
||||||
|
#endif
|
||||||
int broken_set_mem_region;
|
int broken_set_mem_region;
|
||||||
int migration_log;
|
int migration_log;
|
||||||
int vcpu_events;
|
int vcpu_events;
|
||||||
|
@ -200,6 +202,12 @@ int kvm_init_vcpu(CPUState *env)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KVM_CAP_COALESCED_MMIO
|
||||||
|
if (s->coalesced_mmio && !s->coalesced_mmio_ring)
|
||||||
|
s->coalesced_mmio_ring = (void *) env->kvm_run +
|
||||||
|
s->coalesced_mmio * PAGE_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = kvm_arch_init_vcpu(env);
|
ret = kvm_arch_init_vcpu(env);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
qemu_register_reset(kvm_reset_vcpu, env);
|
qemu_register_reset(kvm_reset_vcpu, env);
|
||||||
|
@ -466,10 +474,10 @@ int kvm_init(int smp_cpus)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->coalesced_mmio = 0;
|
||||||
#ifdef KVM_CAP_COALESCED_MMIO
|
#ifdef KVM_CAP_COALESCED_MMIO
|
||||||
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
|
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
|
||||||
#else
|
s->coalesced_mmio_ring = NULL;
|
||||||
s->coalesced_mmio = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->broken_set_mem_region = 1;
|
s->broken_set_mem_region = 1;
|
||||||
|
@ -544,14 +552,12 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
|
void kvm_flush_coalesced_mmio_buffer(void)
|
||||||
{
|
{
|
||||||
#ifdef KVM_CAP_COALESCED_MMIO
|
#ifdef KVM_CAP_COALESCED_MMIO
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
if (s->coalesced_mmio) {
|
if (s->coalesced_mmio_ring) {
|
||||||
struct kvm_coalesced_mmio_ring *ring;
|
struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;
|
||||||
|
|
||||||
ring = (void *)run + (s->coalesced_mmio * TARGET_PAGE_SIZE);
|
|
||||||
while (ring->first != ring->last) {
|
while (ring->first != ring->last) {
|
||||||
struct kvm_coalesced_mmio *ent;
|
struct kvm_coalesced_mmio *ent;
|
||||||
|
|
||||||
|
@ -567,9 +573,9 @@ static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
|
||||||
|
|
||||||
void kvm_cpu_synchronize_state(CPUState *env)
|
void kvm_cpu_synchronize_state(CPUState *env)
|
||||||
{
|
{
|
||||||
if (!env->kvm_state->regs_modified) {
|
if (!env->kvm_vcpu_dirty) {
|
||||||
kvm_arch_get_registers(env);
|
kvm_arch_get_registers(env);
|
||||||
env->kvm_state->regs_modified = 1;
|
env->kvm_vcpu_dirty = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,9 +593,9 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env->kvm_state->regs_modified) {
|
if (env->kvm_vcpu_dirty) {
|
||||||
kvm_arch_put_registers(env);
|
kvm_arch_put_registers(env);
|
||||||
env->kvm_state->regs_modified = 0;
|
env->kvm_vcpu_dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
kvm_arch_pre_run(env, run);
|
kvm_arch_pre_run(env, run);
|
||||||
|
@ -609,7 +615,7 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
kvm_run_coalesced_mmio(env, run);
|
kvm_flush_coalesced_mmio_buffer();
|
||||||
|
|
||||||
ret = 0; /* exit loop */
|
ret = 0; /* exit loop */
|
||||||
switch (run->exit_reason) {
|
switch (run->exit_reason) {
|
||||||
|
@ -939,9 +945,9 @@ static void kvm_invoke_set_guest_debug(void *data)
|
||||||
struct kvm_set_guest_debug_data *dbg_data = data;
|
struct kvm_set_guest_debug_data *dbg_data = data;
|
||||||
CPUState *env = dbg_data->env;
|
CPUState *env = dbg_data->env;
|
||||||
|
|
||||||
if (env->kvm_state->regs_modified) {
|
if (env->kvm_vcpu_dirty) {
|
||||||
kvm_arch_put_registers(env);
|
kvm_arch_put_registers(env);
|
||||||
env->kvm_state->regs_modified = 0;
|
env->kvm_vcpu_dirty = 0;
|
||||||
}
|
}
|
||||||
dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
|
dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
|
||||||
}
|
}
|
||||||
|
|
1
kvm.h
1
kvm.h
|
@ -53,6 +53,7 @@ void kvm_setup_guest_memory(void *start, size_t size);
|
||||||
|
|
||||||
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
||||||
int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
|
||||||
|
void kvm_flush_coalesced_mmio_buffer(void);
|
||||||
|
|
||||||
int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
|
int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
|
||||||
target_ulong len, int type);
|
target_ulong len, int type);
|
||||||
|
|
|
@ -99,12 +99,18 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
|
||||||
break;
|
break;
|
||||||
case R_EDX:
|
case R_EDX:
|
||||||
ret = cpuid->entries[i].edx;
|
ret = cpuid->entries[i].edx;
|
||||||
if (function == 0x80000001) {
|
switch (function) {
|
||||||
|
case 1:
|
||||||
|
/* KVM before 2.6.30 misreports the following features */
|
||||||
|
ret |= CPUID_MTRR | CPUID_PAT | CPUID_MCE | CPUID_MCA;
|
||||||
|
break;
|
||||||
|
case 0x80000001:
|
||||||
/* On Intel, kvm returns cpuid according to the Intel spec,
|
/* On Intel, kvm returns cpuid according to the Intel spec,
|
||||||
* so add missing bits according to the AMD spec:
|
* so add missing bits according to the AMD spec:
|
||||||
*/
|
*/
|
||||||
cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX);
|
cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX);
|
||||||
ret |= cpuid_1_edx & 0xdfeff7ff;
|
ret |= cpuid_1_edx & 0xdfeff7ff;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -794,6 +800,9 @@ static int kvm_put_vcpu_events(CPUState *env)
|
||||||
|
|
||||||
events.sipi_vector = env->sipi_vector;
|
events.sipi_vector = env->sipi_vector;
|
||||||
|
|
||||||
|
events.flags =
|
||||||
|
KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR;
|
||||||
|
|
||||||
return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events);
|
return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
4
vl.c
4
vl.c
|
@ -2996,6 +2996,7 @@ static void gui_update(void *opaque)
|
||||||
DisplayState *ds = opaque;
|
DisplayState *ds = opaque;
|
||||||
DisplayChangeListener *dcl = ds->listeners;
|
DisplayChangeListener *dcl = ds->listeners;
|
||||||
|
|
||||||
|
qemu_flush_coalesced_mmio_buffer();
|
||||||
dpy_refresh(ds);
|
dpy_refresh(ds);
|
||||||
|
|
||||||
while (dcl != NULL) {
|
while (dcl != NULL) {
|
||||||
|
@ -3011,6 +3012,7 @@ static void nographic_update(void *opaque)
|
||||||
{
|
{
|
||||||
uint64_t interval = GUI_REFRESH_INTERVAL;
|
uint64_t interval = GUI_REFRESH_INTERVAL;
|
||||||
|
|
||||||
|
qemu_flush_coalesced_mmio_buffer();
|
||||||
qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
|
qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3280,6 +3282,8 @@ static int cpu_can_run(CPUState *env)
|
||||||
return 0;
|
return 0;
|
||||||
if (env->stopped)
|
if (env->stopped)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (!vm_running)
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue