On 25/03/2023 2:49 am, Marek Marczykowski-Górecki wrote:
> diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
> index 9c82bf9b4ec2..9293009a4075 100644
> --- a/xen/arch/x86/hvm/vmsi.c
> +++ b/xen/arch/x86/hvm/vmsi.c
> @@ -438,6 +438,152 @@ static const struct hvm_io_ops msixtbl_mmio_ops = {
> .write = _msixtbl_write,
> };
>
> +static void __iomem *msixtbl_page_handler_get_hwaddr(
> + const struct domain *d,
> + uint64_t address,
> + bool write)
> +{
> + const struct pci_dev *pdev = NULL;
> + const struct msixtbl_entry *entry;
> + int adj_type;
> +
> + rcu_read_lock(&msixtbl_rcu_lock);
> + /*
> + * Check if it's on the same page as the end of the MSI-X table, but
> + * outside of the table itself.
> + */
> + list_for_each_entry( entry, &d->arch.hvm.msixtbl_list, list )
> + {
> + if ( PFN_DOWN(address) == PFN_DOWN(entry->gtable) &&
> + address < entry->gtable )
> + {
> + adj_type = ADJ_IDX_FIRST;
> + pdev = entry->pdev;
> + break;
> + }
> + if ( PFN_DOWN(address) == PFN_DOWN(entry->gtable + entry->table_len)
> &&
> + address >= entry->gtable + entry->table_len )
> + {
> + adj_type = ADJ_IDX_LAST;
> + pdev = entry->pdev;
> + break;
> + }
> + }
> + rcu_read_unlock(&msixtbl_rcu_lock);
> +
> + if ( !pdev )
> + return NULL;
> +
> + ASSERT(pdev->msix);
> +
> + if ( !pdev->msix->adj_access_table_idx[adj_type] )
> + {
> + gdprintk(XENLOG_WARNING,
> + "Page for adjacent MSI-X table access not initialized for
> %pp\n",
> + pdev);
One minor observation. &pdev->sbdf
Otherwise things will go wrong if sbdf ever moves from being the first
element in a pdev.
~Andrew