Merge tag 'char-misc-4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
"Here are two bugfixes that resolve some reported issues. One in the
firmware loader, that should fix the much-reported problem of crashes
with it. The other is a hyperv fix for a reported regression.

Both have been in linux-next for a week or so with no reported issues"

* tag 'char-misc-4.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
Drivers: hv: vmbus: finally fix hv_need_to_signal_on_read()
firmware: fix NULL pointer dereference in __fw_load_abort()

Changed files
+38 -6
drivers
include
linux
+1 -4
drivers/base/firmware_class.c
··· 558 558 struct firmware_buf *buf = fw_priv->buf; 559 559 560 560 __fw_load_abort(buf); 561 - 562 - /* avoid user action after loading abort */ 563 - fw_priv->buf = NULL; 564 561 } 565 562 566 563 static LIST_HEAD(pending_fw_head); ··· 710 713 711 714 mutex_lock(&fw_lock); 712 715 fw_buf = fw_priv->buf; 713 - if (!fw_buf) 716 + if (fw_state_is_aborted(&fw_buf->fw_st)) 714 717 goto out; 715 718 716 719 switch (loading) {
+1
drivers/hv/ring_buffer.c
··· 383 383 return ret; 384 384 } 385 385 386 + init_cached_read_index(channel); 386 387 next_read_location = hv_get_next_read_location(inring_info); 387 388 next_read_location = hv_copyfrom_ringbuffer(inring_info, &desc, 388 389 sizeof(desc),
+6
drivers/net/hyperv/netvsc.c
··· 1295 1295 ndev = hv_get_drvdata(device); 1296 1296 buffer = get_per_channel_state(channel); 1297 1297 1298 + /* commit_rd_index() -> hv_signal_on_read() needs this. */ 1299 + init_cached_read_index(channel); 1300 + 1298 1301 do { 1299 1302 desc = get_next_pkt_raw(channel); 1300 1303 if (desc != NULL) { ··· 1350 1347 1351 1348 bufferlen = bytes_recvd; 1352 1349 } 1350 + 1351 + init_cached_read_index(channel); 1352 + 1353 1353 } while (1); 1354 1354 1355 1355 if (bufferlen > NETVSC_PACKET_SIZE)
+30 -2
include/linux/hyperv.h
··· 128 128 u32 ring_data_startoffset; 129 129 u32 priv_write_index; 130 130 u32 priv_read_index; 131 + u32 cached_read_index; 131 132 }; 132 133 133 134 /* ··· 181 180 return write; 182 181 } 183 182 183 + static inline u32 hv_get_cached_bytes_to_write( 184 + const struct hv_ring_buffer_info *rbi) 185 + { 186 + u32 read_loc, write_loc, dsize, write; 187 + 188 + dsize = rbi->ring_datasize; 189 + read_loc = rbi->cached_read_index; 190 + write_loc = rbi->ring_buffer->write_index; 191 + 192 + write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : 193 + read_loc - write_loc; 194 + return write; 195 + } 184 196 /* 185 197 * VMBUS version is 32 bit entity broken up into 186 198 * two 16 bit quantities: major_number. minor_number. ··· 1502 1488 1503 1489 static inline void hv_signal_on_read(struct vmbus_channel *channel) 1504 1490 { 1505 - u32 cur_write_sz; 1491 + u32 cur_write_sz, cached_write_sz; 1506 1492 u32 pending_sz; 1507 1493 struct hv_ring_buffer_info *rbi = &channel->inbound; 1508 1494 ··· 1526 1512 1527 1513 cur_write_sz = hv_get_bytes_to_write(rbi); 1528 1514 1529 - if (cur_write_sz >= pending_sz) 1515 + if (cur_write_sz < pending_sz) 1516 + return; 1517 + 1518 + cached_write_sz = hv_get_cached_bytes_to_write(rbi); 1519 + if (cached_write_sz < pending_sz) 1530 1520 vmbus_setevent(channel); 1531 1521 1532 1522 return; 1523 + } 1524 + 1525 + static inline void 1526 + init_cached_read_index(struct vmbus_channel *channel) 1527 + { 1528 + struct hv_ring_buffer_info *rbi = &channel->inbound; 1529 + 1530 + rbi->cached_read_index = rbi->ring_buffer->read_index; 1533 1531 } 1534 1532 1535 1533 /* ··· 1594 1568 /* 1595 1569 * This call commits the read index and potentially signals the host. 1596 1570 * Here is the pattern for using the "in-place" consumption APIs: 1571 + * 1572 + * init_cached_read_index(); 1597 1573 * 1598 1574 * while (get_next_pkt_raw() { 1599 1575 * process the packet "in-place";