From e90e8da72ad694a16a4ffa6e5adae3610208f73b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 20 Oct 2017 12:12:41 +0900 Subject: mmc: tmio: fix swiotlb buffer is full Since the commit de3ee99b097d ("mmc: Delete bounce buffer handling") deletes the bounce buffer handling, a request data size will be referred to max_{req,seg}_size instead of MMC_QUEUE_BOUNCESZ (64k bytes). In other hand, renesas_sdhi_internal_dmac.c will set very big value of max_{req,seg}_size because the max_blk_count is set to 0xffffffff. And then, "swiotlb buffer is full" happens because swiotlb can handle a memory size up to 256k bytes only (IO_TLB_SEGSIZE = 128 and IO_TLB_SHIFT = 11). So, as a workaround, this patch avoids the issue by setting the max_{req,seg}_size up to 256k bytes if swiotlb is running. Reported-by: Dirk Behme Signed-off-by: Yoshihiro Shimoda Acked-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Signed-off-by: Ulf Hansson --- drivers/mmc/host/tmio_mmc_core.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index a7293e186e03..9c4e6199b854 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include "tmio_mmc.h" @@ -1215,6 +1216,18 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, mmc->max_blk_count = pdata->max_blk_count ? : (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs; mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; + /* + * Since swiotlb has memory size limitation, this will calculate + * the maximum size locally (because we don't have any APIs for it now) + * and check the current max_req_size. And then, this will update + * the max_req_size if needed as a workaround. + */ + if (swiotlb_max_segment()) { + unsigned int max_size = (1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE; + + if (mmc->max_req_size > max_size) + mmc->max_req_size = max_size; + } mmc->max_seg_size = mmc->max_req_size; _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD || -- cgit v1.2.3 From 48e1dc10a9440872c0fc07a7fbcfce177f996fd4 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 20 Oct 2017 12:12:42 +0900 Subject: mmc: renesas_sdhi: fix kernel panic in _internal_dmac.c Since this driver checks if the return value of dma_map_sg() is minus or not and keeps to enable the DMAC, it may cause kernel panic when the dma_map_sg() returns 0. So, this patch fixes the issue. Reported-by: Dirk Behme Fixes: 2a68ea7896e3 ("mmc: renesas-sdhi: add support for R-Car Gen3 SDHI DMAC") Signed-off-by: Yoshihiro Shimoda Reviewed-by: Geert Uytterhoeven Acked-by: Wolfram Sang Signed-off-by: Ulf Hansson --- drivers/mmc/host/renesas_sdhi_internal_dmac.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index f905f2361d12..8bae88a150fd 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -146,11 +146,8 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, WARN_ON(host->sg_len > 1); /* This DMAC cannot handle if buffer is not 8-bytes alignment */ - if (!IS_ALIGNED(sg->offset, 8)) { - host->force_pio = true; - renesas_sdhi_internal_dmac_enable_dma(host, false); - return; - } + if (!IS_ALIGNED(sg->offset, 8)) + goto force_pio; if (data->flags & MMC_DATA_READ) { dtran_mode |= DTRAN_MODE_CH_NUM_CH1; @@ -163,8 +160,8 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, } ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir); - if (ret < 0) - return; + if (ret == 0) + goto force_pio; renesas_sdhi_internal_dmac_enable_dma(host, true); @@ -176,6 +173,12 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, dtran_mode); renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, sg->dma_address); + + return; + +force_pio: + host->force_pio = true; + renesas_sdhi_internal_dmac_enable_dma(host, false); } static void renesas_sdhi_internal_dmac_issue_tasklet_fn(unsigned long arg) -- cgit v1.2.3 From 7db814465395f3196ee98c8bd40d214d63e4f708 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Mon, 23 Oct 2017 16:04:11 +0300 Subject: nvme-rdma: fix possible hang when issuing commands during ctrl removal nvme_rdma_queue_is_ready() fails requests in case a queue is not LIVE. If the controller is in RECONNECTING state, we might be in this state for a long time (until we successfully reconnect) and we are better off with failing the request fast. Otherwise, we fail with BLK_STS_RESOURCE to have the block layer try again soon. In case we are removing the controller when the admin queue is not LIVE, we will terminate the request with BLK_STS_RESOURCE but it happens before we call blk_mq_start_request() so the request timeout never expires, and the queue will never get back to LIVE (because we are removing the controller). This causes the removal operation to block infinitly [1]. Thus, if we are removing (state DELETING), and the queue is not LIVE, we need to fail the request permanently as there is no chance for it to ever complete successfully. [1] -- sysrq: SysRq : Show Blocked State task PC stack pid father kworker/u66:2 D 0 440 2 0x80000000 Workqueue: nvme-wq nvme_rdma_del_ctrl_work [nvme_rdma] Call Trace: __schedule+0x3e9/0xb00 schedule+0x40/0x90 schedule_timeout+0x221/0x580 io_schedule_timeout+0x1e/0x50 wait_for_completion_io_timeout+0x118/0x180 blk_execute_rq+0x86/0xc0 __nvme_submit_sync_cmd+0x89/0xf0 nvmf_reg_write32+0x4b/0x90 [nvme_fabrics] nvme_shutdown_ctrl+0x41/0xe0 nvme_rdma_shutdown_ctrl+0xca/0xd0 [nvme_rdma] nvme_rdma_remove_ctrl+0x2b/0x40 [nvme_rdma] nvme_rdma_del_ctrl_work+0x25/0x30 [nvme_rdma] process_one_work+0x1fd/0x630 worker_thread+0x1db/0x3b0 kthread+0x11e/0x150 ret_from_fork+0x27/0x40 01 D 0 2868 2862 0x00000000 Call Trace: __schedule+0x3e9/0xb00 schedule+0x40/0x90 schedule_timeout+0x260/0x580 wait_for_completion+0x108/0x170 flush_work+0x1e0/0x270 nvme_rdma_del_ctrl+0x5a/0x80 [nvme_rdma] nvme_sysfs_delete+0x2a/0x40 dev_attr_store+0x18/0x30 sysfs_kf_write+0x45/0x60 kernfs_fop_write+0x124/0x1c0 __vfs_write+0x28/0x150 vfs_write+0xc7/0x1b0 SyS_write+0x49/0xa0 entry_SYSCALL_64_fastpath+0x18/0xad -- Reported-by: Bart Van Assche Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/host/rdma.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 87bac27ec64b..0ebb539f3bd3 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1614,12 +1614,15 @@ nvme_rdma_queue_is_ready(struct nvme_rdma_queue *queue, struct request *rq) /* * reconnecting state means transport disruption, which * can take a long time and even might fail permanently, - * so we can't let incoming I/O be requeued forever. - * fail it fast to allow upper layers a chance to - * failover. + * fail fast to give upper layers a chance to failover. + * deleting state means that the ctrl will never accept + * commands again, fail it permanently. */ - if (queue->ctrl->ctrl.state == NVME_CTRL_RECONNECTING) + if (queue->ctrl->ctrl.state == NVME_CTRL_RECONNECTING || + queue->ctrl->ctrl.state == NVME_CTRL_DELETING) { + nvme_req(rq)->status = NVME_SC_ABORT_REQ; return BLK_STS_IOERR; + } return BLK_STS_RESOURCE; /* try again later */ } } -- cgit v1.2.3 From c0d5adc35c0b010120391117cb07be6623cf8940 Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Fri, 27 Oct 2017 11:12:30 +0300 Subject: wcn36xx: Remove unnecessary rcu_read_unlock in wcn36xx_bss_info_changed No rcu_read_lock is called, but rcu_read_unlock is still called. Thus rcu_read_unlock should be removed. Signed-off-by: Jia-Ju Bai Acked-by: Bjorn Andersson Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wcn36xx/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 35bd50bcbbd5..b83f01d6e3dd 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -812,7 +812,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, if (!sta) { wcn36xx_err("sta %pM is not found\n", bss_conf->bssid); - rcu_read_unlock(); goto out; } sta_priv = wcn36xx_sta_to_priv(sta); -- cgit v1.2.3 From efea2abcb03215f2efadfe994ff7f652aaff196b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 27 Oct 2017 08:23:21 -0600 Subject: virtio_blk: Fix an SG_IO regression Avoid that submitting an SG_IO ioctl triggers a kernel oops that is preceded by: usercopy: kernel memory overwrite attempt detected to (null) () (6 bytes) kernel BUG at mm/usercopy.c:72! Reported-by: Dann Frazier Fixes: commit ca18d6f769d2 ("block: Make most scsi_req_init() calls implicit") Signed-off-by: Bart Van Assche Cc: Michael S. Tsirkin Cc: Dann Frazier Cc: # v4.13 Reviewed-by: Christoph Hellwig Moved virtblk_initialize_rq() inside CONFIG_VIRTIO_BLK_SCSI. Signed-off-by: Jens Axboe --- drivers/block/virtio_blk.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 34e17ee799be..68846897d213 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -593,10 +593,22 @@ static int virtblk_map_queues(struct blk_mq_tag_set *set) return blk_mq_virtio_map_queues(set, vblk->vdev, 0); } +#ifdef CONFIG_VIRTIO_BLK_SCSI +static void virtblk_initialize_rq(struct request *req) +{ + struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); + + scsi_req_init(&vbr->sreq); +} +#endif + static const struct blk_mq_ops virtio_mq_ops = { .queue_rq = virtio_queue_rq, .complete = virtblk_request_done, .init_request = virtblk_init_request, +#ifdef CONFIG_VIRTIO_BLK_SCSI + .initialize_rq_fn = virtblk_initialize_rq, +#endif .map_queues = virtblk_map_queues, }; -- cgit v1.2.3 From 7eccb738fce57cbe53ed903ccf43f9ab257b15b3 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 27 Oct 2017 18:35:31 +0300 Subject: ath10k: rebuild crypto header in rx data frames Rx data frames notified through HTT_T2H_MSG_TYPE_RX_IND and HTT_T2H_MSG_TYPE_RX_FRAG_IND expect PN/TSC check to be done on host (mac80211) rather than firmware. Rebuild cipher header in every received data frames (that are notified through those HTT interfaces) from the rx_hdr_status tlv available in the rx descriptor of the first msdu. Skip setting RX_FLAG_IV_STRIPPED flag for the packets which requires mac80211 PN/TSC check support and set appropriate RX_FLAG for stripped crypto tail. Hw QCA988X, QCA9887, QCA99X0, QCA9984, QCA9888 and QCA4019 currently need the rebuilding of cipher header to perform PN/TSC check for replay attack. Please note that removing crypto tail for CCMP-256, GCMP and GCMP-256 ciphers in raw mode needs to be fixed. Since Rx with these ciphers in raw mode does not work in the current form even without this patch and removing crypto tail for these chipers needs clean up, raw mode related issues in CCMP-256, GCMP and GCMP-256 can be addressed in follow up patches. Tested-by: Manikanta Pubbisetty Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 105 +++++++++++++++++++++++++----- drivers/net/wireless/ath/ath10k/rx_desc.h | 3 + 2 files changed, 92 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index a3f5dc78353f..5beb6ee0f091 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -550,6 +550,11 @@ static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar, return IEEE80211_TKIP_IV_LEN; case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: return IEEE80211_CCMP_HDR_LEN; + case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2: + return IEEE80211_CCMP_256_HDR_LEN; + case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2: + case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2: + return IEEE80211_GCMP_HDR_LEN; case HTT_RX_MPDU_ENCRYPT_WEP128: case HTT_RX_MPDU_ENCRYPT_WAPI: break; @@ -575,6 +580,11 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar, return IEEE80211_TKIP_ICV_LEN; case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: return IEEE80211_CCMP_MIC_LEN; + case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2: + return IEEE80211_CCMP_256_MIC_LEN; + case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2: + case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2: + return IEEE80211_GCMP_MIC_LEN; case HTT_RX_MPDU_ENCRYPT_WEP128: case HTT_RX_MPDU_ENCRYPT_WAPI: break; @@ -1051,9 +1061,21 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, hdr = (void *)msdu->data; /* Tail */ - if (status->flag & RX_FLAG_IV_STRIPPED) + if (status->flag & RX_FLAG_IV_STRIPPED) { skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype)); + } else { + /* MIC */ + if ((status->flag & RX_FLAG_MIC_STRIPPED) && + enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) + skb_trim(msdu, msdu->len - 8); + + /* ICV */ + if (status->flag & RX_FLAG_ICV_STRIPPED && + enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) + skb_trim(msdu, msdu->len - + ath10k_htt_rx_crypto_tail_len(ar, enctype)); + } /* MMIC */ if ((status->flag & RX_FLAG_MMIC_STRIPPED) && @@ -1075,7 +1097,8 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, struct sk_buff *msdu, struct ieee80211_rx_status *status, - const u8 first_hdr[64]) + const u8 first_hdr[64], + enum htt_rx_mpdu_encrypt_type enctype) { struct ieee80211_hdr *hdr; struct htt_rx_desc *rxd; @@ -1083,6 +1106,7 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; int l3_pad_bytes; + int bytes_aligned = ar->hw_params.decap_align_bytes; /* Delivered decapped frame: * [nwifi 802.11 header] <-- replaced with 802.11 hdr @@ -1111,6 +1135,14 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, /* push original 802.11 header */ hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + memcpy(skb_push(msdu, + ath10k_htt_rx_crypto_param_len(ar, enctype)), + (void *)hdr + round_up(hdr_len, bytes_aligned), + ath10k_htt_rx_crypto_param_len(ar, enctype)); + } + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); /* original 802.11 header has a different DA and in @@ -1171,6 +1203,7 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, u8 sa[ETH_ALEN]; int l3_pad_bytes; struct htt_rx_desc *rxd; + int bytes_aligned = ar->hw_params.decap_align_bytes; /* Delivered decapped frame: * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc @@ -1199,6 +1232,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, /* push original 802.11 header */ hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + memcpy(skb_push(msdu, + ath10k_htt_rx_crypto_param_len(ar, enctype)), + (void *)hdr + round_up(hdr_len, bytes_aligned), + ath10k_htt_rx_crypto_param_len(ar, enctype)); + } + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); /* original 802.11 header has a different DA and in @@ -1212,12 +1253,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, struct sk_buff *msdu, struct ieee80211_rx_status *status, - const u8 first_hdr[64]) + const u8 first_hdr[64], + enum htt_rx_mpdu_encrypt_type enctype) { struct ieee80211_hdr *hdr; size_t hdr_len; int l3_pad_bytes; struct htt_rx_desc *rxd; + int bytes_aligned = ar->hw_params.decap_align_bytes; /* Delivered decapped frame: * [amsdu header] <-- replaced with 802.11 hdr @@ -1233,6 +1276,14 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + memcpy(skb_push(msdu, + ath10k_htt_rx_crypto_param_len(ar, enctype)), + (void *)hdr + round_up(hdr_len, bytes_aligned), + ath10k_htt_rx_crypto_param_len(ar, enctype)); + } + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); } @@ -1267,13 +1318,15 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar, is_decrypted); break; case RX_MSDU_DECAP_NATIVE_WIFI: - ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr); + ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr, + enctype); break; case RX_MSDU_DECAP_ETHERNET2_DIX: ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype); break; case RX_MSDU_DECAP_8023_SNAP_LLC: - ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr); + ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr, + enctype); break; } } @@ -1316,7 +1369,8 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, struct sk_buff_head *amsdu, - struct ieee80211_rx_status *status) + struct ieee80211_rx_status *status, + bool fill_crypt_header) { struct sk_buff *first; struct sk_buff *last; @@ -1326,7 +1380,6 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, enum htt_rx_mpdu_encrypt_type enctype; u8 first_hdr[64]; u8 *qos; - size_t hdr_len; bool has_fcs_err; bool has_crypto_err; bool has_tkip_err; @@ -1351,15 +1404,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, * decapped header. It'll be used for undecapping of each MSDU. */ hdr = (void *)rxd->rx_hdr_status; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(first_hdr, hdr, hdr_len); + memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN); /* Each A-MSDU subframe will use the original header as the base and be * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. */ hdr = (void *)first_hdr; - qos = ieee80211_get_qos_ctl(hdr); - qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + + if (ieee80211_is_data_qos(hdr->frame_control)) { + qos = ieee80211_get_qos_ctl(hdr); + qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + } /* Some attention flags are valid only in the last MSDU. */ last = skb_peek_tail(amsdu); @@ -1406,9 +1461,14 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, status->flag |= RX_FLAG_DECRYPTED; if (likely(!is_mgmt)) - status->flag |= RX_FLAG_IV_STRIPPED | - RX_FLAG_MMIC_STRIPPED; -} + status->flag |= RX_FLAG_MMIC_STRIPPED; + + if (fill_crypt_header) + status->flag |= RX_FLAG_MIC_STRIPPED | + RX_FLAG_ICV_STRIPPED; + else + status->flag |= RX_FLAG_IV_STRIPPED; + } skb_queue_walk(amsdu, msdu) { ath10k_htt_rx_h_csum_offload(msdu); @@ -1424,6 +1484,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, if (is_mgmt) continue; + if (fill_crypt_header) + continue; + hdr = (void *)msdu->data; hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); } @@ -1434,6 +1497,9 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, struct ieee80211_rx_status *status) { struct sk_buff *msdu; + struct sk_buff *first_subframe; + + first_subframe = skb_peek(amsdu); while ((msdu = __skb_dequeue(amsdu))) { /* Setup per-MSDU flags */ @@ -1442,6 +1508,13 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, else status->flag |= RX_FLAG_AMSDU_MORE; + if (msdu == first_subframe) { + first_subframe = NULL; + status->flag &= ~RX_FLAG_ALLOW_SAME_PN; + } else { + status->flag |= RX_FLAG_ALLOW_SAME_PN; + } + ath10k_process_rx(ar, status, msdu); } } @@ -1584,7 +1657,7 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) ath10k_htt_rx_h_unchain(ar, &amsdu); ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); - ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); + ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); return num_msdus; @@ -1923,7 +1996,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb, budget_left -= skb_queue_len(&amsdu); ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); ath10k_htt_rx_h_filter(ar, &amsdu, status); - ath10k_htt_rx_h_mpdu(ar, &amsdu, status); + ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); ath10k_htt_rx_h_deliver(ar, &amsdu, status); break; case -EAGAIN: diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h index c1022a1cf855..28da14398951 100644 --- a/drivers/net/wireless/ath/ath10k/rx_desc.h +++ b/drivers/net/wireless/ath/ath10k/rx_desc.h @@ -239,6 +239,9 @@ enum htt_rx_mpdu_encrypt_type { HTT_RX_MPDU_ENCRYPT_WAPI = 5, HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2 = 6, HTT_RX_MPDU_ENCRYPT_NONE = 7, + HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2 = 8, + HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2 = 9, + HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2 = 10, }; #define RX_MPDU_START_INFO0_PEER_IDX_MASK 0x000007ff -- cgit v1.2.3 From e48e9c429a95e6ff103bb830f07e2e6a6954a839 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Sun, 29 Oct 2017 09:45:07 +0200 Subject: Revert "ath10k: fix napi_poll budget overflow" Thorsten reported on that commit c9353bf483d3 made ath10k unstable with QCA6174 on his Dell XPS13 (9360) with an error message: ath10k_pci 0000:3a:00.0: failed to extract amsdu: -11 It only seemed to happen with certain APs, not all, but when it happened the only way to get ath10k working was to switch the wifi off and on with a hotkey. As this commit made things even worse (a warning vs breaking the whole connection) let's revert the commit for now and while the issue is being fixed. Link: http://lists.infradead.org/pipermail/ath10k/2017-October/010227.html Reported-by: Thorsten Leemhuis Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 5beb6ee0f091..0aeeb233af78 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -1818,8 +1818,7 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp) } static int ath10k_htt_rx_extract_amsdu(struct sk_buff_head *list, - struct sk_buff_head *amsdu, - int budget_left) + struct sk_buff_head *amsdu) { struct sk_buff *msdu; struct htt_rx_desc *rxd; @@ -1830,9 +1829,8 @@ static int ath10k_htt_rx_extract_amsdu(struct sk_buff_head *list, if (WARN_ON(!skb_queue_empty(amsdu))) return -EINVAL; - while ((msdu = __skb_dequeue(list)) && budget_left) { + while ((msdu = __skb_dequeue(list))) { __skb_queue_tail(amsdu, msdu); - budget_left--; rxd = (void *)msdu->data - sizeof(*rxd); if (rxd->msdu_end.common.info0 & @@ -1923,8 +1921,7 @@ static int ath10k_htt_rx_h_rx_offload(struct ath10k *ar, return num_msdu; } -static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb, - int budget_left) +static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) { struct ath10k_htt *htt = &ar->htt; struct htt_resp *resp = (void *)skb->data; @@ -1981,9 +1978,9 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb, if (offload) num_msdus = ath10k_htt_rx_h_rx_offload(ar, &list); - while (!skb_queue_empty(&list) && budget_left) { + while (!skb_queue_empty(&list)) { __skb_queue_head_init(&amsdu); - ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu, budget_left); + ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu); switch (ret) { case 0: /* Note: The in-order indication may report interleaved @@ -1993,7 +1990,6 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb, * should still give an idea about rx rate to the user. */ num_msdus += skb_queue_len(&amsdu); - budget_left -= skb_queue_len(&amsdu); ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); ath10k_htt_rx_h_filter(ar, &amsdu, status); ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); @@ -2636,8 +2632,7 @@ int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget) } spin_lock_bh(&htt->rx_ring.lock); - num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb, - (budget - quota)); + num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb); spin_unlock_bh(&htt->rx_ring.lock); if (num_rx_msdus < 0) { resched_napi = true; -- cgit v1.2.3 From 5e0fab57fb3e0e553758067a15eefdc796ef0a76 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 27 Oct 2017 13:51:22 -0600 Subject: nvme: Fix setting logical block format when revalidating Revalidating the disk needs to set the logical block format and capacity, otherwise it can't figure out if the users modified anything about the namespace. Fixes: cdbff4f26bd9 ("nvme: remove nvme_revalidate_ns") Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/nvme/host/core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 5a14cc7f28ee..37f9039bb9ca 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1249,6 +1249,7 @@ static int nvme_revalidate_disk(struct gendisk *disk) goto out; } + __nvme_revalidate_disk(disk, id); nvme_report_ns_ids(ctrl, ns->ns_id, id, eui64, nguid, &uuid); if (!uuid_equal(&ns->uuid, &uuid) || memcmp(&ns->nguid, &nguid, sizeof(ns->nguid)) || -- cgit v1.2.3 From d5919dcc349d2a16d805ef8096d36e4f519e42ae Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 31 Oct 2017 18:26:15 +0100 Subject: Revert "PM / QoS: Fix device resume latency PM QoS" This reverts commit 0cc2b4e5a020 (PM / QoS: Fix device resume latency PM QoS) as it introduced regressions on multiple systems and the fix-up in commit 2a9a86d5c813 (PM / QoS: Fix default runtime_pm device resume latency) does not address all of them. The original problem that commit 0cc2b4e5a020 was attempting to fix will be addressed later. Fixes: 0cc2b4e5a020 (PM / QoS: Fix device resume latency PM QoS) Reported-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-devices-power | 4 +- drivers/base/cpu.c | 3 +- drivers/base/power/domain_governor.c | 53 ++++++++++++--------------- drivers/base/power/qos.c | 2 +- drivers/base/power/runtime.c | 2 +- drivers/base/power/sysfs.c | 25 ++----------- drivers/cpuidle/governors/menu.c | 4 +- include/linux/pm_qos.h | 5 +-- 8 files changed, 35 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index 5cbb6f038615..676fdf5f2a99 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power @@ -211,9 +211,7 @@ Description: device, after it has been suspended at run time, from a resume request to the moment the device will be ready to process I/O, in microseconds. If it is equal to 0, however, this means that - the PM QoS resume latency may be arbitrary and the special value - "n/a" means that user space cannot accept any resume latency at - all for the given device. + the PM QoS resume latency may be arbitrary. Not all drivers support this attribute. If it isn't supported, it is not present. diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 227bac5f1191..321cd7b4d817 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -377,8 +377,7 @@ int register_cpu(struct cpu *cpu, int num) per_cpu(cpu_sys_devices, num) = &cpu->dev; register_cpu_under_node(num, cpu_to_node(num)); - dev_pm_qos_expose_latency_limit(&cpu->dev, - PM_QOS_RESUME_LATENCY_NO_CONSTRAINT); + dev_pm_qos_expose_latency_limit(&cpu->dev, 0); return 0; } diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 51751cc8c9e6..281f949c5ffe 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c @@ -14,20 +14,23 @@ static int dev_update_qos_constraint(struct device *dev, void *data) { s64 *constraint_ns_p = data; - s64 constraint_ns = -1; + s32 constraint_ns = -1; if (dev->power.subsys_data && dev->power.subsys_data->domain_data) constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns; - if (constraint_ns < 0) + if (constraint_ns < 0) { constraint_ns = dev_pm_qos_read_value(dev); - - if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + constraint_ns *= NSEC_PER_USEC; + } + if (constraint_ns == 0) return 0; - constraint_ns *= NSEC_PER_USEC; - - if (constraint_ns < *constraint_ns_p || *constraint_ns_p < 0) + /* + * constraint_ns cannot be negative here, because the device has been + * suspended. + */ + if (constraint_ns < *constraint_ns_p || *constraint_ns_p == 0) *constraint_ns_p = constraint_ns; return 0; @@ -60,14 +63,10 @@ static bool default_suspend_ok(struct device *dev) spin_unlock_irqrestore(&dev->power.lock, flags); - if (constraint_ns == 0) + if (constraint_ns < 0) return false; - if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) - constraint_ns = -1; - else - constraint_ns *= NSEC_PER_USEC; - + constraint_ns *= NSEC_PER_USEC; /* * We can walk the children without any additional locking, because * they all have been suspended at this point and their @@ -77,19 +76,14 @@ static bool default_suspend_ok(struct device *dev) device_for_each_child(dev, &constraint_ns, dev_update_qos_constraint); - if (constraint_ns < 0) { - /* The children have no constraints. */ - td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; - td->cached_suspend_ok = true; - } else { - constraint_ns -= td->suspend_latency_ns + td->resume_latency_ns; - if (constraint_ns > 0) { - td->effective_constraint_ns = constraint_ns; - td->cached_suspend_ok = true; - } else { - td->effective_constraint_ns = 0; - } + if (constraint_ns > 0) { + constraint_ns -= td->suspend_latency_ns + + td->resume_latency_ns; + if (constraint_ns == 0) + return false; } + td->effective_constraint_ns = constraint_ns; + td->cached_suspend_ok = constraint_ns >= 0; /* * The children have been suspended already, so we don't need to take @@ -151,14 +145,13 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, td = &to_gpd_data(pdd)->td; constraint_ns = td->effective_constraint_ns; /* default_suspend_ok() need not be called before us. */ - if (constraint_ns < 0) + if (constraint_ns < 0) { constraint_ns = dev_pm_qos_read_value(pdd->dev); - - if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + constraint_ns *= NSEC_PER_USEC; + } + if (constraint_ns == 0) continue; - constraint_ns *= NSEC_PER_USEC; - /* * constraint_ns cannot be negative here, because the device has * been suspended. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 7d29286d9313..277d43a83f53 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -189,7 +189,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) plist_head_init(&c->list); c->target_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; - c->no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; + c->no_constraint_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->type = PM_QOS_MIN; c->notifiers = n; diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 13e015905543..7bcf80fa9ada 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -253,7 +253,7 @@ static int rpm_check_suspend_allowed(struct device *dev) || (dev->power.request_pending && dev->power.request == RPM_REQ_RESUME)) retval = -EAGAIN; - else if (__dev_pm_qos_read_value(dev) == 0) + else if (__dev_pm_qos_read_value(dev) < 0) retval = -EPERM; else if (dev->power.runtime_status == RPM_SUSPENDED) retval = 1; diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 632077f05c57..156ab57bca77 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -218,14 +218,7 @@ static ssize_t pm_qos_resume_latency_show(struct device *dev, struct device_attribute *attr, char *buf) { - s32 value = dev_pm_qos_requested_resume_latency(dev); - - if (value == 0) - return sprintf(buf, "n/a\n"); - else if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) - value = 0; - - return sprintf(buf, "%d\n", value); + return sprintf(buf, "%d\n", dev_pm_qos_requested_resume_latency(dev)); } static ssize_t pm_qos_resume_latency_store(struct device *dev, @@ -235,21 +228,11 @@ static ssize_t pm_qos_resume_latency_store(struct device *dev, s32 value; int ret; - if (!kstrtos32(buf, 0, &value)) { - /* - * Prevent users from writing negative or "no constraint" values - * directly. - */ - if (value < 0 || value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) - return -EINVAL; + if (kstrtos32(buf, 0, &value)) + return -EINVAL; - if (value == 0) - value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; - } else if (!strcmp(buf, "n/a") || !strcmp(buf, "n/a\n")) { - value = 0; - } else { + if (value < 0) return -EINVAL; - } ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req, value); diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index aa390404e85f..48eaf2879228 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -298,8 +298,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->needs_update = 0; } - if (resume_latency < latency_req && - resume_latency != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + /* resume_latency is 0 means no restriction */ + if (resume_latency && resume_latency < latency_req) latency_req = resume_latency; /* Special case when user has set very strict latency requirement */ diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 6737a8c9e8c6..032b55909145 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -27,17 +27,16 @@ enum pm_qos_flags_status { PM_QOS_FLAGS_ALL, }; -#define PM_QOS_DEFAULT_VALUE (-1) -#define PM_QOS_LATENCY_ANY S32_MAX +#define PM_QOS_DEFAULT_VALUE -1 #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 #define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE 0 #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0 -#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) +#define PM_QOS_LATENCY_ANY ((s32)(~(__u32)0 >> 1)) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) #define PM_QOS_FLAG_REMOTE_WAKEUP (1 << 1) -- cgit v1.2.3 From 287683d027a3ff83feb6c7044430c79881664ecf Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 31 Oct 2017 20:09:54 +0200 Subject: RDMA/nldev: Enforce device index check for port callback IB device index is nldev's handler and it should be checked always. Fixes: c3f66f7b0052 ("RDMA/netlink: Implement nldev port doit callback") Signed-off-by: Leon Romanovsky Acked-by: Doug Ledford [ Applying directly, since Doug fried his SSD's and is rebuilding - Linus ] Signed-off-by: Linus Torvalds --- drivers/infiniband/core/nldev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 3ba24c428c3b..2fae850a3eff 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c @@ -214,7 +214,9 @@ static int nldev_port_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh, err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1, nldev_policy, extack); - if (err || !tb[RDMA_NLDEV_ATTR_PORT_INDEX]) + if (err || + !tb[RDMA_NLDEV_ATTR_DEV_INDEX] || + !tb[RDMA_NLDEV_ATTR_PORT_INDEX]) return -EINVAL; index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); -- cgit v1.2.3 From 14fc0abafe159fbe8bbcfeca157ef3ba139fa75f Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 31 Oct 2017 20:31:28 +0100 Subject: net: phy: marvell: Only configure RGMII delays when using RGMII The fix 5987feb38aa5 ("net: phy: marvell: logical vs bitwise OR typo") uncovered another bug in the Marvell PHY driver, which broke the Marvell OpenRD platform. It relies on the bootloader configuring the RGMII delays and does not specify a phy-mode in its device tree. The PHY driver should only configure RGMII delays if the phy mode indicates it is using RGMII. Without anything in device tree, the mv643xx Ethernet driver defaults to GMII. Fixes: 5987feb38aa5 ("net: phy: marvell: logical vs bitwise OR typo") Signed-off-by: Andrew Lunn Tested-by: Aaro Koskinen Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/marvell.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 15cbcdba618a..4d02b27df044 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -681,9 +681,11 @@ static int m88e1116r_config_init(struct phy_device *phydev) if (err < 0) return err; - err = m88e1121_config_aneg_rgmii_delays(phydev); - if (err < 0) - return err; + if (phy_interface_is_rgmii(phydev)) { + err = m88e1121_config_aneg_rgmii_delays(phydev); + if (err < 0) + return err; + } err = genphy_soft_reset(phydev); if (err < 0) -- cgit v1.2.3 From 7db8874abd9a134821881bb99301b3afbbe9b080 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sun, 29 Oct 2017 21:57:22 +0800 Subject: net: lapbether: fix double free The function netdev_priv() returns the private data of the device. The memory to store the private data is allocated in alloc_netdev() and is released in netdev_free(). Calling kfree() on the return value of netdev_priv() after netdev_free() results in a double free bug. Signed-off-by: Pan Bian Signed-off-by: David S. Miller --- drivers/net/wan/lapbether.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 63f749078a1f..0e3f8ed84660 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -346,7 +346,6 @@ out: fail: dev_put(dev); free_netdev(ndev); - kfree(lapbeth); goto out; } -- cgit v1.2.3 From d2083d0e92117598dd24ba270af12376f1fb8866 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Mon, 30 Oct 2017 16:50:01 +0800 Subject: net: hns: set correct return value The function of_parse_phandle() returns a NULL pointer if it cannot resolve a phandle property to a device_node pointer. In function hns_nic_dev_probe(), its return value is passed to PTR_ERR to extract the error code. However, in this case, the extracted error code will always be zero, which is unexpected. Signed-off-by: Pan Bian Reviewed-by: Tobias Klauser Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index 36520634c96a..e77192683dba 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -2369,8 +2369,8 @@ static int hns_nic_dev_probe(struct platform_device *pdev) priv->enet_ver = AE_VERSION_2; ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0); - if (IS_ERR_OR_NULL(ae_node)) { - ret = PTR_ERR(ae_node); + if (!ae_node) { + ret = -ENODEV; dev_err(dev, "not find ae-handle\n"); goto out_read_prop_fail; } -- cgit v1.2.3 From 62b0e9243fca257217ef72f383bd38ed5a542b5e Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Mon, 30 Oct 2017 10:51:18 +0100 Subject: mlxsw: reg: Add high and low temperature thresholds The ASIC has the ability to generate events whenever a sensor indicates the temperature goes above or below its high or low thresholds, respectively. In new firmware versions the firmware enforces a minimum of 5 degrees Celsius difference between both thresholds. Make the driver conform to this requirement. Note that this is required even when the events are disabled, as in certain systems interrupts are generated via GPIO based on these thresholds. Fixes: 85926f877040 ("mlxsw: reg: Add definition of temperature management registers") Signed-off-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 4afc8486eb9a..5acfbe5b8b9d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -5827,6 +5827,29 @@ MLXSW_ITEM32(reg, mtmp, mtr, 0x08, 30, 1); */ MLXSW_ITEM32(reg, mtmp, max_temperature, 0x08, 0, 16); +/* reg_mtmp_tee + * Temperature Event Enable. + * 0 - Do not generate event + * 1 - Generate event + * 2 - Generate single event + * Access: RW + */ +MLXSW_ITEM32(reg, mtmp, tee, 0x0C, 30, 2); + +#define MLXSW_REG_MTMP_THRESH_HI 0x348 /* 105 Celsius */ + +/* reg_mtmp_temperature_threshold_hi + * High threshold for Temperature Warning Event. In 0.125 Celsius. + * Access: RW + */ +MLXSW_ITEM32(reg, mtmp, temperature_threshold_hi, 0x0C, 0, 16); + +/* reg_mtmp_temperature_threshold_lo + * Low threshold for Temperature Warning Event. In 0.125 Celsius. + * Access: RW + */ +MLXSW_ITEM32(reg, mtmp, temperature_threshold_lo, 0x10, 0, 16); + #define MLXSW_REG_MTMP_SENSOR_NAME_SIZE 8 /* reg_mtmp_sensor_name @@ -5843,6 +5866,8 @@ static inline void mlxsw_reg_mtmp_pack(char *payload, u8 sensor_index, mlxsw_reg_mtmp_sensor_index_set(payload, sensor_index); mlxsw_reg_mtmp_mte_set(payload, max_temp_enable); mlxsw_reg_mtmp_mtr_set(payload, max_temp_reset); + mlxsw_reg_mtmp_temperature_threshold_hi_set(payload, + MLXSW_REG_MTMP_THRESH_HI); } static inline void mlxsw_reg_mtmp_unpack(char *payload, unsigned int *p_temp, -- cgit v1.2.3 From d70eaa386bf9ecc1e5b3002f64eb59172fcec4fd Mon Sep 17 00:00:00 2001 From: Vadim Pasternak Date: Wed, 1 Nov 2017 12:10:42 +0100 Subject: mlxsw: i2c: Fix buffer increment counter for write transaction It fixes a problem for the last chunk where 'chunk_size' is smaller than MLXSW_I2C_BLK_MAX and data is copied to the wrong offset, overriding previous data. Fixes: 6882b0aee180 ("mlxsw: Introduce support for I2C bus") Signed-off-by: Vadim Pasternak Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c index 12c3a4449120..c0dcfa05b077 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c +++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c @@ -294,7 +294,7 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num, write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size; mlxsw_i2c_set_slave_addr(tran_buf, off); memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox + - chunk_size * i, chunk_size); + MLXSW_I2C_BLK_MAX * i, chunk_size); j = 0; end = jiffies + timeout; -- cgit v1.2.3 From 93161922c658c714715686cd0cf69b090cb9bf1d Mon Sep 17 00:00:00 2001 From: Craig Gallek Date: Mon, 30 Oct 2017 18:50:11 -0400 Subject: tun/tap: sanitize TUNSETSNDBUF input Syzkaller found several variants of the lockup below by setting negative values with the TUNSETSNDBUF ioctl. This patch adds a sanity check to both the tun and tap versions of this ioctl. watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [repro:2389] Modules linked in: irq event stamp: 329692056 hardirqs last enabled at (329692055): [] _raw_spin_unlock_irqrestore+0x31/0x75 hardirqs last disabled at (329692056): [] apic_timer_interrupt+0x98/0xb0 softirqs last enabled at (35659740): [] __do_softirq+0x328/0x48c softirqs last disabled at (35659731): [] irq_exit+0xbc/0xd0 CPU: 0 PID: 2389 Comm: repro Not tainted 4.14.0-rc7 #23 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 task: ffff880009452140 task.stack: ffff880006a20000 RIP: 0010:_raw_spin_lock_irqsave+0x11/0x80 RSP: 0018:ffff880006a27c50 EFLAGS: 00000282 ORIG_RAX: ffffffffffffff10 RAX: ffff880009ac68d0 RBX: ffff880006a27ce0 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffff880006a27ce0 RDI: ffff880009ac6900 RBP: ffff880006a27c60 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 000000000063ff00 R12: ffff880009ac6900 R13: ffff880006a27cf8 R14: 0000000000000001 R15: ffff880006a27cf8 FS: 00007f4be4838700(0000) GS:ffff88000cc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020101000 CR3: 0000000009616000 CR4: 00000000000006f0 Call Trace: prepare_to_wait+0x26/0xc0 sock_alloc_send_pskb+0x14e/0x270 ? remove_wait_queue+0x60/0x60 tun_get_user+0x2cc/0x19d0 ? __tun_get+0x60/0x1b0 tun_chr_write_iter+0x57/0x86 __vfs_write+0x156/0x1e0 vfs_write+0xf7/0x230 SyS_write+0x57/0xd0 entry_SYSCALL_64_fastpath+0x1f/0xbe RIP: 0033:0x7f4be4356df9 RSP: 002b:00007ffc18101c08 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f4be4356df9 RDX: 0000000000000046 RSI: 0000000020101000 RDI: 0000000000000005 RBP: 00007ffc18101c40 R08: 0000000000000001 R09: 0000000000000001 R10: 0000000000000001 R11: 0000000000000293 R12: 0000559c75f64780 R13: 00007ffc18101d30 R14: 0000000000000000 R15: 0000000000000000 Fixes: 33dccbb050bb ("tun: Limit amount of queued packets per device") Fixes: 20d29d7a916a ("net: macvtap driver") Signed-off-by: Craig Gallek Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tap.c | 2 ++ drivers/net/tun.c | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 1b10fcc6a58d..6c0c84c33e1f 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1032,6 +1032,8 @@ static long tap_ioctl(struct file *file, unsigned int cmd, case TUNSETSNDBUF: if (get_user(s, sp)) return -EFAULT; + if (s <= 0) + return -EINVAL; q->sk.sk_sndbuf = s; return 0; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 5550f56cb895..42bb820a56c9 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2429,6 +2429,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ret = -EFAULT; break; } + if (sndbuf <= 0) { + ret = -EINVAL; + break; + } tun->sndbuf = sndbuf; tun_set_sndbuf(tun); -- cgit v1.2.3 From 79d73346ac05bc31f2e96f899c4e9aaaa616a8d4 Mon Sep 17 00:00:00 2001 From: Hongxu Jia Date: Tue, 31 Oct 2017 15:39:40 +0800 Subject: ide:ide-cd: fix kernel panic resulting from missing scsi_req_init Since we split the scsi_request out of struct request, while the standard prep_rq_fn builds 10 byte cmds, it missed to invoke scsi_req_init() to initialize certain fields of a scsi_request structure (.__cmd[], .cmd, .cmd_len and .sense_len but no other members of struct scsi_request). An example panic on virtual machines (qemu/virtualbox) to boot from IDE cdrom: ... [ 8.754381] Call Trace: [ 8.755419] blk_peek_request+0x182/0x2e0 [ 8.755863] blk_fetch_request+0x1c/0x40 [ 8.756148] ? ktime_get+0x40/0xa0 [ 8.756385] do_ide_request+0x37d/0x660 [ 8.756704] ? cfq_group_service_tree_add+0x98/0xc0 [ 8.757011] ? cfq_service_tree_add+0x1e5/0x2c0 [ 8.757313] ? ktime_get+0x40/0xa0 [ 8.757544] __blk_run_queue+0x3d/0x60 [ 8.757837] queue_unplugged+0x2f/0xc0 [ 8.758088] blk_flush_plug_list+0x1f4/0x240 [ 8.758362] blk_finish_plug+0x2c/0x40 ... [ 8.770906] RIP: ide_cdrom_prep_fn+0x63/0x180 RSP: ffff92aec018bae8 [ 8.772329] ---[ end trace 6408481e551a85c9 ]--- ... Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request") Signed-off-by: Hongxu Jia Signed-off-by: Jens Axboe --- drivers/ide/ide-cd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 81e18f9628d0..a7355ab3bb22 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1328,6 +1328,7 @@ static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq) unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9); struct scsi_request *req = scsi_req(rq); + scsi_req_init(req); memset(req->cmd, 0, BLK_MAX_CDB); if (rq_data_dir(rq) == READ) -- cgit v1.2.3