mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: enable dom0 to use PCI devices with pci-passthrough=no
Enable the use of IOMMU + PCI in dom0 without having to specify "pci-passthrough=yes". Due to possible platform specific dependencies of the PCI host, we rely on dom0 to initialize it and perform a PCI PHYSDEVOP calls to add each device to SMMU. Because pci_passthrough is not always enabled on all architectures, add a new function arch_pci_device_physdevop that checks if we need to enable a subset of the PCI subsystem related to managing IOMMU configuration for PCI devices. Enable pci_init() for initializing Xen's internal PCI subsystem, and allow PCI PHYSDEV ops when pci-passthrough is disabled. Signed-off-by: Stewart Hildebrand <stewart.hildebrand@amd.com> Signed-off-by: Mykyta Poturai <mykyta_poturai@epam.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
b9508e7033
commit
d5b6d4bc19
5 files changed
+33
-4
No files matched your search
@@ -151,6 +151,8 @@ void pci_generic_init_bus_range_child(struct dt_device_node *dev,
|
||||
struct pci_host_bridge *bridge,
|
||||
struct pci_config_window *cfg);
|
||||
|
||||
bool arch_pci_device_physdevop(void);
|
||||
|
||||
#else /*!CONFIG_HAS_PCI*/
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
+13
-1
@@ -16,6 +16,7 @@
|
||||
#include <xen/device_tree.h>
|
||||
#include <xen/errno.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <xen/param.h>
|
||||
#include <xen/pci.h>
|
||||
|
||||
@@ -75,6 +76,17 @@ static int __init acpi_pci_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Platform-specific PCI host dependencies require dom0 to handle
|
||||
* initialization and issue PHYSDEVOP_pci_device_add/remove calls for SMMU
|
||||
* device registration. This check is used to enable the minimal PCI
|
||||
* subsystem required for dom0 operation when PCI passthrough is disabled.
|
||||
*/
|
||||
bool arch_pci_device_physdevop(void)
|
||||
{
|
||||
return iommu_enabled;
|
||||
}
|
||||
|
||||
/* By default pci passthrough is disabled. */
|
||||
bool __read_mostly pci_passthrough_enabled;
|
||||
boolean_param("pci-passthrough", pci_passthrough_enabled);
|
||||
@@ -85,7 +97,7 @@ static int __init pci_init(void)
|
||||
* Enable PCI passthrough when has been enabled explicitly
|
||||
* (pci-passthrough=on).
|
||||
*/
|
||||
if ( !pci_passthrough_enabled )
|
||||
if ( !is_pci_passthrough_enabled() && !arch_pci_device_physdevop() )
|
||||
return 0;
|
||||
|
||||
if ( pci_add_segment(0) )
|
||||
|
||||
@@ -57,6 +57,16 @@ static always_inline bool is_pci_passthrough_enabled(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since PCI passthrough is always enabled on x86, physdevop handling doesn't
|
||||
* need special arch-specific behavior. Current call sites work with either
|
||||
* return value, but true is more consistent with passthrough being enabled.
|
||||
*/
|
||||
static inline bool arch_pci_device_physdevop(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void arch_pci_init_pdev(struct pci_dev *pdev);
|
||||
|
||||
bool pci_check_bar(const struct pci_dev *pdev, mfn_t start, mfn_t end);
|
||||
|
||||
@@ -19,7 +19,7 @@ ret_t pci_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
|
||||
struct pci_dev_info pdev_info;
|
||||
nodeid_t node = NUMA_NO_NODE;
|
||||
|
||||
if ( !is_pci_passthrough_enabled() )
|
||||
if ( !is_pci_passthrough_enabled() && !arch_pci_device_physdevop() )
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = -EFAULT;
|
||||
@@ -57,7 +57,7 @@ ret_t pci_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
|
||||
case PHYSDEVOP_pci_device_remove: {
|
||||
struct physdev_pci_device dev;
|
||||
|
||||
if ( !is_pci_passthrough_enabled() )
|
||||
if ( !is_pci_passthrough_enabled() && !arch_pci_device_physdevop() )
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = -EFAULT;
|
||||
@@ -74,7 +74,7 @@ ret_t pci_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
|
||||
struct pci_dev *pdev;
|
||||
pci_sbdf_t sbdf;
|
||||
|
||||
if ( !is_pci_passthrough_enabled() )
|
||||
if ( !is_pci_passthrough_enabled() && !arch_pci_device_physdevop() )
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = -EFAULT;
|
||||
|
||||
@@ -79,6 +79,11 @@ static inline bool is_pci_passthrough_enabled(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool arch_pci_device_physdevop(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct pci_dev_info {
|
||||
|
||||