On 20.11.2025 17:52, Oleksii Kurochko wrote:
> 
> On 11/20/25 4:47 PM, Jan Beulich wrote:
>> On 20.11.2025 16:38, Oleksii Kurochko wrote:
>>> On 11/18/25 7:58 AM, Jan Beulich wrote:
>>>> On 17.11.2025 20:51, Oleksii Kurochko wrote:
>>>>> On 11/12/25 12:49 PM, Jan Beulich wrote:
>>>>>> On 20.10.2025 17:58, Oleksii Kurochko wrote:
>>>>>>> +    if ( *md_pg )
>>>>>>> +        metadata = __map_domain_page(*md_pg);
>>>>>>> +
>>>>>>> +    if ( t < p2m_first_external )
>>>>>>> +    {
>>>>>>>             pte->pte |= MASK_INSR(t, P2M_TYPE_PTE_BITS_MASK);
>>>>>>>     -    return rc;
>>>>>>> +        if ( metadata )
>>>>>>> +            metadata[ctx->index].pte = p2m_invalid;
>>>>>> Shouldn't this be accompanied with a BUILD_BUG_ON(p2m_invalid), as 
>>>>>> otherwise
>>>>>> p2m_alloc_page()'s clearing of the page won't have the intended effect?
>>>>> I think that, at least, at the moment we are always explicitly set p2m 
>>>>> type and
>>>>> do not rely on that by default 0==p2m_invalid.
>>>> You don't, and ...
>>>>
>>>>> Just to be safe, I will add after "if ( metadata )" suggested
>>>>> BUILD_BUG_ON(p2m_invalid):
>>>>>           if ( metadata )
>>>>>               metadata[ctx->index].type = p2m_invalid;
>>>>>                   /*
>>>>>            * metadata.type is expected to be p2m_invalid (0) after the 
>>>>> page is
>>>>>            * allocated and zero-initialized in p2m_alloc_page().
>>>>>            */
>>>>>           BUILD_BUG_ON(p2m_invalid);
>>>>> ...
>>>> ... this leaves me with the impression that you didn't read my reply 
>>>> correctly.
>>>> p2m_alloc_page() clear the page, thus_implicitly_ setting all entries to
>>>> p2m_invalid. That's where the BUILD_BUG_ON() would want to go (the call 
>>>> site,
>>>> ftaod).
>>> I think I still don’t fully understand what the issue would be 
>>> if|p2m_invalid| were
>>> ever equal to 1 instead of 0 in the context of a metadata page.
>>>
>>> Yes, if|p2m_invalid| were 1, there would be a problem if someone tried to 
>>> read this
>>> metadata pagebefore it was assigned any type. They would find a value of 0, 
>>> which
>>> corresponds to a valid type rather than to|p2m_invalid|, as one might 
>>> expect.
>>> However, I’m not sure I currently see a scenario in which the metadata page 
>>> would
>>> be read before being initialized.
>> Are you sure walks can only happen for GFNs that were set up? What you need 
>> to
>> do walks on is under guest control, after all.
> 
> If a GFN lies within the range[p2m->lowest_mapped_gfn, p2m->max_mapped_gfn], 
> then
> |p2m_set_entry()| must already have been called for this GFN.

No. All you know from the pre-condition is that p2m_set_entry() was called for 
the
lowest and highest GFNs in that range.

Jan

> This means that either
> - a metadata page has been created and its entry filled with the appropriate 
> type, or
> - no metadata page was needed and the type was stored directly in|pte->pte|
> 
> For a GFN outside the range(p2m->lowest_mapped_gfn, p2m->max_mapped_gfn),
> |p2m_get_entry()| will not even attempt a walk because of the boundary checks:
>      static mfn_t p2m_get_entry(struct p2m_domain *p2m, gfn_t gfn,
>                                 p2m_type_t *t,
>                                 unsigned int *page_order)
>      ...
>          if ( check_outside_boundary(p2m, gfn, p2m->lowest_mapped_gfn, true,
>                                      &level) )
>              goto out;
>      
>          if ( check_outside_boundary(p2m, gfn, p2m->max_mapped_gfn, false, 
> &level) )
>              goto out;
> 
> If I am misunderstanding something and there are other cases where a walk can 
> occur for
> GFNs that were never set up, then such GFNs would have neither an allocated 
> metadata
> page nor a type stored in|pte->pte|, which looks like we are in trouble.
> 
> ~ Oleksii
> 


Reply via email to