iommu/vt-d: Several minor adjustments
Subsystems (3)
Lu Baolu
maintainercover iommu/vt-d: Several minor adjustments
Hi,
This series includes some adjustments for Intel IOMMU which I have been suggested. Please help to review.
- Enable Intel IOMMU scalable mode by default
- Preset A/D bits for user space DMA usage
- Disallow SVA if devices don't support 64-bit address
- Allow devices to have more than 32 outstanding PRs
Best regards,
baolu
Lu Baolu (5):
iommu/vt-d: Refactor Kconfig a bit
iommu/vt-d: Enable Intel IOMMU scalable mode by default iommu/vt-d: Preset A/D bits for user space DMA usage iommu/vt-d: Disallow SVA if devices don't support 64-bit address iommu/vt-d: Allow devices to have more than 32 outstanding PRs
.../admin-guide/kernel-parameters.txt | 11 +++--- include/linux/intel-svm.h | 5 +++ drivers/iommu/intel/iommu.c | 34 ++++++++----------- drivers/iommu/intel/svm.c | 4 --- drivers/iommu/intel/Kconfig | 19 ++++++----- 5 files changed, 36 insertions(+), 37 deletions(-)
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerPATCH 1/5 iommu/vt-d: Refactor Kconfig a bit
Put all sub-options inside a "if INTEL_IOMMU" so that they don't need to always depend on INTEL_IOMMU. Use IS_ENABLED() instead of #ifdef as well.
--- drivers/iommu/intel/iommu.c | 13 ++----------- drivers/iommu/intel/Kconfig | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 19 deletions(-)
drivers/iommu/intel/iommu.c +2 -11
@@ -327,17 +327,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,static phys_addr_t intel_iommu_iova_to_phys (struct iommu_domain *domain,dma_addr_t iova); -#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON -int dmar_disabled =0 ; -#else -int dmar_disabled =1 ; -#endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */ - -#ifdef CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON -int intel_iommu_sm =1 ; -#else -int intel_iommu_sm; -#endif /* CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ +int dmar_disabled = !IS_ENABLED (CONFIG_INTEL_IOMMU_DEFAULT_ON ); +int intel_iommu_sm =IS_ENABLED (CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON );int intel_iommu_enabled =0 ;EXPORT_SYMBOL_GPL (intel_iommu_enabled);
drivers/iommu/intel/Kconfig +10 -8
@@ -25,9 +25,11 @@ config INTEL_IOMMU and include PCI device scope covered by these DMA remapping devices. +if INTEL_IOMMU + config INTEL_IOMMU_DEBUGFS bool "Export Intel IOMMU internals in Debugfs" - depends on INTEL_IOMMU && IOMMU_DEBUGFS + depends on IOMMU_DEBUGFS select DMAR_PERF help !!!WARNING!!!
@@ -41,7 +43,7 @@ config INTEL_IOMMU_DEBUGFS config INTEL_IOMMU_SVM bool "Support for Shared Virtual Memory with Intel IOMMU" - depends on INTEL_IOMMU && X86_64 + depends on X86_64 select PCI_PASID select PCI_PRI select MMU_NOTIFIER
@@ -53,9 +55,8 @@ config INTEL_IOMMU_SVM means of a Process Address Space ID (PASID). config INTEL_IOMMU_DEFAULT_ON - def_bool y - prompt "Enable Intel DMA Remapping Devices by default" - depends on INTEL_IOMMU + bool "Enable Intel DMA Remapping Devices by default" + default y help Selecting this option will enable a DMAR device at boot time if one is found. If this option is not selected, DMAR support can
@@ -63,7 +64,7 @@ config INTEL_IOMMU_DEFAULT_ON config INTEL_IOMMU_BROKEN_GFX_WA bool "Workaround broken graphics drivers (going away soon)" - depends on INTEL_IOMMU && BROKEN && X86 + depends on BROKEN && X86 help Current Graphics drivers tend to use physical address for DMA and avoid using DMA APIs. Setting this config
@@ -74,7 +75,7 @@ config INTEL_IOMMU_BROKEN_GFX_WA config INTEL_IOMMU_FLOPPY_WA def_bool y - depends on INTEL_IOMMU && X86 + depends on X86 help Floppy disk drivers are known to bypass DMA API calls thereby failing to work when IOMMU is enabled. This
@@ -83,7 +84,6 @@ config INTEL_IOMMU_FLOPPY_WA config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON bool "Enable Intel IOMMU scalable mode by default" - depends on INTEL_IOMMU help Selecting this option will enable by default the scalable mode if hardware presents the capability. The scalable mode is defined in
@@ -92,3 +92,5 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON is not selected, scalable mode support could also be enabled by passing intel_iommu=sm_on to the kernel. If not sure, please use the default value. + +endif # INTEL_IOMMU
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerPATCH 2/5 iommu/vt-d: Enable Intel IOMMU scalable mode by default
In reply to Lu BaoluThe commit 8950dcd83ae7d ("iommu/vt-d: Leave scalable mode default off") leaves the scalable mode default off and end users could turn it on with "intel_iommu=sm_on". Using the Intel IOMMU scalable mode for kernel DMA, user-level device access and Shared Virtual Address have been enabled. This enables the scalable mode by default if the hardware advertises the support and adds kernel options of "intel_iommu=sm_on/sm_off" for end users to configure it through the kernel parameters.
--- Documentation/admin-guide/kernel-parameters.txt | 11 ++++++----- drivers/iommu/intel/iommu.c | 5 ++++- drivers/iommu/intel/Kconfig | 1 + 3 files changed, 11 insertions(+), 6 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +6 -5
@@ -1951,11 +1951,12 @@ By default, super page will be supported if Intel IOMMU has the capability. With this option, super page will not be supported. - sm_on [Default Off] - By default, scalable mode will be disabled even if the - hardware advertises that it has support for the scalable - mode translation. With this option set, scalable mode - will be used on hardware which claims to support it. + sm_on + Enable the Intel IOMMU scalable mode if the hardware + advertises that it has support for the scalable mode + translation. + sm_off + Disallow use of the Intel IOMMU scalable mode. tboot_noforce [Default Off] Do not force the Intel IOMMU enabled under tboot. By default, tboot will force Intel IOMMU on, which
drivers/iommu/intel/iommu.c +4 -1
@@ -433,8 +433,11 @@ static int __init intel_iommu_setup(char *str)pr_info ("Disable supported super page\n" ); intel_iommu_superpage =0 ; }else if (!strncmp (str,"sm_on" ,5 )) { -pr_info ("Intel-IOMMU: scalable mode supported\n" ); +pr_info ("Enable scalable mode if hardware supports\n" ); intel_iommu_sm =1 ; + }else if (!strncmp (str,"sm_off" ,6 )) { +pr_info ("Scalable mode is disallowed\n" ); + intel_iommu_sm =0 ; }else if (!strncmp (str,"tboot_noforce" ,13 )) {pr_info ("Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n" ); intel_iommu_tboot_noforce =1 ;
drivers/iommu/intel/Kconfig +1 -0
@@ -84,6 +84,7 @@ config INTEL_IOMMU_FLOPPY_WA config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON bool "Enable Intel IOMMU scalable mode by default" + default y help Selecting this option will enable by default the scalable mode if hardware presents the capability. The scalable mode is defined in
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerPATCH 3/5 iommu/vt-d: Preset A/D bits for user space DMA usage
In reply to Lu BaoluWe preset the access and dirty bits for IOVA over first level usage only for the kernel DMA (i.e., when domain type is IOMMU_DOMAIN_DMA). We should also preset the FL A/D for user space DMA usage. The idea is that even the user space A/D bit memory write is unnecessary. We should avoid it to minimize the overhead.
--- drivers/iommu/intel/iommu.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/iommu/intel/iommu.c +3 -7
@@ -2339,13 +2339,9 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, attr = prot & (DMA_PTE_READ |DMA_PTE_WRITE |DMA_PTE_SNP ); attr |=DMA_FL_PTE_PRESENT ;if (domain_use_first_level (domain)) { - attr |=DMA_FL_PTE_XD |DMA_FL_PTE_US ; - -if (domain->domain.type ==IOMMU_DOMAIN_DMA ) { - attr |=DMA_FL_PTE_ACCESS ; -if (prot &DMA_PTE_WRITE ) - attr |=DMA_FL_PTE_DIRTY ; - } + attr |=DMA_FL_PTE_XD |DMA_FL_PTE_US |DMA_FL_PTE_ACCESS ; +if (prot &DMA_PTE_WRITE ) + attr |=DMA_FL_PTE_DIRTY ; } pteval = ((phys_addr_t )phys_pfn <<VTD_PAGE_SHIFT ) | attr;
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerPATCH 4/5 iommu/vt-d: Disallow SVA if devices don't support 64-bit address
In reply to Lu BaoluWhen the device and CPU share an address space (such as SVA), the device must support the same addressing capability as the CPU. The CPU does not consider the addressing ability of any device when managing the page table of a process, so the device must have enough addressing ability to bind the page table of the process.
--- drivers/iommu/intel/iommu.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iommu/intel/iommu.c +3 -0
@@ -5372,6 +5372,9 @@ static int intel_iommu_enable_sva(struct device *dev)if (!(iommu->flags &VTD_FLAG_SVM_CAPABLE ))return -ENODEV ; +if (!dev->dma_mask || *dev->dma_mask !=DMA_BIT_MASK (64 )) +return -ENODEV ; +if (intel_iommu_enable_pasid (iommu, dev))return -ENODEV ;
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Robin Murphy
reviewerRe: [PATCH 4/5] iommu/vt-d: Disallow SVA if devices don't support 64-bit address
Quoted 16 lines · Lu Baolu
When the device and CPU share an address space (such as SVA), the device must support the same addressing capability as the CPU. The CPU does not consider the addressing ability of any device when managing the page table of a process, so the device must have enough addressing ability to bind the page table of the process.
Signed-off-by Lu Baolu <[email protected]>--- drivers/iommu/intel/iommu.c | 3 +++ 1 file changed, 3 insertions(+)drivers/iommu/intel/iommu.c +0
-0
drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct device *dev) · line 5375
Quoted 4 lines
drivers/iommu/intel/iommu.c +1
-0@@ -5372,6 +5372,9 @@ static int intel_iommu_enable_sva(struct device *dev)if (!(iommu->flags &VTD_FLAG_SVM_CAPABLE ))return -ENODEV ; +if (!dev->dma_mask || *dev->dma_mask !=DMA_BIT_MASK (64 ))
Careful - VFIO doesn't set DMA masks (since it doesn't use the DMA API), so this appears to be relying on another driver having bound previously, otherwise the mask would still be the default 32-bit one from pci_setup_device(). I'm not sure that's an entirely robust assumption.
Robin.
drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct device *dev) · line 5380
Quoted 6 lines
drivers/iommu/intel/iommu.c +2
-0+return -ENODEV ; +if (intel_iommu_enable_pasid (iommu, dev))return -ENODEV ;
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerRe: [PATCH 4/5] iommu/vt-d: Disallow SVA if devices don't support 64-bit address
Hi Robin,
Thanks a lot for reviewing my patch!
Quoted 12 lines · Robin Murphy
Quoted 11 lines · Lu Baolu
When the device and CPU share an address space (such as SVA), the device must support the same addressing capability as the CPU. The CPU does not consider the addressing ability of any device when managing the page table of a process, so the device must have enough addressing ability to bind the page table of the process.
Signed-off-by Lu Baolu <[email protected]>---
drivers/iommu/intel/iommu.c| 3 +++1 file changed, 3 insertions(+)
Quoted 11 lines
drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct device · line 5375
Quoted 9 lines
drivers/iommu/intel/iommu.c +1
-0@@ -5372,6 +5372,9 @@ static int intel_iommu_enable_sva(struct device *dev) if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE)) return -ENODEV; + if (!dev->dma_mask || *dev->dma_mask != DMA_BIT_MASK(64))Careful - VFIO doesn't set DMA masks (since it doesn't use the DMA API),
SVA doesn't work through the VFIO framework.
Quoted 1 line
so this appears to be relying on another driver having bound previously,
Yes. You are right.
Quoted 1 line
otherwise the mask would still be the default 32-bit one from
pci_setup_device(). I'm not sure that's an entirely robust assumption.
Currently SVA implementation always requires a native kernel driver. The assumption is that the drivers should check and set 64-bit addressing capability before calling iommu_sva_xxx() APIs.
Quoted 8 lines
Robin.
Quoted 5 lines
drivers/iommu/intel/iommu.c +2
-0+ return -ENODEV; + if (intel_iommu_enable_pasid(iommu, dev)) return -ENODEV;
Best regards,
baolu
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Robin Murphy
reviewerRe: [PATCH 4/5] iommu/vt-d: Disallow SVA if devices don't support 64-bit address
Quoted 29 lines · Lu Baolu
Hi Robin,
Thanks a lot for reviewing my patch!
Quoted 12 lines · Robin Murphy
Quoted 11 lines · Lu Baolu
When the device and CPU share an address space (such as SVA), the device must support the same addressing capability as the CPU. The CPU does not consider the addressing ability of any device when managing the page table of a process, so the device must have enough addressing ability to bind the page table of the process.
Signed-off-by Lu Baolu <[email protected]>---
drivers/iommu/intel/iommu.c| 3 +++1 file changed, 3 insertions(+)Quoted 11 lines
drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct device · line 5375
Quoted 9 lines
drivers/iommu/intel/iommu.c +1
-0@@ -5372,6 +5372,9 @@ static int intel_iommu_enable_sva(struct device *dev) if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE)) return -ENODEV; + if (!dev->dma_mask || *dev->dma_mask != DMA_BIT_MASK(64))Careful - VFIO doesn't set DMA masks (since it doesn't use the DMA API),
Quoted 1 line
SVA doesn't work through the VFIO framework.
Did anyone say it does? My point is that, as far as I understand, the SVA UAPI is very much intended to work *with* VFIO, and even if the finer details are still mired in the /dev/ioasid discussion today we should definitely expect to see VFIO-like use-cases at some point. I certainly don't see why any of the guest SVA stuff exists already if not for VFIO-assigned devices?
Quoted 9 lines
Quoted 1 line
so this appears to be relying on another driver having bound previously,
Yes. You are right.
Quoted 1 line
otherwise the mask would still be the default 32-bit one from
pci_setup_device(). I'm not sure that's an entirely robust assumption.Currently SVA implementation always requires a native kernel driver. The assumption is that the drivers should check and set 64-bit addressing capability before calling
iommu_sva_xxx()APIs.
...and given that that is not a documented requirement, and certainly not a technical one (even a self-contained kernel driver could choose to only use SVA contexts and not touch the DMA API), it's an inherently fragile assumption which I'm confident *will* be broken eventually :)
Robin.
Quoted 8 lines
Quoted 5 lines
drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct device *dev) · line 5380
Quoted 5 lines
drivers/iommu/intel/iommu.c +2
-0+ return -ENODEV; + if (intel_iommu_enable_pasid(iommu, dev)) return -ENODEV;Best regards,
baolu
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerRe: [PATCH 4/5] iommu/vt-d: Disallow SVA if devices don't support 64-bit address
Quoted 30 lines · Robin Murphy
Quoted 29 lines · Lu Baolu
Hi Robin,
Thanks a lot for reviewing my patch!
Quoted 23 lines · Robin Murphy
Quoted 16 lines · Lu Baolu
When the device and CPU share an address space (such as SVA), the device must support the same addressing capability as the CPU. The CPU does not consider the addressing ability of any device when managing the page table of a process, so the device must have enough addressing ability to bind the page table of the process.
Signed-off-by Lu Baolu <[email protected]>---
drivers/iommu/intel/iommu.c| 3 +++1 file changed, 3 insertions(+)drivers/iommu/intel/iommu.c +0
-0drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct · line 5375
Quoted 4 lines
drivers/iommu/intel/iommu.c +1
-0@@ -5372,6 +5372,9 @@ static int intel_iommu_enable_sva(struct device *dev) if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE)) return -ENODEV; + if (!dev->dma_mask || *dev->dma_mask != DMA_BIT_MASK(64))Careful - VFIO doesn't set DMA masks (since it doesn't use the DMA API),
Quoted 3 lines
Quoted 1 line
SVA doesn't work through the VFIO framework.
Did anyone say it does? My point is that, as far as I understand, the SVA UAPI is very much intended to work *with* VFIO, and even if the finer details are still mired in the
/dev/ioasiddiscussion today we should definitely expect to see VFIO-like use-cases at some point. I certainly don't see why any of the guest SVA stuff exists already if not for VFIO-assigned devices?
Agreed. From /dev/ioasid design point of view, it's possible to have VFIO-like use case of SVA. Perhaps the device addressing capability could be included in GET_DEV_INFO of /dev/ioasid UAPI.
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
so this appears to be relying on another driver having bound previously,
Yes. You are right.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
otherwise the mask would still be the default 32-bit one from
pci_setup_device(). I'm not sure that's an entirely robust assumption.Currently SVA implementation always requires a native kernel driver. The assumption is that the drivers should check and set 64-bit addressing capability before calling
iommu_sva_xxx()APIs....and given that that is not a documented requirement, and certainly not a technical one (even a self-contained kernel driver could choose to only use SVA contexts and not touch the DMA API), it's an inherently fragile assumption which I'm confident *will* be broken eventually :)
Fair enough. I will drop this patch.
Thanks a lot for the comments.
Best regards,
baolu
Quoted 10 lines
Robin.
Quoted 8 lines
Quoted 5 lines
drivers/iommu/intel/iommu.c static int intel_iommu_enable_sva(struct device *dev) · line 5380
Quoted 5 lines
drivers/iommu/intel/iommu.c +2
-0+ return -ENODEV; + if (intel_iommu_enable_pasid(iommu, dev)) return -ENODEV;Best regards,
baolu
Lu Baolu
maintainerPATCH 5/5 iommu/vt-d: Allow devices to have more than 32 outstanding PRs
In reply to Lu BaoluThe minimum per-IOMMU PRQ queue size is one 4K page, this is more entries than the hardcoded limit of 32 in the current VT-d code. Some devices can support up to 512 outstanding PRQs but underutilized by this limit of 32. Although, 32 gives some rough fairness when multiple devices share the same IOMMU PRQ queue, but far from optimal for customized use case. This extends the per-IOMMU PRQ queue size to four 4K pages and let the devices have as many outstanding page requests as they can.
--- include/linux/intel-svm.h | 5 +++++ drivers/iommu/intel/iommu.c | 3 ++- drivers/iommu/intel/svm.c | 4 ---- 3 files changed, 7 insertions(+), 5 deletions(-)
include/linux/intel-svm.h +5 -0
@@ -14,6 +14,11 @@#define SVM_REQ_EXEC (1<<1)#define SVM_REQ_PRIV (1<<0) +/* Page Request Queue depth */ +#define PRQ_ORDER 2 +#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x20) +#define PRQ_DEPTH ((0x1000 << PRQ_ORDER) >> 5) +/* * The SVM_FLAG_SUPERVISOR_MODE flag requests a PASID which can be used only * for access to kernel addresses. No IOTLB flushes are automatically done
drivers/iommu/intel/iommu.c +2 -1
@@ -33,6 +33,7 @@#include <linux/iommu.h> #include <linux/dma-iommu.h> #include <linux/intel-iommu.h> +#include <linux/intel-svm.h> #include <linux/syscore_ops.h> #include <linux/tboot.h> #include <linux/dmi.h>
@@ -1542,7 +1543,7 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)if (info->pri_supported && (info->pasid_enabled ?pci_prg_resp_pasid_required (pdev) :1 ) && - !pci_reset_pri (pdev) && !pci_enable_pri (pdev,32 )) + !pci_reset_pri (pdev) && !pci_enable_pri (pdev,PRQ_DEPTH )) info->pri_enabled =1 ;#endif if (info->ats_supported && pci_ats_page_aligned(pdev) &&
drivers/iommu/intel/svm.c +0 -4
@@ -31,8 +31,6 @@ static irqreturn_t prq_event_thread(int irq, void *d);static void intel_svm_drain_prq (struct device *dev,u32 pasid);#define to_intel_svm_dev (handle) container_of(handle, struct intel_svm_dev, sva) -#define PRQ_ORDER 0 -static DEFINE_XARRAY_ALLOC (pasid_private_array);static int pasid_private_add (ioasid_t pasid,void *priv) {
@@ -724,8 +722,6 @@ struct page_req_dsc {u64 priv_data[2 ]; }; -#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x20) -static bool is_canonical_address (u64 addr) {int shift =64 - (__VIRTUAL_MASK_SHIFT +1 );
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu