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.

Reply via email to