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

Re: [PATCH] x86/vpci: fix handling of BAR overlaps with non-hole regions


  • To: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 15 May 2025 11:24:59 +0200
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Thu, 15 May 2025 09:25:23 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 15.05.2025 10:41, Roger Pau Monne wrote:
> For once the message printed when a BAR overlaps with a non-hole regions is
> not accurate on x86.  While the BAR won't be mapped by the vPCI logic, it
> is quite likely overlapping with a reserved region in the memory map, and
> already mapped as by default all reserved regions are identity mapped in
> the p2m.  Fix the message so it just warns about the overlap, without
> mentioning that the BAR won't be mapped, as this has caused confusion in
> the past.
> 
> Secondly, when an overlap is detected the BAR 'enabled' field is not set,
> hence other vPCI code that depends on it like vPCI MSI-X handling won't
> function properly, as it sees the BAR as disabled, even when memory
> decoding is enabled for the device and the BAR is likely mapped in the
> p2m.  Change the handling of BARs that overlap non-hole regions to instead
> remove any overlapped regions from the rangeset, so the resulting ranges to
> map just contain the hole regions.  This requires introducing a new
> pci_sanitize_bar_memory() that's implemented per-arch and sanitizes the
> address range to add to the p2m.
> 
> For x86 pci_sanitize_bar_memory() removes any regions present in the host
> memory map, for ARM this is currently left as a dummy handler to not change
> existing behavior.
> 
> Ultimately the above changes should fix the vPCI MSI-X handlers not working
> correctly when the BAR that contains the MSI-X table overlaps with a
> non-hole region, as then the 'enabled' BAR bit won't be set and the MSI-X
> traps won't handle accesses as expected.

While all of this reads plausible, I may need to look at this again later,
to hopefully grok the connections and implications.

> --- a/xen/arch/x86/include/asm/pci.h
> +++ b/xen/arch/x86/include/asm/pci.h
> @@ -2,6 +2,7 @@
>  #define __X86_PCI_H__
>  
>  #include <xen/mm.h>
> +#include <xen/rangeset.h>

Please don't, ...

> @@ -57,14 +58,7 @@ static always_inline bool is_pci_passthrough_enabled(void)
>  
>  void arch_pci_init_pdev(struct pci_dev *pdev);
>  
> -static inline bool pci_check_bar(const struct pci_dev *pdev,
> -                                 mfn_t start, mfn_t end)
> -{
> -    /*
> -     * Check if BAR is not overlapping with any memory region defined
> -     * in the memory map.
> -     */
> -    return is_memory_hole(start, end);
> -}
> +bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end);
> +int pci_sanitize_bar_memory(struct rangeset *r);

... all you need is a struct forward decl here.

> --- a/xen/arch/x86/pci.c
> +++ b/xen/arch/x86/pci.c
> @@ -98,3 +98,53 @@ int pci_conf_write_intercept(unsigned int seg, unsigned 
> int bdf,
>  
>      return rc;
>  }
> +
> +bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end)
> +{
> +    /*
> +     * Check if BAR is not overlapping with any memory region defined
> +     * in the memory map.
> +     */
> +    if ( !is_memory_hole(start, end) )
> +        gdprintk(XENLOG_WARNING,
> +                 "%pp: BAR at [%"PRI_mfn", %"PRI_mfn"] not in memory map 
> hole\n",
> +                 &pdev->sbdf, mfn_x(start), mfn_x(end));
> +
> +    /*
> +     * Unconditionally return true, pci_sanitize_bar_memory() will remove any
> +     * non-hole regions.
> +     */
> +    return true;
> +}
> +
> +/* Remove overlaps with any ranges defined in the host memory map. */
> +int pci_sanitize_bar_memory(struct rangeset *r)
> +{
> +    unsigned int i;
> +
> +    for ( i = 0; i < e820.nr_map; i++ )
> +    {
> +        const struct e820entry *entry = &e820.map[i];
> +        int rc;
> +
> +        if ( !entry->size )
> +            continue;
> +
> +        rc = rangeset_remove_range(r, PFN_DOWN(entry->addr),
> +                                   PFN_UP(entry->addr + entry->size - 1));
> +        if ( rc )
> +            return rc;

Perhaps better continue the loop in a best effort manner, only accumulating
the error to then ...

> +    }
> +
> +    return 0;
> +}

... return here?

Jan



 


Rackspace

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