new file mode 100644
@@ -0,0 +1,23 @@
+This directory contains sources for a kvm test suite.
+
+Tests for x86 architecture are run as kernel images for qemu that supports multiboot format.
+Tests uses an infrastructure called from the bios code. The infrastructure initialize the system/cpu's,
+switch to long-mode and calls the 'main' function of the individual test.
+Tests uses a qemu's virtual test device, named testdev, for services like printing, exiting, query memory size etc.
+See file testdev.txt for more details.
+
+To create the tests' images just type 'make' in this directory.
+Tests' images created in ./test/<ARCH>/*.flat
+
+An example of a test invocation:
+qemu-system-x86_64 -device testdev,chardev=testlog -chardev file,id=testlog,path=msr.out -kernel ./test/x86/msr.flat
+This invocation runs the msr test case. The test output is in file msr.out.
+
+
+
+Directory structure:
+.: Makefile and config files for the tests
+./test/lib: general services for the tests
+./test/lib/<ARCH>: architecture dependent services for the tests
+./test/<ARCH>: the sources of the tests and the created objects/images
+
deleted file mode 100755
@@ -1,92 +0,0 @@
-/*
- * This binary provides access to the guest's balloon driver
- * module.
- *
- * Copyright (C) 2007 Qumranet
- *
- * Author:
- *
- * Dor Laor <dor.laor@qumranet.com>
- *
- * This work is licensed under the GNU LGPL license, version 2.
- */
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-
-#define __user
-#include <linux/kvm.h>
-
-#define PAGE_SIZE 4096ul
-
-
-static int balloon_op(int *fd, int bytes)
-{
- struct kvm_balloon_op bop;
- int r;
-
- bop.npages = bytes/PAGE_SIZE;
- r = ioctl(*fd, KVM_BALLOON_OP, &bop);
- if (r == -1)
- return -errno;
- printf("Ballon handled %d pages successfully\n", bop.npages);
-
- return 0;
-}
-
-static int balloon_init(int *fd)
-{
- *fd = open("/dev/kvm_balloon", O_RDWR);
- if (*fd == -1) {
- perror("open /dev/kvm_balloon");
- return -1;
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- int fd;
- int r;
- int bytes;
-
- if (argc != 3) {
- perror("Please provide op=[i|d], bytes\n");
- return 1;
- }
- bytes = atoi(argv[2]);
-
- switch (*argv[1]) {
- case 'i':
- break;
- case 'd':
- bytes = -bytes;
- break;
- default:
- perror("Wrong op param\n");
- return 1;
- }
-
- if (balloon_init(&fd)) {
- perror("balloon_init failed\n");
- return 1;
- }
-
- if ((r = balloon_op(&fd, bytes))) {
- perror("balloon_op failed\n");
- goto out;
- }
-
-out:
- close(fd);
-
- return r;
-}
-
deleted file mode 100644
@@ -1,15 +0,0 @@
-OUTPUT_FORMAT(binary)
-
-SECTIONS
-{
- . = 0;
- stext = .;
- .text : { *(.init) *(.text) }
- . = ALIGN(4K);
- .data : { *(.data) }
- . = ALIGN(16);
- .bss : { *(.bss) }
- . = ALIGN(4K);
- edata = .;
-}
-
@@ -2,9 +2,7 @@
CFLAGS += -I../include/x86
-all: kvmtrace test_cases
-
-balloon_ctl: balloon_ctl.o
+all: test_cases
cflatobjs += \
test/lib/x86/io.o \
@@ -19,21 +17,17 @@ $(libcflat): CFLAGS += -ffreestanding -I test/lib
CFLAGS += -m$(bits)
FLATLIBS = test/lib/libcflat.a $(libgcc)
-%.flat: %.o $(FLATLIBS)
+%.flat: %.o $(FLATLIBS) flat.lds
$(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,flat.lds $^ $(FLATLIBS)
-tests-common = $(TEST_DIR)/bootstrap \
- $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
- $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
- $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat
+tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \
+ $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \
+ $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat
test_cases: $(tests-common) $(tests)
$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I test/lib -I test/lib/x86
-$(TEST_DIR)/bootstrap: $(TEST_DIR)/bootstrap.o
- $(CC) -nostdlib -o $@ -Wl,-T,bootstrap.lds $^
-
$(TEST_DIR)/access.flat: $(cstart.o) $(TEST_DIR)/access.o $(TEST_DIR)/print.o
$(TEST_DIR)/hypercall.flat: $(cstart.o) $(TEST_DIR)/hypercall.o $(TEST_DIR)/print.o
@@ -43,8 +37,6 @@ $(TEST_DIR)/sieve.flat: $(cstart.o) $(TEST_DIR)/sieve.o \
$(TEST_DIR)/vmexit.flat: $(cstart.o) $(TEST_DIR)/vmexit.o
-$(TEST_DIR)/test32.flat: $(TEST_DIR)/test32.o
-
$(TEST_DIR)/smptest.flat: $(cstart.o) $(TEST_DIR)/smptest.o
$(TEST_DIR)/emulator.flat: $(cstart.o) $(TEST_DIR)/emulator.o \
@@ -62,16 +54,12 @@ $(TEST_DIR)/realmode.flat: $(TEST_DIR)/realmode.o
$(TEST_DIR)/realmode.o: bits = 32
-$(TEST_DIR)/memtest1.flat: $(TEST_DIR)/memtest1.o
-
$(TEST_DIR)/stringio.flat: $(TEST_DIR)/stringio.o
-$(TEST_DIR)/simple.flat: $(TEST_DIR)/simple.o
-
$(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o
arch_clean:
- $(RM) $(TEST_DIR)/bootstrap $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \
+ $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \
$(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o
-include $(TEST_DIR)/.*.d test/lib/.*.d test/lib/x86/.*.d
@@ -5,8 +5,7 @@ ldarch = elf64-x86-64
CFLAGS += -D__x86_64__
tests = $(TEST_DIR)/access.flat $(TEST_DIR)/sieve.flat \
- $(TEST_DIR)/simple.flat $(TEST_DIR)/stringio.flat \
- $(TEST_DIR)/memtest1.flat $(TEST_DIR)/emulator.flat \
- $(TEST_DIR)/hypercall.flat $(TEST_DIR)/apic.flat
+ $(TEST_DIR)/stringio.flat $(TEST_DIR)/emulator.flat \
+ $(TEST_DIR)/hypercall.flat $(TEST_DIR)/apic.flat
include config-x86-common.mak
deleted file mode 100644
@@ -1,611 +0,0 @@
-/*
- * 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
- *
- * Authors:
- *
- * Avi Kivity <avi@qumranet.com>
- * Yaniv Kamay <yaniv@qumranet.com>
- *
- * This work is licensed under the GNU LGPL license, version 2.
- */
-
-#define _GNU_SOURCE
-
-#include <libkvm.h>
-#include "test/lib/x86/fake-apic.h"
-#include "test/x86/ioram.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 "iotable.h"
-
-static uint8_t ioram[IORAM_LEN];
-
-static int gettid(void)
-{
- return syscall(__NR_gettid);
-}
-
-static int tkill(int pid, int sig)
-{
- return syscall(__NR_tkill, pid, sig);
-}
-
-kvm_context_t kvm;
-
-#define MAX_VCPUS 4
-
-#define IPI_SIGNAL (SIGRTMIN + 4)
-
-static int ncpus = 1;
-static sem_t init_sem;
-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;
-
-static struct io_table pio_table;
-
-struct vcpu_info {
- int id;
- pid_t tid;
- sem_t sipi_sem;
-};
-
-struct vcpu_info *vcpus;
-
-static uint32_t apic_sipi_addr;
-
-static void apic_send_sipi(int vcpu)
-{
- sem_post(&vcpus[vcpu].sipi_sem);
-}
-
-static void apic_send_ipi(int vcpu)
-{
- struct vcpu_info *v;
-
- if (vcpu < 0 || vcpu >= ncpus)
- return;
- v = &vcpus[vcpu];
- tkill(v->tid, IPI_SIGNAL);
-}
-
-static int apic_io(void *opaque, int size, int is_write,
- uint64_t addr, uint64_t *value)
-{
- if (!is_write)
- *value = -1u;
-
- switch (addr - APIC_BASE) {
- case APIC_REG_NCPU:
- if (!is_write)
- *value = ncpus;
- break;
- case APIC_REG_ID:
- if (!is_write)
- *value = vcpu;
- break;
- case APIC_REG_SIPI_ADDR:
- if (!is_write)
- *value = apic_sipi_addr;
- else
- apic_sipi_addr = *value;
- break;
- case APIC_REG_SEND_SIPI:
- if (is_write)
- apic_send_sipi(*value);
- break;
- case APIC_REG_IPI_VECTOR:
- if (!is_write)
- *value = apic_ipi_vector;
- else
- apic_ipi_vector = *value;
- break;
- case APIC_REG_SEND_IPI:
- if (is_write)
- apic_send_ipi(*value);
- break;
- }
-
- 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;
- 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);
-}
-
-#define IRQCHIP_IO_BASE 0x2000
-
-static int irqchip_io(void *opaque, int size, int is_write,
- uint64_t addr, uint64_t *value)
-{
- addr -= IRQCHIP_IO_BASE;
-
- if (is_write) {
- kvm_set_irq_level(kvm, addr, *value, NULL);
- }
- return 0;
-}
-
-static int test_inb(void *opaque, uint16_t addr, uint8_t *value)
-{
- 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)
-{
- 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)
-{
- 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);
- }
-
- return 0;
-}
-
-static int test_outb(void *opaque, uint16_t addr, uint8_t value)
-{
- 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);
-
- return 0;
-}
-
-static int test_outw(void *opaque, uint16_t addr, uint16_t value)
-{
- 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)
-{
- 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;
-}
-
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-static int test_debug(void *opaque, void *vcpu,
- struct kvm_debug_exit_arch *arch_info)
-{
- printf("test_debug\n");
- return 0;
-}
-#endif
-
-static int test_halt(void *opaque, int vcpu)
-{
- int n;
-
- sigwait(&ipi_sigmask, &n);
- kvm_inject_irq(kvm, vcpus[vcpu].id, apic_ipi_vector);
- return 0;
-}
-
-static int test_io_window(void *opaque)
-{
- return 0;
-}
-
-static int test_try_push_interrupts(void *opaque)
-{
- return 0;
-}
-
-#ifdef KVM_CAP_USER_NMI
-static void test_push_nmi(void *opaque)
-{
-}
-#endif
-
-static void test_post_kvm_run(void *opaque, void *vcpu)
-{
-}
-
-static int test_pre_kvm_run(void *opaque, void *vcpu)
-{
- return 0;
-}
-
-static int test_mem_read(void *opaque, uint64_t addr, uint8_t *data, int len)
-{
- if (addr < IORAM_BASE_PHYS || addr + len > IORAM_BASE_PHYS + IORAM_LEN)
- return 1;
- memcpy(data, ioram + addr - IORAM_BASE_PHYS, len);
- return 0;
-}
-
-static int test_mem_write(void *opaque, uint64_t addr, uint8_t *data, int len)
-{
- if (addr < IORAM_BASE_PHYS || addr + len > IORAM_BASE_PHYS + IORAM_LEN)
- return 1;
- memcpy(ioram + addr - IORAM_BASE_PHYS, data, len);
- return 0;
-}
-
-static int test_shutdown(void *opaque, void *env)
-{
- printf("shutdown\n");
- kvm_show_regs(kvm, 0);
- exit(1);
- return 1;
-}
-
-static struct kvm_callbacks test_callbacks = {
- .inb = test_inb,
- .inw = test_inw,
- .inl = test_inl,
- .outb = test_outb,
- .outw = test_outw,
- .outl = test_outl,
- .mmio_read = test_mem_read,
- .mmio_write = test_mem_write,
-#ifdef KVM_CAP_SET_GUEST_DEBUG
- .debug = test_debug,
-#endif
- .halt = test_halt,
- .io_window = test_io_window,
- .try_push_interrupts = test_try_push_interrupts,
-#ifdef KVM_CAP_USER_NMI
- .push_nmi = test_push_nmi,
-#endif
- .post_kvm_run = test_post_kvm_run,
- .pre_kvm_run = test_pre_kvm_run,
- .shutdown = test_shutdown,
-};
-
-static void load_file(void *mem, const char *fname)
-{
- int r;
- int fd;
-
- fd = open(fname, O_RDONLY);
- if (fd == -1) {
- perror("open");
- exit(1);
- }
- while ((r = read(fd, mem, 4096)) != -1 && r != 0)
- mem += r;
- if (r == -1) {
- perror("read");
- exit(1);
- }
-}
-
-static void enter_32(kvm_context_t kvm)
-{
- struct kvm_regs regs = {
- .rsp = 0x80000, /* 512KB */
- .rip = 0x100000, /* 1MB */
- .rflags = 2,
- };
- struct kvm_sregs sregs = {
- .cs = { 0, -1u, 8, 11, 1, 0, 1, 1, 0, 1, 0, 0 },
- .ds = { 0, -1u, 16, 3, 1, 0, 1, 1, 0, 1, 0, 0 },
- .es = { 0, -1u, 16, 3, 1, 0, 1, 1, 0, 1, 0, 0 },
- .fs = { 0, -1u, 16, 3, 1, 0, 1, 1, 0, 1, 0, 0 },
- .gs = { 0, -1u, 16, 3, 1, 0, 1, 1, 0, 1, 0, 0 },
- .ss = { 0, -1u, 16, 3, 1, 0, 1, 1, 0, 1, 0, 0 },
-
- .tr = { 0, 10000, 24, 11, 1, 0, 0, 0, 0, 0, 0, 0 },
- .ldt = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- .gdt = { 0, 0 },
- .idt = { 0, 0 },
- .cr0 = 0x37,
- .cr3 = 0,
- .cr4 = 0,
- .efer = 0,
- .apic_base = 0,
- .interrupt_bitmap = { 0 },
- };
-
- kvm_set_regs(kvm, 0, ®s);
- kvm_set_sregs(kvm, 0, &sregs);
-}
-
-static void init_vcpu(int n)
-{
- sigemptyset(&ipi_sigmask);
- sigaddset(&ipi_sigmask, IPI_SIGNAL);
- sigprocmask(SIG_UNBLOCK, &ipi_sigmask, NULL);
- sigprocmask(SIG_BLOCK, &ipi_sigmask, &kernel_sigmask);
- vcpus[n].id = n;
- 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;
- struct kvm_regs regs;
-
- kvm_create_vcpu(kvm, n);
- init_vcpu(n);
- sem_wait(&vcpus[n].sipi_sem);
- kvm_get_regs(kvm, n, ®s);
- regs.rip = apic_sipi_addr;
- kvm_set_regs(kvm, n, ®s);
- kvm_run(kvm, n, &vcpus[n]);
- return NULL;
-}
-
-static void start_vcpu(int n)
-{
- pthread_t thread;
-
- sem_init(&vcpus[n].sipi_sem, 0, 0);
- 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"
-" -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@vger.kernel.org>.\n"
- , progname);
-}
-
-static void sig_ignore(int sig)
-{
- write(1, "boo\n", 4);
-}
-
-int main(int argc, char **argv)
-{
- void *vm_mem;
- int i;
- 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) {
- case 's':
- ncpus = atoi(optarg);
- break;
- 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);
- 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);
-
- if (enter_protected_mode)
- enter_32(kvm);
- else
- load_file(vm_mem + 0xf0000, argv[optind]);
-
- if (nb_args > 1)
- load_file(vm_mem + 0x100000, argv[optind + 1]);
-
- apic_init();
- misc_init();
-
- io_table_register(&pio_table, IRQCHIP_IO_BASE, 0x20, irqchip_io, NULL);
-
- sem_init(&init_sem, 0, 0);
- for (i = 0; i < ncpus; ++i)
- start_vcpu(i);
- for (i = 0; i < ncpus; ++i)
- sem_wait(&init_sem);
-
- kvm_run(kvm, 0, &vcpus[0]);
-
- return 0;
-}
new file mode 100644
@@ -0,0 +1,15 @@
+Tests in this directory and what they do:
+
+access: lots of page table related access (pte/pde) (read/write)
+apic: enable x2apic, self ipi, ioapic intr, ioapic simultaneous
+emulator: move to/from regs, cmps, push, pop, to/from cr8, smsw and lmsw
+hypercall: intel and amd hypercall insn
+msr: write to msr (only KERNEL_GS_BASE for now)
+port80: lots of out to port 80
+realmode: goes back to realmode, shld, push/pop, mov immediate, cmp immediate, add immediate,
+ io, eflags instructions (clc, cli, etc.), jcc short, jcc near, call, long jmp, xchg
+sieve: heavy memory access with no paging and with paging static and with paging vmalloc'ed
+smptest: run smp_id() on every cpu and compares return value to number
+stringio: outs forward and backward
+tsc: write to tsc(0) and write to tsc(100000000000) and read it back
+vmexit: long loops for each: cpuid, vmcall, mov_from_cr8, mov_to_cr8, inl_pmtimer, ipi, ipi+halt
deleted file mode 100644
@@ -1,137 +0,0 @@
-/*
- * minimal bootstrap to set up flat 32-bit protected mode
- */
-
-#include "fake-apic.h"
-
-bstart = 0xf0000
-
-.code16
-
-stack_top = 0x1000
-cpu_up = 0x1000
-cpu_up_pmode = 0x1004
-
-pmode_stack_start = 0x10000
-pmode_stack_shift = 16
-pmode_stack_size = (1 << pmode_stack_shift)
-
-ipi_vec = 0xf0
-
-start:
- mov $stack_top, %sp
- call smp_init
-
- cs lidtl idt_desc
- cs lgdtl gdt_desc
- mov %cr0, %eax
- or $1, %eax
- mov %eax, %cr0
- ljmpl $8, $pmode + bstart
-
-smp_init:
- mov $ipi_vec, %eax
- mov $(APIC_BASE + APIC_REG_IPI_VECTOR), %dx
- out %eax, %dx
- movw $ap_switch_to_pmode, ipi_vec*4
- movw %cs, %ax
- mov %ax, ipi_vec*4+2
- mov $sipi, %eax
- mov $(APIC_BASE + APIC_REG_SIPI_ADDR), %dx
- outl %eax, %dx
- mov $(APIC_BASE + APIC_REG_NCPU), %dx
- inl %dx, %eax
- mov %eax, %ecx
- mov $1, %esi
-smp_loop:
- cmp %esi, %ecx
- jbe smp_done
- mov %esi, %eax
- mov $(APIC_BASE + APIC_REG_SEND_SIPI), %dx
- outl %eax, %dx
-wait_for_cpu:
- cmp cpu_up, %esi
- jne wait_for_cpu
- mov %esi, %eax
- mov $(APIC_BASE + APIC_REG_SEND_IPI), %dx
- out %eax, %dx
-wait_for_cpu_pmode:
- cmp cpu_up_pmode, %esi
- jne wait_for_cpu_pmode
-
- inc %esi
- jmp smp_loop
-smp_done:
- ret
-
-sipi:
- mov $(APIC_BASE + APIC_REG_ID), %dx
- inl %dx, %eax
- mov %eax, cpu_up
- shl $12, %eax
- addl $stack_top, %eax
- movl %eax, %esp
- sti
- nop
-1: hlt
- jmp 1b
-
-ap_switch_to_pmode:
- cs lidtl idt_desc
- cs lgdtl gdt_desc
- mov %cr0, %eax
- or $1, %eax
- mov %eax, %cr0
- ljmpl $8, $ap_pmode + bstart
-
-.code32
-ap_pmode:
- mov $0x10, %ax
- mov %ax, %ds
- mov %ax, %es
- mov %ax, %fs
- mov %ax, %gs
- mov %ax, %ss
- mov $(APIC_BASE + APIC_REG_ID), %dx
- in %dx, %eax
- mov %eax, cpu_up_pmode
- shl $pmode_stack_shift, %eax
- lea pmode_stack_start + pmode_stack_size(%eax), %esp
- sti
- nop
-ap_pmode_wait:
- hlt
- jmp ap_pmode_wait
-
-pmode:
- mov $0x10, %ax
- mov %ax, %ds
- mov %ax, %es
- mov %ax, %fs
- mov %ax, %gs
- mov %ax, %ss
- mov $pmode_stack_start + pmode_stack_size, %esp
- ljmp $8, $0x100000
-
-.align 16
-
-idt_desc:
- .word 8*256-1
- .long 0
-
-gdt_desc:
- .word gdt_end - gdt - 1
- .long gdt + bstart
-
-.align 16
-
-gdt:
- .quad 0
- .quad 0x00cf9b000000ffff // flat 32-bit code segment
- .quad 0x00cf93000000ffff // flat 32-bit data segment
-gdt_end:
-
-. = 0xfff0
- .code16
- ljmp $0xf000, $start
-.align 65536
deleted file mode 100644
@@ -1,7 +0,0 @@
-#include "runtime.h"
-
-void exit(unsigned code)
-{
- asm volatile("out %al, %dx" : : "a"(code), "d"(0xf4));
- asm volatile("cli; hlt");
-}
deleted file mode 100644
@@ -1,44 +0,0 @@
-.text
-
-start:
- mov $0x1000,%r8
- mov $0x0a,%ecx
-
-init_page:
- dec %ecx
- jne no_io
- mov $0x0,%al
- out %al,$0x80
- mov $0x0a,%ecx
-
-no_io:
- mov %r8,(%r8)
- add $0x1000,%r8
- cmp $0x8000000,%r8
- jne init_page
- mov $0x1000,%r8
- mov $0x0a,%ecx
-
-test_loop:
- dec %ecx
- jne no_io2
- mov $0x0,%al
- out %al,$0x80
- mov $0x0a,%ecx
-
-no_io2:
- mov (%r8),%r9
- cmp %r8,%r9
- jne err
- add $0x1000,%r8
- cmp $0x8000000,%r8
- jne test_loop
- mov $0x1000,%r8
- jmp test_loop
-
-err:
- mov $0xffffffffffffffff,%r12
- mov $0xffffffffffffffff,%r13
- mov $0x0,%al
- out %al,$0x80
- jmp err
deleted file mode 100644
@@ -1,6 +0,0 @@
-#ifndef H_RUNTIME
-#define H_RUNTIME
-
-void exit(unsigned code) __attribute__((__noreturn__));
-
-#endif
deleted file mode 100644
@@ -1,13 +0,0 @@
-
- .text
-
- mov $0, %al
- mov $10000, %ebx
-1:
- mov %rbx, %rcx
-2:
- loop 2b
- out %al, $0x80
- inc %al
- add $10000, %rbx
- jmp 1b
deleted file mode 100644
@@ -1,8 +0,0 @@
-.code32
-
-.text
-
-1:
- mov $0x12, %al
- out %al, $0x80
- jmp 1b
new file mode 100644
@@ -0,0 +1,14 @@
+This file describes the virtual device of qemu for supporting this test suite.
+
+Services supplied by the testdev device:
+
+serial output: write only, on io port 0xf1
+exit process: write only, on io port 0xf4, value used as exit code
+ram size: read-only, on io port 0xd1, 4 bytes' size
+irq line setting: write only, on io ports 0x2000 - 0x2018, value to set/clear
+simple io: read/write, on io port 0xe0, 1/2/4 bytes
+
+Test device used a char device for actual output
+
+
+