diff options
78 files changed, 0 insertions, 9098 deletions
diff --git a/kvm/test/COPYRIGHT b/kvm/test/COPYRIGHT deleted file mode 100644 index d35649cb9..000000000 --- a/kvm/test/COPYRIGHT +++ /dev/null @@ -1,4 +0,0 @@ -Copyright (C) 2006 Qumranet. - -The files in this directory and its subdirectories are licensed under the -GNU LGPL, version 2. diff --git a/kvm/test/Makefile b/kvm/test/Makefile deleted file mode 100644 index 456ceae47..000000000 --- a/kvm/test/Makefile +++ /dev/null @@ -1,64 +0,0 @@ - -include config.mak - -DESTDIR := $(PREFIX)/share/qemu/tests - -.PHONY: arch_clean clean - -#make sure env CFLAGS variable is not used -CFLAGS = - -libgcc := $(shell $(CC) --print-libgcc-file-name) - -libcflat := lib/libcflat.a -cflatobjs := \ - lib/panic.o \ - lib/printf.o \ - lib/string.o - -#include architecure specific make rules -include config-$(ARCH).mak - -# cc-option -# Usage: OP_CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0) - -cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ - > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) - -CFLAGS += -O1 -CFLAGS += $(autodepend-flags) -g -fomit-frame-pointer -Wall -CFLAGS += $(call cc-option, -fno-stack-protector, "") -CFLAGS += $(call cc-option, -fno-stack-protector-all, "") -CFLAGS += -I../include -CFLAGS += -I ../libkvm - -LDFLAGS += $(CFLAGS) -L ../libkvm - -CXXFLAGS = $(autodepend-flags) - -autodepend-flags = -MMD -MF $(dir $*).$(notdir $*).d - -LDFLAGS += -pthread -lrt - -kvmtrace_objs= kvmtrace.o - -kvmctl: $(kvmctl_objs) - $(CC) $(LDFLAGS) $^ -o $@ - -kvmtrace: $(kvmtrace_objs) - $(CC) $(LDFLAGS) $^ -o $@ - -$(libcflat): $(cflatobjs) - $(AR) rcs $@ $^ - -%.o: %.S - $(CC) $(CFLAGS) -c -nostdlib -o $@ $< - --include .*.d - -install: - mkdir -p $(DESTDIR) - install $(tests_and_config) $(DESTDIR) - -clean: arch_clean - $(RM) kvmctl kvmtrace *.o *.a .*.d $(libcflat) $(cflatobjs) diff --git a/kvm/test/README b/kvm/test/README deleted file mode 100644 index 6a8383178..000000000 --- a/kvm/test/README +++ /dev/null @@ -1,23 +0,0 @@ -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 - diff --git a/kvm/test/config-i386.mak b/kvm/test/config-i386.mak deleted file mode 100644 index 6dbd19fd8..000000000 --- a/kvm/test/config-i386.mak +++ /dev/null @@ -1,12 +0,0 @@ -TEST_DIR=x86 -cstart.o = $(TEST_DIR)/cstart.o -bits = 32 -ldarch = elf32-i386 -CFLAGS += -D__i386__ -CFLAGS += -I $(KERNELDIR)/include - -tests = $(TEST_DIR)/taskswitch.flat - -include config-x86-common.mak - -$(TEST_DIR)/taskswitch.flat: $(cstart.o) $(TEST_DIR)/taskswitch.o diff --git a/kvm/test/config-ia64.mak b/kvm/test/config-ia64.mak deleted file mode 100644 index d9350fcc5..000000000 --- a/kvm/test/config-ia64.mak +++ /dev/null @@ -1,7 +0,0 @@ -bits = 64 -CFLAGS += -m64 -CFLAGS += -D__ia64__ -CFLAGS += -I../include/ia64 - -all: - diff --git a/kvm/test/config-powerpc-440.mak b/kvm/test/config-powerpc-440.mak deleted file mode 100644 index bb8597153..000000000 --- a/kvm/test/config-powerpc-440.mak +++ /dev/null @@ -1,15 +0,0 @@ - - -# for some reason binutils hates tlbsx unless we say we're 405 :( -CFLAGS += -Wa,-m405 -I lib/powerpc/44x - -cflatobjs += \ - lib/powerpc/44x/map.o \ - lib/powerpc/44x/tlbwe.o \ - lib/powerpc/44x/timebase.o - -simpletests += \ - powerpc/44x/tlbsx.bin \ - powerpc/44x/tlbwe_16KB.bin \ - powerpc/44x/tlbwe_hole.bin \ - powerpc/44x/tlbwe.bin diff --git a/kvm/test/config-powerpc.mak b/kvm/test/config-powerpc.mak deleted file mode 100644 index d053569b8..000000000 --- a/kvm/test/config-powerpc.mak +++ /dev/null @@ -1,39 +0,0 @@ -CFLAGS += -I../include/powerpc -CFLAGS += -Wa,-mregnames -I lib -CFLAGS += -ffreestanding - -cstart := powerpc/cstart.o - -cflatobjs += \ - lib/powerpc/io.o - -$(libcflat): LDFLAGS += -nostdlib - -# these tests do not use libcflat -simpletests := \ - powerpc/spin.bin \ - powerpc/io.bin \ - powerpc/sprg.bin - -# theses tests use cstart.o, libcflat, and libgcc -tests := \ - powerpc/exit.bin \ - powerpc/helloworld.bin - -include config-powerpc-$(PROCESSOR).mak - - -all: kvmtrace kvmctl $(libcflat) $(simpletests) $(tests) - -$(simpletests): %.bin: %.o - $(CC) -nostdlib $^ -Wl,-T,flat.lds -o $@ - -$(tests): %.bin: $(cstart) %.o $(libcflat) - $(CC) -nostdlib $^ $(libgcc) -Wl,-T,flat.lds -o $@ - -kvmctl_objs = main-ppc.o iotable.o ../libkvm/libkvm.a - -arch_clean: - $(RM) $(simpletests) $(tests) $(cstart) - $(RM) $(patsubst %.bin, %.elf, $(simpletests) $(tests)) - $(RM) $(patsubst %.bin, %.o, $(simpletests) $(tests)) diff --git a/kvm/test/config-x86-common.mak b/kvm/test/config-x86-common.mak deleted file mode 100644 index 19bffd421..000000000 --- a/kvm/test/config-x86-common.mak +++ /dev/null @@ -1,77 +0,0 @@ -#This is a make file with common rules for both x86 & x86-64 - -CFLAGS += -I../include/x86 - -all: test_cases - -cflatobjs += \ - lib/x86/io.o \ - lib/x86/smp.o - -cflatobjs += lib/x86/fwcfg.o -cflatobjs += lib/x86/apic.o - -$(libcflat): LDFLAGS += -nostdlib -$(libcflat): CFLAGS += -ffreestanding -I lib - -CFLAGS += -m$(bits) - -libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name) - -FLATLIBS = lib/libcflat.a $(libgcc) -%.flat: %.o $(FLATLIBS) flat.lds - $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,flat.lds $(filter %.o, $^) $(FLATLIBS) - -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_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat - -tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg - -test_cases: $(tests-common) $(tests) - -$(TEST_DIR)/%.o: CFLAGS += -std=gnu99 -ffreestanding -I lib -I lib/x86 - -$(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)/sieve.flat: $(cstart.o) $(TEST_DIR)/sieve.o \ - $(TEST_DIR)/vm.o - -$(TEST_DIR)/vmexit.flat: $(cstart.o) $(TEST_DIR)/vmexit.o - -$(TEST_DIR)/smptest.flat: $(cstart.o) $(TEST_DIR)/smptest.o - -$(TEST_DIR)/emulator.flat: $(cstart.o) $(TEST_DIR)/emulator.o \ - $(TEST_DIR)/vm.o $(TEST_DIR)/print.o - -$(TEST_DIR)/port80.flat: $(cstart.o) $(TEST_DIR)/port80.o - -$(TEST_DIR)/tsc.flat: $(cstart.o) $(TEST_DIR)/tsc.o - -$(TEST_DIR)/apic.flat: $(cstart.o) $(TEST_DIR)/apic.o $(TEST_DIR)/vm.o \ - $(TEST_DIR)/print.o - -$(TEST_DIR)/realmode.flat: $(TEST_DIR)/realmode.o - $(CC) -m32 -nostdlib -o $@ -Wl,-T,$(TEST_DIR)/realmode.lds $^ - -$(TEST_DIR)/realmode.o: bits = 32 - -$(TEST_DIR)/msr.flat: $(cstart.o) $(TEST_DIR)/msr.o - -$(TEST_DIR)/idt_test.flat: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/idt_test.o - -$(TEST_DIR)/xsave.flat: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/xsave.o - -$(TEST_DIR)/rmap_chain.flat: $(cstart.o) $(TEST_DIR)/rmap_chain.o \ - $(TEST_DIR)/print.o $(TEST_DIR)/vm.o - -$(TEST_DIR)/svm.flat: $(cstart.o) $(TEST_DIR)/vm.o - -arch_clean: - $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat \ - $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o - --include $(TEST_DIR)/.*.d lib/.*.d lib/x86/.*.d diff --git a/kvm/test/config-x86_64.mak b/kvm/test/config-x86_64.mak deleted file mode 100644 index b99cf858b..000000000 --- a/kvm/test/config-x86_64.mak +++ /dev/null @@ -1,12 +0,0 @@ -TEST_DIR=x86 -cstart.o = $(TEST_DIR)/cstart64.o -bits = 64 -ldarch = elf64-x86-64 -CFLAGS += -D__x86_64__ - -tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \ - $(TEST_DIR)/emulator.flat $(TEST_DIR)/idt_test.flat \ - $(TEST_DIR)/xsave.flat $(TEST_DIR)/rmap_chain.flat -tests += $(TEST_DIR)/svm.flat - -include config-x86-common.mak diff --git a/kvm/test/configure b/kvm/test/configure deleted file mode 100755 index efb8705fc..000000000 --- a/kvm/test/configure +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -prefix=/usr/local -kerneldir=/lib/modules/$(uname -r)/build -cc=gcc -ld=ld -objcopy=objcopy -ar=ar -arch=`uname -m | sed -e s/i.86/i386/` -processor="$arch" -cross_prefix= - -usage() { - cat <<-EOF - Usage: $0 [options] - - Options include: - --arch=ARCH architecture to compile for ($arch) - --cross-prefix=PREFIX cross compiler prefix - --cc=CC c compiler to use ($cc) - --ld=LD ld linker to use ($ld) - --prefix=PREFIX where to install things ($prefix) - --kerneldir=DIR kernel build directory for kvm.h ($kerneldir) -EOF - exit 1 -} - -while [[ "$1" = -* ]]; do - opt="$1"; shift - arg= - if [[ "$opt" = *=* ]]; then - arg="${opt#*=}" - opt="${opt%%=*}" - fi - case "$opt" in - --prefix) - prefix="$arg" - ;; - --kerneldir) - kerneldir="$arg" - ;; - --arch) - arch="$arg" - ;; - --processor) - processor="$arg" - ;; - --cross-prefix) - cross_prefix="$arg" - ;; - --cc) - cc="$arg" - ;; - --ld) - ld="$arg" - ;; - --help) - usage - ;; - *) - usage - ;; - esac -done - -cat <<EOF > config.mak -PREFIX=$prefix -KERNELDIR=$(readlink -f $kerneldir) -ARCH=$arch -PROCESSOR=$processor -CC=$cross_prefix$cc -LD=$cross_prefix$ld -OBJCOPY=$cross_prefix$objcopy -AR=$cross_prefix$ar -EOF diff --git a/kvm/test/flat.lds b/kvm/test/flat.lds deleted file mode 100644 index 4888f3a8c..000000000 --- a/kvm/test/flat.lds +++ /dev/null @@ -1,20 +0,0 @@ -SECTIONS -{ - . = 4M + SIZEOF_HEADERS; - stext = .; - .text : { *(.init) *(.text) *(.text.*) } - . = ALIGN(4K); - .data : { - *(.data) - exception_table_start = .; - *(.data.ex) - exception_table_end = .; - } - . = ALIGN(16); - .rodata : { *(.rodata) } - . = ALIGN(16); - .bss : { *(.bss) } - . = ALIGN(4K); - edata = .; -} - diff --git a/kvm/test/formats b/kvm/test/formats deleted file mode 100644 index 7f4ebdbce..000000000 --- a/kvm/test/formats +++ /dev/null @@ -1,31 +0,0 @@ -0x00000000 %(ts)d (+%(relts)12d) unknown (0x%(event)016x) vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x ] - -0x00010001 %(ts)d (+%(relts)12d) VMENTRY vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x -0x00010002 %(ts)d (+%(relts)12d) VMEXIT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ exitcode = 0x%(1)08x, rip = 0x%(3)08x %(2)08x ] -0x00020001 %(ts)d (+%(relts)12d) PAGE_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ] -0x00020002 %(ts)d (+%(relts)12d) INJ_VIRQ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ] -0x00020003 %(ts)d (+%(relts)12d) REDELIVER_EVT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ] -0x00020004 %(ts)d (+%(relts)12d) PEND_INTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ] -0x00020005 %(ts)d (+%(relts)12d) IO_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ] -0x00020006 %(ts)d (+%(relts)12d) IO_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ] -0x00020007 %(ts)d (+%(relts)12d) CR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ] -0x00020008 %(ts)d (+%(relts)12d) CR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ] -0x00020009 %(ts)d (+%(relts)12d) DR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ] -0x0002000A %(ts)d (+%(relts)12d) DR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ] -0x0002000B %(ts)d (+%(relts)12d) MSR_READ vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ] -0x0002000C %(ts)d (+%(relts)12d) MSR_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ] -0x0002000D %(ts)d (+%(relts)12d) CPUID vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ func = 0x%(1)08x, eax = 0x%(2)08x, ebx = 0x%(3)08x, ecx = 0x%(4)08x edx = 0x%(5)08x] -0x0002000E %(ts)d (+%(relts)12d) INTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ vector = 0x%(1)02x ] -0x0002000F %(ts)d (+%(relts)12d) NMI vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x -0x00020010 %(ts)d (+%(relts)12d) VMMCALL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ func = 0x%(1)08x ] -0x00020011 %(ts)d (+%(relts)12d) HLT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x -0x00020012 %(ts)d (+%(relts)12d) CLTS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x -0x00020013 %(ts)d (+%(relts)12d) LMSW vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ value = 0x%(1)08x ] -0x00020014 %(ts)d (+%(relts)12d) APIC_ACCESS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ offset = 0x%(1)08x ] -0x00020015 %(ts)d (+%(relts)12d) TDP_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ] -# ppc: tlb traces -0x00020016 GTLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ] -0x00020017 STLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ] -0x00020018 STLB_INVAL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ] -# ppc: instruction emulation - this type is handled more complex in kvmtrace_format, but listed to show the eventid and transported data -#0x00020019 %(ts)d (+%(relts)12d) PPC_INSTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ] diff --git a/kvm/test/iotable.c b/kvm/test/iotable.c deleted file mode 100644 index 91a5016c4..000000000 --- a/kvm/test/iotable.c +++ /dev/null @@ -1,53 +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. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <errno.h> - -#include "iotable.h" - -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; -} diff --git a/kvm/test/iotable.h b/kvm/test/iotable.h deleted file mode 100644 index cb18f2378..000000000 --- a/kvm/test/iotable.h +++ /dev/null @@ -1,40 +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. - */ - -#include <stdint.h> - -#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]; -}; - -struct io_table_entry *io_table_lookup(struct io_table *io_table, - uint64_t addr); -int io_table_register(struct io_table *io_table, uint64_t start, uint64_t size, - io_table_handler_t *handler, void *opaque); diff --git a/kvm/test/kvmtrace.c b/kvm/test/kvmtrace.c deleted file mode 100644 index de3c1897f..000000000 --- a/kvm/test/kvmtrace.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * kvm tracing application - * - * This tool is used for collecting trace buffer data - * for kvm trace. - * - * Based on blktrace 0.99.3 - * - * Copyright (C) 2005 Jens Axboe <axboe@suse.de> - * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk> - * Copyright (C) 2008 Eric Liu <eric.e.liu@intel.com> - * - * This work is licensed under the GNU LGPL license, version 2. - */ - -#define _GNU_SOURCE - -#include <pthread.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <signal.h> -#include <fcntl.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/param.h> -#include <sys/statfs.h> -#include <sys/poll.h> -#include <sys/mman.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <getopt.h> -#include <errno.h> -#include <sched.h> - -#ifndef __user -#define __user -#endif -#include <linux/kvm.h> - -static char kvmtrace_version[] = "0.1"; - -/* - * You may want to increase this even more, if you are logging at a high - * rate and see skipped/missed events - */ -#define BUF_SIZE (512 * 1024) -#define BUF_NR (8) - -#define OFILE_BUF (128 * 1024) - -#define DEBUGFS_TYPE 0x64626720 - -#define max(a, b) ((a) > (b) ? (a) : (b)) - -#define S_OPTS "r:o:w:?Vb:n:D:" -static struct option l_opts[] = { - { - .name = "relay", - .has_arg = required_argument, - .flag = NULL, - .val = 'r' - }, - { - .name = "output", - .has_arg = required_argument, - .flag = NULL, - .val = 'o' - }, - { - .name = "stopwatch", - .has_arg = required_argument, - .flag = NULL, - .val = 'w' - }, - { - .name = "version", - .has_arg = no_argument, - .flag = NULL, - .val = 'V' - }, - { - .name = "buffer-size", - .has_arg = required_argument, - .flag = NULL, - .val = 'b' - }, - { - .name = "num-sub-buffers", - .has_arg = required_argument, - .flag = NULL, - .val = 'n' - }, - { - .name = "output-dir", - .has_arg = required_argument, - .flag = NULL, - .val = 'D' - }, - { - .name = NULL, - } -}; - -struct thread_information { - int cpu; - pthread_t thread; - - int fd; - char fn[MAXPATHLEN + 64]; - - FILE *ofile; - char *ofile_buffer; - - int (*get_subbuf)(struct thread_information *, unsigned int); - int (*read_data)(struct thread_information *, void *, unsigned int); - - unsigned long long data_read; - - struct kvm_trace_information *trace_info; - - int exited; - - /* - * mmap controlled output files - */ - unsigned long long fs_size; - unsigned long long fs_max_size; - unsigned long fs_off; - void *fs_buf; - unsigned long fs_buf_len; - -}; - -struct kvm_trace_information { - int fd; - volatile int trace_started; - unsigned long lost_records; - struct thread_information *threads; - unsigned long buf_size; - unsigned long buf_nr; -}; - -static struct kvm_trace_information trace_information; - -static int ncpus; -static char default_debugfs_path[] = "/sys/kernel/debug"; - -/* command line option globals */ -static char *debugfs_path; -static char *output_name; -static char *output_dir; -static int stop_watch; -static unsigned long buf_size = BUF_SIZE; -static unsigned long buf_nr = BUF_NR; -static unsigned int page_size; - -#define for_each_cpu_online(cpu) \ - for (cpu = 0; cpu < ncpus; cpu++) -#define for_each_tip(tip, i) \ - for (i = 0, tip = trace_information.threads; i < ncpus; i++, tip++) - -#define is_done() (*(volatile int *)(&done)) -static volatile int done; - -#define is_trace_stopped() (*(volatile int *)(&trace_stopped)) -static volatile int trace_stopped; - -static void exit_trace(int status); - -static void handle_sigint(__attribute__((__unused__)) int sig) -{ - ioctl(trace_information.fd, KVM_TRACE_PAUSE); - done = 1; -} - -static int get_lost_records() -{ - int fd; - char tmp[MAXPATHLEN + 64]; - - snprintf(tmp, sizeof(tmp), "%s/kvm/lost_records", debugfs_path); - fd = open(tmp, O_RDONLY); - if (fd < 0) { - /* - * this may be ok, if the kernel doesn't support dropped counts - */ - if (errno == ENOENT) - return 0; - - fprintf(stderr, "Couldn't open dropped file %s\n", tmp); - return -1; - } - - if (read(fd, tmp, sizeof(tmp)) < 0) { - perror(tmp); - close(fd); - return -1; - } - close(fd); - - return atoi(tmp); -} - -static void wait_for_data(struct thread_information *tip, int timeout) -{ - struct pollfd pfd = { .fd = tip->fd, .events = POLLIN }; - - while (!is_done()) { - if (poll(&pfd, 1, timeout) < 0) { - perror("poll"); - break; - } - if (pfd.revents & POLLIN) - break; - } -} - -static int read_data(struct thread_information *tip, void *buf, - unsigned int len) -{ - int ret = 0; - - do { - wait_for_data(tip, 100); - - ret = read(tip->fd, buf, len); - - if (!ret) - continue; - else if (ret > 0) - return ret; - else { - if (errno != EAGAIN) { - perror(tip->fn); - fprintf(stderr, "Thread %d failed read of %s\n", - tip->cpu, tip->fn); - break; - } - continue; - } - } while (!is_done()); - - return ret; - -} - -/* - * For file output, truncate and mmap the file appropriately - */ -static int mmap_subbuf(struct thread_information *tip, unsigned int maxlen) -{ - int ofd = fileno(tip->ofile); - int ret; - unsigned long nr; - unsigned long size; - - /* - * extend file, if we have to. use chunks of 16 subbuffers. - */ - if (tip->fs_off + maxlen > tip->fs_buf_len) { - if (tip->fs_buf) { - munlock(tip->fs_buf, tip->fs_buf_len); - munmap(tip->fs_buf, tip->fs_buf_len); - tip->fs_buf = NULL; - } - - tip->fs_off = tip->fs_size & (page_size - 1); - nr = max(16, tip->trace_info->buf_nr); - size = tip->trace_info->buf_size; - tip->fs_buf_len = (nr * size) - tip->fs_off; - tip->fs_max_size += tip->fs_buf_len; - - if (ftruncate(ofd, tip->fs_max_size) < 0) { - perror("ftruncate"); - return -1; - } - - tip->fs_buf = mmap(NULL, tip->fs_buf_len, PROT_WRITE, - MAP_SHARED, ofd, tip->fs_size - tip->fs_off); - if (tip->fs_buf == MAP_FAILED) { - perror("mmap"); - return -1; - } - mlock(tip->fs_buf, tip->fs_buf_len); - } - - ret = tip->read_data(tip, tip->fs_buf + tip->fs_off, maxlen); - if (ret >= 0) { - tip->data_read += ret; - tip->fs_size += ret; - tip->fs_off += ret; - return 0; - } - - return -1; -} - -static void tip_ftrunc_final(struct thread_information *tip) -{ - /* - * truncate to right size and cleanup mmap - */ - if (tip->ofile) { - int ofd = fileno(tip->ofile); - - if (tip->fs_buf) - munmap(tip->fs_buf, tip->fs_buf_len); - - ftruncate(ofd, tip->fs_size); - } -} - -static void *thread_main(void *arg) -{ - struct thread_information *tip = arg; - pid_t pid = getpid(); - cpu_set_t cpu_mask; - - CPU_ZERO(&cpu_mask); - CPU_SET((tip->cpu), &cpu_mask); - - if (sched_setaffinity(pid, sizeof(cpu_mask), &cpu_mask) == -1) { - perror("sched_setaffinity"); - exit_trace(1); - } - - snprintf(tip->fn, sizeof(tip->fn), "%s/kvm/trace%d", - debugfs_path, tip->cpu); - tip->fd = open(tip->fn, O_RDONLY); - if (tip->fd < 0) { - perror(tip->fn); - fprintf(stderr, "Thread %d failed open of %s\n", tip->cpu, - tip->fn); - exit_trace(1); - } - while (!is_done()) { - if (tip->get_subbuf(tip, tip->trace_info->buf_size) < 0) - break; - } - - /* - * trace is stopped, pull data until we get a short read - */ - while (tip->get_subbuf(tip, tip->trace_info->buf_size) > 0) - ; - - tip_ftrunc_final(tip); - tip->exited = 1; - return NULL; -} - -static int fill_ofname(struct thread_information *tip, char *dst) -{ - struct stat sb; - int len = 0; - - if (output_dir) - len = sprintf(dst, "%s/", output_dir); - else - len = sprintf(dst, "./"); - - if (stat(dst, &sb) < 0) { - if (errno != ENOENT) { - perror("stat"); - return 1; - } - if (mkdir(dst, 0755) < 0) { - perror(dst); - fprintf(stderr, "Can't make output dir\n"); - return 1; - } - } - - sprintf(dst + len, "%s.kvmtrace.%d", output_name, tip->cpu); - - return 0; -} - -static void fill_ops(struct thread_information *tip) -{ - tip->get_subbuf = mmap_subbuf; - tip->read_data = read_data; -} - -static void close_thread(struct thread_information *tip) -{ - if (tip->fd != -1) - close(tip->fd); - if (tip->ofile) - fclose(tip->ofile); - if (tip->ofile_buffer) - free(tip->ofile_buffer); - - tip->fd = -1; - tip->ofile = NULL; - tip->ofile_buffer = NULL; -} - -static int tip_open_output(struct thread_information *tip) -{ - int mode, vbuf_size; - char op[NAME_MAX]; - - if (fill_ofname(tip, op)) - return 1; - - tip->ofile = fopen(op, "w+"); - mode = _IOFBF; - vbuf_size = OFILE_BUF; - - if (tip->ofile == NULL) { - perror(op); - return 1; - } - - tip->ofile_buffer = malloc(vbuf_size); - if (setvbuf(tip->ofile, tip->ofile_buffer, mode, vbuf_size)) { - perror("setvbuf"); - close_thread(tip); - return 1; - } - - fill_ops(tip); - return 0; -} - -static int start_threads(int cpu) -{ - struct thread_information *tip; - - tip = trace_information.threads + cpu; - tip->cpu = cpu; - tip->trace_info = &trace_information; - tip->fd = -1; - - if (tip_open_output(tip)) - return 1; - - if (pthread_create(&tip->thread, NULL, thread_main, tip)) { - perror("pthread_create"); - close_thread(tip); - return 1; - } - - return 0; -} - -static void stop_threads() -{ - struct thread_information *tip; - unsigned long ret; - int i; - - for_each_tip(tip, i) { - if (tip->thread) - (void) pthread_join(tip->thread, (void *) &ret); - close_thread(tip); - } -} - -static int start_trace(void) -{ - int fd; - struct kvm_user_trace_setup kuts; - - fd = trace_information.fd = open("/dev/kvm", O_RDWR); - if (fd == -1) { - perror("/dev/kvm"); - return 1; - } - - memset(&kuts, 0, sizeof(kuts)); - kuts.buf_size = trace_information.buf_size = buf_size; - kuts.buf_nr = trace_information.buf_nr = buf_nr; - - if (ioctl(trace_information.fd , KVM_TRACE_ENABLE, &kuts) < 0) { - perror("KVM_TRACE_ENABLE"); - close(fd); - return 1; - } - trace_information.trace_started = 1; - - return 0; -} - -static void cleanup_trace(void) -{ - if (trace_information.fd == -1) - return; - - trace_information.lost_records = get_lost_records(); - - if (trace_information.trace_started) { - trace_information.trace_started = 0; - if (ioctl(trace_information.fd, KVM_TRACE_DISABLE) < 0) - perror("KVM_TRACE_DISABLE"); - } - - close(trace_information.fd); - trace_information.fd = -1; -} - -static void stop_all_traces(void) -{ - if (!is_trace_stopped()) { - trace_stopped = 1; - stop_threads(); - cleanup_trace(); - } -} - -static void exit_trace(int status) -{ - stop_all_traces(); - exit(status); -} - -static int start_kvm_trace(void) -{ - int i, size; - struct thread_information *tip; - - size = ncpus * sizeof(struct thread_information); - tip = malloc(size); - if (!tip) { - fprintf(stderr, "Out of memory, threads (%d)\n", size); - return 1; - } - memset(tip, 0, size); - trace_information.threads = tip; - - if (start_trace()) - return 1; - - for_each_cpu_online(i) { - if (start_threads(i)) { - fprintf(stderr, "Failed to start worker threads\n"); - break; - } - } - - if (i != ncpus) { - stop_threads(); - cleanup_trace(); - return 1; - } - - return 0; -} - -static void wait_for_threads(void) -{ - struct thread_information *tip; - int i, tips_running; - - do { - tips_running = 0; - usleep(100000); - - for_each_tip(tip, i) - tips_running += !tip->exited; - - } while (tips_running); -} - -static void show_stats(void) -{ - struct thread_information *tip; - unsigned long long data_read; - int i; - - data_read = 0; - for_each_tip(tip, i) { - printf(" CPU%3d: %8llu KiB data\n", - tip->cpu, (tip->data_read + 1023) >> 10); - data_read += tip->data_read; - } - - printf(" Total: lost %lu, %8llu KiB data\n", - trace_information.lost_records, (data_read + 1023) >> 10); - - if (trace_information.lost_records) - fprintf(stderr, "You have lost records, " - "consider using a larger buffer size (-b)\n"); -} - -static char usage_str[] = \ - "[ -r debugfs path ] [ -D output dir ] [ -b buffer size ]\n" \ - "[ -n number of buffers] [ -o <output file> ] [ -w time ] [ -V ]\n\n" \ - "\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \ - "\t-o File(s) to send output to\n" \ - "\t-D Directory to prepend to output file names\n" \ - "\t-w Stop after defined time, in seconds\n" \ - "\t-b Sub buffer size in KiB\n" \ - "\t-n Number of sub buffers\n" \ - "\t-V Print program version info\n\n"; - -static void show_usage(char *prog) -{ - fprintf(stderr, "Usage: %s %s %s", prog, kvmtrace_version, usage_str); - exit(EXIT_FAILURE); -} - -void parse_args(int argc, char **argv) -{ - int c; - - while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) >= 0) { - switch (c) { - case 'r': - debugfs_path = optarg; - break; - case 'o': - output_name = optarg; - break; - case 'w': - stop_watch = atoi(optarg); - if (stop_watch <= 0) { - fprintf(stderr, - "Invalid stopwatch value (%d secs)\n", - stop_watch); - exit(EXIT_FAILURE); - } - break; - case 'V': - printf("%s version %s\n", argv[0], kvmtrace_version); - exit(EXIT_SUCCESS); - case 'b': - buf_size = strtoul(optarg, NULL, 10); - if (buf_size <= 0 || buf_size > 16*1024) { - fprintf(stderr, - "Invalid buffer size (%lu)\n", - buf_size); - exit(EXIT_FAILURE); - } - buf_size <<= 10; - break; - case 'n': - buf_nr = strtoul(optarg, NULL, 10); - if (buf_nr <= 0) { - fprintf(stderr, - "Invalid buffer nr (%lu)\n", buf_nr); - exit(EXIT_FAILURE); - } - break; - case 'D': - output_dir = optarg; - break; - default: - show_usage(argv[0]); - } - } - - if (optind < argc || output_name == NULL) - show_usage(argv[0]); -} - -int main(int argc, char *argv[]) -{ - struct statfs st; - - parse_args(argc, argv); - - if (!debugfs_path) - debugfs_path = default_debugfs_path; - - if (statfs(debugfs_path, &st) < 0) { - perror("statfs"); - fprintf(stderr, "%s does not appear to be a valid path\n", - debugfs_path); - return 1; - } else if (st.f_type != (long) DEBUGFS_TYPE) { - fprintf(stderr, "%s does not appear to be a debug filesystem," - " please mount debugfs.\n", - debugfs_path); - return 1; - } - - page_size = getpagesize(); - - ncpus = sysconf(_SC_NPROCESSORS_ONLN); - if (ncpus < 0) { - fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed\n"); - return 1; - } - - signal(SIGINT, handle_sigint); - signal(SIGHUP, handle_sigint); - signal(SIGTERM, handle_sigint); - signal(SIGALRM, handle_sigint); - signal(SIGPIPE, SIG_IGN); - - if (start_kvm_trace() != 0) - return 1; - - if (stop_watch) - alarm(stop_watch); - - wait_for_threads(); - stop_all_traces(); - show_stats(); - - return 0; -} diff --git a/kvm/test/kvmtrace_format b/kvm/test/kvmtrace_format deleted file mode 100755 index 6556475f7..000000000 --- a/kvm/test/kvmtrace_format +++ /dev/null @@ -1,532 +0,0 @@ -#!/usr/bin/env python - -# by Mark Williamson, (C) 2004 Intel Research Cambridge - -# Program for reformatting trace buffer output according to user-supplied rules - -import re, sys, string, signal, struct, os, getopt, operator - -PREFIX = '/usr' -DATADIR = os.path.join(PREFIX, 'share') -KVMDIR = os.path.join(DATADIR, 'kvm') -FORMATS_FILE = os.path.join(KVMDIR, 'formats') - -def usage(): - print >> sys.stderr, \ - "Usage: " + sys.argv[0] + """ defs-file - Parses trace data in binary format, as output by kvmtrace and - reformats it according to the rules in a file of definitions. The - rules in this file should have the format ({ and } show grouping - and are not part of the syntax): - - {event_id}{whitespace}{text format string} - - The textual format string may include format specifiers, such as: - %(ts)d, %(event)d, %(pid)d %(vcpu)d %(1)d, %(2)d, - %(3)d, %(4)d, %(5)d - [ the 'd' format specifier outputs in decimal, alternatively 'x' - will output in hexadecimal and 'o' will output in octal ] - - Which correspond to the event ID, timestamp counter, pid - , vcpu and the 5 data fields from the trace record. There should be - one such rule for each type of event. - Depending on your system and the volume of trace buffer data, - this script may not be able to keep up with the output of kvmtrace - if it is piped directly. In these circumstances you should have - kvmtrace output to a file for processing off-line. - - kvmtrace_format has the following additional switches - -s - if this switch is set additional trace statistics are - created and printed at the end of the output - """ - sys.exit(1) - -def read_defs(defs_file): - defs = {} - - fd = open(defs_file) - - reg = re.compile('(\S+)\s+(\S.*)') - - while True: - line = fd.readline() - if not line: - break - - if line[0] == '#' or line[0] == '\n': - continue - - m = reg.match(line) - - if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1) - - defs[str(eval(m.group(1)))] = m.group(2) - - return defs - -def sighand(x,y): - global interrupted - interrupted = 1 - -# ppc instruction decoding for event type 0x00020019 (PPC_INSTR) -# some globals for statistic summaries -stat_ppc_instr_mnemonic = {}; -stat_ppc_instr_spr = {}; -stat_ppc_instr_dcr = {}; -stat_ppc_instr_tlb = {}; - -def ppc_instr_print_summary(sortedlist, colname): - print "\n\n%14s + %10s" % (colname, "count") - print "%s" % (15*"-"+"+"+11*"-") - sum = 0 - for value, key in sortedlist: - sum += key - print "%14s | %10d" % (value, key) - print "%14s = %10d" % ("sum", sum) - - -def ppc_instr_summary(): - # don't print empty statistics - if stat_ppc_instr_mnemonic: - ppc_instr_print_summary(sorted(stat_ppc_instr_mnemonic.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic") - if stat_ppc_instr_spr: - ppc_instr_print_summary(sorted(stat_ppc_instr_spr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-spr") - if stat_ppc_instr_dcr: - ppc_instr_print_summary(sorted(stat_ppc_instr_dcr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-dcr") - if stat_ppc_instr_tlb: - ppc_instr_print_summary(sorted(stat_ppc_instr_tlb.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-tlb") - -def get_op(instr): - return (instr >> 26); - -def get_xop(instr): - return (instr >> 1) & 0x3ff; - -def get_sprn(instr): - return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0) - -def get_dcrn(instr): - return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); - -def get_tlbwe_type(instr): - ws = (instr >> 11) & 0x1f; - if ws == 0: - return "PAGEID" - elif ws == 1: - return "XLAT" - elif ws == 2: - return "ATTRIB" - else: - return "UNKNOWN" - -def get_name(instr): - if get_op(instr)==3: - return "trap" - elif get_op(instr)==19: - if get_xop(instr) == 50: - return "rfi" - else: - return "unknown" - elif get_op(instr)==31: - if get_xop(instr) == 83: - return "mfmsr" - - elif get_xop(instr) == 87: - return "lbzx" - - elif get_xop(instr) == 131: - return "wrtee" - - elif get_xop(instr) == 146: - return "mtmsr" - - elif get_xop(instr) == 163: - return "wrteei" - - elif get_xop(instr) == 215: - return "stbx" - - elif get_xop(instr) == 247: - return "stbux" - - elif get_xop(instr) == 279: - return "lhzx" - - elif get_xop(instr) == 311: - return "lhzux" - - elif get_xop(instr) == 323: - return "mfdcr" - - elif get_xop(instr) == 339: - return "mfspr" - - elif get_xop(instr) == 407: - return "sthx" - - elif get_xop(instr) == 439: - return "sthux" - - elif get_xop(instr) == 451: - return "mtdcr" - - elif get_xop(instr) == 467: - return "mtspr" - - elif get_xop(instr) == 470: - return "dcbi" - - elif get_xop(instr) == 534: - return "lwbrx" - - elif get_xop(instr) == 566: - return "tlbsync" - - elif get_xop(instr) == 662: - return "stwbrx" - - elif get_xop(instr) == 978: - return "tlbwe" - - elif get_xop(instr) == 914: - return "tlbsx" - - elif get_xop(instr) == 790: - return "lhbrx" - - elif get_xop(instr) == 918: - return "sthbrx" - - elif get_xop(instr) == 966: - return "iccci" - - else: - return "unknown" - - elif get_op(instr) == 32: - return "lwz" - - elif get_op(instr) == 33: - return "lwzu" - - elif get_op(instr) == 34: - return "lbz" - - elif get_op(instr) == 35: - return "lbzu" - - elif get_op(instr) == 36: - return "stw" - - elif get_op(instr) == 37: - return "stwu" - - elif get_op(instr) == 38: - return "stb" - - elif get_op(instr) == 39: - return "stbu" - - elif get_op(instr) == 40: - return "lhz" - - elif get_op(instr) == 41: - return "lhzu" - - elif get_op(instr) == 44: - return "sth" - - elif get_op(instr) == 45: - return "sthu" - - else: - return "unknown" - -def get_sprn_name(sprn): - if sprn == 0x01a: - return "SRR0" - elif sprn == 0x01b: - return "SRR1" - elif sprn == 0x3b2: - return "MMUCR" - elif sprn == 0x030: - return "PID" - elif sprn == 0x03f: - return "IVPR" - elif sprn == 0x3b3: - return "CCR0" - elif sprn == 0x378: - return "CCR1" - elif sprn == 0x11f: - return "PVR" - elif sprn == 0x03d: - return "DEAR" - elif sprn == 0x03e: - return "ESR" - elif sprn == 0x134: - return "DBCR0" - elif sprn == 0x135: - return "DBCR1" - elif sprn == 0x11c: - return "TBWL" - elif sprn == 0x11d: - return "TBWU" - elif sprn == 0x016: - return "DEC" - elif sprn == 0x150: - return "TSR" - elif sprn == 0x154: - return "TCR" - elif sprn == 0x110: - return "SPRG0" - elif sprn == 0x111: - return "SPRG1" - elif sprn == 0x112: - return "SPRG2" - elif sprn == 0x113: - return "SPRG3" - elif sprn == 0x114: - return "SPRG4" - elif sprn == 0x115: - return "SPRG5" - elif sprn == 0x116: - return "SPRG6" - elif sprn == 0x117: - return "SPRG7" - elif sprn == 0x190: - return "IVOR0" - elif sprn == 0x191: - return "IVOR1" - elif sprn == 0x192: - return "IVOR2" - elif sprn == 0x193: - return "IVOR3" - elif sprn == 0x194: - return "IVOR4" - elif sprn == 0x195: - return "IVOR5" - elif sprn == 0x196: - return "IVOR6" - elif sprn == 0x197: - return "IVOR7" - elif sprn == 0x198: - return "IVOR8" - elif sprn == 0x199: - return "IVOR9" - elif sprn == 0x19a: - return "IVOR10" - elif sprn == 0x19b: - return "IVOR11" - elif sprn == 0x19c: - return "IVOR12" - elif sprn == 0x19d: - return "IVOR13" - elif sprn == 0x19e: - return "IVOR14" - elif sprn == 0x19f: - return "IVOR15" - else: - return "UNKNOWN" - -def get_special(instr): - name = get_name(instr); - if stat_ppc_instr_mnemonic.has_key(name): - stat_ppc_instr_mnemonic[name] += 1 - else: - stat_ppc_instr_mnemonic[name] = 1 - - if get_op(instr) == 31: - if (get_xop(instr) == 339) or (get_xop(instr) == 467): - sprn = get_sprn(instr); - sprn_name = get_sprn_name(sprn); - stat_idx = name+"-"+sprn_name - if stat_ppc_instr_spr.has_key(stat_idx): - stat_ppc_instr_spr[stat_idx] += 1 - else: - stat_ppc_instr_spr[stat_idx] = 1 - return ("- sprn 0x%03x %8s" % (sprn, sprn_name)) - elif (get_xop(instr) == 323 ) or (get_xop(instr) == 451): - dcrn = get_dcrn(instr); - stat_idx = name+"-"+("%04X"%dcrn) - if stat_ppc_instr_dcr.has_key(stat_idx): - stat_ppc_instr_dcr[stat_idx] += 1 - else: - stat_ppc_instr_dcr[stat_idx] = 1 - return ("- dcrn 0x%03x" % dcrn) - elif (get_xop(instr) == 978 ) or (get_xop(instr) == 451): - tlbwe_type = get_tlbwe_type(instr) - stat_idx = name+"-"+tlbwe_type - if stat_ppc_instr_tlb.has_key(stat_idx): - stat_ppc_instr_tlb[stat_idx] += 1 - else: - stat_ppc_instr_tlb[stat_idx] = 1 - return ("- ws -> %8s" % tlbwe_type) - return "" - -##### Main code - -summary = False - -try: - opts, arg = getopt.getopt(sys.argv[1:], "sc:" ) - for opt in opts: - if opt[0] == '-s' : summary = True - -except getopt.GetoptError: - usage() - -signal.signal(signal.SIGTERM, sighand) -signal.signal(signal.SIGHUP, sighand) -signal.signal(signal.SIGINT, sighand) - -interrupted = 0 - -if len(arg) > 0: - defs = read_defs(arg[0]) -else: - defs = read_defs(FORMATS_FILE) - -# structure of trace record (as output by kvmtrace): -# HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I) -# -# HDR consists of EVENT:28:, n_data:3:, ts_in:1: -# pid:32, vcpu_id:32 -# EVENT means Event ID -# n_data means number of data (like D1, D2, ...) -# ts_in means Timestamp data exists(1) or not(0). -# if ts_in == 0, TSC(Q) does not exists. -# -HDRREC = "<III" -TSCREC = "<Q" -D1REC = "<I" -D2REC = "<II" -D3REC = "<III" -D4REC = "<IIII" -D5REC = "<IIIII" -KMAGIC = "<I" - -last_ts = 0 - -i=0 - -while not interrupted: - try: - i=i+1 - - if i == 1: - line = sys.stdin.read(struct.calcsize(KMAGIC)) - if not line: - break - kmgc = struct.unpack(KMAGIC, line)[0] - - #firstly try to parse data file as little endian - # if "kvmtrace-metadata".kmagic != kmagic - # then data file must be big endian" - if kmgc != 0x12345678: - if kmgc != 0x78563412: - print >> sys.stderr, "Bad data file: magic number error." - break; - else: - HDRREC = ">III" - TSCREC = ">Q" - D1REC = ">I" - D2REC = ">II" - D3REC = ">III" - D4REC = ">IIII" - D5REC = ">IIIII" - continue - - line = sys.stdin.read(struct.calcsize(HDRREC)) - if not line: - break - (event, pid, vcpu_id) = struct.unpack(HDRREC, line) - - n_data = event >> 28 & 0x7 - ts_in = event >> 31 - - d1 = 0 - d2 = 0 - d3 = 0 - d4 = 0 - d5 = 0 - - ts = 0 - - if ts_in == 1: - line = sys.stdin.read(struct.calcsize(TSCREC)) - if not line: - break - ts = struct.unpack(TSCREC, line)[0] - if n_data == 1: - line = sys.stdin.read(struct.calcsize(D1REC)) - if not line: - break - d1 = struct.unpack(D1REC, line)[0] - if n_data == 2: - line = sys.stdin.read(struct.calcsize(D2REC)) - if not line: - break - (d1, d2) = struct.unpack(D2REC, line) - if n_data == 3: - line = sys.stdin.read(struct.calcsize(D3REC)) - if not line: - break - (d1, d2, d3) = struct.unpack(D3REC, line) - if n_data == 4: - line = sys.stdin.read(struct.calcsize(D4REC)) - if not line: - break - (d1, d2, d3, d4) = struct.unpack(D4REC, line) - if n_data == 5: - line = sys.stdin.read(struct.calcsize(D5REC)) - if not line: - break - (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line) - - event &= 0x0fffffff - - # provide relative TSC - - if last_ts > 0 and ts_in == 1: - relts = ts - last_ts - else: - relts = 0 - - if ts_in == 1: - last_ts = ts - - args = {'ts' : ts, - 'event' : event, - 'relts': relts, - 'pid' : pid, - 'vcpu' : vcpu_id, - '1' : d1, - '2' : d2, - '3' : d3, - '4' : d4, - '5' : d5 } - - # some event types need more than just formats mapping they are if/elif - # chained here and the last default else is the mapping via formats - if event == 0x00020019: - pdata = (ts, relts, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1)) - print "%d (+%12d) PPC_INSTR vcpu = 0x%08x pid = 0x%08x [ instr = 0x%08x, pc = 0x%08x, emul = %01d, mnemonic = %8s %s" % pdata - else: - try: - if defs.has_key(str(event)): - print defs[str(event)] % args - else: - if defs.has_key(str(0)): print defs[str(0)] % args - except TypeError: - if defs.has_key(str(event)): - print defs[str(event)] - print args - else: - if defs.has_key(str(0)): - print defs[str(0)] - print args - - except IOError, struct.error: sys.exit() - -if summary: - ppc_instr_summary() diff --git a/kvm/test/lib/libcflat.h b/kvm/test/lib/libcflat.h deleted file mode 100644 index d0d3df2ea..000000000 --- a/kvm/test/lib/libcflat.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -#ifndef __LIBCFLAT_H -#define __LIBCFLAT_H - -#include <stdarg.h> - -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned u32; -typedef unsigned long ulong; -typedef unsigned long long u64; -typedef unsigned long size_t; -typedef _Bool bool; - -#define true 1 -#define false 0 - -extern void exit(int code); -extern void panic(char *fmt, ...); - -extern unsigned long strlen(const char *buf); -extern char *strcat(char *dest, const char *src); - -extern int printf(const char *fmt, ...); -extern int vsnprintf(char *buf, int size, const char *fmt, va_list va); - -extern void puts(const char *s); - -extern void *memset(void *s, int c, size_t n); - -#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0])) - -#endif diff --git a/kvm/test/lib/panic.c b/kvm/test/lib/panic.c deleted file mode 100644 index 6e0b29ebe..000000000 --- a/kvm/test/lib/panic.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "libcflat.h" - -void panic(char *fmt, ...) -{ - va_list va; - char buf[2000]; - - va_start(va, fmt); - vsnprintf(buf, sizeof(buf), fmt, va); - va_end(va); - puts(buf); - exit(-1); -} diff --git a/kvm/test/lib/powerpc/44x/map.c b/kvm/test/lib/powerpc/44x/map.c deleted file mode 100644 index 113434d2f..000000000 --- a/kvm/test/lib/powerpc/44x/map.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -#include "libcflat.h" - -#define TLB_SIZE 64 - -extern void tlbwe(unsigned int index, - unsigned char tid, - unsigned int word0, - unsigned int word1, - unsigned int word2); - -unsigned int next_free_index; - -#define PAGE_SHIFT 12 -#define PAGE_MASK (~((1<<PAGE_SHIFT)-1)) - -#define V (1<<9) - -void map(unsigned long vaddr, unsigned long paddr) -{ - unsigned int w0, w1, w2; - - /* We don't install exception handlers, so we can't handle TLB misses, - * so we can't loop around and overwrite entry 0. */ - if (next_free_index++ >= TLB_SIZE) - panic("TLB overflow"); - - w0 = (vaddr & PAGE_MASK) | V; - w1 = paddr & PAGE_MASK; - w2 = 0x3; - - tlbwe(next_free_index, 0, w0, w1, w2); -} diff --git a/kvm/test/lib/powerpc/44x/timebase.S b/kvm/test/lib/powerpc/44x/timebase.S deleted file mode 100644 index 385904da3..000000000 --- a/kvm/test/lib/powerpc/44x/timebase.S +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -/* unsigned long long mftb(void); */ -.global mftb -mftb: - mftbu r5 - mftbl r4 - mftbu r3 - cmpw r3, r5 - bne mftb - blr diff --git a/kvm/test/lib/powerpc/44x/timebase.h b/kvm/test/lib/powerpc/44x/timebase.h deleted file mode 100644 index ce85347bd..000000000 --- a/kvm/test/lib/powerpc/44x/timebase.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -#ifndef __TIMEBASE_H__ -#define __TIMEBASE_H__ - -unsigned long long mftb(void); - -#endif /* __TIMEBASE_H__ */ diff --git a/kvm/test/lib/powerpc/44x/tlbwe.S b/kvm/test/lib/powerpc/44x/tlbwe.S deleted file mode 100644 index 3790374eb..000000000 --- a/kvm/test/lib/powerpc/44x/tlbwe.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -#define SPRN_MMUCR 0x3b2 - -/* tlbwe(uint index, uint8_t tid, uint word0, uint word1, uint word2) */ -.global tlbwe -tlbwe: - mtspr SPRN_MMUCR, r4 - tlbwe r5, r3, 0 - tlbwe r6, r3, 1 - tlbwe r7, r3, 2 - blr diff --git a/kvm/test/lib/powerpc/io.c b/kvm/test/lib/powerpc/io.c deleted file mode 100644 index 8bd239521..000000000 --- a/kvm/test/lib/powerpc/io.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -#include "libcflat.h" - -#define BASE 0xf0000000 -#define _putc ((volatile char *)(BASE)) -#define _exit ((volatile char *)(BASE+1)) - -void puts(const char *s) -{ - while (*s != '\0') - *_putc = *s++; -} - -void exit(int code) -{ - *_exit = code; -} diff --git a/kvm/test/lib/printf.c b/kvm/test/lib/printf.c deleted file mode 100644 index 3bb9e3d74..000000000 --- a/kvm/test/lib/printf.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "libcflat.h" - -typedef struct pstream { - char *buffer; - int remain; - int added; -} pstream_t; - -static void addchar(pstream_t *p, char c) -{ - if (p->remain) { - *p->buffer++ = c; - --p->remain; - } - ++p->added; -} - -void print_str(pstream_t *p, const char *s) -{ - while (*s) - addchar(p, *s++); -} - -static char digits[16] = "0123456789abcdef"; - -void print_int(pstream_t *ps, long long n, int base) -{ - char buf[sizeof(long) * 3 + 2], *p = buf; - int s = 0, i; - - if (n < 0) { - n = -n; - s = 1; - } - - while (n) { - *p++ = digits[n % base]; - n /= base; - } - - if (s) - *p++ = '-'; - - if (p == buf) - *p++ = '0'; - - for (i = 0; i < (p - buf) / 2; ++i) { - char tmp; - - tmp = buf[i]; - buf[i] = p[-1-i]; - p[-1-i] = tmp; - } - - *p = 0; - - print_str(ps, buf); -} - -void print_unsigned(pstream_t *ps, unsigned long long n, int base) -{ - char buf[sizeof(long) * 3 + 1], *p = buf; - int i; - - while (n) { - *p++ = digits[n % base]; - n /= base; - } - - if (p == buf) - *p++ = '0'; - - for (i = 0; i < (p - buf) / 2; ++i) { - char tmp; - - tmp = buf[i]; - buf[i] = p[-1-i]; - p[-1-i] = tmp; - } - - *p = 0; - - print_str(ps, buf); -} - -int vsnprintf(char *buf, int size, const char *fmt, va_list va) -{ - pstream_t s; - - s.buffer = buf; - s.remain = size - 1; - s.added = 0; - while (*fmt) { - char f = *fmt++; - int nlong = 0; - - if (f != '%') { - addchar(&s, f); - continue; - } - morefmt: - f = *fmt++; - switch (f) { - case '%': - addchar(&s, '%'); - break; - case '\0': - --fmt; - break; - case 'l': - ++nlong; - goto morefmt; - case 'd': - switch (nlong) { - case 0: - print_int(&s, va_arg(va, int), 10); - break; - case 1: - print_int(&s, va_arg(va, long), 10); - break; - default: - print_int(&s, va_arg(va, long long), 10); - break; - } - break; - case 'x': - switch (nlong) { - case 0: - print_unsigned(&s, va_arg(va, unsigned), 16); - break; - case 1: - print_unsigned(&s, va_arg(va, unsigned long), 16); - break; - default: - print_unsigned(&s, va_arg(va, unsigned long long), 16); - break; - } - break; - case 'p': - print_str(&s, "0x"); - print_unsigned(&s, (unsigned long)va_arg(va, void *), 16); - break; - case 's': - print_str(&s, va_arg(va, const char *)); - break; - default: - addchar(&s, f); - break; - } - } - *s.buffer = 0; - ++s.added; - return s.added; -} - - -int snprintf(char *buf, int size, const char *fmt, ...) -{ - va_list va; - int r; - - va_start(va, fmt); - r = vsnprintf(buf, size, fmt, va); - va_end(va); - return r; -} - -int printf(const char *fmt, ...) -{ - va_list va; - char buf[2000]; - int r; - - va_start(va, fmt); - r = vsnprintf(buf, sizeof buf, fmt, va); - va_end(va); - puts(buf); - return r; -} diff --git a/kvm/test/lib/string.c b/kvm/test/lib/string.c deleted file mode 100644 index acac3c053..000000000 --- a/kvm/test/lib/string.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "libcflat.h" - -unsigned long strlen(const char *buf) -{ - unsigned long len = 0; - - while (*buf++) - ++len; - return len; -} - -char *strcat(char *dest, const char *src) -{ - char *p = dest; - - while (*p) - ++p; - while ((*p++ = *src++) != 0) - ; - return dest; -} - -void *memset(void *s, int c, size_t n) -{ - size_t i; - char *a = s; - - for (i = 0; i < n; ++i) - a[i] = c; - - return s; -} diff --git a/kvm/test/lib/x86/apic-defs.h b/kvm/test/lib/x86/apic-defs.h deleted file mode 100644 index c061e3d4a..000000000 --- a/kvm/test/lib/x86/apic-defs.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef _ASM_X86_APICDEF_H -#define _ASM_X86_APICDEF_H - -/* - * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) - * - * Alan Cox <Alan.Cox@linux.org>, 1995. - * Ingo Molnar <mingo@redhat.com>, 1999, 2000 - */ - -#define APIC_DEFAULT_PHYS_BASE 0xfee00000 - -#define APIC_ID 0x20 - -#define APIC_LVR 0x30 -#define APIC_LVR_MASK 0xFF00FF -#define GET_APIC_VERSION(x) ((x) & 0xFFu) -#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu) -#ifdef CONFIG_X86_32 -# define APIC_INTEGRATED(x) ((x) & 0xF0u) -#else -# define APIC_INTEGRATED(x) (1) -#endif -#define APIC_XAPIC(x) ((x) >= 0x14) -#define APIC_TASKPRI 0x80 -#define APIC_TPRI_MASK 0xFFu -#define APIC_ARBPRI 0x90 -#define APIC_ARBPRI_MASK 0xFFu -#define APIC_PROCPRI 0xA0 -#define APIC_EOI 0xB0 -#define APIC_EIO_ACK 0x0 -#define APIC_RRR 0xC0 -#define APIC_LDR 0xD0 -#define APIC_LDR_MASK (0xFFu << 24) -#define GET_APIC_LOGICAL_ID(x) (((x) >> 24) & 0xFFu) -#define SET_APIC_LOGICAL_ID(x) (((x) << 24)) -#define APIC_ALL_CPUS 0xFFu -#define APIC_DFR 0xE0 -#define APIC_DFR_CLUSTER 0x0FFFFFFFul -#define APIC_DFR_FLAT 0xFFFFFFFFul -#define APIC_SPIV 0xF0 -#define APIC_SPIV_FOCUS_DISABLED (1 << 9) -#define APIC_SPIV_APIC_ENABLED (1 << 8) -#define APIC_ISR 0x100 -#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */ -#define APIC_TMR 0x180 -#define APIC_IRR 0x200 -#define APIC_ESR 0x280 -#define APIC_ESR_SEND_CS 0x00001 -#define APIC_ESR_RECV_CS 0x00002 -#define APIC_ESR_SEND_ACC 0x00004 -#define APIC_ESR_RECV_ACC 0x00008 -#define APIC_ESR_SENDILL 0x00020 -#define APIC_ESR_RECVILL 0x00040 -#define APIC_ESR_ILLREGA 0x00080 -#define APIC_ICR 0x300 -#define APIC_DEST_SELF 0x40000 -#define APIC_DEST_ALLINC 0x80000 -#define APIC_DEST_ALLBUT 0xC0000 -#define APIC_ICR_RR_MASK 0x30000 -#define APIC_ICR_RR_INVALID 0x00000 -#define APIC_ICR_RR_INPROG 0x10000 -#define APIC_ICR_RR_VALID 0x20000 -#define APIC_INT_LEVELTRIG 0x08000 -#define APIC_INT_ASSERT 0x04000 -#define APIC_ICR_BUSY 0x01000 -#define APIC_DEST_LOGICAL 0x00800 -#define APIC_DEST_PHYSICAL 0x00000 -#define APIC_DM_FIXED 0x00000 -#define APIC_DM_LOWEST 0x00100 -#define APIC_DM_SMI 0x00200 -#define APIC_DM_REMRD 0x00300 -#define APIC_DM_NMI 0x00400 -#define APIC_DM_INIT 0x00500 -#define APIC_DM_STARTUP 0x00600 -#define APIC_DM_EXTINT 0x00700 -#define APIC_VECTOR_MASK 0x000FF -#define APIC_ICR2 0x310 -#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF) -#define SET_APIC_DEST_FIELD(x) ((x) << 24) -#define APIC_LVTT 0x320 -#define APIC_LVTTHMR 0x330 -#define APIC_LVTPC 0x340 -#define APIC_LVT0 0x350 -#define APIC_LVT_TIMER_BASE_MASK (0x3 << 18) -#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3) -#define SET_APIC_TIMER_BASE(x) (((x) << 18)) -#define APIC_TIMER_BASE_CLKIN 0x0 -#define APIC_TIMER_BASE_TMBASE 0x1 -#define APIC_TIMER_BASE_DIV 0x2 -#define APIC_LVT_TIMER_PERIODIC (1 << 17) -#define APIC_LVT_MASKED (1 << 16) -#define APIC_LVT_LEVEL_TRIGGER (1 << 15) -#define APIC_LVT_REMOTE_IRR (1 << 14) -#define APIC_INPUT_POLARITY (1 << 13) -#define APIC_SEND_PENDING (1 << 12) -#define APIC_MODE_MASK 0x700 -#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7) -#define SET_APIC_DELIVERY_MODE(x, y) (((x) & ~0x700) | ((y) << 8)) -#define APIC_MODE_FIXED 0x0 -#define APIC_MODE_NMI 0x4 -#define APIC_MODE_EXTINT 0x7 -#define APIC_LVT1 0x360 -#define APIC_LVTERR 0x370 -#define APIC_TMICT 0x380 -#define APIC_TMCCT 0x390 -#define APIC_TDCR 0x3E0 -#define APIC_SELF_IPI 0x3F0 -#define APIC_TDR_DIV_TMBASE (1 << 2) -#define APIC_TDR_DIV_1 0xB -#define APIC_TDR_DIV_2 0x0 -#define APIC_TDR_DIV_4 0x1 -#define APIC_TDR_DIV_8 0x2 -#define APIC_TDR_DIV_16 0x3 -#define APIC_TDR_DIV_32 0x8 -#define APIC_TDR_DIV_64 0x9 -#define APIC_TDR_DIV_128 0xA -#define APIC_EILVT0 0x500 -#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */ -#define APIC_EILVT_NR_AMD_10H 4 -#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF) -#define APIC_EILVT_MSG_FIX 0x0 -#define APIC_EILVT_MSG_SMI 0x2 -#define APIC_EILVT_MSG_NMI 0x4 -#define APIC_EILVT_MSG_EXT 0x7 -#define APIC_EILVT_MASKED (1 << 16) -#define APIC_EILVT1 0x510 -#define APIC_EILVT2 0x520 -#define APIC_EILVT3 0x530 - -#define APIC_BASE_MSR 0x800 - -#endif /* _ASM_X86_APICDEF_H */ diff --git a/kvm/test/lib/x86/apic.c b/kvm/test/lib/x86/apic.c deleted file mode 100644 index 7bb98ed34..000000000 --- a/kvm/test/lib/x86/apic.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "libcflat.h" -#include "apic.h" - -static void *g_apic = (void *)0xfee00000; -static void *g_ioapic = (void *)0xfec00000; - -struct apic_ops { - u32 (*reg_read)(unsigned reg); - void (*reg_write)(unsigned reg, u32 val); - void (*icr_write)(u32 val, u32 dest); - u32 (*id)(void); -}; - -static void outb(unsigned char data, unsigned short port) -{ - asm volatile ("out %0, %1" : : "a"(data), "d"(port)); -} - -static u32 xapic_read(unsigned reg) -{ - return *(volatile u32 *)(g_apic + reg); -} - -static void xapic_write(unsigned reg, u32 val) -{ - *(volatile u32 *)(g_apic + reg) = val; -} - -static void xapic_icr_write(u32 val, u32 dest) -{ - while (xapic_read(APIC_ICR) & APIC_ICR_BUSY) - ; - xapic_write(APIC_ICR2, dest << 24); - xapic_write(APIC_ICR, val); -} - -static uint32_t xapic_id(void) -{ - return xapic_read(APIC_ID) >> 24; -} - -static const struct apic_ops xapic_ops = { - .reg_read = xapic_read, - .reg_write = xapic_write, - .icr_write = xapic_icr_write, - .id = xapic_id, -}; - -static const struct apic_ops *apic_ops = &xapic_ops; - -static u32 x2apic_read(unsigned reg) -{ - unsigned a, d; - - asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(APIC_BASE_MSR + reg/16)); - return a | (u64)d << 32; -} - -static void x2apic_write(unsigned reg, u32 val) -{ - asm volatile ("wrmsr" : : "a"(val), "d"(0), "c"(APIC_BASE_MSR + reg/16)); -} - -static void x2apic_icr_write(u32 val, u32 dest) -{ - asm volatile ("wrmsr" : : "a"(val), "d"(dest), - "c"(APIC_BASE_MSR + APIC_ICR/16)); -} - -static uint32_t x2apic_id(void) -{ - return xapic_read(APIC_ID); -} - -static const struct apic_ops x2apic_ops = { - .reg_read = x2apic_read, - .reg_write = x2apic_write, - .icr_write = x2apic_icr_write, - .id = x2apic_id, -}; - -u32 apic_read(unsigned reg) -{ - return apic_ops->reg_read(reg); -} - -void apic_write(unsigned reg, u32 val) -{ - apic_ops->reg_write(reg, val); -} - -void apic_icr_write(u32 val, u32 dest) -{ - apic_ops->icr_write(val, dest); -} - -uint32_t apic_id(void) -{ - return apic_ops->id(); -} - -#define MSR_APIC_BASE 0x0000001b - -int enable_x2apic(void) -{ - unsigned a, b, c, d; - - asm ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1)); - - if (c & (1 << 21)) { - asm ("rdmsr" : "=a"(a), "=d"(d) : "c"(MSR_APIC_BASE)); - a |= 1 << 10; - asm ("wrmsr" : : "a"(a), "d"(d), "c"(MSR_APIC_BASE)); - apic_ops = &x2apic_ops; - return 1; - } else { - return 0; - } -} - -void ioapic_write_reg(unsigned reg, u32 value) -{ - *(volatile u32 *)g_ioapic = reg; - *(volatile u32 *)(g_ioapic + 0x10) = value; -} - -void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e) -{ - ioapic_write_reg(0x10 + line * 2 + 0, ((u32 *)&e)[0]); - ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]); -} - -void enable_apic(void) -{ - printf("enabling apic\n"); - xapic_write(0xf0, 0x1ff); /* spurious vector register */ -} - -void mask_pic_interrupts(void) -{ - outb(0xff, 0x21); - outb(0xff, 0xa1); -} diff --git a/kvm/test/lib/x86/apic.h b/kvm/test/lib/x86/apic.h deleted file mode 100644 index e325e9aae..000000000 --- a/kvm/test/lib/x86/apic.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CFLAT_APIC_H -#define CFLAT_APIC_H - -#include <stdint.h> -#include "apic-defs.h" - -typedef struct { - uint8_t vector; - uint8_t delivery_mode:3; - uint8_t dest_mode:1; - uint8_t delivery_status:1; - uint8_t polarity:1; - uint8_t remote_irr:1; - uint8_t trig_mode:1; - uint8_t mask:1; - uint8_t reserve:7; - uint8_t reserved[4]; - uint8_t dest_id; -} ioapic_redir_entry_t; - -void mask_pic_interrupts(void); - -void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e); -void ioapic_write_reg(unsigned reg, uint32_t value); - -void enable_apic(void); -uint32_t apic_read(unsigned reg); -void apic_write(unsigned reg, uint32_t val); -void apic_icr_write(uint32_t val, uint32_t dest); -uint32_t apic_id(void); - -int enable_x2apic(void); - -#endif diff --git a/kvm/test/lib/x86/fake-apic.h b/kvm/test/lib/x86/fake-apic.h deleted file mode 100644 index eed63baef..000000000 --- a/kvm/test/lib/x86/fake-apic.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SILLY_APIC_H -#define SILLY_APIC_H - -#define APIC_BASE 0x1000 -#define APIC_SIZE 0x100 - -#define APIC_REG_NCPU 0x00 -#define APIC_REG_ID 0x04 -#define APIC_REG_SIPI_ADDR 0x08 -#define APIC_REG_SEND_SIPI 0x0c -#define APIC_REG_IPI_VECTOR 0x10 -#define APIC_REG_SEND_IPI 0x14 - -#endif diff --git a/kvm/test/lib/x86/fwcfg.c b/kvm/test/lib/x86/fwcfg.c deleted file mode 100644 index e2cdd1577..000000000 --- a/kvm/test/lib/x86/fwcfg.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "fwcfg.h" -#include "smp.h" - -static struct spinlock lock; - -uint64_t fwcfg_get_u(uint16_t index, int bytes) -{ - uint64_t r = 0; - uint8_t b; - int i; - - spin_lock(&lock); - asm volatile ("out %0, %1" : : "a"(index), "d"((uint16_t)BIOS_CFG_IOPORT)); - for (i = 0; i < bytes; ++i) { - asm volatile ("in %1, %0" : "=a"(b) : "d"((uint16_t)(BIOS_CFG_IOPORT + 1))); - r |= (uint64_t)b << (i * 8); - } - spin_unlock(&lock); - return r; -} - -uint8_t fwcfg_get_u8(unsigned index) -{ - return fwcfg_get_u(index, 1); -} - -uint16_t fwcfg_get_u16(unsigned index) -{ - return fwcfg_get_u(index, 2); -} - -uint32_t fwcfg_get_u32(unsigned index) -{ - return fwcfg_get_u(index, 4); -} - -uint64_t fwcfg_get_u64(unsigned index) -{ - return fwcfg_get_u(index, 8); -} - -unsigned fwcfg_get_nb_cpus(void) -{ - return fwcfg_get_u16(FW_CFG_NB_CPUS); -} diff --git a/kvm/test/lib/x86/fwcfg.h b/kvm/test/lib/x86/fwcfg.h deleted file mode 100644 index e0836ca4d..000000000 --- a/kvm/test/lib/x86/fwcfg.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef FWCFG_H -#define FWCFG_H - -#include <stdint.h> - -#define FW_CFG_SIGNATURE 0x00 -#define FW_CFG_ID 0x01 -#define FW_CFG_UUID 0x02 -#define FW_CFG_RAM_SIZE 0x03 -#define FW_CFG_NOGRAPHIC 0x04 -#define FW_CFG_NB_CPUS 0x05 -#define FW_CFG_MACHINE_ID 0x06 -#define FW_CFG_KERNEL_ADDR 0x07 -#define FW_CFG_KERNEL_SIZE 0x08 -#define FW_CFG_KERNEL_CMDLINE 0x09 -#define FW_CFG_INITRD_ADDR 0x0a -#define FW_CFG_INITRD_SIZE 0x0b -#define FW_CFG_BOOT_DEVICE 0x0c -#define FW_CFG_NUMA 0x0d -#define FW_CFG_BOOT_MENU 0x0e -#define FW_CFG_MAX_CPUS 0x0f -#define FW_CFG_MAX_ENTRY 0x10 - -#define FW_CFG_WRITE_CHANNEL 0x4000 -#define FW_CFG_ARCH_LOCAL 0x8000 -#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL) - -#define FW_CFG_INVALID 0xffff - -#define BIOS_CFG_IOPORT 0x510 - -#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) -#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1) -#define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2) - -uint8_t fwcfg_get_u8(unsigned index); -uint16_t fwcfg_get_u16(unsigned index); -uint32_t fwcfg_get_u32(unsigned index); -uint64_t fwcfg_get_u64(unsigned index); - -unsigned fwcfg_get_nb_cpus(void); - -#endif - diff --git a/kvm/test/lib/x86/idt.h b/kvm/test/lib/x86/idt.h deleted file mode 100644 index 6babcb4a4..000000000 --- a/kvm/test/lib/x86/idt.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __IDT_TEST__ -#define __IDT_TEST__ - -void setup_idt(void); - -#define ASM_TRY(catch) \ - "movl $0, %%gs:4 \n\t" \ - ".pushsection .data.ex \n\t" \ - ".quad 1111f, " catch "\n\t" \ - ".popsection \n\t" \ - "1111:" - -#define UD_VECTOR 6 -#define GP_VECTOR 13 - -unsigned exception_vector(void); -unsigned exception_error_code(void); - -#endif diff --git a/kvm/test/lib/x86/io.c b/kvm/test/lib/x86/io.c deleted file mode 100644 index 894f398b1..000000000 --- a/kvm/test/lib/x86/io.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "libcflat.h" -#include "smp.h" - -static struct spinlock lock; - -static void print_serial(const char *buf) -{ - unsigned long len = strlen(buf); - - asm volatile ("rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); -} - -void puts(const char *s) -{ - spin_lock(&lock); - print_serial(s); - spin_unlock(&lock); -} - -void exit(int code) -{ - asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4)); -} diff --git a/kvm/test/lib/x86/msr.h b/kvm/test/lib/x86/msr.h deleted file mode 100644 index 509a42187..000000000 --- a/kvm/test/lib/x86/msr.h +++ /dev/null @@ -1,406 +0,0 @@ -#ifndef _ASM_X86_MSR_INDEX_H -#define _ASM_X86_MSR_INDEX_H - -/* CPU model specific register (MSR) numbers */ - -/* x86-64 specific MSRs */ -#define MSR_EFER 0xc0000080 /* extended feature register */ -#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */ -#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ -#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */ -#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ -#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ -#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ -#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */ -#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */ - -/* EFER bits: */ -#define _EFER_SCE 0 /* SYSCALL/SYSRET */ -#define _EFER_LME 8 /* Long mode enable */ -#define _EFER_LMA 10 /* Long mode active (read-only) */ -#define _EFER_NX 11 /* No execute enable */ -#define _EFER_SVME 12 /* Enable virtualization */ -#define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */ -#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */ - -#define EFER_SCE (1<<_EFER_SCE) -#define EFER_LME (1<<_EFER_LME) -#define EFER_LMA (1<<_EFER_LMA) -#define EFER_NX (1<<_EFER_NX) -#define EFER_SVME (1<<_EFER_SVME) -#define EFER_LMSLE (1<<_EFER_LMSLE) -#define EFER_FFXSR (1<<_EFER_FFXSR) - -/* Intel MSRs. Some also available on other CPUs */ -#define MSR_IA32_PERFCTR0 0x000000c1 -#define MSR_IA32_PERFCTR1 0x000000c2 -#define MSR_FSB_FREQ 0x000000cd - -#define MSR_MTRRcap 0x000000fe -#define MSR_IA32_BBL_CR_CTL 0x00000119 - -#define MSR_IA32_SYSENTER_CS 0x00000174 -#define MSR_IA32_SYSENTER_ESP 0x00000175 -#define MSR_IA32_SYSENTER_EIP 0x00000176 - -#define MSR_IA32_MCG_CAP 0x00000179 -#define MSR_IA32_MCG_STATUS 0x0000017a -#define MSR_IA32_MCG_CTL 0x0000017b - -#define MSR_IA32_PEBS_ENABLE 0x000003f1 -#define MSR_IA32_DS_AREA 0x00000600 -#define MSR_IA32_PERF_CAPABILITIES 0x00000345 - -#define MSR_MTRRfix64K_00000 0x00000250 -#define MSR_MTRRfix16K_80000 0x00000258 -#define MSR_MTRRfix16K_A0000 0x00000259 -#define MSR_MTRRfix4K_C0000 0x00000268 -#define MSR_MTRRfix4K_C8000 0x00000269 -#define MSR_MTRRfix4K_D0000 0x0000026a -#define MSR_MTRRfix4K_D8000 0x0000026b -#define MSR_MTRRfix4K_E0000 0x0000026c -#define MSR_MTRRfix4K_E8000 0x0000026d -#define MSR_MTRRfix4K_F0000 0x0000026e -#define MSR_MTRRfix4K_F8000 0x0000026f -#define MSR_MTRRdefType 0x000002ff - -#define MSR_IA32_CR_PAT 0x00000277 - -#define MSR_IA32_DEBUGCTLMSR 0x000001d9 -#define MSR_IA32_LASTBRANCHFROMIP 0x000001db -#define MSR_IA32_LASTBRANCHTOIP 0x000001dc -#define MSR_IA32_LASTINTFROMIP 0x000001dd -#define MSR_IA32_LASTINTTOIP 0x000001de - -/* DEBUGCTLMSR bits (others vary by model): */ -#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ -#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ -#define DEBUGCTLMSR_TR (1UL << 6) -#define DEBUGCTLMSR_BTS (1UL << 7) -#define DEBUGCTLMSR_BTINT (1UL << 8) -#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9) -#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) -#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) - -#define MSR_IA32_MC0_CTL 0x00000400 -#define MSR_IA32_MC0_STATUS 0x00000401 -#define MSR_IA32_MC0_ADDR 0x00000402 -#define MSR_IA32_MC0_MISC 0x00000403 - -#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) -#define MSR_IA32_MCx_STATUS(x) (MSR_IA32_MC0_STATUS + 4*(x)) -#define MSR_IA32_MCx_ADDR(x) (MSR_IA32_MC0_ADDR + 4*(x)) -#define MSR_IA32_MCx_MISC(x) (MSR_IA32_MC0_MISC + 4*(x)) - -/* These are consecutive and not in the normal 4er MCE bank block */ -#define MSR_IA32_MC0_CTL2 0x00000280 -#define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x)) - -#define CMCI_EN (1ULL << 30) -#define CMCI_THRESHOLD_MASK 0xffffULL - -#define MSR_P6_PERFCTR0 0x000000c1 -#define MSR_P6_PERFCTR1 0x000000c2 -#define MSR_P6_EVNTSEL0 0x00000186 -#define MSR_P6_EVNTSEL1 0x00000187 - -/* AMD64 MSRs. Not complete. See the architecture manual for a more - complete list. */ - -#define MSR_AMD64_PATCH_LEVEL 0x0000008b -#define MSR_AMD64_NB_CFG 0xc001001f -#define MSR_AMD64_PATCH_LOADER 0xc0010020 -#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 -#define MSR_AMD64_OSVW_STATUS 0xc0010141 -#define MSR_AMD64_DC_CFG 0xc0011022 -#define MSR_AMD64_IBSFETCHCTL 0xc0011030 -#define MSR_AMD64_IBSFETCHLINAD 0xc0011031 -#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 -#define MSR_AMD64_IBSOPCTL 0xc0011033 -#define MSR_AMD64_IBSOPRIP 0xc0011034 -#define MSR_AMD64_IBSOPDATA 0xc0011035 -#define MSR_AMD64_IBSOPDATA2 0xc0011036 -#define MSR_AMD64_IBSOPDATA3 0xc0011037 -#define MSR_AMD64_IBSDCLINAD 0xc0011038 -#define MSR_AMD64_IBSDCPHYSAD 0xc0011039 -#define MSR_AMD64_IBSCTL 0xc001103a - -/* Fam 10h MSRs */ -#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 -#define FAM10H_MMIO_CONF_ENABLE (1<<0) -#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf -#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 -#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffff -#define FAM10H_MMIO_CONF_BASE_SHIFT 20 -#define MSR_FAM10H_NODE_ID 0xc001100c - -/* K8 MSRs */ -#define MSR_K8_TOP_MEM1 0xc001001a -#define MSR_K8_TOP_MEM2 0xc001001d -#define MSR_K8_SYSCFG 0xc0010010 -#define MSR_K8_INT_PENDING_MSG 0xc0010055 -/* C1E active bits in int pending message */ -#define K8_INTP_C1E_ACTIVE_MASK 0x18000000 -#define MSR_K8_TSEG_ADDR 0xc0010112 -#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */ -#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */ -#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */ - -/* K7 MSRs */ -#define MSR_K7_EVNTSEL0 0xc0010000 -#define MSR_K7_PERFCTR0 0xc0010004 -#define MSR_K7_EVNTSEL1 0xc0010001 -#define MSR_K7_PERFCTR1 0xc0010005 -#define MSR_K7_EVNTSEL2 0xc0010002 -#define MSR_K7_PERFCTR2 0xc0010006 -#define MSR_K7_EVNTSEL3 0xc0010003 -#define MSR_K7_PERFCTR3 0xc0010007 -#define MSR_K7_CLK_CTL 0xc001001b -#define MSR_K7_HWCR 0xc0010015 -#define MSR_K7_FID_VID_CTL 0xc0010041 -#define MSR_K7_FID_VID_STATUS 0xc0010042 - -/* K6 MSRs */ -#define MSR_K6_EFER 0xc0000080 -#define MSR_K6_STAR 0xc0000081 -#define MSR_K6_WHCR 0xc0000082 -#define MSR_K6_UWCCR 0xc0000085 -#define MSR_K6_EPMR 0xc0000086 -#define MSR_K6_PSOR 0xc0000087 -#define MSR_K6_PFIR 0xc0000088 - -/* Centaur-Hauls/IDT defined MSRs. */ -#define MSR_IDT_FCR1 0x00000107 -#define MSR_IDT_FCR2 0x00000108 -#define MSR_IDT_FCR3 0x00000109 -#define MSR_IDT_FCR4 0x0000010a - -#define MSR_IDT_MCR0 0x00000110 -#define MSR_IDT_MCR1 0x00000111 -#define MSR_IDT_MCR2 0x00000112 -#define MSR_IDT_MCR3 0x00000113 -#define MSR_IDT_MCR4 0x00000114 -#define MSR_IDT_MCR5 0x00000115 -#define MSR_IDT_MCR6 0x00000116 -#define MSR_IDT_MCR7 0x00000117 -#define MSR_IDT_MCR_CTRL 0x00000120 - -/* VIA Cyrix defined MSRs*/ -#define MSR_VIA_FCR 0x00001107 -#define MSR_VIA_LONGHAUL 0x0000110a -#define MSR_VIA_RNG 0x0000110b -#define MSR_VIA_BCR2 0x00001147 - -/* Transmeta defined MSRs */ -#define MSR_TMTA_LONGRUN_CTRL 0x80868010 -#define MSR_TMTA_LONGRUN_FLAGS 0x80868011 -#define MSR_TMTA_LRTI_READOUT 0x80868018 -#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a - -/* Intel defined MSRs. */ -#define MSR_IA32_P5_MC_ADDR 0x00000000 -#define MSR_IA32_P5_MC_TYPE 0x00000001 -#define MSR_IA32_TSC 0x00000010 -#define MSR_IA32_PLATFORM_ID 0x00000017 -#define MSR_IA32_EBL_CR_POWERON 0x0000002a -#define MSR_IA32_FEATURE_CONTROL 0x0000003a - -#define FEATURE_CONTROL_LOCKED (1<<0) -#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) -#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) - -#define MSR_IA32_APICBASE 0x0000001b -#define MSR_IA32_APICBASE_BSP (1<<8) -#define MSR_IA32_APICBASE_ENABLE (1<<11) -#define MSR_IA32_APICBASE_BASE (0xfffff<<12) - -#define MSR_IA32_UCODE_WRITE 0x00000079 -#define MSR_IA32_UCODE_REV 0x0000008b - -#define MSR_IA32_PERF_STATUS 0x00000198 -#define MSR_IA32_PERF_CTL 0x00000199 - -#define MSR_IA32_MPERF 0x000000e7 -#define MSR_IA32_APERF 0x000000e8 - -#define MSR_IA32_THERM_CONTROL 0x0000019a -#define MSR_IA32_THERM_INTERRUPT 0x0000019b - -#define THERM_INT_LOW_ENABLE (1 << 0) -#define THERM_INT_HIGH_ENABLE (1 << 1) - -#define MSR_IA32_THERM_STATUS 0x0000019c - -#define THERM_STATUS_PROCHOT (1 << 0) - -#define MSR_THERM2_CTL 0x0000019d - -#define MSR_THERM2_CTL_TM_SELECT (1ULL << 16) - -#define MSR_IA32_MISC_ENABLE 0x000001a0 - -#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 - -/* MISC_ENABLE bits: architectural */ -#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) -#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) -#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) -#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) -#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) -#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) -#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) -#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) -#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) -#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) - -/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ -#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) -#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) -#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) -#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) -#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) -#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) -#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) -#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) -#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) -#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) -#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) -#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) -#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) -#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) -#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) - -/* P4/Xeon+ specific */ -#define MSR_IA32_MCG_EAX 0x00000180 -#define MSR_IA32_MCG_EBX 0x00000181 -#define MSR_IA32_MCG_ECX 0x00000182 -#define MSR_IA32_MCG_EDX 0x00000183 -#define MSR_IA32_MCG_ESI 0x00000184 -#define MSR_IA32_MCG_EDI 0x00000185 -#define MSR_IA32_MCG_EBP 0x00000186 -#define MSR_IA32_MCG_ESP 0x00000187 -#define MSR_IA32_MCG_EFLAGS 0x00000188 -#define MSR_IA32_MCG_EIP 0x00000189 -#define MSR_IA32_MCG_RESERVED 0x0000018a - -/* Pentium IV performance counter MSRs */ -#define MSR_P4_BPU_PERFCTR0 0x00000300 -#define MSR_P4_BPU_PERFCTR1 0x00000301 -#define MSR_P4_BPU_PERFCTR2 0x00000302 -#define MSR_P4_BPU_PERFCTR3 0x00000303 -#define MSR_P4_MS_PERFCTR0 0x00000304 -#define MSR_P4_MS_PERFCTR1 0x00000305 -#define MSR_P4_MS_PERFCTR2 0x00000306 -#define MSR_P4_MS_PERFCTR3 0x00000307 -#define MSR_P4_FLAME_PERFCTR0 0x00000308 -#define MSR_P4_FLAME_PERFCTR1 0x00000309 -#define MSR_P4_FLAME_PERFCTR2 0x0000030a -#define MSR_P4_FLAME_PERFCTR3 0x0000030b -#define MSR_P4_IQ_PERFCTR0 0x0000030c -#define MSR_P4_IQ_PERFCTR1 0x0000030d -#define MSR_P4_IQ_PERFCTR2 0x0000030e -#define MSR_P4_IQ_PERFCTR3 0x0000030f -#define MSR_P4_IQ_PERFCTR4 0x00000310 -#define MSR_P4_IQ_PERFCTR5 0x00000311 -#define MSR_P4_BPU_CCCR0 0x00000360 -#define MSR_P4_BPU_CCCR1 0x00000361 -#define MSR_P4_BPU_CCCR2 0x00000362 -#define MSR_P4_BPU_CCCR3 0x00000363 -#define MSR_P4_MS_CCCR0 0x00000364 -#define MSR_P4_MS_CCCR1 0x00000365 -#define MSR_P4_MS_CCCR2 0x00000366 -#define MSR_P4_MS_CCCR3 0x00000367 -#define MSR_P4_FLAME_CCCR0 0x00000368 -#define MSR_P4_FLAME_CCCR1 0x00000369 -#define MSR_P4_FLAME_CCCR2 0x0000036a -#define MSR_P4_FLAME_CCCR3 0x0000036b -#define MSR_P4_IQ_CCCR0 0x0000036c -#define MSR_P4_IQ_CCCR1 0x0000036d -#define MSR_P4_IQ_CCCR2 0x0000036e -#define MSR_P4_IQ_CCCR3 0x0000036f -#define MSR_P4_IQ_CCCR4 0x00000370 -#define MSR_P4_IQ_CCCR5 0x00000371 -#define MSR_P4_ALF_ESCR0 0x000003ca -#define MSR_P4_ALF_ESCR1 0x000003cb -#define MSR_P4_BPU_ESCR0 0x000003b2 -#define MSR_P4_BPU_ESCR1 0x000003b3 -#define MSR_P4_BSU_ESCR0 0x000003a0 -#define MSR_P4_BSU_ESCR1 0x000003a1 -#define MSR_P4_CRU_ESCR0 0x000003b8 -#define MSR_P4_CRU_ESCR1 0x000003b9 -#define MSR_P4_CRU_ESCR2 0x000003cc -#define MSR_P4_CRU_ESCR3 0x000003cd -#define MSR_P4_CRU_ESCR4 0x000003e0 -#define MSR_P4_CRU_ESCR5 0x000003e1 -#define MSR_P4_DAC_ESCR0 0x000003a8 -#define MSR_P4_DAC_ESCR1 0x000003a9 -#define MSR_P4_FIRM_ESCR0 0x000003a4 -#define MSR_P4_FIRM_ESCR1 0x000003a5 -#define MSR_P4_FLAME_ESCR0 0x000003a6 -#define MSR_P4_FLAME_ESCR1 0x000003a7 -#define MSR_P4_FSB_ESCR0 0x000003a2 -#define MSR_P4_FSB_ESCR1 0x000003a3 -#define MSR_P4_IQ_ESCR0 0x000003ba -#define MSR_P4_IQ_ESCR1 0x000003bb -#define MSR_P4_IS_ESCR0 0x000003b4 -#define MSR_P4_IS_ESCR1 0x000003b5 -#define MSR_P4_ITLB_ESCR0 0x000003b6 -#define MSR_P4_ITLB_ESCR1 0x000003b7 -#define MSR_P4_IX_ESCR0 0x000003c8 -#define MSR_P4_IX_ESCR1 0x000003c9 -#define MSR_P4_MOB_ESCR0 0x000003aa -#define MSR_P4_MOB_ESCR1 0x000003ab -#define MSR_P4_MS_ESCR0 0x000003c0 -#define MSR_P4_MS_ESCR1 0x000003c1 -#define MSR_P4_PMH_ESCR0 0x000003ac -#define MSR_P4_PMH_ESCR1 0x000003ad -#define MSR_P4_RAT_ESCR0 0x000003bc -#define MSR_P4_RAT_ESCR1 0x000003bd -#define MSR_P4_SAAT_ESCR0 0x000003ae -#define MSR_P4_SAAT_ESCR1 0x000003af -#define MSR_P4_SSU_ESCR0 0x000003be -#define MSR_P4_SSU_ESCR1 0x000003bf /* guess: not in manual */ - -#define MSR_P4_TBPU_ESCR0 0x000003c2 -#define MSR_P4_TBPU_ESCR1 0x000003c3 -#define MSR_P4_TC_ESCR0 0x000003c4 -#define MSR_P4_TC_ESCR1 0x000003c5 -#define MSR_P4_U2L_ESCR0 0x000003b0 -#define MSR_P4_U2L_ESCR1 0x000003b1 - -#define MSR_P4_PEBS_MATRIX_VERT 0x000003f2 - -/* Intel Core-based CPU performance counters */ -#define MSR_CORE_PERF_FIXED_CTR0 0x00000309 -#define MSR_CORE_PERF_FIXED_CTR1 0x0000030a -#define MSR_CORE_PERF_FIXED_CTR2 0x0000030b -#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d -#define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e -#define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f -#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 - -/* Geode defined MSRs */ -#define MSR_GEODE_BUSCONT_CONF0 0x00001900 - -/* Intel VT MSRs */ -#define MSR_IA32_VMX_BASIC 0x00000480 -#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481 -#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482 -#define MSR_IA32_VMX_EXIT_CTLS 0x00000483 -#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484 -#define MSR_IA32_VMX_MISC 0x00000485 -#define MSR_IA32_VMX_CR0_FIXED0 0x00000486 -#define MSR_IA32_VMX_CR0_FIXED1 0x00000487 -#define MSR_IA32_VMX_CR4_FIXED0 0x00000488 -#define MSR_IA32_VMX_CR4_FIXED1 0x00000489 -#define MSR_IA32_VMX_VMCS_ENUM 0x0000048a -#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b -#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c - -/* AMD-V MSRs */ - -#define MSR_VM_CR 0xc0010114 -#define MSR_VM_IGNNE 0xc0010115 -#define MSR_VM_HSAVE_PA 0xc0010117 - -#endif /* _ASM_X86_MSR_INDEX_H */ diff --git a/kvm/test/lib/x86/processor.h b/kvm/test/lib/x86/processor.h deleted file mode 100644 index 67d7ca5ac..000000000 --- a/kvm/test/lib/x86/processor.h +++ /dev/null @@ -1,261 +0,0 @@ -#ifndef LIBCFLAT_PROCESSOR_H -#define LIBCFLAT_PROCESSOR_H - -#include "libcflat.h" - -struct descriptor_table_ptr { - u16 limit; - ulong base; -} __attribute__((packed)); - -static inline void barrier(void) -{ - asm volatile ("" : : : "memory"); -} - -static inline u16 read_cs(void) -{ - unsigned val; - - asm ("mov %%cs, %0" : "=mr"(val)); - return val; -} - -static inline u16 read_ds(void) -{ - unsigned val; - - asm ("mov %%ds, %0" : "=mr"(val)); - return val; -} - -static inline u16 read_es(void) -{ - unsigned val; - - asm ("mov %%es, %0" : "=mr"(val)); - return val; -} - -static inline u16 read_ss(void) -{ - unsigned val; - - asm ("mov %%ss, %0" : "=mr"(val)); - return val; -} - -static inline u16 read_fs(void) -{ - unsigned val; - - asm ("mov %%fs, %0" : "=mr"(val)); - return val; -} - -static inline u16 read_gs(void) -{ - unsigned val; - - asm ("mov %%gs, %0" : "=mr"(val)); - return val; -} - -static inline void write_ds(unsigned val) -{ - asm ("mov %0, %%ds" : : "rm"(val) : "memory"); -} - -static inline void write_es(unsigned val) -{ - asm ("mov %0, %%es" : : "rm"(val) : "memory"); -} - -static inline void write_ss(unsigned val) -{ - asm ("mov %0, %%ss" : : "rm"(val) : "memory"); -} - -static inline void write_fs(unsigned val) -{ - asm ("mov %0, %%fs" : : "rm"(val) : "memory"); -} - -static inline void write_gs(unsigned val) -{ - asm ("mov %0, %%gs" : : "rm"(val) : "memory"); -} - -static inline u64 rdmsr(u32 index) -{ - u32 a, d; - asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(index) : "memory"); - return a | ((u64)d << 32); -} - -static inline void wrmsr(u32 index, u64 val) -{ - u32 a = val, d = val >> 32; - asm volatile ("wrmsr" : : "a"(a), "d"(d), "c"(index) : "memory"); -} - -static inline void write_cr0(ulong val) -{ - asm volatile ("mov %0, %%cr0" : : "r"(val) : "memory"); -} - -static inline ulong read_cr0(void) -{ - ulong val; - asm volatile ("mov %%cr0, %0" : "=r"(val) : : "memory"); - return val; -} - -static inline void write_cr2(ulong val) -{ - asm volatile ("mov %0, %%cr2" : : "r"(val) : "memory"); -} - -static inline ulong read_cr2(void) -{ - ulong val; - asm volatile ("mov %%cr2, %0" : "=r"(val) : : "memory"); - return val; -} - -static inline void write_cr3(ulong val) -{ - asm volatile ("mov %0, %%cr3" : : "r"(val) : "memory"); -} - -static inline ulong read_cr3(void) -{ - ulong val; - asm volatile ("mov %%cr3, %0" : "=r"(val) : : "memory"); - return val; -} - -static inline void write_cr4(ulong val) -{ - asm volatile ("mov %0, %%cr4" : : "r"(val) : "memory"); -} - -static inline ulong read_cr4(void) -{ - ulong val; - asm volatile ("mov %%cr4, %0" : "=r"(val) : : "memory"); - return val; -} - -static inline void write_cr8(ulong val) -{ - asm volatile ("mov %0, %%cr8" : : "r"(val) : "memory"); -} - -static inline ulong read_cr8(void) -{ - ulong val; - asm volatile ("mov %%cr8, %0" : "=r"(val) : : "memory"); - return val; -} - -static inline void lgdt(const struct descriptor_table_ptr *ptr) -{ - asm volatile ("lgdt %0" : : "m"(*ptr)); -} - -static inline void sgdt(struct descriptor_table_ptr *ptr) -{ - asm volatile ("sgdt %0" : "=m"(*ptr)); -} - -static inline void lidt(const struct descriptor_table_ptr *ptr) -{ - asm volatile ("lidt %0" : : "m"(*ptr)); -} - -static inline void sidt(struct descriptor_table_ptr *ptr) -{ - asm volatile ("sidt %0" : "=m"(*ptr)); -} - -static inline void lldt(unsigned val) -{ - asm volatile ("lldt %0" : : "rm"(val)); -} - -static inline u16 sldt(void) -{ - u16 val; - asm volatile ("sldt %0" : "=rm"(val)); - return val; -} - -static inline void ltr(unsigned val) -{ - asm volatile ("ltr %0" : : "rm"(val)); -} - -static inline u16 str(void) -{ - u16 val; - asm volatile ("str %0" : "=rm"(val)); - return val; -} - -static inline void write_dr6(ulong val) -{ - asm volatile ("mov %0, %%dr6" : : "r"(val) : "memory"); -} - -static inline ulong read_dr6(void) -{ - ulong val; - asm volatile ("mov %%dr6, %0" : "=r"(val)); - return val; -} - -static inline void write_dr7(ulong val) -{ - asm volatile ("mov %0, %%dr7" : : "r"(val) : "memory"); -} - -static inline ulong read_dr7(void) -{ - ulong val; - asm volatile ("mov %%dr7, %0" : "=r"(val)); - return val; -} - -struct cpuid { u32 a, b, c, d; }; - -static inline struct cpuid cpuid_indexed(u32 function, u32 index) -{ - struct cpuid r; - asm volatile ("cpuid" - : "=a"(r.a), "=b"(r.b), "=c"(r.c), "=d"(r.d) - : "0"(function), "2"(index)); - return r; -} - -static inline struct cpuid cpuid(u32 function) -{ - return cpuid_indexed(function, 0); -} - -static inline void pause(void) -{ - asm volatile ("pause"); -} - -static inline void cli(void) -{ - asm volatile ("cli"); -} - -static inline void sti(void) -{ - asm volatile ("sti"); -} - -#endif diff --git a/kvm/test/lib/x86/smp.c b/kvm/test/lib/x86/smp.c deleted file mode 100644 index 241f7551e..000000000 --- a/kvm/test/lib/x86/smp.c +++ /dev/null @@ -1,128 +0,0 @@ - -#include <libcflat.h> -#include "smp.h" -#include "apic.h" -#include "fwcfg.h" - -#define IPI_VECTOR 0x20 - -static struct spinlock ipi_lock; -static void (*ipi_function)(void *data); -static void *ipi_data; -static volatile int ipi_done; - -static __attribute__((used)) void ipi() -{ - ipi_function(ipi_data); - apic_write(APIC_EOI, 0); - ipi_done = 1; -} - -asm ( - "ipi_entry: \n" - " call ipi \n" -#ifndef __x86_64__ - " iret" -#else - " iretq" -#endif - ); - - -static void set_ipi_descriptor(void (*ipi_entry)(void)) -{ - unsigned short *desc = (void *)(IPI_VECTOR * sizeof(long) * 2); - unsigned short cs; - unsigned long ipi = (unsigned long)ipi_entry; - - asm ("mov %%cs, %0" : "=r"(cs)); - desc[0] = ipi; - desc[1] = cs; - desc[2] = 0x8e00; - desc[3] = ipi >> 16; -#ifdef __x86_64__ - desc[4] = ipi >> 32; - desc[5] = ipi >> 48; - desc[6] = 0; - desc[7] = 0; -#endif -} - -void spin_lock(struct spinlock *lock) -{ - int v = 1; - - do { - asm volatile ("xchg %1, %0" : "+m"(lock->v), "+r"(v)); - } while (v); - asm volatile ("" : : : "memory"); -} - -void spin_unlock(struct spinlock *lock) -{ - asm volatile ("" : : : "memory"); - lock->v = 0; -} - -int cpu_count(void) -{ - return fwcfg_get_nb_cpus(); -} - -int smp_id(void) -{ - unsigned id; - - asm ("mov %%gs:0, %0" : "=r"(id)); - return id; -} - -static void setup_smp_id(void *data) -{ - asm ("mov %0, %%gs:0" : : "r"(apic_id()) : "memory"); -} - -static void __on_cpu(int cpu, void (*function)(void *data), void *data, - int wait) -{ - spin_lock(&ipi_lock); - if (cpu == smp_id()) - function(data); - else { - ipi_done = 0; - ipi_function = function; - ipi_data = data; - apic_icr_write(APIC_INT_ASSERT | APIC_DEST_PHYSICAL | APIC_DM_FIXED - | IPI_VECTOR, - cpu); - if (wait) { - while (!ipi_done) - ; - } - } - spin_unlock(&ipi_lock); -} - -void on_cpu(int cpu, void (*function)(void *data), void *data) -{ - __on_cpu(cpu, function, data, 1); -} - -void on_cpu_async(int cpu, void (*function)(void *data), void *data) -{ - __on_cpu(cpu, function, data, 0); -} - - -void smp_init(void) -{ - int i; - void ipi_entry(void); - - set_ipi_descriptor(ipi_entry); - - setup_smp_id(0); - for (i = 1; i < cpu_count(); ++i) - on_cpu(i, setup_smp_id, 0); - -} diff --git a/kvm/test/lib/x86/smp.h b/kvm/test/lib/x86/smp.h deleted file mode 100644 index c2e73501c..000000000 --- a/kvm/test/lib/x86/smp.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __SMP_H -#define __SMP_H - -struct spinlock { - int v; -}; - -void smp_init(void); - -int cpu_count(void); -int smp_id(void); -void on_cpu(int cpu, void (*function)(void *data), void *data); -void on_cpu_async(int cpu, void (*function)(void *data), void *data); -void spin_lock(struct spinlock *lock); -void spin_unlock(struct spinlock *lock); - -#endif diff --git a/kvm/test/main-ppc.c b/kvm/test/main-ppc.c deleted file mode 100644 index 5af59f846..000000000 --- a/kvm/test/main-ppc.c +++ /dev/null @@ -1,383 +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 - * Copyright IBM Corp. 2008 - * - * Authors: - * - * Avi Kivity <avi@qumranet.com> - * Yaniv Kamay <yaniv@qumranet.com> - * Hollis Blanchard <hollisb@us.ibm.com> - * - * 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> - -#include "iotable.h" - -static int gettid(void) -{ - return syscall(__NR_gettid); -} - -kvm_context_t kvm; - -#define IPI_SIGNAL (SIGRTMIN + 4) - -struct io_table mmio_table; - -static int ncpus = 1; -static sem_t exited_sem; -static __thread int vcpu; -static sigset_t kernel_sigmask; -static sigset_t ipi_sigmask; -static uint64_t memory_size = 128 * 1024 * 1024; - -struct vcpu_info { - pid_t tid; -}; - -struct vcpu_info *vcpus; - -/* Must match flat.lds linker script */ -#define VM_TEST_LOAD_ADDRESS 0x100000 - -static int test_debug(void *opaque, void *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, void *vcpu) -{ -} - -static int test_pre_kvm_run(void *opaque, void *vcpu) -{ - return 0; -} - -static int mmio_handler(void *opaque, int len, int is_write, uint64_t offset, - uint64_t *data) -{ - int r = 0; - - switch (offset) { - case 0: /* putc */ - putc(*(char *)data, stdout); - fflush(stdout); - break; - case 1: /* exit */ - r = *(char *)data; - break; - default: - printf("%s: offset %"PRIx64" len %d data %"PRIx64"\n", - __func__, offset, len, *(uint64_t *)data); - r = -EINVAL; - } - - return r; -} - -static int test_mem_read(void *opaque, uint64_t addr, uint8_t *data, int len) -{ - struct io_table_entry *iodev; - -#if 0 - printf("%s: addr %"PRIx64" len %d\n", __func__, addr, len); -#endif - - iodev = io_table_lookup(&mmio_table, addr); - if (!iodev) { - printf("couldn't find device\n"); - return -ENODEV; - } - - return iodev->handler(iodev->opaque, len, 0, addr - iodev->start, - (uint64_t *)data); -} - -static int test_mem_write(void *opaque, uint64_t addr, uint8_t *data, int len) -{ - struct io_table_entry *iodev; - -#if 0 - printf("%s: addr %"PRIx64" len %d data %"PRIx64"\n", - __func__, addr, len, *(uint64_t *)data); -#endif - - iodev = io_table_lookup(&mmio_table, addr); - if (!iodev) { - printf("couldn't find device\n"); - return -ENODEV; - } - - return iodev->handler(iodev->opaque, len, 1, addr - iodev->start, - (uint64_t *)data); -} - -static int test_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data) -{ - printf("%s: dcrn %04X\n", __func__, dcrn); - *data = 0; - return 0; -} - -static int test_dcr_write(int vcpu, uint32_t dcrn, uint32_t data) -{ - printf("%s: dcrn %04X data %04X\n", __func__, dcrn, 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, - .powerpc_dcr_read = test_dcr_read, - .powerpc_dcr_write = test_dcr_write, -}; - -static unsigned long load_file(void *mem, const char *fname, int inval_icache) -{ - ssize_t 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"); - printf("read %d bytes\n", bytes); - 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) -{ - 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); -} - -static void *do_create_vcpu(void *_n) -{ - struct kvm_regs regs; - int n = (long)_n; - - kvm_create_vcpu(kvm, n); - init_vcpu(n); - - kvm_get_regs(kvm, n, ®s); - regs.pc = VM_TEST_LOAD_ADDRESS; - kvm_set_regs(kvm, n, ®s); - - kvm_run(kvm, n, &vcpus[n]); - sem_post(&exited_sem); - 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-ppc@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; - 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 + VM_TEST_LOAD_ADDRESS, argv[optind], 1); - sync_caches(vm_mem + VM_TEST_LOAD_ADDRESS, len); - - io_table_register(&mmio_table, 0xf0000000, 64, mmio_handler, NULL); - - sem_init(&exited_sem, 0, 0); - for (i = 0; i < ncpus; ++i) - start_vcpu(i); - /* Wait for all vcpus to exit. */ - for (i = 0; i < ncpus; ++i) - sem_wait(&exited_sem); - - return 0; -} diff --git a/kvm/test/powerpc/44x/tlbsx.S b/kvm/test/powerpc/44x/tlbsx.S deleted file mode 100644 index b15874b18..000000000 --- a/kvm/test/powerpc/44x/tlbsx.S +++ /dev/null @@ -1,33 +0,0 @@ -#define SPRN_MMUCR 0x3b2 - -#define TLBWORD0 0x10000210 -#define TLBWORD1 0x10000000 -#define TLBWORD2 0x00000003 - -.global _start -_start: - li r4, 0 - mtspr SPRN_MMUCR, r4 - - li r3, 23 - - lis r4, TLBWORD0@h - ori r4, r4, TLBWORD0@l - tlbwe r4, r3, 0 - - lis r4, TLBWORD1@h - ori r4, r4, TLBWORD1@l - tlbwe r4, r3, 1 - - lis r4, TLBWORD2@h - ori r4, r4, TLBWORD2@l - tlbwe r4, r3, 2 - - lis r4, 0x1000 - tlbsx r5, r4, r0 - cmpwi r5, 23 - beq good - trap - -good: - b . diff --git a/kvm/test/powerpc/44x/tlbwe.S b/kvm/test/powerpc/44x/tlbwe.S deleted file mode 100644 index ec6ef5c57..000000000 --- a/kvm/test/powerpc/44x/tlbwe.S +++ /dev/null @@ -1,27 +0,0 @@ -#define SPRN_MMUCR 0x3b2 - -/* Create a mapping at 4MB */ -#define TLBWORD0 0x00400210 -#define TLBWORD1 0x00400000 -#define TLBWORD2 0x00000003 - -.global _start -_start: - li r4, 0 - mtspr SPRN_MMUCR, r4 - - li r3, 23 - - lis r4, TLBWORD0@h - ori r4, r4, TLBWORD0@l - tlbwe r4, r3, 0 - - lis r4, TLBWORD1@h - ori r4, r4, TLBWORD1@l - tlbwe r4, r3, 1 - - lis r4, TLBWORD2@h - ori r4, r4, TLBWORD2@l - tlbwe r4, r3, 2 - - b . diff --git a/kvm/test/powerpc/44x/tlbwe_16KB.S b/kvm/test/powerpc/44x/tlbwe_16KB.S deleted file mode 100644 index 1bd10bf17..000000000 --- a/kvm/test/powerpc/44x/tlbwe_16KB.S +++ /dev/null @@ -1,35 +0,0 @@ -#define SPRN_MMUCR 0x3b2 - -/* 16KB mapping at 4MB */ -#define TLBWORD0 0x00400220 -#define TLBWORD1 0x00400000 -#define TLBWORD2 0x00000003 - -.global _start -_start: - li r4, 0 - mtspr SPRN_MMUCR, r4 - - li r3, 5 - - lis r4, TLBWORD0@h - ori r4, r4, TLBWORD0@l - tlbwe r4, r3, 0 - - lis r4, TLBWORD1@h - ori r4, r4, TLBWORD1@l - tlbwe r4, r3, 1 - - lis r4, TLBWORD2@h - ori r4, r4, TLBWORD2@l - tlbwe r4, r3, 2 - - /* load from 4MB */ - lis r3, 0x0040 - lwz r4, 0(r3) - - /* load from 4MB+8KB */ - ori r3, r3, 0x2000 - lwz r4, 0(r3) - - b . diff --git a/kvm/test/powerpc/44x/tlbwe_hole.S b/kvm/test/powerpc/44x/tlbwe_hole.S deleted file mode 100644 index 5efd30357..000000000 --- a/kvm/test/powerpc/44x/tlbwe_hole.S +++ /dev/null @@ -1,27 +0,0 @@ -#define SPRN_MMUCR 0x3b2 - -/* Try to map real address 1GB. */ -#define TLBWORD0 0x40000210 -#define TLBWORD1 0x40000000 -#define TLBWORD2 0x00000003 - -.global _start -_start: - li r4, 0 - mtspr SPRN_MMUCR, r4 - - li r3, 23 - - lis r4, TLBWORD0@h - ori r4, r4, TLBWORD0@l - tlbwe r4, r3, 0 - - lis r4, TLBWORD1@h - ori r4, r4, TLBWORD1@l - tlbwe r4, r3, 1 - - lis r4, TLBWORD2@h - ori r4, r4, TLBWORD2@l - tlbwe r4, r3, 2 - - b . diff --git a/kvm/test/powerpc/cstart.S b/kvm/test/powerpc/cstart.S deleted file mode 100644 index 70a0e9fcd..000000000 --- a/kvm/test/powerpc/cstart.S +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -#define OUTPUT_VADDR 0xf0000000 -#define OUTPUT_PADDR 0xf0000000 - -.globl _start -_start: - /* In the future we might need to assign a stack and zero BSS here. */ - - /* Map the debug page 1:1. */ - lis r3, OUTPUT_VADDR@h - ori r3, r3, OUTPUT_VADDR@l - lis r4, OUTPUT_PADDR@h - ori r4, r4, OUTPUT_PADDR@l - bl map - - /* Call main() and pass return code to exit(). */ - bl main - bl exit - - b . diff --git a/kvm/test/powerpc/exit.c b/kvm/test/powerpc/exit.c deleted file mode 100644 index 804ee04d9..000000000 --- a/kvm/test/powerpc/exit.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Hollis Blanchard <hollisb@us.ibm.com> - */ - -int main(void) -{ - return 1; -} diff --git a/kvm/test/powerpc/helloworld.c b/kvm/test/powerpc/helloworld.c deleted file mode 100644 index f8630f7c5..000000000 --- a/kvm/test/powerpc/helloworld.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2008 - * - * Authors: Deepa Srinivasan <deepas@us.ibm.com> - */ - -#include "libcflat.h" - -int main() -{ - printf("Hello World\n"); - - return 1; -} diff --git a/kvm/test/powerpc/io.S b/kvm/test/powerpc/io.S deleted file mode 100644 index 97567cb6c..000000000 --- a/kvm/test/powerpc/io.S +++ /dev/null @@ -1,32 +0,0 @@ -#define SPRN_MMUCR 0x3b2 - -#define TLBWORD0 0xf0000210 -#define TLBWORD1 0xf0000000 -#define TLBWORD2 0x00000003 - -.global _start -_start: - li r4, 0 - mtspr SPRN_MMUCR, r4 - - li r3, 2 - - lis r4, TLBWORD0@h - ori r4, r4, TLBWORD0@l - tlbwe r4, r3, 0 - - lis r4, TLBWORD1@h - ori r4, r4, TLBWORD1@l - tlbwe r4, r3, 1 - - lis r4, TLBWORD2@h - ori r4, r4, TLBWORD2@l - tlbwe r4, r3, 2 - - lis r3, 0xf000 - lis r4, 0x1234 - ori r4, r4, 0x5678 - stb r4, 0(r3) - lbz r5, 0(r3) - - b . diff --git a/kvm/test/powerpc/spin.S b/kvm/test/powerpc/spin.S deleted file mode 100644 index 4406641c2..000000000 --- a/kvm/test/powerpc/spin.S +++ /dev/null @@ -1,4 +0,0 @@ - -.global _start -_start: - b . diff --git a/kvm/test/powerpc/sprg.S b/kvm/test/powerpc/sprg.S deleted file mode 100644 index d0414a480..000000000 --- a/kvm/test/powerpc/sprg.S +++ /dev/null @@ -1,7 +0,0 @@ - -.global _start -_start: - li r3, 42 - mtsprg 0, r3 - mfsprg r4, 0 - b . diff --git a/kvm/test/testdev.txt b/kvm/test/testdev.txt deleted file mode 100644 index ac436efad..000000000 --- a/kvm/test/testdev.txt +++ /dev/null @@ -1,14 +0,0 @@ -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 - - - diff --git a/kvm/test/x86/README b/kvm/test/x86/README deleted file mode 100644 index ab5a2ae27..000000000 --- a/kvm/test/x86/README +++ /dev/null @@ -1,14 +0,0 @@ -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 -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 diff --git a/kvm/test/x86/access.c b/kvm/test/x86/access.c deleted file mode 100644 index a0d88e1e0..000000000 --- a/kvm/test/x86/access.c +++ /dev/null @@ -1,708 +0,0 @@ - -#include "libcflat.h" - -#define smp_id() 0 - -#define true 1 -#define false 0 - -static _Bool verbose = false; - -typedef unsigned long pt_element_t; - -#define PAGE_SIZE ((pt_element_t)4096) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 40) - 1) & PAGE_MASK)) -#define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21)) - -#define PT_PRESENT_MASK ((pt_element_t)1 << 0) -#define PT_WRITABLE_MASK ((pt_element_t)1 << 1) -#define PT_USER_MASK ((pt_element_t)1 << 2) -#define PT_ACCESSED_MASK ((pt_element_t)1 << 5) -#define PT_DIRTY_MASK ((pt_element_t)1 << 6) -#define PT_PSE_MASK ((pt_element_t)1 << 7) -#define PT_NX_MASK ((pt_element_t)1 << 63) - -#define CR0_WP_MASK (1UL << 16) - -#define PFERR_PRESENT_MASK (1U << 0) -#define PFERR_WRITE_MASK (1U << 1) -#define PFERR_USER_MASK (1U << 2) -#define PFERR_RESERVED_MASK (1U << 3) -#define PFERR_FETCH_MASK (1U << 4) - -#define MSR_EFER 0xc0000080 -#define EFER_NX_MASK (1ull << 11) - -/* - * page table access check tests - */ - -enum { - AC_PTE_PRESENT, - AC_PTE_WRITABLE, - AC_PTE_USER, - AC_PTE_ACCESSED, - AC_PTE_DIRTY, - AC_PTE_NX, - AC_PTE_BIT51, - - AC_PDE_PRESENT, - AC_PDE_WRITABLE, - AC_PDE_USER, - AC_PDE_ACCESSED, - AC_PDE_DIRTY, - AC_PDE_PSE, - AC_PDE_NX, - AC_PDE_BIT51, - - AC_ACCESS_USER, - AC_ACCESS_WRITE, - AC_ACCESS_FETCH, - AC_ACCESS_TWICE, - // AC_ACCESS_PTE, - - AC_CPU_EFER_NX, - AC_CPU_CR0_WP, - - NR_AC_FLAGS -}; - -const char *ac_names[] = { - [AC_PTE_PRESENT] = "pte.p", - [AC_PTE_ACCESSED] = "pte.a", - [AC_PTE_WRITABLE] = "pte.rw", - [AC_PTE_USER] = "pte.user", - [AC_PTE_DIRTY] = "pte.d", - [AC_PTE_NX] = "pte.nx", - [AC_PTE_BIT51] = "pte.51", - [AC_PDE_PRESENT] = "pde.p", - [AC_PDE_ACCESSED] = "pde.a", - [AC_PDE_WRITABLE] = "pde.rw", - [AC_PDE_USER] = "pde.user", - [AC_PDE_DIRTY] = "pde.d", - [AC_PDE_PSE] = "pde.pse", - [AC_PDE_NX] = "pde.nx", - [AC_PDE_BIT51] = "pde.51", - [AC_ACCESS_WRITE] = "write", - [AC_ACCESS_USER] = "user", - [AC_ACCESS_FETCH] = "fetch", - [AC_ACCESS_TWICE] = "twice", - [AC_CPU_EFER_NX] = "efer.nx", - [AC_CPU_CR0_WP] = "cr0.wp", -}; - -static inline void *va(pt_element_t phys) -{ - return (void *)phys; -} - -static unsigned long read_cr0() -{ - unsigned long cr0; - - asm volatile ("mov %%cr0, %0" : "=r"(cr0)); - - return cr0; -} - -static void write_cr0(unsigned long cr0) -{ - asm volatile ("mov %0, %%cr0" : : "r"(cr0)); -} - -typedef struct { - unsigned short offset0; - unsigned short selector; - unsigned short ist : 3; - unsigned short : 5; - unsigned short type : 4; - unsigned short : 1; - unsigned short dpl : 2; - unsigned short p : 1; - unsigned short offset1; - unsigned offset2; - unsigned reserved; -} idt_entry_t; - -typedef struct { - pt_element_t pt_pool; - unsigned pt_pool_size; - unsigned pt_pool_current; -} ac_pool_t; - -typedef struct { - unsigned flags[NR_AC_FLAGS]; - void *virt; - pt_element_t phys; - pt_element_t *ptep; - pt_element_t expected_pte; - pt_element_t *pdep; - pt_element_t expected_pde; - pt_element_t ignore_pde; - int expected_fault; - unsigned expected_error; - idt_entry_t idt[256]; -} ac_test_t; - -typedef struct { - unsigned short limit; - unsigned long linear_addr; -} __attribute__((packed)) descriptor_table_t; - - -static void ac_test_show(ac_test_t *at); - -void lidt(idt_entry_t *idt, int nentries) -{ - descriptor_table_t dt; - - dt.limit = nentries * sizeof(*idt) - 1; - dt.linear_addr = (unsigned long)idt; - asm volatile ("lidt %0" : : "m"(dt)); -} - -unsigned short read_cs() -{ - unsigned short r; - - asm volatile ("mov %%cs, %0" : "=r"(r)); - return r; -} - -unsigned long long rdmsr(unsigned index) -{ - unsigned a, d; - - asm volatile("rdmsr" : "=a"(a), "=d"(d) : "c"(index)); - return ((unsigned long long)d << 32) | a; -} - -void wrmsr(unsigned index, unsigned long long val) -{ - unsigned a = val, d = val >> 32; - - asm volatile("wrmsr" : : "a"(a), "d"(d), "c"(index)); -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) -{ - memset(e, 0, sizeof *e); - e->offset0 = (unsigned long)addr; - e->selector = read_cs(); - e->ist = 0; - e->type = 14; - e->dpl = dpl; - e->p = 1; - e->offset1 = (unsigned long)addr >> 16; - e->offset2 = (unsigned long)addr >> 32; -} - -void set_cr0_wp(int wp) -{ - unsigned long cr0 = read_cr0(); - - cr0 &= ~CR0_WP_MASK; - if (wp) - cr0 |= CR0_WP_MASK; - write_cr0(cr0); -} - -void set_efer_nx(int nx) -{ - unsigned long long efer; - - efer = rdmsr(MSR_EFER); - efer &= ~EFER_NX_MASK; - if (nx) - efer |= EFER_NX_MASK; - wrmsr(MSR_EFER, efer); -} - -static void ac_env_int(ac_pool_t *pool) -{ - static idt_entry_t idt[256]; - - memset(idt, 0, sizeof(idt)); - lidt(idt, 256); - extern char page_fault, kernel_entry; - set_idt_entry(&idt[14], &page_fault, 0); - set_idt_entry(&idt[0x20], &kernel_entry, 3); - - pool->pt_pool = 33 * 1024 * 1024; - pool->pt_pool_size = 120 * 1024 * 1024 - pool->pt_pool; - pool->pt_pool_current = 0; -} - -void ac_test_init(ac_test_t *at, void *virt) -{ - wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK); - set_cr0_wp(1); - for (int i = 0; i < NR_AC_FLAGS; ++i) - at->flags[i] = 0; - at->virt = virt; - at->phys = 32 * 1024 * 1024; -} - -int ac_test_bump_one(ac_test_t *at) -{ - for (int i = 0; i < NR_AC_FLAGS; ++i) - if (!at->flags[i]) { - at->flags[i] = 1; - return 1; - } else - at->flags[i] = 0; - return 0; -} - -_Bool ac_test_legal(ac_test_t *at) -{ - if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_ACCESS_WRITE]) - return false; - return true; -} - -int ac_test_bump(ac_test_t *at) -{ - int ret; - - ret = ac_test_bump_one(at); - while (ret && !ac_test_legal(at)) - ret = ac_test_bump_one(at); - return ret; -} - -unsigned long read_cr3() -{ - unsigned long cr3; - - asm volatile ("mov %%cr3, %0" : "=r"(cr3)); - return cr3; -} - -void invlpg(void *addr) -{ - asm volatile ("invlpg (%0)" : : "r"(addr)); -} - -pt_element_t ac_test_alloc_pt(ac_pool_t *pool) -{ - pt_element_t ret = pool->pt_pool + pool->pt_pool_current; - pool->pt_pool_current += PAGE_SIZE; - return ret; -} - -_Bool ac_test_enough_room(ac_pool_t *pool) -{ - return pool->pt_pool_current + 4 * PAGE_SIZE <= pool->pt_pool_size; -} - -void ac_test_reset_pt_pool(ac_pool_t *pool) -{ - pool->pt_pool_current = 0; -} - -void ac_set_expected_status(ac_test_t *at) -{ - int pde_valid, pte_valid; - - invlpg(at->virt); - - if (at->ptep) - at->expected_pte = *at->ptep; - at->expected_pde = *at->pdep; - at->ignore_pde = 0; - at->expected_fault = 0; - at->expected_error = PFERR_PRESENT_MASK; - - pde_valid = at->flags[AC_PDE_PRESENT] - && !at->flags[AC_PDE_BIT51] - && !(at->flags[AC_PDE_NX] && !at->flags[AC_CPU_EFER_NX]); - pte_valid = pde_valid - && at->flags[AC_PTE_PRESENT] - && !at->flags[AC_PTE_BIT51] - && !(at->flags[AC_PTE_NX] && !at->flags[AC_CPU_EFER_NX]); - if (at->flags[AC_ACCESS_TWICE]) { - if (pde_valid) { - at->expected_pde |= PT_ACCESSED_MASK; - if (pte_valid) - at->expected_pte |= PT_ACCESSED_MASK; - } - } - - if (at->flags[AC_ACCESS_USER]) - at->expected_error |= PFERR_USER_MASK; - - if (at->flags[AC_ACCESS_WRITE]) - at->expected_error |= PFERR_WRITE_MASK; - - if (at->flags[AC_ACCESS_FETCH]) - at->expected_error |= PFERR_FETCH_MASK; - - if (!at->flags[AC_PDE_PRESENT]) { - at->expected_fault = 1; - at->expected_error &= ~PFERR_PRESENT_MASK; - } else if (!pde_valid) { - at->expected_fault = 1; - at->expected_error |= PFERR_RESERVED_MASK; - } - - if (at->flags[AC_ACCESS_USER] && !at->flags[AC_PDE_USER]) - at->expected_fault = 1; - - if (at->flags[AC_ACCESS_WRITE] - && !at->flags[AC_PDE_WRITABLE] - && (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER])) - at->expected_fault = 1; - - if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_PDE_NX]) - at->expected_fault = 1; - - if (!at->flags[AC_PDE_ACCESSED]) - at->ignore_pde = PT_ACCESSED_MASK; - - if (!pde_valid) - goto fault; - - if (!at->expected_fault) - at->expected_pde |= PT_ACCESSED_MASK; - - if (at->flags[AC_PDE_PSE]) { - if (at->flags[AC_ACCESS_WRITE] && !at->expected_fault) - at->expected_pde |= PT_DIRTY_MASK; - goto no_pte; - } - - if (!at->flags[AC_PTE_PRESENT]) { - at->expected_fault = 1; - at->expected_error &= ~PFERR_PRESENT_MASK; - } else if (!pte_valid) { - at->expected_fault = 1; - at->expected_error |= PFERR_RESERVED_MASK; - } - - if (at->flags[AC_ACCESS_USER] && !at->flags[AC_PTE_USER]) - at->expected_fault = 1; - - if (at->flags[AC_ACCESS_WRITE] - && !at->flags[AC_PTE_WRITABLE] - && (at->flags[AC_CPU_CR0_WP] || at->flags[AC_ACCESS_USER])) - at->expected_fault = 1; - - if (at->flags[AC_ACCESS_FETCH] && at->flags[AC_PTE_NX]) - at->expected_fault = 1; - - if (at->expected_fault) - goto fault; - - at->expected_pte |= PT_ACCESSED_MASK; - if (at->flags[AC_ACCESS_WRITE]) - at->expected_pte |= PT_DIRTY_MASK; - -no_pte: -fault: - if (!at->expected_fault) - at->ignore_pde = 0; - if (!at->flags[AC_CPU_EFER_NX]) - at->expected_error &= ~PFERR_FETCH_MASK; -} - -void ac_test_setup_pte(ac_test_t *at, ac_pool_t *pool) -{ - unsigned long root = read_cr3(); - - if (!ac_test_enough_room(pool)) - ac_test_reset_pt_pool(pool); - - at->ptep = 0; - for (int i = 4; i >= 1 && (i >= 2 || !at->flags[AC_PDE_PSE]); --i) { - pt_element_t *vroot = va(root & PT_BASE_ADDR_MASK); - unsigned index = ((unsigned long)at->virt >> (12 + (i-1) * 9)) & 511; - pt_element_t pte = 0; - switch (i) { - case 4: - case 3: - pte = vroot[index]; - pte = ac_test_alloc_pt(pool) | PT_PRESENT_MASK; - pte |= PT_WRITABLE_MASK | PT_USER_MASK; - break; - case 2: - if (!at->flags[AC_PDE_PSE]) - pte = ac_test_alloc_pt(pool); - else { - pte = at->phys & PT_PSE_BASE_ADDR_MASK; - pte |= PT_PSE_MASK; - } - if (at->flags[AC_PDE_PRESENT]) - pte |= PT_PRESENT_MASK; - if (at->flags[AC_PDE_WRITABLE]) - pte |= PT_WRITABLE_MASK; - if (at->flags[AC_PDE_USER]) - pte |= PT_USER_MASK; - if (at->flags[AC_PDE_ACCESSED]) - pte |= PT_ACCESSED_MASK; - if (at->flags[AC_PDE_DIRTY]) - pte |= PT_DIRTY_MASK; - if (at->flags[AC_PDE_NX]) - pte |= PT_NX_MASK; - if (at->flags[AC_PDE_BIT51]) - pte |= 1ull << 51; - at->pdep = &vroot[index]; - break; - case 1: - pte = at->phys & PT_BASE_ADDR_MASK; - if (at->flags[AC_PTE_PRESENT]) - pte |= PT_PRESENT_MASK; - if (at->flags[AC_PTE_WRITABLE]) - pte |= PT_WRITABLE_MASK; - if (at->flags[AC_PTE_USER]) - pte |= PT_USER_MASK; - if (at->flags[AC_PTE_ACCESSED]) - pte |= PT_ACCESSED_MASK; - if (at->flags[AC_PTE_DIRTY]) - pte |= PT_DIRTY_MASK; - if (at->flags[AC_PTE_NX]) - pte |= PT_NX_MASK; - if (at->flags[AC_PTE_BIT51]) - pte |= 1ull << 51; - at->ptep = &vroot[index]; - break; - } - vroot[index] = pte; - root = vroot[index]; - } - ac_set_expected_status(at); -} - -static void ac_test_check(ac_test_t *at, _Bool *success_ret, _Bool cond, - const char *fmt, ...) -{ - va_list ap; - char buf[500]; - - if (!*success_ret) { - return; - } - - if (!cond) { - return; - } - - *success_ret = false; - - if (!verbose) { - ac_test_show(at); - } - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - printf("FAIL: %s\n", buf); -} - -static int pt_match(pt_element_t pte1, pt_element_t pte2, pt_element_t ignore) -{ - pte1 &= ~ignore; - pte2 &= ~ignore; - return pte1 == pte2; -} - -int ac_test_do_access(ac_test_t *at) -{ - static unsigned unique = 42; - int fault = 0; - unsigned e; - static unsigned char user_stack[4096]; - unsigned long rsp; - _Bool success = true; - - ++unique; - - *((unsigned char *)at->phys) = 0xc3; /* ret */ - - unsigned r = unique; - set_cr0_wp(at->flags[AC_CPU_CR0_WP]); - set_efer_nx(at->flags[AC_CPU_EFER_NX]); - - if (at->flags[AC_ACCESS_TWICE]) { - asm volatile ( - "mov $fixed2, %%rsi \n\t" - "mov (%[addr]), %[reg] \n\t" - "fixed2:" - : [reg]"=r"(r), [fault]"=a"(fault), "=b"(e) - : [addr]"r"(at->virt) - : "rsi" - ); - fault = 0; - } - - asm volatile ("mov $fixed1, %%rsi \n\t" - "mov %%rsp, %%rdx \n\t" - "cmp $0, %[user] \n\t" - "jz do_access \n\t" - "push %%rax; mov %[user_ds], %%ax; mov %%ax, %%ds; pop %%rax \n\t" - "pushq %[user_ds] \n\t" - "pushq %[user_stack_top] \n\t" - "pushfq \n\t" - "pushq %[user_cs] \n\t" - "pushq $do_access \n\t" - "iretq \n" - "do_access: \n\t" - "cmp $0, %[fetch] \n\t" - "jnz 2f \n\t" - "cmp $0, %[write] \n\t" - "jnz 1f \n\t" - "mov (%[addr]), %[reg] \n\t" - "jmp done \n\t" - "1: mov %[reg], (%[addr]) \n\t" - "jmp done \n\t" - "2: call *%[addr] \n\t" - "done: \n" - "fixed1: \n" - "int %[kernel_entry_vector] \n\t" - "back_to_kernel:" - : [reg]"+r"(r), "+a"(fault), "=b"(e), "=&d"(rsp) - : [addr]"r"(at->virt), - [write]"r"(at->flags[AC_ACCESS_WRITE]), - [user]"r"(at->flags[AC_ACCESS_USER]), - [fetch]"r"(at->flags[AC_ACCESS_FETCH]), - [user_ds]"i"(32+3), - [user_cs]"i"(24+3), - [user_stack_top]"r"(user_stack + sizeof user_stack), - [kernel_entry_vector]"i"(0x20) - : "rsi"); - - asm volatile (".section .text.pf \n\t" - "page_fault: \n\t" - "pop %rbx \n\t" - "mov %rsi, (%rsp) \n\t" - "movl $1, %eax \n\t" - "iretq \n\t" - ".section .text"); - - asm volatile (".section .text.entry \n\t" - "kernel_entry: \n\t" - "mov %rdx, %rsp \n\t" - "jmp back_to_kernel \n\t" - ".section .text"); - - ac_test_check(at, &success, fault && !at->expected_fault, - "unexpected fault"); - ac_test_check(at, &success, !fault && at->expected_fault, - "unexpected access"); - ac_test_check(at, &success, fault && e != at->expected_error, - "error code %x expected %x", e, at->expected_error); - ac_test_check(at, &success, at->ptep && *at->ptep != at->expected_pte, - "pte %x expected %x", *at->ptep, at->expected_pte); - ac_test_check(at, &success, - !pt_match(*at->pdep, at->expected_pde, at->ignore_pde), - "pde %x expected %x", *at->pdep, at->expected_pde); - - if (success && verbose) { - printf("PASS\n"); - } - return success; -} - -static void ac_test_show(ac_test_t *at) -{ - char line[5000]; - - *line = 0; - strcat(line, "test"); - for (int i = 0; i < NR_AC_FLAGS; ++i) - if (at->flags[i]) { - strcat(line, " "); - strcat(line, ac_names[i]); - } - strcat(line, ": "); - printf("%s", line); -} - -/* - * This test case is used to triger the bug which is fixed by - * commit e09e90a5 in the kvm tree - */ -static int corrupt_hugepage_triger(ac_pool_t *pool) -{ - ac_test_t at1, at2; - - ac_test_init(&at1, (void *)(0x123400000000)); - ac_test_init(&at2, (void *)(0x666600000000)); - - at2.flags[AC_CPU_CR0_WP] = 1; - at2.flags[AC_PDE_PSE] = 1; - at2.flags[AC_PDE_PRESENT] = 1; - ac_test_setup_pte(&at2, pool); - if (!ac_test_do_access(&at2)) - goto err; - - at1.flags[AC_CPU_CR0_WP] = 1; - at1.flags[AC_PDE_PSE] = 1; - at1.flags[AC_PDE_WRITABLE] = 1; - at1.flags[AC_PDE_PRESENT] = 1; - ac_test_setup_pte(&at1, pool); - if (!ac_test_do_access(&at1)) - goto err; - - at1.flags[AC_ACCESS_WRITE] = 1; - ac_set_expected_status(&at1); - if (!ac_test_do_access(&at1)) - goto err; - - at2.flags[AC_ACCESS_WRITE] = 1; - ac_set_expected_status(&at2); - if (!ac_test_do_access(&at2)) - goto err; - - return 1; - -err: - printf("corrupt_hugepage_triger test fail\n"); - return 0; -} - -int ac_test_exec(ac_test_t *at, ac_pool_t *pool) -{ - int r; - - if (verbose) { - ac_test_show(at); - } - ac_test_setup_pte(at, pool); - r = ac_test_do_access(at); - return r; -} - -int ac_test_run(void) -{ - ac_test_t at; - ac_pool_t pool; - int tests, successes; - - printf("run\n"); - tests = successes = 0; - ac_env_int(&pool); - ac_test_init(&at, (void *)(0x123400000000 + 16 * smp_id())); - do { - ++tests; - successes += ac_test_exec(&at, &pool); - } while (ac_test_bump(&at)); - - ++tests; - successes += corrupt_hugepage_triger(&pool); - - printf("\n%d tests, %d failures\n", tests, tests - successes); - - return successes == tests; -} - -int main() -{ - int r; - - printf("starting test\n\n"); - r = ac_test_run(); - return r ? 0 : 1; -} diff --git a/kvm/test/x86/apic.c b/kvm/test/x86/apic.c deleted file mode 100644 index 48fa0f7b8..000000000 --- a/kvm/test/x86/apic.c +++ /dev/null @@ -1,309 +0,0 @@ -#include "libcflat.h" -#include "apic.h" -#include "vm.h" - -typedef struct { - unsigned short offset0; - unsigned short selector; - unsigned short ist : 3; - unsigned short : 5; - unsigned short type : 4; - unsigned short : 1; - unsigned short dpl : 2; - unsigned short p : 1; - unsigned short offset1; -#ifdef __x86_64__ - unsigned offset2; - unsigned reserved; -#endif -} idt_entry_t; - -typedef struct { - ulong regs[sizeof(ulong)*2]; - ulong func; - ulong rip; - ulong cs; - ulong rflags; -} isr_regs_t; - -#ifdef __x86_64__ -# define R "r" -#else -# define R "e" -#endif - -extern char isr_entry_point[]; - -asm ( - "isr_entry_point: \n" -#ifdef __x86_64__ - "push %r15 \n\t" - "push %r14 \n\t" - "push %r13 \n\t" - "push %r12 \n\t" - "push %r11 \n\t" - "push %r10 \n\t" - "push %r9 \n\t" - "push %r8 \n\t" -#endif - "push %"R "di \n\t" - "push %"R "si \n\t" - "push %"R "bp \n\t" - "push %"R "sp \n\t" - "push %"R "bx \n\t" - "push %"R "dx \n\t" - "push %"R "cx \n\t" - "push %"R "ax \n\t" -#ifdef __x86_64__ - "mov %rsp, %rdi \n\t" - "callq *8*16(%rsp) \n\t" -#else - "push %esp \n\t" - "calll *4+4*8(%esp) \n\t" - "add $4, %esp \n\t" -#endif - "pop %"R "ax \n\t" - "pop %"R "cx \n\t" - "pop %"R "dx \n\t" - "pop %"R "bx \n\t" - "pop %"R "bp \n\t" - "pop %"R "bp \n\t" - "pop %"R "si \n\t" - "pop %"R "di \n\t" -#ifdef __x86_64__ - "pop %r8 \n\t" - "pop %r9 \n\t" - "pop %r10 \n\t" - "pop %r11 \n\t" - "pop %r12 \n\t" - "pop %r13 \n\t" - "pop %r14 \n\t" - "pop %r15 \n\t" -#endif -#ifdef __x86_64__ - "add $8, %rsp \n\t" - "iretq \n\t" -#else - "add $4, %esp \n\t" - "iretl \n\t" -#endif - ); - -static idt_entry_t idt[256]; - -static int g_fail; -static int g_tests; - -static void outb(unsigned char data, unsigned short port) -{ - asm volatile ("out %0, %1" : : "a"(data), "d"(port)); -} - -static void report(const char *msg, int pass) -{ - ++g_tests; - printf("%s: %s\n", msg, (pass ? "PASS" : "FAIL")); - if (!pass) - ++g_fail; -} - -static void test_lapic_existence(void) -{ - u32 lvr; - - lvr = apic_read(APIC_LVR); - printf("apic version: %x\n", lvr); - report("apic existence", (u16)lvr == 0x14); -} - -#define MSR_APIC_BASE 0x0000001b - -void test_enable_x2apic(void) -{ - if (enable_x2apic()) { - printf("x2apic enabled\n"); - } else { - printf("x2apic not detected\n"); - } -} - -static void init_idt(void) -{ - struct { - u16 limit; - ulong idt; - } __attribute__((packed)) idt_ptr = { - sizeof(idt_entry_t) * 256 - 1, - (ulong)&idt, - }; - - asm volatile("lidt %0" : : "m"(idt_ptr)); -} - -static void set_idt_entry(unsigned vec, void (*func)(isr_regs_t *regs)) -{ - u8 *thunk = vmalloc(50); - ulong ptr = (ulong)thunk; - idt_entry_t ent = { - .offset0 = ptr, - .selector = read_cs(), - .ist = 0, - .type = 14, - .dpl = 0, - .p = 1, - .offset1 = ptr >> 16, -#ifdef __x86_64__ - .offset2 = ptr >> 32, -#endif - }; -#ifdef __x86_64__ - /* sub $8, %rsp */ - *thunk++ = 0x48; *thunk++ = 0x83; *thunk++ = 0xec; *thunk++ = 0x08; - /* mov $func_low, %(rsp) */ - *thunk++ = 0xc7; *thunk++ = 0x04; *thunk++ = 0x24; - *(u32 *)thunk = (ulong)func; thunk += 4; - /* mov $func_high, %(rsp+4) */ - *thunk++ = 0xc7; *thunk++ = 0x44; *thunk++ = 0x24; *thunk++ = 0x04; - *(u32 *)thunk = (ulong)func >> 32; thunk += 4; - /* jmp isr_entry_point */ - *thunk ++ = 0xe9; - *(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); -#else - /* push $func */ - *thunk++ = 0x68; - *(u32 *)thunk = (ulong)func; - /* jmp isr_entry_point */ - *thunk ++ = 0xe9; - *(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); -#endif - idt[vec] = ent; -} - -static void irq_disable(void) -{ - asm volatile("cli"); -} - -static void irq_enable(void) -{ - asm volatile("sti"); -} - -static void eoi(void) -{ - apic_write(APIC_EOI, 0); -} - -static int ipi_count; - -static void self_ipi_isr(isr_regs_t *regs) -{ - ++ipi_count; - eoi(); -} - -static void test_self_ipi(void) -{ - int vec = 0xf1; - - set_idt_entry(vec, self_ipi_isr); - irq_enable(); - apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | vec, - 0); - asm volatile ("nop"); - report("self ipi", ipi_count == 1); -} - -static void set_ioapic_redir(unsigned line, unsigned vec) -{ - ioapic_redir_entry_t e = { - .vector = vec, - .delivery_mode = 0, - .trig_mode = 0, - }; - - ioapic_write_redir(line, e); -} - -static void set_irq_line(unsigned line, int val) -{ - asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line))); -} - -static void toggle_irq_line(unsigned line) -{ - set_irq_line(line, 1); - set_irq_line(line, 0); -} - -static int g_isr_77; - -static void ioapic_isr_77(isr_regs_t *regs) -{ - ++g_isr_77; - eoi(); -} - -static void test_ioapic_intr(void) -{ - set_idt_entry(0x77, ioapic_isr_77); - set_ioapic_redir(0x10, 0x77); - toggle_irq_line(0x10); - asm volatile ("nop"); - report("ioapic interrupt", g_isr_77 == 1); -} - -static int g_78, g_66, g_66_after_78; -static ulong g_66_rip, g_78_rip; - -static void ioapic_isr_78(isr_regs_t *regs) -{ - ++g_78; - g_78_rip = regs->rip; - eoi(); -} - -static void ioapic_isr_66(isr_regs_t *regs) -{ - ++g_66; - if (g_78) - ++g_66_after_78; - g_66_rip = regs->rip; - eoi(); -} - -static void test_ioapic_simultaneous(void) -{ - set_idt_entry(0x78, ioapic_isr_78); - set_idt_entry(0x66, ioapic_isr_66); - set_ioapic_redir(0x10, 0x78); - set_ioapic_redir(0x11, 0x66); - irq_disable(); - toggle_irq_line(0x11); - toggle_irq_line(0x10); - irq_enable(); - asm volatile ("nop"); - report("ioapic simultaneous interrupt", - g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip); -} - -int main() -{ - setup_vm(); - - test_lapic_existence(); - - mask_pic_interrupts(); - enable_apic(); - test_enable_x2apic(); - init_idt(); - - test_self_ipi(); - - test_ioapic_intr(); - test_ioapic_simultaneous(); - - printf("\nsummary: %d tests, %d failures\n", g_tests, g_fail); - - return g_fail != 0; -} diff --git a/kvm/test/x86/cstart.S b/kvm/test/x86/cstart.S deleted file mode 100644 index 0471b92e7..000000000 --- a/kvm/test/x86/cstart.S +++ /dev/null @@ -1,19 +0,0 @@ - - -.bss - -.section .init - -mb_magic = 0x1BADB002 -mb_flags = 0x0 - - # multiboot header - .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) - -.globl start -start: - call main - push %eax - call exit - - diff --git a/kvm/test/x86/cstart64.S b/kvm/test/x86/cstart64.S deleted file mode 100644 index 46e9d5cd4..000000000 --- a/kvm/test/x86/cstart64.S +++ /dev/null @@ -1,230 +0,0 @@ - -#include "apic-defs.h" - -.globl boot_idt -boot_idt = 0 - -ipi_vector = 0x20 - -max_cpus = 4 - -.bss - - . = . + 4096 * max_cpus - .align 16 -stacktop: - - . = . + 4096 - .align 16 -ring0stacktop: - -.data - -.align 4096 -ptl2: -i = 0 - .rept 512 * 4 - .quad 0x1e7 | (i << 21) - i = i + 1 - .endr - -.align 4096 -ptl3: - .quad ptl2 + 7 + 0 * 4096 - .quad ptl2 + 7 + 1 * 4096 - .quad ptl2 + 7 + 2 * 4096 - .quad ptl2 + 7 + 3 * 4096 - -.align 4096 -ptl4: - .quad ptl3 + 7 - -.align 4096 - -gdt64_desc: - .word gdt64_end - gdt64 - 1 - .quad gdt64 - -gdt64: - .quad 0 - .quad 0x00af9b000000ffff // 64-bit code segment - .quad 0x00cf93000000ffff // 64-bit data segment - .quad 0x00affb000000ffff // 64-bit code segment (user) - .quad 0x00cff3000000ffff // 64-bit data segment (user) - .quad 0x00cf9b000000ffff // 32-bit code segment - .quad 0x00cf92000000ffff // 32-bit code segment - .quad 0x008F9A000000FFFF // 16-bit code segment - .quad 0x008F92000000FFFF // 16-bit data segment - -tss_descr: - .rept max_cpus - .quad 0x000089000000ffff // 64-bit avail tss - .quad 0 // tss high addr - .endr -gdt64_end: - -i = 0 -tss: - .rept max_cpus - .long 0 - .quad ring0stacktop - i * 4096 - .quad 0, 0, 0 - .quad 0, 0, 0, 0, 0, 0, 0, 0 - .long 0, 0, 0 -i = i + 1 - .endr -tss_end: - -.section .init - -.code32 - -mb_magic = 0x1BADB002 -mb_flags = 0x0 - - # multiboot header - .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) - -MSR_GS_BASE = 0xc0000101 - -.macro setup_percpu_area - lea -4096(%esp), %eax - mov $0, %edx - mov $MSR_GS_BASE, %ecx - wrmsr -.endm - -.globl start -start: - mov $stacktop, %esp - setup_percpu_area - call prepare_64 - jmpl $8, $start64 - -prepare_64: - lgdt gdt64_desc - - mov %cr4, %eax - bts $5, %eax // pae - mov %eax, %cr4 - - mov $ptl4, %eax - mov %eax, %cr3 - -efer = 0xc0000080 - mov $efer, %ecx - rdmsr - bts $8, %eax - wrmsr - - mov %cr0, %eax - bts $0, %eax - bts $31, %eax - mov %eax, %cr0 - ret - -smp_stacktop: .long 0xa0000 - -.align 16 - -gdt32: - .quad 0 - .quad 0x00cf9b000000ffff // flat 32-bit code segment - .quad 0x00cf93000000ffff // flat 32-bit data segment -gdt32_end: - -.code16 -sipi_entry: - mov %cr0, %eax - or $1, %eax - mov %eax, %cr0 - lgdtl gdt32_descr - sipi_entry - ljmpl $8, $ap_start32 - -gdt32_descr: - .word gdt32_end - gdt32 - 1 - .long gdt32 - -sipi_end: - -.code32 -ap_start32: - mov $0x10, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss - mov $-4096, %esp - lock/xaddl %esp, smp_stacktop - setup_percpu_area - call prepare_64 - ljmpl $8, $ap_start64 - -.code64 -ap_start64: - call load_tss - call enable_apic - call enable_x2apic - sti - nop - lock incw cpu_online_count - -1: hlt - jmp 1b - -start64: - call load_tss - call mask_pic_interrupts - call enable_apic - call smp_init - call enable_x2apic - call main - mov %eax, %edi - call exit - -idt_descr: - .word 16 * 256 - 1 - .quad boot_idt - -load_tss: - lidtq idt_descr - mov $0, %eax - mov %ax, %ss - mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax - mov (%rax), %eax - shr $24, %eax - mov %eax, %ebx - shl $4, %ebx - mov $((tss_end - tss) / max_cpus), %edx - imul %edx - add $tss, %rax - mov %ax, tss_descr+2(%rbx) - shr $16, %rax - mov %al, tss_descr+4(%rbx) - shr $8, %rax - mov %al, tss_descr+7(%rbx) - shr $8, %rax - mov %eax, tss_descr+8(%rbx) - lea tss_descr-gdt64(%rbx), %rax - ltr %ax - ret - -smp_init: - cld - lea sipi_entry, %rsi - xor %rdi, %rdi - mov $(sipi_end - sipi_entry), %rcx - rep/movsb - mov $APIC_DEFAULT_PHYS_BASE, %eax - movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) - movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax) - movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) - call fwcfg_get_nb_cpus -1: pause - cmpw %ax, cpu_online_count - jne 1b -smp_init_done: - ret - -cpu_online_count: .word 1 diff --git a/kvm/test/x86/emulator.c b/kvm/test/x86/emulator.c deleted file mode 100644 index eefb76429..000000000 --- a/kvm/test/x86/emulator.c +++ /dev/null @@ -1,397 +0,0 @@ -#include "ioram.h" -#include "vm.h" -#include "libcflat.h" - -#define memset __builtin_memset -#define TESTDEV_IO_PORT 0xe0 - -int fails, tests; - -void report(const char *name, int result) -{ - ++tests; - if (result) - printf("PASS: %s\n", name); - else { - printf("FAIL: %s\n", name); - ++fails; - } -} - -static char st1[] = "abcdefghijklmnop"; - -void test_stringio() -{ - unsigned char r = 0; - asm volatile("cld \n\t" - "movw %0, %%dx \n\t" - "rep outsb \n\t" - : : "i"((short)TESTDEV_IO_PORT), - "S"(st1), "c"(sizeof(st1) - 1)); - asm volatile("inb %1, %0\n\t" : "=a"(r) : "i"((short)TESTDEV_IO_PORT)); - report("outsb up", r == st1[sizeof(st1) - 2]); /* last char */ - - asm volatile("std \n\t" - "movw %0, %%dx \n\t" - "rep outsb \n\t" - : : "i"((short)TESTDEV_IO_PORT), - "S"(st1 + sizeof(st1) - 2), "c"(sizeof(st1) - 1)); - asm volatile("cld \n\t" : : ); - asm volatile("in %1, %0\n\t" : "=a"(r) : "i"((short)TESTDEV_IO_PORT)); - report("outsb down", r == st1[0]); -} - -void test_cmps_one(unsigned char *m1, unsigned char *m3) -{ - void *rsi, *rdi; - long rcx, tmp; - - rsi = m1; rdi = m3; rcx = 30; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsb" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpsb (1)", rcx == 0 && rsi == m1 + 30 && rdi == m3 + 30); - - rsi = m1; rdi = m3; rcx = 15; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsw" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpsw (1)", rcx == 0 && rsi == m1 + 30 && rdi == m3 + 30); - - rsi = m1; rdi = m3; rcx = 7; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsl" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpll (1)", rcx == 0 && rsi == m1 + 28 && rdi == m3 + 28); - - rsi = m1; rdi = m3; rcx = 4; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsq" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpsq (1)", rcx == 0 && rsi == m1 + 32 && rdi == m3 + 32); - - rsi = m1; rdi = m3; rcx = 130; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsb" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpsb (2)", - rcx == 29 && rsi == m1 + 101 && rdi == m3 + 101); - - rsi = m1; rdi = m3; rcx = 65; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsw" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpsw (2)", - rcx == 14 && rsi == m1 + 102 && rdi == m3 + 102); - - rsi = m1; rdi = m3; rcx = 32; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsl" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpll (2)", - rcx == 6 && rsi == m1 + 104 && rdi == m3 + 104); - - rsi = m1; rdi = m3; rcx = 16; - asm volatile("xor %[tmp], %[tmp] \n\t" - "repe/cmpsq" - : "+S"(rsi), "+D"(rdi), "+c"(rcx), [tmp]"=&r"(tmp) - : : "cc"); - report("repe/cmpsq (2)", - rcx == 3 && rsi == m1 + 104 && rdi == m3 + 104); - -} - -void test_cmps(void *mem) -{ - unsigned char *m1 = mem, *m2 = mem + 1024; - unsigned char m3[1024]; - - for (int i = 0; i < 100; ++i) - m1[i] = m2[i] = m3[i] = i; - for (int i = 100; i < 200; ++i) - m1[i] = (m3[i] = m2[i] = i) + 1; - test_cmps_one(m1, m3); - test_cmps_one(m1, m2); -} - -void test_cr8(void) -{ - unsigned long src, dst; - - dst = 777; - src = 3; - asm volatile("mov %[src], %%cr8; mov %%cr8, %[dst]" - : [dst]"+r"(dst), [src]"+r"(src)); - report("mov %cr8", dst == 3 && src == 3); -} - -void test_push(void *mem) -{ - unsigned long tmp; - unsigned long *stack_top = mem + 4096; - unsigned long *new_stack_top; - unsigned long memw = 0x123456789abcdeful; - - memset(mem, 0x55, (void *)stack_top - mem); - - asm volatile("mov %%rsp, %[tmp] \n\t" - "mov %[stack_top], %%rsp \n\t" - "pushq $-7 \n\t" - "pushq %[reg] \n\t" - "pushq (%[mem]) \n\t" - "pushq $-7070707 \n\t" - "mov %%rsp, %[new_stack_top] \n\t" - "mov %[tmp], %%rsp" - : [tmp]"=&r"(tmp), [new_stack_top]"=r"(new_stack_top) - : [stack_top]"r"(stack_top), - [reg]"r"(-17l), [mem]"r"(&memw) - : "memory"); - - report("push $imm8", stack_top[-1] == -7ul); - report("push %reg", stack_top[-2] == -17ul); - report("push mem", stack_top[-3] == 0x123456789abcdeful); - report("push $imm", stack_top[-4] == -7070707); -} - -void test_pop(void *mem) -{ - unsigned long tmp; - unsigned long *stack_top = mem + 4096; - unsigned long memw = 0x123456789abcdeful; - static unsigned long tmp2; - - memset(mem, 0x55, (void *)stack_top - mem); - - asm volatile("pushq %[val] \n\t" - "popq (%[mem])" - : : [val]"m"(memw), [mem]"r"(mem) : "memory"); - report("pop mem", *(unsigned long *)mem == memw); - - memw = 7 - memw; - asm volatile("mov %%rsp, %[tmp] \n\t" - "mov %[stack_top], %%rsp \n\t" - "pushq %[val] \n\t" - "popq %[tmp2] \n\t" - "mov %[tmp], %%rsp" - : [tmp]"=&r"(tmp), [tmp2]"=m"(tmp2) - : [val]"r"(memw), [stack_top]"r"(stack_top) - : "memory"); - report("pop mem (2)", tmp2 == memw); - - memw = 129443 - memw; - asm volatile("mov %%rsp, %[tmp] \n\t" - "mov %[stack_top], %%rsp \n\t" - "pushq %[val] \n\t" - "popq %[tmp2] \n\t" - "mov %[tmp], %%rsp" - : [tmp]"=&r"(tmp), [tmp2]"=r"(tmp2) - : [val]"r"(memw), [stack_top]"r"(stack_top) - : "memory"); - report("pop reg", tmp2 == memw); - - asm volatile("mov %%rsp, %[tmp] \n\t" - "mov %[stack_top], %%rsp \n\t" - "push $1f \n\t" - "ret \n\t" - "2: jmp 2b \n\t" - "1: mov %[tmp], %%rsp" - : [tmp]"=&r"(tmp) : [stack_top]"r"(stack_top) - : "memory"); - report("ret", 1); -} - -void test_ljmp(void *mem) -{ - unsigned char *m = mem; - volatile int res = 1; - - *(unsigned long**)m = &&jmpf; - asm volatile ("data16/mov %%cs, %0":"=m"(*(m + sizeof(unsigned long)))); - asm volatile ("rex64/ljmp *%0"::"m"(*m)); - res = 0; -jmpf: - report("ljmp", res); -} - -void test_incdecnotneg(void *mem) -{ - unsigned long *m = mem, v = 1234; - unsigned char *mb = mem, vb = 66; - - *m = 0; - - asm volatile ("incl %0":"+m"(*m)); - report("incl", *m == 1); - asm volatile ("decl %0":"+m"(*m)); - report("decl", *m == 0); - asm volatile ("incb %0":"+m"(*m)); - report("incb", *m == 1); - asm volatile ("decb %0":"+m"(*m)); - report("decb", *m == 0); - - asm volatile ("lock incl %0":"+m"(*m)); - report("lock incl", *m == 1); - asm volatile ("lock decl %0":"+m"(*m)); - report("lock decl", *m == 0); - asm volatile ("lock incb %0":"+m"(*m)); - report("lock incb", *m == 1); - asm volatile ("lock decb %0":"+m"(*m)); - report("lock decb", *m == 0); - - *m = v; - - asm ("lock negq %0" : "+m"(*m)); v = -v; - report("lock negl", *m == v); - asm ("lock notq %0" : "+m"(*m)); v = ~v; - report("lock notl", *m == v); - - *mb = vb; - - asm ("lock negb %0" : "+m"(*mb)); vb = -vb; - report("lock negb", *mb == vb); - asm ("lock notb %0" : "+m"(*mb)); vb = ~vb; - report("lock notb", *mb == vb); -} - -void test_smsw(void) -{ - char mem[16]; - unsigned short msw, msw_orig, *pmsw; - int i, zero; - - msw_orig = read_cr0(); - - asm("smsw %0" : "=r"(msw)); - report("smsw (1)", msw == msw_orig); - - memset(mem, 0, 16); - pmsw = (void *)mem; - asm("smsw %0" : "=m"(pmsw[4])); - zero = 1; - for (i = 0; i < 8; ++i) - if (i != 4 && pmsw[i]) - zero = 0; - report("smsw (2)", msw == pmsw[4] && zero); -} - -void test_lmsw(void) -{ - char mem[16]; - unsigned short msw, *pmsw; - unsigned long cr0; - - cr0 = read_cr0(); - - msw = cr0 ^ 8; - asm("lmsw %0" : : "r"(msw)); - printf("before %lx after %lx\n", cr0, read_cr0()); - report("lmsw (1)", (cr0 ^ read_cr0()) == 8); - - pmsw = (void *)mem; - *pmsw = cr0; - asm("lmsw %0" : : "m"(*pmsw)); - printf("before %lx after %lx\n", cr0, read_cr0()); - report("lmsw (2)", cr0 == read_cr0()); - - /* lmsw can't clear cr0.pe */ - msw = (cr0 & ~1ul) ^ 4; /* change EM to force trap */ - asm("lmsw %0" : : "r"(msw)); - report("lmsw (3)", (cr0 ^ read_cr0()) == 4 && (cr0 & 1)); - - /* back to normal */ - msw = cr0; - asm("lmsw %0" : : "r"(msw)); -} - -void test_xchg(void *mem) -{ - unsigned long *memq = mem; - unsigned long rax; - - asm volatile("mov $0x123456789abcdef, %%rax\n\t" - "mov %%rax, (%[memq])\n\t" - "mov $0xfedcba9876543210, %%rax\n\t" - "xchg %%al, (%[memq])\n\t" - "mov %%rax, %[rax]\n\t" - : [rax]"=r"(rax) - : [memq]"r"(memq) - : "memory"); - report("xchg reg, r/m (1)", - rax == 0xfedcba98765432ef && *memq == 0x123456789abcd10); - - asm volatile("mov $0x123456789abcdef, %%rax\n\t" - "mov %%rax, (%[memq])\n\t" - "mov $0xfedcba9876543210, %%rax\n\t" - "xchg %%ax, (%[memq])\n\t" - "mov %%rax, %[rax]\n\t" - : [rax]"=r"(rax) - : [memq]"r"(memq) - : "memory"); - report("xchg reg, r/m (2)", - rax == 0xfedcba987654cdef && *memq == 0x123456789ab3210); - - asm volatile("mov $0x123456789abcdef, %%rax\n\t" - "mov %%rax, (%[memq])\n\t" - "mov $0xfedcba9876543210, %%rax\n\t" - "xchg %%eax, (%[memq])\n\t" - "mov %%rax, %[rax]\n\t" - : [rax]"=r"(rax) - : [memq]"r"(memq) - : "memory"); - report("xchg reg, r/m (3)", - rax == 0x89abcdef && *memq == 0x123456776543210); - - asm volatile("mov $0x123456789abcdef, %%rax\n\t" - "mov %%rax, (%[memq])\n\t" - "mov $0xfedcba9876543210, %%rax\n\t" - "xchg %%rax, (%[memq])\n\t" - "mov %%rax, %[rax]\n\t" - : [rax]"=r"(rax) - : [memq]"r"(memq) - : "memory"); - report("xchg reg, r/m (4)", - rax == 0x123456789abcdef && *memq == 0xfedcba9876543210); -} - -int main() -{ - void *mem; - unsigned long t1, t2; - - setup_vm(); - mem = vmap(IORAM_BASE_PHYS, IORAM_LEN); - - // test mov reg, r/m and mov r/m, reg - t1 = 0x123456789abcdef; - asm volatile("mov %[t1], (%[mem]) \n\t" - "mov (%[mem]), %[t2]" - : [t2]"=r"(t2) - : [t1]"r"(t1), [mem]"r"(mem) - : "memory"); - report("mov reg, r/m (1)", t2 == 0x123456789abcdef); - - test_cmps(mem); - - test_push(mem); - test_pop(mem); - - test_xchg(mem); - - test_cr8(); - - test_smsw(); - test_lmsw(); - test_ljmp(mem); - test_stringio(); - test_incdecnotneg(mem); - - printf("\nSUMMARY: %d tests, %d failures\n", tests, fails); - return fails ? 1 : 0; -} diff --git a/kvm/test/x86/hypercall.c b/kvm/test/x86/hypercall.c deleted file mode 100644 index 95120a23b..000000000 --- a/kvm/test/x86/hypercall.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "libcflat.h" - -#define KVM_HYPERCALL_INTEL ".byte 0x0f,0x01,0xc1" -#define KVM_HYPERCALL_AMD ".byte 0x0f,0x01,0xd9" - -static inline long kvm_hypercall0_intel(unsigned int nr) -{ - long ret; - asm volatile(KVM_HYPERCALL_INTEL - : "=a"(ret) - : "a"(nr)); - return ret; -} - -static inline long kvm_hypercall0_amd(unsigned int nr) -{ - long ret; - asm volatile(KVM_HYPERCALL_AMD - : "=a"(ret) - : "a"(nr)); - return ret; -} - -int main(int ac, char **av) -{ - kvm_hypercall0_intel(-1u); - printf("Hypercall via VMCALL: OK\n"); - kvm_hypercall0_amd(-1u); - printf("Hypercall via VMMCALL: OK\n"); - return 0; -} diff --git a/kvm/test/x86/idt.c b/kvm/test/x86/idt.c deleted file mode 100644 index 590839f6a..000000000 --- a/kvm/test/x86/idt.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "idt.h" -#include "libcflat.h" - -typedef struct { - unsigned short offset0; - unsigned short selector; - unsigned short ist : 3; - unsigned short : 5; - unsigned short type : 4; - unsigned short : 1; - unsigned short dpl : 2; - unsigned short p : 1; - unsigned short offset1; - unsigned offset2; - unsigned reserved; -} idt_entry_t; - -static idt_entry_t idt[256]; - -typedef struct { - unsigned short limit; - unsigned long linear_addr; -} __attribute__((packed)) descriptor_table_t; - -void lidt(idt_entry_t *idt, int nentries) -{ - descriptor_table_t dt; - - dt.limit = nentries * sizeof(*idt) - 1; - dt.linear_addr = (unsigned long)idt; - asm volatile ("lidt %0" : : "m"(dt)); -} - -unsigned short read_cs() -{ - unsigned short r; - - asm volatile ("mov %%cs, %0" : "=r"(r)); - return r; -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) -{ - memset(e, 0, sizeof *e); - e->offset0 = (unsigned long)addr; - e->selector = read_cs(); - e->ist = 0; - e->type = 14; - e->dpl = dpl; - e->p = 1; - e->offset1 = (unsigned long)addr >> 16; - e->offset2 = (unsigned long)addr >> 32; -} - -struct ex_regs { - unsigned long rax, rcx, rdx, rbx; - unsigned long dummy, rbp, rsi, rdi; - unsigned long r8, r9, r10, r11; - unsigned long r12, r13, r14, r15; - unsigned long vector; - unsigned long error_code; - unsigned long rip; - unsigned long cs; - unsigned long rflags; -}; - -struct ex_record { - unsigned long rip; - unsigned long handler; -}; - -extern struct ex_record exception_table_start, exception_table_end; - -void do_handle_exception(struct ex_regs *regs) -{ - struct ex_record *ex; - unsigned ex_val; - - ex_val = regs->vector | (regs->error_code << 16); - - asm("mov %0, %%gs:4" : : "r"(ex_val)); - - for (ex = &exception_table_start; ex != &exception_table_end; ++ex) { - if (ex->rip == regs->rip) { - regs->rip = ex->handler; - return; - } - } - printf("unhandled excecption\n"); - exit(7); -} - -asm (".pushsection .text \n\t" - "ud_fault: \n\t" - "pushq $0 \n\t" - "pushq $6 \n\t" - "jmp handle_exception \n\t" - - "gp_fault: \n\t" - "pushq $13 \n\t" - "jmp handle_exception \n\t" - - "handle_exception: \n\t" - "push %r15; push %r14; push %r13; push %r12 \n\t" - "push %r11; push %r10; push %r9; push %r8 \n\t" - "push %rdi; push %rsi; push %rbp; sub $8, %rsp \n\t" - "push %rbx; push %rdx; push %rcx; push %rax \n\t" - "mov %rsp, %rdi \n\t" - "call do_handle_exception \n\t" - "pop %rax; pop %rcx; pop %rdx; pop %rbx \n\t" - "add $8, %rsp; pop %rbp; pop %rsi; pop %rdi \n\t" - "pop %r8; pop %r9; pop %r10; pop %r11 \n\t" - "pop %r12; pop %r13; pop %r14; pop %r15 \n\t" - "add $16, %rsp \n\t" - "iretq \n\t" - ".popsection"); - - -void setup_idt(void) -{ - extern char ud_fault, gp_fault; - - lidt(idt, 256); - set_idt_entry(&idt[6], &ud_fault, 0); - set_idt_entry(&idt[13], &gp_fault, 0); -} - -unsigned exception_vector(void) -{ - unsigned short vector; - - asm("mov %%gs:4, %0" : "=rm"(vector)); - return vector; -} - -unsigned exception_error_code(void) -{ - unsigned short error_code; - - asm("mov %%gs:6, %0" : "=rm"(error_code)); - return error_code; -} diff --git a/kvm/test/x86/idt_test.c b/kvm/test/x86/idt_test.c deleted file mode 100644 index 59256d41c..000000000 --- a/kvm/test/x86/idt_test.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "libcflat.h" -#include "idt.h" - -int test_ud2(void) -{ - asm volatile(ASM_TRY("1f") - "ud2 \n\t" - "1:" :); - return exception_vector(); -} - -int test_gp(void) -{ - unsigned long tmp; - - asm volatile("mov $0xffffffff, %0 \n\t" - ASM_TRY("1f") - "mov %0, %%cr4\n\t" - "1:" - : "=a"(tmp)); - return exception_vector(); -} - -static int nr_fail, nr_test; - -static void report(int cond, const char *name) -{ - ++nr_test; - if (!cond) { - ++nr_fail; - printf("%s: FAIL\n", name); - } else { - printf("%s: PASS\n", name); - } -} - -int main(void) -{ - int r; - - printf("Starting IDT test\n"); - setup_idt(); - r = test_gp(); - report(r == GP_VECTOR, "Testing #GP"); - r = test_ud2(); - report(r == UD_VECTOR, "Testing #UD"); - printf("%d failures of %d tests\n", nr_fail, nr_test); - return !nr_fail ? 0 : 1; -} diff --git a/kvm/test/x86/ioram.h b/kvm/test/x86/ioram.h deleted file mode 100644 index 2938142b3..000000000 --- a/kvm/test/x86/ioram.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __IO_RAM_H -#define __IO_RAM_H - -#define IORAM_BASE_PHYS 0xff000000UL -#define IORAM_LEN 0x10000UL - -#endif diff --git a/kvm/test/x86/msr.c b/kvm/test/x86/msr.c deleted file mode 100644 index 1e7987de2..000000000 --- a/kvm/test/x86/msr.c +++ /dev/null @@ -1,141 +0,0 @@ -/* msr tests */ - -#include "libcflat.h" - -struct msr_info { - int index; - char *name; - struct tc { - int valid; - unsigned long long value; - unsigned long long expected; - } val_pairs[20]; -}; - - -#define addr_64 0x0000123456789abcULL - -struct msr_info msr_info[] = -{ - { .index = 0x0000001b, .name = "MSR_IA32_APICBASE", - .val_pairs = { - { .valid = 1, .value = 0x0000000056789900, .expected = 0x0000000056789900}, - { .valid = 1, .value = 0x0000000056789D01, .expected = 0x0000000056789D01}, - } - }, - { .index = 0x00000174, .name = "IA32_SYSENTER_CS", - .val_pairs = {{ .valid = 1, .value = 0x1234, .expected = 0x1234}} - }, - { .index = 0x00000175, .name = "MSR_IA32_SYSENTER_ESP", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0x00000176, .name = "IA32_SYSENTER_EIP", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0x000001a0, .name = "MSR_IA32_MISC_ENABLE", - // reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63 - .val_pairs = {{ .valid = 1, .value = 0x400c51889, .expected = 0x400c51889}} - }, - { .index = 0x00000277, .name = "MSR_IA32_CR_PAT", - .val_pairs = {{ .valid = 1, .value = 0x07070707, .expected = 0x07070707}} - }, - { .index = 0xc0000100, .name = "MSR_FS_BASE", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0xc0000101, .name = "MSR_GS_BASE", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0xc0000102, .name = "MSR_KERNEL_GS_BASE", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0xc0000080, .name = "MSR_EFER", - .val_pairs = {{ .valid = 1, .value = 0xD00, .expected = 0xD00}} - }, - { .index = 0xc0000082, .name = "MSR_LSTAR", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0xc0000083, .name = "MSR_CSTAR", - .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} - }, - { .index = 0xc0000084, .name = "MSR_SYSCALL_MASK", - .val_pairs = {{ .valid = 1, .value = 0xffffffff, .expected = 0xffffffff}} - }, - -// MSR_IA32_DEBUGCTLMSR needs svm feature LBRV -// MSR_VM_HSAVE_PA only AMD host -}; - -static int find_msr_info(int msr_index) -{ - int i; - for (i = 0; i < sizeof(msr_info)/sizeof(msr_info[0]) ; i++) { - if (msr_info[i].index == msr_index) { - return i; - } - } - return -1; -} - - -int nr_passed, nr_tests; - -static void report(const char *name, int passed) -{ - ++nr_tests; - if (passed) - ++nr_passed; - printf("%s: %s\n", name, passed ? "PASS" : "FAIL"); -} - -static void wrmsr(unsigned index, unsigned long long value) -{ - unsigned a = value, d = value >> 32; - - asm volatile("wrmsr" : : "a"(a), "d"(d), "c"(index)); -} - -static unsigned long long rdmsr(unsigned index) -{ - unsigned a, d; - - asm volatile("rdmsr" : "=a"(a), "=d"(d) : "c"(index)); - return ((unsigned long long)d << 32) | a; -} - -static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected) -{ - unsigned long long r = 0; - int index; - char *sptr; - if ((index = find_msr_info(msr_index)) != -1) { - sptr = msr_info[index].name; - } else { - printf("couldn't find name for msr # 0x%x, skipping\n", msr_index); - return; - } - wrmsr(msr_index, input); - r = rdmsr(msr_index); - if (expected != r) { - printf("testing %s: output = 0x%x:0x%x expected = 0x%x:0x%x\n", sptr, r >> 32, r, expected >> 32, expected); - } - report(sptr, expected == r); -} - -int main(int ac, char **av) -{ - int i, j; - for (i = 0 ; i < sizeof(msr_info) / sizeof(msr_info[0]); i++) { - for (j = 0; j < sizeof(msr_info[i].val_pairs) / sizeof(msr_info[i].val_pairs[0]); j++) { - if (msr_info[i].val_pairs[j].valid) { - test_msr_rw(msr_info[i].index, msr_info[i].val_pairs[j].value, msr_info[i].val_pairs[j].expected); - } else { - break; - } - } - } - - printf("%d tests, %d failures\n", nr_tests, nr_tests - nr_passed); - - return nr_passed == nr_tests ? 0 : 1; -} - diff --git a/kvm/test/x86/port80.c b/kvm/test/x86/port80.c deleted file mode 100644 index 522c1a4dc..000000000 --- a/kvm/test/x86/port80.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "libcflat.h" - -int main() -{ - int i; - - printf("begining port 0x80 write test\n"); - for (i = 0; i < 10000000; ++i) - asm volatile("outb %al, $0x80"); - printf("done\n"); - return 0; -} diff --git a/kvm/test/x86/print.S b/kvm/test/x86/print.S deleted file mode 100644 index c1b1c0d7c..000000000 --- a/kvm/test/x86/print.S +++ /dev/null @@ -1,31 +0,0 @@ - -#include "print.h" - -#define PSEUDO_SERIAL_PORT 0xf1 - - -.text - PRINT "boo" - hlt -1: jmp 1b - -.globl print -print: - push %rax - push %rsi - push %rdx - - mov %rdi, %rsi - mov $(PSEUDO_SERIAL_PORT), %edx - -putchar: - cmpb $0, (%rsi) - jz done - outsb - jmp putchar -done: - - pop %rdx - pop %rsi - pop %rax - ret diff --git a/kvm/test/x86/print.h b/kvm/test/x86/print.h deleted file mode 100644 index d5bd2f997..000000000 --- a/kvm/test/x86/print.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PRINT_H -#define PRINT_H - -.macro PRINT text - -.data - -333: .asciz "\text\n" - -.previous - - push %rdi - lea 333b, %rdi - call print - pop %rdi - -.endm - -#endif diff --git a/kvm/test/x86/realmode.c b/kvm/test/x86/realmode.c deleted file mode 100644 index bb161ac48..000000000 --- a/kvm/test/x86/realmode.c +++ /dev/null @@ -1,1027 +0,0 @@ -asm(".code16gcc"); - -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned u32; -typedef unsigned long long u64; - -void test_function(void); - -asm( - "test_function: \n\t" - "mov $0x1234, %eax \n\t" - "ret" - ); - -static int strlen(const char *str) -{ - int n; - - for (n = 0; *str; ++str) - ++n; - return n; -} - -static void print_serial(const char *buf) -{ - unsigned long len = strlen(buf); - - asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); -} - -static void exit(int code) -{ - asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4)); -} - -struct regs { - u32 eax, ebx, ecx, edx; - u32 esi, edi, esp, ebp; - u32 eip, eflags; -}; - -static u64 gdt[] = { - 0, - 0x00cf9b000000ffffull, // flat 32-bit code segment - 0x00cf93000000ffffull, // flat 32-bit data segment -}; - -static struct { - u16 limit; - void *base; -} __attribute__((packed)) gdt_descr = { - sizeof(gdt) - 1, - gdt, -}; - -static void exec_in_big_real_mode(const struct regs *inregs, - struct regs *outregs, - const u8 *insn, int insn_len) -{ - unsigned long tmp; - static struct regs save; - int i; - extern u8 test_insn[], test_insn_end[]; - - for (i = 0; i < insn_len; ++i) - test_insn[i] = insn[i]; - for (; i < test_insn_end - test_insn; ++i) - test_insn[i] = 0x90; // nop - - save = *inregs; - asm volatile( - "lgdtl %[gdt_descr] \n\t" - "mov %%cr0, %[tmp] \n\t" - "or $1, %[tmp] \n\t" - "mov %[tmp], %%cr0 \n\t" - "mov %[bigseg], %%gs \n\t" - "and $-2, %[tmp] \n\t" - "mov %[tmp], %%cr0 \n\t" - - "xchg %%eax, %[save]+0 \n\t" - "xchg %%ebx, %[save]+4 \n\t" - "xchg %%ecx, %[save]+8 \n\t" - "xchg %%edx, %[save]+12 \n\t" - "xchg %%esi, %[save]+16 \n\t" - "xchg %%edi, %[save]+20 \n\t" - "xchg %%esp, %[save]+24 \n\t" - "xchg %%ebp, %[save]+28 \n\t" - - "test_insn: . = . + 32\n\t" - "test_insn_end: \n\t" - - "xchg %%eax, %[save]+0 \n\t" - "xchg %%ebx, %[save]+4 \n\t" - "xchg %%ecx, %[save]+8 \n\t" - "xchg %%edx, %[save]+12 \n\t" - "xchg %%esi, %[save]+16 \n\t" - "xchg %%edi, %[save]+20 \n\t" - "xchg %%esp, %[save]+24 \n\t" - "xchg %%ebp, %[save]+28 \n\t" - - /* Save EFLAGS in outregs*/ - "pushfl \n\t" - "popl %[save]+36 \n\t" - - "xor %[tmp], %[tmp] \n\t" - "mov %[tmp], %%gs \n\t" - : [tmp]"=&r"(tmp), [save]"+m"(save) - : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) - : "cc", "memory" - ); - *outregs = save; -} - -#define R_AX 1 -#define R_BX 2 -#define R_CX 4 -#define R_DX 8 -#define R_SI 16 -#define R_DI 32 -#define R_SP 64 -#define R_BP 128 - -int regs_equal(const struct regs *r1, const struct regs *r2, int ignore) -{ - const u32 *p1 = &r1->eax, *p2 = &r2->eax; // yuck - int i; - - for (i = 0; i < 8; ++i) - if (!(ignore & (1 << i)) && p1[i] != p2[i]) - return 0; - return 1; -} - -#define MK_INSN(name, str) \ - asm ( \ - ".text 1\n\t" \ - "insn_" #name ": " str " \n\t" \ - "insn_" #name "_end: \n\t" \ - ".text\n\t" \ - ); \ - extern u8 insn_##name[], insn_##name##_end[] - -void test_xchg(void) -{ - struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs; - - MK_INSN(xchg_test1, "xchg %eax,%eax\n\t"); - MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t"); - MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t"); - MK_INSN(xchg_test4, "xchg %eax,%edx\n\t"); - MK_INSN(xchg_test5, "xchg %eax,%esi\n\t"); - MK_INSN(xchg_test6, "xchg %eax,%edi\n\t"); - MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t"); - MK_INSN(xchg_test8, "xchg %eax,%esp\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test1, - insn_xchg_test1_end - insn_xchg_test1); - - if (!regs_equal(&inregs, &outregs, 0)) - print_serial("xchg test 1: FAIL\n"); - else - print_serial("xchg test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test2, - insn_xchg_test2_end - insn_xchg_test2); - - if (!regs_equal(&inregs, &outregs, R_AX | R_BX) || - outregs.eax != inregs.ebx || - outregs.ebx != inregs.eax) - print_serial("xchg test 2: FAIL\n"); - else - print_serial("xchg test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test3, - insn_xchg_test3_end - insn_xchg_test3); - - if (!regs_equal(&inregs, &outregs, R_AX | R_CX) || - outregs.eax != inregs.ecx || - outregs.ecx != inregs.eax) - print_serial("xchg test 3: FAIL\n"); - else - print_serial("xchg test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test4, - insn_xchg_test4_end - insn_xchg_test4); - - if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || - outregs.eax != inregs.edx || - outregs.edx != inregs.eax) - print_serial("xchg test 4: FAIL\n"); - else - print_serial("xchg test 4: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test5, - insn_xchg_test5_end - insn_xchg_test5); - - if (!regs_equal(&inregs, &outregs, R_AX | R_SI) || - outregs.eax != inregs.esi || - outregs.esi != inregs.eax) - print_serial("xchg test 5: FAIL\n"); - else - print_serial("xchg test 5: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test6, - insn_xchg_test6_end - insn_xchg_test6); - - if (!regs_equal(&inregs, &outregs, R_AX | R_DI) || - outregs.eax != inregs.edi || - outregs.edi != inregs.eax) - print_serial("xchg test 6: FAIL\n"); - else - print_serial("xchg test 6: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test7, - insn_xchg_test7_end - insn_xchg_test7); - - if (!regs_equal(&inregs, &outregs, R_AX | R_BP) || - outregs.eax != inregs.ebp || - outregs.ebp != inregs.eax) - print_serial("xchg test 7: FAIL\n"); - else - print_serial("xchg test 7: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xchg_test8, - insn_xchg_test8_end - insn_xchg_test8); - - if (!regs_equal(&inregs, &outregs, R_AX | R_SP) || - outregs.eax != inregs.esp || - outregs.esp != inregs.eax) - print_serial("xchg test 8: FAIL\n"); - else - print_serial("xchg test 8: PASS\n"); -} - -void test_shld(void) -{ - struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs; - MK_INSN(shld_test, "shld $8,%edx,%eax\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_shld_test, - insn_shld_test_end - insn_shld_test); - if (outregs.eax != 0xbeef) - print_serial("shld: FAIL\n"); - else - print_serial("shld: PASS\n"); -} - -void test_mov_imm(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax"); - MK_INSN(mov_r16_imm_1, "mov $1234, %ax"); - MK_INSN(mov_r8_imm_1, "mov $0x12, %ah"); - MK_INSN(mov_r8_imm_2, "mov $0x34, %al"); - MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_mov_r16_imm_1, - insn_mov_r16_imm_1_end - insn_mov_r16_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234) - print_serial("mov test 1: FAIL\n"); - else - print_serial("mov test 1: PASS\n"); - - /* test mov $imm, %eax */ - exec_in_big_real_mode(&inregs, &outregs, - insn_mov_r32_imm_1, - insn_mov_r32_imm_1_end - insn_mov_r32_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567890) - print_serial("mov test 2: FAIL\n"); - else - print_serial("mov test 2: PASS\n"); - - /* test mov $imm, %al/%ah */ - exec_in_big_real_mode(&inregs, &outregs, - insn_mov_r8_imm_1, - insn_mov_r8_imm_1_end - insn_mov_r8_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1200) - print_serial("mov test 3: FAIL\n"); - else - print_serial("mov test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_mov_r8_imm_2, - insn_mov_r8_imm_2_end - insn_mov_r8_imm_2); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x34) - print_serial("mov test 4: FAIL\n"); - else - print_serial("mov test 4: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_mov_r8_imm_3, - insn_mov_r8_imm_3_end - insn_mov_r8_imm_3); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) - print_serial("mov test 5: FAIL\n"); - else - print_serial("mov test 5: PASS\n"); -} - -void test_sub_imm(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t"); - MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t"); - MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t"); - MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_sub_r16_imm_1, - insn_sub_r16_imm_1_end - insn_sub_r16_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1224) - print_serial("sub test 1: FAIL\n"); - else - print_serial("sub test 1: PASS\n"); - - /* test mov $imm, %eax */ - exec_in_big_real_mode(&inregs, &outregs, - insn_sub_r32_imm_1, - insn_sub_r32_imm_1_end - insn_sub_r32_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567880) - print_serial("sub test 2: FAIL\n"); - else - print_serial("sub test 2: PASS\n"); - - /* test mov $imm, %al/%ah */ - exec_in_big_real_mode(&inregs, &outregs, - insn_sub_r8_imm_1, - insn_sub_r8_imm_1_end - insn_sub_r8_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x0200) - print_serial("sub test 3: FAIL\n"); - else - print_serial("sub test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_sub_r8_imm_2, - insn_sub_r8_imm_2_end - insn_sub_r8_imm_2); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x24) - print_serial("sub test 4: FAIL\n"); - else - print_serial("sub test 4: PASS\n"); -} - - -void test_xor_imm(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t"); - MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t"); - MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t"); - MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xor_r16_imm_1, - insn_xor_r16_imm_1_end - insn_xor_r16_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) - print_serial("xor test 1: FAIL\n"); - else - print_serial("xor test 1: PASS\n"); - - /* test mov $imm, %eax */ - exec_in_big_real_mode(&inregs, &outregs, - insn_xor_r32_imm_1, - insn_xor_r32_imm_1_end - insn_xor_r32_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) - print_serial("xor test 2: FAIL\n"); - else - print_serial("xor test 2: PASS\n"); - - /* test mov $imm, %al/%ah */ - exec_in_big_real_mode(&inregs, &outregs, - insn_xor_r8_imm_1, - insn_xor_r8_imm_1_end - insn_xor_r8_imm_1); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) - print_serial("xor test 3: FAIL\n"); - else - print_serial("xor test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_xor_r8_imm_2, - insn_xor_r8_imm_2_end - insn_xor_r8_imm_2); - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) - print_serial("xor test 4: FAIL\n"); - else - print_serial("xor test 4: PASS\n"); -} - -void test_cmp_imm(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(cmp_test1, "mov $0x34, %al\n\t" - "cmp $0x34, %al\n\t"); - MK_INSN(cmp_test2, "mov $0x34, %al\n\t" - "cmp $0x39, %al\n\t"); - MK_INSN(cmp_test3, "mov $0x34, %al\n\t" - "cmp $0x24, %al\n\t"); - - /* test cmp imm8 with AL */ - /* ZF: (bit 6) Zero Flag becomes 1 if an operation results - * in a 0 writeback, or 0 register - */ - exec_in_big_real_mode(&inregs, &outregs, - insn_cmp_test1, - insn_cmp_test1_end - insn_cmp_test1); - if ((outregs.eflags & (1<<6)) != (1<<6)) - print_serial("cmp test 1: FAIL\n"); - else - print_serial("cmp test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_cmp_test2, - insn_cmp_test2_end - insn_cmp_test2); - if ((outregs.eflags & (1<<6)) != 0) - print_serial("cmp test 2: FAIL\n"); - else - print_serial("cmp test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_cmp_test3, - insn_cmp_test3_end - insn_cmp_test3); - if ((outregs.eflags & (1<<6)) != 0) - print_serial("cmp test 3: FAIL\n"); - else - print_serial("cmp test 3: PASS\n"); -} - -void test_add_imm(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(add_test1, "mov $0x43211234, %eax \n\t" - "add $0x12344321, %eax \n\t"); - MK_INSN(add_test2, "mov $0x12, %eax \n\t" - "add $0x21, %al\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_add_test1, - insn_add_test1_end - insn_add_test1); - if (outregs.eax != 0x55555555) - print_serial("add test 1: FAIL\n"); - else - print_serial("add test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_add_test2, - insn_add_test2_end - insn_add_test2); - if (outregs.eax != 0x33) - print_serial("add test 2: FAIL\n"); - else - print_serial("add test 2: PASS\n"); -} - -void test_eflags_insn(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(clc, "clc"); - MK_INSN(cli, "cli"); - MK_INSN(sti, "sti"); - MK_INSN(cld, "cld"); - MK_INSN(std, "std"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_clc, - insn_clc_end - insn_clc); - if (outregs.eflags & 1) - print_serial("clc test: FAIL\n"); - else - print_serial("clc test: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_cli, - insn_cli_end - insn_cli); - if (outregs.eflags & (1 << 9)) - print_serial("cli test: FAIL\n"); - else - print_serial("cli test: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_sti, - insn_sti_end - insn_sti); - if (!(outregs.eflags & (1 << 9))) - print_serial("sti test: FAIL\n"); - else - print_serial("sti test: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_cld, - insn_cld_end - insn_cld); - if (outregs.eflags & (1 << 10)) - print_serial("cld test: FAIL\n"); - else - print_serial("cld test: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_std, - insn_std_end - insn_std); - if (!(outregs.eflags & (1 << 10))) - print_serial("std test: FAIL\n"); - else - print_serial("std test: PASS\n"); -} - -void test_io(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(io_test1, "mov $0xff, %al \n\t" - "out %al, $0xe0 \n\t" - "mov $0x00, %al \n\t" - "in $0xe0, %al \n\t"); - MK_INSN(io_test2, "mov $0xffff, %ax \n\t" - "out %ax, $0xe0 \n\t" - "mov $0x0000, %ax \n\t" - "in $0xe0, %ax \n\t"); - MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t" - "out %eax, $0xe0 \n\t" - "mov $0x000000, %eax \n\t" - "in $0xe0, %eax \n\t"); - MK_INSN(io_test4, "mov $0xe0, %dx \n\t" - "mov $0xff, %al \n\t" - "out %al, %dx \n\t" - "mov $0x00, %al \n\t" - "in %dx, %al \n\t"); - MK_INSN(io_test5, "mov $0xe0, %dx \n\t" - "mov $0xffff, %ax \n\t" - "out %ax, %dx \n\t" - "mov $0x0000, %ax \n\t" - "in %dx, %ax \n\t"); - MK_INSN(io_test6, "mov $0xe0, %dx \n\t" - "mov $0xffffffff, %eax \n\t" - "out %eax, %dx \n\t" - "mov $0x00000000, %eax \n\t" - "in %dx, %eax \n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_io_test1, - insn_io_test1_end - insn_io_test1); - - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xff) - print_serial("I/O test 1: FAIL\n"); - else - print_serial("I/O test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_io_test2, - insn_io_test2_end - insn_io_test2); - - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffff) - print_serial("I/O test 2: FAIL\n"); - else - print_serial("I/O test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_io_test3, - insn_io_test3_end - insn_io_test3); - - if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffffffff) - print_serial("I/O test 3: FAIL\n"); - else - print_serial("I/O test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_io_test4, - insn_io_test4_end - insn_io_test4); - - if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xff) - print_serial("I/O test 4: FAIL\n"); - else - print_serial("I/O test 4: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_io_test5, - insn_io_test5_end - insn_io_test5); - - if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffff) - print_serial("I/O test 5: FAIL\n"); - else - print_serial("I/O test 5: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_io_test6, - insn_io_test6_end - insn_io_test6); - - if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffffffff) - print_serial("I/O test 6: FAIL\n"); - else - print_serial("I/O test 6: PASS\n"); -} - -void test_call(void) -{ - struct regs inregs = { 0 }, outregs; - u32 esp[16]; - - inregs.esp = (u32)esp; - - MK_INSN(call1, "mov $test_function, %eax \n\t" - "call *%eax\n\t"); - MK_INSN(call_near1, "jmp 2f\n\t" - "1: mov $0x1234, %eax\n\t" - "ret\n\t" - "2: call 1b\t"); - MK_INSN(call_near2, "call 1f\n\t" - "jmp 2f\n\t" - "1: mov $0x1234, %eax\n\t" - "ret\n\t" - "2:\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_call1, - insn_call1_end - insn_call1); - if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) - print_serial("Call Test 1: FAIL\n"); - else - print_serial("Call Test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_call_near1, insn_call_near1_end - insn_call_near1); - if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) - print_serial("Call near Test 1: FAIL\n"); - else - print_serial("Call near Test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_call_near2, insn_call_near2_end - insn_call_near2); - if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) - print_serial("Call near Test 2: FAIL\n"); - else - print_serial("Call near Test 2: PASS\n"); -} - -void test_jcc_short(void) -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(jnz_short1, "jnz 1f\n\t" - "mov $0x1234, %eax\n\t" - "1:\n\t"); - MK_INSN(jnz_short2, "1:\n\t" - "cmp $0x1234, %eax\n\t" - "mov $0x1234, %eax\n\t" - "jnz 1b\n\t"); - MK_INSN(jmp_short1, "jmp 1f\n\t" - "mov $0x1234, %eax\n\t" - "1:\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_jnz_short1, insn_jnz_short1_end - insn_jnz_short1); - if(!regs_equal(&inregs, &outregs, 0)) - print_serial("JNZ short Test 1: FAIL\n"); - else - print_serial("JNZ short Test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_jnz_short2, insn_jnz_short2_end - insn_jnz_short2); - if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) - print_serial("JNZ short Test 2: FAIL\n"); - else - print_serial("JNZ short Test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_jmp_short1, insn_jmp_short1_end - insn_jmp_short1); - if(!regs_equal(&inregs, &outregs, 0)) - print_serial("JMP short Test 1: FAIL\n"); - else - print_serial("JMP short Test 1: PASS\n"); -} - -void test_jcc_near(void) -{ - struct regs inregs = { 0 }, outregs; - /* encode near jmp manually. gas will not do it if offsets < 127 byte */ - MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t" - "mov $0x1234, %eax\n\t"); - MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t" - "mov $0x1234, %eax\n\t" - ".byte 0x0f, 0x85, 0xf0, 0xff\n\t"); - MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t" - "mov $0x1234, %eax\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_jnz_near1, insn_jnz_near1_end - insn_jnz_near1); - if(!regs_equal(&inregs, &outregs, 0)) - print_serial("JNZ near Test 1: FAIL\n"); - else - print_serial("JNZ near Test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_jnz_near2, insn_jnz_near2_end - insn_jnz_near2); - if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) - print_serial("JNZ near Test 2: FAIL\n"); - else - print_serial("JNZ near Test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_jmp_near1, insn_jmp_near1_end - insn_jmp_near1); - if(!regs_equal(&inregs, &outregs, 0)) - print_serial("JMP near Test 1: FAIL\n"); - else - print_serial("JMP near Test 1: PASS\n"); -} - -void test_long_jmp() -{ - struct regs inregs = { 0 }, outregs; - u32 esp[16]; - - inregs.esp = (u32)esp; - MK_INSN(long_jmp, "call 1f\n\t" - "jmp 2f\n\t" - "1: jmp $0, $test_function\n\t" - "2:\n\t"); - exec_in_big_real_mode(&inregs, &outregs, - insn_long_jmp, - insn_long_jmp_end - insn_long_jmp); - if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) - print_serial("Long JMP Test: FAIL\n"); - else - print_serial("Long JMP Test: PASS\n"); -} -void test_push_pop() -{ - struct regs inregs = { 0 }, outregs; - MK_INSN(push32, "mov $0x12345678, %eax\n\t" - "push %eax\n\t" - "pop %ebx\n\t"); - MK_INSN(push16, "mov $0x1234, %ax\n\t" - "push %ax\n\t" - "pop %bx\n\t"); - - MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten - "mov $0x123, %ax\n\t" - "mov %ax, %es\n\t" - "push %es\n\t" - "pop %bx \n\t" - ); - MK_INSN(pop_es, "push %ax\n\t" - "pop %es\n\t" - "mov %es, %bx\n\t" - ); - MK_INSN(push_pop_ss, "push %ss\n\t" - "pushw %ax\n\t" - "popw %ss\n\t" - "mov %ss, %bx\n\t" - "pop %ss\n\t" - ); - MK_INSN(push_pop_fs, "push %fs\n\t" - "pushl %eax\n\t" - "popl %fs\n\t" - "mov %fs, %ebx\n\t" - "pop %fs\n\t" - ); - - exec_in_big_real_mode(&inregs, &outregs, - insn_push32, - insn_push32_end - insn_push32); - if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x12345678) - print_serial("Push/Pop Test 1: FAIL\n"); - else - print_serial("Push/Pop Test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_push16, - insn_push16_end - insn_push16); - - if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x1234) - print_serial("Push/Pop Test 2: FAIL\n"); - else - print_serial("Push/Pop Test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_push_es, - insn_push_es_end - insn_push_es); - if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax || outregs.eax != 0x123) - print_serial("Push/Pop Test 3: FAIL\n"); - else - print_serial("Push/Pop Test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_pop_es, - insn_pop_es_end - insn_pop_es); - - if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) - print_serial("Push/Pop Test 4: FAIL\n"); - else - print_serial("Push/Pop Test 4: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_push_pop_ss, - insn_push_pop_ss_end - insn_push_pop_ss); - - if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) - print_serial("Push/Pop Test 5: FAIL\n"); - else - print_serial("Push/Pop Test 5: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_push_pop_fs, - insn_push_pop_fs_end - insn_push_pop_fs); - - if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) - print_serial("Push/Pop Test 6: FAIL\n"); - else - print_serial("Push/Pop Test 6: PASS\n"); -} - -void test_null(void) -{ - struct regs inregs = { 0 }, outregs; - exec_in_big_real_mode(&inregs, &outregs, 0, 0); - if (!regs_equal(&inregs, &outregs, 0)) - print_serial("null test: FAIL\n"); - else - print_serial("null test: PASS\n"); -} - -struct { - char stack[500]; - char top[]; -} tmp_stack; - -void test_pusha_popa() -{ - struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top }, outregs; - - MK_INSN(pusha, "pusha\n\t" - "pop %edi\n\t" - "pop %esi\n\t" - "pop %ebp\n\t" - "add $4, %esp\n\t" - "pop %ebx\n\t" - "pop %edx\n\t" - "pop %ecx\n\t" - "pop %eax\n\t" - ); - - MK_INSN(popa, "push %eax\n\t" - "push %ecx\n\t" - "push %edx\n\t" - "push %ebx\n\t" - "push %esp\n\t" - "push %ebp\n\t" - "push %esi\n\t" - "push %edi\n\t" - "popa\n\t" - ); - - exec_in_big_real_mode(&inregs, &outregs, - insn_pusha, - insn_pusha_end - insn_pusha); - - if (!regs_equal(&inregs, &outregs, 0)) - print_serial("Pusha/Popa Test1: FAIL\n"); - else - print_serial("Pusha/Popa Test1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_popa, - insn_popa_end - insn_popa); - if (!regs_equal(&inregs, &outregs, 0)) - print_serial("Pusha/Popa Test2: FAIL\n"); - else - print_serial("Pusha/Popa Test2: PASS\n"); -} - -void test_iret() -{ - struct regs inregs = { 0 }, outregs; - - MK_INSN(iret32, "pushf\n\t" - "pushl %cs\n\t" - "call 1f\n\t" /* a near call will push eip onto the stack */ - "jmp 2f\n\t" - "1: iret\n\t" - "2:\n\t" - ); - - MK_INSN(iret16, "pushfw\n\t" - "pushw %cs\n\t" - "callw 1f\n\t" - "jmp 2f\n\t" - "1: iretw\n\t" - "2:\n\t"); - - MK_INSN(iret_flags32, "pushfl\n\t" - "popl %eax\n\t" - "andl $~0x2, %eax\n\t" - "orl $0xffc08028, %eax\n\t" - "pushl %eax\n\t" - "pushl %cs\n\t" - "call 1f\n\t" - "jmp 2f\n\t" - "1: iret\n\t" - "2:\n\t"); - - MK_INSN(iret_flags16, "pushfw\n\t" - "popw %ax\n\t" - "and $~0x2, %ax\n\t" - "or $0x8028, %ax\n\t" - "pushw %ax\n\t" - "pushw %cs\n\t" - "callw 1f\n\t" - "jmp 2f\n\t" - "1: iretw\n\t" - "2:\n\t"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_iret32, - insn_iret32_end - insn_iret32); - - if (!regs_equal(&inregs, &outregs, 0)) - print_serial("iret Test 1: FAIL\n"); - else - print_serial("iret Test 1: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_iret16, - insn_iret16_end - insn_iret16); - - if (!regs_equal(&inregs, &outregs, 0)) - print_serial("iret Test 2: FAIL\n"); - else - print_serial("iret Test 2: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_iret_flags32, - insn_iret_flags32_end - insn_iret_flags32); - - if (!regs_equal(&inregs, &outregs, R_AX)) - print_serial("iret Test 3: FAIL\n"); - else - print_serial("iret Test 3: PASS\n"); - - exec_in_big_real_mode(&inregs, &outregs, - insn_iret_flags16, - insn_iret_flags16_end - insn_iret_flags16); - - if (!regs_equal(&inregs, &outregs, R_AX)) - print_serial("iret Test 4: FAIL\n"); - else - print_serial("iret Test 4: PASS\n"); -} - -void realmode_start(void) -{ - test_null(); - - test_shld(); - test_push_pop(); - test_pusha_popa(); - test_mov_imm(); - test_cmp_imm(); - test_add_imm(); - test_sub_imm(); - test_xor_imm(); - test_io(); - test_eflags_insn(); - test_jcc_short(); - test_jcc_near(); - /* test_call() uses short jump so call it after testing jcc */ - test_call(); - /* long jmp test uses call near so test it after testing call */ - test_long_jmp(); - test_xchg(); - test_iret(); - - exit(0); -} - -unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; - -struct __attribute__((packed)) { - unsigned short limit; - void *base; -} r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; - -asm( - ".section .init \n\t" - - ".code32 \n\t" - - "mb_magic = 0x1BADB002 \n\t" - "mb_flags = 0x0 \n\t" - - "# multiboot header \n\t" - ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" - - ".globl start \n\t" - ".data \n\t" - ". = . + 4096 \n\t" - "stacktop: \n\t" - - ".text \n\t" - "start: \n\t" - "lgdt r_gdt_descr \n\t" - "ljmp $8, $1f; 1: \n\t" - ".code16gcc \n\t" - "mov $16, %eax \n\t" - "mov %ax, %ds \n\t" - "mov %ax, %es \n\t" - "mov %ax, %fs \n\t" - "mov %ax, %gs \n\t" - "mov %ax, %ss \n\t" - "mov %cr0, %eax \n\t" - "btc $0, %eax \n\t" - "mov %eax, %cr0 \n\t" - "ljmp $0, $realmode_entry \n\t" - - "realmode_entry: \n\t" - - "xor %ax, %ax \n\t" - "mov %ax, %ds \n\t" - "mov %ax, %es \n\t" - "mov %ax, %ss \n\t" - "mov %ax, %fs \n\t" - "mov %ax, %gs \n\t" - "mov $stacktop, %esp\n\t" - "ljmp $0, $realmode_start \n\t" - - ".code16gcc \n\t" - ); diff --git a/kvm/test/x86/realmode.lds b/kvm/test/x86/realmode.lds deleted file mode 100644 index c7386b8e7..000000000 --- a/kvm/test/x86/realmode.lds +++ /dev/null @@ -1,12 +0,0 @@ -SECTIONS -{ - . = 16K; - stext = .; - .text : { *(.init) *(.text) } - . = ALIGN(4K); - .data : { *(.data) *(.rodata*) } - . = ALIGN(16); - .bss : { *(.bss) } - edata = .; -} - diff --git a/kvm/test/x86/rmap_chain.c b/kvm/test/x86/rmap_chain.c deleted file mode 100644 index 9add9b8fb..000000000 --- a/kvm/test/x86/rmap_chain.c +++ /dev/null @@ -1,53 +0,0 @@ -/* test long rmap chains */ - -#include "libcflat.h" -#include "vm.h" -#include "smp.h" - -void print(const char *s); - -static unsigned int inl(unsigned short port) -{ - unsigned int val; - asm volatile ("inl %w1, %0":"=a" (val):"Nd" (port)); - return val; -} - -int main (void) -{ - int i; - int nr_pages; - void *target_page, *virt_addr; - - setup_vm(); - - nr_pages = inl(0xd1) / PAGE_SIZE; - nr_pages -= 1000; - target_page = alloc_page(); - - virt_addr = (void *) 0xfffffa000; - for (i = 0; i < nr_pages; i++) { - install_page(phys_to_virt(read_cr3()), virt_to_phys(target_page), - virt_addr); - virt_addr += PAGE_SIZE; - } - printf("created %d mappings\n", nr_pages); - - virt_addr = (void *) 0xfffffa000; - for (i = 0; i < nr_pages; i++) { - unsigned long *touch = virt_addr; - - *touch = 0; - virt_addr += PAGE_SIZE; - } - printf("instantiated mappings\n"); - - virt_addr += PAGE_SIZE; - install_pte(phys_to_virt(read_cr3()), 1, virt_addr, - 0 | PTE_PRESENT | PTE_WRITE, target_page); - - *(unsigned long *)virt_addr = 0; - printf("PASS\n"); - - return 0; -} diff --git a/kvm/test/x86/sieve.c b/kvm/test/x86/sieve.c deleted file mode 100644 index ef4a5a0ae..000000000 --- a/kvm/test/x86/sieve.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "vm.h" -#include "libcflat.h" - -int sieve(char* data, int size) -{ - int i, j, r = 0; - - for (i = 0; i < size; ++i) - data[i] = 1; - - data[0] = data[1] = 0; - - for (i = 2; i < size; ++i) - if (data[i]) { - ++r; - for (j = i*2; j < size; j += i) - data[j] = 0; - } - return r; -} - -void test_sieve(const char *msg, char *data, int size) -{ - int r; - - printf("%s:", msg); - r = sieve(data, size); - printf("%d out of %d\n", r, size); -} - -#define STATIC_SIZE 1000000 -#define VSIZE 100000000 -char static_data[STATIC_SIZE]; - -int main() -{ - void *v; - int i; - - printf("starting sieve\n"); - test_sieve("static", static_data, STATIC_SIZE); - setup_vm(); - test_sieve("mapped", static_data, STATIC_SIZE); - for (i = 0; i < 3; ++i) { - v = vmalloc(VSIZE); - test_sieve("virtual", v, VSIZE); - vfree(v); - } - - return 0; -} diff --git a/kvm/test/x86/smptest.c b/kvm/test/x86/smptest.c deleted file mode 100644 index 37805999b..000000000 --- a/kvm/test/x86/smptest.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "libcflat.h" -#include "smp.h" - -static void ipi_test(void *data) -{ - int n = (long)data; - - printf("ipi called, cpu %d\n", n); - if (n != smp_id()) - printf("but wrong cpu %d\n", smp_id()); -} - -int main() -{ - int ncpus; - int i; - - smp_init(); - - ncpus = cpu_count(); - printf("found %d cpus\n", ncpus); - for (i = 0; i < ncpus; ++i) - on_cpu(i, ipi_test, (void *)(long)i); - return 0; -} diff --git a/kvm/test/x86/svm.c b/kvm/test/x86/svm.c deleted file mode 100644 index 2f1c900ff..000000000 --- a/kvm/test/x86/svm.c +++ /dev/null @@ -1,411 +0,0 @@ -#include "svm.h" -#include "libcflat.h" -#include "processor.h" -#include "msr.h" -#include "vm.h" -#include "smp.h" -#include "types.h" - -static void setup_svm(void) -{ - void *hsave = alloc_page(); - - wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave)); - wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME); -} - -static void vmcb_set_seg(struct vmcb_seg *seg, u16 selector, - u64 base, u32 limit, u32 attr) -{ - seg->selector = selector; - seg->attrib = attr; - seg->limit = limit; - seg->base = base; -} - -static void vmcb_ident(struct vmcb *vmcb) -{ - u64 vmcb_phys = virt_to_phys(vmcb); - struct vmcb_save_area *save = &vmcb->save; - struct vmcb_control_area *ctrl = &vmcb->control; - u32 data_seg_attr = 3 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK - | SVM_SELECTOR_DB_MASK | SVM_SELECTOR_G_MASK; - u32 code_seg_attr = 9 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK - | SVM_SELECTOR_L_MASK | SVM_SELECTOR_G_MASK; - struct descriptor_table_ptr desc_table_ptr; - - memset(vmcb, 0, sizeof(*vmcb)); - asm volatile ("vmsave" : : "a"(vmcb_phys) : "memory"); - vmcb_set_seg(&save->es, read_es(), 0, -1U, data_seg_attr); - vmcb_set_seg(&save->cs, read_cs(), 0, -1U, code_seg_attr); - vmcb_set_seg(&save->ss, read_ss(), 0, -1U, data_seg_attr); - vmcb_set_seg(&save->ds, read_ds(), 0, -1U, data_seg_attr); - sgdt(&desc_table_ptr); - vmcb_set_seg(&save->gdtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); - sidt(&desc_table_ptr); - vmcb_set_seg(&save->idtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); - ctrl->asid = 1; - save->cpl = 0; - save->efer = rdmsr(MSR_EFER); - save->cr4 = read_cr4(); - save->cr3 = read_cr3(); - save->cr0 = read_cr0(); - save->dr7 = read_dr7(); - save->dr6 = read_dr6(); - save->cr2 = read_cr2(); - save->g_pat = rdmsr(MSR_IA32_CR_PAT); - save->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR); - ctrl->intercept = (1ULL << INTERCEPT_VMRUN) | (1ULL << INTERCEPT_VMMCALL); -} - -struct test { - const char *name; - bool (*supported)(void); - void (*prepare)(struct test *test); - void (*guest_func)(struct test *test); - bool (*finished)(struct test *test); - bool (*succeeded)(struct test *test); - struct vmcb *vmcb; - int exits; - ulong scratch; -}; - -static void test_thunk(struct test *test) -{ - test->guest_func(test); - asm volatile ("vmmcall" : : : "memory"); -} - -static bool test_run(struct test *test, struct vmcb *vmcb) -{ - u64 vmcb_phys = virt_to_phys(vmcb); - u64 guest_stack[10000]; - bool success; - - test->vmcb = vmcb; - test->prepare(test); - vmcb->save.rip = (ulong)test_thunk; - vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); - do { - asm volatile ( - "clgi \n\t" - "vmload \n\t" - "push %%rbp \n\t" - "push %1 \n\t" - "vmrun \n\t" - "pop %1 \n\t" - "pop %%rbp \n\t" - "vmsave \n\t" - "stgi" - : : "a"(vmcb_phys), "D"(test) - : "rbx", "rcx", "rdx", "rsi", - "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15", - "memory"); - ++test->exits; - } while (!test->finished(test)); - - success = test->succeeded(test); - - printf("%s: %s\n", test->name, success ? "PASS" : "FAIL"); - - return success; -} - -static bool default_supported(void) -{ - return true; -} - -static void default_prepare(struct test *test) -{ - vmcb_ident(test->vmcb); - cli(); -} - -static bool default_finished(struct test *test) -{ - return true; /* one vmexit */ -} - -static void null_test(struct test *test) -{ -} - -static bool null_check(struct test *test) -{ - return test->vmcb->control.exit_code == SVM_EXIT_VMMCALL; -} - -static void prepare_no_vmrun_int(struct test *test) -{ - test->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMRUN); -} - -static bool check_no_vmrun_int(struct test *test) -{ - return test->vmcb->control.exit_code == SVM_EXIT_ERR; -} - -static void test_vmrun(struct test *test) -{ - asm volatile ("vmrun" : : "a"(virt_to_phys(test->vmcb))); -} - -static bool check_vmrun(struct test *test) -{ - return test->vmcb->control.exit_code == SVM_EXIT_VMRUN; -} - -static void prepare_cr3_intercept(struct test *test) -{ - default_prepare(test); - test->vmcb->control.intercept_cr_read |= 1 << 3; -} - -static void test_cr3_intercept(struct test *test) -{ - asm volatile ("mov %%cr3, %0" : "=r"(test->scratch) : : "memory"); -} - -static bool check_cr3_intercept(struct test *test) -{ - return test->vmcb->control.exit_code == SVM_EXIT_READ_CR3; -} - -static bool check_cr3_nointercept(struct test *test) -{ - return null_check(test) && test->scratch == read_cr3(); -} - -static void corrupt_cr3_intercept_bypass(void *_test) -{ - struct test *test = _test; - extern volatile u32 mmio_insn; - - while (!__sync_bool_compare_and_swap(&test->scratch, 1, 2)) - pause(); - pause(); - pause(); - pause(); - mmio_insn = 0x90d8200f; // mov %cr3, %rax; nop -} - -static void prepare_cr3_intercept_bypass(struct test *test) -{ - default_prepare(test); - test->vmcb->control.intercept_cr_read |= 1 << 3; - on_cpu_async(1, corrupt_cr3_intercept_bypass, test); -} - -static void test_cr3_intercept_bypass(struct test *test) -{ - ulong a = 0xa0000; - - test->scratch = 1; - while (test->scratch != 2) - barrier(); - - asm volatile ("mmio_insn: mov %0, (%0); nop" - : "+a"(a) : : "memory"); - test->scratch = a; -} - -static bool next_rip_supported(void) -{ - return (cpuid(SVM_CPUID_FUNC).d & 8); -} - -static void prepare_next_rip(struct test *test) -{ - test->vmcb->control.intercept |= (1ULL << INTERCEPT_RDTSC); -} - - -static void test_next_rip(struct test *test) -{ - asm volatile ("rdtsc\n\t" - ".globl exp_next_rip\n\t" - "exp_next_rip:\n\t" ::: "eax", "edx"); -} - -static bool check_next_rip(struct test *test) -{ - extern char exp_next_rip; - unsigned long address = (unsigned long)&exp_next_rip; - - return address == test->vmcb->control.next_rip; -} - -static void prepare_mode_switch(struct test *test) -{ - test->vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR) - | (1ULL << UD_VECTOR) - | (1ULL << DF_VECTOR) - | (1ULL << PF_VECTOR); - test->scratch = 0; -} - -static void test_mode_switch(struct test *test) -{ - asm volatile(" cli\n" - " ljmp *1f\n" /* jump to 32-bit code segment */ - "1:\n" - " .long 2f\n" - " .long 40\n" - ".code32\n" - "2:\n" - " movl %%cr0, %%eax\n" - " btcl $31, %%eax\n" /* clear PG */ - " movl %%eax, %%cr0\n" - " movl $0xc0000080, %%ecx\n" /* EFER */ - " rdmsr\n" - " btcl $8, %%eax\n" /* clear LME */ - " wrmsr\n" - " movl %%cr4, %%eax\n" - " btcl $5, %%eax\n" /* clear PAE */ - " movl %%eax, %%cr4\n" - " movw $64, %%ax\n" - " movw %%ax, %%ds\n" - " ljmpl $56, $3f\n" /* jump to 16 bit protected-mode */ - ".code16\n" - "3:\n" - " movl %%cr0, %%eax\n" - " btcl $0, %%eax\n" /* clear PE */ - " movl %%eax, %%cr0\n" - " ljmpl $0, $4f\n" /* jump to real-mode */ - "4:\n" - " vmmcall\n" - " movl %%cr0, %%eax\n" - " btsl $0, %%eax\n" /* set PE */ - " movl %%eax, %%cr0\n" - " ljmpl $40, $5f\n" /* back to protected mode */ - ".code32\n" - "5:\n" - " movl %%cr4, %%eax\n" - " btsl $5, %%eax\n" /* set PAE */ - " movl %%eax, %%cr4\n" - " movl $0xc0000080, %%ecx\n" /* EFER */ - " rdmsr\n" - " btsl $8, %%eax\n" /* set LME */ - " wrmsr\n" - " movl %%cr0, %%eax\n" - " btsl $31, %%eax\n" /* set PG */ - " movl %%eax, %%cr0\n" - " ljmpl $8, $6f\n" /* back to long mode */ - ".code64\n\t" - "6:\n" - " vmmcall\n" - ::: "rax", "rbx", "rcx", "rdx", "memory"); -} - -static bool mode_switch_finished(struct test *test) -{ - u64 cr0, cr4, efer; - - cr0 = test->vmcb->save.cr0; - cr4 = test->vmcb->save.cr4; - efer = test->vmcb->save.efer; - - /* Only expect VMMCALL intercepts */ - if (test->vmcb->control.exit_code != SVM_EXIT_VMMCALL) - return true; - - /* Jump over VMMCALL instruction */ - test->vmcb->save.rip += 3; - - /* Do sanity checks */ - switch (test->scratch) { - case 0: - /* Test should be in real mode now - check for this */ - if ((cr0 & 0x80000001) || /* CR0.PG, CR0.PE */ - (cr4 & 0x00000020) || /* CR4.PAE */ - (efer & 0x00000500)) /* EFER.LMA, EFER.LME */ - return true; - break; - case 2: - /* Test should be back in long-mode now - check for this */ - if (((cr0 & 0x80000001) != 0x80000001) || /* CR0.PG, CR0.PE */ - ((cr4 & 0x00000020) != 0x00000020) || /* CR4.PAE */ - ((efer & 0x00000500) != 0x00000500)) /* EFER.LMA, EFER.LME */ - return true; - break; - } - - /* one step forward */ - test->scratch += 1; - - return test->scratch == 2; -} - -static bool check_mode_switch(struct test *test) -{ - return test->scratch == 2; -} - -static void prepare_asid_zero(struct test *test) -{ - test->vmcb->control.asid = 0; -} - -static void test_asid_zero(struct test *test) -{ - asm volatile ("vmmcall\n\t"); -} - -static bool check_asid_zero(struct test *test) -{ - return test->vmcb->control.exit_code == SVM_EXIT_ERR; -} - -static struct test tests[] = { - { "null", default_supported, default_prepare, null_test, - default_finished, null_check }, - { "vmrun", default_supported, default_prepare, test_vmrun, - default_finished, check_vmrun }, - { "vmrun intercept check", default_supported, prepare_no_vmrun_int, - null_test, default_finished, check_no_vmrun_int }, - { "cr3 read intercept", default_supported, prepare_cr3_intercept, - test_cr3_intercept, default_finished, check_cr3_intercept }, - { "cr3 read nointercept", default_supported, default_prepare, - test_cr3_intercept, default_finished, check_cr3_nointercept }, - { "cr3 read intercept emulate", default_supported, - prepare_cr3_intercept_bypass, test_cr3_intercept_bypass, - default_finished, check_cr3_intercept }, - { "next_rip", next_rip_supported, prepare_next_rip, test_next_rip, - default_finished, check_next_rip }, - { "mode_switch", default_supported, prepare_mode_switch, test_mode_switch, - mode_switch_finished, check_mode_switch }, - { "asid_zero", default_supported, prepare_asid_zero, test_asid_zero, - default_finished, check_asid_zero }, - -}; - -int main(int ac, char **av) -{ - int i, nr, passed, done; - struct vmcb *vmcb; - - setup_vm(); - smp_init(); - - if (!(cpuid(0x80000001).c & 4)) { - printf("SVM not availble\n"); - return 0; - } - - setup_svm(); - - vmcb = alloc_page(); - - nr = ARRAY_SIZE(tests); - passed = done = 0; - for (i = 0; i < nr; ++i) { - if (!tests[i].supported()) - continue; - done += 1; - passed += test_run(&tests[i], vmcb); - } - - printf("\nSUMMARY: %d TESTS, %d FAILURES\n", done, (done - passed)); - return passed == done ? 0 : 1; -} diff --git a/kvm/test/x86/svm.h b/kvm/test/x86/svm.h deleted file mode 100644 index 3fdc0d33d..000000000 --- a/kvm/test/x86/svm.h +++ /dev/null @@ -1,328 +0,0 @@ -#ifndef __SVM_H -#define __SVM_H - -#include "libcflat.h" - -enum { - INTERCEPT_INTR, - INTERCEPT_NMI, - INTERCEPT_SMI, - INTERCEPT_INIT, - INTERCEPT_VINTR, - INTERCEPT_SELECTIVE_CR0, - INTERCEPT_STORE_IDTR, - INTERCEPT_STORE_GDTR, - INTERCEPT_STORE_LDTR, - INTERCEPT_STORE_TR, - INTERCEPT_LOAD_IDTR, - INTERCEPT_LOAD_GDTR, - INTERCEPT_LOAD_LDTR, - INTERCEPT_LOAD_TR, - INTERCEPT_RDTSC, - INTERCEPT_RDPMC, - INTERCEPT_PUSHF, - INTERCEPT_POPF, - INTERCEPT_CPUID, - INTERCEPT_RSM, - INTERCEPT_IRET, - INTERCEPT_INTn, - INTERCEPT_INVD, - INTERCEPT_PAUSE, - INTERCEPT_HLT, - INTERCEPT_INVLPG, - INTERCEPT_INVLPGA, - INTERCEPT_IOIO_PROT, - INTERCEPT_MSR_PROT, - INTERCEPT_TASK_SWITCH, - INTERCEPT_FERR_FREEZE, - INTERCEPT_SHUTDOWN, - INTERCEPT_VMRUN, - INTERCEPT_VMMCALL, - INTERCEPT_VMLOAD, - INTERCEPT_VMSAVE, - INTERCEPT_STGI, - INTERCEPT_CLGI, - INTERCEPT_SKINIT, - INTERCEPT_RDTSCP, - INTERCEPT_ICEBP, - INTERCEPT_WBINVD, - INTERCEPT_MONITOR, - INTERCEPT_MWAIT, - INTERCEPT_MWAIT_COND, -}; - - -struct __attribute__ ((__packed__)) vmcb_control_area { - u16 intercept_cr_read; - u16 intercept_cr_write; - u16 intercept_dr_read; - u16 intercept_dr_write; - u32 intercept_exceptions; - u64 intercept; - u8 reserved_1[42]; - u16 pause_filter_count; - u64 iopm_base_pa; - u64 msrpm_base_pa; - u64 tsc_offset; - u32 asid; - u8 tlb_ctl; - u8 reserved_2[3]; - u32 int_ctl; - u32 int_vector; - u32 int_state; - u8 reserved_3[4]; - u32 exit_code; - u32 exit_code_hi; - u64 exit_info_1; - u64 exit_info_2; - u32 exit_int_info; - u32 exit_int_info_err; - u64 nested_ctl; - u8 reserved_4[16]; - u32 event_inj; - u32 event_inj_err; - u64 nested_cr3; - u64 lbr_ctl; - u64 reserved_5; - u64 next_rip; - u8 reserved_6[816]; -}; - - -#define TLB_CONTROL_DO_NOTHING 0 -#define TLB_CONTROL_FLUSH_ALL_ASID 1 - -#define V_TPR_MASK 0x0f - -#define V_IRQ_SHIFT 8 -#define V_IRQ_MASK (1 << V_IRQ_SHIFT) - -#define V_INTR_PRIO_SHIFT 16 -#define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) - -#define V_IGN_TPR_SHIFT 20 -#define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) - -#define V_INTR_MASKING_SHIFT 24 -#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) - -#define SVM_INTERRUPT_SHADOW_MASK 1 - -#define SVM_IOIO_STR_SHIFT 2 -#define SVM_IOIO_REP_SHIFT 3 -#define SVM_IOIO_SIZE_SHIFT 4 -#define SVM_IOIO_ASIZE_SHIFT 7 - -#define SVM_IOIO_TYPE_MASK 1 -#define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) -#define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) -#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) -#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) - -#define SVM_VM_CR_VALID_MASK 0x001fULL -#define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL -#define SVM_VM_CR_SVM_DIS_MASK 0x0010ULL - -struct __attribute__ ((__packed__)) vmcb_seg { - u16 selector; - u16 attrib; - u32 limit; - u64 base; -}; - -struct __attribute__ ((__packed__)) vmcb_save_area { - struct vmcb_seg es; - struct vmcb_seg cs; - struct vmcb_seg ss; - struct vmcb_seg ds; - struct vmcb_seg fs; - struct vmcb_seg gs; - struct vmcb_seg gdtr; - struct vmcb_seg ldtr; - struct vmcb_seg idtr; - struct vmcb_seg tr; - u8 reserved_1[43]; - u8 cpl; - u8 reserved_2[4]; - u64 efer; - u8 reserved_3[112]; - u64 cr4; - u64 cr3; - u64 cr0; - u64 dr7; - u64 dr6; - u64 rflags; - u64 rip; - u8 reserved_4[88]; - u64 rsp; - u8 reserved_5[24]; - u64 rax; - u64 star; - u64 lstar; - u64 cstar; - u64 sfmask; - u64 kernel_gs_base; - u64 sysenter_cs; - u64 sysenter_esp; - u64 sysenter_eip; - u64 cr2; - u8 reserved_6[32]; - u64 g_pat; - u64 dbgctl; - u64 br_from; - u64 br_to; - u64 last_excp_from; - u64 last_excp_to; -}; - -struct __attribute__ ((__packed__)) vmcb { - struct vmcb_control_area control; - struct vmcb_save_area save; -}; - -#define SVM_CPUID_FEATURE_SHIFT 2 -#define SVM_CPUID_FUNC 0x8000000a - -#define SVM_VM_CR_SVM_DISABLE 4 - -#define SVM_SELECTOR_S_SHIFT 4 -#define SVM_SELECTOR_DPL_SHIFT 5 -#define SVM_SELECTOR_P_SHIFT 7 -#define SVM_SELECTOR_AVL_SHIFT 8 -#define SVM_SELECTOR_L_SHIFT 9 -#define SVM_SELECTOR_DB_SHIFT 10 -#define SVM_SELECTOR_G_SHIFT 11 - -#define SVM_SELECTOR_TYPE_MASK (0xf) -#define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT) -#define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT) -#define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT) -#define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT) -#define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT) -#define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT) -#define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT) - -#define SVM_SELECTOR_WRITE_MASK (1 << 1) -#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK -#define SVM_SELECTOR_CODE_MASK (1 << 3) - -#define INTERCEPT_CR0_MASK 1 -#define INTERCEPT_CR3_MASK (1 << 3) -#define INTERCEPT_CR4_MASK (1 << 4) -#define INTERCEPT_CR8_MASK (1 << 8) - -#define INTERCEPT_DR0_MASK 1 -#define INTERCEPT_DR1_MASK (1 << 1) -#define INTERCEPT_DR2_MASK (1 << 2) -#define INTERCEPT_DR3_MASK (1 << 3) -#define INTERCEPT_DR4_MASK (1 << 4) -#define INTERCEPT_DR5_MASK (1 << 5) -#define INTERCEPT_DR6_MASK (1 << 6) -#define INTERCEPT_DR7_MASK (1 << 7) - -#define SVM_EVTINJ_VEC_MASK 0xff - -#define SVM_EVTINJ_TYPE_SHIFT 8 -#define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) - -#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) -#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) -#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) -#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) - -#define SVM_EVTINJ_VALID (1 << 31) -#define SVM_EVTINJ_VALID_ERR (1 << 11) - -#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK -#define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK - -#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR -#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI -#define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT -#define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT - -#define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID -#define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR - -#define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 -#define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 -#define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 - -#define SVM_EXIT_READ_CR0 0x000 -#define SVM_EXIT_READ_CR3 0x003 -#define SVM_EXIT_READ_CR4 0x004 -#define SVM_EXIT_READ_CR8 0x008 -#define SVM_EXIT_WRITE_CR0 0x010 -#define SVM_EXIT_WRITE_CR3 0x013 -#define SVM_EXIT_WRITE_CR4 0x014 -#define SVM_EXIT_WRITE_CR8 0x018 -#define SVM_EXIT_READ_DR0 0x020 -#define SVM_EXIT_READ_DR1 0x021 -#define SVM_EXIT_READ_DR2 0x022 -#define SVM_EXIT_READ_DR3 0x023 -#define SVM_EXIT_READ_DR4 0x024 -#define SVM_EXIT_READ_DR5 0x025 -#define SVM_EXIT_READ_DR6 0x026 -#define SVM_EXIT_READ_DR7 0x027 -#define SVM_EXIT_WRITE_DR0 0x030 -#define SVM_EXIT_WRITE_DR1 0x031 -#define SVM_EXIT_WRITE_DR2 0x032 -#define SVM_EXIT_WRITE_DR3 0x033 -#define SVM_EXIT_WRITE_DR4 0x034 -#define SVM_EXIT_WRITE_DR5 0x035 -#define SVM_EXIT_WRITE_DR6 0x036 -#define SVM_EXIT_WRITE_DR7 0x037 -#define SVM_EXIT_EXCP_BASE 0x040 -#define SVM_EXIT_INTR 0x060 -#define SVM_EXIT_NMI 0x061 -#define SVM_EXIT_SMI 0x062 -#define SVM_EXIT_INIT 0x063 -#define SVM_EXIT_VINTR 0x064 -#define SVM_EXIT_CR0_SEL_WRITE 0x065 -#define SVM_EXIT_IDTR_READ 0x066 -#define SVM_EXIT_GDTR_READ 0x067 -#define SVM_EXIT_LDTR_READ 0x068 -#define SVM_EXIT_TR_READ 0x069 -#define SVM_EXIT_IDTR_WRITE 0x06a -#define SVM_EXIT_GDTR_WRITE 0x06b -#define SVM_EXIT_LDTR_WRITE 0x06c -#define SVM_EXIT_TR_WRITE 0x06d -#define SVM_EXIT_RDTSC 0x06e -#define SVM_EXIT_RDPMC 0x06f -#define SVM_EXIT_PUSHF 0x070 -#define SVM_EXIT_POPF 0x071 -#define SVM_EXIT_CPUID 0x072 -#define SVM_EXIT_RSM 0x073 -#define SVM_EXIT_IRET 0x074 -#define SVM_EXIT_SWINT 0x075 -#define SVM_EXIT_INVD 0x076 -#define SVM_EXIT_PAUSE 0x077 -#define SVM_EXIT_HLT 0x078 -#define SVM_EXIT_INVLPG 0x079 -#define SVM_EXIT_INVLPGA 0x07a -#define SVM_EXIT_IOIO 0x07b -#define SVM_EXIT_MSR 0x07c -#define SVM_EXIT_TASK_SWITCH 0x07d -#define SVM_EXIT_FERR_FREEZE 0x07e -#define SVM_EXIT_SHUTDOWN 0x07f -#define SVM_EXIT_VMRUN 0x080 -#define SVM_EXIT_VMMCALL 0x081 -#define SVM_EXIT_VMLOAD 0x082 -#define SVM_EXIT_VMSAVE 0x083 -#define SVM_EXIT_STGI 0x084 -#define SVM_EXIT_CLGI 0x085 -#define SVM_EXIT_SKINIT 0x086 -#define SVM_EXIT_RDTSCP 0x087 -#define SVM_EXIT_ICEBP 0x088 -#define SVM_EXIT_WBINVD 0x089 -#define SVM_EXIT_MONITOR 0x08a -#define SVM_EXIT_MWAIT 0x08b -#define SVM_EXIT_MWAIT_COND 0x08c -#define SVM_EXIT_NPF 0x400 - -#define SVM_EXIT_ERR -1 - -#define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) - -#endif - diff --git a/kvm/test/x86/taskswitch.c b/kvm/test/x86/taskswitch.c deleted file mode 100644 index 8ed8a935f..000000000 --- a/kvm/test/x86/taskswitch.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2010 Siemens AG - * Author: Jan Kiszka - * - * Released under GPLv2. - */ - -#include "libcflat.h" - -#define FIRST_SPARE_SEL 0x18 - -struct exception_frame { - unsigned long error_code; - unsigned long ip; - unsigned long cs; - unsigned long flags; -}; - -struct tss32 { - unsigned short prev; - unsigned short res1; - unsigned long esp0; - unsigned short ss0; - unsigned short res2; - unsigned long esp1; - unsigned short ss1; - unsigned short res3; - unsigned long esp2; - unsigned short ss2; - unsigned short res4; - unsigned long cr3; - unsigned long eip; - unsigned long eflags; - unsigned long eax, ecx, edx, ebx, esp, ebp, esi, edi; - unsigned short es; - unsigned short res5; - unsigned short cs; - unsigned short res6; - unsigned short ss; - unsigned short res7; - unsigned short ds; - unsigned short res8; - unsigned short fs; - unsigned short res9; - unsigned short gs; - unsigned short res10; - unsigned short ldt; - unsigned short res11; - unsigned short t:1; - unsigned short res12:15; - unsigned short iomap_base; -}; - -static char main_stack[4096]; -static char fault_stack[4096]; -static struct tss32 main_tss; -static struct tss32 fault_tss; - -static unsigned long long gdt[] __attribute__((aligned(16))) = { - 0, - 0x00cf9b000000ffffull, - 0x00cf93000000ffffull, - 0, 0, /* TSS segments */ - 0, /* task return gate */ -}; - -static unsigned long long gdtr; - -void fault_entry(void); - -static __attribute__((used, regparm(1))) void -fault_handler(unsigned long error_code) -{ - unsigned short *desc; - - printf("fault at %x:%x, prev task %x, error code %x\n", - main_tss.cs, main_tss.eip, fault_tss.prev, error_code); - - main_tss.eip += 2; - - desc = (unsigned short *)&gdt[3]; - desc[2] &= ~0x0200; - - desc = (unsigned short *)&gdt[5]; - desc[0] = 0; - desc[1] = fault_tss.prev; - desc[2] = 0x8500; - desc[3] = 0; -} - -asm ( - "fault_entry:\n" - " mov (%esp),%eax\n" - " call fault_handler\n" - " jmp $0x28, $0\n" -); - -static void setup_tss(struct tss32 *tss, void *entry, - void *stack_base, unsigned long stack_size) -{ - unsigned long cr3; - unsigned short cs, ds; - - asm ("mov %%cr3,%0" : "=r" (cr3)); - asm ("mov %%cs,%0" : "=r" (cs)); - asm ("mov %%ds,%0" : "=r" (ds)); - - tss->ss0 = tss->ss1 = tss->ss2 = tss->ss = ds; - tss->esp0 = tss->esp1 = tss->esp2 = tss->esp = - (unsigned long)stack_base + stack_size; - tss->ds = tss->es = tss->fs = tss->gs = ds; - tss->cs = cs; - tss->eip = (unsigned long)entry; - tss->cr3 = cr3; -} - -static void setup_tss_desc(unsigned short tss_sel, struct tss32 *tss) -{ - unsigned long addr = (unsigned long)tss; - unsigned short *desc; - - desc = (unsigned short *)&gdt[tss_sel/8]; - desc[0] = sizeof(*tss) - 1; - desc[1] = addr; - desc[2] = 0x8900 | ((addr & 0x00ff0000) >> 16); - desc[3] = (addr & 0xff000000) >> 16; -} - -static void set_intr_task(unsigned short tss_sel, int intr, struct tss32 *tss) -{ - unsigned short *desc = (void *)(intr* sizeof(long) * 2); - - setup_tss_desc(tss_sel, tss); - - desc[0] = 0; - desc[1] = tss_sel; - desc[2] = 0x8500; - desc[3] = 0; -} - -int main(int ac, char **av) -{ - const long invalid_segment = 0x1234; - - gdtr = ((unsigned long long)(unsigned long)&gdt << 16) | - (sizeof(gdt) - 1); - asm ("lgdt %0" : : "m" (gdtr)); - - setup_tss(&main_tss, 0, main_stack, sizeof(main_stack)); - setup_tss_desc(FIRST_SPARE_SEL, &main_tss); - asm ("ltr %0" : : "r" ((unsigned short)FIRST_SPARE_SEL)); - - setup_tss(&fault_tss, fault_entry, fault_stack, sizeof(fault_stack)); - set_intr_task(FIRST_SPARE_SEL+8, 13, &fault_tss); - - asm ( - "mov %0,%%es\n" - : : "r" (invalid_segment) : "edi" - ); - - printf("post fault\n"); - - return 0; -} diff --git a/kvm/test/x86/tsc.c b/kvm/test/x86/tsc.c deleted file mode 100644 index 394a9c6b8..000000000 --- a/kvm/test/x86/tsc.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "libcflat.h" - -u64 rdtsc(void) -{ - unsigned a, d; - - asm volatile("rdtsc" : "=a"(a), "=d"(d)); - return a | (u64)d << 32; -} - -void wrtsc(u64 tsc) -{ - unsigned a = tsc, d = tsc >> 32; - - asm volatile("wrmsr" : : "a"(a), "d"(d), "c"(0x10)); -} - -void test_wrtsc(u64 t1) -{ - u64 t2; - - wrtsc(t1); - t2 = rdtsc(); - printf("rdtsc after wrtsc(%lld): %lld\n", t1, t2); -} - -int main() -{ - u64 t1, t2; - - t1 = rdtsc(); - t2 = rdtsc(); - printf("rdtsc latency %lld\n", (unsigned)(t2 - t1)); - - test_wrtsc(0); - test_wrtsc(100000000000ull); - return 0; -} diff --git a/kvm/test/x86/types.h b/kvm/test/x86/types.h deleted file mode 100644 index fd2274399..000000000 --- a/kvm/test/x86/types.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __TYPES_H -#define __TYPES_H - -#define DE_VECTOR 0 -#define DB_VECTOR 1 -#define BP_VECTOR 3 -#define OF_VECTOR 4 -#define BR_VECTOR 5 -#define UD_VECTOR 6 -#define NM_VECTOR 7 -#define DF_VECTOR 8 -#define TS_VECTOR 10 -#define NP_VECTOR 11 -#define SS_VECTOR 12 -#define GP_VECTOR 13 -#define PF_VECTOR 14 -#define MF_VECTOR 16 -#define MC_VECTOR 18 - -#endif diff --git a/kvm/test/x86/unittests.cfg b/kvm/test/x86/unittests.cfg deleted file mode 100644 index 7796e4112..000000000 --- a/kvm/test/x86/unittests.cfg +++ /dev/null @@ -1,65 +0,0 @@ -# Define your new unittest following the convention: -# [unittest_name] -# file = foo.flat # Name of the flat file to be used -# smp = 2 # Number of processors the VM will use during this test -# extra_params = -cpu qemu64,+x2apic # Additional parameters used - -[apic] -file = apic.flat -smp = 2 -extra_params: -cpu qemu64,+x2apic - -[smptest] -file = smptest.flat -smp = 2 - -[smptest3] -file = smptest.flat -smp = 3 - -[vmexit] -file = vmexit.flat -smp = 2 - -[access] -file = access.flat - -[emulator] -file = emulator.flat - -[hypercall] -file = hypercall.flat - -[idt_test] -file = idt_test.flat - -[msr] -file = msr.flat - -[port80] -file = port80.flat - -[realmode] -file = realmode.flat - -[sieve] -file = sieve.flat - -[tsc] -file = tsc.flat - -[xsave] -file = xsave.flat - -[rmap_chain] -file = rmap_chain.flat - -[svm] -file = svm.flat -smp = 2 -extra_params = -enable-nesting -cpu qemu64,+svm - -[svm-disabled] -file = svm.flat -smp = 2 -extra_params = -cpu qemu64,-svm diff --git a/kvm/test/x86/vm.c b/kvm/test/x86/vm.c deleted file mode 100644 index 62b3ba8d1..000000000 --- a/kvm/test/x86/vm.c +++ /dev/null @@ -1,229 +0,0 @@ -#include "vm.h" -#include "libcflat.h" - -#define PAGE_SIZE 4096ul -#ifdef __x86_64__ -#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) -#else -#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE) -#endif - -#define X86_CR0_PE 0x00000001 -#define X86_CR0_PG 0x80000000 -#define X86_CR4_PSE 0x00000010 -static void *free = 0; -static void *vfree_top = 0; - -static void free_memory(void *mem, unsigned long size) -{ - while (size >= PAGE_SIZE) { - *(void **)mem = free; - free = mem; - mem += PAGE_SIZE; - size -= PAGE_SIZE; - } -} - -void *alloc_page() -{ - void *p; - - if (!free) - return 0; - - p = free; - free = *(void **)free; - - return p; -} - -void free_page(void *page) -{ - *(void **)page = free; - free = page; -} - -extern char edata; -static unsigned long end_of_memory; - -#ifdef __x86_64__ -#define PAGE_LEVEL 4 -#define PGDIR_WIDTH 9 -#define PGDIR_MASK 511 -#else -#define PAGE_LEVEL 2 -#define PGDIR_WIDTH 10 -#define PGDIR_MASK 1023 -#endif - -void install_pte(unsigned long *cr3, - int pte_level, - void *virt, - unsigned long pte, - unsigned long *pt_page) -{ - int level; - unsigned long *pt = cr3; - unsigned offset; - - for (level = PAGE_LEVEL; level > pte_level; --level) { - offset = ((unsigned long)virt >> ((level-1) * PGDIR_WIDTH + 12)) & PGDIR_MASK; - if (!(pt[offset] & PTE_PRESENT)) { - unsigned long *new_pt = pt_page; - if (!new_pt) - new_pt = alloc_page(); - else - pt_page = 0; - memset(new_pt, 0, PAGE_SIZE); - pt[offset] = virt_to_phys(new_pt) | PTE_PRESENT | PTE_WRITE; - } - pt = phys_to_virt(pt[offset] & 0xffffffffff000ull); - } - offset = ((unsigned long)virt >> ((level-1) * PGDIR_WIDTH + 12)) & PGDIR_MASK; - pt[offset] = pte; -} - -static unsigned long get_pte(unsigned long *cr3, void *virt) -{ - int level; - unsigned long *pt = cr3, pte; - unsigned offset; - - for (level = PAGE_LEVEL; level > 1; --level) { - offset = ((unsigned long)virt >> (((level-1) * PGDIR_WIDTH) + 12)) & PGDIR_MASK; - pte = pt[offset]; - if (!(pte & PTE_PRESENT)) - return 0; - if (level == 2 && (pte & PTE_PSE)) - return pte; - pt = phys_to_virt(pte & 0xffffffffff000ull); - } - offset = ((unsigned long)virt >> (((level-1) * PGDIR_WIDTH) + 12)) & PGDIR_MASK; - pte = pt[offset]; - return pte; -} - -void install_large_page(unsigned long *cr3, - unsigned long phys, - void *virt) -{ - install_pte(cr3, 2, virt, phys | PTE_PRESENT | PTE_WRITE | PTE_PSE, 0); -} - -void install_page(unsigned long *cr3, - unsigned long phys, - void *virt) -{ - install_pte(cr3, 1, virt, phys | PTE_PRESENT | PTE_WRITE, 0); -} - - -static inline void load_gdt(unsigned long *table, int nent) -{ - struct descriptor_table_ptr descr; - - descr.limit = nent * 8 - 1; - descr.base = (ulong)table; - lgdt(&descr); -} - -#define SEG_CS_32 8 -#define SEG_CS_64 16 - -struct ljmp { - void *ofs; - unsigned short seg; -}; - -static void setup_mmu(unsigned long len) -{ - unsigned long *cr3 = alloc_page(); - unsigned long phys = 0; - - if (len < (1ul << 32)) - len = 1ul << 32; /* map mmio 1:1 */ - - memset(cr3, 0, PAGE_SIZE); - while (phys + LARGE_PAGE_SIZE <= len) { - install_large_page(cr3, phys, (void *)phys); - phys += LARGE_PAGE_SIZE; - } - while (phys + PAGE_SIZE <= len) { - install_page(cr3, phys, (void *)phys); - phys += PAGE_SIZE; - } - write_cr3(virt_to_phys(cr3)); -#ifndef __x86_64__ - write_cr4(X86_CR4_PSE); -#endif - write_cr0(X86_CR0_PG |X86_CR0_PE); - - printf("paging enabled\n"); - printf("cr0 = %x\n", read_cr0()); - printf("cr3 = %x\n", read_cr3()); - printf("cr4 = %x\n", read_cr4()); -} - -static unsigned int inl(unsigned short port) -{ - unsigned int val; - asm volatile("inl %w1, %0" : "=a"(val) : "Nd"(port)); - return val; -} - -void setup_vm() -{ - end_of_memory = inl(0xd1); - free_memory(&edata, end_of_memory - (unsigned long)&edata); - setup_mmu(end_of_memory); -} - -void *vmalloc(unsigned long size) -{ - void *mem, *p; - unsigned pages; - - size += sizeof(unsigned long); - - size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - vfree_top -= size; - mem = p = vfree_top; - pages = size / PAGE_SIZE; - while (pages--) { - install_page(phys_to_virt(read_cr3()), virt_to_phys(alloc_page()), p); - p += PAGE_SIZE; - } - *(unsigned long *)mem = size; - mem += sizeof(unsigned long); - return mem; -} - -void vfree(void *mem) -{ - unsigned long size = ((unsigned long *)mem)[-1]; - - while (size) { - free_page(phys_to_virt(get_pte(phys_to_virt(read_cr3()), mem) & PTE_ADDR)); - mem += PAGE_SIZE; - size -= PAGE_SIZE; - } -} - -void *vmap(unsigned long long phys, unsigned long size) -{ - void *mem, *p; - unsigned pages; - - size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - vfree_top -= size; - phys &= ~(unsigned long long)(PAGE_SIZE - 1); - - mem = p = vfree_top; - pages = size / PAGE_SIZE; - while (pages--) { - install_page(phys_to_virt(read_cr3()), phys, p); - phys += PAGE_SIZE; - p += PAGE_SIZE; - } - return mem; -} diff --git a/kvm/test/x86/vm.h b/kvm/test/x86/vm.h deleted file mode 100644 index a3d26765d..000000000 --- a/kvm/test/x86/vm.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef VM_H -#define VM_H - -#include "processor.h" - -#define PAGE_SIZE 4096ul -#ifdef __x86_64__ -#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) -#else -#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE) -#endif - -#define PTE_PRESENT (1ull << 0) -#define PTE_PSE (1ull << 7) -#define PTE_WRITE (1ull << 1) -#define PTE_ADDR (0xffffffffff000ull) - -void setup_vm(); - -void *vmalloc(unsigned long size); -void vfree(void *mem); -void *vmap(unsigned long long phys, unsigned long size); - -void install_pte(unsigned long *cr3, - int pte_level, - void *virt, - unsigned long pte, - unsigned long *pt_page); - -void *alloc_page(); - -void install_large_page(unsigned long *cr3,unsigned long phys, - void *virt); -void install_page(unsigned long *cr3, unsigned long phys, void *virt); - -static inline unsigned long virt_to_phys(const void *virt) -{ - return (unsigned long)virt; -} - -static inline void *phys_to_virt(unsigned long phys) -{ - return (void *)phys; -} - -#endif diff --git a/kvm/test/x86/vmexit.c b/kvm/test/x86/vmexit.c deleted file mode 100644 index 707d5c6f8..000000000 --- a/kvm/test/x86/vmexit.c +++ /dev/null @@ -1,188 +0,0 @@ - -#include "libcflat.h" -#include "smp.h" - -static inline unsigned long long rdtsc() -{ - long long r; - -#ifdef __x86_64__ - unsigned a, d; - - asm volatile ("rdtsc" : "=a"(a), "=d"(d)); - r = a | ((long long)d << 32); -#else - asm volatile ("rdtsc" : "=A"(r)); -#endif - return r; -} - -static unsigned int inl(unsigned short port) -{ - unsigned int val; - asm volatile("inl %w1, %0" : "=a"(val) : "Nd"(port)); - return val; -} - -#define GOAL (1ull << 30) - -#ifdef __x86_64__ -# define R "r" -#else -# define R "e" -#endif - -static void cpuid(void) -{ - asm volatile ("push %%"R "bx; cpuid; pop %%"R "bx" - : : : "eax", "ecx", "edx"); -} - -static void vmcall(void) -{ - unsigned long a = 0, b, c, d; - - asm volatile ("vmcall" : "+a"(a), "=b"(b), "=c"(c), "=d"(d)); -} - -#define MSR_EFER 0xc0000080 -#define EFER_NX_MASK (1ull << 11) - -unsigned long long rdmsr(unsigned index) -{ - unsigned a, d; - - asm volatile("rdmsr" : "=a"(a), "=d"(d) : "c"(index)); - return ((unsigned long long)d << 32) | a; -} - -void wrmsr(unsigned index, unsigned long long val) -{ - unsigned a = val, d = val >> 32; - - asm volatile("wrmsr" : : "a"(a), "d"(d), "c"(index)); -} - -static void mov_from_cr8(void) -{ - unsigned long cr8; - - asm volatile ("mov %%cr8, %0" : "=r"(cr8)); -} - -static void mov_to_cr8(void) -{ - unsigned long cr8 = 0; - - asm volatile ("mov %0, %%cr8" : : "r"(cr8)); -} - -static int is_smp(void) -{ - return cpu_count() > 1; -} - -static void nop(void *junk) -{ -} - -static void ipi(void) -{ - on_cpu(1, nop, 0); -} - -static void ipi_halt(void) -{ - unsigned long long t; - - on_cpu(1, nop, 0); - t = rdtsc() + 2000; - while (rdtsc() < t) - ; -} - -static void inl_pmtimer(void) -{ - inl(0xb008); -} - -static struct test { - void (*func)(void); - const char *name; - int (*valid)(void); - int parallel; -} tests[] = { - { cpuid, "cpuid", .parallel = 1, }, - { vmcall, "vmcall", .parallel = 1, }, - { mov_from_cr8, "mov_from_cr8", .parallel = 1, }, - { mov_to_cr8, "mov_to_cr8" , .parallel = 1, }, - { inl_pmtimer, "inl_from_pmtimer", .parallel = 1, }, - { ipi, "ipi", is_smp, .parallel = 0, }, - { ipi_halt, "ipi+halt", is_smp, .parallel = 0, }, -}; - -unsigned iterations; -volatile int nr_cpus_done; - -static void run_test(void *_func) -{ - int i; - void (*func)(void) = _func; - - for (i = 0; i < iterations; ++i) - func(); - - nr_cpus_done++; -} - -static void do_test(struct test *test) -{ - int i; - unsigned long long t1, t2; - void (*func)(void) = test->func; - - iterations = 32; - - if (test->valid && !test->valid()) { - printf("%s (skipped)\n", test->name); - return; - } - - do { - iterations *= 2; - t1 = rdtsc(); - - if (!test->parallel) { - for (i = 0; i < iterations; ++i) - func(); - } else { - nr_cpus_done = 0; - for (i = cpu_count(); i > 0; i--) - on_cpu_async(i-1, run_test, func); - while (nr_cpus_done < cpu_count()) - ; - } - t2 = rdtsc(); - } while ((t2 - t1) < GOAL); - printf("%s %d\n", test->name, (int)((t2 - t1) / iterations)); -} - -static void enable_nx(void *junk) -{ - wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK); -} - -int main(void) -{ - int i; - - smp_init(); - - for (i = cpu_count(); i > 0; i--) - on_cpu(i-1, enable_nx, 0); - - for (i = 0; i < ARRAY_SIZE(tests); ++i) - do_test(&tests[i]); - - return 0; -} diff --git a/kvm/test/x86/xsave.c b/kvm/test/x86/xsave.c deleted file mode 100644 index a22b44c7f..000000000 --- a/kvm/test/x86/xsave.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "libcflat.h" -#include "idt.h" - -#ifdef __x86_64__ -#define uint64_t unsigned long -#else -#define uint64_t unsigned long long -#endif - -static inline void __cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - /* ecx is often an input as well as an output. */ - asm volatile("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (*eax), "2" (*ecx)); -} - -/* - * Generic CPUID function - * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx - * resulting in stale register contents being returned. - */ -void cpuid(unsigned int op, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = 0; - __cpuid(eax, ebx, ecx, edx); -} - -/* Some CPUID calls want 'count' to be placed in ecx */ -void cpuid_count(unsigned int op, int count, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = count; - __cpuid(eax, ebx, ecx, edx); -} - -int xgetbv_checking(u32 index, u64 *result) -{ - u32 eax, edx; - - asm volatile(ASM_TRY("1f") - ".byte 0x0f,0x01,0xd0\n\t" /* xgetbv */ - "1:" - : "=a" (eax), "=d" (edx) - : "c" (index)); - *result = eax + ((u64)edx << 32); - return exception_vector(); -} - -int xsetbv_checking(u32 index, u64 value) -{ - u32 eax = value; - u32 edx = value >> 32; - - asm volatile(ASM_TRY("1f") - ".byte 0x0f,0x01,0xd1\n\t" /* xsetbv */ - "1:" - : : "a" (eax), "d" (edx), "c" (index)); - return exception_vector(); -} - -unsigned long read_cr4(void) -{ - unsigned long val; - asm volatile("mov %%cr4,%0" : "=r" (val)); - return val; -} - -int write_cr4_checking(unsigned long val) -{ - asm volatile(ASM_TRY("1f") - "mov %0,%%cr4\n\t" - "1:": : "r" (val)); - return exception_vector(); -} - -#define CPUID_1_ECX_XSAVE (1 << 26) -#define CPUID_1_ECX_OSXSAVE (1 << 27) -int check_cpuid_1_ecx(unsigned int bit) -{ - unsigned int eax, ebx, ecx, edx; - cpuid(1, &eax, &ebx, &ecx, &edx); - if (ecx & bit) - return 1; - return 0; -} - -uint64_t get_supported_xcr0(void) -{ - unsigned int eax, ebx, ecx, edx; - cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); - printf("eax %x, ebx %x, ecx %x, edx %x\n", - eax, ebx, ecx, edx); - return eax + ((u64)edx << 32); -} - -#define X86_CR4_OSXSAVE 0x00040000 -#define XCR_XFEATURE_ENABLED_MASK 0x00000000 -#define XCR_XFEATURE_ILLEGAL_MASK 0x00000010 - -#define XSTATE_FP 0x1 -#define XSTATE_SSE 0x2 -#define XSTATE_YMM 0x4 - -static int total_tests, fail_tests; - -void pass_if(int condition) -{ - total_tests ++; - if (condition) - printf("Pass!\n"); - else { - printf("Fail!\n"); - fail_tests ++; - } -} - -void test_xsave(void) -{ - unsigned long cr4; - uint64_t supported_xcr0; - uint64_t test_bits; - u64 xcr0; - int r; - - printf("Legal instruction testing:\n"); - supported_xcr0 = get_supported_xcr0(); - printf("Supported XCR0 bits: 0x%x\n", supported_xcr0); - - printf("Check minimal XSAVE required bits: "); - test_bits = XSTATE_FP | XSTATE_SSE; - pass_if((supported_xcr0 & test_bits) == test_bits); - - printf("Set CR4 OSXSAVE: "); - cr4 = read_cr4(); - r = write_cr4_checking(cr4 | X86_CR4_OSXSAVE); - pass_if(r == 0); - - printf("Check CPUID.1.ECX.OSXSAVE - expect 1: "); - pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE)); - - printf(" Legal tests\n"); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP): "); - test_bits = XSTATE_FP; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == 0); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_FP | XSTATE_SSE): "); - test_bits = XSTATE_FP | XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == 0); - printf(" xgetbv(XCR_XFEATURE_ENABLED_MASK): "); - r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0); - pass_if(r == 0); - printf(" Illegal tests\n"); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, 0) - expect #GP: "); - test_bits = 0; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_SSE) " - "- expect #GP: "); - test_bits = XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - if (supported_xcr0 & XSTATE_YMM) { - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_YMM) - expect #GP: "); - test_bits = XSTATE_YMM; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_FP | XSTATE_YMM) - expect #GP: "); - test_bits = XSTATE_FP | XSTATE_YMM; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - } - printf(" xsetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) " - "- expect #GP: "); - test_bits = XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ILLEGAL_MASK, test_bits); - pass_if(r == GP_VECTOR); - printf(" xgetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) " - "- expect #GP: "); - test_bits = XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ILLEGAL_MASK, test_bits); - pass_if(r == GP_VECTOR); - - printf("Unset CR4 OSXSAVE: "); - cr4 &= ~X86_CR4_OSXSAVE; - r = write_cr4_checking(cr4); - pass_if(r == 0); - printf("Check CPUID.1.ECX.OSXSAVE - expect 0: "); - pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE) == 0); - printf(" Illegal tests:\n"); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP) - expect #UD: "); - test_bits = XSTATE_FP; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == UD_VECTOR); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_FP | XSTATE_SSE) - expect #UD: "); - test_bits = XSTATE_FP | XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == UD_VECTOR); - printf(" Illegal tests:\n"); - printf(" xgetbv(XCR_XFEATURE_ENABLED_MASK) - expect #UD: "); - r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0); - pass_if(r == UD_VECTOR); -} - -void test_no_xsave(void) -{ - unsigned long cr4; - u64 xcr0; - int r; - - printf("Check CPUID.1.ECX.OSXSAVE - expect 0: "); - pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE) == 0); - - printf("Illegal instruction testing:\n"); - - printf("Set OSXSAVE in CR4 - expect #GP: "); - cr4 = read_cr4(); - r = write_cr4_checking(cr4 | X86_CR4_OSXSAVE); - pass_if(r == GP_VECTOR); - - printf("Execute xgetbv - expect #UD: "); - r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0); - pass_if(r == UD_VECTOR); - - printf("Execute xsetbv - expect #UD: "); - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, 0x3); - pass_if(r == UD_VECTOR); -} - -int main(void) -{ - setup_idt(); - if (check_cpuid_1_ecx(CPUID_1_ECX_XSAVE)) { - printf("CPU has XSAVE feature\n"); - test_xsave(); - } else { - printf("CPU don't has XSAVE feature\n"); - test_no_xsave(); - } - printf("Total test: %d\n", total_tests); - if (fail_tests == 0) - printf("ALL PASS!\n"); - else { - printf("Fail %d tests.\n", fail_tests); - return 1; - } - return 0; -} |