.. | .. |
---|
929 | 929 | |
---|
930 | 930 | static void release_login_buffer(struct ibmvnic_adapter *adapter) |
---|
931 | 931 | { |
---|
| 932 | + if (!adapter->login_buf) |
---|
| 933 | + return; |
---|
| 934 | + |
---|
| 935 | + dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token, |
---|
| 936 | + adapter->login_buf_sz, DMA_TO_DEVICE); |
---|
932 | 937 | kfree(adapter->login_buf); |
---|
933 | 938 | adapter->login_buf = NULL; |
---|
934 | 939 | } |
---|
935 | 940 | |
---|
936 | 941 | static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter) |
---|
937 | 942 | { |
---|
| 943 | + if (!adapter->login_rsp_buf) |
---|
| 944 | + return; |
---|
| 945 | + |
---|
| 946 | + dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token, |
---|
| 947 | + adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); |
---|
938 | 948 | kfree(adapter->login_rsp_buf); |
---|
939 | 949 | adapter->login_rsp_buf = NULL; |
---|
940 | 950 | } |
---|
.. | .. |
---|
3861 | 3871 | if (rc) { |
---|
3862 | 3872 | adapter->login_pending = false; |
---|
3863 | 3873 | netdev_err(adapter->netdev, "Failed to send login, rc=%d\n", rc); |
---|
3864 | | - goto buf_rsp_map_failed; |
---|
| 3874 | + goto buf_send_failed; |
---|
3865 | 3875 | } |
---|
3866 | 3876 | |
---|
3867 | 3877 | return 0; |
---|
3868 | 3878 | |
---|
| 3879 | +buf_send_failed: |
---|
| 3880 | + dma_unmap_single(dev, rsp_buffer_token, rsp_buffer_size, |
---|
| 3881 | + DMA_FROM_DEVICE); |
---|
3869 | 3882 | buf_rsp_map_failed: |
---|
3870 | 3883 | kfree(login_rsp_buffer); |
---|
3871 | 3884 | adapter->login_rsp_buf = NULL; |
---|
.. | .. |
---|
4430 | 4443 | int num_tx_pools; |
---|
4431 | 4444 | int num_rx_pools; |
---|
4432 | 4445 | u64 *size_array; |
---|
| 4446 | + u32 rsp_len; |
---|
4433 | 4447 | int i; |
---|
4434 | 4448 | |
---|
4435 | 4449 | /* CHECK: Test/set of login_pending does not need to be atomic |
---|
.. | .. |
---|
4440 | 4454 | return 0; |
---|
4441 | 4455 | } |
---|
4442 | 4456 | adapter->login_pending = false; |
---|
4443 | | - |
---|
4444 | | - dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, |
---|
4445 | | - DMA_TO_DEVICE); |
---|
4446 | | - dma_unmap_single(dev, adapter->login_rsp_buf_token, |
---|
4447 | | - adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); |
---|
4448 | 4457 | |
---|
4449 | 4458 | /* If the number of queues requested can't be allocated by the |
---|
4450 | 4459 | * server, the login response will return with code 1. We will need |
---|
.. | .. |
---|
4481 | 4490 | ibmvnic_reset(adapter, VNIC_RESET_FATAL); |
---|
4482 | 4491 | return -EIO; |
---|
4483 | 4492 | } |
---|
| 4493 | + |
---|
| 4494 | + rsp_len = be32_to_cpu(login_rsp->len); |
---|
| 4495 | + if (be32_to_cpu(login->login_rsp_len) < rsp_len || |
---|
| 4496 | + rsp_len <= be32_to_cpu(login_rsp->off_txsubm_subcrqs) || |
---|
| 4497 | + rsp_len <= be32_to_cpu(login_rsp->off_rxadd_subcrqs) || |
---|
| 4498 | + rsp_len <= be32_to_cpu(login_rsp->off_rxadd_buff_size) || |
---|
| 4499 | + rsp_len <= be32_to_cpu(login_rsp->off_supp_tx_desc)) { |
---|
| 4500 | + /* This can happen if a login request times out and there are |
---|
| 4501 | + * 2 outstanding login requests sent, the LOGIN_RSP crq |
---|
| 4502 | + * could have been for the older login request. So we are |
---|
| 4503 | + * parsing the newer response buffer which may be incomplete |
---|
| 4504 | + */ |
---|
| 4505 | + dev_err(dev, "FATAL: Login rsp offsets/lengths invalid\n"); |
---|
| 4506 | + ibmvnic_reset(adapter, VNIC_RESET_FATAL); |
---|
| 4507 | + return -EIO; |
---|
| 4508 | + } |
---|
| 4509 | + |
---|
4484 | 4510 | size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + |
---|
4485 | 4511 | be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size)); |
---|
4486 | 4512 | /* variable buffer sizes are not supported, so just read the |
---|