@@ -147,6 +147,7 @@ struct KVMCPUState {
int stop;
int stopped;
int created;
+ void *vcpu_ctx;
struct qemu_work_item *queued_work_first, *queued_work_last;
};
@@ -833,7 +833,7 @@ static void kvm_kernel_lapic_save_to_user(APICState *s)
struct kvm_lapic_state *kapic = &apic;
int i, v;
- kvm_get_lapic(kvm_context, s->cpu_env->cpu_index, kapic);
+ kvm_get_lapic(s->cpu_env->kvm_cpu_state.vcpu_ctx, kapic);
s->id = kapic_reg(kapic, 0x2) >> 24;
s->tpr = kapic_reg(kapic, 0x8);
@@ -886,7 +886,7 @@ static void kvm_kernel_lapic_load_from_user(APICState *s)
kapic_set_reg(klapic, 0x38, s->initial_count);
kapic_set_reg(klapic, 0x3e, s->divide_conf);
- kvm_set_lapic(kvm_context, s->cpu_env->cpu_index, klapic);
+ kvm_set_lapic(s->cpu_env->kvm_cpu_state.vcpu_ctx, klapic);
}
#endif
@@ -70,7 +70,7 @@ static uint8_t read_byte_virt(CPUState *env, target_ulong virt)
{
struct kvm_sregs sregs;
- kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
+ kvm_get_sregs(env->kvm_cpu_state.vcpu_ctx, &sregs);
return ldub_phys(map_addr(&sregs, virt, NULL));
}
@@ -78,7 +78,7 @@ static void write_byte_virt(CPUState *env, target_ulong virt, uint8_t b)
{
struct kvm_sregs sregs;
- kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
+ kvm_get_sregs(env->kvm_cpu_state.vcpu_ctx, &sregs);
stb_phys(map_addr(&sregs, virt, NULL), b);
}
@@ -86,7 +86,7 @@ static __u64 kvm_rsp_read(CPUState *env)
{
struct kvm_regs regs;
- kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ kvm_get_regs(env->kvm_cpu_state.vcpu_ctx, ®s);
return regs.rsp;
}
@@ -192,7 +192,7 @@ static int bios_is_mapped(CPUState *env, uint64_t rip)
if (bios_enabled)
return 1;
- kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
+ kvm_get_sregs(env->kvm_cpu_state.vcpu_ctx, &sregs);
probe = (rip & 0xf0000000) + 0xe0000;
phys = map_addr(&sregs, probe, &perms);
@@ -241,7 +241,7 @@ static int enable_vapic(CPUState *env)
if (pcr_cpu < 0)
return 0;
- kvm_enable_vapic(kvm_context, env->cpu_index, vapic_phys + (pcr_cpu << 7));
+ kvm_enable_vapic(env->kvm_cpu_state.vcpu_ctx, vapic_phys + (pcr_cpu << 7));
cpu_physical_memory_rw(vapic_phys + (pcr_cpu << 7) + 4, &one, 1, 1);
bios_enabled = 1;
@@ -314,7 +314,7 @@ void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write)
void kvm_tpr_vcpu_start(CPUState *env)
{
- kvm_enable_tpr_access_reporting(kvm_context, env->cpu_index);
+ kvm_enable_tpr_access_reporting(env->kvm_cpu_state.vcpu_ctx);
if (bios_enabled)
enable_vapic(env);
}
@@ -364,7 +364,7 @@ static void vtpr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
struct kvm_sregs sregs;
uint32_t rip;
- kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ kvm_get_regs(env->kvm_cpu_state.vcpu_ctx, ®s);
rip = regs.rip - 2;
write_byte_virt(env, rip, 0x66);
write_byte_virt(env, rip + 1, 0x90);
@@ -372,7 +372,7 @@ static void vtpr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
return;
if (!bios_is_mapped(env, rip))
printf("bios not mapped?\n");
- kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
+ kvm_get_sregs(env->kvm_cpu_state.vcpu_ctx, &sregs);
for (addr = 0xfffff000u; addr >= 0x80000000u; addr -= 4096)
if (map_addr(&sregs, addr, NULL) == 0xfee00000u) {
real_tpr = addr + 0x80;
@@ -356,10 +356,12 @@ kvm_context_t kvm_init(struct kvm_callbacks *callbacks,
void kvm_finalize(kvm_context_t kvm)
{
+ /* FIXME
if (kvm->vcpu_fd[0] != -1)
close(kvm->vcpu_fd[0]);
if (kvm->vm_fd != -1)
close(kvm->vm_fd);
+ */
close(kvm->fd);
free(kvm);
}
@@ -374,32 +376,43 @@ void kvm_disable_pit_creation(kvm_context_t kvm)
kvm->no_pit_creation = 1;
}
-int kvm_create_vcpu(kvm_context_t kvm, int slot)
+kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id)
{
long mmap_size;
int r;
+ kvm_vcpu_context_t vcpu_ctx = malloc(sizeof(struct kvm_vcpu_context));
- r = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, slot);
+ if (!vcpu_ctx) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ vcpu_ctx->kvm = kvm;
+ vcpu_ctx->id = id;
+
+ r = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, id);
if (r == -1) {
- r = -errno;
fprintf(stderr, "kvm_create_vcpu: %m\n");
- return r;
+ goto err;
}
- kvm->vcpu_fd[slot] = r;
+ vcpu_ctx->fd = r;
mmap_size = ioctl(kvm->fd, KVM_GET_VCPU_MMAP_SIZE, 0);
if (mmap_size == -1) {
- r = -errno;
fprintf(stderr, "get vcpu mmap size: %m\n");
- return r;
+ goto err_fd;
}
- kvm->run[slot] = mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED,
- kvm->vcpu_fd[slot], 0);
- if (kvm->run[slot] == MAP_FAILED) {
- r = -errno;
+ vcpu_ctx->run = mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ vcpu_ctx->fd, 0);
+ if (vcpu_ctx->run == MAP_FAILED) {
fprintf(stderr, "mmap vcpu area: %m\n");
- return r;
+ goto err_fd;
}
- return 0;
+ return vcpu_ctx;
+err_fd:
+ close(vcpu_ctx->fd);
+err:
+ free(vcpu_ctx);
+ return NULL;
}
int kvm_create_vm(kvm_context_t kvm)
@@ -414,8 +427,6 @@ int kvm_create_vm(kvm_context_t kvm)
kvm->nr_allocated_irq_routes = 0;
#endif
- kvm->vcpu_fd[0] = -1;
-
fd = ioctl(fd, KVM_CREATE_VM, 0);
if (fd == -1) {
fprintf(stderr, "kvm_create_vm: %m\n");
@@ -731,8 +742,10 @@ int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip)
#endif
-static int handle_io(kvm_context_t kvm, struct kvm_run *run, int vcpu)
+static int handle_io(kvm_vcpu_context_t vcpu)
{
+ struct kvm_run *run = vcpu->run;
+ kvm_context_t kvm = vcpu->kvm;
uint16_t addr = run->io.port;
int r;
int i;
@@ -786,10 +799,11 @@ static int handle_io(kvm_context_t kvm, struct kvm_run *run, int vcpu)
return 0;
}
-int handle_debug(kvm_context_t kvm, int vcpu, void *env)
+int handle_debug(kvm_vcpu_context_t vcpu, void *env)
{
#ifdef KVM_CAP_SET_GUEST_DEBUG
- struct kvm_run *run = kvm->run[vcpu];
+ struct kvm_run *run = vcpu->run;
+ kvm_context_t kvm = vcpu->kvm;
return kvm->callbacks->debug(kvm->opaque, env, &run->debug.arch);
#else
@@ -797,61 +811,63 @@ int handle_debug(kvm_context_t kvm, int vcpu, void *env)
#endif
}
-int kvm_get_regs(kvm_context_t kvm, int vcpu, struct kvm_regs *regs)
+int kvm_get_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_GET_REGS, regs);
+ return ioctl(vcpu->fd, KVM_GET_REGS, regs);
}
-int kvm_set_regs(kvm_context_t kvm, int vcpu, struct kvm_regs *regs)
+int kvm_set_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_REGS, regs);
+ return ioctl(vcpu->fd, KVM_SET_REGS, regs);
}
-int kvm_get_fpu(kvm_context_t kvm, int vcpu, struct kvm_fpu *fpu)
+int kvm_get_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_GET_FPU, fpu);
+ return ioctl(vcpu->fd, KVM_GET_FPU, fpu);
}
-int kvm_set_fpu(kvm_context_t kvm, int vcpu, struct kvm_fpu *fpu)
+int kvm_set_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_FPU, fpu);
+ return ioctl(vcpu->fd, KVM_SET_FPU, fpu);
}
-int kvm_get_sregs(kvm_context_t kvm, int vcpu, struct kvm_sregs *sregs)
+int kvm_get_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *sregs)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_GET_SREGS, sregs);
+ return ioctl(vcpu->fd, KVM_GET_SREGS, sregs);
}
-int kvm_set_sregs(kvm_context_t kvm, int vcpu, struct kvm_sregs *sregs)
+int kvm_set_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *sregs)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_SREGS, sregs);
+ return ioctl(vcpu->fd, KVM_SET_SREGS, sregs);
}
#ifdef KVM_CAP_MP_STATE
-int kvm_get_mpstate(kvm_context_t kvm, int vcpu, struct kvm_mp_state *mp_state)
+int kvm_get_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state)
{
int r;
- r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_MP_STATE);
+ r = ioctl(vcpu->kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_MP_STATE);
if (r > 0)
- return ioctl(kvm->vcpu_fd[vcpu], KVM_GET_MP_STATE, mp_state);
+ return ioctl(vcpu->fd, KVM_GET_MP_STATE, mp_state);
return -ENOSYS;
}
-int kvm_set_mpstate(kvm_context_t kvm, int vcpu, struct kvm_mp_state *mp_state)
+int kvm_set_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state)
{
int r;
- r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_MP_STATE);
+ r = ioctl(vcpu->kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_MP_STATE);
if (r > 0)
- return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_MP_STATE, mp_state);
+ return ioctl(vcpu->fd, KVM_SET_MP_STATE, mp_state);
return -ENOSYS;
}
#endif
-static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run)
+static int handle_mmio(kvm_vcpu_context_t vcpu)
{
- unsigned long addr = kvm_run->mmio.phys_addr;
+ unsigned long addr = vcpu->run->mmio.phys_addr;
+ kvm_context_t kvm = vcpu->kvm;
+ struct kvm_run *kvm_run = vcpu->run;
void *data = kvm_run->mmio.data;
/* hack: Red Hat 7.1 generates these weird accesses. */
@@ -871,9 +887,9 @@ int handle_io_window(kvm_context_t kvm)
return kvm->callbacks->io_window(kvm->opaque);
}
-int handle_halt(kvm_context_t kvm, int vcpu)
+int handle_halt(kvm_vcpu_context_t vcpu)
{
- return kvm->callbacks->halt(kvm->opaque, vcpu);
+ return vcpu->kvm->callbacks->halt(vcpu->kvm->opaque, vcpu);
}
int handle_shutdown(kvm_context_t kvm, void *env)
@@ -903,25 +919,22 @@ int pre_kvm_run(kvm_context_t kvm, void *env)
return kvm->callbacks->pre_kvm_run(kvm->opaque, env);
}
-int kvm_get_interrupt_flag(kvm_context_t kvm, int vcpu)
+int kvm_get_interrupt_flag(kvm_vcpu_context_t vcpu)
{
- struct kvm_run *run = kvm->run[vcpu];
-
- return run->if_flag;
+ return vcpu->run->if_flag;
}
-int kvm_is_ready_for_interrupt_injection(kvm_context_t kvm, int vcpu)
+int kvm_is_ready_for_interrupt_injection(kvm_vcpu_context_t vcpu)
{
- struct kvm_run *run = kvm->run[vcpu];
-
- return run->ready_for_interrupt_injection;
+ return vcpu->run->ready_for_interrupt_injection;
}
-int kvm_run(kvm_context_t kvm, int vcpu, void *env)
+int kvm_run(kvm_vcpu_context_t vcpu, void *env)
{
int r;
- int fd = kvm->vcpu_fd[vcpu];
- struct kvm_run *run = kvm->run[vcpu];
+ int fd = vcpu->fd;
+ struct kvm_run *run = vcpu->run;
+ kvm_context_t kvm = vcpu->kvm;
again:
push_nmi(kvm);
@@ -969,35 +982,35 @@ again:
switch (run->exit_reason) {
case KVM_EXIT_UNKNOWN:
fprintf(stderr, "unhandled vm exit: 0x%x vcpu_id %d\n",
- (unsigned)run->hw.hardware_exit_reason, vcpu);
- kvm_show_regs(kvm, vcpu);
+ (unsigned)run->hw.hardware_exit_reason,vcpu->id);
+ kvm_show_regs(vcpu);
abort();
break;
case KVM_EXIT_FAIL_ENTRY:
fprintf(stderr, "kvm_run: failed entry, reason %u\n",
(unsigned)run->fail_entry.hardware_entry_failure_reason & 0xffff);
- kvm_show_regs(kvm, vcpu);
+ kvm_show_regs(vcpu);
return -ENOEXEC;
break;
case KVM_EXIT_EXCEPTION:
fprintf(stderr, "exception %d (%x)\n",
run->ex.exception,
run->ex.error_code);
- kvm_show_regs(kvm, vcpu);
- kvm_show_code(kvm, vcpu);
+ kvm_show_regs(vcpu);
+ kvm_show_code(vcpu);
abort();
break;
case KVM_EXIT_IO:
- r = handle_io(kvm, run, vcpu);
+ r = handle_io(vcpu);
break;
case KVM_EXIT_DEBUG:
- r = handle_debug(kvm, vcpu, env);
+ r = handle_debug(vcpu, env);
break;
case KVM_EXIT_MMIO:
- r = handle_mmio(kvm, run);
+ r = handle_mmio(vcpu);
break;
case KVM_EXIT_HLT:
- r = handle_halt(kvm, vcpu);
+ r = handle_halt(vcpu);
break;
case KVM_EXIT_IRQ_WINDOW_OPEN:
break;
@@ -1014,10 +1027,10 @@ again:
break;
#endif
default:
- if (kvm_arch_run(run, kvm, vcpu)) {
+ if (kvm_arch_run(vcpu)) {
fprintf(stderr, "unhandled vm exit: 0x%x\n",
run->exit_reason);
- kvm_show_regs(kvm, vcpu);
+ kvm_show_regs(vcpu);
abort();
}
break;
@@ -1029,28 +1042,28 @@ more:
return r;
}
-int kvm_inject_irq(kvm_context_t kvm, int vcpu, unsigned irq)
+int kvm_inject_irq(kvm_vcpu_context_t vcpu, unsigned irq)
{
struct kvm_interrupt intr;
intr.irq = irq;
- return ioctl(kvm->vcpu_fd[vcpu], KVM_INTERRUPT, &intr);
+ return ioctl(vcpu->fd, KVM_INTERRUPT, &intr);
}
#ifdef KVM_CAP_SET_GUEST_DEBUG
-int kvm_set_guest_debug(kvm_context_t kvm, int vcpu, struct kvm_guest_debug *dbg)
+int kvm_set_guest_debug(kvm_vcpu_context_t vcpu, struct kvm_guest_debug *dbg)
{
- return ioctl(kvm->vcpu_fd[vcpu], KVM_SET_GUEST_DEBUG, dbg);
+ return ioctl(vcpu->fd, KVM_SET_GUEST_DEBUG, dbg);
}
#endif
-int kvm_set_signal_mask(kvm_context_t kvm, int vcpu, const sigset_t *sigset)
+int kvm_set_signal_mask(kvm_vcpu_context_t vcpu, const sigset_t *sigset)
{
struct kvm_signal_mask *sigmask;
int r;
if (!sigset) {
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_SIGNAL_MASK, NULL);
+ r = ioctl(vcpu->fd, KVM_SET_SIGNAL_MASK, NULL);
if (r == -1)
r = -errno;
return r;
@@ -1061,7 +1074,7 @@ int kvm_set_signal_mask(kvm_context_t kvm, int vcpu, const sigset_t *sigset)
sigmask->len = 8;
memcpy(sigmask->sigset, sigset, sizeof(*sigset));
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_SIGNAL_MASK, sigmask);
+ r = ioctl(vcpu->fd, KVM_SET_SIGNAL_MASK, sigmask);
if (r == -1)
r = -errno;
free(sigmask);
@@ -1087,10 +1100,10 @@ int kvm_has_sync_mmu(kvm_context_t kvm)
return r;
}
-int kvm_inject_nmi(kvm_context_t kvm, int vcpu)
+int kvm_inject_nmi(kvm_vcpu_context_t vcpu)
{
#ifdef KVM_CAP_USER_NMI
- return ioctl(kvm->vcpu_fd[vcpu], KVM_NMI);
+ return ioctl(vcpu->fd, KVM_NMI);
#else
return -ENOSYS;
#endif
@@ -20,13 +20,15 @@
#include <signal.h>
struct kvm_context;
+struct kvm_vcpu_context;
typedef struct kvm_context *kvm_context_t;
+typedef struct kvm_vcpu_context *kvm_vcpu_context_t;
#if defined(__x86_64__) || defined(__i386__)
struct kvm_msr_list *kvm_get_msr_list(kvm_context_t);
-int kvm_get_msrs(kvm_context_t, int vcpu, struct kvm_msr_entry *msrs, int n);
-int kvm_set_msrs(kvm_context_t, int vcpu, struct kvm_msr_entry *msrs, int n);
+int kvm_get_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
+int kvm_set_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
#endif
/*!
@@ -65,7 +67,7 @@ struct kvm_callbacks {
* Typically, you should yeild here to prevent 100% CPU utilization
* on the host CPU.
*/
- int (*halt)(void *opaque, int vcpu);
+ int (*halt)(void *opaque, kvm_vcpu_context_t vcpu);
int (*shutdown)(void *opaque, void *env);
int (*io_window)(void *opaque);
int (*try_push_interrupts)(void *opaque);
@@ -74,15 +76,15 @@ struct kvm_callbacks {
#endif
void (*post_kvm_run)(void *opaque, void *env);
int (*pre_kvm_run)(void *opaque, void *env);
- int (*tpr_access)(void *opaque, int vcpu, uint64_t rip, int is_write);
+ int (*tpr_access)(void *opaque, kvm_vcpu_context_t vcpu, uint64_t rip, int is_write);
#if defined(__powerpc__)
- int (*powerpc_dcr_read)(int vcpu, uint32_t dcrn, uint32_t *data);
- int (*powerpc_dcr_write)(int vcpu, uint32_t dcrn, uint32_t data);
+ int (*powerpc_dcr_read)(kvm_vcpu_context_t vcpu, uint32_t dcrn, uint32_t *data);
+ int (*powerpc_dcr_write)(kvm_vcpu_context_t vcpu, uint32_t dcrn, uint32_t data);
#endif
#if defined(__s390__)
- int (*s390_handle_intercept)(kvm_context_t context, int vcpu,
+ int (*s390_handle_intercept)(kvm_context_t context, kvm_vcpu_context_t vcpu,
struct kvm_run *run);
- int (*s390_handle_reset)(kvm_context_t context, int vcpu,
+ int (*s390_handle_reset)(kvm_context_t context, kvm_vcpu_context_t vcpu,
struct kvm_run *run);
#endif
};
@@ -163,7 +165,7 @@ void kvm_create_irqchip(kvm_context_t kvm);
* \param slot vcpu number (> 0)
* \return 0 on success, -errno on failure
*/
-int kvm_create_vcpu(kvm_context_t kvm, int slot);
+kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id);
/*!
* \brief Start the VCPU
@@ -186,7 +188,7 @@ int kvm_create_vcpu(kvm_context_t kvm, int slot);
* return except for when an error has occured, or when you have sent it
* an EINTR signal.
*/
-int kvm_run(kvm_context_t kvm, int vcpu, void *env);
+int kvm_run(kvm_vcpu_context_t vcpu, void *env);
/*!
* \brief Get interrupt flag from on last exit to userspace
@@ -197,7 +199,7 @@ int kvm_run(kvm_context_t kvm, int vcpu, void *env);
* \param vcpu Which virtual CPU should get dumped
* \return interrupt flag value (0 or 1)
*/
-int kvm_get_interrupt_flag(kvm_context_t kvm, int vcpu);
+int kvm_get_interrupt_flag(kvm_vcpu_context_t vcpu);
/*!
* \brief Get the value of the APIC_BASE msr as of last exit to userspace
@@ -208,7 +210,7 @@ int kvm_get_interrupt_flag(kvm_context_t kvm, int vcpu);
* \param vcpu Which virtual CPU should get dumped
* \return APIC_BASE msr contents
*/
-uint64_t kvm_get_apic_base(kvm_context_t kvm, int vcpu);
+uint64_t kvm_get_apic_base(kvm_vcpu_context_t vcpu);
/*!
* \brief Check if a vcpu is ready for interrupt injection
@@ -219,7 +221,7 @@ uint64_t kvm_get_apic_base(kvm_context_t kvm, int vcpu);
* \param vcpu Which virtual CPU should get dumped
* \return boolean indicating interrupt injection readiness
*/
-int kvm_is_ready_for_interrupt_injection(kvm_context_t kvm, int vcpu);
+int kvm_is_ready_for_interrupt_injection(kvm_vcpu_context_t vcpu);
/*!
* \brief Read VCPU registers
@@ -236,7 +238,7 @@ int kvm_is_ready_for_interrupt_injection(kvm_context_t kvm, int vcpu);
* registers values
* \return 0 on success
*/
-int kvm_get_regs(kvm_context_t kvm, int vcpu, struct kvm_regs *regs);
+int kvm_get_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs);
/*!
* \brief Write VCPU registers
@@ -251,7 +253,7 @@ int kvm_get_regs(kvm_context_t kvm, int vcpu, struct kvm_regs *regs);
* registers values
* \return 0 on success
*/
-int kvm_set_regs(kvm_context_t kvm, int vcpu, struct kvm_regs *regs);
+int kvm_set_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs);
/*!
* \brief Read VCPU fpu registers
*
@@ -267,7 +269,7 @@ int kvm_set_regs(kvm_context_t kvm, int vcpu, struct kvm_regs *regs);
* fpu registers values
* \return 0 on success
*/
-int kvm_get_fpu(kvm_context_t kvm, int vcpu, struct kvm_fpu *fpu);
+int kvm_get_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu);
/*!
* \brief Write VCPU fpu registers
@@ -281,7 +283,7 @@ int kvm_get_fpu(kvm_context_t kvm, int vcpu, struct kvm_fpu *fpu);
* \param fpu Pointer to a kvm_fpu which holds the new vcpu fpu state
* \return 0 on success
*/
-int kvm_set_fpu(kvm_context_t kvm, int vcpu, struct kvm_fpu *fpu);
+int kvm_set_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu);
/*!
* \brief Read VCPU system registers
@@ -299,7 +301,7 @@ int kvm_set_fpu(kvm_context_t kvm, int vcpu, struct kvm_fpu *fpu);
* registers values
* \return 0 on success
*/
-int kvm_get_sregs(kvm_context_t kvm, int vcpu, struct kvm_sregs *regs);
+int kvm_get_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *regs);
/*!
* \brief Write VCPU system registers
@@ -314,30 +316,28 @@ int kvm_get_sregs(kvm_context_t kvm, int vcpu, struct kvm_sregs *regs);
* registers values
* \return 0 on success
*/
-int kvm_set_sregs(kvm_context_t kvm, int vcpu, struct kvm_sregs *regs);
+int kvm_set_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *regs);
#ifdef KVM_CAP_MP_STATE
/*!
* * \brief Read VCPU MP state
*
*/
-int kvm_get_mpstate(kvm_context_t kvm, int vcpu,
- struct kvm_mp_state *mp_state);
+int kvm_get_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state);
/*!
* * \brief Write VCPU MP state
*
*/
-int kvm_set_mpstate(kvm_context_t kvm, int vcpu,
- struct kvm_mp_state *mp_state);
+int kvm_set_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state);
/*!
* * \brief Reset VCPU MP state
*
*/
-static inline int kvm_reset_mpstate(kvm_context_t kvm, int vcpu)
+static inline int kvm_reset_mpstate(kvm_vcpu_context_t vcpu)
{
struct kvm_mp_state mp_state = {.mp_state = KVM_MP_STATE_UNINITIALIZED};
- return kvm_set_mpstate(kvm, vcpu, &mp_state);
+ return kvm_set_mpstate(vcpu, &mp_state);
}
#endif
@@ -351,10 +351,10 @@ static inline int kvm_reset_mpstate(kvm_context_t kvm, int vcpu)
* \param irq Vector number
* \return 0 on success
*/
-int kvm_inject_irq(kvm_context_t kvm, int vcpu, unsigned irq);
+int kvm_inject_irq(kvm_vcpu_context_t vcpu, unsigned irq);
#ifdef KVM_CAP_SET_GUEST_DEBUG
-int kvm_set_guest_debug(kvm_context_t, int vcpu, struct kvm_guest_debug *dbg);
+int kvm_set_guest_debug(kvm_vcpu_context_t, struct kvm_guest_debug *dbg);
#endif
#if defined(__i386__) || defined(__x86_64__)
@@ -369,7 +369,7 @@ int kvm_set_guest_debug(kvm_context_t, int vcpu, struct kvm_guest_debug *dbg);
* \param entries cpuid function entries table
* \return 0 on success, or -errno on error
*/
-int kvm_setup_cpuid(kvm_context_t kvm, int vcpu, int nent,
+int kvm_setup_cpuid(kvm_vcpu_context_t vcpu, int nent,
struct kvm_cpuid_entry *entries);
/*!
@@ -385,7 +385,7 @@ int kvm_setup_cpuid(kvm_context_t kvm, int vcpu, int nent,
* \param entries cpuid function entries table
* \return 0 on success, or -errno on error
*/
-int kvm_setup_cpuid2(kvm_context_t kvm, int vcpu, int nent,
+int kvm_setup_cpuid2(kvm_vcpu_context_t vcpu, int nent,
struct kvm_cpuid_entry2 *entries);
/*!
@@ -414,7 +414,7 @@ int kvm_get_shadow_pages(kvm_context_t kvm , unsigned int *nrshadow_pages);
* \param vcpu Which virtual CPU should get dumped
* \param cr8 next cr8 value
*/
-void kvm_set_cr8(kvm_context_t kvm, int vcpu, uint64_t cr8);
+void kvm_set_cr8(kvm_vcpu_context_t vcpu, uint64_t cr8);
/*!
* \brief Get cr8 for sync tpr in qemu apic emulation
@@ -425,7 +425,7 @@ void kvm_set_cr8(kvm_context_t kvm, int vcpu, uint64_t cr8);
* \param kvm Pointer to the current kvm_context
* \param vcpu Which virtual CPU should get dumped
*/
-__u64 kvm_get_cr8(kvm_context_t kvm, int vcpu);
+__u64 kvm_get_cr8(kvm_vcpu_context_t vcpu);
#endif
/*!
@@ -441,23 +441,7 @@ __u64 kvm_get_cr8(kvm_context_t kvm, int vcpu);
* \param sigset signal mask for guest mode
* \return 0 on success, or -errno on error
*/
-int kvm_set_signal_mask(kvm_context_t kvm, int vcpu, const sigset_t *sigset);
-
-/*!
- * \brief Dump all VCPU information
- *
- * This dumps \b all the information that KVM has about a virtual CPU, namely:
- * - GP Registers
- * - System registers (selectors, descriptors, etc)
- * - VMCS Data
- * - MSRS
- * - Pending interrupts
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \return 0 on success
- */
-int kvm_dump_vcpu(kvm_context_t kvm, int vcpu);
+int kvm_set_signal_mask(kvm_vcpu_context_t vcpu, const sigset_t *sigset);
/*!
* \brief Dump VCPU registers
@@ -471,7 +455,7 @@ int kvm_dump_vcpu(kvm_context_t kvm, int vcpu);
* \param vcpu Which virtual CPU should get dumped
* \return 0 on success
*/
-void kvm_show_regs(kvm_context_t kvm, int vcpu);
+void kvm_show_regs(kvm_vcpu_context_t vcpu);
void *kvm_create_phys_mem(kvm_context_t, unsigned long phys_start,
@@ -593,7 +577,7 @@ int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
* \param vcpu Which virtual CPU should be accessed
* \param s Local apic state of the specific virtual CPU
*/
-int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s);
+int kvm_get_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s);
/*!
* \brief Set in kernel local APIC for vcpu
@@ -604,7 +588,7 @@ int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s);
* \param vcpu Which virtual CPU should be accessed
* \param s Local apic state of the specific virtual CPU
*/
-int kvm_set_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s);
+int kvm_set_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s);
#endif
@@ -617,7 +601,7 @@ int kvm_set_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s);
* \param vcpu Which virtual CPU should get dumped
* \return 0 on success
*/
-int kvm_inject_nmi(kvm_context_t kvm, int vcpu);
+int kvm_inject_nmi(kvm_vcpu_context_t vcpu);
#endif
@@ -677,7 +661,7 @@ int kvm_reinject_control(kvm_context_t kvm, int pit_reinject);
* \param kvm Pointer to the current kvm_context
* \param vcpu vcpu to enable tpr access reporting on
*/
-int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu);
+int kvm_enable_tpr_access_reporting(kvm_vcpu_context_t vcpu);
/*!
* \brief Disable kernel tpr access reporting
@@ -687,9 +671,9 @@ int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu);
* \param kvm Pointer to the current kvm_context
* \param vcpu vcpu to disable tpr access reporting on
*/
-int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu);
+int kvm_disable_tpr_access_reporting(kvm_vcpu_context_t vcpu);
-int kvm_enable_vapic(kvm_context_t kvm, int vcpu, uint64_t vapic);
+int kvm_enable_vapic(kvm_vcpu_context_t vcpu, uint64_t vapic);
#endif
@@ -44,8 +44,6 @@ struct kvm_context {
/// Filedescriptor to /dev/kvm
int fd;
int vm_fd;
- int vcpu_fd[MAX_VCPUS];
- struct kvm_run *run[MAX_VCPUS];
/// Callbacks that KVM uses to emulate various unvirtualizable functionality
struct kvm_callbacks *callbacks;
void *opaque;
@@ -71,6 +69,14 @@ struct kvm_context {
int max_gsi;
};
+struct kvm_vcpu_context
+{
+ int fd;
+ struct kvm_run *run;
+ struct kvm_context *kvm;
+ uint32_t id;
+};
+
int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
void **vm_mem);
int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory,
@@ -78,17 +84,17 @@ int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory,
int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
void **vm_mem);
-int kvm_arch_run(struct kvm_run *run, kvm_context_t kvm, int vcpu);
+int kvm_arch_run(kvm_vcpu_context_t vcpu);
-void kvm_show_code(kvm_context_t kvm, int vcpu);
+void kvm_show_code(kvm_vcpu_context_t vcpu);
-int handle_halt(kvm_context_t kvm, int vcpu);
+int handle_halt(kvm_vcpu_context_t vcpu);
int handle_shutdown(kvm_context_t kvm, void *env);
void post_kvm_run(kvm_context_t kvm, void *env);
int pre_kvm_run(kvm_context_t kvm, void *env);
int handle_io_window(kvm_context_t kvm);
-int handle_debug(kvm_context_t kvm, int vcpu, void *env);
+int handle_debug(kvm_vcpu_context_t vcpu, void *env);
int try_push_interrupts(kvm_context_t kvm);
#endif
@@ -31,7 +31,7 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
return 0;
}
-int kvm_arch_halt(void *opaque, int vcpu)
+int kvm_arch_halt(void *opaque, kvm_vcpu_context_t vcpu)
{
CPUState *env = cpu_single_env;
env->hflags |= HF_HALTED_MASK;
@@ -104,7 +104,7 @@ void kvm_save_mpstate(CPUState *env)
int r;
struct kvm_mp_state mp_state;
- r = kvm_get_mpstate(kvm_context, env->cpu_index, &mp_state);
+ r = kvm_get_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
if (r < 0)
env->mp_state = -1;
else
@@ -122,7 +122,7 @@ void kvm_load_mpstate(CPUState *env)
* so don't touch it.
*/
if (env->mp_state != -1)
- kvm_set_mpstate(kvm_context, env->cpu_index, &mp_state);
+ kvm_set_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
#endif
}
@@ -130,7 +130,7 @@ void kvm_arch_cpu_reset(CPUState *env)
{
if (kvm_irqchip_in_kernel(kvm_context)) {
#ifdef KVM_CAP_MP_STATE
- kvm_reset_mpstate(kvm_context, env->cpu_index);
+ kvm_reset_mpstate(env->kvm_cpu_state.vcpu_ctx);
#endif
} else {
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
@@ -195,7 +195,7 @@ void kvm_arch_load_regs(CPUState *env)
regs.rflags = env->eflags;
regs.rip = env->eip;
- kvm_set_regs(kvm_context, env->cpu_index, ®s);
+ kvm_set_regs(env->kvm_cpu_state.vcpu_ctx, ®s);
memset(&fpu, 0, sizeof fpu);
fpu.fsw = env->fpus & ~(7 << 11);
@@ -206,7 +206,7 @@ void kvm_arch_load_regs(CPUState *env)
memcpy(fpu.fpr, env->fpregs, sizeof env->fpregs);
memcpy(fpu.xmm, env->xmm_regs, sizeof env->xmm_regs);
fpu.mxcsr = env->mxcsr;
- kvm_set_fpu(kvm_context, env->cpu_index, &fpu);
+ kvm_set_fpu(env->kvm_cpu_state.vcpu_ctx, &fpu);
memcpy(sregs.interrupt_bitmap, env->interrupt_bitmap, sizeof(sregs.interrupt_bitmap));
@@ -251,7 +251,7 @@ void kvm_arch_load_regs(CPUState *env)
sregs.efer = env->efer;
- kvm_set_sregs(kvm_context, env->cpu_index, &sregs);
+ kvm_set_sregs(env->kvm_cpu_state.vcpu_ctx, &sregs);
/* msrs */
n = 0;
@@ -270,7 +270,7 @@ void kvm_arch_load_regs(CPUState *env)
}
#endif
- rc = kvm_set_msrs(kvm_context, env->cpu_index, msrs, n);
+ rc = kvm_set_msrs(env->kvm_cpu_state.vcpu_ctx, msrs, n);
if (rc == -1)
perror("kvm_set_msrs FAILED");
}
@@ -282,7 +282,7 @@ void kvm_load_tsc(CPUState *env)
set_msr_entry(&msr, MSR_IA32_TSC, env->tsc);
- rc = kvm_set_msrs(kvm_context, env->cpu_index, &msr, 1);
+ rc = kvm_set_msrs(env->kvm_cpu_state.vcpu_ctx, &msr, 1);
if (rc == -1)
perror("kvm_set_tsc FAILED.\n");
}
@@ -293,7 +293,7 @@ void kvm_save_mpstate(CPUState *env)
int r;
struct kvm_mp_state mp_state;
- r = kvm_get_mpstate(kvm_context, env->cpu_index, &mp_state);
+ r = kvm_get_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
if (r < 0)
env->mp_state = -1;
else
@@ -311,7 +311,7 @@ void kvm_load_mpstate(CPUState *env)
* so don't touch it.
*/
if (env->mp_state != -1)
- kvm_set_mpstate(kvm_context, env->cpu_index, &mp_state);
+ kvm_set_mpstate(env->kvm_cpu_state.vcpu_ctx, &mp_state);
#endif
}
@@ -324,7 +324,7 @@ void kvm_arch_save_regs(CPUState *env)
uint32_t hflags;
uint32_t i, n, rc;
- kvm_get_regs(kvm_context, env->cpu_index, ®s);
+ kvm_get_regs(env->kvm_cpu_state.vcpu_ctx, ®s);
env->regs[R_EAX] = regs.rax;
env->regs[R_EBX] = regs.rbx;
@@ -348,7 +348,7 @@ void kvm_arch_save_regs(CPUState *env)
env->eflags = regs.rflags;
env->eip = regs.rip;
- kvm_get_fpu(kvm_context, env->cpu_index, &fpu);
+ kvm_get_fpu(env->kvm_cpu_state.vcpu_ctx, &fpu);
env->fpstt = (fpu.fsw >> 11) & 7;
env->fpus = fpu.fsw;
env->fpuc = fpu.fcw;
@@ -358,7 +358,7 @@ void kvm_arch_save_regs(CPUState *env)
memcpy(env->xmm_regs, fpu.xmm, sizeof env->xmm_regs);
env->mxcsr = fpu.mxcsr;
- kvm_get_sregs(kvm_context, env->cpu_index, &sregs);
+ kvm_get_sregs(env->kvm_cpu_state.vcpu_ctx, &sregs);
memcpy(env->interrupt_bitmap, sregs.interrupt_bitmap, sizeof(env->interrupt_bitmap));
@@ -444,7 +444,7 @@ void kvm_arch_save_regs(CPUState *env)
msrs[n++].index = MSR_LSTAR;
}
#endif
- rc = kvm_get_msrs(kvm_context, env->cpu_index, msrs, n);
+ rc = kvm_get_msrs(env->kvm_cpu_state.vcpu_ctx, msrs, n);
if (rc == -1) {
perror("kvm_get_msrs FAILED");
}
@@ -580,7 +580,7 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
for (i = 0x80000000; i <= limit; ++i)
do_cpuid_ent(&cpuid_ent[cpuid_nent++], i, 0, ©);
- kvm_setup_cpuid2(kvm_context, cenv->cpu_index, cpuid_nent, cpuid_ent);
+ kvm_setup_cpuid2(cenv->kvm_cpu_state.vcpu_ctx, cpuid_nent, cpuid_ent);
kvm_trim_features(&cenv->cpuid_features,
kvm_arch_get_supported_cpuid(cenv, 1, R_EDX));
@@ -594,7 +594,7 @@ int kvm_arch_qemu_init_env(CPUState *cenv)
return 0;
}
-int kvm_arch_halt(void *opaque, int vcpu)
+int kvm_arch_halt(void *opaque, kvm_vcpu_context_t vcpu)
{
CPUState *env = cpu_single_env;
@@ -610,20 +610,18 @@ int kvm_arch_halt(void *opaque, int vcpu)
void kvm_arch_pre_kvm_run(void *opaque, CPUState *env)
{
if (!kvm_irqchip_in_kernel(kvm_context))
- kvm_set_cr8(kvm_context, env->cpu_index, cpu_get_apic_tpr(env));
+ kvm_set_cr8(env->kvm_cpu_state.vcpu_ctx, cpu_get_apic_tpr(env));
}
void kvm_arch_post_kvm_run(void *opaque, CPUState *env)
{
- int vcpu = env->cpu_index;
-
cpu_single_env = env;
- env->eflags = kvm_get_interrupt_flag(kvm_context, vcpu)
+ env->eflags = kvm_get_interrupt_flag(env->kvm_cpu_state.vcpu_ctx)
? env->eflags | IF_MASK : env->eflags & ~IF_MASK;
- cpu_set_apic_tpr(env, kvm_get_cr8(kvm_context, vcpu));
- cpu_set_apic_base(env, kvm_get_apic_base(kvm_context, vcpu));
+ cpu_set_apic_tpr(env, kvm_get_cr8(env->kvm_cpu_state.vcpu_ctx));
+ cpu_set_apic_base(env, kvm_get_apic_base(env->kvm_cpu_state.vcpu_ctx));
}
int kvm_arch_has_work(CPUState *env)
@@ -641,13 +639,13 @@ int kvm_arch_try_push_interrupts(void *opaque)
CPUState *env = cpu_single_env;
int r, irq;
- if (kvm_is_ready_for_interrupt_injection(kvm_context, env->cpu_index) &&
+ if (kvm_is_ready_for_interrupt_injection(env->kvm_cpu_state.vcpu_ctx) &&
(env->interrupt_request & CPU_INTERRUPT_HARD) &&
(env->eflags & IF_MASK)) {
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
irq = cpu_get_pic_interrupt(env);
if (irq >= 0) {
- r = kvm_inject_irq(kvm_context, env->cpu_index, irq);
+ r = kvm_inject_irq(env->kvm_cpu_state.vcpu_ctx, irq);
if (r < 0)
printf("cpu %d fail inject %x\n", env->cpu_index, irq);
}
@@ -666,7 +664,7 @@ void kvm_arch_push_nmi(void *opaque)
return;
env->interrupt_request &= ~CPU_INTERRUPT_NMI;
- r = kvm_inject_nmi(kvm_context, env->cpu_index);
+ r = kvm_inject_nmi(env->kvm_cpu_state.vcpu_ctx);
if (r < 0)
printf("cpu %d fail inject NMI\n", env->cpu_index);
}
@@ -682,7 +680,7 @@ void kvm_arch_update_regs_for_sipi(CPUState *env)
kvm_arch_load_regs(env);
}
-int handle_tpr_access(void *opaque, int vcpu,
+int handle_tpr_access(void *opaque, kvm_vcpu_context_t vcpu,
uint64_t rip, int is_write)
{
kvm_tpr_access_report(cpu_single_env, rip, is_write);
@@ -695,7 +693,7 @@ void kvm_arch_cpu_reset(CPUState *env)
if (env->cpu_index != 0) {
if (kvm_irqchip_in_kernel(kvm_context)) {
#ifdef KVM_CAP_MP_STATE
- kvm_reset_mpstate(kvm_context, env->cpu_index);
+ kvm_reset_mpstate(env->kvm_cpu_state.vcpu_ctx);
#endif
} else {
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
@@ -204,7 +204,7 @@ int kvm_cpu_exec(CPUState *env)
{
int r;
- r = kvm_run(kvm_context, env->cpu_index, env);
+ r = kvm_run(env->kvm_cpu_state.vcpu_ctx, env);
if (r < 0) {
printf("kvm_run returned %d\n", r);
exit(1);
@@ -366,7 +366,7 @@ static void setup_kernel_sigmask(CPUState *env)
sigprocmask(SIG_BLOCK, NULL, &set);
sigdelset(&set, SIG_IPI);
- kvm_set_signal_mask(kvm_context, env->cpu_index, &set);
+ kvm_set_signal_mask(env->kvm_cpu_state.vcpu_ctx, &set);
}
static void qemu_kvm_system_reset(void)
@@ -432,7 +432,7 @@ static void *ap_main_loop(void *_env)
env->thread_id = kvm_get_thread_id();
sigfillset(&signals);
sigprocmask(SIG_BLOCK, &signals, NULL);
- kvm_create_vcpu(kvm_context, env->cpu_index);
+ env->kvm_cpu_state.vcpu_ctx = kvm_create_vcpu(kvm_context, env->cpu_index);
#ifdef USE_KVM_DEVICE_ASSIGNMENT
/* do ioperm for io ports of assigned devices */
@@ -723,7 +723,7 @@ static int kvm_io_window(void *opaque)
}
-static int kvm_halt(void *opaque, int vcpu)
+static int kvm_halt(void *opaque, kvm_vcpu_context_t vcpu)
{
return kvm_arch_halt(opaque, vcpu);
}
@@ -1027,8 +1027,8 @@ static void kvm_invoke_set_guest_debug(void *data)
{
struct kvm_set_guest_debug_data *dbg_data = data;
- dbg_data->err = kvm_set_guest_debug(kvm_context, cpu_single_env->cpu_index,
- &dbg_data->dbg);
+ dbg_data->err = kvm_set_guest_debug(cpu_single_env->kvm_cpu_state.vcpu_ctx,
+ &dbg_data->dbg);
}
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
@@ -70,7 +70,6 @@ int kvm_arch_qemu_create_context(void);
void kvm_arch_save_regs(CPUState *env);
void kvm_arch_load_regs(CPUState *env);
int kvm_arch_qemu_init_env(CPUState *cenv);
-int kvm_arch_halt(void *opaque, int vcpu);
void kvm_arch_pre_kvm_run(void *opaque, CPUState *env);
void kvm_arch_post_kvm_run(void *opaque, CPUState *env);
int kvm_arch_has_work(CPUState *env);
@@ -113,8 +112,6 @@ void qemu_kvm_notify_work(void);
void kvm_tpr_opt_setup(void);
void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write);
-int handle_tpr_access(void *opaque, int vcpu,
- uint64_t rip, int is_write);
void kvm_tpr_vcpu_start(CPUState *env);
int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf);
@@ -138,8 +135,8 @@ void kvm_arch_do_ioperm(void *_data);
#endif
#ifdef TARGET_PPC
-int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data);
-int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data);
+int handle_powerpc_dcr_read(kvm_vcpu_context_t vcpu, uint32_t dcrn, uint32_t *data);
+int handle_powerpc_dcr_write(kvm_vcpu_context_t vcpu,uint32_t dcrn, uint32_t data);
#endif
#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))
@@ -165,6 +162,9 @@ struct ioperm_data {
int qemu_kvm_has_sync_mmu(void);
void qemu_kvm_cpu_stop(CPUState *env);
+int kvm_arch_halt(void *opaque, kvm_vcpu_context_t vcpu);
+int handle_tpr_access(void *opaque, kvm_vcpu_context_t vcpu,
+ uint64_t rip, int is_write);
#define kvm_enabled() (kvm_allowed)
#define qemu_kvm_irqchip_in_kernel() kvm_irqchip_in_kernel(kvm_context)
@@ -96,22 +96,23 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
#ifdef KVM_EXIT_TPR_ACCESS
-static int handle_tpr_access(kvm_context_t kvm, struct kvm_run *run, int vcpu)
+static int handle_tpr_access(kvm_vcpu_context_t vcpu)
{
- return kvm->callbacks->tpr_access(kvm->opaque, vcpu,
+ struct kvm_run *run = vcpu->run;
+ return vcpu->kvm->callbacks->tpr_access(vcpu->kvm->opaque, vcpu,
run->tpr_access.rip,
run->tpr_access.is_write);
}
-int kvm_enable_vapic(kvm_context_t kvm, int vcpu, uint64_t vapic)
+int kvm_enable_vapic(kvm_vcpu_context_t vcpu, uint64_t vapic)
{
int r;
struct kvm_vapic_addr va = {
.vapic_addr = vapic,
};
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_VAPIC_ADDR, &va);
+ r = ioctl(vcpu->fd, KVM_SET_VAPIC_ADDR, &va);
if (r == -1) {
r = -errno;
perror("kvm_enable_vapic");
@@ -122,9 +123,11 @@ int kvm_enable_vapic(kvm_context_t kvm, int vcpu, uint64_t vapic)
#endif
-int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu)
+int kvm_arch_run(kvm_vcpu_context_t vcpu)
{
int r = 0;
+ struct kvm_run *run = vcpu->run;
+
switch (run->exit_reason) {
#ifdef KVM_EXIT_SET_TPR
@@ -133,7 +136,7 @@ int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu)
#endif
#ifdef KVM_EXIT_TPR_ACCESS
case KVM_EXIT_TPR_ACCESS:
- r = handle_tpr_access(kvm, run, vcpu);
+ r = handle_tpr_access(vcpu);
break;
#endif
default:
@@ -212,12 +215,12 @@ int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_start)
#ifdef KVM_CAP_IRQCHIP
-int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
+int kvm_get_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s)
{
int r;
- if (!kvm->irqchip_in_kernel)
+ if (!kvm_irqchip_in_kernel(vcpu->kvm))
return 0;
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_LAPIC, s);
+ r = ioctl(vcpu->fd, KVM_GET_LAPIC, s);
if (r == -1) {
r = -errno;
perror("kvm_get_lapic");
@@ -225,12 +228,12 @@ int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
return r;
}
-int kvm_set_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
+int kvm_set_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s)
{
int r;
- if (!kvm->irqchip_in_kernel)
+ if (!kvm_irqchip_in_kernel(vcpu->kvm))
return 0;
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_LAPIC, s);
+ r = ioctl(vcpu->fd, KVM_SET_LAPIC, s);
if (r == -1) {
r = -errno;
perror("kvm_set_lapic");
@@ -270,10 +273,10 @@ int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s)
#endif
-void kvm_show_code(kvm_context_t kvm, int vcpu)
+void kvm_show_code(kvm_vcpu_context_t vcpu)
{
#define SHOW_CODE_LEN 50
- int fd = kvm->vcpu_fd[vcpu];
+ int fd = vcpu->fd;
struct kvm_regs regs;
struct kvm_sregs sregs;
int r, n;
@@ -281,6 +284,7 @@ void kvm_show_code(kvm_context_t kvm, int vcpu)
unsigned char code;
char code_str[SHOW_CODE_LEN * 3 + 1];
unsigned long rip;
+ kvm_context_t kvm = vcpu->kvm;
r = ioctl(fd, KVM_GET_SREGS, &sregs);
if (r == -1) {
@@ -339,8 +343,7 @@ struct kvm_msr_list *kvm_get_msr_list(kvm_context_t kvm)
return msrs;
}
-int kvm_get_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
- int n)
+int kvm_get_msrs(kvm_vcpu_context_t vcpu, struct kvm_msr_entry *msrs, int n)
{
struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
int r, e;
@@ -351,7 +354,7 @@ int kvm_get_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
}
kmsrs->nmsrs = n;
memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_MSRS, kmsrs);
+ r = ioctl(vcpu->fd, KVM_GET_MSRS, kmsrs);
e = errno;
memcpy(msrs, kmsrs->entries, n * sizeof *msrs);
free(kmsrs);
@@ -359,8 +362,7 @@ int kvm_get_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
return r;
}
-int kvm_set_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
- int n)
+int kvm_set_msrs(kvm_vcpu_context_t vcpu, struct kvm_msr_entry *msrs, int n)
{
struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
int r, e;
@@ -371,7 +373,7 @@ int kvm_set_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
}
kmsrs->nmsrs = n;
memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_MSRS, kmsrs);
+ r = ioctl(vcpu->fd, KVM_SET_MSRS, kmsrs);
e = errno;
free(kmsrs);
errno = e;
@@ -393,9 +395,9 @@ static void print_dt(FILE *file, const char *name, struct kvm_dtable *dt)
fprintf(stderr, "%s %llx/%x\n", name, dt->base, dt->limit);
}
-void kvm_show_regs(kvm_context_t kvm, int vcpu)
+void kvm_show_regs(kvm_vcpu_context_t vcpu)
{
- int fd = kvm->vcpu_fd[vcpu];
+ int fd = vcpu->fd;
struct kvm_regs regs;
struct kvm_sregs sregs;
int r;
@@ -437,26 +439,22 @@ void kvm_show_regs(kvm_context_t kvm, int vcpu)
sregs.efer);
}
-uint64_t kvm_get_apic_base(kvm_context_t kvm, int vcpu)
+uint64_t kvm_get_apic_base(kvm_vcpu_context_t vcpu)
{
- struct kvm_run *run = kvm->run[vcpu];
-
- return run->apic_base;
+ return vcpu->run->apic_base;
}
-void kvm_set_cr8(kvm_context_t kvm, int vcpu, uint64_t cr8)
+void kvm_set_cr8(kvm_vcpu_context_t vcpu, uint64_t cr8)
{
- struct kvm_run *run = kvm->run[vcpu];
-
- run->cr8 = cr8;
+ vcpu->run->cr8 = cr8;
}
-__u64 kvm_get_cr8(kvm_context_t kvm, int vcpu)
+__u64 kvm_get_cr8(kvm_vcpu_context_t vcpu)
{
- return kvm->run[vcpu]->cr8;
+ return vcpu->run->cr8;
}
-int kvm_setup_cpuid(kvm_context_t kvm, int vcpu, int nent,
+int kvm_setup_cpuid(kvm_vcpu_context_t vcpu, int nent,
struct kvm_cpuid_entry *entries)
{
struct kvm_cpuid *cpuid;
@@ -468,13 +466,13 @@ int kvm_setup_cpuid(kvm_context_t kvm, int vcpu, int nent,
cpuid->nent = nent;
memcpy(cpuid->entries, entries, nent * sizeof(*entries));
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_CPUID, cpuid);
+ r = ioctl(vcpu->fd, KVM_SET_CPUID, cpuid);
free(cpuid);
return r;
}
-int kvm_setup_cpuid2(kvm_context_t kvm, int vcpu, int nent,
+int kvm_setup_cpuid2(kvm_vcpu_context_t vcpu, int nent,
struct kvm_cpuid_entry2 *entries)
{
struct kvm_cpuid2 *cpuid;
@@ -486,7 +484,7 @@ int kvm_setup_cpuid2(kvm_context_t kvm, int vcpu, int nent,
cpuid->nent = nent;
memcpy(cpuid->entries, entries, nent * sizeof(*entries));
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_CPUID2, cpuid);
+ r = ioctl(vcpu->fd, KVM_SET_CPUID2, cpuid);
if (r == -1) {
fprintf(stderr, "kvm_setup_cpuid2: %m\n");
return -errno;
@@ -531,17 +529,17 @@ int kvm_get_shadow_pages(kvm_context_t kvm, unsigned int *nrshadow_pages)
#ifdef KVM_CAP_VAPIC
-static int tpr_access_reporting(kvm_context_t kvm, int vcpu, int enabled)
+static int tpr_access_reporting(kvm_vcpu_context_t vcpu, int enabled)
{
int r;
struct kvm_tpr_access_ctl tac = {
.enabled = enabled,
};
- r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
+ r = ioctl(vcpu->kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
if (r == -1 || r == 0)
return -ENOSYS;
- r = ioctl(kvm->vcpu_fd[vcpu], KVM_TPR_ACCESS_REPORTING, &tac);
+ r = ioctl(vcpu->fd, KVM_TPR_ACCESS_REPORTING, &tac);
if (r == -1) {
r = -errno;
perror("KVM_TPR_ACCESS_REPORTING");
@@ -550,14 +548,14 @@ static int tpr_access_reporting(kvm_context_t kvm, int vcpu, int enabled)
return 0;
}
-int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu)
+int kvm_enable_tpr_access_reporting(kvm_vcpu_context_t vcpu)
{
- return tpr_access_reporting(kvm, vcpu, 1);
+ return tpr_access_reporting(vcpu, 1);
}
-int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu)
+int kvm_disable_tpr_access_reporting(kvm_vcpu_context_t vcpu)
{
- return tpr_access_reporting(kvm, vcpu, 0);
+ return tpr_access_reporting(vcpu, 0);
}
#endif
@@ -45,11 +45,11 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
return 0;
}
-int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu)
+int kvm_arch_run(kvm_vcpu_context_t vcpu)
{
int r = 0;
- switch (run->exit_reason) {
+ switch (vcp->run->exit_reason) {
default:
r = 1;
break;
@@ -58,12 +58,12 @@ int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu)
return r;
}
-void kvm_show_code(kvm_context_t kvm, int vcpu)
+void kvm_show_code(kvm_vcpu_context_t vcpu)
{
fprintf(stderr, "kvm_show_code not supported yet!\n");
}
-void kvm_show_regs(kvm_context_t kvm, int vcpu)
+void kvm_show_regs(kvm_vcpu_context_t vcpu)
{
fprintf(stderr,"kvm_show_regs not supportted today!\n");
}
@@ -23,9 +23,11 @@
#include <stdio.h>
#include <inttypes.h>
-int handle_dcr(struct kvm_run *run, kvm_context_t kvm, int vcpu)
+int handle_dcr(kvm_vcpu_context_t vcpu)
{
int ret = 0;
+ struct kvm_run *run = vcpu->run;
+ kvm_context_t kvm = vcpu->kvm;
if (run->dcr.is_write)
ret = kvm->callbacks->powerpc_dcr_write(vcpu,
@@ -39,17 +41,17 @@ int handle_dcr(struct kvm_run *run, kvm_context_t kvm, int vcpu)
return ret;
}
-void kvm_show_code(kvm_context_t kvm, int vcpu)
+void kvm_show_code(kvm_vcpu_context_t vcpu)
{
fprintf(stderr, "%s: Operation not supported\n", __FUNCTION__);
}
-void kvm_show_regs(kvm_context_t kvm, int vcpu)
+void kvm_show_regs(kvm_vcpu_context_t vcpu)
{
struct kvm_regs regs;
int i;
- if (kvm_get_regs(kvm, vcpu, ®s))
+ if (kvm_get_regs(vcpu, ®s))
return;
fprintf(stderr,"guest vcpu #%d\n", vcpu);
@@ -84,13 +86,13 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
return 0;
}
-int kvm_arch_run(struct kvm_run *run, kvm_context_t kvm, int vcpu)
+int kvm_arch_run(kvm_vcpu_context_t vcpu)
{
int ret = 0;
- switch (run->exit_reason){
+ switch (vcpu->run->exit_reason){
case KVM_EXIT_DCR:
- ret = handle_dcr(run, kvm, vcpu);
+ ret = handle_dcr(vcpu);
break;
default:
ret = 1;
On vcpu creation cookie is returned which is used in future communication. Signed-off-by: Gleb Natapov <gleb@redhat.com> -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html