mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
iommu/io-pgtable-arm: Simplify level indexing
The nature of the LPAE format means that data->pg_shift is always redundant with data->bits_per_level, since they represent the size of a page and the number of PTEs per page respectively, and the size of a PTE is constant. Thus it works out more efficient to only store the latter, and derive the former via a trivial addition where necessary. Signed-off-by: Robin Murphy <robin.murphy@arm.com> [will: Reworked granule check in iopte_to_paddr()] Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
c79278c185
commit
5fb190b0b5
1 changed files with 13 additions and 16 deletions
|
@ -36,10 +36,11 @@
|
|||
* in a virtual address mapped by the pagetable in d.
|
||||
*/
|
||||
#define ARM_LPAE_LVL_SHIFT(l,d) \
|
||||
(((ARM_LPAE_MAX_LEVELS - 1 - (l)) * (d)->bits_per_level) + \
|
||||
(d)->pg_shift)
|
||||
(((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level) + \
|
||||
ilog2(sizeof(arm_lpae_iopte)))
|
||||
|
||||
#define ARM_LPAE_GRANULE(d) (1UL << (d)->pg_shift)
|
||||
#define ARM_LPAE_GRANULE(d) \
|
||||
(sizeof(arm_lpae_iopte) << (d)->bits_per_level)
|
||||
#define ARM_LPAE_PGD_SIZE(d) \
|
||||
(sizeof(arm_lpae_iopte) << (d)->pgd_bits)
|
||||
|
||||
|
@ -55,9 +56,7 @@
|
|||
((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1))
|
||||
|
||||
/* Calculate the block/page mapping size at level l for pagetable in d. */
|
||||
#define ARM_LPAE_BLOCK_SIZE(l,d) \
|
||||
(1ULL << (ilog2(sizeof(arm_lpae_iopte)) + \
|
||||
((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level)))
|
||||
#define ARM_LPAE_BLOCK_SIZE(l,d) (1ULL << ARM_LPAE_LVL_SHIFT(l,d))
|
||||
|
||||
/* Page table bits */
|
||||
#define ARM_LPAE_PTE_TYPE_SHIFT 0
|
||||
|
@ -175,8 +174,7 @@ struct arm_lpae_io_pgtable {
|
|||
|
||||
int pgd_bits;
|
||||
int start_level;
|
||||
unsigned long pg_shift;
|
||||
unsigned long bits_per_level;
|
||||
int bits_per_level;
|
||||
|
||||
void *pgd;
|
||||
};
|
||||
|
@ -206,7 +204,7 @@ static phys_addr_t iopte_to_paddr(arm_lpae_iopte pte,
|
|||
{
|
||||
u64 paddr = pte & ARM_LPAE_PTE_ADDR_MASK;
|
||||
|
||||
if (data->pg_shift < 16)
|
||||
if (ARM_LPAE_GRANULE(data) < SZ_64K)
|
||||
return paddr;
|
||||
|
||||
/* Rotate the packed high-order bits back to the top */
|
||||
|
@ -742,9 +740,8 @@ static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
|
|||
static struct arm_lpae_io_pgtable *
|
||||
arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
|
||||
{
|
||||
unsigned long va_bits;
|
||||
struct arm_lpae_io_pgtable *data;
|
||||
int levels;
|
||||
int levels, va_bits, pg_shift;
|
||||
|
||||
arm_lpae_restrict_pgsizes(cfg);
|
||||
|
||||
|
@ -766,10 +763,10 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
|
|||
if (!data)
|
||||
return NULL;
|
||||
|
||||
data->pg_shift = __ffs(cfg->pgsize_bitmap);
|
||||
data->bits_per_level = data->pg_shift - ilog2(sizeof(arm_lpae_iopte));
|
||||
pg_shift = __ffs(cfg->pgsize_bitmap);
|
||||
data->bits_per_level = pg_shift - ilog2(sizeof(arm_lpae_iopte));
|
||||
|
||||
va_bits = cfg->ias - data->pg_shift;
|
||||
va_bits = cfg->ias - pg_shift;
|
||||
levels = DIV_ROUND_UP(va_bits, data->bits_per_level);
|
||||
data->start_level = ARM_LPAE_MAX_LEVELS - levels;
|
||||
|
||||
|
@ -1135,9 +1132,9 @@ static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops)
|
|||
|
||||
pr_err("cfg: pgsize_bitmap 0x%lx, ias %u-bit\n",
|
||||
cfg->pgsize_bitmap, cfg->ias);
|
||||
pr_err("data: %d levels, 0x%zx pgd_size, %lu pg_shift, %lu bits_per_level, pgd @ %p\n",
|
||||
pr_err("data: %d levels, 0x%zx pgd_size, %u pg_shift, %u bits_per_level, pgd @ %p\n",
|
||||
ARM_LPAE_MAX_LEVELS - data->start_level, ARM_LPAE_PGD_SIZE(data),
|
||||
data->pg_shift, data->bits_per_level, data->pgd);
|
||||
ilog2(ARM_LPAE_GRANULE(data)), data->bits_per_level, data->pgd);
|
||||
}
|
||||
|
||||
#define __FAIL(ops, i) ({ \
|
||||
|
|
Loading…
Reference in a new issue