public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] Remove memory size from linker script (v2)
@ 2007-10-10 20:03 Anthony Liguori
       [not found] ` <11920466271613-git-send-email-aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 4+ messages in thread
From: Anthony Liguori @ 2007-10-10 20:03 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Anthony Liguori, Jerone Young, Avi Kivity

The memory size is currently hardcoded into the linker script (end_of_memory).
This prevents the memory size from being specified dynamically in kvmctl.
This patch adds a PIO port that can be used to query the memory size in the
tests.

Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

diff --git a/user/flat.lds b/user/flat.lds
index 7dd922c..61f1057 100644
--- a/user/flat.lds
+++ b/user/flat.lds
@@ -13,6 +13,5 @@ SECTIONS
     .bss : { *(.bss) }
     . = ALIGN(4K);
     edata = .;
-    end_of_memory = 128M;
 }
 
diff --git a/user/main.c b/user/main.c
index 3eb8dea..9a57a24 100644
--- a/user/main.c
+++ b/user/main.c
@@ -144,7 +144,15 @@ static int test_inl(void *opaque, uint16_t addr, uint32_t *value)
 {
 	if (apic_io(addr, 0, value))
 		return 0;
-	printf("inl 0x%x\n", addr);
+
+	switch (addr) {
+	case 0xd1:
+		*value = 128 * 1024 * 1024;
+		break;
+	default:
+		printf("inl 0x%x\n", addr);
+		break;
+	}
 	return 0;
 }
 
diff --git a/user/test/vm.c b/user/test/vm.c
index 2eb8d96..e0e78d7 100644
--- a/user/test/vm.c
+++ b/user/test/vm.c
@@ -58,7 +58,8 @@ void free_page(void *page)
     free = page;
 }
 
-extern char edata, end_of_memory;
+extern char edata;
+static unsigned long end_of_memory;
 
 #define PTE_PRESENT (1ull << 0)
 #define PTE_PSE     (1ull << 7)
@@ -202,10 +203,18 @@ static void setup_mmu(unsigned long len)
     print("paging enabled\n");
 }
 
+static unsigned int inl(unsigned short port)
+{
+    unsigned int val;
+    asm volatile("inl %w1, %0" : "=a"(val) : "Nd"(port));
+    return val;
+}
+
 void setup_vm()
 {
-    free_memory(&edata, &end_of_memory - &edata);
-    setup_mmu((long)&end_of_memory);
+    end_of_memory = inl(0xd1);
+    free_memory(&edata, end_of_memory - (unsigned long)&edata);
+    setup_mmu(end_of_memory);
 }
 
 void *vmalloc(unsigned long size)

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

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

* [PATCH 2/3] Allow memory to be specified in kvmctl (v2)
       [not found] ` <11920466271613-git-send-email-aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2007-10-10 20:03   ` Anthony Liguori
  2007-10-10 20:03   ` [PATCH 3/3] Use a table to dispatch IO requests " Anthony Liguori
  2007-10-11 11:24   ` [PATCH 1/3] Remove memory size from linker script (v2) Avi Kivity
  2 siblings, 0 replies; 4+ messages in thread
From: Anthony Liguori @ 2007-10-10 20:03 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Anthony Liguori, Jerone Young, Avi Kivity

This patch adds a --memory option to kvmctl to allow the memory size of the
guest to be specified.

Since v1, I added more checks for bad input as suggested by Muli.

Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

diff --git a/user/main.c b/user/main.c
index 9a57a24..a08e0a7 100644
--- a/user/main.c
+++ b/user/main.c
@@ -57,6 +57,7 @@ static __thread int vcpu;
 static int apic_ipi_vector = 0xff;
 static sigset_t kernel_sigmask;
 static sigset_t ipi_sigmask;
+static uint64_t memory_size = 128 * 1024 * 1024;
 
 struct vcpu_info {
 	pid_t tid;
@@ -147,7 +148,7 @@ static int test_inl(void *opaque, uint16_t addr, uint32_t *value)
 
 	switch (addr) {
 	case 0xd1:
-		*value = 128 * 1024 * 1024;
+		*value = memory_size;
 		break;
 	default:
 		printf("inl 0x%x\n", addr);
@@ -328,14 +329,16 @@ static void start_vcpu(int 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"
-		"  -p, --protected-mode   start VM in protected mode\n"
-		"  -h, --help             display this help screen and exit\n"
-		"\n"
-		"Report bugs to <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>.\n"
+"Usage: %s [OPTIONS] [bootstrap] flatfile\n"
+"KVM test harness.\n"
+"\n"
+"  -s, --smp=NUM          create a VM with NUM virtual CPUs\n"
+"  -p, --protected-mode   start VM in protected mode\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);
 }
 
@@ -348,16 +351,18 @@ int main(int argc, char **argv)
 {
 	void *vm_mem;
 	int i;
-	const char *sopts = "s:ph";
+	const char *sopts = "s:phm:";
 	struct option lopts[] = {
 		{ "smp", 1, 0, 's' },
 		{ "protected-mode", 0, 0, 'p' },
+		{ "memory", 1, 0, 'm' },
 		{ "help", 0, 0, 'h' },
 		{ 0 },
 	};
 	int opt_ind, ch;
 	bool enter_protected_mode = false;
 	int nb_args;
+	char *endptr;
 
 	while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) {
 		switch (ch) {
@@ -367,6 +372,31 @@ int main(int argc, char **argv)
 		case 'p':
 			enter_protected_mode = true;
 			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);
@@ -401,7 +431,7 @@ int main(int argc, char **argv)
 		fprintf(stderr, "kvm_init failed\n");
 		return 1;
 	}
-	if (kvm_create(kvm, 128 * 1024 * 1024, &vm_mem) < 0) {
+	if (kvm_create(kvm, memory_size, &vm_mem) < 0) {
 		kvm_finalize(kvm);
 		fprintf(stderr, "kvm_create failed\n");
 		return 1;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

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

* [PATCH 3/3] Use a table to dispatch IO requests in kvmctl (v2)
       [not found] ` <11920466271613-git-send-email-aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
  2007-10-10 20:03   ` [PATCH 2/3] Allow memory to be specified in kvmctl (v2) Anthony Liguori
@ 2007-10-10 20:03   ` Anthony Liguori
  2007-10-11 11:24   ` [PATCH 1/3] Remove memory size from linker script (v2) Avi Kivity
  2 siblings, 0 replies; 4+ messages in thread
From: Anthony Liguori @ 2007-10-10 20:03 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Hollis Blanchard, Anthony Liguori, Jerone Young, Avi Kivity

This patch attempts to clean up kvmctl so that it can be more easily made to
work for multiple architectures and to support more emulation.

For dispatch, it's using a simple array as suggested by Avi.

For x86, we'll have two tables, a pio_table and an mmio_table.  For PPC we can
just have a single table.  The IO functions can support accesses of up to 8
bytes and can handle input/output in the same function.

I tried to keep this nice and simple so as to not add too much complexity to
kvmctl.

Signed-off-by: Anthony Liguori <aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

diff --git a/user/main.c b/user/main.c
index a08e0a7..b718cc8 100644
--- a/user/main.c
+++ b/user/main.c
@@ -51,6 +51,24 @@ kvm_context_t kvm;
 
 #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;
@@ -59,6 +77,8 @@ 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;
 	sem_t sipi_sem;
@@ -68,9 +88,36 @@ struct vcpu_info *vcpus;
 
 static uint32_t apic_sipi_addr;
 
-static int apic_range(unsigned addr)
+struct io_table_entry *io_table_lookup(struct io_table *io_table, uint64_t addr)
 {
-	return (addr >= APIC_BASE) && (addr < APIC_BASE + APIC_SIZE);
+	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 void apic_send_sipi(int vcpu)
@@ -88,11 +135,9 @@ static void apic_send_ipi(int vcpu)
 	tkill(v->tid, IPI_SIGNAL);
 }
 
-static int apic_io(unsigned addr, int is_write, uint32_t *value)
+static int apic_io(void *opaque, int size, int is_write,
+		   uint64_t addr, uint64_t *value)
 {
-	if (!apic_range(addr))
-		return 0;
-
 	if (!is_write)
 		*value = -1u;
 
@@ -126,69 +171,153 @@ static int apic_io(unsigned addr, int is_write, uint32_t *value)
 			apic_send_ipi(*value);
 		break;
 	}
-	return 1;
+
+	return 0;
+}
+
+static int apic_init(void)
+{
+	return io_table_register(&pio_table, APIC_BASE,
+				 APIC_SIZE, apic_io, NULL);
+}
+
+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;
+	}
+
+	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;
+
+	return io_table_register(&pio_table, 0xd1, 1, misc_io, NULL);
 }
 
 static int test_inb(void *opaque, uint16_t addr, uint8_t *value)
 {
-	printf("inb 0x%x\n", addr);
+	struct io_table_entry *entry;
+
+	entry = io_table_lookup(&pio_table, addr);
+	if (entry) {
+		uint64_t val;
+		entry->handler(entry->opaque, 1, 0, addr, &val);
+		*value = val;
+	} else {
+		*value = -1;
+		printf("inb 0x%x\n", addr);
+	}
+
 	return 0;
 }
 
 static int test_inw(void *opaque, uint16_t addr, uint16_t *value)
 {
-	printf("inw 0x%x\n", addr);
+	struct io_table_entry *entry;
+
+	entry = io_table_lookup(&pio_table, addr);
+	if (entry) {
+		uint64_t val;
+		entry->handler(entry->opaque, 2, 0, addr, &val);
+		*value = val;
+	} else {
+		*value = -1;
+		printf("inw 0x%x\n", addr);
+	}
+
 	return 0;
 }
 
 static int test_inl(void *opaque, uint16_t addr, uint32_t *value)
 {
-	if (apic_io(addr, 0, value))
-		return 0;
-
-	switch (addr) {
-	case 0xd1:
-		*value = memory_size;
-		break;
-	default:
+	struct io_table_entry *entry;
+
+	entry = io_table_lookup(&pio_table, addr);
+	if (entry) {
+		uint64_t val;
+		entry->handler(entry->opaque, 4, 0, addr, &val);
+		*value = val;
+	} else {
+		*value = -1;
 		printf("inl 0x%x\n", addr);
-		break;
 	}
+
 	return 0;
 }
 
 static int test_outb(void *opaque, uint16_t addr, uint8_t value)
 {
-	static int newline = 1;
+	struct io_table_entry *entry;
+
+	entry = io_table_lookup(&pio_table, addr);
+	if (entry) {
+		uint64_t val = value;
+		entry->handler(entry->opaque, 1, 1, addr, &val);
+	} else
+ 		printf("outb $0x%x, 0x%x\n", value, addr);
 
-	switch (addr) {
-	case 0xff: // irq injector
-		printf("injecting interrupt 0x%x\n", value);
-		kvm_inject_irq(kvm, 0, value);
-		break;
-	case 0xf1: // serial
-		if (newline)
-			fputs("GUEST: ", stdout);
-		putchar(value);
-		newline = value == '\n';
-		break;
-	default:
-		printf("outb $0x%x, 0x%x\n", value, addr);
-	}
 	return 0;
 }
 
 static int test_outw(void *opaque, uint16_t addr, uint16_t value)
 {
-	printf("outw $0x%x, 0x%x\n", value, addr);
+	struct io_table_entry *entry;
+
+	entry = io_table_lookup(&pio_table, addr);
+	if (entry) {
+		uint64_t val = value;
+		entry->handler(entry->opaque, 2, 1, addr, &val);
+	} else
+		printf("outw $0x%x, 0x%x\n", value, addr);
+
 	return 0;
 }
 
 static int test_outl(void *opaque, uint16_t addr, uint32_t value)
 {
-	if (apic_io(addr, 1, &value))
-		return 0;
-	printf("outl $0x%x, 0x%x\n", value, addr);
+	struct io_table_entry *entry;
+
+	entry = io_table_lookup(&pio_table, addr);
+	if (entry) {
+		uint64_t val = value;
+		entry->handler(entry->opaque, 4, 1, addr, &val);
+	} else
+		printf("outl $0x%x, 0x%x\n", value, addr);
+
 	return 0;
 }
 
@@ -445,6 +574,9 @@ int main(int argc, char **argv)
 	if (nb_args > 1)
 		load_file(vm_mem + 0x100000, argv[optind + 1]);
 
+	apic_init();
+	misc_init();
+
 	sem_init(&init_sem, 0, 0);
 	init_vcpu(0);
 	for (i = 1; i < ncpus; ++i)

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

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

* Re: [PATCH 1/3] Remove memory size from linker script (v2)
       [not found] ` <11920466271613-git-send-email-aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
  2007-10-10 20:03   ` [PATCH 2/3] Allow memory to be specified in kvmctl (v2) Anthony Liguori
  2007-10-10 20:03   ` [PATCH 3/3] Use a table to dispatch IO requests " Anthony Liguori
@ 2007-10-11 11:24   ` Avi Kivity
  2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2007-10-11 11:24 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Jerone Young

Anthony Liguori wrote:
> The memory size is currently hardcoded into the linker script (end_of_memory).
> This prevents the memory size from being specified dynamically in kvmctl.
> This patch adds a PIO port that can be used to query the memory size in the
> tests.
>
>   

Applied all three, thanks.


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


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

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

end of thread, other threads:[~2007-10-11 11:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-10 20:03 [PATCH 1/3] Remove memory size from linker script (v2) Anthony Liguori
     [not found] ` <11920466271613-git-send-email-aliguori-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2007-10-10 20:03   ` [PATCH 2/3] Allow memory to be specified in kvmctl (v2) Anthony Liguori
2007-10-10 20:03   ` [PATCH 3/3] Use a table to dispatch IO requests " Anthony Liguori
2007-10-11 11:24   ` [PATCH 1/3] Remove memory size from linker script (v2) Avi Kivity

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