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.

Reply via email to