[PATCH 12 of 19] Move abi 10 functions to libkvm-x86.c

Jerone Young
2007-11-02T18:25:01Z

# Date 1194027873 18000
# Node ID 0ade452df6c708a2b44696a23e733d59c8906aea
# Parent 01b86b564fb9e751295ff8eddf5f38cfb24e1e34
Move abi 10 functions to libkvm-x86.c

Move handle_io_abi_10 to libkvm-x86.c

Move handle_mmio_abi10 to libkvm-x86.c

Move kvm_run_abi10 to libkvm-x86.c

Move kvm_show_code to libkvm-x86.c

Signed-off-by: Jerone Young <jyoung5-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

diff --git a/libkvm/kvm-x86.h b/libkvm/kvm-x86.h
--- a/libkvm/kvm-x86.h
+++ b/libkvm/kvm-x86.h
@@ -38,4 +38,8 @@ void *kvm_create_kernel_phys_mem(kvm_con
void *kvm_create_kernel_phys_mem(kvm_context_t kvm, unsigned long phys_start,
unsigned long len, int log, int writable);

+int kvm_run_abi10(kvm_context_t kvm, int vcpu);
+
+void kvm_show_code(kvm_context_t kvm, int vcpu);
+
#endif
diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
--- a/libkvm/libkvm-x86.c
+++ b/libkvm/libkvm-x86.c
@@ -1,5 +1,6 @@
#include "libkvm.h"
#include "kvm-x86.h"
+#include "kvm-abi-10.h"
#include <errno.h>
#include <sys/ioctl.h>
#include <string.h>
@@ -11,6 +12,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <stdlib.h>

int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
void **vm_mem)
@@ -407,4 +409,224 @@ int kvm_set_lapic(kvm_context_t kvm, int

#endif

-
+static int handle_io_abi10(kvm_context_t kvm, struct kvm_run_abi10 *run,
+ int vcpu)
+{
+ uint16_t addr = run->io.port;
+ int r;
+ int i;
+ void *p = (void *)run + run->io.data_offset;
+
+ for (i = 0; i < run->io.count; ++i) {
+ switch (run->io.direction) {
+ case KVM_EXIT_IO_IN:
+ switch (run->io.size) {
+ case 1:
+ r = kvm->callbacks->inb(kvm->opaque, addr, p);
+ break;
+ case 2:
+ r = kvm->callbacks->inw(kvm->opaque, addr, p);
+ break;
+ case 4:
+ r = kvm->callbacks->inl(kvm->opaque, addr, p);
+ break;
+ default:
+ fprintf(stderr, "bad I/O size %d\n", run->io.size);
+ return -EMSGSIZE;
+ }
+ break;
+ case KVM_EXIT_IO_OUT:
+ switch (run->io.size) {
+ case 1:
+ r = kvm->callbacks->outb(kvm->opaque, addr,
+ *(uint8_t *)p);
+ break;
+ case 2:
+ r = kvm->callbacks->outw(kvm->opaque, addr,
+ *(uint16_t *)p);
+ break;
+ case 4:
+ r = kvm->callbacks->outl(kvm->opaque, addr,
+ *(uint32_t *)p);
+ break;
+ default:
+ fprintf(stderr, "bad I/O size %d\n", run->io.size);
+ return -EMSGSIZE;
+ }
+ break;
+ default:
+ fprintf(stderr, "bad I/O direction %d\n", run->io.direction);
+ return -EPROTO;
+ }
+
+ p += run->io.size;
+ }
+ run->io_completed = 1;
+
+ return 0;
+}
+
+static int handle_mmio_abi10(kvm_context_t kvm, struct kvm_run_abi10 *kvm_run)
+{
+ unsigned long addr = kvm_run->mmio.phys_addr;
+ void *data = kvm_run->mmio.data;
+ int r = -1;
+
+ if (kvm_run->mmio.is_write) {
+ switch (kvm_run->mmio.len) {
+ case 1:
+ r = kvm->callbacks->writeb(kvm->opaque, addr,
+ *(uint8_t *)data);
+ break;
+ case 2:
+ r = kvm->callbacks->writew(kvm->opaque, addr,
+ *(uint16_t *)data);
+ break;
+ case 4:
+ r = kvm->callbacks->writel(kvm->opaque, addr,
+ *(uint32_t *)data);
+ break;
+ case 8:
+ r = kvm->callbacks->writeq(kvm->opaque, addr,
+ *(uint64_t *)data);
+ break;
+ }
+ } else {
+ switch (kvm_run->mmio.len) {
+ case 1:
+ r = kvm->callbacks->readb(kvm->opaque, addr,
+ (uint8_t *)data);
+ break;
+ case 2:
+ r = kvm->callbacks->readw(kvm->opaque, addr,
+ (uint16_t *)data);
+ break;
+ case 4:
+ r = kvm->callbacks->readl(kvm->opaque, addr,
+ (uint32_t *)data);
+ break;
+ case 8:
+ r = kvm->callbacks->readq(kvm->opaque, addr,
+ (uint64_t *)data);
+ break;
+ }
+ kvm_run->io_completed = 1;
+ }
+ return r;
+}
+
+int kvm_run_abi10(kvm_context_t kvm, int vcpu)
+{
+ int r;
+ int fd = kvm->vcpu_fd[vcpu];
+ struct kvm_run_abi10 *run = (struct kvm_run_abi10 *)kvm->run[vcpu];
+
+again:
+ run->request_interrupt_window = try_push_interrupts(kvm);
+ r = pre_kvm_run(kvm, vcpu);
+ if (r)
+ return r;
+ r = ioctl(fd, KVM_RUN, 0);
+ post_kvm_run(kvm, vcpu);
+
+ run->io_completed = 0;
+ if (r == -1 && errno != EINTR) {
+ r = -errno;
+ printf("kvm_run: %m\n");
+ return r;
+ }
+ if (r == -1) {
+ r = handle_io_window(kvm);
+ goto more;
+ }
+ if (1) {
+ 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);
+ 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);
+ 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);
+ abort();
+ break;
+ case KVM_EXIT_IO:
+ r = handle_io_abi10(kvm, run, vcpu);
+ break;
+ case KVM_EXIT_DEBUG:
+ r = handle_debug(kvm, vcpu);
+ break;
+ case KVM_EXIT_MMIO:
+ r = handle_mmio_abi10(kvm, run);
+ break;
+ case KVM_EXIT_HLT:
+ r = handle_halt(kvm, vcpu);
+ break;
+ case KVM_EXIT_IRQ_WINDOW_OPEN:
+ break;
+ case KVM_EXIT_SHUTDOWN:
+ r = handle_shutdown(kvm, vcpu);
+ break;
+ default:
+ fprintf(stderr, "unhandled vm exit: 0x%x\n", run->exit_reason);
+ kvm_show_regs(kvm, vcpu);
+ abort();
+ break;
+ }
+ }
+more:
+ if (!r)
+ goto again;
+ return r;
+}
+
+
+void kvm_show_code(kvm_context_t kvm, int vcpu)
+{
+#define CR0_PE_MASK (1ULL<<0)
+ int fd = kvm->vcpu_fd[vcpu];
+ struct kvm_regs regs;
+ struct kvm_sregs sregs;
+ int r;
+ unsigned char code[50];
+ int back_offset;
+ char code_str[sizeof(code) * 3 + 1];
+ unsigned long rip;
+
+ r = ioctl(fd, KVM_GET_SREGS, &sregs);
+ if (r == -1) {
+ perror("KVM_GET_SREGS");
+ return;
+ }
+ if (sregs.cr0 & CR0_PE_MASK)
+ return;
+
+ r = ioctl(fd, KVM_GET_REGS, &regs);
+ if (r == -1) {
+ perror("KVM_GET_REGS");
+ return;
+ }
+ rip = sregs.cs.base + regs.rip;
+ back_offset = regs.rip;
+ if (back_offset > 20)
+ back_offset = 20;
+ memcpy(code, kvm->physical_memory + rip - back_offset, sizeof code);
+ *code_str = 0;
+ for (r = 0; r < sizeof code; ++r) {
+ if (r == back_offset)
+ strcat(code_str, " -->");
+ sprintf(code_str + strlen(code_str), " %02x", code[r]);
+ }
+ fprintf(stderr, "code:%s\n", code_str);
+}
+
diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -545,8 +545,7 @@ int kvm_set_irqchip(kvm_context_t kvm, s

#endif

-static int handle_io_abi10(kvm_context_t kvm, struct kvm_run_abi10 *run,
- int vcpu)
+static int handle_io(kvm_context_t kvm, struct kvm_run *run, int vcpu)
{
uint16_t addr = run->io.port;
int r;
@@ -597,62 +596,6 @@ static int handle_io_abi10(kvm_context_t

p += run->io.size;
}
- run->io_completed = 1;
-
- return 0;
-}
-
-static int handle_io(kvm_context_t kvm, struct kvm_run *run, int vcpu)
-{
- uint16_t addr = run->io.port;
- int r;
- int i;
- void *p = (void *)run + run->io.data_offset;
-
- for (i = 0; i < run->io.count; ++i) {
- switch (run->io.direction) {
- case KVM_EXIT_IO_IN:
- switch (run->io.size) {
- case 1:
- r = kvm->callbacks->inb(kvm->opaque, addr, p);
- break;
- case 2:
- r = kvm->callbacks->inw(kvm->opaque, addr, p);
- break;
- case 4:
- r = kvm->callbacks->inl(kvm->opaque, addr, p);
- break;
- default:
- fprintf(stderr, "bad I/O size %d\n", run->io.size);
- return -EMSGSIZE;
- }
- break;
- case KVM_EXIT_IO_OUT:
- switch (run->io.size) {
- case 1:
- r = kvm->callbacks->outb(kvm->opaque, addr,
- *(uint8_t *)p);
- break;
- case 2:
- r = kvm->callbacks->outw(kvm->opaque, addr,
- *(uint16_t *)p);
- break;
- case 4:
- r = kvm->callbacks->outl(kvm->opaque, addr,
- *(uint32_t *)p);
- break;
- default:
- fprintf(stderr, "bad I/O size %d\n", run->io.size);
- return -EMSGSIZE;
- }
- break;
- default:
- fprintf(stderr, "bad I/O direction %d\n", run->io.direction);
- return -EPROTO;
- }
-
- p += run->io.size;
- }

return 0;
}
@@ -818,50 +761,15 @@ void kvm_show_regs(kvm_context_t kvm, in
sregs.efer);
}

-static void kvm_show_code(kvm_context_t kvm, int vcpu)
-{
-#define CR0_PE_MASK (1ULL<<0)
- int fd = kvm->vcpu_fd[vcpu];
- struct kvm_regs regs;
- struct kvm_sregs sregs;
- int r;
- unsigned char code[50];
- int back_offset;
- char code_str[sizeof(code) * 3 + 1];
- unsigned long rip;
-
- r = ioctl(fd, KVM_GET_SREGS, &sregs);
- if (r == -1) {
- perror("KVM_GET_SREGS");
- return;
- }
- if (sregs.cr0 & CR0_PE_MASK)
- return;
-
- r = ioctl(fd, KVM_GET_REGS, &regs);
- if (r == -1) {
- perror("KVM_GET_REGS");
- return;
- }
- rip = sregs.cs.base + regs.rip;
- back_offset = regs.rip;
- if (back_offset > 20)
- back_offset = 20;
- memcpy(code, kvm->physical_memory + rip - back_offset, sizeof code);
- *code_str = 0;
- for (r = 0; r < sizeof code; ++r) {
- if (r == back_offset)
- strcat(code_str, " -->");
- sprintf(code_str + strlen(code_str), " %02x", code[r]);
- }
- fprintf(stderr, "code:%s\n", code_str);
-}
-
-static int handle_mmio_abi10(kvm_context_t kvm, struct kvm_run_abi10 *kvm_run)
+static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run)
{
unsigned long addr = kvm_run->mmio.phys_addr;
void *data = kvm_run->mmio.data;
int r = -1;
+
+ /* hack: Red Hat 7.1 generates these wierd accesses. */
+ if (addr == 0xa0000 && kvm_run->mmio.len == 3)
+ return 0;

if (kvm_run->mmio.is_write) {
switch (kvm_run->mmio.len) {
@@ -893,51 +801,6 @@ static int handle_mmio_abi10(kvm_context
r = kvm->callbacks->readq(kvm->opaque, addr, (uint64_t *)data);
break;
}
- kvm_run->io_completed = 1;
- }
- return r;
-}
-
-static int handle_mmio(kvm_context_t kvm, struct kvm_run *kvm_run)
-{
- unsigned long addr = kvm_run->mmio.phys_addr;
- void *data = kvm_run->mmio.data;
- int r = -1;
-
- /* hack: Red Hat 7.1 generates these wierd accesses. */
- if (addr == 0xa0000 && kvm_run->mmio.len == 3)
- return 0;
-
- if (kvm_run->mmio.is_write) {
- switch (kvm_run->mmio.len) {
- case 1:
- r = kvm->callbacks->writeb(kvm->opaque, addr, *(uint8_t *)data);
- break;
- case 2:
- r = kvm->callbacks->writew(kvm->opaque, addr, *(uint16_t *)data);
- break;
- case 4:
- r = kvm->callbacks->writel(kvm->opaque, addr, *(uint32_t *)data);
- break;
- case 8:
- r = kvm->callbacks->writeq(kvm->opaque, addr, *(uint64_t *)data);
- break;
- }
- } else {
- switch (kvm_run->mmio.len) {
- case 1:
- r = kvm->callbacks->readb(kvm->opaque, addr, (uint8_t *)data);
- break;
- case 2:
- r = kvm->callbacks->readw(kvm->opaque, addr, (uint16_t *)data);
- break;
- case 4:
- r = kvm->callbacks->readl(kvm->opaque, addr, (uint32_t *)data);
- break;
- case 8:
- r = kvm->callbacks->readq(kvm->opaque, addr, (uint64_t *)data);
- break;
- }
}
return r;
}
@@ -1013,81 +876,6 @@ __u64 kvm_get_cr8(kvm_context_t kvm, int
__u64 kvm_get_cr8(kvm_context_t kvm, int vcpu)
{
return kvm->run[vcpu]->cr8;
-}
-
-static int kvm_run_abi10(kvm_context_t kvm, int vcpu)
-{
- int r;
- int fd = kvm->vcpu_fd[vcpu];
- struct kvm_run_abi10 *run = (struct kvm_run_abi10 *)kvm->run[vcpu];
-
-again:
- run->request_interrupt_window = try_push_interrupts(kvm);
- r = pre_kvm_run(kvm, vcpu);
- if (r)
- return r;
- r = ioctl(fd, KVM_RUN, 0);
- post_kvm_run(kvm, vcpu);
-
- run->io_completed = 0;
- if (r == -1 && errno != EINTR) {
- r = -errno;
- printf("kvm_run: %m\n");
- return r;
- }
- if (r == -1) {
- r = handle_io_window(kvm);
- goto more;
- }
- if (1) {
- 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);
- 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);
- 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);
- abort();
- break;
- case KVM_EXIT_IO:
- r = handle_io_abi10(kvm, run, vcpu);
- break;
- case KVM_EXIT_DEBUG:
- r = handle_debug(kvm, vcpu);
- break;
- case KVM_EXIT_MMIO:
- r = handle_mmio_abi10(kvm, run);
- break;
- case KVM_EXIT_HLT:
- r = handle_halt(kvm, vcpu);
- break;
- case KVM_EXIT_IRQ_WINDOW_OPEN:
- break;
- case KVM_EXIT_SHUTDOWN:
- r = handle_shutdown(kvm, vcpu);
- break;
- default:
- fprintf(stderr, "unhandled vm exit: 0x%x\n", run->exit_reason);
- kvm_show_regs(kvm, vcpu);
- abort();
- break;
- }
- }
-more:
- if (!r)
- goto again;
- return r;
}

int kvm_run(kvm_context_t kvm, int vcpu)