On 01.06.2022 14:59, Roger Pau Monné wrote:
> On Fri, May 27, 2022 at 01:17:35PM +0200, Jan Beulich wrote:
>> Page tables are used for two purposes after allocation: They either
>> start out all empty, or they are filled to replace a superpage.
>> Subsequently, to replace all empty or fully contiguous page tables,
>> contiguous sub-regions will be recorded within individual page tables.
>> Install the initial set of markers immediately after allocation. Make
>> sure to retain these markers when further populating a page table in
>> preparation for it to replace a superpage.
>>
>> The markers are simply 4-bit fields holding the order value of
>> contiguous entries. To demonstrate this, if a page table had just 16
>> entries, this would be the initial (fully contiguous) set of markers:
>>
>> index 0 1 2 3 4 5 6 7 8 9 A B C D E F
>> marker 4 0 1 0 2 0 1 0 3 0 1 0 2 0 1 0
>>
>> "Contiguous" here means not only present entries with successively
>> increasing MFNs, each one suitably aligned for its slot, and identical
>> attributes, but also a respective number of all non-present (zero except
>> for the markers) entries.
>>
>> Signed-off-by: Jan Beulich <[email protected]>
>> Reviewed-by: Kevin Tian <[email protected]>
>
> Reviewed-by: Roger Pau Monné <[email protected]>
Thanks.
>> @@ -538,11 +539,12 @@ int iommu_free_pgtables(struct domain *d
>> return 0;
>> }
>>
>> -struct page_info *iommu_alloc_pgtable(struct domain_iommu *hd)
>> +struct page_info *iommu_alloc_pgtable(struct domain_iommu *hd,
>> + uint64_t contig_mask)
>> {
>> unsigned int memflags = 0;
>> struct page_info *pg;
>> - void *p;
>> + uint64_t *p;
>>
>> #ifdef CONFIG_NUMA
>> if ( hd->node != NUMA_NO_NODE )
>> @@ -554,7 +556,29 @@ struct page_info *iommu_alloc_pgtable(st
>> return NULL;
>>
>> p = __map_domain_page(pg);
>> - clear_page(p);
>> +
>> + if ( contig_mask )
>> + {
>> + /* See pt-contig-markers.h for a description of the marker scheme.
>> */
>> + unsigned int i, shift = find_first_set_bit(contig_mask);
>> +
>> + ASSERT((CONTIG_LEVEL_SHIFT & (contig_mask >> shift)) ==
>> CONTIG_LEVEL_SHIFT);
>> +
>> + p[0] = (CONTIG_LEVEL_SHIFT + 0ull) << shift;
>> + p[1] = 0;
>> + p[2] = 1ull << shift;
>> + p[3] = 0;
>> +
>> + for ( i = 4; i < PAGE_SIZE / 8; i += 4 )
>
> FWIW, you could also use sizeof(*p) instead of hardcoding 8.
Indeed. Changed.
Jan