Merge branch 'liquidio-lowmem-fixes'

Rick Farrington says:

====================
liquidio: avoid vm low memory crashes

This patchset addresses issues brought about by low memory conditions
in a VM.  These conditions were not seen when the driver was exercised
normally.  Rather, they were brought about through manual fault injection.
They are being included in the interest of hardening the driver against
unforeseen circumstances.

1. Fix GPF in octeon_init_droq(); zero the allocated block 'recv_buf_list'.
   This prevents a GPF trying to access an invalid 'recv_buf_list[i]' entry
   in octeon_droq_destroy_ring_buffers() if init didn't alloc all entries.
2. Don't dereference a NULL ptr in octeon_droq_destroy_ring_buffers().
3. For defensive programming, zero the allocated block 'oct->droq' in
   octeon_setup_output_queues() and 'oct->instr_queue' in
   octeon_setup_instr_queues().

change log:
V1 -> V2:
1. Corrected syntax in 'Subject' lines; no functional or code changes.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2017-07-19 13:24:47 -07:00
commit 6b098a08ad
2 changed files with 8 additions and 6 deletions

View File

@ -876,11 +876,11 @@ int octeon_setup_instr_queues(struct octeon_device *oct)
oct->num_iqs = 0;
oct->instr_queue[0] = vmalloc_node(sizeof(*oct->instr_queue[0]),
oct->instr_queue[0] = vzalloc_node(sizeof(*oct->instr_queue[0]),
numa_node);
if (!oct->instr_queue[0])
oct->instr_queue[0] =
vmalloc(sizeof(struct octeon_instr_queue));
vzalloc(sizeof(struct octeon_instr_queue));
if (!oct->instr_queue[0])
return 1;
memset(oct->instr_queue[0], 0, sizeof(struct octeon_instr_queue));
@ -923,9 +923,9 @@ int octeon_setup_output_queues(struct octeon_device *oct)
desc_size = CFG_GET_DEF_RX_BUF_SIZE(CHIP_CONF(oct, cn23xx_vf));
}
oct->num_oqs = 0;
oct->droq[0] = vmalloc_node(sizeof(*oct->droq[0]), numa_node);
oct->droq[0] = vzalloc_node(sizeof(*oct->droq[0]), numa_node);
if (!oct->droq[0])
oct->droq[0] = vmalloc(sizeof(*oct->droq[0]));
oct->droq[0] = vzalloc(sizeof(*oct->droq[0]));
if (!oct->droq[0])
return 1;

View File

@ -145,6 +145,8 @@ octeon_droq_destroy_ring_buffers(struct octeon_device *oct,
for (i = 0; i < droq->max_count; i++) {
pg_info = &droq->recv_buf_list[i].pg_info;
if (!pg_info)
continue;
if (pg_info->dma)
lio_unmap_ring(oct->pci_dev,
@ -275,12 +277,12 @@ int octeon_init_droq(struct octeon_device *oct,
droq->max_count);
droq->recv_buf_list = (struct octeon_recv_buffer *)
vmalloc_node(droq->max_count *
vzalloc_node(droq->max_count *
OCT_DROQ_RECVBUF_SIZE,
numa_node);
if (!droq->recv_buf_list)
droq->recv_buf_list = (struct octeon_recv_buffer *)
vmalloc(droq->max_count *
vzalloc(droq->max_count *
OCT_DROQ_RECVBUF_SIZE);
if (!droq->recv_buf_list) {
dev_err(&oct->pci_dev->dev, "Output queue recv buf list alloc failed\n");