提交 7cd96743 编写于 作者: H Hector Martin 提交者: Yongqiang Liu

iommu/io-pgtable-arm: Fix table descriptor paddr formatting

stable inclusion
from linux-4.19.226
commit 4208239d748b5a8f32d5c2323d6f385dcb7f9b9e

--------------------------------

[ Upstream commit 9abe2ac8 ]

Table descriptors were being installed without properly formatting the
address using paddr_to_iopte, which does not match up with the
iopte_deref in __arm_lpae_map. This is incorrect for the LPAE pte
format, as it does not handle the high bits properly.

This was found on Apple T6000 DARTs, which require a new pte format
(different shift); adding support for that to
paddr_to_iopte/iopte_to_paddr caused it to break badly, as even <48-bit
addresses would end up incorrect in that case.

Fixes: 6c89928f ("iommu/io-pgtable-arm: Support 52-bit physical address")
Acked-by: NRobin Murphy <robin.murphy@arm.com>
Signed-off-by: NHector Martin <marcan@marcan.st>
Link: https://lore.kernel.org/r/20211120031343.88034-1-marcan@marcan.stSigned-off-by: NJoerg Roedel <jroedel@suse.de>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
Signed-off-by: NLaibin Qiu <qiulaibin@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 aed0db3a
...@@ -299,11 +299,12 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, ...@@ -299,11 +299,12 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table, static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
arm_lpae_iopte *ptep, arm_lpae_iopte *ptep,
arm_lpae_iopte curr, arm_lpae_iopte curr,
struct io_pgtable_cfg *cfg) struct arm_lpae_io_pgtable *data)
{ {
arm_lpae_iopte old, new; arm_lpae_iopte old, new;
struct io_pgtable_cfg *cfg = &data->iop.cfg;
new = __pa(table) | ARM_LPAE_PTE_TYPE_TABLE; new = paddr_to_iopte(__pa(table), data) | ARM_LPAE_PTE_TYPE_TABLE;
if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
new |= ARM_LPAE_PTE_NSTABLE; new |= ARM_LPAE_PTE_NSTABLE;
...@@ -354,7 +355,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, ...@@ -354,7 +355,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
if (!cptep) if (!cptep)
return -ENOMEM; return -ENOMEM;
pte = arm_lpae_install_table(cptep, ptep, 0, cfg); pte = arm_lpae_install_table(cptep, ptep, 0, data);
if (pte) if (pte)
__arm_lpae_free_pages(cptep, tblsz, cfg); __arm_lpae_free_pages(cptep, tblsz, cfg);
} else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) {
...@@ -513,7 +514,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, ...@@ -513,7 +514,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
__arm_lpae_init_pte(data, blk_paddr, pte, lvl, &tablep[i]); __arm_lpae_init_pte(data, blk_paddr, pte, lvl, &tablep[i]);
} }
pte = arm_lpae_install_table(tablep, ptep, blk_pte, cfg); pte = arm_lpae_install_table(tablep, ptep, blk_pte, data);
if (pte != blk_pte) { if (pte != blk_pte) {
__arm_lpae_free_pages(tablep, tablesz, cfg); __arm_lpae_free_pages(tablep, tablesz, cfg);
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册