From patchwork Wed May 31 07:37:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9756079 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 6BD9160360 for ; Wed, 31 May 2017 07:40:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57D36284C4 for ; Wed, 31 May 2017 07:40:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4C0C5284CF; Wed, 31 May 2017 07:40:15 +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 48FB7284D2 for ; Wed, 31 May 2017 07:40:14 +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 1dFyCY-0002Io-7H; Wed, 31 May 2017 07:37:54 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dFyCW-0002Ii-Nz for xen-devel@lists.xenproject.org; Wed, 31 May 2017 07:37:52 +0000 Received: from [85.158.137.68] by server-9.bemta-3.messagelabs.com id 31/49-26749-FC27E295; Wed, 31 May 2017 07:37:51 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrNIsWRWlGSWpSXmKPExsXS6fjDS/dckV6 kQeMJPYvvWyYzOTB6HP5whSWAMYo1My8pvyKBNePVv0+MBR+WMVZcn9jL3MC4o7yLkZNDSCBP 4suiA6wgNq+AncTt1ZeZQGwJAUOJ0wtvsoDYLAKqEvd+X2QDsdkE1CXanm0HqufgEBEwkDh3N AnEZBbQl9i2DqxaWCBUYvLRb2wQ04skJi1cBzadU8Be4vG7bewg5bwCghJ/dwhDdNpJtFyMms DIMwshMQshMQuolVlAS+Lhr1ssELa2xLKFr5khSqQllv/jgAjbSWxu6mFHVQJie0rMePGRcQE jxypGjeLUorLUIl0jI72kosz0jJLcxMwcXUMDY73c1OLixPTUnMSkYr3k/NxNjMBArWdgYNzB OPWE3yFGSQ4mJVHeChu9SCG+pPyUyozE4oz4otKc1OJDjDIcHEoSvD8KgXKCRanpqRVpmTnAm IFJS3DwKInwbgRJ8xYXJOYWZ6ZDpE4xKkqJQyQEQBIZpXlwbbA4vcQoKyXMy8jAwCDEU5BalJ tZgir/ilGcg1FJmPcryBSezLwSuOmvgBYzAS3etUMbZHFJIkJKqoFxyQ3WpQ0HtNpjX9Y8WqB ZeFXMUs+mp8lg7YcZOwzXyWxmzzN7x97NURf4ZfvnVTPn81t7Hj18L/mkRMaU5c4HTG9tU9gd LDFxQbPq9zZ5/mj+S+8ZTQX2T+cvVFj85jhfsQjrPZmu42KXdyWlGlz5x8hwK/vuQYZ4Zi9hP 52bpyeHrPy/fKqSEktxRqKhFnNRcSIAM2a+f84CAAA= X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-7.tower-31.messagelabs.com!1496216268!95759205!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.19; banners=-,-,- X-VirusChecked: Checked Received: (qmail 42436 invoked from network); 31 May 2017 07:37:50 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-7.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 31 May 2017 07:37:50 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Wed, 31 May 2017 01:37:47 -0600 Message-Id: <592E8EEB020000780015E02E@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.2 Date: Wed, 31 May 2017 01:37:47 -0600 From: "Jan Beulich" To: "xen-devel" References: <592E8C92020000780015E014@prv-mh.provo.novell.com> <592E8C92020000780015E014@prv-mh.provo.novell.com> In-Reply-To: <592E8C92020000780015E014@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH 1/2] hvmloader: dynamically determine scratch memory range for 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 This re-enables tests on configurations where commit 0d6968635c ("hvmloader: avoid tests when they would clobber used memory") forced them to be skipped. Signed-off-by: Jan Beulich hvmloader: dynamically determine scratch memory range for tests This re-enables tests on configurations where commit 0d6968635c ("hvmloader: avoid tests when they would clobber used memory") forced them to be skipped. Signed-off-by: Jan Beulich --- a/tools/firmware/hvmloader/tests.c +++ b/tools/firmware/hvmloader/tests.c @@ -29,14 +29,15 @@ /* * Memory layout during tests: - * 4MB to 8MB is cleared. - * Page directory resides at 4MB. - * 2 page table pages reside at 4MB+4kB to 4MB+12kB. - * Pagetables identity-map 0-8MB, except 4kB at va 6MB maps to pa 5MB. + * The 4MB block at test_mem_base is cleared. + * Page directory resides at test_mem_base. + * 2 page table pages reside at test_mem_base+4kB to test_mem_base+12kB. + * Pagetables identity-map 0-4MB and test_mem_base-test_mem_base+4MB, + * except 4kB at va test_mem_base+2MB maps to pa test_mem_base+1MB. */ -#define TEST_MEM_BASE (4ul << 20) +static unsigned long test_mem_base; #define TEST_MEM_SIZE (4ul << 20) -#define PD_START TEST_MEM_BASE +#define PD_START test_mem_base #define PT_START (PD_START + 4096) static void setup_paging(void) @@ -45,14 +46,25 @@ static void setup_paging(void) uint32_t *pt = (uint32_t *)PT_START; uint32_t i; - /* Identity map 0-8MB. */ - for ( i = 0; i < 2; i++ ) - pd[i] = (unsigned long)pt + (i<<12) + 3; - for ( i = 0; i < 2 * 1024; i++ ) - pt[i] = (i << 12) + 3; + /* Identity map [0,_end). */ + for ( i = 0; i <= (unsigned long)(_end - 1) >> (PAGE_SHIFT + 10); ++i ) + { + unsigned int j; + + pd[i] = (unsigned long)pt + 3; + for ( j = 0; j < PAGE_SIZE / sizeof(*pt); ++j ) + *pt++ = (i << (PAGE_SHIFT + 10)) + (j << PAGE_SHIFT) + 3; + } + + /* Identity map TEST_MEM_SIZE @ test_mem_base. */ + for ( i = 0; i < (TEST_MEM_SIZE >> (PAGE_SHIFT + 10)); ++i ) + pd[i + (test_mem_base >> (PAGE_SHIFT + 10))] = + (unsigned long)pt + (i << PAGE_SHIFT) + 3; + for ( i = 0; i < (TEST_MEM_SIZE >> PAGE_SHIFT); ++i ) + *pt++ = test_mem_base + (i << PAGE_SHIFT) + 3; - /* Page at virtual 6MB maps to physical 5MB. */ - pt[6u<<8] -= 0x100000u; + /* Page at virtual test_mem_base+2MB maps physical test_mem_base+1MB. */ + pt[(long)(-TEST_MEM_SIZE + 0x200000) >> PAGE_SHIFT] -= 0x100000; } static void start_paging(void) @@ -81,42 +93,42 @@ static int rep_io_test(void) uint32_t *p; uint32_t i, p0, p1, p2; int okay = TEST_PASS; - - static const struct { + const struct { unsigned long addr; uint32_t expected; } check[] = { - { 0x00500000, 0x987654ff }, - { 0x00500ffc, 0xff000000 }, - { 0x005ffffc, 0xff000000 }, - { 0x00601000, 0x000000ff }, + { test_mem_base + 0x00100000, 0x987654ff }, + { test_mem_base + 0x00100ffc, 0xff000000 }, + { test_mem_base + 0x001ffffc, 0xff000000 }, + { test_mem_base + 0x00201000, 0x000000ff }, { 0, 0 } }; start_paging(); /* Phys 5MB = 0xdeadbeef */ - *(uint32_t *)0x500000ul = 0xdeadbeef; + *(uint32_t *)(test_mem_base + 0x100000) = 0xdeadbeef; /* Phys 5MB = 0x98765432 */ - *(uint32_t *)0x600000ul = 0x98765432; + *(uint32_t *)(test_mem_base + 0x200000) = 0x98765432; /* Phys 0x5fffff = Phys 0x500000 = 0xff (byte) */ asm volatile ( "rep insb" : "=d" (p0), "=c" (p1), "=D" (p2) - : "0" (0x5f), "1" (2), "2" (0x5ffffful) : "memory" ); + : "0" (0x5f), "1" (2), "2" (test_mem_base + 0x1fffff) : "memory" ); /* Phys 0x500fff = Phys 0x601000 = 0xff (byte) */ asm volatile ( "std ; rep insb ; cld" : "=d" (p0), "=c" (p1), "=D" (p2) - : "0" (0x5f), "1" (2), "2" (0x601000ul) : "memory" ); + : "0" (0x5f), "1" (2), "2" (test_mem_base + 0x201000) : "memory" ); stop_paging(); i = 0; - for ( p = (uint32_t *)0x4ff000ul; p < (uint32_t *)0x602000ul; p++ ) + for ( p = (uint32_t *)(test_mem_base + 0x0ff000); + p < (uint32_t *)(test_mem_base + 0x202000); p++ ) { uint32_t expected = 0; if ( check[i].addr == (unsigned long)p ) @@ -148,13 +160,14 @@ static int shadow_gs_test(void) if ( !(edx & (1u<<29)) ) return TEST_SKIP; - /* Long mode pagetable setup: Identity map 0-8MB with 2MB mappings. */ + /* Long mode pagetable setup: Identity map [0,_end) with 2MB mappings. */ *pd = (unsigned long)pd + 0x1007; /* Level 4 */ pd += 512; *pd = (unsigned long)pd + 0x1007; /* Level 3 */ pd += 512; - for ( i = 0; i < 4; i++ ) /* Level 2 */ - *pd++ = (i << 21) + 0x1e3; + /* Level 2: */ + for ( i = 0; i <= (unsigned long)(_end - 1) >> (PAGE_SHIFT + 9); i++ ) + *pd++ = (i << (PAGE_SHIFT + 9)) + 0x1e3; asm volatile ( /* CR4.PAE=1 */ @@ -208,29 +221,6 @@ void perform_tests(void) printf("Testing HVM environment:\n"); BUILD_BUG_ON(SCRATCH_PHYSICAL_ADDRESS > HVMLOADER_PHYSICAL_ADDRESS); - if ( hvm_info->low_mem_pgend < - ((TEST_MEM_BASE + TEST_MEM_SIZE) >> PAGE_SHIFT) ) - { - printf("Skipping tests due to insufficient memory (<%luMB)\n", - (TEST_MEM_BASE + TEST_MEM_SIZE) >> 20); - return; - } - - if ( (unsigned long)_end > TEST_MEM_BASE ) - { - printf("Skipping tests due to overlap with base image\n"); - return; - } - - if ( hvm_start_info->cmdline_paddr && - hvm_start_info->cmdline_paddr < TEST_MEM_BASE + TEST_MEM_SIZE && - ((hvm_start_info->cmdline_paddr + - strlen((char *)(uintptr_t)hvm_start_info->cmdline_paddr)) >= - TEST_MEM_BASE) ) - { - printf("Skipping tests due to overlap with command line\n"); - return; - } if ( hvm_start_info->rsdp_paddr ) { @@ -238,54 +228,67 @@ void perform_tests(void) return; } - if ( hvm_start_info->nr_modules ) + for ( ; ; test_mem_base += TEST_MEM_SIZE ) { - const struct hvm_modlist_entry *modlist = - (void *)(uintptr_t)hvm_start_info->modlist_paddr; - - if ( hvm_start_info->modlist_paddr > UINTPTR_MAX || - ((UINTPTR_MAX - (uintptr_t)modlist) / sizeof(*modlist) < - hvm_start_info->nr_modules) ) + if ( hvm_info->low_mem_pgend < + ((test_mem_base + TEST_MEM_SIZE) >> PAGE_SHIFT) ) { - printf("Skipping tests due to inaccessible module list\n"); + printf("Skipping tests due to insufficient memory (<%luMB)\n", + (test_mem_base + TEST_MEM_SIZE) >> 20); return; } - if ( TEST_MEM_BASE < (uintptr_t)(modlist + - hvm_start_info->nr_modules) && - (uintptr_t)modlist < TEST_MEM_BASE + TEST_MEM_SIZE ) - { - printf("Skipping tests due to overlap with module list\n"); - return; - } + if ( (unsigned long)_end > test_mem_base ) + continue; + + if ( hvm_start_info->cmdline_paddr && + hvm_start_info->cmdline_paddr < test_mem_base + TEST_MEM_SIZE && + ((hvm_start_info->cmdline_paddr + + strlen((char *)(uintptr_t)hvm_start_info->cmdline_paddr)) >= + test_mem_base) ) + continue; - for ( i = 0; i < hvm_start_info->nr_modules; ++i ) + if ( hvm_start_info->nr_modules ) { - if ( TEST_MEM_BASE < modlist[i].paddr + modlist[i].size && - modlist[i].paddr < TEST_MEM_BASE + TEST_MEM_SIZE ) - { - printf("Skipping tests due to overlap with module %u\n", i); - return; - } + const struct hvm_modlist_entry *modlist = + (void *)(uintptr_t)hvm_start_info->modlist_paddr; + + if ( hvm_start_info->modlist_paddr > UINTPTR_MAX || + ((UINTPTR_MAX - (uintptr_t)modlist) / sizeof(*modlist) < + hvm_start_info->nr_modules) ) + continue; + + if ( test_mem_base < (uintptr_t)(modlist + + hvm_start_info->nr_modules) && + (uintptr_t)modlist < test_mem_base + TEST_MEM_SIZE ) + continue; - if ( modlist[i].cmdline_paddr && - modlist[i].cmdline_paddr < TEST_MEM_BASE + TEST_MEM_SIZE && - ((modlist[i].cmdline_paddr + - strlen((char *)(uintptr_t)modlist[i].cmdline_paddr)) >= - TEST_MEM_BASE) ) + for ( i = 0; i < hvm_start_info->nr_modules; ++i ) { - printf("Skipping tests due to overlap with module %u cmdline\n", - i); - return; + if ( test_mem_base < modlist[i].paddr + modlist[i].size && + modlist[i].paddr < test_mem_base + TEST_MEM_SIZE ) + break; + + if ( modlist[i].cmdline_paddr && + modlist[i].cmdline_paddr < test_mem_base + TEST_MEM_SIZE && + ((modlist[i].cmdline_paddr + + strlen((char *)(uintptr_t)modlist[i].cmdline_paddr)) >= + test_mem_base) ) + break; } + if ( i < hvm_start_info->nr_modules ) + continue; } + + printf("Using scratch memory at %lx\n", test_mem_base); + break; } passed = skipped = 0; for ( i = 0; tests[i].test; i++ ) { printf(" - %s ... ", tests[i].description); - memset((char *)(4ul << 20), 0, 4ul << 20); + memset((char *)test_mem_base, 0, TEST_MEM_SIZE); setup_paging(); switch ( (*tests[i].test)() ) { --- a/tools/firmware/hvmloader/tests.c +++ b/tools/firmware/hvmloader/tests.c @@ -29,14 +29,15 @@ /* * Memory layout during tests: - * 4MB to 8MB is cleared. - * Page directory resides at 4MB. - * 2 page table pages reside at 4MB+4kB to 4MB+12kB. - * Pagetables identity-map 0-8MB, except 4kB at va 6MB maps to pa 5MB. + * The 4MB block at test_mem_base is cleared. + * Page directory resides at test_mem_base. + * 2 page table pages reside at test_mem_base+4kB to test_mem_base+12kB. + * Pagetables identity-map 0-4MB and test_mem_base-test_mem_base+4MB, + * except 4kB at va test_mem_base+2MB maps to pa test_mem_base+1MB. */ -#define TEST_MEM_BASE (4ul << 20) +static unsigned long test_mem_base; #define TEST_MEM_SIZE (4ul << 20) -#define PD_START TEST_MEM_BASE +#define PD_START test_mem_base #define PT_START (PD_START + 4096) static void setup_paging(void) @@ -45,14 +46,25 @@ static void setup_paging(void) uint32_t *pt = (uint32_t *)PT_START; uint32_t i; - /* Identity map 0-8MB. */ - for ( i = 0; i < 2; i++ ) - pd[i] = (unsigned long)pt + (i<<12) + 3; - for ( i = 0; i < 2 * 1024; i++ ) - pt[i] = (i << 12) + 3; + /* Identity map [0,_end). */ + for ( i = 0; i <= (unsigned long)(_end - 1) >> (PAGE_SHIFT + 10); ++i ) + { + unsigned int j; + + pd[i] = (unsigned long)pt + 3; + for ( j = 0; j < PAGE_SIZE / sizeof(*pt); ++j ) + *pt++ = (i << (PAGE_SHIFT + 10)) + (j << PAGE_SHIFT) + 3; + } + + /* Identity map TEST_MEM_SIZE @ test_mem_base. */ + for ( i = 0; i < (TEST_MEM_SIZE >> (PAGE_SHIFT + 10)); ++i ) + pd[i + (test_mem_base >> (PAGE_SHIFT + 10))] = + (unsigned long)pt + (i << PAGE_SHIFT) + 3; + for ( i = 0; i < (TEST_MEM_SIZE >> PAGE_SHIFT); ++i ) + *pt++ = test_mem_base + (i << PAGE_SHIFT) + 3; - /* Page at virtual 6MB maps to physical 5MB. */ - pt[6u<<8] -= 0x100000u; + /* Page at virtual test_mem_base+2MB maps physical test_mem_base+1MB. */ + pt[(long)(-TEST_MEM_SIZE + 0x200000) >> PAGE_SHIFT] -= 0x100000; } static void start_paging(void) @@ -81,42 +93,42 @@ static int rep_io_test(void) uint32_t *p; uint32_t i, p0, p1, p2; int okay = TEST_PASS; - - static const struct { + const struct { unsigned long addr; uint32_t expected; } check[] = { - { 0x00500000, 0x987654ff }, - { 0x00500ffc, 0xff000000 }, - { 0x005ffffc, 0xff000000 }, - { 0x00601000, 0x000000ff }, + { test_mem_base + 0x00100000, 0x987654ff }, + { test_mem_base + 0x00100ffc, 0xff000000 }, + { test_mem_base + 0x001ffffc, 0xff000000 }, + { test_mem_base + 0x00201000, 0x000000ff }, { 0, 0 } }; start_paging(); /* Phys 5MB = 0xdeadbeef */ - *(uint32_t *)0x500000ul = 0xdeadbeef; + *(uint32_t *)(test_mem_base + 0x100000) = 0xdeadbeef; /* Phys 5MB = 0x98765432 */ - *(uint32_t *)0x600000ul = 0x98765432; + *(uint32_t *)(test_mem_base + 0x200000) = 0x98765432; /* Phys 0x5fffff = Phys 0x500000 = 0xff (byte) */ asm volatile ( "rep insb" : "=d" (p0), "=c" (p1), "=D" (p2) - : "0" (0x5f), "1" (2), "2" (0x5ffffful) : "memory" ); + : "0" (0x5f), "1" (2), "2" (test_mem_base + 0x1fffff) : "memory" ); /* Phys 0x500fff = Phys 0x601000 = 0xff (byte) */ asm volatile ( "std ; rep insb ; cld" : "=d" (p0), "=c" (p1), "=D" (p2) - : "0" (0x5f), "1" (2), "2" (0x601000ul) : "memory" ); + : "0" (0x5f), "1" (2), "2" (test_mem_base + 0x201000) : "memory" ); stop_paging(); i = 0; - for ( p = (uint32_t *)0x4ff000ul; p < (uint32_t *)0x602000ul; p++ ) + for ( p = (uint32_t *)(test_mem_base + 0x0ff000); + p < (uint32_t *)(test_mem_base + 0x202000); p++ ) { uint32_t expected = 0; if ( check[i].addr == (unsigned long)p ) @@ -148,13 +160,14 @@ static int shadow_gs_test(void) if ( !(edx & (1u<<29)) ) return TEST_SKIP; - /* Long mode pagetable setup: Identity map 0-8MB with 2MB mappings. */ + /* Long mode pagetable setup: Identity map [0,_end) with 2MB mappings. */ *pd = (unsigned long)pd + 0x1007; /* Level 4 */ pd += 512; *pd = (unsigned long)pd + 0x1007; /* Level 3 */ pd += 512; - for ( i = 0; i < 4; i++ ) /* Level 2 */ - *pd++ = (i << 21) + 0x1e3; + /* Level 2: */ + for ( i = 0; i <= (unsigned long)(_end - 1) >> (PAGE_SHIFT + 9); i++ ) + *pd++ = (i << (PAGE_SHIFT + 9)) + 0x1e3; asm volatile ( /* CR4.PAE=1 */ @@ -208,29 +221,6 @@ void perform_tests(void) printf("Testing HVM environment:\n"); BUILD_BUG_ON(SCRATCH_PHYSICAL_ADDRESS > HVMLOADER_PHYSICAL_ADDRESS); - if ( hvm_info->low_mem_pgend < - ((TEST_MEM_BASE + TEST_MEM_SIZE) >> PAGE_SHIFT) ) - { - printf("Skipping tests due to insufficient memory (<%luMB)\n", - (TEST_MEM_BASE + TEST_MEM_SIZE) >> 20); - return; - } - - if ( (unsigned long)_end > TEST_MEM_BASE ) - { - printf("Skipping tests due to overlap with base image\n"); - return; - } - - if ( hvm_start_info->cmdline_paddr && - hvm_start_info->cmdline_paddr < TEST_MEM_BASE + TEST_MEM_SIZE && - ((hvm_start_info->cmdline_paddr + - strlen((char *)(uintptr_t)hvm_start_info->cmdline_paddr)) >= - TEST_MEM_BASE) ) - { - printf("Skipping tests due to overlap with command line\n"); - return; - } if ( hvm_start_info->rsdp_paddr ) { @@ -238,54 +228,67 @@ void perform_tests(void) return; } - if ( hvm_start_info->nr_modules ) + for ( ; ; test_mem_base += TEST_MEM_SIZE ) { - const struct hvm_modlist_entry *modlist = - (void *)(uintptr_t)hvm_start_info->modlist_paddr; - - if ( hvm_start_info->modlist_paddr > UINTPTR_MAX || - ((UINTPTR_MAX - (uintptr_t)modlist) / sizeof(*modlist) < - hvm_start_info->nr_modules) ) + if ( hvm_info->low_mem_pgend < + ((test_mem_base + TEST_MEM_SIZE) >> PAGE_SHIFT) ) { - printf("Skipping tests due to inaccessible module list\n"); + printf("Skipping tests due to insufficient memory (<%luMB)\n", + (test_mem_base + TEST_MEM_SIZE) >> 20); return; } - if ( TEST_MEM_BASE < (uintptr_t)(modlist + - hvm_start_info->nr_modules) && - (uintptr_t)modlist < TEST_MEM_BASE + TEST_MEM_SIZE ) - { - printf("Skipping tests due to overlap with module list\n"); - return; - } + if ( (unsigned long)_end > test_mem_base ) + continue; + + if ( hvm_start_info->cmdline_paddr && + hvm_start_info->cmdline_paddr < test_mem_base + TEST_MEM_SIZE && + ((hvm_start_info->cmdline_paddr + + strlen((char *)(uintptr_t)hvm_start_info->cmdline_paddr)) >= + test_mem_base) ) + continue; - for ( i = 0; i < hvm_start_info->nr_modules; ++i ) + if ( hvm_start_info->nr_modules ) { - if ( TEST_MEM_BASE < modlist[i].paddr + modlist[i].size && - modlist[i].paddr < TEST_MEM_BASE + TEST_MEM_SIZE ) - { - printf("Skipping tests due to overlap with module %u\n", i); - return; - } + const struct hvm_modlist_entry *modlist = + (void *)(uintptr_t)hvm_start_info->modlist_paddr; + + if ( hvm_start_info->modlist_paddr > UINTPTR_MAX || + ((UINTPTR_MAX - (uintptr_t)modlist) / sizeof(*modlist) < + hvm_start_info->nr_modules) ) + continue; + + if ( test_mem_base < (uintptr_t)(modlist + + hvm_start_info->nr_modules) && + (uintptr_t)modlist < test_mem_base + TEST_MEM_SIZE ) + continue; - if ( modlist[i].cmdline_paddr && - modlist[i].cmdline_paddr < TEST_MEM_BASE + TEST_MEM_SIZE && - ((modlist[i].cmdline_paddr + - strlen((char *)(uintptr_t)modlist[i].cmdline_paddr)) >= - TEST_MEM_BASE) ) + for ( i = 0; i < hvm_start_info->nr_modules; ++i ) { - printf("Skipping tests due to overlap with module %u cmdline\n", - i); - return; + if ( test_mem_base < modlist[i].paddr + modlist[i].size && + modlist[i].paddr < test_mem_base + TEST_MEM_SIZE ) + break; + + if ( modlist[i].cmdline_paddr && + modlist[i].cmdline_paddr < test_mem_base + TEST_MEM_SIZE && + ((modlist[i].cmdline_paddr + + strlen((char *)(uintptr_t)modlist[i].cmdline_paddr)) >= + test_mem_base) ) + break; } + if ( i < hvm_start_info->nr_modules ) + continue; } + + printf("Using scratch memory at %lx\n", test_mem_base); + break; } passed = skipped = 0; for ( i = 0; tests[i].test; i++ ) { printf(" - %s ... ", tests[i].description); - memset((char *)(4ul << 20), 0, 4ul << 20); + memset((char *)test_mem_base, 0, TEST_MEM_SIZE); setup_paging(); switch ( (*tests[i].test)() ) {