emulation when determining guest CPU Frequency. Instead, the guest's
          timer frequency is specified directly.
 
+config MIPS_VA_BITS_48
+       bool "48 bits virtual memory"
+       depends on 64BIT
+       help
+         Support a maximum at least 48 bits of application virtual memory.
+         Default is 40 bits or less, depending on the CPU.
+         This option result in a small memory overhead for page tables.
+         This option is only supported with 16k and 64k page sizes.
+         If unsure, say N.
+
 choice
        prompt "Kernel page size"
        default PAGE_SIZE_4KB
 config PAGE_SIZE_4KB
        bool "4kB"
        depends on !CPU_LOONGSON2 && !CPU_LOONGSON3
+       depends on !MIPS_VA_BITS_48
        help
         This option select the standard 4kB Linux page size.  On some
         R3000-family processors this is the only available page size.  Using
 config PAGE_SIZE_8KB
        bool "8kB"
        depends on CPU_R8000 || CPU_CAVIUM_OCTEON
+       depends on !MIPS_VA_BITS_48
        help
          Using 8kB page size will result in higher performance kernel at
          the price of higher memory consumption.  This option is available
 config PAGE_SIZE_32KB
        bool "32kB"
        depends on CPU_CAVIUM_OCTEON
+       depends on !MIPS_VA_BITS_48
        help
          Using 32kB page size will result in higher performance kernel at
          the price of higher memory consumption.  This option is available
 
 #include <asm/cachectl.h>
 #include <asm/fixmap.h>
 
-#ifdef CONFIG_PAGE_SIZE_64KB
+#if defined(CONFIG_PAGE_SIZE_64KB) && !defined(CONFIG_MIPS_VA_BITS_48)
 #include <asm-generic/pgtable-nopmd.h>
 #else
 #include <asm-generic/pgtable-nopud.h>
 #define PTE_ORDER              0
 #endif
 #ifdef CONFIG_PAGE_SIZE_16KB
-#define PGD_ORDER              0
+#ifdef CONFIG_MIPS_VA_BITS_48
+#define PGD_ORDER               1
+#else
+#define PGD_ORDER               0
+#endif
 #define PUD_ORDER              aieeee_attempt_to_allocate_pud
 #define PMD_ORDER              0
 #define PTE_ORDER              0
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PGD_ORDER              0
 #define PUD_ORDER              aieeee_attempt_to_allocate_pud
+#ifdef CONFIG_MIPS_VA_BITS_48
+#define PMD_ORDER              0
+#else
 #define PMD_ORDER              aieeee_attempt_to_allocate_pmd
+#endif
 #define PTE_ORDER              0
 #endif
 
 #endif
 #define PTRS_PER_PTE   ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
 
-#if PGDIR_SIZE >= TASK_SIZE64
-#define USER_PTRS_PER_PGD      (1)
-#else
-#define USER_PTRS_PER_PGD      (TASK_SIZE64 / PGDIR_SIZE)
-#endif
+#define USER_PTRS_PER_PGD       ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1)
 #define FIRST_USER_ADDRESS     0UL
 
 /*
 
  * 8192EB ...
  */
 #define TASK_SIZE32    0x7fff8000UL
-#define TASK_SIZE64    0x10000000000UL
+#ifdef CONFIG_MIPS_VA_BITS_48
+#define TASK_SIZE64     (0x1UL << ((cpu_data[0].vmbits>48)?48:cpu_data[0].vmbits))
+#else
+#define TASK_SIZE64     0x10000000000UL
+#endif
 #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
 #define STACK_TOP_MAX  TASK_SIZE64