FILE
kvm_mmu.h
File preview with syntax highlighting.
linux-6.19.14/arch/loongarch/include/asm/kvm_mmu.h
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 4 */ 5 6#ifndef __ASM_LOONGARCH_KVM_MMU_H__ 7#define __ASM_LOONGARCH_KVM_MMU_H__ 8 9#include <linux/kvm_host.h> 10#include <asm/pgalloc.h> 11#include <asm/tlb.h> 12 13/* 14 * KVM_MMU_CACHE_MIN_PAGES is the number of GPA page table translation levels 15 * for which pages need to be cached. 16 */ 17#define KVM_MMU_CACHE_MIN_PAGES (CONFIG_PGTABLE_LEVELS - 1) 18 19/* 20 * _PAGE_MODIFIED is a SW pte bit, it records page ever written on host 21 * kernel, on secondary MMU it records the page writeable attribute, in 22 * order for fast path handling. 23 */ 24#define KVM_PAGE_WRITEABLE _PAGE_MODIFIED 25 26#define _KVM_FLUSH_PGTABLE 0x1 27#define _KVM_HAS_PGMASK 0x2 28#define kvm_pfn_pte(pfn, prot) (((pfn) << PFN_PTE_SHIFT) | pgprot_val(prot)) 29#define kvm_pte_pfn(x) ((phys_addr_t)((x & _PFN_MASK) >> PFN_PTE_SHIFT)) 30 31typedef unsigned long kvm_pte_t; 32typedef struct kvm_ptw_ctx kvm_ptw_ctx; 33typedef int (*kvm_pte_ops)(kvm_pte_t *pte, phys_addr_t addr, kvm_ptw_ctx *ctx); 34 35struct kvm_ptw_ctx { 36 kvm_pte_ops ops; 37 unsigned long flag; 38 39 /* for kvm_arch_mmu_enable_log_dirty_pt_masked use */ 40 unsigned long mask; 41 unsigned long gfn; 42 43 /* page walk mmu info */ 44 unsigned int level; 45 unsigned long pgtable_shift; 46 unsigned long invalid_entry; 47 unsigned long *invalid_ptes; 48 unsigned int *pte_shifts; 49 void *opaque; 50 51 /* free pte table page list */ 52 struct list_head list; 53}; 54 55kvm_pte_t *kvm_pgd_alloc(void); 56 57static inline void kvm_set_pte(kvm_pte_t *ptep, kvm_pte_t val) 58{ 59 WRITE_ONCE(*ptep, val); 60} 61 62static inline int kvm_pte_young(kvm_pte_t pte) { return pte & _PAGE_ACCESSED; } 63static inline int kvm_pte_huge(kvm_pte_t pte) { return pte & _PAGE_HUGE; } 64static inline int kvm_pte_dirty(kvm_pte_t pte) { return pte & __WRITEABLE; } 65static inline int kvm_pte_writeable(kvm_pte_t pte) { return pte & KVM_PAGE_WRITEABLE; } 66 67static inline kvm_pte_t kvm_pte_mkyoung(kvm_pte_t pte) 68{ 69 return pte | _PAGE_ACCESSED; 70} 71 72static inline kvm_pte_t kvm_pte_mkold(kvm_pte_t pte) 73{ 74 return pte & ~_PAGE_ACCESSED; 75} 76 77static inline kvm_pte_t kvm_pte_mkdirty(kvm_pte_t pte) 78{ 79 return pte | __WRITEABLE; 80} 81 82static inline kvm_pte_t kvm_pte_mkclean(kvm_pte_t pte) 83{ 84 return pte & ~__WRITEABLE; 85} 86 87static inline kvm_pte_t kvm_pte_mkhuge(kvm_pte_t pte) 88{ 89 return pte | _PAGE_HUGE; 90} 91 92static inline kvm_pte_t kvm_pte_mksmall(kvm_pte_t pte) 93{ 94 return pte & ~_PAGE_HUGE; 95} 96 97static inline kvm_pte_t kvm_pte_mkwriteable(kvm_pte_t pte) 98{ 99 return pte | KVM_PAGE_WRITEABLE; 100} 101 102static inline int kvm_need_flush(kvm_ptw_ctx *ctx) 103{ 104 return ctx->flag & _KVM_FLUSH_PGTABLE; 105} 106 107static inline kvm_pte_t *kvm_pgtable_offset(kvm_ptw_ctx *ctx, kvm_pte_t *table, 108 phys_addr_t addr) 109{ 110 111 return table + ((addr >> ctx->pgtable_shift) & (PTRS_PER_PTE - 1)); 112} 113 114static inline phys_addr_t kvm_pgtable_addr_end(kvm_ptw_ctx *ctx, 115 phys_addr_t addr, phys_addr_t end) 116{ 117 phys_addr_t boundary, size; 118 119 size = 0x1UL << ctx->pgtable_shift; 120 boundary = (addr + size) & ~(size - 1); 121 return (boundary - 1 < end - 1) ? boundary : end; 122} 123 124static inline int kvm_pte_present(kvm_ptw_ctx *ctx, kvm_pte_t *entry) 125{ 126 if (!ctx || ctx->level == 0) 127 return !!(*entry & _PAGE_PRESENT); 128 129 return *entry != ctx->invalid_entry; 130} 131 132static inline int kvm_pte_none(kvm_ptw_ctx *ctx, kvm_pte_t *entry) 133{ 134 return *entry == ctx->invalid_entry; 135} 136 137static inline void kvm_ptw_enter(kvm_ptw_ctx *ctx) 138{ 139 ctx->level--; 140 ctx->pgtable_shift = ctx->pte_shifts[ctx->level]; 141 ctx->invalid_entry = ctx->invalid_ptes[ctx->level]; 142} 143 144static inline void kvm_ptw_exit(kvm_ptw_ctx *ctx) 145{ 146 ctx->level++; 147 ctx->pgtable_shift = ctx->pte_shifts[ctx->level]; 148 ctx->invalid_entry = ctx->invalid_ptes[ctx->level]; 149} 150 151#endif /* __ASM_LOONGARCH_KVM_MMU_H__ */
~/
Read-only file preview.