Re: [PATCH] swiotlb: Allow swiotlb to live at pre-defined address

From: kbuild test robot
Date: Fri Mar 27 2020 - 02:06:37 EST


Hi Alexander,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on swiotlb/linux-next tip/x86/core v5.6-rc7 next-20200326]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Alexander-Graf/swiotlb-Allow-swiotlb-to-live-at-pre-defined-address/20200327-062125
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9420e8ade4353a6710908ffafa23ecaf1caa0123
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-187-gbff9b106-dirty
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@xxxxxxxxx>


sparse warnings: (new ones prefixed by >>)

kernel/dma/swiotlb.c:97:14: sparse: sparse: symbol 'max_segment' was not declared. Should it be static?
>> kernel/dma/swiotlb.c:143:53: sparse: sparse: incorrect type in argument 3 (different base types) @@ expected unsigned long *res @@ got long *res @@
>> kernel/dma/swiotlb.c:143:53: sparse: expected unsigned long *res
>> kernel/dma/swiotlb.c:143:53: sparse: got char **
>> kernel/dma/swiotlb.c:268:16: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected unsigned char [noderef] <asn:2> *vstart @@ got n:2> *vstart @@
>> kernel/dma/swiotlb.c:268:16: sparse: expected unsigned char [noderef] <asn:2> *vstart
>> kernel/dma/swiotlb.c:268:16: sparse: got void *
>> kernel/dma/swiotlb.c:272:35: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected char *tlb @@ got unsigned char [noderef] <aschar *tlb @@
>> kernel/dma/swiotlb.c:272:35: sparse: expected char *tlb
>> kernel/dma/swiotlb.c:272:35: sparse: got unsigned char [noderef] <asn:2> *vstart
>> kernel/dma/swiotlb.c:273:26: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void *addr @@ got unsigned char [noderef] <asvoid *addr @@
>> kernel/dma/swiotlb.c:273:26: sparse: expected void *addr
kernel/dma/swiotlb.c:273:26: sparse: got unsigned char [noderef] <asn:2> *vstart

vim +143 kernel/dma/swiotlb.c

118
119 static int __init
120 setup_io_tlb_npages(char *str)
121 {
122 if (isdigit(*str)) {
123 io_tlb_nslabs = simple_strtoul(str, &str, 0);
124 /* avoid tail segment of size < IO_TLB_SEGSIZE */
125 io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
126 }
127 if (*str == ',')
128 ++str;
129 if (!strncmp(str, "force", 5)) {
130 swiotlb_force = SWIOTLB_FORCE;
131 str += 5;
132 } else if (!strncmp(str, "noforce", 7)) {
133 swiotlb_force = SWIOTLB_NO_FORCE;
134 io_tlb_nslabs = 1;
135 str += 7;
136 }
137
138 if (*str == ',')
139 ++str;
140 if (!strncmp(str, "addr=", 5)) {
141 char *addrstr = str + 5;
142
> 143 io_tlb_addr = kstrtoul(addrstr, 0, &str);
144 if (addrstr == str)
145 io_tlb_addr = INVALID_PHYS_ADDR;
146 }
147
148 return 0;
149 }
150 early_param("swiotlb", setup_io_tlb_npages);
151
152 static bool no_iotlb_memory;
153
154 unsigned long swiotlb_nr_tbl(void)
155 {
156 return unlikely(no_iotlb_memory) ? 0 : io_tlb_nslabs;
157 }
158 EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
159
160 unsigned int swiotlb_max_segment(void)
161 {
162 return unlikely(no_iotlb_memory) ? 0 : max_segment;
163 }
164 EXPORT_SYMBOL_GPL(swiotlb_max_segment);
165
166 void swiotlb_set_max_segment(unsigned int val)
167 {
168 if (swiotlb_force == SWIOTLB_FORCE)
169 max_segment = 1;
170 else
171 max_segment = rounddown(val, PAGE_SIZE);
172 }
173
174 /* default to 64MB */
175 #define IO_TLB_DEFAULT_SIZE (64UL<<20)
176 unsigned long swiotlb_size_or_default(void)
177 {
178 unsigned long size;
179
180 size = io_tlb_nslabs << IO_TLB_SHIFT;
181
182 return size ? size : (IO_TLB_DEFAULT_SIZE);
183 }
184
185 void swiotlb_print_info(void)
186 {
187 unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT;
188
189 if (no_iotlb_memory) {
190 pr_warn("No low mem\n");
191 return;
192 }
193
194 pr_info("mapped [mem %#010llx-%#010llx] (%luMB)\n",
195 (unsigned long long)io_tlb_start,
196 (unsigned long long)io_tlb_end,
197 bytes >> 20);
198 }
199
200 /*
201 * Early SWIOTLB allocation may be too early to allow an architecture to
202 * perform the desired operations. This function allows the architecture to
203 * call SWIOTLB when the operations are possible. It needs to be called
204 * before the SWIOTLB memory is used.
205 */
206 void __init swiotlb_update_mem_attributes(void)
207 {
208 void *vaddr;
209 unsigned long bytes;
210
211 if (no_iotlb_memory || late_alloc)
212 return;
213
214 vaddr = phys_to_virt(io_tlb_start);
215 bytes = PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT);
216 set_memory_decrypted((unsigned long)vaddr, bytes >> PAGE_SHIFT);
217 memset(vaddr, 0, bytes);
218 }
219
220 int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
221 {
222 unsigned long i, bytes;
223 size_t alloc_size;
224
225 bytes = nslabs << IO_TLB_SHIFT;
226
227 io_tlb_nslabs = nslabs;
228 io_tlb_start = __pa(tlb);
229 io_tlb_end = io_tlb_start + bytes;
230
231 /*
232 * Allocate and initialize the free list array. This array is used
233 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
234 * between io_tlb_start and io_tlb_end.
235 */
236 alloc_size = PAGE_ALIGN(io_tlb_nslabs * sizeof(int));
237 io_tlb_list = memblock_alloc(alloc_size, PAGE_SIZE);
238 if (!io_tlb_list)
239 panic("%s: Failed to allocate %zu bytes align=0x%lx\n",
240 __func__, alloc_size, PAGE_SIZE);
241
242 alloc_size = PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t));
243 io_tlb_orig_addr = memblock_alloc(alloc_size, PAGE_SIZE);
244 if (!io_tlb_orig_addr)
245 panic("%s: Failed to allocate %zu bytes align=0x%lx\n",
246 __func__, alloc_size, PAGE_SIZE);
247
248 for (i = 0; i < io_tlb_nslabs; i++) {
249 io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
250 io_tlb_orig_addr[i] = INVALID_PHYS_ADDR;
251 }
252 io_tlb_index = 0;
253
254 if (verbose)
255 swiotlb_print_info();
256
257 swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
258 return 0;
259 }
260
261 static int __init swiotlb_init_io(int verbose, unsigned long bytes)
262 {
263 unsigned __iomem char *vstart;
264
265 if (io_tlb_addr == INVALID_PHYS_ADDR)
266 return -EINVAL;
267
> 268 vstart = memremap(io_tlb_addr, bytes, MEMREMAP_WB);
269 if (!vstart)
270 return -EINVAL;
271
> 272 if (swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose)) {
> 273 memunmap(vstart);
274 return -EINVAL;
275 }
276
277 return 0;
278 }
279

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx