Hi,
On 21/02/2022 10:22, Julien Grall wrote:
@@ -1333,21 +1386,34 @@ static int xen_pt_update(unsigned long virt,
while ( left )
{
unsigned int order, level;
+ unsigned int nr_contig;
+ unsigned int new_flags;
level = xen_pt_mapping_level(vfn, mfn, left, flags);
order = XEN_PT_LEVEL_ORDER(level);
ASSERT(left >= BIT(order, UL));
- rc = xen_pt_update_entry(root, pfn_to_paddr(vfn), mfn, level, flags);
- if ( rc )
- break;
+ /*
+ * Check if we can set the contiguous mapping and update the
+ * flags accordingly.
+ */
+ nr_contig = xen_pt_check_contig(vfn, mfn, level, left, flags);
+ new_flags = flags | ((nr_contig > 1) ? _PAGE_CONTIG : 0);
- vfn += 1U << order;
- if ( !mfn_eq(mfn, INVALID_MFN) )
- mfn = mfn_add(mfn, 1U << order);
+ for ( ; nr_contig > 0; nr_contig-- )
+ {
+ rc = xen_pt_update_entry(root, pfn_to_paddr(vfn), mfn, level,
+ new_flags);
+ if ( rc )
+ break;
- left -= (1U << order);
+ vfn += 1U << order;
+ if ( !mfn_eq(mfn, INVALID_MFN) )
+ mfn = mfn_add(mfn, 1U << order);
+
+ left -= (1U << order);
+ }
I forgot to add:
if ( rc )
break;
Without it, the outer loop will never exit in case of an error.
Cheers,
--
Julien Grall