BACKPORT: FROMLIST: iommu/io-pgtable: Add configure() operation

Allow IOMMU drivers to create the io-pgtable configuration without
allocating any tables. This will be used by the SMMUv3-KVM driver to
initialize a config and pass it to KVM.

Link: https://lore.kernel.org/all/20241212180423.1578358-4-smostafa@google.com/

Bug: 357781595
Bug: 384432312

Change-Id: I6e6aed0f7e2c57d07bd15519569a886d07330e60
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
Jean-Philippe Brucker
2024-12-12 18:03:27 +00:00
committed by Mostafa Saleh
parent eebbcde477
commit efe0081240
3 changed files with 46 additions and 0 deletions
+16
View File
@@ -194,6 +194,13 @@ out_free_data:
return NULL;
}
static int arm_64_lpae_configure_s1(struct io_pgtable_cfg *cfg)
{
struct arm_lpae_io_pgtable data = {};
return arm_lpae_init_pgtable_s1(cfg, &data);
}
static struct io_pgtable *
arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
{
@@ -225,6 +232,13 @@ out_free_data:
return NULL;
}
static int arm_64_lpae_configure_s2(struct io_pgtable_cfg *cfg)
{
struct arm_lpae_io_pgtable data = {};
return arm_lpae_init_pgtable_s2(cfg, &data);
}
static struct io_pgtable *
arm_32_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
{
@@ -312,12 +326,14 @@ struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
.caps = IO_PGTABLE_CAP_CUSTOM_ALLOCATOR,
.alloc = arm_64_lpae_alloc_pgtable_s1,
.free = arm_lpae_free_pgtable,
.configure = arm_64_lpae_configure_s1,
};
struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns = {
.caps = IO_PGTABLE_CAP_CUSTOM_ALLOCATOR,
.alloc = arm_64_lpae_alloc_pgtable_s2,
.free = arm_lpae_free_pgtable,
.configure = arm_64_lpae_configure_s2,
};
struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns = {
+15
View File
@@ -99,3 +99,18 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops)
io_pgtable_init_table[iop->fmt]->free(iop);
}
EXPORT_SYMBOL_GPL(free_io_pgtable_ops);
int io_pgtable_configure(struct io_pgtable_cfg *cfg)
{
const struct io_pgtable_init_fns *fns;
if (cfg->fmt >= IO_PGTABLE_NUM_FMTS)
return -EINVAL;
fns = io_pgtable_init_table[cfg->fmt];
if (!fns || !fns->configure)
return -EOPNOTSUPP;
return fns->configure(cfg);
}
EXPORT_SYMBOL_GPL(io_pgtable_configure);
+15
View File
@@ -49,6 +49,7 @@ struct iommu_flush_ops {
/**
* struct io_pgtable_cfg - Configuration data for a set of page tables.
*
* @fmt: Format used for these page tables
* @quirks: A bitmap of hardware quirks that require some special
* action by the low-level page table allocator.
* @pgsize_bitmap: A bitmap of page sizes supported by this set of page
@@ -62,6 +63,7 @@ struct iommu_flush_ops {
* page table walker.
*/
struct io_pgtable_cfg {
enum io_pgtable_fmt fmt;
/*
* IO_PGTABLE_QUIRK_ARM_NS: (ARM formats) Set NS and NSTABLE bits in
* stage 1 PTEs, for hardware which insists on validating them
@@ -241,6 +243,17 @@ struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
*/
void free_io_pgtable_ops(struct io_pgtable_ops *ops);
/**
* io_pgtable_configure - Create page table config
*
* @cfg: The page table configuration.
*
* Initialize @cfg in the same way as alloc_io_pgtable_ops(), without allocating
* anything.
*
* Not all io_pgtable drivers implement this operation.
*/
int io_pgtable_configure(struct io_pgtable_cfg *cfg);
/*
* Internal structures for page table allocator implementations.
@@ -301,11 +314,13 @@ enum io_pgtable_caps {
*
* @alloc: Allocate a set of page tables described by cfg.
* @free: Free the page tables associated with iop.
* @configure: Create the configuration without allocating anything. Optional.
* @caps: Combination of @io_pgtable_caps flags encoding the backend capabilities.
*/
struct io_pgtable_init_fns {
struct io_pgtable *(*alloc)(struct io_pgtable_cfg *cfg, void *cookie);
void (*free)(struct io_pgtable *iop);
int (*configure)(struct io_pgtable_cfg *cfg);
u32 caps;
};