2018-03-22 01:07:06

by stuart hayes

[permalink] [raw]
Subject: [PATCH] dell_rbu: make firmware payload memory uncachable

The dell_rbu driver takes firmware update payloads and puts them in memory so
the system BIOS can find them after a reboot. This sometimes fails (though
rarely), because the memory containing the payload is in the CPU cache but
never gets written back to main memory before the system is rebooted (CPU
cache contents are lost on reboot).

With this patch, the payload memory will be changed to uncachable to ensure
that the payload is actually in main memory before the system is rebooted.

Signed-off-by: Stuart Hayes <[email protected]>
---
Note that there is no maintainer for this driver, so I'd be grateful if
someone could apply this... thank you!

diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 2f452f1..6b84814 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -180,6 +180,11 @@ static int create_packet(void *data, size_t length)
invalid_addr_packet_array[idx++] = packet_data_temp_buf;
packet_data_temp_buf = NULL;
}
+ /*
+ * set to uncachable or it may never get written back before
+ * reboot
+ */
+ set_memory_uc(packet_data_temp_buf, 1 << (ordernum));
}
spin_lock(&rbu_data.lock);

@@ -349,6 +354,7 @@ static void packet_empty_list(void)
* to make sure there are no stale RBU packets left in memory
*/
memset(newpacket->data, 0, rbu_data.packetsize);
+ set_memory_wb(newpacket->data, (1 << newpacket->ordernum));
free_pages((unsigned long) newpacket->data,
newpacket->ordernum);
kfree(newpacket);


2018-03-23 02:52:52

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] dell_rbu: make firmware payload memory uncachable

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-a0-201811 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
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' [-Werror=implicit-function-declaration]
set_memory_uc(packet_data_temp_buf, 1 << (ordernum));
^
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' [-Werror=implicit-function-declaration]
set_memory_wb(newpacket->data, (1 << newpacket->ordernum));
^
cc1: some warnings being treated as errors

vim +/set_memory_uc +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


Attachments:
(No filename) (10.06 kB)
.config.gz (30.95 kB)
Download all attachments

2018-03-23 03:00:56

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] dell_rbu: make firmware payload memory uncachable

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


Attachments:
(No filename) (13.68 kB)
.config.gz (30.94 kB)
Download all attachments

2018-03-23 22:20:42

by stuart hayes

[permalink] [raw]
Subject: Re: [PATCH] dell_rbu: make firmware payload memory uncachable



On 3/22/2018 9:58 PM, kbuild test robot wrote:
> 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
>

Please disregard this one, will send a "v2" shortly. Not sure how I managed to send this version...
Thanks!