[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC][XTF] add split memory access tests
Add tests to verify that accesses crossing the upper address boundary are being handled similarly with and without the emulator involved. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- /dev/null +++ b/tests/split-access/Makefile @@ -0,0 +1,9 @@ +include $(ROOT)/build/common.mk + +NAME := split-access +CATEGORY := utility +TEST-ENVS := $(HVM_ENVIRONMENTS) + +obj-perenv += main.o + +include $(ROOT)/build/gen.mk --- /dev/null +++ b/tests/split-access/main.c @@ -0,0 +1,218 @@ +/** + * @file tests/split-access/main.c + * @ref test-split-access + * + * @page test-split-access split-access + * + * @todo Docs for test-split-access + * + * @see tests/split-access/main.c + */ +#include <xtf.h> + +#include <arch/decode.h> + +const char test_title[] = "Split memory access insns"; + +/* Keep the compiler from leveraging undefined behavior. */ +#define touch(x) ({ asm ( "" : "+g" (x) ); }) + +void do_mov(bool force) +{ + const unsigned long *ptr = NULL; + + touch(ptr); + + for ( --ptr; ; ) + { + unsigned long val; + exinfo_t fault = 0; + + asm volatile ( "test %[fep], %[fep];" + "jz 1f;" + _ASM_XEN_FEP + "1: mov %[src],%[dst]; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax) + : [dst] "=r" (val), "+a" (fault) + : [src] "m" (*ptr), [fep] "q" (force) ); + if ( fault ) + { + char excstr[16]; + + x86_decode_exinfo(excstr, ARRAY_SIZE(excstr), fault); + xtf_warning("Got %s for %p'\n", excstr, ptr); + } + else if ( val != *ptr ) + xtf_failure("%lx != %lx for %p'\n", val, *ptr, ptr); + + touch(ptr); + if ( !ptr ) + break; + + ptr = (void *)(long)ptr + 1; + } +} + +void do_lfs(bool force) +{ + const struct __packed { unsigned long off; uint16_t sel; } *ptr = NULL; + + touch(ptr); + + for ( --ptr; ; ) + { + unsigned long off; + exinfo_t fault = 0; + + asm volatile ( "test %[fep], %[fep];" + "jz 1f;" + _ASM_XEN_FEP + "1: lfs %[src],%[dst]; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax) + : [dst] "=r" (off), "+a" (fault) + : [src] "m" (*ptr), [fep] "q" (force) ); + if ( fault ) + { + char excstr[16]; + + x86_decode_exinfo(excstr, ARRAY_SIZE(excstr), fault); + xtf_warning("Got %s for %p'\n", excstr, ptr); + } + else if ( off != ptr->off ) + xtf_failure("%lx != %lx for %p'\n", off, ptr->off, ptr); + + touch(ptr); + if ( !ptr ) + break; + + ptr = (void *)(long)ptr + 1; + } +} + +void do_lidt(bool force) +{ + const desc_ptr *ptr = NULL; + + touch(ptr); + + for ( --ptr; ; ) + { + exinfo_t fault = 0; + + asm volatile ( "test %[fep], %[fep];" + "jz 1f;" + _ASM_XEN_FEP + "1: lidt %[src]; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax) + : "+a" (fault) + : [src] "m" (*ptr), [fep] "q" (force) ); + if ( fault ) + { + char excstr[16]; + + x86_decode_exinfo(excstr, ARRAY_SIZE(excstr), fault); + xtf_warning("Got %s for %p\n", excstr, ptr); + } + else + asm volatile ( "lidt %0" :: "m" (idt_ptr) ); + + touch(ptr); + if ( !ptr ) + break; + + ptr = (void *)(long)ptr + 1; + } +} + +#ifndef __x86_64__ +void do_bound(bool force) +{ + const struct { unsigned long lo, hi; } *ptr = NULL; + + touch(ptr); + + for ( --ptr; ; ) + { + exinfo_t fault = 0; + + asm volatile ( "test %[fep], %[fep];" + "jz 1f;" + _ASM_XEN_FEP + "1: bound %[off], %[bnd]; 2:" + _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax) + : "+a" (fault) + : [bnd] "m" (*ptr), [off] "r" (0), [fep] "q" (force) ); + if ( fault ) + { + char excstr[16]; + + x86_decode_exinfo(excstr, ARRAY_SIZE(excstr), fault); + xtf_warning("Got %s for %p\n", excstr, ptr); + } + + touch(ptr); + if ( !ptr ) + break; + + ptr = (void *)(long)ptr + 1; + } +} +#endif + +void run_tests(bool force) +{ + printk("Testing%s MOV\n", force ? " emulated" : ""); + do_mov(force); + + printk("Testing%s LFS\n", force ? " emulated" : ""); + do_lfs(force); + + printk("Testing%s LIDT\n", force ? " emulated" : ""); + do_lidt(force); + +#ifndef __x86_64__ + printk("Testing%s BOUND\n", force ? " emulated" : ""); + do_bound(force); +#endif +} + +void test_main(void) +{ +#if !defined(__x86_64__) && CONFIG_PAGING_LEVELS > 0 + /* + * To better tell actual hardware behavior, zap the mapping for the last + * (large) page below 4Gb. That'll make us see page faults when hardware + * when all segmentation checks pass, rather than observing #GP/#SS due to + * the emulator being invoked anyway due to accesses touching an unmapped + * MMIO range. This matches x86-64 behavior at the 2^^64 boundary. + */ +# if CONFIG_PAGING_LEVELS == 2 + pse_l2_identmap[pse_l2_table_offset(~0UL)] = 0; +# elif CONFIG_PAGING_LEVELS == 3 + pae_l2_identmap[pae_l2_table_offset(~0UL)] = 0; +# else +# error Bad 32-bit paging mode! +# endif + + invlpg((void *)~0UL); +#endif + + run_tests(false); + + if ( !xtf_has_fep ) + xtf_skip("FEP support not detected - some tests will be skipped\n"); + else + run_tests(true); + + xtf_success(NULL); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |