On 04/23/2018 06:18 PM, Jan Kiszka wrote:
> 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
This is already defined inmates/lib/x86/inmate.h, which is included.
Ralf
> +
> +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");
> +}
>
--
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.