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.
