[POWERPC] Only use H_BULK_REMOVE if the firmware supports it
authorPaul Mackerras <paulus@samba.org>
Thu, 8 Feb 2007 04:02:35 +0000 (15:02 +1100)
committerPaul Mackerras <paulus@samba.org>
Thu, 8 Feb 2007 04:02:35 +0000 (15:02 +1100)
The previous patch changing pSeries to use H_BULK_REMOVE broke the
JS20 blade, where the firmware doesn't support H_BULK_REMOVE.  This
adds a firmware check so that on machines that don't have H_BULK_REMOVE,
we just use the H_REMOVE call as before.

Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/platforms/pseries/lpar.c
include/asm-powerpc/firmware.h

index 1c7b2baa5f73cf97758bf681a2420c75865bfaf3..90522e3c9d46b1979eb86d738fe7c0b7c62718a9 100644 (file)
@@ -59,6 +59,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
        {FW_FEATURE_XDABR,              "hcall-xdabr"},
        {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
        {FW_FEATURE_SPLPAR,             "hcall-splpar"},
+       {FW_FEATURE_BULK_REMOVE,        "hcall-bulk"},
 };
 
 /* Build up the firmware features bitmask using the contents of
index 5a684fbd8f27208a55a8fe366d61dffd8f619073..7496005566efd6b48cc64d11ad841c0a4716d8dd 100644 (file)
@@ -516,7 +516,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
 static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 {
        unsigned long i, pix, rc;
-       unsigned long flags;
+       unsigned long flags = 0;
        struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
        int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
        unsigned long param[9];
@@ -540,16 +540,22 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
                                hash = ~hash;
                        slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
                        slot += hidx & _PTEIDX_GROUP_IX;
-                       param[pix] = HBR_REQUEST | HBR_AVPN | slot;
-                       param[pix+1] = hpte_encode_v(va, psize) & HPTE_V_AVPN;
-                       pix += 2;
-                       if (pix == 8) {
-                               rc = plpar_hcall9(H_BULK_REMOVE, param,
+                       if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+                               pSeries_lpar_hpte_invalidate(slot, va, psize,
+                                                            local);
+                       } else {
+                               param[pix] = HBR_REQUEST | HBR_AVPN | slot;
+                               param[pix+1] = hpte_encode_v(va, psize) &
+                                       HPTE_V_AVPN;
+                               pix += 2;
+                               if (pix == 8) {
+                                       rc = plpar_hcall9(H_BULK_REMOVE, param,
                                                param[0], param[1], param[2],
                                                param[3], param[4], param[5],
                                                param[6], param[7]);
-                               BUG_ON(rc != H_SUCCESS);
-                               pix = 0;
+                                       BUG_ON(rc != H_SUCCESS);
+                                       pix = 0;
+                               }
                        }
                } pte_iterate_hashed_end();
        }
index abba808cc53c2e28b5e5b250c054090c154f9714..3671c128f271eae3806930d50bb54387b7cc0e6f 100644 (file)
@@ -44,6 +44,7 @@
 #define FW_FEATURE_LPAR                ASM_CONST(0x0000000000400000)
 #define FW_FEATURE_PS3_LV1     ASM_CONST(0x0000000000800000)
 #define FW_FEATURE_BEAT                ASM_CONST(0x0000000001000000)
+#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000)
 
 #ifndef __ASSEMBLY__