Hi Stuart, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.16-rc6 next-20180322] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Stuart-Hayes/dell_rbu-make-firmware-payload-memory-uncachable/20180323-094405 config: i386-randconfig-x014-201811 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/firmware/dell_rbu.c: In function 'create_packet': >> drivers/firmware/dell_rbu.c:187:3: error: implicit declaration of function 'set_memory_uc'; did you mean 'add_memory'? [-Werror=implicit-function-declaration] set_memory_uc(packet_data_temp_buf, 1 << (ordernum)); ^~~~~~~~~~~~~ add_memory drivers/firmware/dell_rbu.c: In function 'packet_empty_list': >> drivers/firmware/dell_rbu.c:357:3: error: implicit declaration of function 'set_memory_wb'; did you mean 'add_memory'? [-Werror=implicit-function-declaration] set_memory_wb(newpacket->data, (1 << newpacket->ordernum)); ^~~~~~~~~~~~~ add_memory Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32 Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD Cyclomatic Complexity 2 include/linux/list.h:__list_add Cyclomatic Complexity 1 include/linux/list.h:list_add_tail Cyclomatic Complexity 1 include/linux/list.h:__list_del Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry Cyclomatic Complexity 1 include/linux/list.h:list_del Cyclomatic Complexity 1 include/linux/list.h:list_empty Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_save_flags Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR Cyclomatic Complexity 1 include/linux/err.h:IS_ERR Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_irqs_disabled_flags Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock Cyclomatic Complexity 1 arch/x86/include/asm/io.h:virt_to_phys Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large Cyclomatic Complexity 5 include/linux/slab.h:kmalloc Cyclomatic Complexity 1 include/linux/slab.h:kzalloc Cyclomatic Complexity 1 include/linux/platform_device.h:platform_device_register_resndata Cyclomatic Complexity 1 include/linux/platform_device.h:platform_device_register_simple Cyclomatic Complexity 1 include/linux/dma-debug.h:debug_dma_free_coherent Cyclomatic Complexity 1 arch/x86/include/asm/dma-mapping.h:get_arch_dma_ops Cyclomatic Complexity 4 include/linux/dma-mapping.h:get_dma_ops Cyclomatic Complexity 71 include/linux/dma-mapping.h:dma_free_attrs Cyclomatic Complexity 1 include/linux/dma-mapping.h:dma_free_coherent Cyclomatic Complexity 1 drivers/firmware/dell_rbu.c:init_packet_head Cyclomatic Complexity 3 drivers/firmware/dell_rbu.c:img_update_free Cyclomatic Complexity 3 drivers/firmware/dell_rbu.c:packet_empty_list Cyclomatic Complexity 1 drivers/firmware/dell_rbu.c:dcdrbu_exit Cyclomatic Complexity 5 drivers/firmware/dell_rbu.c:dcdrbu_init Cyclomatic Complexity 2 drivers/firmware/dell_rbu.c:write_rbu_packet_size Cyclomatic Complexity 2 drivers/firmware/dell_rbu.c:read_rbu_packet_size Cyclomatic Complexity 2 drivers/firmware/dell_rbu.c:read_rbu_image_type Cyclomatic Complexity 9 drivers/firmware/dell_rbu.c:write_rbu_image_type Cyclomatic Complexity 71 drivers/firmware/dell_rbu.c:img_update_realloc Cyclomatic Complexity 75 drivers/firmware/dell_rbu.c:create_packet Cyclomatic Complexity 5 drivers/firmware/dell_rbu.c:packetize_data Cyclomatic Complexity 7 drivers/firmware/dell_rbu.c:callbackfn_rbu Cyclomatic Complexity 3 drivers/firmware/dell_rbu.c:read_rbu_mono_data Cyclomatic Complexity 4 drivers/firmware/dell_rbu.c:do_packet_read Cyclomatic Complexity 4 drivers/firmware/dell_rbu.c:packet_read_list Cyclomatic Complexity 5 drivers/firmware/dell_rbu.c:read_packet_data Cyclomatic Complexity 3 drivers/firmware/dell_rbu.c:read_rbu_data Cyclomatic Complexity 1 drivers/firmware/dell_rbu.c:_GLOBAL__sub_I_00100_0_dell_rbu.c Cyclomatic Complexity 1 drivers/firmware/dell_rbu.c:_GLOBAL__sub_D_00100_1_dell_rbu.c cc1: some warnings being treated as errors vim +187 drivers/firmware/dell_rbu.c 101 102 static int create_packet(void *data, size_t length) 103 { 104 struct packet_data *newpacket; 105 int ordernum = 0; 106 int retval = 0; 107 unsigned int packet_array_size = 0; 108 void **invalid_addr_packet_array = NULL; 109 void *packet_data_temp_buf = NULL; 110 unsigned int idx = 0; 111 112 pr_debug("create_packet: entry \n"); 113 114 if (!rbu_data.packetsize) { 115 pr_debug("create_packet: packetsize not specified\n"); 116 retval = -EINVAL; 117 goto out_noalloc; 118 } 119 120 spin_unlock(&rbu_data.lock); 121 122 newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL); 123 124 if (!newpacket) { 125 printk(KERN_WARNING 126 "dell_rbu:%s: failed to allocate new " 127 "packet\n", __func__); 128 retval = -ENOMEM; 129 spin_lock(&rbu_data.lock); 130 goto out_noalloc; 131 } 132 133 ordernum = get_order(length); 134 135 /* 136 * BIOS errata mean we cannot allocate packets below 1MB or they will 137 * be overwritten by BIOS. 138 * 139 * array to temporarily hold packets 140 * that are below the allocation floor 141 * 142 * NOTE: very simplistic because we only need the floor to be at 1MB 143 * due to BIOS errata. This shouldn't be used for higher floors 144 * or you will run out of mem trying to allocate the array. 145 */ 146 packet_array_size = max( 147 (unsigned int)(allocation_floor / rbu_data.packetsize), 148 (unsigned int)1); 149 invalid_addr_packet_array = kzalloc(packet_array_size * sizeof(void*), 150 GFP_KERNEL); 151 152 if (!invalid_addr_packet_array) { 153 printk(KERN_WARNING 154 "dell_rbu:%s: failed to allocate " 155 "invalid_addr_packet_array \n", 156 __func__); 157 retval = -ENOMEM; 158 spin_lock(&rbu_data.lock); 159 goto out_alloc_packet; 160 } 161 162 while (!packet_data_temp_buf) { 163 packet_data_temp_buf = (unsigned char *) 164 __get_free_pages(GFP_KERNEL, ordernum); 165 if (!packet_data_temp_buf) { 166 printk(KERN_WARNING 167 "dell_rbu:%s: failed to allocate new " 168 "packet\n", __func__); 169 retval = -ENOMEM; 170 spin_lock(&rbu_data.lock); 171 goto out_alloc_packet_array; 172 } 173 174 if ((unsigned long)virt_to_phys(packet_data_temp_buf) 175 < allocation_floor) { 176 pr_debug("packet 0x%lx below floor at 0x%lx.\n", 177 (unsigned long)virt_to_phys( 178 packet_data_temp_buf), 179 allocation_floor); 180 invalid_addr_packet_array[idx++] = packet_data_temp_buf; 181 packet_data_temp_buf = NULL; 182 } 183 /* 184 * set to uncachable or it may never get written back before 185 * reboot 186 */ > 187 set_memory_uc(packet_data_temp_buf, 1 << (ordernum)); 188 } 189 spin_lock(&rbu_data.lock); 190 191 newpacket->data = packet_data_temp_buf; 192 193 pr_debug("create_packet: newpacket at physical addr %lx\n", 194 (unsigned long)virt_to_phys(newpacket->data)); 195 196 /* packets may not have fixed size */ 197 newpacket->length = length; 198 newpacket->ordernum = ordernum; 199 ++rbu_data.num_packets; 200 201 /* initialize the newly created packet headers */ 202 INIT_LIST_HEAD(&newpacket->list); 203 list_add_tail(&newpacket->list, &packet_data_head.list); 204 205 memcpy(newpacket->data, data, length); 206 207 pr_debug("create_packet: exit \n"); 208 209 out_alloc_packet_array: 210 /* always free packet array */ 211 for (;idx>0;idx--) { 212 pr_debug("freeing unused packet below floor 0x%lx.\n", 213 (unsigned long)virt_to_phys( 214 invalid_addr_packet_array[idx-1])); 215 free_pages((unsigned long)invalid_addr_packet_array[idx-1], 216 ordernum); 217 } 218 kfree(invalid_addr_packet_array); 219 220 out_alloc_packet: 221 /* if error, free data */ 222 if (retval) 223 kfree(newpacket); 224 225 out_noalloc: 226 return retval; 227 } 228 229 static int packetize_data(const u8 *data, size_t length) 230 { 231 int rc = 0; 232 int done = 0; 233 int packet_length; 234 u8 *temp; 235 u8 *end = (u8 *) data + length; 236 pr_debug("packetize_data: data length %zd\n", length); 237 if (!rbu_data.packetsize) { 238 printk(KERN_WARNING 239 "dell_rbu: packetsize not specified\n"); 240 return -EIO; 241 } 242 243 temp = (u8 *) data; 244 245 /* packetize the hunk */ 246 while (!done) { 247 if ((temp + rbu_data.packetsize) < end) 248 packet_length = rbu_data.packetsize; 249 else { 250 /* this is the last packet */ 251 packet_length = end - temp; 252 done = 1; 253 } 254 255 if ((rc = create_packet(temp, packet_length))) 256 return rc; 257 258 pr_debug("%p:%td\n", temp, (end - temp)); 259 temp += packet_length; 260 } 261 262 rbu_data.imagesize = length; 263 264 return rc; 265 } 266 267 static int do_packet_read(char *data, struct list_head *ptemp_list, 268 int length, int bytes_read, int *list_read_count) 269 { 270 void *ptemp_buf; 271 struct packet_data *newpacket = NULL; 272 int bytes_copied = 0; 273 int j = 0; 274 275 newpacket = list_entry(ptemp_list, struct packet_data, list); 276 *list_read_count += newpacket->length; 277 278 if (*list_read_count > bytes_read) { 279 /* point to the start of unread data */ 280 j = newpacket->length - (*list_read_count - bytes_read); 281 /* point to the offset in the packet buffer */ 282 ptemp_buf = (u8 *) newpacket->data + j; 283 /* 284 * check if there is enough room in 285 * * the incoming buffer 286 */ 287 if (length > (*list_read_count - bytes_read)) 288 /* 289 * copy what ever is there in this 290 * packet and move on 291 */ 292 bytes_copied = (*list_read_count - bytes_read); 293 else 294 /* copy the remaining */ 295 bytes_copied = length; 296 memcpy(data, ptemp_buf, bytes_copied); 297 } 298 return bytes_copied; 299 } 300 301 static int packet_read_list(char *data, size_t * pread_length) 302 { 303 struct list_head *ptemp_list; 304 int temp_count = 0; 305 int bytes_copied = 0; 306 int bytes_read = 0; 307 int remaining_bytes = 0; 308 char *pdest = data; 309 310 /* check if we have any packets */ 311 if (0 == rbu_data.num_packets) 312 return -ENOMEM; 313 314 remaining_bytes = *pread_length; 315 bytes_read = rbu_data.packet_read_count; 316 317 ptemp_list = (&packet_data_head.list)->next; 318 while (!list_empty(ptemp_list)) { 319 bytes_copied = do_packet_read(pdest, ptemp_list, 320 remaining_bytes, bytes_read, &temp_count); 321 remaining_bytes -= bytes_copied; 322 bytes_read += bytes_copied; 323 pdest += bytes_copied; 324 /* 325 * check if we reached end of buffer before reaching the 326 * last packet 327 */ 328 if (remaining_bytes == 0) 329 break; 330 331 ptemp_list = ptemp_list->next; 332 } 333 /*finally set the bytes read */ 334 *pread_length = bytes_read - rbu_data.packet_read_count; 335 rbu_data.packet_read_count = bytes_read; 336 return 0; 337 } 338 339 static void packet_empty_list(void) 340 { 341 struct list_head *ptemp_list; 342 struct list_head *pnext_list; 343 struct packet_data *newpacket; 344 345 ptemp_list = (&packet_data_head.list)->next; 346 while (!list_empty(ptemp_list)) { 347 newpacket = 348 list_entry(ptemp_list, struct packet_data, list); 349 pnext_list = ptemp_list->next; 350 list_del(ptemp_list); 351 ptemp_list = pnext_list; 352 /* 353 * zero out the RBU packet memory before freeing 354 * to make sure there are no stale RBU packets left in memory 355 */ 356 memset(newpacket->data, 0, rbu_data.packetsize); > 357 set_memory_wb(newpacket->data, (1 << newpacket->ordernum)); 358 free_pages((unsigned long) newpacket->data, 359 newpacket->ordernum); 360 kfree(newpacket); 361 } 362 rbu_data.packet_read_count = 0; 363 rbu_data.num_packets = 0; 364 rbu_data.imagesize = 0; 365 } 366 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation