Commit 17a0364c authored by Alexey Kardashevskiy's avatar Alexey Kardashevskiy Committed by Michael Ellerman
Browse files

powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features



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: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: default avatarThiago Jung Bauermann <bauerman@linux.ibm.com>
Tested-by: default avatarThiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20191216041924.42318-4-aik@ozlabs.ru
parent 7559d3d2
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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 |
+2 −1
Original line number Diff line number Diff line
@@ -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"},
+7 −5
Original line number Diff line number Diff line
@@ -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);
@@ -1341,9 +1341,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;
}