On 15/01/2021 13:26, Jan Beulich wrote:
> On 15.01.2021 14:09, Andrew Cooper wrote:
>> On 14/01/2021 15:23, Jan Beulich wrote:
>>> @@ -1052,19 +1063,19 @@ map_grant_ref(
>>>      shah = shared_entry_header(rgt, ref);
>>>      act = active_entry_acquire(rgt, ref);
>>>  
>>> -    /* Make sure we do not access memory speculatively */
>>> -    status = evaluate_nospec(rgt->gt_version == 1) ? &shah->flags
>>> -                                                 : &status_entry(rgt, ref);
>>> -
>>>      /* If already pinned, check the active domid and avoid refcnt 
>>> overflow. */
>>>      if ( act->pin &&
>>>           ((act->domid != ld->domain_id) ||
>>> -          (act->pin & 0x80808080U) != 0 ||
>>> +          (act->pin & (pin_incr << (GNTPIN_cntr_width - 1))) ||
>> This, I'm afraid, is not an improvement.  What we want is:
>>
>> #define GNTPIN_overflow_mask 0x80808080U
>>
>> The reason for checking all at once is defence in depth (not strictly
>> necessary, but also not a problem),
> How is this not a problem? There is absolutely no reason to
> reject a request just because some unrelated field may be
> about to overflow. In fact I now think that I didn't even
> leverage the full potential - the "act->pin != old_pin" check
> could also be relaxed this way, I think. Just that it sits on
> a path we probably don't really care about very much.

Hmm - I see your point.  I'd missed the fact that a previous operation
could leave this timebomb waiting for us.  (Probably wants a note to
this effect in the commit message).

However we go about fixing it, "pin_incr << (GNTPIN_cntr_width - 1)" is
too obscure IMO.  Perhaps all we need is a

#define GNTPIN_overflow_mask(x) ((x) << (GNTPIN_cntr_width - 1))

but it does occur to me that this logic only works to being with when
pin_incr is strictly 1 in the relevant bytes.

~Andrew

Reply via email to