[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v9 15/16] xen/arm: vpci: check guest range


  • To: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • From: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
  • Date: Tue, 26 Sep 2023 11:27:48 -0400
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=citrix.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MEzqKmuwoHB5XNbcaO9bs9bXpXVIreUDVmcaDQLXX8I=; b=mXCRJu/QohT8aR7WaOV7+OqZ2MJVKbjOCF+oM9dhKuT1ZjKdXj2o3LZglP2NrEx1y+ZpCH4bQzg5LcVLqV07fYZYBYmDm+DDYDJp4GlNfmSfUeVowQKnSzQC3O5Tl5GTlp2NIxOFe2nPLH9XbAvnFszISzxmHYWA+FQ23FOP+N3G5P+jLQPoS/0sGnpbX826QnQ2lONDHkJaEBsH11hyl8vk88dXUbLT8zLsEfITl1KwGEMbBJXD5cvgwiNRUjMQPf4wCc+PElqCvSrtd8fKRHXJ/hi2RMwQdTqR9cgJNfRHWAsl79dy019Mz3na41yURjYgFHbCB765kak7oonl3A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kqp8DU3Aj3wH6hqLLNZ1kyo//c1Lpawbtu+NRgM+6i3LQZgBiSc8B4PGwAP4dD3+q5i5jf1ZXv0DLz/quQ07PeF/oHTJJ2U6VxUyZaNHKrNq/b+8vQqi3v/QwwedS9WFFDwOlBcpl0GAXsaVl8JzQyz7u9kaOR6gv9wC11XW4kBCNhpj01hrdTBkn0KPDerqayhtNLK/WJBJrSRXY92cSSQ49sH8oCvgx7+msfmriAKppNya7zgFYofjft+T0xkhMYJVIAx1IKFq4lWEF6+rvB+AYW4hFwKvqxLG1g2RVzfKDVvNZo+KWoC5+SKtN58WNqS12hofz+jgEjW8qMzaTg==
  • Cc: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Tue, 26 Sep 2023 15:28:13 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 9/26/23 04:07, Roger Pau Monné wrote:
> On Mon, Sep 25, 2023 at 05:49:00PM -0400, Stewart Hildebrand wrote:
>> On 9/22/23 04:44, Roger Pau Monné wrote:
>>> On Tue, Aug 29, 2023 at 11:19:47PM +0000, Volodymyr Babchuk wrote:
>>>> From: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
>>>>
>>>> Skip mapping the BAR if it is not in a valid range.
>>>>
>>>> Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
>>>> ---
>>>>  xen/drivers/vpci/header.c | 9 +++++++++
>>>>  1 file changed, 9 insertions(+)
>>>>
>>>> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
>>>> index 1d243eeaf9..dbabdcbed2 100644
>>>> --- a/xen/drivers/vpci/header.c
>>>> +++ b/xen/drivers/vpci/header.c
>>>> @@ -345,6 +345,15 @@ static int modify_bars(const struct pci_dev *pdev, 
>>>> uint16_t cmd, bool rom_only)
>>>>               bar->enabled == !!(cmd & PCI_COMMAND_MEMORY) )
>>>>              continue;
>>>>
>>>> +#ifdef CONFIG_ARM
>>>> +        if ( !is_hardware_domain(pdev->domain) )
>>>> +        {
>>>> +            if ( (start_guest < PFN_DOWN(GUEST_VPCI_MEM_ADDR)) ||
>>>> +                 (end_guest >= PFN_DOWN(GUEST_VPCI_MEM_ADDR + 
>>>> GUEST_VPCI_MEM_SIZE)) )
>>>> +                continue;
>>>> +        }
>>>> +#endif
>>>
>>> Hm, I think this should be in a hook similar to pci_check_bar() that
>>> can be implemented per-arch.
>>>
>>> IIRC at least on x86 we allow the guest to place the BARs whenever it
>>> wants, would such placement cause issues to the hypervisor on Arm?
>>
>> Hm. I wrote this patch in a hurry to make v9 of this series work on ARM. In 
>> my haste I also forgot about the prefetchable range starting at 
>> GUEST_VPCI_PREFETCH_MEM_ADDR, but that won't matter as we can probably throw 
>> this patch out.
>>
>> Now that I've had some more time to investigate, I believe the check in this 
>> patch is more or less redundant to the existing check in map_range() added 
>> in baa6ea700386 ("vpci: add permission checks to map_range()").
>>
>> The issue is that during initialization bar->guest_addr is zeroed, and this 
>> initial value of bar->guest_addr will fail the permissions check in 
>> map_range() and crash the domain. When the guest writes a new valid BAR, the 
>> old invalid address remains in the rangeset to be mapped. If we simply 
>> remove the old invalid BAR from the rangeset, that seems to fix the issue. 
>> So something like this:
> 
> It does seem to me we are missing a proper cleanup of the rangeset
> contents in some paths then.  In the above paragraph you mention "the
> old invalid address remains in the rangeset to be mapped", how does it
> get in there in the first place, and why is the rangeset not emptied
> if the mapping failed?

Back in ("vpci/header: handle p2m range sets per BAR") I added a v->domain == 
pdev->domain check near the top of vpci_process_pending() as you appropriately 
suggested.

+    if ( v->domain != pdev->domain )
+    {
+        read_unlock(&v->domain->pci_lock);
+        return false;
+    }

I have also reverted this patch ("xen/arm: vpci: check guest range").

The sequence of events leading to the old value remaining in the rangeset are:

# xl pci-assignable-add 01:00.0
drivers/vpci/vpci.c:vpci_deassign_device()
    deassign 0000:01:00.0 from d0
# grep pci domu.cfg
pci = [ "01:00.0" ]
# xl create domu.cfg
drivers/vpci/vpci.c:vpci_deassign_device()
    deassign 0000:01:00.0 from d[IO]
drivers/vpci/vpci.c:vpci_assign_device()
    assign 0000:01:00.0 to d1
    bar->guest_addr is initialized to zero because of the line: pdev->vpci = 
xzalloc(struct vpci);
drivers/vpci/header.c:init_bars()
drivers/vpci/header.c:modify_bars()
    BAR0: start 0xe0000, end 0xe000f, start_guest 0x0, end_guest 0xf
    The range { 0-f } is added to the BAR0 rangeset for d1
drivers/vpci/header.c:defer_map()
    raise_softirq(SCHEDULE_SOFTIRQ);
drivers/vpci/header.c:vpci_process_pending()
    vpci_process_pending() returns because v->domain != pdev->domain (i.e. d0 
!= d1)
    BAR0 rangeset still contains { 0-f }
xl create finishes

Then during domU boot, guest initializes BAR0:

drivers/vpci/header.c:guest_bar_write()
    bar->guest_addr = 0x23000000
drivers/vpci/header.c:modify_bars()
    BAR0: start 0xe0000, end 0xe000f, start_guest 0x23000, end_guest 0x2300f
    The d1 BAR0 rangeset now contains both { 0-f } and { 23000-2300f }
drivers/vpci/header.c:defer_map()
    raise_softirq(SCHEDULE_SOFTIRQ);
drivers/vpci/header.c:vpci_process_pending()
    rangeset_consume_ranges(bar->mem, map_range, &data);
drivers/vpci/header.c:map_range()
    The range { 0-f } fails the permissions check and we crash the domU (back 
in vpci_process_pending)



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.