Patch "powerpc/pseries/iommu: DLPAR add doesn't completely initialize pci_controller" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    powerpc/pseries/iommu: DLPAR add doesn't completely initialize pci_controller

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     powerpc-pseries-iommu-dlpar-add-doesn-t-completely-i.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 681780eeb6af749154ce5feab89ce64fc306c104
Author: Gaurav Batra <gbatra@xxxxxxxxxxxxx>
Date:   Thu Feb 15 16:18:33 2024 -0600

    powerpc/pseries/iommu: DLPAR add doesn't completely initialize pci_controller
    
    [ Upstream commit a5c57fd2e9bd1c8ea8613a8f94fd0be5eccbf321 ]
    
    When a PCI device is dynamically added, the kernel oopses with a NULL
    pointer dereference:
    
      BUG: Kernel NULL pointer dereference on read at 0x00000030
      Faulting instruction address: 0xc0000000006bbe5c
      Oops: Kernel access of bad area, sig: 11 [#1]
      LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
      Modules linked in: rpadlpar_io rpaphp rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache netfs xsk_diag bonding nft_compat nf_tables nfnetlink rfkill binfmt_misc dm_multipath rpcrdma sunrpc rdma_ucm ib_srpt ib_isert iscsi_target_mod target_core_mod ib_umad ib_iser libiscsi scsi_transport_iscsi ib_ipoib rdma_cm iw_cm ib_cm mlx5_ib ib_uverbs ib_core pseries_rng drm drm_panel_orientation_quirks xfs libcrc32c mlx5_core mlxfw sd_mod t10_pi sg tls ibmvscsi ibmveth scsi_transport_srp vmx_crypto pseries_wdt psample dm_mirror dm_region_hash dm_log dm_mod fuse
      CPU: 17 PID: 2685 Comm: drmgr Not tainted 6.7.0-203405+ #66
      Hardware name: IBM,9080-HEX POWER10 (raw) 0x800200 0xf000006 of:IBM,FW1060.00 (NH1060_008) hv:phyp pSeries
      NIP:  c0000000006bbe5c LR: c000000000a13e68 CTR: c0000000000579f8
      REGS: c00000009924f240 TRAP: 0300   Not tainted  (6.7.0-203405+)
      MSR:  8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 24002220  XER: 20040006
      CFAR: c000000000a13e64 DAR: 0000000000000030 DSISR: 40000000 IRQMASK: 0
      ...
      NIP sysfs_add_link_to_group+0x34/0x94
      LR  iommu_device_link+0x5c/0x118
      Call Trace:
       iommu_init_device+0x26c/0x318 (unreliable)
       iommu_device_link+0x5c/0x118
       iommu_init_device+0xa8/0x318
       iommu_probe_device+0xc0/0x134
       iommu_bus_notifier+0x44/0x104
       notifier_call_chain+0xb8/0x19c
       blocking_notifier_call_chain+0x64/0x98
       bus_notify+0x50/0x7c
       device_add+0x640/0x918
       pci_device_add+0x23c/0x298
       of_create_pci_dev+0x400/0x884
       of_scan_pci_dev+0x124/0x1b0
       __of_scan_bus+0x78/0x18c
       pcibios_scan_phb+0x2a4/0x3b0
       init_phb_dynamic+0xb8/0x110
       dlpar_add_slot+0x170/0x3b8 [rpadlpar_io]
       add_slot_store.part.0+0xb4/0x130 [rpadlpar_io]
       kobj_attr_store+0x2c/0x48
       sysfs_kf_write+0x64/0x78
       kernfs_fop_write_iter+0x1b0/0x290
       vfs_write+0x350/0x4a0
       ksys_write+0x84/0x140
       system_call_exception+0x124/0x330
       system_call_vectored_common+0x15c/0x2ec
    
    Commit a940904443e4 ("powerpc/iommu: Add iommu_ops to report capabilities
    and allow blocking domains") broke DLPAR add of PCI devices.
    
    The above added iommu_device structure to pci_controller. During
    system boot, PCI devices are discovered and this newly added iommu_device
    structure is initialized by a call to iommu_device_register().
    
    During DLPAR add of a PCI device, a new pci_controller structure is
    allocated but there are no calls made to iommu_device_register()
    interface.
    
    Fix is to register the iommu device during DLPAR add as well.
    
    Fixes: a940904443e4 ("powerpc/iommu: Add iommu_ops to report capabilities and allow blocking domains")
    Signed-off-by: Gaurav Batra <gbatra@xxxxxxxxxxxxx>
    Reviewed-by: Brian King <brking@xxxxxxxxxxxxxxxxxx>
    Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
    Link: https://msgid.link/20240215221833.4817-1-gbatra@xxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index d9fcff5750271..2689e7139b9ea 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -30,6 +30,16 @@ void *pci_traverse_device_nodes(struct device_node *start,
 				void *data);
 extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
 
+#if defined(CONFIG_IOMMU_API) && (defined(CONFIG_PPC_PSERIES) || \
+				  defined(CONFIG_PPC_POWERNV))
+extern void ppc_iommu_register_device(struct pci_controller *phb);
+extern void ppc_iommu_unregister_device(struct pci_controller *phb);
+#else
+static inline void ppc_iommu_register_device(struct pci_controller *phb) { }
+static inline void ppc_iommu_unregister_device(struct pci_controller *phb) { }
+#endif
+
+
 /* From rtas_pci.h */
 extern void init_pci_config_tokens (void);
 extern unsigned long get_phb_buid (struct device_node *);
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 14251bc5219eb..efaca0c6eff9d 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1344,7 +1344,7 @@ static struct iommu_device *spapr_tce_iommu_probe_device(struct device *dev)
 	struct pci_controller *hose;
 
 	if (!dev_is_pci(dev))
-		return ERR_PTR(-EPERM);
+		return ERR_PTR(-ENODEV);
 
 	pdev = to_pci_dev(dev);
 	hose = pdev->bus->sysdata;
@@ -1393,6 +1393,21 @@ static const struct attribute_group *spapr_tce_iommu_groups[] = {
 	NULL,
 };
 
+void ppc_iommu_register_device(struct pci_controller *phb)
+{
+	iommu_device_sysfs_add(&phb->iommu, phb->parent,
+				spapr_tce_iommu_groups, "iommu-phb%04x",
+				phb->global_number);
+	iommu_device_register(&phb->iommu, &spapr_tce_iommu_ops,
+				phb->parent);
+}
+
+void ppc_iommu_unregister_device(struct pci_controller *phb)
+{
+	iommu_device_unregister(&phb->iommu);
+	iommu_device_sysfs_remove(&phb->iommu);
+}
+
 /*
  * This registers IOMMU devices of PHBs. This needs to happen
  * after core_initcall(iommu_init) + postcore_initcall(pci_driver_init) and
@@ -1403,11 +1418,7 @@ static int __init spapr_tce_setup_phb_iommus_initcall(void)
 	struct pci_controller *hose;
 
 	list_for_each_entry(hose, &hose_list, list_node) {
-		iommu_device_sysfs_add(&hose->iommu, hose->parent,
-				       spapr_tce_iommu_groups, "iommu-phb%04x",
-				       hose->global_number);
-		iommu_device_register(&hose->iommu, &spapr_tce_iommu_ops,
-				      hose->parent);
+		ppc_iommu_register_device(hose);
 	}
 	return 0;
 }
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 4ba8245681192..4448386268d99 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -35,6 +35,8 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
 
 	pseries_msi_allocate_domains(phb);
 
+	ppc_iommu_register_device(phb);
+
 	/* Create EEH devices for the PHB */
 	eeh_phb_pe_create(phb);
 
@@ -76,6 +78,8 @@ int remove_phb_dynamic(struct pci_controller *phb)
 		}
 	}
 
+	ppc_iommu_unregister_device(phb);
+
 	pseries_msi_free_domains(phb);
 
 	/* Keep a reference so phb isn't freed yet */




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux