Blob Blame History Raw
From 11e13750b26517cee98c734463af5fc1dbcca9fa Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Tue, 30 Oct 2018 23:24:32 +0100
Subject: [PATCH] KABI: hide new member in struct iommu_table from genksyms.

References: bsc#1061840
Patch-mainline: no, kabi

The it_userspace table should not be used outside KVM. If anyone abuses
the pointer for anything else they can continue to do so but they will
not get access to the KVM-internal data there. A separate pointer is
added for the new sparse table format.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
 arch/powerpc/include/asm/iommu.h          | 16 +++++++++++-----
 arch/powerpc/platforms/powernv/pci-ioda.c | 11 +++++++++--
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 1317e3bcabe8..e1609a12f148 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -69,8 +69,6 @@ struct iommu_table_ops {
 			long index,
 			unsigned long *hpa,
 			enum dma_data_direction *direction);
-
-	__be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc);
 #endif
 	void (*clear)(struct iommu_table *tbl,
 			long index, long npages);
@@ -79,6 +77,9 @@ struct iommu_table_ops {
 	void (*flush)(struct iommu_table *tbl);
 	void (*free)(struct iommu_table *tbl);
 };
+struct iommu_table_ops_2 {
+	__be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc);
+};
 
 /* These are used by VIO */
 extern struct iommu_table_ops iommu_table_lpar_multi_ops;
@@ -119,16 +120,21 @@ struct iommu_table {
 	unsigned long *it_map;       /* A simple allocation bitmap for now */
 	unsigned long  it_page_shift;/* table iommu page size */
 	struct list_head it_group_list;/* List of iommu_table_group_link */
-	__be64 *it_userspace; /* userspace view of the table */
+	unsigned long *it_userspace; /* userspace view of the table */
 	struct iommu_table_ops *it_ops;
 	struct kref    it_kref;
+#ifndef __GENKSYMS__
+#define it_userspace it_userspace_sparse
+	__be64 *it_userspace; /* userspace view of the table */
 	int it_nid;
+	struct iommu_table_ops_2 *it_ops2;
+#endif
 };
 
 #define IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry) \
-		((tbl)->it_ops->useraddrptr((tbl), (entry), false))
+		((tbl)->it_ops2->useraddrptr((tbl), (entry), false))
 #define IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry) \
-		((tbl)->it_ops->useraddrptr((tbl), (entry), true))
+		((tbl)->it_ops2->useraddrptr((tbl), (entry), true))
 
 /* Pure 2^n version of get_order */
 static inline __attribute_const__
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 1ade757b7fc6..a904e98d74c4 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1881,11 +1881,13 @@ static struct iommu_table_ops pnv_ioda1_iommu_ops = {
 #ifdef CONFIG_IOMMU_API
 	.exchange = pnv_ioda1_tce_xchg,
 	.exchange_rm = pnv_ioda1_tce_xchg_rm,
-	.useraddrptr = pnv_tce_useraddrptr,
 #endif
 	.clear = pnv_ioda1_tce_free,
 	.get = pnv_tce_get,
 };
+static struct iommu_table_ops_2 pnv_ioda1_iommu_ops_2 = {
+	.useraddrptr = pnv_tce_useraddrptr,
+};
 
 #define PHB3_TCE_KILL_INVAL_ALL		PPC_BIT(0)
 #define PHB3_TCE_KILL_INVAL_PE		PPC_BIT(1)
@@ -2051,13 +2053,16 @@ static struct iommu_table_ops pnv_ioda2_iommu_ops = {
 #ifdef CONFIG_IOMMU_API
 	.exchange = pnv_ioda2_tce_xchg,
 	.exchange_rm = pnv_ioda2_tce_xchg_rm,
-	.useraddrptr = pnv_tce_useraddrptr,
 #endif
 	.clear = pnv_ioda2_tce_free,
 	.get = pnv_tce_get,
 	.free = pnv_ioda2_table_free,
 };
 
+static struct iommu_table_ops_2 pnv_ioda2_iommu_ops_2 = {
+	.useraddrptr = pnv_tce_useraddrptr,
+};
+
 static int pnv_pci_ioda_dev_dma_weight(struct pci_dev *dev, void *data)
 {
 	unsigned int *weight = (unsigned int *)data;
@@ -2212,6 +2217,7 @@ static void pnv_pci_ioda1_setup_dma_pe(struct pnv_phb *phb,
 				  IOMMU_PAGE_SHIFT_4K);
 
 	tbl->it_ops = &pnv_ioda1_iommu_ops;
+	tbl->it_ops2 = &pnv_ioda1_iommu_ops_2;
 	pe->table_group.tce32_start = tbl->it_offset << tbl->it_page_shift;
 	pe->table_group.tce32_size = tbl->it_size << tbl->it_page_shift;
 	iommu_init_table(tbl, phb->hose->node);
@@ -2321,6 +2327,7 @@ static long pnv_pci_ioda2_create_table(struct iommu_table_group *table_group,
 		return -ENOMEM;
 
 	tbl->it_ops = &pnv_ioda2_iommu_ops;
+	tbl->it_ops2 = &pnv_ioda2_iommu_ops_2;
 
 	ret = pnv_pci_ioda2_table_alloc_pages(nid,
 			bus_offset, page_shift, window_size,
-- 
2.13.7