Re: [PATCH 1/1] iommu/vt-d: Fix NULL pointer dereference in dev_iommu_priv_set()

2020-09-04 Thread Joerg Roedel
On Thu, Sep 03, 2020 at 02:51:32PM +0800, Lu Baolu wrote:
> ---
>  drivers/iommu/intel/iommu.c | 100 
>  1 file changed, 55 insertions(+), 45 deletions(-)

Applied for v5.9, thanks.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/1] iommu/vt-d: Fix NULL pointer dereference in dev_iommu_priv_set()

2020-09-03 Thread Torsten Hilbrich
On 03.09.20 08:51, Lu Baolu wrote:
> The dev_iommu_priv_set() must be called after probe_device(). This fixes
> a NULL pointer deference bug when booting a system with kernel cmdline
> "intel_iommu=on,igfx_off", where the dev_iommu_priv_set() is abused.
[...]

> 
> Fixes: 01b9d4e21148c ("iommu/vt-d: Use dev_iommu_priv_get/set()")
> Reported-by: Torsten Hilbrich 
> Reported-by: Wendy Wang 
> Link: 
> https://lore.kernel.org/linux-iommu/96717683-70be-7388-3d2f-61131070a...@secunet.com/
> Signed-off-by: Lu Baolu 

Tested-by: Torsten Hilbrich 

Regards,

Torsten
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/1] iommu/vt-d: Fix NULL pointer dereference in dev_iommu_priv_set()

2020-09-03 Thread Lu Baolu
The dev_iommu_priv_set() must be called after probe_device(). This fixes
a NULL pointer deference bug when booting a system with kernel cmdline
"intel_iommu=on,igfx_off", where the dev_iommu_priv_set() is abused.

The following stacktrace was produced:

[0.00] Command line: BOOT_IMAGE=/isolinux/bzImage console=tty1 
intel_iommu=on,igfx_off
...
[3.341682] DMAR: Host address width 39
[3.341684] DMAR: DRHD base: 0x00fed9 flags: 0x0
[3.341702] DMAR: dmar0: reg_base_addr fed9 ver 1:0 cap 1cc40660462 
ecap 19e2ff0505e
[3.341705] DMAR: DRHD base: 0x00fed91000 flags: 0x1
[3.341711] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008c40660462 
ecap f050da
[3.341713] DMAR: RMRR base: 0x009aa9f000 end: 0x009aabefff
[3.341716] DMAR: RMRR base: 0x009d00 end: 0x009f7f
[3.341726] DMAR: No ATSR found
[3.341772] BUG: kernel NULL pointer dereference, address: 0038
[3.341774] #PF: supervisor write access in kernel mode
[3.341776] #PF: error_code(0x0002) - not-present page
[3.341777] PGD 0 P4D 0
[3.341780] Oops: 0002 [#1] SMP PTI
[3.341783] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.9.0-devel+ #2
[3.341785] Hardware name: LENOVO 20HGS0TW00/20HGS0TW00, BIOS N1WET46S 
(1.25s ) 03/30/2018
[3.341790] RIP: 0010:intel_iommu_init+0xed0/0x1136
[3.341792] Code: fe e9 61 02 00 00 bb f4 ff ff ff e9 57 02 00 00 48 63 d1 
48 c1 e2 04 48
 03 50 20 48 8b 12 48 85 d2 74 0b 48 8b 92 d0 02 00 00 48 
89 7a 38 ff c1
 e9 15 f5 ff ff 48 c7 c7 60 99 ac a7 49 c7 c7 a0
[3.341796] RSP: :96d180073dd0 EFLAGS: 00010282
[3.341798] RAX: 8c91037a7d20 RBX:  RCX: 
[3.341800] RDX:  RSI:  RDI: 
[3.341802] RBP: 96d180073e90 R08: 0001 R09: 8c91039fe3c0
[3.341804] R10: 0226 R11: 0226 R12: 000b
[3.341806] R13: 8c910367c650 R14: a8426d60 R15: 
[3.341808] FS:  () GS:8c910748() 
knlGS:
[3.341810] CS:  0010 DS:  ES:  CR0: 80050033
[3.341812] CR2: 0038 CR3: 0004b100a001 CR4: 003706e0
[3.341814] Call Trace:
[3.341820]  ? _raw_spin_unlock_irqrestore+0x1f/0x30
[3.341824]  ? call_rcu+0x10e/0x320
[3.341828]  ? trace_hardirqs_on+0x2c/0xd0
[3.341831]  ? rdinit_setup+0x2c/0x2c
[3.341834]  ? e820__memblock_setup+0x8b/0x8b
[3.341836]  pci_iommu_init+0x16/0x3f
[3.341839]  do_one_initcall+0x46/0x1e4
[3.341842]  kernel_init_freeable+0x169/0x1b2
[3.341845]  ? rest_init+0x9f/0x9f
[3.341847]  kernel_init+0xa/0x101
[3.341849]  ret_from_fork+0x22/0x30
[3.341851] Modules linked in:
[3.341854] CR2: 0038
[3.341860] ---[ end trace 3653722a6f936f18 ]---

Fixes: 01b9d4e21148c ("iommu/vt-d: Use dev_iommu_priv_get/set()")
Reported-by: Torsten Hilbrich 
Reported-by: Wendy Wang 
Link: 
https://lore.kernel.org/linux-iommu/96717683-70be-7388-3d2f-61131070a...@secunet.com/
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel/iommu.c | 100 
 1 file changed, 55 insertions(+), 45 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 50431c7b2e71..777b9be60a0e 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -366,7 +366,6 @@ static int iommu_skip_te_disable;
 int intel_iommu_gfx_mapped;
 EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
 
-#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
 #define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
 struct device_domain_info *get_domain_info(struct device *dev)
 {
@@ -376,8 +375,7 @@ struct device_domain_info *get_domain_info(struct device 
*dev)
return NULL;
 
info = dev_iommu_priv_get(dev);
-   if (unlikely(info == DUMMY_DEVICE_DOMAIN_INFO ||
-info == DEFER_DEVICE_DOMAIN_INFO))
+   if (unlikely(info == DEFER_DEVICE_DOMAIN_INFO))
return NULL;
 
return info;
@@ -773,11 +771,6 @@ struct context_entry *iommu_context_addr(struct 
intel_iommu *iommu, u8 bus,
return [devfn];
 }
 
-static int iommu_dummy(struct device *dev)
-{
-   return dev_iommu_priv_get(dev) == DUMMY_DEVICE_DOMAIN_INFO;
-}
-
 static bool attach_deferred(struct device *dev)
 {
return dev_iommu_priv_get(dev) == DEFER_DEVICE_DOMAIN_INFO;
@@ -810,6 +803,53 @@ is_downstream_to_pci_bridge(struct device *dev, struct 
device *bridge)
return false;
 }
 
+static bool quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
+{
+   struct dmar_drhd_unit *drhd;
+   u32 vtbar;
+   int rc;
+
+   /* We know that this device on this chipset has its own IOMMU.
+* If we find it under a different IOMMU, then the BIOS is lying
+*