[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 09/11] vpci/header: Reset the command register when adding devices
Hi, Roger! On 26.10.21 14:00, Roger Pau Monné wrote: > On Thu, Sep 30, 2021 at 10:52:21AM +0300, Oleksandr Andrushchenko wrote: >> From: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> >> >> Reset the command register when passing through a PCI device: >> it is possible that when passing through a PCI device its memory >> decoding bits in the command register are already set. Thus, a >> guest OS may not write to the command register to update memory >> decoding, so guest mappings (guest's view of the BARs) are >> left not updated. >> >> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> >> Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx> >> --- >> Since v1: >> - do not write 0 to the command register, but respect host settings. >> --- >> xen/drivers/vpci/header.c | 17 +++++++++++++---- >> 1 file changed, 13 insertions(+), 4 deletions(-) >> >> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c >> index 754aeb5a584f..70d911b147e1 100644 >> --- a/xen/drivers/vpci/header.c >> +++ b/xen/drivers/vpci/header.c >> @@ -451,8 +451,7 @@ static void cmd_write(const struct pci_dev *pdev, >> unsigned int reg, >> pci_conf_write16(pdev->sbdf, reg, cmd); >> } >> >> -static void guest_cmd_write(const struct pci_dev *pdev, unsigned int reg, >> - uint32_t cmd, void *data) >> +static uint32_t emulate_cmd_reg(const struct pci_dev *pdev, uint32_t cmd) >> { >> /* TODO: Add proper emulation for all bits of the command register. */ >> >> @@ -467,14 +466,20 @@ static void guest_cmd_write(const struct pci_dev >> *pdev, unsigned int reg, >> cmd |= PCI_COMMAND_INTX_DISABLE; >> else >> { >> - uint16_t current_cmd = pci_conf_read16(pdev->sbdf, reg); >> + uint16_t current_cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND); > Either we keep reg here or we drop the parameter altogether from the > function prototype. Having one caller pass 0 while the other passing > PCI_COMMAND is confusing. The more that the parameter is now > effectively unused. This is probably because git diff isn't really helpful here in showing the change: static uint32_t emulate_cmd_reg(const struct pci_dev *pdev, uint32_t cmd) { /* TODO: Add proper emulation for all bits of the command register. */ if ( (cmd & PCI_COMMAND_INTX_DISABLE) == 0 ) { /* * Guest wants to enable INTx. It can't be enabled if: * - host has INTx disabled * - MSI/MSI-X enabled */ if ( pdev->vpci->msi->enabled ) cmd |= PCI_COMMAND_INTX_DISABLE; else { uint16_t current_cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND); if ( current_cmd & PCI_COMMAND_INTX_DISABLE ) cmd |= PCI_COMMAND_INTX_DISABLE; } } return cmd; } So, reg is not used here and cmd is the desired value of the PCI_COMMAND register. So, I see no confusion here. >> >> if ( current_cmd & PCI_COMMAND_INTX_DISABLE ) >> cmd |= PCI_COMMAND_INTX_DISABLE; >> } >> } >> >> - cmd_write(pdev, reg, cmd, data); >> + return cmd; >> +} >> + >> +static void guest_cmd_write(const struct pci_dev *pdev, unsigned int reg, >> + uint32_t cmd, void *data) >> +{ >> + cmd_write(pdev, reg, emulate_cmd_reg(pdev, cmd), data); >> } >> >> static void bar_write(const struct pci_dev *pdev, unsigned int reg, >> @@ -793,6 +798,10 @@ int vpci_bar_add_handlers(const struct domain *d, const >> struct pci_dev *pdev) >> gdprintk(XENLOG_ERR, >> "%pp: failed to add BAR handlers for dom%pd: %d\n", >> &pdev->sbdf, d, rc); >> + >> + /* Reset the command register with respect to host settings. */ >> + pci_conf_write16(pdev->sbdf, PCI_COMMAND, emulate_cmd_reg(pdev, 0)); > I think we likely want to unset the memory and IO decoding bits from > the command register, as the guest view of the BAR address is > currently forced to 0, and not mapped into the guest p2m. By passing 0 here as the desired value of the PCI_COMMAND register we do that. The emulation code will take care of that. > > Thanks, Roger. Thank you, Oleksandr
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |