mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
sparc64: Bind PCIe devices to use IOMMU v2 service
In order to use Hypervisor (HV) IOMMU v2 API for map/demap, each PCIe device has to be bound to IOTSB using HV API pci_iotsb_bind(). Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com> Reviewed-by: chris hyser <chris.hyser@oracle.com> Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
31f077dc7d
commit
5116ab4eab
3 changed files with 60 additions and 0 deletions
|
@ -216,6 +216,43 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long dma_4v_iotsb_bind(unsigned long devhandle,
|
||||||
|
unsigned long iotsb_num,
|
||||||
|
struct pci_bus *bus_dev)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev;
|
||||||
|
unsigned long err;
|
||||||
|
unsigned int bus;
|
||||||
|
unsigned int device;
|
||||||
|
unsigned int fun;
|
||||||
|
|
||||||
|
list_for_each_entry(pdev, &bus_dev->devices, bus_list) {
|
||||||
|
if (pdev->subordinate) {
|
||||||
|
/* No need to bind pci bridge */
|
||||||
|
dma_4v_iotsb_bind(devhandle, iotsb_num,
|
||||||
|
pdev->subordinate);
|
||||||
|
} else {
|
||||||
|
bus = bus_dev->number;
|
||||||
|
device = PCI_SLOT(pdev->devfn);
|
||||||
|
fun = PCI_FUNC(pdev->devfn);
|
||||||
|
err = pci_sun4v_iotsb_bind(devhandle, iotsb_num,
|
||||||
|
HV_PCI_DEVICE_BUILD(bus,
|
||||||
|
device,
|
||||||
|
fun));
|
||||||
|
|
||||||
|
/* If bind fails for one device it is going to fail
|
||||||
|
* for rest of the devices because we are sharing
|
||||||
|
* IOTSB. So in case of failure simply return with
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void dma_4v_iommu_demap(void *demap_arg, unsigned long entry,
|
static void dma_4v_iommu_demap(void *demap_arg, unsigned long entry,
|
||||||
unsigned long npages)
|
unsigned long npages)
|
||||||
{
|
{
|
||||||
|
@ -629,6 +666,12 @@ static int pci_sun4v_atu_alloc_iotsb(struct pci_pbm_info *pbm)
|
||||||
}
|
}
|
||||||
iotsb->iotsb_num = iotsb_num;
|
iotsb->iotsb_num = iotsb_num;
|
||||||
|
|
||||||
|
err = dma_4v_iotsb_bind(pbm->devhandle, iotsb_num, pbm->pci_bus);
|
||||||
|
if (err) {
|
||||||
|
pr_err(PFX "pci_iotsb_bind failed error: %ld\n", err);
|
||||||
|
goto iotsb_conf_failed;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
iotsb_conf_failed:
|
iotsb_conf_failed:
|
||||||
|
|
|
@ -96,4 +96,7 @@ unsigned long pci_sun4v_iotsb_conf(unsigned long devhandle,
|
||||||
unsigned long page_size,
|
unsigned long page_size,
|
||||||
unsigned long dvma_base,
|
unsigned long dvma_base,
|
||||||
u64 *iotsb_num);
|
u64 *iotsb_num);
|
||||||
|
unsigned long pci_sun4v_iotsb_bind(unsigned long devhandle,
|
||||||
|
unsigned long iotsb_num,
|
||||||
|
unsigned int pci_device);
|
||||||
#endif /* !(_PCI_SUN4V_H) */
|
#endif /* !(_PCI_SUN4V_H) */
|
||||||
|
|
|
@ -378,3 +378,17 @@ ENTRY(pci_sun4v_iotsb_conf)
|
||||||
retl
|
retl
|
||||||
stx %o1, [%g1]
|
stx %o1, [%g1]
|
||||||
ENDPROC(pci_sun4v_iotsb_conf)
|
ENDPROC(pci_sun4v_iotsb_conf)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* %o0: devhandle
|
||||||
|
* %o1: iotsb_num/iotsb_handle
|
||||||
|
* %o2: pci_device
|
||||||
|
*
|
||||||
|
* returns %o0: status
|
||||||
|
*/
|
||||||
|
ENTRY(pci_sun4v_iotsb_bind)
|
||||||
|
mov HV_FAST_PCI_IOTSB_BIND, %o5
|
||||||
|
ta HV_FAST_TRAP
|
||||||
|
retl
|
||||||
|
nop
|
||||||
|
ENDPROC(pci_sun4v_iotsb_bind)
|
||||||
|
|
Loading…
Reference in a new issue