Re: [PATCH v3 01/15] genpt: Generic Page Table base API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jason,

On Mon, Jun 16, 2025 at 03:06:04PM -0300, Jason Gunthorpe wrote:
> The generic API is intended to be separated from the implementation of
> page table algorithms. It contains only accessors for walking and
> manipulating the table and helpers that are useful for building an
> implementation. Memory management is not in the generic API, but part of
> the implementation.
> 
> Using a multi-compilation approach the implementation module would include
> headers in this order:
> 
>   common.h
>   defs_FMT.h
>   pt_defs.h
>   FMT.h
>   pt_common.h
>   IMPLEMENTATION.h
> 
> Where each compilation unit would have a combination of FMT and
> IMPLEMENTATION to produce a per-format per-implementation module.
> 
> The API is designed so that the format headers have minimal logic, and
> default implementations are provided if the format doesn't include one.
> 
> Generally formats provide their code via an inline function using the
> pattern:
> 
>   static inline FMTpt_XX(..) {}
>   #define pt_XX FMTpt_XX
> 
> The common code then enforces a function signature so that there is no
> drift in function arguments, or accidental polymorphic functions (as has
> been slightly troublesome in mm). Use of function-like #defines are
> avoided in the format even though many of the functions are small enough.
> 
> Provide kdocs for the API surface.
> 
> This is enough to implement the 8 initial format variations with all of
> their features:
>  * Entries comprised of contiguous blocks of IO PTEs for larger page
>    sizes (AMDv1, ARMv8)
>  * Multi-level tables, up to 6 levels. Runtime selected top level
>  * Runtime variable table level size (ARM's concatenated tables)
>  * Expandable top level (AMDv1)
>  * Optional leaf entries at any level
>  * 32 bit/64 bit virtual and output addresses, using every bit
>  * Sign extended addressing (x86)
>  * Dirty tracking
> 
> A basic simple format takes about 200 lines to declare the require inline
> functions.
> 
> Tested-by: Alejandro Jimenez <alejandro.j.jimenez@xxxxxxxxxx>
> Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
> ---

../..

> +static __always_inline struct pt_range _pt_top_range(struct pt_common *common,
> +						     uintptr_t top_of_table)
> +{
> +	struct pt_range range = {
> +		.common = common,
> +		.top_table =
> +			(struct pt_table_p *)(top_of_table &
> +					      ~(uintptr_t)PT_TOP_LEVEL_MASK),
> +#ifdef PT_FIXED_TOP_LEVEL

I am not able to find definition for above macro.
Was it intentional to leave the macro 'PT_FIXED_TOP_LEVEL' undefined?

Thanks,
Ankit

> +		.top_level = PT_FIXED_TOP_LEVEL,
> +#else
> +		.top_level = top_of_table % (1 << PT_TOP_LEVEL_BITS),
> +#endif
> +	};
> +	struct pt_state pts = { .range = &range, .level = range.top_level };
> +	unsigned int max_vasz_lg2;
> +
> +	max_vasz_lg2 = common->max_vasz_lg2;
> +	if (pt_feature(common, PT_FEAT_DYNAMIC_TOP) &&
> +	    pts.level != PT_MAX_TOP_LEVEL)
> +		max_vasz_lg2 = min_t(unsigned int, common->max_vasz_lg2,
> +				     pt_num_items_lg2(&pts) +
> +					     pt_table_item_lg2sz(&pts));
> +
> +	/*
> +	 * The top range will default to the lower region only with sign extend.
> +	 */
> +	range.max_vasz_lg2 = max_vasz_lg2;
> +	if (pt_feature(common, PT_FEAT_SIGN_EXTEND))
> +		max_vasz_lg2--;
> +
> +	range.va = fvalog2_set_mod(pt_full_va_prefix(common), 0, max_vasz_lg2);
> +	range.last_va =
> +		fvalog2_set_mod_max(pt_full_va_prefix(common), max_vasz_lg2);
> +	return range;
> +}
> -- 
> 2.43.0
> 




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux