linux/arch/powerpc/include/asm/book3s/64/mmu.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ASM_POWERPC_BOOK3S_64_MMU_H_
   3#define _ASM_POWERPC_BOOK3S_64_MMU_H_
   4
   5#include <asm/page.h>
   6
   7#ifndef __ASSEMBLY__
   8/*
   9 * Page size definition
  10 *
  11 *    shift : is the "PAGE_SHIFT" value for that page size
  12 *    sllp  : is a bit mask with the value of SLB L || LP to be or'ed
  13 *            directly to a slbmte "vsid" value
  14 *    penc  : is the HPTE encoding mask for the "LP" field:
  15 *
  16 */
  17struct mmu_psize_def {
  18        unsigned int    shift;  /* number of bits */
  19        int             penc[MMU_PAGE_COUNT];   /* HPTE encoding */
  20        unsigned int    tlbiel; /* tlbiel supported for that page size */
  21        unsigned long   avpnm;  /* bits to mask out in AVPN in the HPTE */
  22        unsigned long   h_rpt_pgsize; /* H_RPT_INVALIDATE page size encoding */
  23        union {
  24                unsigned long   sllp;   /* SLB L||LP (exact mask to use in slbmte) */
  25                unsigned long ap;       /* Ap encoding used by PowerISA 3.0 */
  26        };
  27};
  28extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
  29#endif /* __ASSEMBLY__ */
  30
  31/* 64-bit classic hash table MMU */
  32#include <asm/book3s/64/mmu-hash.h>
  33
  34#ifndef __ASSEMBLY__
  35/*
  36 * ISA 3.0 partition and process table entry format
  37 */
  38struct prtb_entry {
  39        __be64 prtb0;
  40        __be64 prtb1;
  41};
  42extern struct prtb_entry *process_tb;
  43
  44struct patb_entry {
  45        __be64 patb0;
  46        __be64 patb1;
  47};
  48extern struct patb_entry *partition_tb;
  49
  50/* Bits in patb0 field */
  51#define PATB_HR         (1UL << 63)
  52#define RPDB_MASK       0x0fffffffffffff00UL
  53#define RPDB_SHIFT      (1UL << 8)
  54#define RTS1_SHIFT      61              /* top 2 bits of radix tree size */
  55#define RTS1_MASK       (3UL << RTS1_SHIFT)
  56#define RTS2_SHIFT      5               /* bottom 3 bits of radix tree size */
  57#define RTS2_MASK       (7UL << RTS2_SHIFT)
  58#define RPDS_MASK       0x1f            /* root page dir. size field */
  59
  60/* Bits in patb1 field */
  61#define PATB_GR         (1UL << 63)     /* guest uses radix; must match HR */
  62#define PRTS_MASK       0x1f            /* process table size field */
  63#define PRTB_MASK       0x0ffffffffffff000UL
  64
  65/* Number of supported PID bits */
  66extern unsigned int mmu_pid_bits;
  67
  68/* Base PID to allocate from */
  69extern unsigned int mmu_base_pid;
  70
  71/*
  72 * memory block size used with radix translation.
  73 */
  74extern unsigned long __ro_after_init radix_mem_block_size;
  75
  76#define PRTB_SIZE_SHIFT (mmu_pid_bits + 4)
  77#define PRTB_ENTRIES    (1ul << mmu_pid_bits)
  78
  79/*
  80 * Power9 currently only support 64K partition table size.
  81 */
  82#define PATB_SIZE_SHIFT 16
  83
  84typedef unsigned long mm_context_id_t;
  85struct spinlock;
  86
  87/* Maximum possible number of NPUs in a system. */
  88#define NV_MAX_NPUS 8
  89
  90typedef struct {
  91        union {
  92                /*
  93                 * We use id as the PIDR content for radix. On hash we can use
  94                 * more than one id. The extended ids are used when we start
  95                 * having address above 512TB. We allocate one extended id
  96                 * for each 512TB. The new id is then used with the 49 bit
  97                 * EA to build a new VA. We always use ESID_BITS_1T_MASK bits
  98                 * from EA and new context ids to build the new VAs.
  99                 */
 100                mm_context_id_t id;
 101                mm_context_id_t extended_id[TASK_SIZE_USER64/TASK_CONTEXT_SIZE];
 102        };
 103
 104        /* Number of bits in the mm_cpumask */
 105        atomic_t active_cpus;
 106
 107        /* Number of users of the external (Nest) MMU */
 108        atomic_t copros;
 109
 110        /* Number of user space windows opened in process mm_context */
 111        atomic_t vas_windows;
 112
 113        struct hash_mm_context *hash_context;
 114
 115        void __user *vdso;
 116        /*
 117         * pagetable fragment support
 118         */
 119        void *pte_frag;
 120        void *pmd_frag;
 121#ifdef CONFIG_SPAPR_TCE_IOMMU
 122        struct list_head iommu_group_mem_list;
 123#endif
 124
 125#ifdef CONFIG_PPC_MEM_KEYS
 126        /*
 127         * Each bit represents one protection key.
 128         * bit set   -> key allocated
 129         * bit unset -> key available for allocation
 130         */
 131        u32 pkey_allocation_map;
 132        s16 execute_only_pkey; /* key holding execute-only protection */
 133#endif
 134} mm_context_t;
 135
 136static inline u16 mm_ctx_user_psize(mm_context_t *ctx)
 137{
 138        return ctx->hash_context->user_psize;
 139}
 140
 141static inline void mm_ctx_set_user_psize(mm_context_t *ctx, u16 user_psize)
 142{
 143        ctx->hash_context->user_psize = user_psize;
 144}
 145
 146static inline unsigned char *mm_ctx_low_slices(mm_context_t *ctx)
 147{
 148        return ctx->hash_context->low_slices_psize;
 149}
 150
 151static inline unsigned char *mm_ctx_high_slices(mm_context_t *ctx)
 152{
 153        return ctx->hash_context->high_slices_psize;
 154}
 155
 156static inline unsigned long mm_ctx_slb_addr_limit(mm_context_t *ctx)
 157{
 158        return ctx->hash_context->slb_addr_limit;
 159}
 160
 161static inline void mm_ctx_set_slb_addr_limit(mm_context_t *ctx, unsigned long limit)
 162{
 163        ctx->hash_context->slb_addr_limit = limit;
 164}
 165
 166static inline struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize)
 167{
 168#ifdef CONFIG_PPC_64K_PAGES
 169        if (psize == MMU_PAGE_64K)
 170                return &ctx->hash_context->mask_64k;
 171#endif
 172#ifdef CONFIG_HUGETLB_PAGE
 173        if (psize == MMU_PAGE_16M)
 174                return &ctx->hash_context->mask_16m;
 175        if (psize == MMU_PAGE_16G)
 176                return &ctx->hash_context->mask_16g;
 177#endif
 178        BUG_ON(psize != MMU_PAGE_4K);
 179
 180        return &ctx->hash_context->mask_4k;
 181}
 182
 183#ifdef CONFIG_PPC_SUBPAGE_PROT
 184static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx)
 185{
 186        return ctx->hash_context->spt;
 187}
 188#endif
 189
 190/*
 191 * The current system page and segment sizes
 192 */
 193extern int mmu_linear_psize;
 194extern int mmu_virtual_psize;
 195extern int mmu_vmalloc_psize;
 196extern int mmu_vmemmap_psize;
 197extern int mmu_io_psize;
 198
 199/* MMU initialization */
 200void mmu_early_init_devtree(void);
 201void hash__early_init_devtree(void);
 202void radix__early_init_devtree(void);
 203#ifdef CONFIG_PPC_PKEY
 204void pkey_early_init_devtree(void);
 205#else
 206static inline void pkey_early_init_devtree(void) {}
 207#endif
 208
 209extern void hash__early_init_mmu(void);
 210extern void radix__early_init_mmu(void);
 211static inline void __init early_init_mmu(void)
 212{
 213        if (radix_enabled())
 214                return radix__early_init_mmu();
 215        return hash__early_init_mmu();
 216}
 217extern void hash__early_init_mmu_secondary(void);
 218extern void radix__early_init_mmu_secondary(void);
 219static inline void early_init_mmu_secondary(void)
 220{
 221        if (radix_enabled())
 222                return radix__early_init_mmu_secondary();
 223        return hash__early_init_mmu_secondary();
 224}
 225
 226extern void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base,
 227                                         phys_addr_t first_memblock_size);
 228static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 229                                              phys_addr_t first_memblock_size)
 230{
 231        /*
 232         * Hash has more strict restrictions. At this point we don't
 233         * know which translations we will pick. Hence go with hash
 234         * restrictions.
 235         */
 236        return hash__setup_initial_memory_limit(first_memblock_base,
 237                                           first_memblock_size);
 238}
 239
 240#ifdef CONFIG_PPC_PSERIES
 241extern void radix_init_pseries(void);
 242#else
 243static inline void radix_init_pseries(void) { }
 244#endif
 245
 246#ifdef CONFIG_HOTPLUG_CPU
 247#define arch_clear_mm_cpumask_cpu(cpu, mm)                              \
 248        do {                                                            \
 249                if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {            \
 250                        atomic_dec(&(mm)->context.active_cpus);         \
 251                        cpumask_clear_cpu(cpu, mm_cpumask(mm));         \
 252                }                                                       \
 253        } while (0)
 254
 255void cleanup_cpu_mmu_context(void);
 256#endif
 257
 258static inline int get_user_context(mm_context_t *ctx, unsigned long ea)
 259{
 260        int index = ea >> MAX_EA_BITS_PER_CONTEXT;
 261
 262        if (likely(index < ARRAY_SIZE(ctx->extended_id)))
 263                return ctx->extended_id[index];
 264
 265        /* should never happen */
 266        WARN_ON(1);
 267        return 0;
 268}
 269
 270static inline unsigned long get_user_vsid(mm_context_t *ctx,
 271                                          unsigned long ea, int ssize)
 272{
 273        unsigned long context = get_user_context(ctx, ea);
 274
 275        return get_vsid(context, ea, ssize);
 276}
 277
 278#endif /* __ASSEMBLY__ */
 279#endif /* _ASM_POWERPC_BOOK3S_64_MMU_H_ */
 280