From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934126AbdJQIGD (ORCPT ); Tue, 17 Oct 2017 04:06:03 -0400 Received: from smtpbgbr2.qq.com ([54.207.22.56]:39387 "EHLO smtpbgbr2.qq.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934080AbdJQIFJ (ORCPT ); Tue, 17 Oct 2017 04:05:09 -0400 X-QQ-mid: bizesmtp2t1508227425tpvm6avuo X-QQ-SSF: 01100000008000F0FOF0B00A0000000 X-QQ-FEAT: EcrU/iQvn3uxvvTZDzIEobhhT1q142jIIOKfMAieF5MJqEEC1On1PTI9KNPhU qQoF1hXr87xkEb4tRYLHfu04Fav1hfIEGVvddCa203leGuzeoGamHAVoTJhLhu/8MAAkc92 duLRwdAdb+OWVOYXvqcSDz1RiSjKa2ll/ZIV6r/txf013AHLoitJL7yDbkbDZvqNkEWK4fM v5NQxGI9MDAlJN3OZKKfuNj577OkiArRpZYcn1V3ii6WeRCZ7p76qH7e8Ym+OSwCXx98tUk oBJWsvUk38bVK+sigeAcvNPdOQe/cxCg6vBa32kAR6xoqk X-QQ-GoodBg: 0 From: Huacai Chen To: Christoph Hellwig Cc: Marek Szyprowski , Robin Murphy , Andrew Morton , Fuxin Zhang , linux-kernel@vger.kernel.org, Ralf Baechle , James Hogan , linux-mips@linux-mips.org, "James E . J . Bottomley" , "Martin K . Petersen" , linux-scsi@vger.kernel.org, Tejun Heo , linux-ide@vger.kernel.org, Huacai Chen , stable@vger.kernel.org Subject: [PATCH V8 5/5] libata: Align DMA buffer to dma_get_cache_alignment() Date: Tue, 17 Oct 2017 16:05:42 +0800 Message-Id: <1508227542-13165-5-git-send-email-chenhc@lemote.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1508227542-13165-1-git-send-email-chenhc@lemote.com> References: <1508227542-13165-1-git-send-email-chenhc@lemote.com> X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:lemote.com:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In non-coherent DMA mode, kernel uses cache flushing operations to maintain I/O coherency, so in ata_do_dev_read_id() the DMA buffer should be aligned to ARCH_DMA_MINALIGN. Otherwise, If a DMA buffer and a kernel structure share a same cache line, and if the kernel structure has dirty data, cache_invalidate (no writeback) will cause data corruption. Cc: stable@vger.kernel.org Signed-off-by: Huacai Chen --- drivers/ata/libata-core.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ee4c1ec..e134955 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1833,8 +1833,19 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev) unsigned int ata_do_dev_read_id(struct ata_device *dev, struct ata_taskfile *tf, u16 *id) { - return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, - id, sizeof(id[0]) * ATA_ID_WORDS, 0); + u16 *devid; + int res, size = sizeof(u16) * ATA_ID_WORDS; + + if (IS_ALIGNED((unsigned long)id, dma_get_cache_alignment(&dev->tdev))) + res = ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, id, size, 0); + else { + devid = kmalloc(size, GFP_KERNEL); + res = ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, devid, size, 0); + memcpy(id, devid, size); + kfree(devid); + } + + return res; } /** -- 2.7.0