public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 2] Fix kvm-userspace/user/ for PowerPC
@ 2008-01-09  0:04 Hollis Blanchard
  2008-01-09  0:04 ` [PATCH 1 of 2] Add OBJCOPY to kvm-userspace/user/configure output Hollis Blanchard
  2008-01-09  0:04 ` [PATCH 2 of 2] Add PowerPC kvmctl harness and fix building the testcases Hollis Blanchard
  0 siblings, 2 replies; 4+ messages in thread
From: Hollis Blanchard @ 2008-01-09  0:04 UTC (permalink / raw)
  To: Avi Kivity
  Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

When applied after Jerone's kvm_create_kernel_phys_mem() libkvm patch, these
patches get the kvm-userspace/user/ test harness building and somewhat working
for PowerPC. For the moment it's just a simply binary loader (hence the need
for objcopy), but in the future it should be easy to add an ELF or even uImage
loader.

3 files changed, 449 insertions(+), 9 deletions(-)
user/config-powerpc.mak |   30 ++-
user/configure          |    2 
user/main-ppc.c         |  426 +++++++++++++++++++++++++++++++++++++++++++++++

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1 of 2] Add OBJCOPY to kvm-userspace/user/configure output
  2008-01-09  0:04 [PATCH 0 of 2] Fix kvm-userspace/user/ for PowerPC Hollis Blanchard
@ 2008-01-09  0:04 ` Hollis Blanchard
  2008-01-09  0:04 ` [PATCH 2 of 2] Add PowerPC kvmctl harness and fix building the testcases Hollis Blanchard
  1 sibling, 0 replies; 4+ messages in thread
From: Hollis Blanchard @ 2008-01-09  0:04 UTC (permalink / raw)
  To: Avi Kivity
  Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

# HG changeset patch
# User Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
# Date 1199836243 21600
# Node ID 2b1946f501613724c363f98cbdfd95248b947657
# Parent  332daa1196f0a74d2ad3c34ed2ca41d5d859b0de

Signed-off-by: Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

---
1 file changed, 2 insertions(+)
user/configure |    2 ++


diff --git a/user/configure b/user/configure
--- a/user/configure
+++ b/user/configure
@@ -4,6 +4,7 @@ kerneldir=/lib/modules/$(uname -r)/build
 kerneldir=/lib/modules/$(uname -r)/build
 cc=gcc
 ld=ld
+objcopy=objcopy
 arch=`uname -m | sed -e s/i.86/i386/`
 cross_prefix=
 
@@ -63,4 +64,5 @@ ARCH=$arch
 ARCH=$arch
 CC=$cross_prefix$cc
 LD=$cross_prefix$ld
+OBJCOPY=$cross_prefix$objcopy
 EOF

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2 of 2] Add PowerPC kvmctl harness and fix building the testcases
  2008-01-09  0:04 [PATCH 0 of 2] Fix kvm-userspace/user/ for PowerPC Hollis Blanchard
  2008-01-09  0:04 ` [PATCH 1 of 2] Add OBJCOPY to kvm-userspace/user/configure output Hollis Blanchard
@ 2008-01-09  0:04 ` Hollis Blanchard
  2008-01-09  8:50   ` Avi Kivity
  1 sibling, 1 reply; 4+ messages in thread
From: Hollis Blanchard @ 2008-01-09  0:04 UTC (permalink / raw)
  To: Avi Kivity
  Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

# HG changeset patch
# User Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
# Date 1199836753 21600
# Node ID dd6de019e916f0cc2b4f75afb95a9d28323cb174
# Parent  2b1946f501613724c363f98cbdfd95248b947657

Signed-off-by: Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

---
2 files changed, 447 insertions(+), 9 deletions(-)
user/config-powerpc.mak |   30 ++-
user/main-ppc.c         |  426 +++++++++++++++++++++++++++++++++++++++++++++++


diff --git a/user/config-powerpc.mak b/user/config-powerpc.mak
--- a/user/config-powerpc.mak
+++ b/user/config-powerpc.mak
@@ -1,14 +1,26 @@ TEST_DIR=test/powerpc
-TEST_DIR=test/powerpc
 CFLAGS += -m32
 CFLAGS += -D__powerpc__
 CFLAGS += -I $(KERNELDIR)/include
+# for some reaons binutils hates tlbsx unless we say we're 405 :(
+CFLAGS += -Wa,-mregnames,-m405
 
-tests= $(TEST_DIR)/io.S \
-	$(TEST_DIR)/spin.S \
-	$(TEST_DIR)/sprg.S \
-	$(TEST_DIR)/44x/tlbsx.S \
-	$(TEST_DIR)/44x/tlbwe_16KB.S \
-	$(TEST_DIR)/44x/tlbwe_hole.S \
-	$(TEST_DIR)/44x/tlbwe.S
+%.bin: %.o
+	$(OBJCOPY) -O binary $^ $@
 
-kvmctl_objs = main.o ../libkvm/libkvm.a
+testobjs := \
+	io.bin \
+	spin.bin \
+	sprg.bin \
+	44x/tlbsx.bin \
+	44x/tlbwe_16KB.bin \
+	44x/tlbwe_hole.bin \
+	44x/tlbwe.bin
+
+tests := $(addprefix test/powerpc/, $(testobjs))
+
+all: kvmctl $(tests)
+
+kvmctl_objs = main-ppc.o ../libkvm/libkvm.a
+
+arch_clean:
+	rm -f $(tests)
diff --git a/user/main-ppc.c b/user/main-ppc.c
new file mode 100644
--- /dev/null
+++ b/user/main-ppc.c
@@ -0,0 +1,426 @@
+/*
+ * Kernel-based Virtual Machine test driver
+ *
+ * This test driver provides a simple way of testing kvm, without a full
+ * device model.
+ *
+ * Copyright (C) 2006 Qumranet
+ * Copyright IBM Corp. 2008
+ *
+ * Authors:
+ *
+ *  Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
+ *  Yaniv Kamay <yaniv-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
+ *  Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
+ *
+ * This work is licensed under the GNU LGPL license, version 2.
+ */
+
+#define _GNU_SOURCE
+
+#include <libkvm.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <semaphore.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/syscall.h>
+#include <linux/unistd.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+static int gettid(void)
+{
+	return syscall(__NR_gettid);
+}
+
+kvm_context_t kvm;
+
+#define MAX_VCPUS 4
+
+#define IPI_SIGNAL (SIGRTMIN + 4)
+
+#define MAX_IO_TABLE	50
+
+typedef int (io_table_handler_t)(void *, int, int, uint64_t, uint64_t *);
+
+struct io_table_entry
+{
+	uint64_t start;
+	uint64_t end;
+	io_table_handler_t *handler;
+	void *opaque;
+};
+
+struct io_table
+{
+	int nr_entries;
+	struct io_table_entry entries[MAX_IO_TABLE];
+};
+
+static int ncpus = 1;
+static sem_t init_sem;
+static __thread int vcpu;
+static sigset_t kernel_sigmask;
+static sigset_t ipi_sigmask;
+static uint64_t memory_size = 128 * 1024 * 1024;
+
+static struct io_table pio_table;
+
+struct vcpu_info {
+	pid_t tid;
+};
+
+struct vcpu_info *vcpus;
+
+struct io_table_entry *io_table_lookup(struct io_table *io_table, uint64_t addr)
+{
+	int i;
+
+	for (i = 0; i < io_table->nr_entries; i++) {
+		if (io_table->entries[i].start <= addr &&
+		    addr < io_table->entries[i].end)
+			return &io_table->entries[i];
+	}
+
+	return NULL;
+}
+
+int io_table_register(struct io_table *io_table, uint64_t start, uint64_t size,
+		      io_table_handler_t *handler, void *opaque)
+{
+	struct io_table_entry *entry;
+
+	if (io_table->nr_entries == MAX_IO_TABLE)
+		return -ENOSPC;
+
+	entry = &io_table->entries[io_table->nr_entries];
+	io_table->nr_entries++;
+
+	entry->start = start;
+	entry->end = start + size;
+	entry->handler = handler;
+	entry->opaque = opaque;
+
+	return 0;
+}
+
+static int misc_io(void *opaque, int size, int is_write,
+		   uint64_t addr, uint64_t *value)
+{
+	static int newline = 1;
+
+	if (!is_write)
+		*value = -1;
+
+	switch (addr) {
+	case 0xff: // irq injector
+		if (is_write) {
+			printf("injecting interrupt 0x%x\n", (uint8_t)*value);
+			kvm_inject_irq(kvm, 0, *value);
+		}
+		break;
+	case 0xf1: // serial
+		if (is_write) {
+			if (newline)
+				fputs("GUEST: ", stdout);
+			putchar(*value);
+			newline = *value == '\n';
+		}
+		break;
+	case 0xd1:
+		if (!is_write)
+			*value = memory_size;
+		break;
+	case 0xf4: // exit
+		if (is_write)
+			exit(*value);
+		break;
+	}
+
+	return 0;
+}
+
+static int misc_init(void)
+{
+	int err;
+
+	err = io_table_register(&pio_table, 0xff, 1, misc_io, NULL);
+	if (err < 0)
+		return err;
+
+	err = io_table_register(&pio_table, 0xf1, 1, misc_io, NULL);
+	if (err < 0)
+		return err;
+
+	err = io_table_register(&pio_table, 0xf4, 1, misc_io, NULL);
+	if (err < 0)
+		return err;
+
+	return io_table_register(&pio_table, 0xd1, 1, misc_io, NULL);
+}
+
+static int test_debug(void *opaque, int vcpu)
+{
+	printf("test_debug\n");
+	return 0;
+}
+
+static int test_halt(void *opaque, int vcpu)
+{
+	int n;
+
+	sigwait(&ipi_sigmask, &n);
+	return 0;
+}
+
+static int test_io_window(void *opaque)
+{
+	return 0;
+}
+
+static int test_try_push_interrupts(void *opaque)
+{
+	return 0;
+}
+
+static void test_post_kvm_run(void *opaque, int vcpu)
+{
+}
+
+static int test_pre_kvm_run(void *opaque, int vcpu)
+{
+	return 0;
+}
+
+static int test_mem_read(void *opaque, uint64_t addr, uint8_t *data, int len)
+{
+	printf("%s: addr %"PRIx64" len %d\n", __func__, addr, len);
+	memset(data, 0, len);
+	return 0;
+}
+
+static int test_mem_write(void *opaque, uint64_t addr, uint8_t *data, int len)
+{
+	printf("%s: addr %"PRIx64" len %d data %"PRIx64"\n",
+	       __func__, addr, len, *(uint64_t *)data);
+	return 0;
+}
+
+static struct kvm_callbacks test_callbacks = {
+	.mmio_read   = test_mem_read,
+	.mmio_write  = test_mem_write,
+	.debug       = test_debug,
+	.halt        = test_halt,
+	.io_window = test_io_window,
+	.try_push_interrupts = test_try_push_interrupts,
+	.post_kvm_run = test_post_kvm_run,
+	.pre_kvm_run = test_pre_kvm_run,
+};
+
+static unsigned long load_file(void *mem, const char *fname, int inval_icache)
+{
+	int r;
+	int fd;
+	unsigned long bytes = 0;
+
+	fd = open(fname, O_RDONLY);
+	if (fd == -1) {
+		perror("open");
+		exit(1);
+	}
+
+	while ((r = read(fd, mem, 4096)) != -1 && r != 0) {
+		mem += r;
+		bytes += r;
+	}
+
+	if (r == -1) {
+		perror("read");
+		exit(1);
+	}
+
+	return bytes;
+}
+
+#define ICACHE_LINE_SIZE 32
+
+void sync_caches(void *mem, unsigned long len)
+{
+	unsigned long i;
+
+	for (i = 0; i < len; i += ICACHE_LINE_SIZE)
+		asm volatile ("dcbst %0, %1" : : "g"(mem), "r"(i));
+	asm volatile ("sync");
+	for (i = 0; i < len; i += ICACHE_LINE_SIZE)
+		asm volatile ("icbi %0, %1" : : "g"(mem), "r"(i));
+	asm volatile ("sync; isync");
+}
+
+static void init_vcpu(int n, unsigned long entry)
+{
+	struct kvm_regs regs = {
+		.pc = entry,
+	};
+
+	kvm_set_regs(kvm, 0, &regs);
+
+	sigemptyset(&ipi_sigmask);
+	sigaddset(&ipi_sigmask, IPI_SIGNAL);
+	sigprocmask(SIG_UNBLOCK, &ipi_sigmask, NULL);
+	sigprocmask(SIG_BLOCK, &ipi_sigmask, &kernel_sigmask);
+	vcpus[n].tid = gettid();
+	vcpu = n;
+	kvm_set_signal_mask(kvm, n, &kernel_sigmask);
+	sem_post(&init_sem);
+}
+
+static void *do_create_vcpu(void *_n)
+{
+	int n = (long)_n;
+
+	kvm_create_vcpu(kvm, n);
+	init_vcpu(n, 0x0);
+	kvm_run(kvm, n);
+	return NULL;
+}
+
+static void start_vcpu(int n)
+{
+	pthread_t thread;
+
+	pthread_create(&thread, NULL, do_create_vcpu, (void *)(long)n);
+}
+
+static void usage(const char *progname)
+{
+	fprintf(stderr,
+"Usage: %s [OPTIONS] [bootstrap] flatfile\n"
+"KVM test harness.\n"
+"\n"
+"  -s, --smp=NUM          create a VM with NUM virtual CPUs\n"
+"  -m, --memory=NUM[GMKB] allocate NUM memory for virtual machine.  A suffix\n"
+"                         can be used to change the unit (default: `M')\n"
+"  -h, --help             display this help screen and exit\n"
+"\n"
+"Report bugs to <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>.\n"
+		, progname);
+}
+
+static void sig_ignore(int sig)
+{
+	write(1, "boo\n", 4);
+}
+
+int main(int argc, char **argv)
+{
+	void *vm_mem;
+	unsigned long len;
+	int i;
+	const char *sopts = "s:phm:";
+	struct option lopts[] = {
+		{ "smp", 1, 0, 's' },
+		{ "memory", 1, 0, 'm' },
+		{ "help", 0, 0, 'h' },
+		{ 0 },
+	};
+	int opt_ind, ch;
+	int nb_args;
+	char *endptr;
+
+	while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) {
+		switch (ch) {
+		case 's':
+			ncpus = atoi(optarg);
+			break;
+		case 'm':
+			memory_size = strtoull(optarg, &endptr, 0);
+			switch (*endptr) {
+			case 'G': case 'g':
+				memory_size <<= 30;
+				break;
+			case '\0':
+			case 'M': case 'm':
+				memory_size <<= 20;
+				break;
+			case 'K': case 'k':
+				memory_size <<= 10;
+				break;
+			default:
+				fprintf(stderr,
+					"Unrecongized memory suffix: %c\n",
+					*endptr);
+				exit(1);
+			}
+			if (memory_size == 0) {
+				fprintf(stderr,
+					"Invalid memory size: 0\n");
+				exit(1);
+			}
+			break;
+		case 'h':
+			usage(argv[0]);
+			exit(0);
+		case '?':
+		default:
+			fprintf(stderr,
+				"Try `%s --help' for more information.\n",
+				argv[0]);
+			exit(1);
+		}
+	}
+
+	nb_args = argc - optind;
+	if (nb_args < 1 || nb_args > 2) {
+		fprintf(stderr,
+			"Incorrect number of arguments.\n"
+			"Try `%s --help' for more information.\n",
+			argv[0]);
+		exit(1);
+	}
+
+	signal(IPI_SIGNAL, sig_ignore);
+
+	vcpus = calloc(ncpus, sizeof *vcpus);
+	if (!vcpus) {
+		fprintf(stderr, "calloc failed\n");
+		return 1;
+	}
+
+	kvm = kvm_init(&test_callbacks, 0);
+	if (!kvm) {
+		fprintf(stderr, "kvm_init failed\n");
+		return 1;
+	}
+	if (kvm_create(kvm, memory_size, &vm_mem) < 0) {
+		kvm_finalize(kvm);
+		fprintf(stderr, "kvm_create failed\n");
+		return 1;
+	}
+
+	vm_mem = kvm_create_phys_mem(kvm, 0, memory_size, 0, 1);
+
+	len = load_file(vm_mem, argv[optind], 1);
+	sync_caches(vm_mem, len);
+
+	misc_init();
+
+	sem_init(&init_sem, 0, 0);
+	init_vcpu(0, 0x0);
+	for (i = 1; i < ncpus; ++i)
+		start_vcpu(i);
+	for (i = 0; i < ncpus; ++i)
+		sem_wait(&init_sem);
+
+	kvm_run(kvm, 0);
+
+	return 0;
+}

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2 of 2] Add PowerPC kvmctl harness and fix building the testcases
  2008-01-09  0:04 ` [PATCH 2 of 2] Add PowerPC kvmctl harness and fix building the testcases Hollis Blanchard
@ 2008-01-09  8:50   ` Avi Kivity
  0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2008-01-09  8:50 UTC (permalink / raw)
  To: Hollis Blanchard
  Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Hollis Blanchard wrote:
> +
> +static int misc_init(void)
> +{
> +	int err;
> +
> +	err = io_table_register(&pio_table, 0xff, 1, misc_io, NULL);
> +	if (err < 0)
> +		return err;
> +
> +	err = io_table_register(&pio_table, 0xf1, 1, misc_io, NULL);
> +	if (err < 0)
> +		return err;
> +
> +	err = io_table_register(&pio_table, 0xf4, 1, misc_io, NULL);
> +	if (err < 0)
> +		return err;
> +
> +	return io_table_register(&pio_table, 0xd1, 1, misc_io, NULL);
> +}
>   

I thought ppc doesn't have pio (and certainly doesn't need the random 
hacks above)?

While it's okay to not share code with x86 for the test harness, at 
least remove the x86 specific parts.

-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-01-09  8:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-09  0:04 [PATCH 0 of 2] Fix kvm-userspace/user/ for PowerPC Hollis Blanchard
2008-01-09  0:04 ` [PATCH 1 of 2] Add OBJCOPY to kvm-userspace/user/configure output Hollis Blanchard
2008-01-09  0:04 ` [PATCH 2 of 2] Add PowerPC kvmctl harness and fix building the testcases Hollis Blanchard
2008-01-09  8:50   ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox