|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v10 07/17] vpci/header: implement guest BAR register handlers
On 10/12/23 18:09, Volodymyr Babchuk wrote:
> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
> index 33db58580c..40d1a07ada 100644
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -477,6 +477,74 @@ static void cf_check bar_write(
> pci_conf_write32(pdev->sbdf, reg, val);
> }
>
> +static void cf_check guest_bar_write(const struct pci_dev *pdev,
> + unsigned int reg, uint32_t val, void
> *data)
> +{
> + struct vpci_bar *bar = data;
> + bool hi = false;
> + uint64_t guest_addr = bar->guest_addr;
This initialization is using the initial value of bar ...
> +
> + if ( bar->type == VPCI_BAR_MEM64_HI )
> + {
> + ASSERT(reg > PCI_BASE_ADDRESS_0);
> + bar--;
... but here bar is decremented ...
> + hi = true;
> + }
> + else
> + {
> + val &= PCI_BASE_ADDRESS_MEM_MASK;
> + }
> +
... so to ensure a consistent state, the initialization should be moved here.
> + guest_addr &= ~(0xffffffffULL << (hi ? 32 : 0));
> + guest_addr |= (uint64_t)val << (hi ? 32 : 0);
> +
> + /* Allow guest to size BAR correctly */
> + guest_addr &= ~(bar->size - 1);
> +
> + /*
> + * Make sure that the guest set address has the same page offset
> + * as the physical address on the host or otherwise things won't work as
> + * expected.
> + */
> + if ( guest_addr != ~(bar->size -1 ) &&
Should this sizing check only apply to the lower 32 bits, or take "hi" into
account?
For reference, it may be helpful to see an example sequence of a Linux domU
sizing a 64 bit BAR. I instrumented guest_bar_write() to print the raw/initial
val argument, and guest_bar_read() to print the final reg_val:
(XEN) drivers/vpci/header.c:guest_bar_read d1 0000:01:00.0 reg 0x10 val
0xe0100004
(XEN) drivers/vpci/header.c:guest_bar_write d1 0000:01:00.0 reg 0x10 val
0xffffffff
(XEN) drivers/vpci/header.c:guest_bar_read d1 0000:01:00.0 reg 0x10 val
0xffffc004
(XEN) drivers/vpci/header.c:guest_bar_write d1 0000:01:00.0 reg 0x10 val
0xe0100004
(XEN) drivers/vpci/header.c:guest_bar_read d1 0000:01:00.0 reg 0x14 val 0x0
(hi)
(XEN) drivers/vpci/header.c:guest_bar_write d1 0000:01:00.0 reg 0x14 val
0xffffffff (hi)
(XEN) drivers/vpci/header.c:guest_bar_read d1 0000:01:00.0 reg 0x14 val
0xffffffff (hi)
(XEN) drivers/vpci/header.c:guest_bar_write d1 0000:01:00.0 reg 0x14 val 0x0
(hi)
(XEN) drivers/vpci/header.c:guest_bar_write d1 0000:01:00.0 reg 0x10 val
0x23000004
(XEN) drivers/vpci/header.c:guest_bar_read d1 0000:01:00.0 reg 0x10 val
0x23000004
(XEN) drivers/vpci/header.c:guest_bar_write d1 0000:01:00.0 reg 0x14 val 0x0
(hi)
(XEN) drivers/vpci/header.c:guest_bar_read d1 0000:01:00.0 reg 0x14 val 0x0
(hi)
> + PAGE_OFFSET(guest_addr) != PAGE_OFFSET(bar->addr) )
> + {
> + gprintk(XENLOG_WARNING,
> + "%pp: ignored BAR %zu write attempting to change page
> offset\n",
> + &pdev->sbdf, bar - pdev->vpci->header.bars + hi);
> + return;
> + }
> +
> + bar->guest_addr = guest_addr;
> +}
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |