xref: /spdk/test/env/vtophys/vtophys.c (revision 57fd99b91e71a4baa5543e19ff83958dc99d4dac)
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