#endif /* CONFIG_SPU_BASE */
 
+#ifdef CONFIG_PPC64
+
+#define get_cache_geometry(level) \
+       (ppc64_caches.level.assoc << 16 | ppc64_caches.level.line_size)
+
+#define ARCH_DLINFO_CACHE_GEOMETRY                                     \
+       NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);           \
+       NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, get_cache_geometry(l1i));     \
+       NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1i.size);           \
+       NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_geometry(l1i));     \
+       NEW_AUX_ENT(AT_L2_CACHESIZE, ppc64_caches.l2.size);             \
+       NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, get_cache_geometry(l2));       \
+       NEW_AUX_ENT(AT_L3_CACHESIZE, ppc64_caches.l3.size);             \
+       NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, get_cache_geometry(l3))
+
+#else
+#define ARCH_DLINFO_CACHE_GEOMETRY
+#endif
+
 /*
  * The requirements here are:
  * - keep the final alignment of sp (sp & 0xf)
        NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);                      \
        NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);                      \
        VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base);  \
+       ARCH_DLINFO_CACHE_GEOMETRY;                                     \
 } while (0)
 
 #endif /* _ASM_POWERPC_ELF_H */
 
  */
 #define AT_SYSINFO_EHDR                33
 
-#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
+/*
+ * AT_*CACHEBSIZE above represent the cache *block* size which is
+ * the size that is affected by the cache management instructions.
+ *
+ * It doesn't nececssarily matches the cache *line* size which is
+ * more of a performance tuning hint. Additionally the latter can
+ * be different for the different cache levels.
+ *
+ * The set of entries below represent more extensive information
+ * about the caches, in the form of two entry per cache type,
+ * one entry containing the cache size in bytes, and the other
+ * containing the cache line size in bytes in the bottom 16 bits
+ * and the cache associativity in the next 16 bits.
+ *
+ * The associativity is such that if N is the 16-bit value, the
+ * cache is N way set associative. A value if 0xffff means fully
+ * associative, a value of 1 means directly mapped.
+ *
+ * For all these fields, a value of 0 means that the information
+ * is not known.
+ */
+
+#define AT_L1I_CACHESIZE       40
+#define AT_L1I_CACHEGEOMETRY   41
+#define AT_L1D_CACHESIZE       42
+#define AT_L1D_CACHEGEOMETRY   43
+#define AT_L2_CACHESIZE                44
+#define AT_L2_CACHEGEOMETRY    45
+#define AT_L3_CACHESIZE                46
+#define AT_L3_CACHEGEOMETRY    47
+
+#define AT_VECTOR_SIZE_ARCH    14 /* entries in ARCH_DLINFO */
 
 #endif
 
        info->block_size = bsize;
        info->log_block_size = __ilog2(bsize);
        info->blocks_per_page = PAGE_SIZE / bsize;
+
+       if (sets == 0)
+               info->assoc = 0xffff;
+       else
+               info->assoc = size / (sets * lsize);
 }
 
 static bool __init parse_cache_info(struct device_node *np,