Am Mon, 23 Apr 2018 18:18:30 +0200
schrieb "Jan Kiszka" <[email protected]>:

> From: Jan Kiszka <[email protected]>
> 
> On x86, we unfortunately need to parse the guest instruction that
> triggered an MMIO access interception. This parser started to be small
> and simple - and then real life bit. It already passed the point where
> we should have added systematic tests.
> 
> This is the hypervisor-located building block for such tests. The test
> creates a MMIO target page right after the Communication Page. Write
> accesses to the virtual registers 0xff8..0xfff are stored per cell,
> read accesses reproduce that written value. The virtual registers are
> backed by the Communication Page of the same cell at the same
> address, thus create a second channel to validate accesses.
> 
> This test device is optional, configured in during build time by
> setting CONFIG_TEST_DEVICE in config.h and during runtime by adding
> JAILHOUSE_CELL_TEST_DEVICE to the cell's config flags.
> 
> Signed-off-by: Jan Kiszka <[email protected]>
> ---
>  hypervisor/arch/x86/Kbuild        |   4 +-
>  hypervisor/arch/x86/test-device.c | 110
> ++++++++++++++++++++++++++++++++++++++
> include/jailhouse/cell-config.h   |   1 + 3 files changed, 114
> insertions(+), 1 deletion(-) create mode 100644
> hypervisor/arch/x86/test-device.c
> 
> diff --git a/hypervisor/arch/x86/Kbuild b/hypervisor/arch/x86/Kbuild
> index 476f9c1cc..8ab8d5636 100644
> --- a/hypervisor/arch/x86/Kbuild
> +++ b/hypervisor/arch/x86/Kbuild
> @@ -26,9 +26,11 @@ common-objs-y := apic.o dbg-write.o entry.o
> setup.o control.o mmio.o iommu.o \ paging.o pci.o i8042.o vcpu.o
> vga.o ivshmem.o 
>  # units initialization order as defined by linking order:
> -# iommu, ioapic, [cat], <generic units>
> +# iommu, ioapic, [test-device], [cat], <generic units>
>  
>  common-objs-y += ioapic.o
>  
> +common-objs-$(CONFIG_TEST_DEVICE) += test-device.o
> +
>  built-in-amd-y := svm.o amd_iommu.o svm-vmexit.o $(common-objs-y)
>  built-in-intel-y := vmx.o vtd.o vmx-vmexit.o $(common-objs-y) cat.o
> diff --git a/hypervisor/arch/x86/test-device.c
> b/hypervisor/arch/x86/test-device.c new file mode 100644
> index 000000000..081dad9f2
> --- /dev/null
> +++ b/hypervisor/arch/x86/test-device.c
> @@ -0,0 +1,110 @@
> +/*
> + * 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 <jailhouse/control.h>
> +#include <jailhouse/mmio.h>
> +#include <jailhouse/printk.h>
> +#include <jailhouse/unit.h>
> +
> +static unsigned int testdev_mmio_count_regions(struct cell *cell)
> +{
> +     return cell->config->flags & JAILHOUSE_CELL_TEST_DEVICE ?
> 1 : 0; +}
> +
> +static enum mmio_result testdev_handle_mmio_access(void *arg,
> +                                                struct
> mmio_access *mmio) +{
> +     void *test_reg =
> &this_cell()->comm_page.padding[mmio->address]; +
> +     if (mmio->address < 0xff8)

||  mmio->address > (0x1000 - mmio->size)

and now drop that condition in all cases down low

Henning

> +             goto invalid_access;
> +
> +     switch (mmio->size) {
> +     case 1:
> +             if (mmio->is_write)
> +                     *(u8 *)test_reg = mmio->value;
> +             else
> +                     mmio->value = *(u8 *)test_reg;
> +             break;
> +     case 2:
> +             if (mmio->address > 0x1000-2)
> +                     goto invalid_access;
> +             if (mmio->is_write)
> +                     *(u16 *)test_reg = mmio->value;
> +             else
> +                     mmio->value = *(u16 *)test_reg;
> +             break;
> +     case 4:
> +             if (mmio->address > 0x1000-4)
> +                     goto invalid_access;
> +             if (mmio->is_write)
> +                     *(u32 *)test_reg = mmio->value;
> +             else
> +                     mmio->value = *(u32 *)test_reg;
> +             break;
> +     case 8:
> +             if (mmio->address > 0x1000-8)
> +                     goto invalid_access;
> +             if (mmio->is_write)
> +                     *(u64 *)test_reg = mmio->value;
> +             else
> +                     mmio->value = *(u64 *)test_reg;
> +             break;
> +     }
> +     return MMIO_HANDLED;
> +
> +invalid_access:
> +     printk("testdev: invalid %s, register %lx, size %d\n",
> +            mmio->is_write ? "write" : "read", mmio->address,
> mmio->size);
> +     return MMIO_ERROR;
> +}
> +
> +static unsigned long testdev_get_mmio_base(struct cell *cell)
> +{
> +     const struct jailhouse_memory *mem;
> +     unsigned int n;
> +
> +     for_each_mem_region(mem, cell->config, n)
> +             if (mem->flags & JAILHOUSE_MEM_COMM_REGION)
> +                     return mem->virt_start + PAGE_SIZE;
> +
> +     return INVALID_PHYS_ADDR;
> +}
> +
> +static int testdev_cell_init(struct cell *cell)
> +{
> +     unsigned long comm_base;
> +
> +     if (cell->config->flags & JAILHOUSE_CELL_TEST_DEVICE) {
> +             comm_base = testdev_get_mmio_base(cell);
> +             if (comm_base == INVALID_PHYS_ADDR)
> +                     return trace_error(-EINVAL);
> +
> +             mmio_region_register(cell, comm_base, PAGE_SIZE,
> +                                  testdev_handle_mmio_access,
> NULL);
> +     }
> +     return 0;
> +}
> +
> +static void testdev_cell_exit(struct cell *cell)
> +{
> +     if (cell->config->flags & JAILHOUSE_CELL_TEST_DEVICE)
> +             mmio_region_unregister(cell,
> testdev_get_mmio_base(cell)); +}
> +
> +static int testdev_init(void)
> +{
> +     return 0;
> +}
> +
> +DEFINE_UNIT_SHUTDOWN_STUB(testdev);
> +DEFINE_UNIT(testdev, "Test device");
> diff --git a/include/jailhouse/cell-config.h
> b/include/jailhouse/cell-config.h index 15ed7cdd5..1d0ae2e59 100644
> --- a/include/jailhouse/cell-config.h
> +++ b/include/jailhouse/cell-config.h
> @@ -49,6 +49,7 @@
>  
>  #define JAILHOUSE_CELL_PASSIVE_COMMREG       0x00000001
>  #define JAILHOUSE_CELL_DEBUG_CONSOLE 0x00000002
> +#define JAILHOUSE_CELL_TEST_DEVICE   0x00000004
>  
>  #define JAILHOUSE_CELL_DESC_SIGNATURE        "JHCELL"
>  

-- 
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