linux/arch/arm64/include/asm/kvm_mmu.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012,2013 - ARM Ltd
   3 * Author: Marc Zyngier <marc.zyngier@arm.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18#ifndef __ARM64_KVM_MMU_H__
  19#define __ARM64_KVM_MMU_H__
  20
  21#include <asm/page.h>
  22#include <asm/memory.h>
  23#include <asm/cpufeature.h>
  24
  25/*
  26 * As ARMv8.0 only has the TTBR0_EL2 register, we cannot express
  27 * "negative" addresses. This makes it impossible to directly share
  28 * mappings with the kernel.
  29 *
  30 * Instead, give the HYP mode its own VA region at a fixed offset from
  31 * the kernel by just masking the top bits (which are all ones for a
  32 * kernel address). We need to find out how many bits to mask.
  33 *
  34 * We want to build a set of page tables that cover both parts of the
  35 * idmap (the trampoline page used to initialize EL2), and our normal
  36 * runtime VA space, at the same time.
  37 *
  38 * Given that the kernel uses VA_BITS for its entire address space,
  39 * and that half of that space (VA_BITS - 1) is used for the linear
  40 * mapping, we can also limit the EL2 space to (VA_BITS - 1).
  41 *
  42 * The main question is "Within the VA_BITS space, does EL2 use the
  43 * top or the bottom half of that space to shadow the kernel's linear
  44 * mapping?". As we need to idmap the trampoline page, this is
  45 * determined by the range in which this page lives.
  46 *
  47 * If the page is in the bottom half, we have to use the top half. If
  48 * the page is in the top half, we have to use the bottom half:
  49 *
  50 * T = __pa_symbol(__hyp_idmap_text_start)
  51 * if (T & BIT(VA_BITS - 1))
  52 *      HYP_VA_MIN = 0  //idmap in upper half
  53 * else
  54 *      HYP_VA_MIN = 1 << (VA_BITS - 1)
  55 * HYP_VA_MAX = HYP_VA_MIN + (1 << (VA_BITS - 1)) - 1
  56 *
  57 * This of course assumes that the trampoline page exists within the
  58 * VA_BITS range. If it doesn't, then it means we're in the odd case
  59 * where the kernel idmap (as well as HYP) uses more levels than the
  60 * kernel runtime page tables (as seen when the kernel is configured
  61 * for 4k pages, 39bits VA, and yet memory lives just above that
  62 * limit, forcing the idmap to use 4 levels of page tables while the
  63 * kernel itself only uses 3). In this particular case, it doesn't
  64 * matter which side of VA_BITS we use, as we're guaranteed not to
  65 * conflict with anything.
  66 *
  67 * When using VHE, there are no separate hyp mappings and all KVM
  68 * functionality is already mapped as part of the main kernel
  69 * mappings, and none of this applies in that case.
  70 */
  71
  72#define HYP_PAGE_OFFSET_HIGH_MASK       ((UL(1) << VA_BITS) - 1)
  73#define HYP_PAGE_OFFSET_LOW_MASK        ((UL(1) << (VA_BITS - 1)) - 1)
  74
  75#ifdef __ASSEMBLY__
  76
  77#include <asm/alternative.h>
  78#include <asm/cpufeature.h>
  79
  80/*
  81 * Convert a kernel VA into a HYP VA.
  82 * reg: VA to be converted.
  83 *
  84 * This generates the following sequences:
  85 * - High mask:
  86 *              and x0, x0, #HYP_PAGE_OFFSET_HIGH_MASK
  87 *              nop
  88 * - Low mask:
  89 *              and x0, x0, #HYP_PAGE_OFFSET_HIGH_MASK
  90 *              and x0, x0, #HYP_PAGE_OFFSET_LOW_MASK
  91 * - VHE:
  92 *              nop
  93 *              nop
  94 *
  95 * The "low mask" version works because the mask is a strict subset of
  96 * the "high mask", hence performing the first mask for nothing.
  97 * Should be completely invisible on any viable CPU.
  98 */
  99.macro kern_hyp_va      reg
 100alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
 101        and     \reg, \reg, #HYP_PAGE_OFFSET_HIGH_MASK
 102alternative_else_nop_endif
 103alternative_if ARM64_HYP_OFFSET_LOW
 104        and     \reg, \reg, #HYP_PAGE_OFFSET_LOW_MASK
 105alternative_else_nop_endif
 106.endm
 107
 108#else
 109
 110#include <asm/pgalloc.h>
 111#include <asm/cache.h>
 112#include <asm/cacheflush.h>
 113#include <asm/mmu_context.h>
 114#include <asm/pgtable.h>
 115
 116static inline unsigned long __kern_hyp_va(unsigned long v)
 117{
 118        asm volatile(ALTERNATIVE("and %0, %0, %1",
 119                                 "nop",
 120                                 ARM64_HAS_VIRT_HOST_EXTN)
 121                     : "+r" (v)
 122                     : "i" (HYP_PAGE_OFFSET_HIGH_MASK));
 123        asm volatile(ALTERNATIVE("nop",
 124                                 "and %0, %0, %1",
 125                                 ARM64_HYP_OFFSET_LOW)
 126                     : "+r" (v)
 127                     : "i" (HYP_PAGE_OFFSET_LOW_MASK));
 128        return v;
 129}
 130
 131#define kern_hyp_va(v)  ((typeof(v))(__kern_hyp_va((unsigned long)(v))))
 132
 133/*
 134 * We currently only support a 40bit IPA.
 135 */
 136#define KVM_PHYS_SHIFT  (40)
 137#define KVM_PHYS_SIZE   (1UL << KVM_PHYS_SHIFT)
 138#define KVM_PHYS_MASK   (KVM_PHYS_SIZE - 1UL)
 139
 140#include <asm/stage2_pgtable.h>
 141
 142int create_hyp_mappings(void *from, void *to, pgprot_t prot);
 143int create_hyp_io_mappings(void *from, void *to, phys_addr_t);
 144void free_hyp_pgds(void);
 145
 146void stage2_unmap_vm(struct kvm *kvm);
 147int kvm_alloc_stage2_pgd(struct kvm *kvm);
 148void kvm_free_stage2_pgd(struct kvm *kvm);
 149int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 150                          phys_addr_t pa, unsigned long size, bool writable);
 151
 152int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
 153
 154void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 155
 156phys_addr_t kvm_mmu_get_httbr(void);
 157phys_addr_t kvm_get_idmap_vector(void);
 158int kvm_mmu_init(void);
 159void kvm_clear_hyp_idmap(void);
 160
 161#define kvm_set_pte(ptep, pte)          set_pte(ptep, pte)
 162#define kvm_set_pmd(pmdp, pmd)          set_pmd(pmdp, pmd)
 163
 164static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
 165{
 166        pte_val(pte) |= PTE_S2_RDWR;
 167        return pte;
 168}
 169
 170static inline pmd_t kvm_s2pmd_mkwrite(pmd_t pmd)
 171{
 172        pmd_val(pmd) |= PMD_S2_RDWR;
 173        return pmd;
 174}
 175
 176static inline void kvm_set_s2pte_readonly(pte_t *pte)
 177{
 178        pteval_t pteval;
 179        unsigned long tmp;
 180
 181        asm volatile("//        kvm_set_s2pte_readonly\n"
 182        "       prfm    pstl1strm, %2\n"
 183        "1:     ldxr    %0, %2\n"
 184        "       and     %0, %0, %3              // clear PTE_S2_RDWR\n"
 185        "       orr     %0, %0, %4              // set PTE_S2_RDONLY\n"
 186        "       stxr    %w1, %0, %2\n"
 187        "       cbnz    %w1, 1b\n"
 188        : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*pte))
 189        : "L" (~PTE_S2_RDWR), "L" (PTE_S2_RDONLY));
 190}
 191
 192static inline bool kvm_s2pte_readonly(pte_t *pte)
 193{
 194        return (pte_val(*pte) & PTE_S2_RDWR) == PTE_S2_RDONLY;
 195}
 196
 197static inline void kvm_set_s2pmd_readonly(pmd_t *pmd)
 198{
 199        kvm_set_s2pte_readonly((pte_t *)pmd);
 200}
 201
 202static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
 203{
 204        return kvm_s2pte_readonly((pte_t *)pmd);
 205}
 206
 207static inline bool kvm_page_empty(void *ptr)
 208{
 209        struct page *ptr_page = virt_to_page(ptr);
 210        return page_count(ptr_page) == 1;
 211}
 212
 213#define hyp_pte_table_empty(ptep) kvm_page_empty(ptep)
 214
 215#ifdef __PAGETABLE_PMD_FOLDED
 216#define hyp_pmd_table_empty(pmdp) (0)
 217#else
 218#define hyp_pmd_table_empty(pmdp) kvm_page_empty(pmdp)
 219#endif
 220
 221#ifdef __PAGETABLE_PUD_FOLDED
 222#define hyp_pud_table_empty(pudp) (0)
 223#else
 224#define hyp_pud_table_empty(pudp) kvm_page_empty(pudp)
 225#endif
 226
 227struct kvm;
 228
 229#define kvm_flush_dcache_to_poc(a,l)    __flush_dcache_area((a), (l))
 230
 231static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
 232{
 233        return (vcpu_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
 234}
 235
 236static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
 237                                               kvm_pfn_t pfn,
 238                                               unsigned long size)
 239{
 240        void *va = page_address(pfn_to_page(pfn));
 241
 242        kvm_flush_dcache_to_poc(va, size);
 243
 244        if (icache_is_aliasing()) {
 245                /* any kind of VIPT cache */
 246                __flush_icache_all();
 247        } else if (is_kernel_in_hyp_mode() || !icache_is_vpipt()) {
 248                /* PIPT or VPIPT at EL2 (see comment in __kvm_tlb_flush_vmid_ipa) */
 249                flush_icache_range((unsigned long)va,
 250                                   (unsigned long)va + size);
 251        }
 252}
 253
 254static inline void __kvm_flush_dcache_pte(pte_t pte)
 255{
 256        struct page *page = pte_page(pte);
 257        kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
 258}
 259
 260static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
 261{
 262        struct page *page = pmd_page(pmd);
 263        kvm_flush_dcache_to_poc(page_address(page), PMD_SIZE);
 264}
 265
 266static inline void __kvm_flush_dcache_pud(pud_t pud)
 267{
 268        struct page *page = pud_page(pud);
 269        kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
 270}
 271
 272#define kvm_virt_to_phys(x)             __pa_symbol(x)
 273
 274void kvm_set_way_flush(struct kvm_vcpu *vcpu);
 275void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
 276
 277static inline bool __kvm_cpu_uses_extended_idmap(void)
 278{
 279        return __cpu_uses_extended_idmap();
 280}
 281
 282static inline void __kvm_extend_hypmap(pgd_t *boot_hyp_pgd,
 283                                       pgd_t *hyp_pgd,
 284                                       pgd_t *merged_hyp_pgd,
 285                                       unsigned long hyp_idmap_start)
 286{
 287        int idmap_idx;
 288
 289        /*
 290         * Use the first entry to access the HYP mappings. It is
 291         * guaranteed to be free, otherwise we wouldn't use an
 292         * extended idmap.
 293         */
 294        VM_BUG_ON(pgd_val(merged_hyp_pgd[0]));
 295        merged_hyp_pgd[0] = __pgd(__pa(hyp_pgd) | PMD_TYPE_TABLE);
 296
 297        /*
 298         * Create another extended level entry that points to the boot HYP map,
 299         * which contains an ID mapping of the HYP init code. We essentially
 300         * merge the boot and runtime HYP maps by doing so, but they don't
 301         * overlap anyway, so this is fine.
 302         */
 303        idmap_idx = hyp_idmap_start >> VA_BITS;
 304        VM_BUG_ON(pgd_val(merged_hyp_pgd[idmap_idx]));
 305        merged_hyp_pgd[idmap_idx] = __pgd(__pa(boot_hyp_pgd) | PMD_TYPE_TABLE);
 306}
 307
 308static inline unsigned int kvm_get_vmid_bits(void)
 309{
 310        int reg = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
 311
 312        return (cpuid_feature_extract_unsigned_field(reg, ID_AA64MMFR1_VMIDBITS_SHIFT) == 2) ? 16 : 8;
 313}
 314
 315#endif /* __ASSEMBLY__ */
 316#endif /* __ARM64_KVM_MMU_H__ */
 317