Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
xen.26345
5d9ef2ef-PCI-clear-maskall-fields-on-assign.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5d9ef2ef-PCI-clear-maskall-fields-on-assign.patch of Package xen.26345
# Commit 575e18d54d19eda787f6477a4acd3c50f72751a9 # Date 2019-10-10 10:59:27 +0200 # Author Roger Pau Monné <roger.pau@citrix.com> # Committer Jan Beulich <jbeulich@suse.com> pci: clear {host/guest}_maskall field on assign The current implementation of host_maskall makes it sticky across assign and deassign calls, which means that once a guest forces Xen to set host_maskall the maskall bit is not going to be cleared until a call to PHYSDEVOP_prepare_msix is performed. Such call however shouldn't be part of the normal flow when doing PCI passthrough, and hence the flag needs to be cleared when assigning in order to prevent host_maskall being carried over from previous assignations. Note that the entry maskbit is reset when the msix capability is initialized, and the guest_maskall field is also cleared so that the hardware value matches Xen's internal state (hardware maskall = host_maskall | guest_maskall). Also note that doing the reset of host_maskall there would allow the guest to reset such field by enabling and disabling MSIX, which is not intended. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Tested-by: Chao Gao <chao.gao@intel.com> --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -1271,6 +1271,31 @@ void pci_cleanup_msi(struct pci_dev *pde msi_free_irqs(pdev); } +int pci_reset_msix_state(struct pci_dev *pdev) +{ + uint8_t slot = PCI_SLOT(pdev->devfn); + uint8_t func = PCI_FUNC(pdev->devfn); + unsigned int pos = pci_find_cap_offset(pdev->seg, pdev->bus, slot, func, + PCI_CAP_ID_MSIX); + + ASSERT(pos); + /* + * Xen expects the device state to be the after reset one, and hence + * host_maskall = guest_maskall = false and all entries should have the + * mask bit set. Test that the maskall bit is not set, having it set could + * signal that the device hasn't been reset properly. + */ + if ( pci_conf_read16(pdev->seg, pdev->bus, slot, func, + msix_control_reg(pos)) & + PCI_MSIX_FLAGS_MASKALL ) + return -EBUSY; + + pdev->msix->host_maskall = false; + pdev->msix->guest_maskall = false; + + return 0; +} + int pci_msi_conf_write_intercept(struct pci_dev *pdev, unsigned int reg, unsigned int size, uint32_t *data) { --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1410,7 +1410,12 @@ static int assign_device(struct domain * } if ( pdev->msix ) + { + rc = pci_reset_msix_state(pdev); + if ( rc ) + goto done; msixtbl_init(d); + } pdev->fault.count = 0; --- a/xen/include/asm-x86/msi.h +++ b/xen/include/asm-x86/msi.h @@ -91,6 +91,7 @@ extern int __setup_msi_irq(struct irq_de extern void teardown_msi_irq(int irq); extern int msi_free_vector(struct msi_desc *entry); extern int pci_restore_msi_state(struct pci_dev *pdev); +extern int pci_reset_msix_state(struct pci_dev *pdev); struct msi_desc { struct msi_attrib {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor