powerpc/pseries/iommu: Separate FW_FEATURE_MULTITCE to put/stuff features
authorAlexey Kardashevskiy <aik@ozlabs.ru>
Mon, 16 Dec 2019 04:19:23 +0000 (15:19 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 6 Jan 2020 05:25:30 +0000 (16:25 +1100)
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>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20191216041924.42318-4-aik@ozlabs.ru
arch/powerpc/include/asm/firmware.h
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/platforms/pseries/iommu.c

index b3e214a97f3ad5a19bab0f205389a9504dc74cc8..ca33f4ef6cb46ee8ce8477e13f12f3be074ac28a 100644 (file)
@@ -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 |
index d4a8f17024172eae37d7df7be451c6d276ba96f1..d3acff23f2e3538363056dd02c59b3077e7c2be9 100644 (file)
@@ -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"},
index b4ce9d472dfe0c2cbfadb25502851da9580dbbda..2e0a8eab5588989a713c85944eb30d361cc64509 100644 (file)
@@ -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;
 }