Merge remote branch 'qemu-kvm/uq/master' into staging-tmp

This commit is contained in:
Anthony Liguori 2010-02-08 10:06:54 -06:00
commit 8217d94586
8 changed files with 49 additions and 17 deletions

View File

@ -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_flush_coalesced_mmio_buffer(void);
/*******************************************/
/* host CPU ticks (if available) */

View File

@ -197,6 +197,7 @@ typedef struct CPUWatchpoint {
const char *cpu_model_str; \
struct KVMState *kvm_state; \
struct kvm_run *kvm_run; \
int kvm_fd;
int kvm_fd; \
int kvm_vcpu_dirty;
#endif

6
exec.c
View File

@ -2415,6 +2415,12 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t 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)
{
RAMBlock *new_block;

View File

@ -25,6 +25,7 @@
#include "isa.h"
#include "pc.h"
#include "sysemu.h"
#include "kvm.h"
//#define VMPORT_DEBUG
@ -58,6 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
unsigned char command;
uint32_t eax;
cpu_synchronize_state(env);
eax = env->regs[R_EAX];
if (eax != VMPORT_MAGIC)
return eax;

View File

@ -57,8 +57,10 @@ struct KVMState
KVMSlot slots[32];
int fd;
int vmfd;
int regs_modified;
int coalesced_mmio;
#ifdef KVM_CAP_COALESCED_MMIO
struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
#endif
int broken_set_mem_region;
int migration_log;
int vcpu_events;
@ -200,6 +202,12 @@ int kvm_init_vcpu(CPUState *env)
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);
if (ret == 0) {
qemu_register_reset(kvm_reset_vcpu, env);
@ -466,10 +474,10 @@ int kvm_init(int smp_cpus)
goto err;
}
s->coalesced_mmio = 0;
#ifdef KVM_CAP_COALESCED_MMIO
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
#else
s->coalesced_mmio = 0;
s->coalesced_mmio_ring = NULL;
#endif
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;
}
static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
void kvm_flush_coalesced_mmio_buffer(void)
{
#ifdef KVM_CAP_COALESCED_MMIO
KVMState *s = kvm_state;
if (s->coalesced_mmio) {
struct kvm_coalesced_mmio_ring *ring;
ring = (void *)run + (s->coalesced_mmio * TARGET_PAGE_SIZE);
if (s->coalesced_mmio_ring) {
struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;
while (ring->first != ring->last) {
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)
{
if (!env->kvm_state->regs_modified) {
if (!env->kvm_vcpu_dirty) {
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;
}
if (env->kvm_state->regs_modified) {
if (env->kvm_vcpu_dirty) {
kvm_arch_put_registers(env);
env->kvm_state->regs_modified = 0;
env->kvm_vcpu_dirty = 0;
}
kvm_arch_pre_run(env, run);
@ -609,7 +615,7 @@ int kvm_cpu_exec(CPUState *env)
abort();
}
kvm_run_coalesced_mmio(env, run);
kvm_flush_coalesced_mmio_buffer();
ret = 0; /* exit loop */
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;
CPUState *env = dbg_data->env;
if (env->kvm_state->regs_modified) {
if (env->kvm_vcpu_dirty) {
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);
}

1
kvm.h
View File

@ -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_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,
target_ulong len, int type);

View File

@ -99,12 +99,18 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
break;
case R_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,
* so add missing bits according to the AMD spec:
*/
cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX);
ret |= cpuid_1_edx & 0xdfeff7ff;
break;
}
break;
}
@ -794,6 +800,9 @@ static int kvm_put_vcpu_events(CPUState *env)
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);
#else
return 0;

4
vl.c
View File

@ -2996,6 +2996,7 @@ static void gui_update(void *opaque)
DisplayState *ds = opaque;
DisplayChangeListener *dcl = ds->listeners;
qemu_flush_coalesced_mmio_buffer();
dpy_refresh(ds);
while (dcl != NULL) {
@ -3011,6 +3012,7 @@ static void nographic_update(void *opaque)
{
uint64_t interval = GUI_REFRESH_INTERVAL;
qemu_flush_coalesced_mmio_buffer();
qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
}
@ -3280,6 +3282,8 @@ static int cpu_can_run(CPUState *env)
return 0;
if (env->stopped)
return 0;
if (!vm_running)
return 0;
return 1;
}