|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2.1 2/2] vpci/msix: fix PBA accesses
On 01.03.2022 10:08, Roger Pau Monné wrote:
> On Tue, Mar 01, 2022 at 09:46:13AM +0100, Jan Beulich wrote:
>> On 26.02.2022 11:05, Roger Pau Monne wrote:
>>> --- a/xen/drivers/vpci/msix.c
>>> +++ b/xen/drivers/vpci/msix.c
>>> @@ -198,8 +198,13 @@ static int cf_check msix_read(
>>> if ( !access_allowed(msix->pdev, addr, len) )
>>> return X86EMUL_OKAY;
>>>
>>> + spin_lock(&msix->pdev->vpci->lock);
>>> if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) )
>>> {
>>> + struct vpci *vpci = msix->pdev->vpci;
>>> + paddr_t base = vmsix_table_addr(vpci, VPCI_MSIX_PBA);
>>> + unsigned int idx = addr - base;
>>> +
>>> /*
>>> * Access to PBA.
>>> *
>>> @@ -207,25 +212,43 @@ static int cf_check msix_read(
>>> * guest address space. If this changes the address will need to be
>>> * translated.
>>> */
>>> +
>>> + if ( !msix->pba )
>>> + {
>>> + msix->pba = ioremap(base, vmsix_table_size(vpci,
>>> VPCI_MSIX_PBA));
>>> + if ( !msix->pba )
>>> + {
>>> + /*
>>> + * If unable to map the PBA return all 1s (all pending):
>>> it's
>>> + * likely better to trigger spurious events than drop them.
>>> + */
>>> + spin_unlock(&vpci->lock);
>>> + gprintk(XENLOG_WARNING,
>>> + "%pp: unable to map MSI-X PBA, report all
>>> pending\n",
>>> + msix->pdev);
>>> + return X86EMUL_OKAY;
>>
>> Hmm, this may report more set bits than there are vectors. Which is
>> probably fine, but the comment may want adjusting a little to make
>> clear this is understood and meant to be that way.
>
> Yes, it could return more bits than vectors, but that area is also
> part of the PBA (as the end is aligned to 8 bytes). I will adjust the
> comment.
>
>>> + }
>>> + }
>>
>> Imo it would make sense to limit the locked region to around just this
>> check-and-map logic. There's no need for ...
>>
>>> switch ( len )
>>> {
>>> case 4:
>>> - *data = readl(addr);
>>> + *data = readl(msix->pba + idx);
>>> break;
>>>
>>> case 8:
>>> - *data = readq(addr);
>>> + *data = readq(msix->pba + idx);
>>> break;
>>>
>>> default:
>>> ASSERT_UNREACHABLE();
>>> break;
>>> }
>>> + spin_unlock(&vpci->lock);
>>
>> ... the actual access to happen under lock, as you remove the mapping
>> only when the device is being removed. I'm inclined to suggest making
>> a helper function, which does an unlocked check, then the ioremap(),
>> then takes the lock and re-checks whether the field's still NULL, and
>> either installs the mapping or (after unlocking) iounmap()s it.
>
> I'm fine with dropping the lock earlier, but I'm not sure there's much
> point in placing this in a separate helper, as it's the mapping of at
> most 2 pages (PBA is 2048 bytes in size, 64bit aligned).
>
> I guess you are suggesting this in preparation for adding support to
> access the non PBA area falling into the same page(s)?
Not just. The write path wants to use the same logic, and with it
becoming a little more involved I think it would be better to have it
in just one place.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |