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
|
@ -36,10 +36,11 @@
|
||||||
* in a virtual address mapped by the pagetable in d.
|
* in a virtual address mapped by the pagetable in d.
|
||||||
*/
|
*/
|
||||||
#define ARM_LPAE_LVL_SHIFT(l,d) \
|
#define ARM_LPAE_LVL_SHIFT(l,d) \
|
||||||
(((ARM_LPAE_MAX_LEVELS - 1 - (l)) * (d)->bits_per_level) + \
|
(((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level) + \
|
||||||
(d)->pg_shift)
|
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) \
|
#define ARM_LPAE_PGD_SIZE(d) \
|
||||||
(sizeof(arm_lpae_iopte) << (d)->pgd_bits)
|
(sizeof(arm_lpae_iopte) << (d)->pgd_bits)
|
||||||
|
|
||||||
|
@ -55,9 +56,7 @@
|
||||||
((1 << ((d)->bits_per_level + ARM_LPAE_PGD_IDX(l,d))) - 1))
|
((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. */
|
/* Calculate the block/page mapping size at level l for pagetable in d. */
|
||||||
#define ARM_LPAE_BLOCK_SIZE(l,d) \
|
#define ARM_LPAE_BLOCK_SIZE(l,d) (1ULL << ARM_LPAE_LVL_SHIFT(l,d))
|
||||||
(1ULL << (ilog2(sizeof(arm_lpae_iopte)) + \
|
|
||||||
((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level)))
|
|
||||||
|
|
||||||
/* Page table bits */
|
/* Page table bits */
|
||||||
#define ARM_LPAE_PTE_TYPE_SHIFT 0
|
#define ARM_LPAE_PTE_TYPE_SHIFT 0
|
||||||
|
@ -175,8 +174,7 @@ struct arm_lpae_io_pgtable {
|
||||||
|
|
||||||
int pgd_bits;
|
int pgd_bits;
|
||||||
int start_level;
|
int start_level;
|
||||||
unsigned long pg_shift;
|
int bits_per_level;
|
||||||
unsigned long bits_per_level;
|
|
||||||
|
|
||||||
void *pgd;
|
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;
|
u64 paddr = pte & ARM_LPAE_PTE_ADDR_MASK;
|
||||||
|
|
||||||
if (data->pg_shift < 16)
|
if (ARM_LPAE_GRANULE(data) < SZ_64K)
|
||||||
return paddr;
|
return paddr;
|
||||||
|
|
||||||
/* Rotate the packed high-order bits back to the top */
|
/* 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 *
|
static struct arm_lpae_io_pgtable *
|
||||||
arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
|
arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
|
||||||
{
|
{
|
||||||
unsigned long va_bits;
|
|
||||||
struct arm_lpae_io_pgtable *data;
|
struct arm_lpae_io_pgtable *data;
|
||||||
int levels;
|
int levels, va_bits, pg_shift;
|
||||||
|
|
||||||
arm_lpae_restrict_pgsizes(cfg);
|
arm_lpae_restrict_pgsizes(cfg);
|
||||||
|
|
||||||
|
@ -766,10 +763,10 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
|
||||||
if (!data)
|
if (!data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
data->pg_shift = __ffs(cfg->pgsize_bitmap);
|
pg_shift = __ffs(cfg->pgsize_bitmap);
|
||||||
data->bits_per_level = data->pg_shift - ilog2(sizeof(arm_lpae_iopte));
|
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);
|
levels = DIV_ROUND_UP(va_bits, data->bits_per_level);
|
||||||
data->start_level = ARM_LPAE_MAX_LEVELS - levels;
|
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",
|
pr_err("cfg: pgsize_bitmap 0x%lx, ias %u-bit\n",
|
||||||
cfg->pgsize_bitmap, cfg->ias);
|
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),
|
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) ({ \
|
#define __FAIL(ops, i) ({ \
|
||||||
|
|
Loading…
Reference in New Issue