1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2015 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk/config.h" 9 #include "spdk/env.h" 10 #include "spdk/util.h" 11 #include "spdk_internal/cunit.h" 12 13 #include "CUnit/Basic.h" 14 15 #define __SPDK_ENV_NAME(path) (strrchr(#path, '/') + 1) 16 #define _SPDK_ENV_NAME(path) __SPDK_ENV_NAME(path) 17 #define SPDK_ENV_NAME _SPDK_ENV_NAME(SPDK_CONFIG_ENV) 18 19 static void 20 vtophys_malloc_test(void) 21 { 22 void *p = NULL; 23 int i; 24 unsigned int size = 1; 25 uint64_t paddr; 26 27 /* Verify vtophys doesn't work on regular malloc memory */ 28 for (i = 0; i < 31; i++) { 29 p = malloc(size); 30 if (p == NULL) { 31 continue; 32 } 33 34 paddr = spdk_vtophys(p, NULL); 35 CU_ASSERT(paddr == SPDK_VTOPHYS_ERROR); 36 37 free(p); 38 size = size << 1; 39 } 40 41 /* Test addresses that are not in the valid x86-64 usermode range */ 42 paddr = spdk_vtophys((void *)0x0000800000000000ULL, NULL); 43 CU_ASSERT(paddr == SPDK_VTOPHYS_ERROR); 44 } 45 46 static void 47 vtophys_spdk_malloc_test(void) 48 { 49 void *buf = NULL, *p = NULL; 50 size_t buf_align = 512; 51 int i; 52 unsigned int size = 1; 53 uint64_t paddr, tmpsize; 54 55 /* Test vtophys on memory allocated through SPDK */ 56 for (i = 0; i < 31; i++) { 57 buf = spdk_zmalloc(size, buf_align, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA); 58 if (buf == NULL) { 59 continue; 60 } 61 62 /* test vtophys translation with no length parameter */ 63 paddr = spdk_vtophys(buf, NULL); 64 CU_ASSERT(paddr != SPDK_VTOPHYS_ERROR); 65 66 /* translate the entire buffer; it's not necessarily contiguous */ 67 p = buf; 68 tmpsize = size; 69 while (p < buf + size) { 70 paddr = spdk_vtophys(p, &tmpsize); 71 CU_ASSERT(paddr != SPDK_VTOPHYS_ERROR); 72 CU_ASSERT(tmpsize >= spdk_min(size, buf_align)); 73 p += tmpsize; 74 tmpsize = buf + size - p; 75 } 76 CU_ASSERT(tmpsize == 0); 77 78 /* translate a valid vaddr, but with length 0 */ 79 p = buf; 80 tmpsize = 0; 81 paddr = spdk_vtophys(p, &tmpsize); 82 CU_ASSERT(paddr != SPDK_VTOPHYS_ERROR); 83 CU_ASSERT(tmpsize == 0); 84 85 /* translate the first half of the buffer */ 86 p = buf; 87 tmpsize = size / 2; 88 while (p < buf + size / 2) { 89 paddr = spdk_vtophys(p, &tmpsize); 90 CU_ASSERT(paddr != SPDK_VTOPHYS_ERROR); 91 CU_ASSERT(tmpsize >= spdk_min(size / 2, buf_align)); 92 p += tmpsize; 93 tmpsize = buf + size / 2 - p; 94 } 95 CU_ASSERT(tmpsize == 0); 96 97 /* translate the second half of the buffer */ 98 p = buf + size / 2; 99 tmpsize = size / 2; 100 while (p < buf + size) { 101 paddr = spdk_vtophys(p, &tmpsize); 102 CU_ASSERT(paddr != SPDK_VTOPHYS_ERROR); 103 CU_ASSERT(tmpsize >= spdk_min(size / 2, buf_align)); 104 p += tmpsize; 105 tmpsize = buf + size - p; 106 } 107 CU_ASSERT(tmpsize == 0); 108 109 /* translate a region that's not entirely registered */ 110 p = buf; 111 tmpsize = UINT64_MAX; 112 while (p < buf + size) { 113 paddr = spdk_vtophys(p, &tmpsize); 114 CU_ASSERT(paddr != SPDK_VTOPHYS_ERROR); 115 CU_ASSERT(tmpsize >= buf_align); 116 p += tmpsize; 117 /* verify our region is really contiguous */ 118 CU_ASSERT(paddr + tmpsize - 1 == spdk_vtophys(p - 1, &tmpsize)); 119 tmpsize = UINT64_MAX; 120 } 121 122 spdk_free(buf); 123 size = size << 1; 124 } 125 } 126 127 int 128 main(int argc, char **argv) 129 { 130 struct spdk_env_opts opts; 131 CU_pSuite suite = NULL; 132 unsigned num_failures; 133 134 opts.opts_size = sizeof(opts); 135 spdk_env_opts_init(&opts); 136 opts.name = "vtophys"; 137 opts.core_mask = "0x1"; 138 if (strcmp(SPDK_ENV_NAME, "env_dpdk") == 0) { 139 opts.env_context = "--log-level=lib.eal:8"; 140 } 141 142 if (spdk_env_init(&opts) < 0) { 143 printf("Err: Unable to initialize SPDK env\n"); 144 return 1; 145 } 146 147 if (CU_initialize_registry() != CUE_SUCCESS) { 148 return CU_get_error(); 149 } 150 151 suite = CU_add_suite("components_suite", NULL, NULL); 152 if (suite == NULL) { 153 CU_cleanup_registry(); 154 return CU_get_error(); 155 } 156 157 if ( 158 CU_add_test(suite, "vtophys_malloc_test", vtophys_malloc_test) == NULL || 159 CU_add_test(suite, "vtophys_spdk_malloc_test", vtophys_spdk_malloc_test) == NULL 160 ) { 161 CU_cleanup_registry(); 162 return CU_get_error(); 163 } 164 165 num_failures = spdk_ut_run_tests(argc, argv, NULL); 166 CU_cleanup_registry(); 167 return num_failures; 168 } 169