From: Jan Kiszka <[email protected]> This lays the ground for systematic tests of the MMIO instruction parser in x86. The test-case inmate uses the new MMIO access test device for writing and reading with yet a small number of instructions variants. This is supposed to expanded later on with further patterns - but it already revealed several bugs in the handling of immediate writes.
Signed-off-by: Jan Kiszka <[email protected]> --- configs/x86/tiny-demo.c | 3 +- inmates/Makefile | 7 +- inmates/tests/arm/Makefile | 1 + inmates/tests/arm64/Makefile | 1 + inmates/tests/x86/Makefile | 19 +++++ inmates/tests/x86/mmio-access.c | 149 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 inmates/tests/arm/Makefile create mode 100644 inmates/tests/arm64/Makefile create mode 100644 inmates/tests/x86/Makefile create mode 100644 inmates/tests/x86/mmio-access.c diff --git a/configs/x86/tiny-demo.c b/configs/x86/tiny-demo.c index 9666bf63c..0556cd88a 100644 --- a/configs/x86/tiny-demo.c +++ b/configs/x86/tiny-demo.c @@ -28,7 +28,8 @@ struct { .signature = JAILHOUSE_CELL_DESC_SIGNATURE, .revision = JAILHOUSE_CONFIG_REVISION, .name = "tiny-demo", - .flags = JAILHOUSE_CELL_PASSIVE_COMMREG, + .flags = JAILHOUSE_CELL_PASSIVE_COMMREG | + JAILHOUSE_CELL_TEST_DEVICE, .cpu_set_size = sizeof(config.cpus), .num_memory_regions = ARRAY_SIZE(config.mem_regions), diff --git a/inmates/Makefile b/inmates/Makefile index 29b6236c6..2f26bf55d 100644 --- a/inmates/Makefile +++ b/inmates/Makefile @@ -35,7 +35,8 @@ endif OBJCOPYFLAGS := -O binary LDFLAGS += --gc-sections -T -subdir-y := lib/$(SRCARCH) demos/$(SRCARCH) tools/$(SRCARCH) +subdir-y := lib/$(SRCARCH) demos/$(SRCARCH) tests/$(SRCARCH) tools/$(SRCARCH) -# demos and tools depend on the library -$(obj)/demos/$(SRCARCH) $(obj)/tools/$(SRCARCH): $(obj)/lib/$(SRCARCH) +# demos, tests and tools depend on the library +$(obj)/demos/$(SRCARCH) $(obj)/tests/$(SRCARCH) $(obj)/tools/$(SRCARCH): \ + $(obj)/lib/$(SRCARCH) diff --git a/inmates/tests/arm/Makefile b/inmates/tests/arm/Makefile new file mode 100644 index 000000000..7ae637a7b --- /dev/null +++ b/inmates/tests/arm/Makefile @@ -0,0 +1 @@ +# nothing to do for now diff --git a/inmates/tests/arm64/Makefile b/inmates/tests/arm64/Makefile new file mode 100644 index 000000000..7ae637a7b --- /dev/null +++ b/inmates/tests/arm64/Makefile @@ -0,0 +1 @@ +# nothing to do for now diff --git a/inmates/tests/x86/Makefile b/inmates/tests/x86/Makefile new file mode 100644 index 000000000..ba276eb87 --- /dev/null +++ b/inmates/tests/x86/Makefile @@ -0,0 +1,19 @@ +# +# Jailhouse, a Linux-based partitioning hypervisor +# +# Copyright (c) Siemens AG, 2013-2018 +# +# Authors: +# Jan Kiszka <[email protected]> +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. +# + +include $(INMATES_LIB)/Makefile.lib + +INMATES := mmio-access.bin + +mmio-access-y := mmio-access.o + +$(eval $(call DECLARE_TARGETS,$(INMATES))) diff --git a/inmates/tests/x86/mmio-access.c b/inmates/tests/x86/mmio-access.c new file mode 100644 index 000000000..243e975b4 --- /dev/null +++ b/inmates/tests/x86/mmio-access.c @@ -0,0 +1,149 @@ +/* + * Jailhouse, a Linux-based partitioning hypervisor + * + * Copyright (c) Siemens AG, 2018 + * + * Authors: + * Jan Kiszka <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include <inmate.h> + +#define EXPECT_EQUAL(a, b) evaluate(a, b, __LINE__) + +#define COMM_REGION_BASE 0x100000 + +static bool all_passed = true; + +static void evaluate(u64 a, u64 b, int line) +{ + bool passed = (a == b); + + printk("Test at line #%d %s\n", line, passed ? "passed" : "FAILED"); + if (!passed) { + printk(" %llx != %llx\n", a, b); + all_passed = false; + } +} + +void inmate_main(void) +{ + volatile u64 *comm_page_reg = (void *)(COMM_REGION_BASE + 0xff8); + void *mmio_reg = (void *)(COMM_REGION_BASE + 0x1ff8); + u64 pattern, reg64; + + printk("\n"); + + /* --- Read Tests --- */ + + pattern = 0x1122334455667788; + mmio_write64(mmio_reg, pattern); + EXPECT_EQUAL(*comm_page_reg, pattern); + + /* MOV_FROM_MEM (8b), 64-bit data, mod=0, reg=0, rm=3 */ + asm volatile("movq (%%rbx), %%rax" + : "=a" (reg64) : "a" (0), "b" (mmio_reg)); + EXPECT_EQUAL(reg64, pattern); + + /* MOV_FROM_MEM (8b), 32-bit data */ + asm volatile("movl (%%rbx), %%eax" + : "=a" (reg64) : "a" (0), "b" (mmio_reg)); + EXPECT_EQUAL(reg64, (u32)pattern); + + /* MOVZXB (0f b6), to 64-bit, mod=0, reg=0, rm=3 */ + asm volatile("movzxb (%%rbx), %%rax" + : "=a" (reg64) : "a" (0), "b" (mmio_reg)); + EXPECT_EQUAL(reg64, (u8)pattern); + + /* MOVZXW (0f b7) */ + asm volatile("movzxw (%%rbx), %%rax" + : "=a" (reg64) : "a" (0), "b" (mmio_reg)); + EXPECT_EQUAL(reg64, (u16)pattern); + + /* MEM_TO_AX (a1), 64-bit data, 64-bit address */ + asm volatile("movabs (0x101ff8), %%rax" + : "=a" (reg64) : "a" (0)); + EXPECT_EQUAL(reg64, pattern); + + /* MEM_TO_AX (a1), 32-bit data, 64-bit address */ + asm volatile("movabs (0x101ff8), %%eax" + : "=a" (reg64) : "a" (0)); + EXPECT_EQUAL(reg64, (u32)pattern); + + printk("MMIO read test %s\n\n", all_passed ? "passed" : "FAILED"); + + /* --- Write Tests --- */ + + all_passed = true; + pattern = 0x8899aabbccddeeff; + mmio_write64(mmio_reg, ~pattern); + EXPECT_EQUAL(*comm_page_reg, ~pattern); + + /* MOV_TO_MEM (89), 64-bit data, mod=0, reg=0, rm=4, SIB.base=5 (disp32) */ + asm volatile("movq %%rax, (0x101ff8)" + : : "a" (pattern)); + EXPECT_EQUAL(*comm_page_reg, pattern); + + pattern = ~pattern; + /* MOV_TO_MEM (89), 64-bit data, mod=0, reg=0, rm=5 (rip+disp32) */ + asm volatile("movq %%rax, cmdline+0x101ef8(%%rip)" + : : "a" (pattern)); + EXPECT_EQUAL(*comm_page_reg, pattern); + + /* IMMEDIATE_TO_MEM (c7), 64-bit data, mod=0, reg=0, rm=3 */ + asm volatile("movq %0, (%%rbx)" + : : "i" (0x12345678), "b" (mmio_reg)); + EXPECT_EQUAL(*comm_page_reg, 0x12345678); + + /* IMMEDIATE_TO_MEM (c7), 64-bit data, mod=0, reg=0, rm=3, sign-extend */ + asm volatile("movq %0, (%%rbx)" + : : "i" (0xccddeeff), "b" (mmio_reg)); + EXPECT_EQUAL(*comm_page_reg, 0xffffffffccddeeff); + + mmio_write64(mmio_reg, 0x1122334455667788); + /* IMMEDIATE_TO_MEM (c7), 32-bit data */ + asm volatile("movl %0, (%%rbx)" + : : "i" (0xccddeeff), "b" (mmio_reg)); + EXPECT_EQUAL(*comm_page_reg, 0x11223344ccddeeff); + + mmio_write64(mmio_reg, 0x1122334455667788); + /* IMMEDIATE_TO_MEM (c7), 32-bit data, mod=1 (disp8), reg=0, rm=3 */ + asm volatile("movl %0, 0x10(%%rbx)" + : : "i" (0xccddeeff), "b" (mmio_reg - 0x10)); + EXPECT_EQUAL(*comm_page_reg, 0x11223344ccddeeff); + + /* IMMEDIATE_TO_MEM (c7), 32-bit data, mod=2 (disp32), reg=0, rm=3 */ + asm volatile("movl %0, 0x10000000(%%rbx)" + : : "i" (0xccddeeff), "b" (mmio_reg - 0x10000000)); + EXPECT_EQUAL(*comm_page_reg, 0x11223344ccddeeff); + + /* MOVB_TO_MEM (88), mod=0, reg=0, rm=3 */ + asm volatile("mov %%al, (%%rbx)" + : : "a" (0x99), "b" (mmio_reg)); + EXPECT_EQUAL(*comm_page_reg, 0x11223344ccddee99); + + /* MOV_TO_MEM (89), 64-bit data, mod=1 (disp8), reg=0, rm=3 */ + asm volatile("movq %%rax, 0x10(%%rbx)" + : : "a" (0x12345678), "b" (mmio_reg - 0x10)); + EXPECT_EQUAL(*comm_page_reg, 0x12345678); + + /* MOV_TO_MEM (89), 64-bit data, mod=2 (disp32), reg=0, rm=3 */ + asm volatile("movq %%rax, 0x10000000(%%rbx)" + : : "a" (0x12345678), "b" (mmio_reg - 0x10000000)); + EXPECT_EQUAL(*comm_page_reg, 0x12345678); + + /* MOV_TO_MEM (89), 64-bit data, mod=0, reg=0, rm=4 (SIB) */ + asm volatile("movq %%rax, (%%rbx,%%rcx)" + : : "a" (0x12345678), "b" (mmio_reg), "c" (0)); + EXPECT_EQUAL(*comm_page_reg, 0x12345678); + + /* MOV_TO_MEM (89), 64-bit data, mod=2 (disp32), reg=0, rm=4 (SIB) */ + asm volatile("movq %%rax, 0x10000000(%%rbx,%%rcx)" + : : "a" (0x12345678), "b" (mmio_reg - 0x10000000), "c" (0)); + EXPECT_EQUAL(*comm_page_reg, 0x12345678); + + printk("MMIO write test %s\n", all_passed ? "passed" : "FAILED"); +} -- 2.13.6 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
