From patchwork Thu Jul 6 09:42:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9827861 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 18CC260317 for ; Thu, 6 Jul 2017 09:44:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 08EEB2856C for ; Thu, 6 Jul 2017 09:44:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F044F285E4; Thu, 6 Jul 2017 09:44:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6FD011FF22 for ; Thu, 6 Jul 2017 09:44:46 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dT3Ik-0002JZ-3b; Thu, 06 Jul 2017 09:42:22 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dT3Ij-0002JT-AY for xen-devel@lists.xenproject.org; Thu, 06 Jul 2017 09:42:21 +0000 Received: from [85.158.139.211] by server-1.bemta-5.messagelabs.com id 40/7C-01993-CF50E595; Thu, 06 Jul 2017 09:42:20 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrBIsWRWlGSWpSXmKPExsXS6fjDS/c3a1y kwb47xhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8bBBTfYCjoNKpa9aGZsYJyj0MXIySEkkCex a9pbdhCbV8BOYvr26cwgtoSAocTphTdZuhg5OFgEVCWOTiwECbMJqEu0PdvOCmKLCOhLzP/0k xWkhFnAQOLudxOQsLCAucSJV2sYQcJCQBNf/eUBMXkFBCX+7hAGqWAW0JJ4+OsWC4StLbFs4W tmiCHSEsv/cUxg5J2F0DALScMsJA2zEBoWMLKsYtQoTi0qSy3SNTTSSyrKTM8oyU3MzNE1NDD Vy00tLk5MT81JTCrWS87P3cQIDC8GINjB2DfL+RCjJAeTkiiv+OHYSCG+pPyUyozE4oz4otKc 1OJDjDIcHEoSvCdY4iKFBItS01Mr0jJzgIEOk5bg4FES4Y35AdTKW1yQmFucmQ6ROsVozLFh9 fovTByvJvz/xiTEkpeflyolzjsPZJIASGlGaR7cIFgEXmKUlRLmZQQ6TYinILUoN7MEVf4Voz gHo5IwrxIwnoV4MvNK4Pa9AjqFCegUxcYYkFNKEhFSUg2Mfm+edbeyNPzN4KlY3LRnq85Xhh0 s8S5G8d/4pGK/dLDwf936U+o022SLCb8NTdYpc0XfjWIz2rolZKHgEhezh35lUXNqgt+efdos bbJsTadNZZvw36CsGGnZ/Y9Y0hJe86Q3u15SyUz8dLHSlvVOh6nVId6UsykHy7L4N7w5yTPNP 18qRlCJpTgj0VCLuag4EQDXAc1AuwIAAA== X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-13.tower-206.messagelabs.com!1499334137!86157380!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 47548 invoked from network); 6 Jul 2017 09:42:19 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-13.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 6 Jul 2017 09:42:19 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Thu, 06 Jul 2017 03:42:17 -0600 Message-Id: <595E22190200007800169140@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.2 Date: Thu, 06 Jul 2017 03:42:17 -0600 From: "Jan Beulich" To: "Andrew Cooper" References: <595E22190200007800169140@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Disposition: inline Cc: xen-devel Subject: [Xen-devel] [PATCH RFC][XTF] add split memory access tests X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- /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 + +#include + +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: + */