linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH kernel v2 0/4] Enable IOMMU support for pseries Secure VMs
@ 2019-12-16  4:19 Alexey Kardashevskiy
  2019-12-16  4:19 ` [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" Alexey Kardashevskiy
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Alexey Kardashevskiy @ 2019-12-16  4:19 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Michael Anderson, Ram Pai, kvm-ppc,
	Paul Mackerras, Thiago Jung Bauermann, David Gibson

This enables IOMMU for SVM. Instead of sharing
a H_PUT_TCE_INDIRECT page, this uses H_PUT_TCE for mapping
and H_STUFF_TCE for clearing TCEs which should bring
acceptable performance at the boot time; otherwise things
work with the same speed anyway.

Please comment. Thanks.


This is based on sha1
37d4e84f765b Linus Torvalds Merge tag 'ceph-for-5.5-rc2' of git://github.com/ceph/ceph-client

Please comment. Thanks.



Alexey Kardashevskiy (3):
  powerpc/pseries: Allow not having
    ibm,hypertas-functions::hcall-multi-tce for DDW
  powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff
    features
  powerpc/pseries/svm: Allow IOMMU to work in SVM

Ram Pai (1):
  Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure
    guests"

 arch/powerpc/include/asm/firmware.h       |  6 ++-
 arch/powerpc/platforms/pseries/firmware.c | 10 +++-
 arch/powerpc/platforms/pseries/iommu.c    | 65 +++++++++++++----------
 3 files changed, 50 insertions(+), 31 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests"
  2019-12-16  4:19 [PATCH kernel v2 0/4] Enable IOMMU support for pseries Secure VMs Alexey Kardashevskiy
@ 2019-12-16  4:19 ` Alexey Kardashevskiy
  2019-12-16 22:58   ` Thiago Jung Bauermann
  2020-01-06 23:33   ` Michael Ellerman
  2019-12-16  4:19 ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW Alexey Kardashevskiy
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 17+ messages in thread
From: Alexey Kardashevskiy @ 2019-12-16  4:19 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Michael Anderson, Ram Pai, kvm-ppc,
	Thiago Jung Bauermann, David Gibson

From: Ram Pai <linuxram@us.ibm.com>

This reverts commit edea902c1c1efb855f77e041f9daf1abe7a9768a.

At the time the change allowed direct DMA ops for secure VMs; however
since then we switched on using SWIOTLB backed with IOMMU (direct mapping)
and to make this work, we need dma_iommu_ops which handles all cases
including TCE mapping I/O pages in the presence of an IOMMU.

Fixes: edea902c1c1e ("powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests")
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
[aik: added "revert" and "fixes:"]
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v2
* made it a revert patch, added "fixes:"
---
 arch/powerpc/platforms/pseries/iommu.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 6ba081dd61c9..df7db33ca93b 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -36,7 +36,6 @@
 #include <asm/udbg.h>
 #include <asm/mmzone.h>
 #include <asm/plpar_wrappers.h>
-#include <asm/svm.h>
 
 #include "pseries.h"
 
@@ -1320,15 +1319,7 @@ void iommu_init_early_pSeries(void)
 	of_reconfig_notifier_register(&iommu_reconfig_nb);
 	register_memory_notifier(&iommu_mem_nb);
 
-	/*
-	 * Secure guest memory is inacessible to devices so regular DMA isn't
-	 * possible.
-	 *
-	 * In that case keep devices' dma_map_ops as NULL so that the generic
-	 * DMA code path will use SWIOTLB to bounce buffers for DMA.
-	 */
-	if (!is_secure_guest())
-		set_pci_dma_ops(&dma_iommu_ops);
+	set_pci_dma_ops(&dma_iommu_ops);
 }
 
 static int __init disable_multitce(char *str)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW
  2019-12-16  4:19 [PATCH kernel v2 0/4] Enable IOMMU support for pseries Secure VMs Alexey Kardashevskiy
  2019-12-16  4:19 ` [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" Alexey Kardashevskiy
@ 2019-12-16  4:19 ` Alexey Kardashevskiy
  2019-12-16 23:07   ` Thiago Jung Bauermann
  2020-01-02 22:02   ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce " Ram Pai
  2019-12-16  4:19 ` [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features Alexey Kardashevskiy
  2019-12-16  4:19 ` [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM Alexey Kardashevskiy
  3 siblings, 2 replies; 17+ messages in thread
From: Alexey Kardashevskiy @ 2019-12-16  4:19 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Michael Anderson, Ram Pai, kvm-ppc,
	Thiago Jung Bauermann, David Gibson

By default a pseries guest supports a H_PUT_TCE hypercall which maps
a single IOMMU page in a DMA window. Additionally the hypervisor may
support H_PUT_TCE_INDIRECT/H_STUFF_TCE which update multiple TCEs at once;
this is advertised via the device tree /rtas/ibm,hypertas-functions
property which Linux converts to FW_FEATURE_MULTITCE.

FW_FEATURE_MULTITCE is checked when dma_iommu_ops is used; however
the code managing the huge DMA window (DDW) ignores it and calls
H_PUT_TCE_INDIRECT even if it is explicitly disabled via
the "multitce=off" kernel command line parameter.

This adds FW_FEATURE_MULTITCE checking to the DDW code path.

This changes tce_build_pSeriesLP to take liobn and page size as
the huge window does not have iommu_table descriptor which usually
the place to store these numbers.

Fixes: 4e8b0cf46b25 ("powerpc/pseries: Add support for dynamic dma windows")
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---

I've put "Fixes" which is from 2011-02-10 but probably should remove it,
or otherwise all these "stable backport branch" scripts will react on
"Fixes" and try pulling this back and we do not really want this as
this patch won't help anyone with anything useful.

---
Changes:
v2
* added "fixes"
---
 arch/powerpc/platforms/pseries/iommu.c | 44 ++++++++++++++++++--------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index df7db33ca93b..f6e9b87c82fc 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -132,10 +132,10 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
 	return be64_to_cpu(*tcep);
 }
 
-static void tce_free_pSeriesLP(struct iommu_table*, long, long);
+static void tce_free_pSeriesLP(unsigned long liobn, long, long);
 static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long);
 
-static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
+static int tce_build_pSeriesLP(unsigned long liobn, long tcenum, long tceshift,
 				long npages, unsigned long uaddr,
 				enum dma_data_direction direction,
 				unsigned long attrs)
@@ -146,25 +146,25 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	int ret = 0;
 	long tcenum_start = tcenum, npages_start = npages;
 
-	rpn = __pa(uaddr) >> TCE_SHIFT;
+	rpn = __pa(uaddr) >> tceshift;
 	proto_tce = TCE_PCI_READ;
 	if (direction != DMA_TO_DEVICE)
 		proto_tce |= TCE_PCI_WRITE;
 
 	while (npages--) {
-		tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
-		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
+		tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
+		rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);
 
 		if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
 			ret = (int)rc;
-			tce_free_pSeriesLP(tbl, tcenum_start,
+			tce_free_pSeriesLP(liobn, tcenum_start,
 			                   (npages_start - (npages + 1)));
 			break;
 		}
 
 		if (rc && printk_ratelimit()) {
 			printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
-			printk("\tindex   = 0x%llx\n", (u64)tbl->it_index);
+			printk("\tindex   = 0x%llx\n", (u64)liobn);
 			printk("\ttcenum  = 0x%llx\n", (u64)tcenum);
 			printk("\ttce val = 0x%llx\n", tce );
 			dump_stack();
@@ -193,7 +193,8 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	unsigned long flags;
 
 	if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) {
-		return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+		return tce_build_pSeriesLP(tbl->it_index, tcenum,
+					   tbl->it_page_shift, npages, uaddr,
 		                           direction, attrs);
 	}
 
@@ -209,8 +210,9 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 		/* If allocation fails, fall back to the loop implementation */
 		if (!tcep) {
 			local_irq_restore(flags);
-			return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
-					    direction, attrs);
+			return tce_build_pSeriesLP(tbl->it_index, tcenum,
+					tbl->it_page_shift,
+					npages, uaddr, direction, attrs);
 		}
 		__this_cpu_write(tce_page, tcep);
 	}
@@ -261,16 +263,16 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	return ret;
 }
 
-static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
+static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages)
 {
 	u64 rc;
 
 	while (npages--) {
-		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
+		rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0);
 
 		if (rc && printk_ratelimit()) {
 			printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
-			printk("\tindex   = 0x%llx\n", (u64)tbl->it_index);
+			printk("\tindex   = 0x%llx\n", (u64)liobn);
 			printk("\ttcenum  = 0x%llx\n", (u64)tcenum);
 			dump_stack();
 		}
@@ -285,7 +287,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
 	u64 rc;
 
 	if (!firmware_has_feature(FW_FEATURE_MULTITCE))
-		return tce_free_pSeriesLP(tbl, tcenum, npages);
+		return tce_free_pSeriesLP(tbl->it_index, tcenum, npages);
 
 	rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
 
@@ -400,6 +402,20 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
 	u64 rc = 0;
 	long l, limit;
 
+	if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
+		unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
+		unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
+				be64_to_cpu(maprange->dma_base);
+		unsigned long tcenum = dmastart >> tceshift;
+		unsigned long npages = num_pfn << PAGE_SHIFT >>
+				be32_to_cpu(maprange->tce_shift);
+		void *uaddr = __va(start_pfn << PAGE_SHIFT);
+
+		return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn),
+				tcenum, tceshift, npages, (unsigned long) uaddr,
+				DMA_BIDIRECTIONAL, 0);
+	}
+
 	local_irq_disable();	/* to protect tcep and the page behind it */
 	tcep = __this_cpu_read(tce_page);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features
  2019-12-16  4:19 [PATCH kernel v2 0/4] Enable IOMMU support for pseries Secure VMs Alexey Kardashevskiy
  2019-12-16  4:19 ` [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" Alexey Kardashevskiy
  2019-12-16  4:19 ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW Alexey Kardashevskiy
@ 2019-12-16  4:19 ` Alexey Kardashevskiy
  2019-12-16 23:19   ` Thiago Jung Bauermann
  2020-01-02 22:24   ` Ram Pai
  2019-12-16  4:19 ` [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM Alexey Kardashevskiy
  3 siblings, 2 replies; 17+ messages in thread
From: Alexey Kardashevskiy @ 2019-12-16  4:19 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Michael Anderson, Ram Pai, kvm-ppc,
	Thiago Jung Bauermann, David Gibson

H_PUT_TCE_INDIRECT allows packing up to 512 TCE updates into a single
hypercall; H_STUFF_TCE can clear lots in a single hypercall too.

However, unlike H_STUFF_TCE (which writes the same TCE to all entries),
H_PUT_TCE_INDIRECT uses a 4K page with new TCEs. In a secure VM
environment this means sharing a secure VM page with a hypervisor which
we would rather avoid.

This splits the FW_FEATURE_MULTITCE feature into FW_FEATURE_PUT_TCE_IND
and FW_FEATURE_STUFF_TCE. "hcall-multi-tce" in
the "/rtas/ibm,hypertas-functions" device tree property sets both;
the "multitce=off" kernel command line parameter disables both.

This should not cause behavioural change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v2
* instead of checking for secure VM here and there, this adds a new
FW feature
* moved SVM enablement to a separate patch
---
 arch/powerpc/include/asm/firmware.h       |  6 ++++--
 arch/powerpc/platforms/pseries/firmware.c |  3 ++-
 arch/powerpc/platforms/pseries/iommu.c    | 12 +++++++-----
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index b3e214a97f3a..ca33f4ef6cb4 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -33,7 +33,7 @@
 #define FW_FEATURE_LLAN		ASM_CONST(0x0000000000010000)
 #define FW_FEATURE_BULK_REMOVE	ASM_CONST(0x0000000000020000)
 #define FW_FEATURE_XDABR	ASM_CONST(0x0000000000040000)
-#define FW_FEATURE_MULTITCE	ASM_CONST(0x0000000000080000)
+#define FW_FEATURE_PUT_TCE_IND	ASM_CONST(0x0000000000080000)
 #define FW_FEATURE_SPLPAR	ASM_CONST(0x0000000000100000)
 #define FW_FEATURE_LPAR		ASM_CONST(0x0000000000400000)
 #define FW_FEATURE_PS3_LV1	ASM_CONST(0x0000000000800000)
@@ -51,6 +51,7 @@
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0000001000000000)
 #define FW_FEATURE_PAPR_SCM 	ASM_CONST(0x0000002000000000)
 #define FW_FEATURE_ULTRAVISOR	ASM_CONST(0x0000004000000000)
+#define FW_FEATURE_STUFF_TCE	ASM_CONST(0x0000008000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -63,7 +64,8 @@ enum {
 		FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
 		FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
 		FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
-		FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
+		FW_FEATURE_PUT_TCE_IND | FW_FEATURE_STUFF_TCE |
+		FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
 		FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO |
 		FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
 		FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index d4a8f1702417..d3acff23f2e3 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -55,7 +55,8 @@ hypertas_fw_features_table[] = {
 	{FW_FEATURE_LLAN,		"hcall-lLAN"},
 	{FW_FEATURE_BULK_REMOVE,	"hcall-bulk"},
 	{FW_FEATURE_XDABR,		"hcall-xdabr"},
-	{FW_FEATURE_MULTITCE,		"hcall-multi-tce"},
+	{FW_FEATURE_PUT_TCE_IND | FW_FEATURE_STUFF_TCE,
+					"hcall-multi-tce"},
 	{FW_FEATURE_SPLPAR,		"hcall-splpar"},
 	{FW_FEATURE_VPHN,		"hcall-vphn"},
 	{FW_FEATURE_SET_MODE,		"hcall-set-mode"},
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index f6e9b87c82fc..07b91938c3cc 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -192,7 +192,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	int ret = 0;
 	unsigned long flags;
 
-	if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) {
+	if ((npages == 1) || !firmware_has_feature(FW_FEATURE_PUT_TCE_IND)) {
 		return tce_build_pSeriesLP(tbl->it_index, tcenum,
 					   tbl->it_page_shift, npages, uaddr,
 		                           direction, attrs);
@@ -286,7 +286,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
 {
 	u64 rc;
 
-	if (!firmware_has_feature(FW_FEATURE_MULTITCE))
+	if (!firmware_has_feature(FW_FEATURE_STUFF_TCE))
 		return tce_free_pSeriesLP(tbl->it_index, tcenum, npages);
 
 	rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
@@ -402,7 +402,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
 	u64 rc = 0;
 	long l, limit;
 
-	if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
+	if (!firmware_has_feature(FW_FEATURE_PUT_TCE_IND)) {
 		unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
 		unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
 				be64_to_cpu(maprange->dma_base);
@@ -1342,9 +1342,11 @@ static int __init disable_multitce(char *str)
 {
 	if (strcmp(str, "off") == 0 &&
 	    firmware_has_feature(FW_FEATURE_LPAR) &&
-	    firmware_has_feature(FW_FEATURE_MULTITCE)) {
+	    (firmware_has_feature(FW_FEATURE_PUT_TCE_IND) ||
+	     firmware_has_feature(FW_FEATURE_STUFF_TCE))) {
 		printk(KERN_INFO "Disabling MULTITCE firmware feature\n");
-		powerpc_firmware_features &= ~FW_FEATURE_MULTITCE;
+		powerpc_firmware_features &=
+			~(FW_FEATURE_PUT_TCE_IND | FW_FEATURE_STUFF_TCE);
 	}
 	return 1;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM
  2019-12-16  4:19 [PATCH kernel v2 0/4] Enable IOMMU support for pseries Secure VMs Alexey Kardashevskiy
                   ` (2 preceding siblings ...)
  2019-12-16  4:19 ` [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features Alexey Kardashevskiy
@ 2019-12-16  4:19 ` Alexey Kardashevskiy
  2019-12-16 23:23   ` Thiago Jung Bauermann
  2020-01-02 22:21   ` Ram Pai
  3 siblings, 2 replies; 17+ messages in thread
From: Alexey Kardashevskiy @ 2019-12-16  4:19 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Michael Anderson, Ram Pai, kvm-ppc,
	Thiago Jung Bauermann, David Gibson

H_PUT_TCE_INDIRECT uses a shared page to send up to 512 TCE to
a hypervisor in a single hypercall. This does not work for secure VMs
as the page needs to be shared or the VM should use H_PUT_TCE instead.

This disables H_PUT_TCE_INDIRECT by clearing the FW_FEATURE_PUT_TCE_IND
feature bit so SVMs will map TCEs using H_PUT_TCE.

This is not a part of init_svm() as it is called too late after FW
patching is done and may result in a warning like this:

[    3.727716] Firmware features changed after feature patching!
[    3.727965] WARNING: CPU: 0 PID: 1 at (...)arch/powerpc/lib/feature-fixups.c:466 check_features+0xa4/0xc0

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
v2
* new in the patchset
---
 arch/powerpc/platforms/pseries/firmware.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index d3acff23f2e3..3e49cc23a97a 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -22,6 +22,7 @@
 #include <asm/firmware.h>
 #include <asm/prom.h>
 #include <asm/udbg.h>
+#include <asm/svm.h>
 
 #include "pseries.h"
 
@@ -101,6 +102,12 @@ static void __init fw_hypertas_feature_init(const char *hypertas,
 		}
 	}
 
+	if (is_secure_guest() &&
+	    (powerpc_firmware_features & FW_FEATURE_PUT_TCE_IND)) {
+		powerpc_firmware_features &= ~FW_FEATURE_PUT_TCE_IND;
+		pr_debug("SVM: disabling PUT_TCE_IND firmware feature\n");
+	}
+
 	pr_debug(" <- fw_hypertas_feature_init()\n");
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests"
  2019-12-16  4:19 ` [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" Alexey Kardashevskiy
@ 2019-12-16 22:58   ` Thiago Jung Bauermann
  2020-01-06 23:33   ` Michael Ellerman
  1 sibling, 0 replies; 17+ messages in thread
From: Thiago Jung Bauermann @ 2019-12-16 22:58 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, Ram Pai, kvm-ppc, linuxppc-dev, David Gibson


Hello Alexey,

Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> From: Ram Pai <linuxram@us.ibm.com>
>
> This reverts commit edea902c1c1efb855f77e041f9daf1abe7a9768a.
>
> At the time the change allowed direct DMA ops for secure VMs; however
> since then we switched on using SWIOTLB backed with IOMMU (direct mapping)
> and to make this work, we need dma_iommu_ops which handles all cases
> including TCE mapping I/O pages in the presence of an IOMMU.
>
> Fixes: edea902c1c1e ("powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests")
> Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> [aik: added "revert" and "fixes:"]
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Tested-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>

-- 
Thiago Jung Bauermann
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW
  2019-12-16  4:19 ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW Alexey Kardashevskiy
@ 2019-12-16 23:07   ` Thiago Jung Bauermann
  2019-12-17  0:09     ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce " Alexey Kardashevskiy
  2020-01-02 22:02   ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce " Ram Pai
  1 sibling, 1 reply; 17+ messages in thread
From: Thiago Jung Bauermann @ 2019-12-16 23:07 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, Ram Pai, kvm-ppc, linuxppc-dev, David Gibson


Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> By default a pseries guest supports a H_PUT_TCE hypercall which maps
> a single IOMMU page in a DMA window. Additionally the hypervisor may
> support H_PUT_TCE_INDIRECT/H_STUFF_TCE which update multiple TCEs at once;
> this is advertised via the device tree /rtas/ibm,hypertas-functions
> property which Linux converts to FW_FEATURE_MULTITCE.
>
> FW_FEATURE_MULTITCE is checked when dma_iommu_ops is used; however
> the code managing the huge DMA window (DDW) ignores it and calls
> H_PUT_TCE_INDIRECT even if it is explicitly disabled via
> the "multitce=off" kernel command line parameter.
>
> This adds FW_FEATURE_MULTITCE checking to the DDW code path.
>
> This changes tce_build_pSeriesLP to take liobn and page size as
> the huge window does not have iommu_table descriptor which usually
> the place to store these numbers.
>
> Fixes: 4e8b0cf46b25 ("powerpc/pseries: Add support for dynamic dma windows")
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Tested-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>

Some minor nits below. Feel free to ignore.

> @@ -146,25 +146,25 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  	int ret = 0;
>  	long tcenum_start = tcenum, npages_start = npages;
>
> -	rpn = __pa(uaddr) >> TCE_SHIFT;
> +	rpn = __pa(uaddr) >> tceshift;
>  	proto_tce = TCE_PCI_READ;
>  	if (direction != DMA_TO_DEVICE)
>  		proto_tce |= TCE_PCI_WRITE;
>
>  	while (npages--) {
> -		tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
> +		tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);

Is it necessary to cast to u64 here? plpar_tce_put() takes unsigned long
for both arguments.

> @@ -261,16 +263,16 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  	return ret;
>  }
>
> -static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
> +static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages)
>  {
>  	u64 rc;
>
>  	while (npages--) {
> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0);

Same comment regarding cast to u64.

> @@ -400,6 +402,20 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
>  	u64 rc = 0;
>  	long l, limit;
>
> +	if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
> +		unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
> +		unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
> +				be64_to_cpu(maprange->dma_base);
> +		unsigned long tcenum = dmastart >> tceshift;
> +		unsigned long npages = num_pfn << PAGE_SHIFT >>
> +				be32_to_cpu(maprange->tce_shift);

Could use the tceshift variable here.

> +		void *uaddr = __va(start_pfn << PAGE_SHIFT);
> +
> +		return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn),
> +				tcenum, tceshift, npages, (unsigned long) uaddr,
> +				DMA_BIDIRECTIONAL, 0);
> +	}
> +
>  	local_irq_disable();	/* to protect tcep and the page behind it */
>  	tcep = __this_cpu_read(tce_page);


--
Thiago Jung Bauermann
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features
  2019-12-16  4:19 ` [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features Alexey Kardashevskiy
@ 2019-12-16 23:19   ` Thiago Jung Bauermann
  2020-01-02 22:24   ` Ram Pai
  1 sibling, 0 replies; 17+ messages in thread
From: Thiago Jung Bauermann @ 2019-12-16 23:19 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, Ram Pai, kvm-ppc, linuxppc-dev, David Gibson


Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> H_PUT_TCE_INDIRECT allows packing up to 512 TCE updates into a single
> hypercall; H_STUFF_TCE can clear lots in a single hypercall too.
>
> However, unlike H_STUFF_TCE (which writes the same TCE to all entries),
> H_PUT_TCE_INDIRECT uses a 4K page with new TCEs. In a secure VM
> environment this means sharing a secure VM page with a hypervisor which
> we would rather avoid.
>
> This splits the FW_FEATURE_MULTITCE feature into FW_FEATURE_PUT_TCE_IND
> and FW_FEATURE_STUFF_TCE. "hcall-multi-tce" in
> the "/rtas/ibm,hypertas-functions" device tree property sets both;
> the "multitce=off" kernel command line parameter disables both.
>
> This should not cause behavioural change.
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Tested-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>

-- 
Thiago Jung Bauermann
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM
  2019-12-16  4:19 ` [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM Alexey Kardashevskiy
@ 2019-12-16 23:23   ` Thiago Jung Bauermann
  2020-01-02 22:21   ` Ram Pai
  1 sibling, 0 replies; 17+ messages in thread
From: Thiago Jung Bauermann @ 2019-12-16 23:23 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, Ram Pai, kvm-ppc, linuxppc-dev, David Gibson


Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> H_PUT_TCE_INDIRECT uses a shared page to send up to 512 TCE to
> a hypervisor in a single hypercall. This does not work for secure VMs
> as the page needs to be shared or the VM should use H_PUT_TCE instead.
>
> This disables H_PUT_TCE_INDIRECT by clearing the FW_FEATURE_PUT_TCE_IND
> feature bit so SVMs will map TCEs using H_PUT_TCE.
>
> This is not a part of init_svm() as it is called too late after FW
> patching is done and may result in a warning like this:
>
> [    3.727716] Firmware features changed after feature patching!
> [    3.727965] WARNING: CPU: 0 PID: 1 at (...)arch/powerpc/lib/feature-fixups.c:466 check_features+0xa4/0xc0
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Tested-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>

-- 
Thiago Jung Bauermann
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce for DDW
  2019-12-16 23:07   ` Thiago Jung Bauermann
@ 2019-12-17  0:09     ` Alexey Kardashevskiy
  2019-12-17  2:06       ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce " Thiago Jung Bauermann
  0 siblings, 1 reply; 17+ messages in thread
From: Alexey Kardashevskiy @ 2019-12-17  0:09 UTC (permalink / raw)
  To: Thiago Jung Bauermann
  Cc: Michael Anderson, Ram Pai, kvm-ppc, linuxppc-dev, David Gibson



On 17/12/2019 10:07, Thiago Jung Bauermann wrote:
> 
> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
> 
>> By default a pseries guest supports a H_PUT_TCE hypercall which maps
>> a single IOMMU page in a DMA window. Additionally the hypervisor may
>> support H_PUT_TCE_INDIRECT/H_STUFF_TCE which update multiple TCEs at once;
>> this is advertised via the device tree /rtas/ibm,hypertas-functions
>> property which Linux converts to FW_FEATURE_MULTITCE.
>>
>> FW_FEATURE_MULTITCE is checked when dma_iommu_ops is used; however
>> the code managing the huge DMA window (DDW) ignores it and calls
>> H_PUT_TCE_INDIRECT even if it is explicitly disabled via
>> the "multitce=off" kernel command line parameter.
>>
>> This adds FW_FEATURE_MULTITCE checking to the DDW code path.
>>
>> This changes tce_build_pSeriesLP to take liobn and page size as
>> the huge window does not have iommu_table descriptor which usually
>> the place to store these numbers.
>>
>> Fixes: 4e8b0cf46b25 ("powerpc/pseries: Add support for dynamic dma windows")
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> 
> Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> Tested-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> 
> Some minor nits below. Feel free to ignore.
> 
>> @@ -146,25 +146,25 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
>>  	int ret = 0;
>>  	long tcenum_start = tcenum, npages_start = npages;
>>
>> -	rpn = __pa(uaddr) >> TCE_SHIFT;
>> +	rpn = __pa(uaddr) >> tceshift;
>>  	proto_tce = TCE_PCI_READ;
>>  	if (direction != DMA_TO_DEVICE)
>>  		proto_tce |= TCE_PCI_WRITE;
>>
>>  	while (npages--) {
>> -		tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
>> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
>> +		tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
>> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);
> 
> Is it necessary to cast to u64 here? plpar_tce_put() takes unsigned long
> for both arguments.


Looked as an unrelated change. Small but still unrelated.


> 
>> @@ -261,16 +263,16 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
>>  	return ret;
>>  }
>>
>> -static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
>> +static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages)
>>  {
>>  	u64 rc;
>>
>>  	while (npages--) {
>> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
>> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0);
> 
> Same comment regarding cast to u64.
> 
>> @@ -400,6 +402,20 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
>>  	u64 rc = 0;
>>  	long l, limit;
>>
>> +	if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
>> +		unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
>> +		unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
>> +				be64_to_cpu(maprange->dma_base);
>> +		unsigned long tcenum = dmastart >> tceshift;
>> +		unsigned long npages = num_pfn << PAGE_SHIFT >>
>> +				be32_to_cpu(maprange->tce_shift);
> 
> Could use the tceshift variable here.


True, overlooked.
Thanks for the reviews!


> 
>> +		void *uaddr = __va(start_pfn << PAGE_SHIFT);
>> +
>> +		return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn),
>> +				tcenum, tceshift, npages, (unsigned long) uaddr,
>> +				DMA_BIDIRECTIONAL, 0);
>> +	}
>> +
>>  	local_irq_disable();	/* to protect tcep and the page behind it */
>>  	tcep = __this_cpu_read(tce_page);
> 
> 
> --
> Thiago Jung Bauermann
> IBM Linux Technology Center
> 

-- 
Alexey

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW
  2019-12-17  0:09     ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce " Alexey Kardashevskiy
@ 2019-12-17  2:06       ` Thiago Jung Bauermann
  0 siblings, 0 replies; 17+ messages in thread
From: Thiago Jung Bauermann @ 2019-12-17  2:06 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, Ram Pai, kvm-ppc, linuxppc-dev, David Gibson


Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> On 17/12/2019 10:07, Thiago Jung Bauermann wrote:
>>
>> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
>>
>>> By default a pseries guest supports a H_PUT_TCE hypercall which maps
>>> a single IOMMU page in a DMA window. Additionally the hypervisor may
>>> support H_PUT_TCE_INDIRECT/H_STUFF_TCE which update multiple TCEs at once;
>>> this is advertised via the device tree /rtas/ibm,hypertas-functions
>>> property which Linux converts to FW_FEATURE_MULTITCE.
>>>
>>> FW_FEATURE_MULTITCE is checked when dma_iommu_ops is used; however
>>> the code managing the huge DMA window (DDW) ignores it and calls
>>> H_PUT_TCE_INDIRECT even if it is explicitly disabled via
>>> the "multitce=off" kernel command line parameter.
>>>
>>> This adds FW_FEATURE_MULTITCE checking to the DDW code path.
>>>
>>> This changes tce_build_pSeriesLP to take liobn and page size as
>>> the huge window does not have iommu_table descriptor which usually
>>> the place to store these numbers.
>>>
>>> Fixes: 4e8b0cf46b25 ("powerpc/pseries: Add support for dynamic dma windows")
>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>
>> Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
>> Tested-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
>>
>> Some minor nits below. Feel free to ignore.
>>
>>> @@ -146,25 +146,25 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
>>>  	int ret = 0;
>>>  	long tcenum_start = tcenum, npages_start = npages;
>>>
>>> -	rpn = __pa(uaddr) >> TCE_SHIFT;
>>> +	rpn = __pa(uaddr) >> tceshift;
>>>  	proto_tce = TCE_PCI_READ;
>>>  	if (direction != DMA_TO_DEVICE)
>>>  		proto_tce |= TCE_PCI_WRITE;
>>>
>>>  	while (npages--) {
>>> -		tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
>>> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
>>> +		tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
>>> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);
>>
>> Is it necessary to cast to u64 here? plpar_tce_put() takes unsigned long
>> for both arguments.
>
> Looked as an unrelated change. Small but still unrelated.

Ah, I hadn't noticed that the cast was already in the original code.

>>> @@ -400,6 +402,20 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
>>>  	u64 rc = 0;
>>>  	long l, limit;
>>>
>>> +	if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
>>> +		unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
>>> +		unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
>>> +				be64_to_cpu(maprange->dma_base);
>>> +		unsigned long tcenum = dmastart >> tceshift;
>>> +		unsigned long npages = num_pfn << PAGE_SHIFT >>
>>> +				be32_to_cpu(maprange->tce_shift);
>>
>> Could use the tceshift variable here.
>
>
> True, overlooked.
> Thanks for the reviews!

Thank you for the patches!

--
Thiago Jung Bauermann
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re:  [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce for DDW
  2019-12-16  4:19 ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW Alexey Kardashevskiy
  2019-12-16 23:07   ` Thiago Jung Bauermann
@ 2020-01-02 22:02   ` Ram Pai
  1 sibling, 0 replies; 17+ messages in thread
From: Ram Pai @ 2020-01-02 22:02 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, kvm-ppc, linuxppc-dev, Thiago Jung Bauermann,
	David Gibson

On Mon, Dec 16, 2019 at 03:19:22PM +1100, Alexey Kardashevskiy wrote:
> By default a pseries guest supports a H_PUT_TCE hypercall which maps
> a single IOMMU page in a DMA window. Additionally the hypervisor may
> support H_PUT_TCE_INDIRECT/H_STUFF_TCE which update multiple TCEs at once;
> this is advertised via the device tree /rtas/ibm,hypertas-functions
> property which Linux converts to FW_FEATURE_MULTITCE.
> 
> FW_FEATURE_MULTITCE is checked when dma_iommu_ops is used; however
> the code managing the huge DMA window (DDW) ignores it and calls
> H_PUT_TCE_INDIRECT even if it is explicitly disabled via
> the "multitce=off" kernel command line parameter.
> 
> This adds FW_FEATURE_MULTITCE checking to the DDW code path.
> 
> This changes tce_build_pSeriesLP to take liobn and page size as
> the huge window does not have iommu_table descriptor which usually
> the place to store these numbers.
> 
> Fixes: 4e8b0cf46b25 ("powerpc/pseries: Add support for dynamic dma windows")
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> 
> I've put "Fixes" which is from 2011-02-10 but probably should remove it,
> or otherwise all these "stable backport branch" scripts will react on
> "Fixes" and try pulling this back and we do not really want this as
> this patch won't help anyone with anything useful.
> 
> ---
> Changes:
> v2
> * added "fixes"
> ---
>  arch/powerpc/platforms/pseries/iommu.c | 44 ++++++++++++++++++--------
>  1 file changed, 30 insertions(+), 14 deletions(-)

some minor comments below.

> 
> diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
> index df7db33ca93b..f6e9b87c82fc 100644
> --- a/arch/powerpc/platforms/pseries/iommu.c
> +++ b/arch/powerpc/platforms/pseries/iommu.c
> @@ -132,10 +132,10 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
>  	return be64_to_cpu(*tcep);
>  }
> 
> -static void tce_free_pSeriesLP(struct iommu_table*, long, long);
> +static void tce_free_pSeriesLP(unsigned long liobn, long, long);
>  static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long);
> 
> -static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
> +static int tce_build_pSeriesLP(unsigned long liobn, long tcenum, long tceshift,
>  				long npages, unsigned long uaddr,
>  				enum dma_data_direction direction,
>  				unsigned long attrs)
> @@ -146,25 +146,25 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  	int ret = 0;
>  	long tcenum_start = tcenum, npages_start = npages;
> 
> -	rpn = __pa(uaddr) >> TCE_SHIFT;
> +	rpn = __pa(uaddr) >> tceshift;
>  	proto_tce = TCE_PCI_READ;
>  	if (direction != DMA_TO_DEVICE)
>  		proto_tce |= TCE_PCI_WRITE;
> 
>  	while (npages--) {
> -		tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
> +		tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);
> 
>  		if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
>  			ret = (int)rc;
> -			tce_free_pSeriesLP(tbl, tcenum_start,
> +			tce_free_pSeriesLP(liobn, tcenum_start,
>  			                   (npages_start - (npages + 1)));
>  			break;
>  		}
> 
>  		if (rc && printk_ratelimit()) {
>  			printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
> -			printk("\tindex   = 0x%llx\n", (u64)tbl->it_index);
> +			printk("\tindex   = 0x%llx\n", (u64)liobn);
>  			printk("\ttcenum  = 0x%llx\n", (u64)tcenum);
>  			printk("\ttce val = 0x%llx\n", tce );
>  			dump_stack();
> @@ -193,7 +193,8 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  	unsigned long flags;
> 
>  	if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) {
> -		return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
> +		return tce_build_pSeriesLP(tbl->it_index, tcenum,
> +					   tbl->it_page_shift, npages, uaddr,
>  		                           direction, attrs);
>  	}
> 
> @@ -209,8 +210,9 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  		/* If allocation fails, fall back to the loop implementation */
>  		if (!tcep) {
>  			local_irq_restore(flags);
> -			return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
> -					    direction, attrs);
> +			return tce_build_pSeriesLP(tbl->it_index, tcenum,
> +					tbl->it_page_shift,
> +					npages, uaddr, direction, attrs);
>  		}
>  		__this_cpu_write(tce_page, tcep);
>  	}
> @@ -261,16 +263,16 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
>  	return ret;
>  }
> 
> -static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
> +static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages)
>  {
>  	u64 rc;
> 
>  	while (npages--) {
> -		rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
> +		rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0);

minor nitpick.  The magic number '12' can be replaced by TCE_SHIFT

> 
>  		if (rc && printk_ratelimit()) {
>  			printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
> -			printk("\tindex   = 0x%llx\n", (u64)tbl->it_index);
> +			printk("\tindex   = 0x%llx\n", (u64)liobn);
>  			printk("\ttcenum  = 0x%llx\n", (u64)tcenum);
>  			dump_stack();
>  		}
> @@ -285,7 +287,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
>  	u64 rc;
> 
>  	if (!firmware_has_feature(FW_FEATURE_MULTITCE))
> -		return tce_free_pSeriesLP(tbl, tcenum, npages);
> +		return tce_free_pSeriesLP(tbl->it_index, tcenum, npages);
> 
>  	rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);

Same here.

> 
> @@ -400,6 +402,20 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
>  	u64 rc = 0;
>  	long l, limit;
> 
> +	if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
> +		unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
> +		unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
> +				be64_to_cpu(maprange->dma_base);
> +		unsigned long tcenum = dmastart >> tceshift;
> +		unsigned long npages = num_pfn << PAGE_SHIFT >>
> +				be32_to_cpu(maprange->tce_shift);
				^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      this can be 'tceshift'. Saves some cpu-cycles.



> +		void *uaddr = __va(start_pfn << PAGE_SHIFT);
> +
> +		return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn),
> +				tcenum, tceshift, npages, (unsigned long) uaddr,
> +				DMA_BIDIRECTIONAL, 0);
> +	}
> +

The code under the if statement, go into a static inline function of its own?


>  	local_irq_disable();	/* to protect tcep and the page behind it */
>  	tcep = __this_cpu_read(tce_page);
> 


Reviewed-by: Ram Pai <linuxram@us.ibm.com>

-- 
Ram Pai


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM
  2019-12-16  4:19 ` [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM Alexey Kardashevskiy
  2019-12-16 23:23   ` Thiago Jung Bauermann
@ 2020-01-02 22:21   ` Ram Pai
  2020-01-03  0:08     ` David Gibson
  1 sibling, 1 reply; 17+ messages in thread
From: Ram Pai @ 2020-01-02 22:21 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, kvm-ppc, linuxppc-dev, Thiago Jung Bauermann,
	David Gibson

On Mon, Dec 16, 2019 at 03:19:24PM +1100, Alexey Kardashevskiy wrote:
> H_PUT_TCE_INDIRECT uses a shared page to send up to 512 TCE to
> a hypervisor in a single hypercall.

Actually H_PUT_TCE_INDIRECT never used shared page.  It would have
used shared pages if the 'shared-page' solution was accepted. :)



> This does not work for secure VMs
> as the page needs to be shared or the VM should use H_PUT_TCE instead.

Maybe you should say something like this.. ?

H_PUT_TCE_INDIRECT does not work for secure VMs, since the page
containing the TCE entries is not accessible to the hypervisor.

> 
> This disables H_PUT_TCE_INDIRECT by clearing the FW_FEATURE_PUT_TCE_IND
> feature bit so SVMs will map TCEs using H_PUT_TCE.
> 
> This is not a part of init_svm() as it is called too late after FW
> patching is done and may result in a warning like this:
> 
> [    3.727716] Firmware features changed after feature patching!
> [    3.727965] WARNING: CPU: 0 PID: 1 at (...)arch/powerpc/lib/feature-fixups.c:466 check_features+0xa4/0xc0
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>


Reviewed-by: Ram Pai <linuxram@us.ibm.com>


> ---
> Changes:
> v2
> * new in the patchset
> ---
>  arch/powerpc/platforms/pseries/firmware.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
> index d3acff23f2e3..3e49cc23a97a 100644
> --- a/arch/powerpc/platforms/pseries/firmware.c
> +++ b/arch/powerpc/platforms/pseries/firmware.c
> @@ -22,6 +22,7 @@
>  #include <asm/firmware.h>
>  #include <asm/prom.h>
>  #include <asm/udbg.h>
> +#include <asm/svm.h>
> 
>  #include "pseries.h"
> 
> @@ -101,6 +102,12 @@ static void __init fw_hypertas_feature_init(const char *hypertas,
>  		}
>  	}
> 
> +	if (is_secure_guest() &&
> +	    (powerpc_firmware_features & FW_FEATURE_PUT_TCE_IND)) {
> +		powerpc_firmware_features &= ~FW_FEATURE_PUT_TCE_IND;
> +		pr_debug("SVM: disabling PUT_TCE_IND firmware feature\n");
> +	}
> +
>  	pr_debug(" <- fw_hypertas_feature_init()\n");
>  }
> 
> -- 
> 2.17.1

-- 
Ram Pai


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re:  [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features
  2019-12-16  4:19 ` [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features Alexey Kardashevskiy
  2019-12-16 23:19   ` Thiago Jung Bauermann
@ 2020-01-02 22:24   ` Ram Pai
  1 sibling, 0 replies; 17+ messages in thread
From: Ram Pai @ 2020-01-02 22:24 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Michael Anderson, kvm-ppc, linuxppc-dev, Thiago Jung Bauermann,
	David Gibson

On Mon, Dec 16, 2019 at 03:19:23PM +1100, Alexey Kardashevskiy wrote:
> H_PUT_TCE_INDIRECT allows packing up to 512 TCE updates into a single
> hypercall; H_STUFF_TCE can clear lots in a single hypercall too.
> 
> However, unlike H_STUFF_TCE (which writes the same TCE to all entries),
> H_PUT_TCE_INDIRECT uses a 4K page with new TCEs. In a secure VM
> environment this means sharing a secure VM page with a hypervisor which
> we would rather avoid.
> 
> This splits the FW_FEATURE_MULTITCE feature into FW_FEATURE_PUT_TCE_IND

Can FW_FEATURE_PUT_TCE_IND be made FW_FEATURE_PUT_TCE_INDIRECT?
It conveys the meaning a bit better than FW_FEATURE_PUT_TCE_IND.

This patch is a good optimization. 

Reviewed-by: Ram Pai <linuxram@us.ibm.com>

Thanks,
RP
> -- 

snip..

> 2.17.1

-- 
Ram Pai


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM
  2020-01-02 22:21   ` Ram Pai
@ 2020-01-03  0:08     ` David Gibson
  2020-01-03  2:06       ` Ram Pai
  0 siblings, 1 reply; 17+ messages in thread
From: David Gibson @ 2020-01-03  0:08 UTC (permalink / raw)
  To: Ram Pai
  Cc: Alexey Kardashevskiy, Michael Anderson, kvm-ppc, linuxppc-dev,
	Thiago Jung Bauermann

[-- Attachment #1: Type: text/plain, Size: 2714 bytes --]

On Thu, Jan 02, 2020 at 02:21:06PM -0800, Ram Pai wrote:
> On Mon, Dec 16, 2019 at 03:19:24PM +1100, Alexey Kardashevskiy wrote:
> > H_PUT_TCE_INDIRECT uses a shared page to send up to 512 TCE to
> > a hypervisor in a single hypercall.
> 
> Actually H_PUT_TCE_INDIRECT never used shared page.  It would have
> used shared pages if the 'shared-page' solution was accepted. :)

Well, it depends what you mean by "shared".  In the non-PEF case we do
use a shared page in the sense that it is accessed by both guest and
hypervisor.  It's just not shared in the PEF sense.

> > This does not work for secure VMs
> > as the page needs to be shared or the VM should use H_PUT_TCE instead.
> 
> Maybe you should say something like this.. ?
> 
> H_PUT_TCE_INDIRECT does not work for secure VMs, since the page
> containing the TCE entries is not accessible to the hypervisor.
> 
> > 
> > This disables H_PUT_TCE_INDIRECT by clearing the FW_FEATURE_PUT_TCE_IND
> > feature bit so SVMs will map TCEs using H_PUT_TCE.
> > 
> > This is not a part of init_svm() as it is called too late after FW
> > patching is done and may result in a warning like this:
> > 
> > [    3.727716] Firmware features changed after feature patching!
> > [    3.727965] WARNING: CPU: 0 PID: 1 at (...)arch/powerpc/lib/feature-fixups.c:466 check_features+0xa4/0xc0
> > 
> > Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> 
> 
> Reviewed-by: Ram Pai <linuxram@us.ibm.com>
> 
> 
> > ---
> > Changes:
> > v2
> > * new in the patchset
> > ---
> >  arch/powerpc/platforms/pseries/firmware.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
> > index d3acff23f2e3..3e49cc23a97a 100644
> > --- a/arch/powerpc/platforms/pseries/firmware.c
> > +++ b/arch/powerpc/platforms/pseries/firmware.c
> > @@ -22,6 +22,7 @@
> >  #include <asm/firmware.h>
> >  #include <asm/prom.h>
> >  #include <asm/udbg.h>
> > +#include <asm/svm.h>
> > 
> >  #include "pseries.h"
> > 
> > @@ -101,6 +102,12 @@ static void __init fw_hypertas_feature_init(const char *hypertas,
> >  		}
> >  	}
> > 
> > +	if (is_secure_guest() &&
> > +	    (powerpc_firmware_features & FW_FEATURE_PUT_TCE_IND)) {
> > +		powerpc_firmware_features &= ~FW_FEATURE_PUT_TCE_IND;
> > +		pr_debug("SVM: disabling PUT_TCE_IND firmware feature\n");
> > +	}
> > +
> >  	pr_debug(" <- fw_hypertas_feature_init()\n");
> >  }
> > 
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM
  2020-01-03  0:08     ` David Gibson
@ 2020-01-03  2:06       ` Ram Pai
  0 siblings, 0 replies; 17+ messages in thread
From: Ram Pai @ 2020-01-03  2:06 UTC (permalink / raw)
  To: David Gibson
  Cc: Alexey Kardashevskiy, Michael Anderson, kvm-ppc, linuxppc-dev,
	Thiago Jung Bauermann

On Fri, Jan 03, 2020 at 11:08:49AM +1100, David Gibson wrote:
> On Thu, Jan 02, 2020 at 02:21:06PM -0800, Ram Pai wrote:
> > On Mon, Dec 16, 2019 at 03:19:24PM +1100, Alexey Kardashevskiy wrote:
> > > H_PUT_TCE_INDIRECT uses a shared page to send up to 512 TCE to
> > > a hypervisor in a single hypercall.
> > 
> > Actually H_PUT_TCE_INDIRECT never used shared page.  It would have
> > used shared pages if the 'shared-page' solution was accepted. :)
> 
> Well, it depends what you mean by "shared".  In the non-PEF case we do
> use a shared page in the sense that it is accessed by both guest and
> hypervisor.  It's just not shared in the PEF sense.

Ah..I see. That sentence can be right or wrong based on the reader's
interpretion of the phrase 'shared page'.  To me a 'shared page' is a
page that is **explicitly** shared with the hypervisor. However I can see
'shared page' to mean a page that is simply shared; either implicitly or
explicitly.

Given that, there is a possibility for mis-interpretation, I think, it
might be better to avoid the phrase 'shared page' if possible.

> 
> > > This does not work for secure VMs
> > > as the page needs to be shared or the VM should use H_PUT_TCE instead.
> > 
> > Maybe you should say something like this.. ?
> > 
> > H_PUT_TCE_INDIRECT does not work for secure VMs, since the page
> > containing the TCE entries is not accessible to the hypervisor.
> > 
> > > 

..snip.

-- 
Ram Pai


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests"
  2019-12-16  4:19 ` [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" Alexey Kardashevskiy
  2019-12-16 22:58   ` Thiago Jung Bauermann
@ 2020-01-06 23:33   ` Michael Ellerman
  1 sibling, 0 replies; 17+ messages in thread
From: Michael Ellerman @ 2020-01-06 23:33 UTC (permalink / raw)
  To: Alexey Kardashevskiy, linuxppc-dev
  Cc: Alexey Kardashevskiy, Michael Anderson, Ram Pai, kvm-ppc,
	Thiago Jung Bauermann, David Gibson

On Mon, 2019-12-16 at 04:19:21 UTC, Alexey Kardashevskiy wrote:
> From: Ram Pai <linuxram@us.ibm.com>
> 
> This reverts commit edea902c1c1efb855f77e041f9daf1abe7a9768a.
> 
> At the time the change allowed direct DMA ops for secure VMs; however
> since then we switched on using SWIOTLB backed with IOMMU (direct mapping)
> and to make this work, we need dma_iommu_ops which handles all cases
> including TCE mapping I/O pages in the presence of an IOMMU.
> 
> Fixes: edea902c1c1e ("powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests")
> Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> [aik: added "revert" and "fixes:"]
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Series applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/d862b44133b7a1d7de25288e09eabf4df415e971

cheers

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-01-06 23:47 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-16  4:19 [PATCH kernel v2 0/4] Enable IOMMU support for pseries Secure VMs Alexey Kardashevskiy
2019-12-16  4:19 ` [PATCH kernel v2 1/4] Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" Alexey Kardashevskiy
2019-12-16 22:58   ` Thiago Jung Bauermann
2020-01-06 23:33   ` Michael Ellerman
2019-12-16  4:19 ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce for DDW Alexey Kardashevskiy
2019-12-16 23:07   ` Thiago Jung Bauermann
2019-12-17  0:09     ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce " Alexey Kardashevskiy
2019-12-17  2:06       ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce " Thiago Jung Bauermann
2020-01-02 22:02   ` [PATCH kernel v2 2/4] powerpc/pseries: Allow not having ibm,hypertas-functions::hcall-multi-tce " Ram Pai
2019-12-16  4:19 ` [PATCH kernel v2 3/4] powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features Alexey Kardashevskiy
2019-12-16 23:19   ` Thiago Jung Bauermann
2020-01-02 22:24   ` Ram Pai
2019-12-16  4:19 ` [PATCH kernel v2 4/4] powerpc/pseries/svm: Allow IOMMU to work in SVM Alexey Kardashevskiy
2019-12-16 23:23   ` Thiago Jung Bauermann
2020-01-02 22:21   ` Ram Pai
2020-01-03  0:08     ` David Gibson
2020-01-03  2:06       ` Ram Pai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).