5252#include <linux/acpi.h>
5353#include <linux/sizes.h>
5454#include <linux/of_irq.h>
55+ #include <linux/swiotlb.h>
56+ #include <linux/memblock.h>
5557#include <asm/mshyperv.h>
5658
5759/*
@@ -468,6 +470,22 @@ struct pci_eject_response {
468470
469471static int pci_ring_size = VMBUS_RING_SIZE (SZ_16K );
470472
473+ static phys_addr_t hv_pci_swiotlb_base ;
474+ static size_t hv_pci_swiotlb_size ;
475+
476+ static int __init early_hv_pci_swiotlb (char * p )
477+ {
478+ hv_pci_swiotlb_base = memparse (p , & p );
479+ if (* p == ',' )
480+ hv_pci_swiotlb_size = memparse (p + 1 , NULL );
481+ if (hv_pci_swiotlb_base && hv_pci_swiotlb_size )
482+ memblock_reserve (hv_pci_swiotlb_base , hv_pci_swiotlb_size );
483+ return 0 ;
484+ }
485+ early_param ("hv_pci_swiotlb" , early_hv_pci_swiotlb );
486+
487+ static struct io_tlb_mem * hv_pci_swiotlb_pool ;
488+
471489/*
472490 * Driver specific state.
473491 */
@@ -2510,6 +2528,25 @@ static void hv_pci_assign_numa_node(struct hv_pcibus_device *hbus)
25102528 }
25112529}
25122530
2531+ /**
2532+ * hv_pci_assign_swiotlb() - assign dedicated swiotlb pool to bus devices
2533+ * @bus: PCI bus whose devices should use the pool
2534+ *
2535+ * If a dedicated swiotlb pool was configured via hv_pci_swiotlb=,
2536+ * assign it to every device on the bus so their DMA bounce buffering
2537+ * uses the restricted region.
2538+ */
2539+ static void hv_pci_assign_swiotlb (struct pci_bus * bus )
2540+ {
2541+ struct pci_dev * dev ;
2542+
2543+ if (!hv_pci_swiotlb_pool )
2544+ return ;
2545+
2546+ list_for_each_entry (dev , & bus -> devices , bus_list )
2547+ dev -> dev .dma_io_tlb_mem = hv_pci_swiotlb_pool ;
2548+ }
2549+
25132550/**
25142551 * create_root_hv_pci_bus() - Expose a new root PCI bus
25152552 * @hbus: Root PCI bus, as understood by this driver
@@ -2533,6 +2570,7 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus)
25332570 hv_pci_assign_numa_node (hbus );
25342571 pci_bus_assign_resources (bridge -> bus );
25352572 hv_pci_assign_slots (hbus );
2573+ hv_pci_assign_swiotlb (bridge -> bus );
25362574 pci_bus_add_devices (bridge -> bus );
25372575 pci_unlock_rescan_remove ();
25382576 hbus -> state = hv_pcibus_installed ;
@@ -2803,6 +2841,7 @@ static void pci_devices_present_work(struct work_struct *work)
28032841 pci_scan_child_bus (hbus -> bridge -> bus );
28042842 hv_pci_assign_numa_node (hbus );
28052843 hv_pci_assign_slots (hbus );
2844+ hv_pci_assign_swiotlb (hbus -> bridge -> bus );
28062845 pci_unlock_rescan_remove ();
28072846 break ;
28082847
@@ -4221,6 +4260,17 @@ static int __init init_hv_pci_drv(void)
42214260 if (hv_root_partition () && !hv_nested )
42224261 return - ENODEV ;
42234262
4263+ if (hv_pci_swiotlb_base && hv_pci_swiotlb_size ) {
4264+ hv_pci_swiotlb_pool = swiotlb_create_pool (hv_pci_swiotlb_base ,
4265+ hv_pci_swiotlb_size ,
4266+ "hv-pci-swiotlb" );
4267+ if (IS_ERR (hv_pci_swiotlb_pool )) {
4268+ pr_err ("hv_pci: failed to create swiotlb pool: %ld\n" ,
4269+ PTR_ERR (hv_pci_swiotlb_pool ));
4270+ hv_pci_swiotlb_pool = NULL ;
4271+ }
4272+ }
4273+
42244274 ret = hv_pci_irqchip_init ();
42254275 if (ret )
42264276 return ret ;
0 commit comments