18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2020 Google LLC 48c2ecf20Sopenharmony_ci * Author: Will Deacon <will@kernel.org> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __ARM64_KVM_PGTABLE_H__ 88c2ecf20Sopenharmony_ci#define __ARM64_KVM_PGTABLE_H__ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/bits.h> 118c2ecf20Sopenharmony_ci#include <linux/kvm_host.h> 128c2ecf20Sopenharmony_ci#include <linux/types.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_citypedef u64 kvm_pte_t; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/** 178c2ecf20Sopenharmony_ci * struct kvm_pgtable - KVM page-table. 188c2ecf20Sopenharmony_ci * @ia_bits: Maximum input address size, in bits. 198c2ecf20Sopenharmony_ci * @start_level: Level at which the page-table walk starts. 208c2ecf20Sopenharmony_ci * @pgd: Pointer to the first top-level entry of the page-table. 218c2ecf20Sopenharmony_ci * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_cistruct kvm_pgtable { 248c2ecf20Sopenharmony_ci u32 ia_bits; 258c2ecf20Sopenharmony_ci u32 start_level; 268c2ecf20Sopenharmony_ci kvm_pte_t *pgd; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci /* Stage-2 only */ 298c2ecf20Sopenharmony_ci struct kvm_s2_mmu *mmu; 308c2ecf20Sopenharmony_ci}; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/** 338c2ecf20Sopenharmony_ci * enum kvm_pgtable_prot - Page-table permissions and attributes. 348c2ecf20Sopenharmony_ci * @KVM_PGTABLE_PROT_X: Execute permission. 358c2ecf20Sopenharmony_ci * @KVM_PGTABLE_PROT_W: Write permission. 368c2ecf20Sopenharmony_ci * @KVM_PGTABLE_PROT_R: Read permission. 378c2ecf20Sopenharmony_ci * @KVM_PGTABLE_PROT_DEVICE: Device attributes. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_cienum kvm_pgtable_prot { 408c2ecf20Sopenharmony_ci KVM_PGTABLE_PROT_X = BIT(0), 418c2ecf20Sopenharmony_ci KVM_PGTABLE_PROT_W = BIT(1), 428c2ecf20Sopenharmony_ci KVM_PGTABLE_PROT_R = BIT(2), 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci KVM_PGTABLE_PROT_DEVICE = BIT(3), 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define PAGE_HYP (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W) 488c2ecf20Sopenharmony_ci#define PAGE_HYP_EXEC (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X) 498c2ecf20Sopenharmony_ci#define PAGE_HYP_RO (KVM_PGTABLE_PROT_R) 508c2ecf20Sopenharmony_ci#define PAGE_HYP_DEVICE (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE) 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/** 538c2ecf20Sopenharmony_ci * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk. 548c2ecf20Sopenharmony_ci * @KVM_PGTABLE_WALK_LEAF: Visit leaf entries, including invalid 558c2ecf20Sopenharmony_ci * entries. 568c2ecf20Sopenharmony_ci * @KVM_PGTABLE_WALK_TABLE_PRE: Visit table entries before their 578c2ecf20Sopenharmony_ci * children. 588c2ecf20Sopenharmony_ci * @KVM_PGTABLE_WALK_TABLE_POST: Visit table entries after their 598c2ecf20Sopenharmony_ci * children. 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_cienum kvm_pgtable_walk_flags { 628c2ecf20Sopenharmony_ci KVM_PGTABLE_WALK_LEAF = BIT(0), 638c2ecf20Sopenharmony_ci KVM_PGTABLE_WALK_TABLE_PRE = BIT(1), 648c2ecf20Sopenharmony_ci KVM_PGTABLE_WALK_TABLE_POST = BIT(2), 658c2ecf20Sopenharmony_ci}; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_citypedef int (*kvm_pgtable_visitor_fn_t)(u64 addr, u64 end, u32 level, 688c2ecf20Sopenharmony_ci kvm_pte_t *ptep, 698c2ecf20Sopenharmony_ci enum kvm_pgtable_walk_flags flag, 708c2ecf20Sopenharmony_ci void * const arg); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/** 738c2ecf20Sopenharmony_ci * struct kvm_pgtable_walker - Hook into a page-table walk. 748c2ecf20Sopenharmony_ci * @cb: Callback function to invoke during the walk. 758c2ecf20Sopenharmony_ci * @arg: Argument passed to the callback function. 768c2ecf20Sopenharmony_ci * @flags: Bitwise-OR of flags to identify the entry types on which to 778c2ecf20Sopenharmony_ci * invoke the callback function. 788c2ecf20Sopenharmony_ci */ 798c2ecf20Sopenharmony_cistruct kvm_pgtable_walker { 808c2ecf20Sopenharmony_ci const kvm_pgtable_visitor_fn_t cb; 818c2ecf20Sopenharmony_ci void * const arg; 828c2ecf20Sopenharmony_ci const enum kvm_pgtable_walk_flags flags; 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/** 868c2ecf20Sopenharmony_ci * kvm_pgtable_hyp_init() - Initialise a hypervisor stage-1 page-table. 878c2ecf20Sopenharmony_ci * @pgt: Uninitialised page-table structure to initialise. 888c2ecf20Sopenharmony_ci * @va_bits: Maximum virtual address bits. 898c2ecf20Sopenharmony_ci * 908c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_ciint kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/** 958c2ecf20Sopenharmony_ci * kvm_pgtable_hyp_destroy() - Destroy an unused hypervisor stage-1 page-table. 968c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_hyp_init(). 978c2ecf20Sopenharmony_ci * 988c2ecf20Sopenharmony_ci * The page-table is assumed to be unreachable by any hardware walkers prior 998c2ecf20Sopenharmony_ci * to freeing and therefore no TLB invalidation is performed. 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_civoid kvm_pgtable_hyp_destroy(struct kvm_pgtable *pgt); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/** 1048c2ecf20Sopenharmony_ci * kvm_pgtable_hyp_map() - Install a mapping in a hypervisor stage-1 page-table. 1058c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_hyp_init(). 1068c2ecf20Sopenharmony_ci * @addr: Virtual address at which to place the mapping. 1078c2ecf20Sopenharmony_ci * @size: Size of the mapping. 1088c2ecf20Sopenharmony_ci * @phys: Physical address of the memory to map. 1098c2ecf20Sopenharmony_ci * @prot: Permissions and attributes for the mapping. 1108c2ecf20Sopenharmony_ci * 1118c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored, @size is rounded-up to 1128c2ecf20Sopenharmony_ci * the next page boundary and @phys is rounded-down to the previous page 1138c2ecf20Sopenharmony_ci * boundary. 1148c2ecf20Sopenharmony_ci * 1158c2ecf20Sopenharmony_ci * If device attributes are not explicitly requested in @prot, then the 1168c2ecf20Sopenharmony_ci * mapping will be normal, cacheable. Attempts to install a new mapping 1178c2ecf20Sopenharmony_ci * for a virtual address that is already mapped will be rejected with an 1188c2ecf20Sopenharmony_ci * error and a WARN(). 1198c2ecf20Sopenharmony_ci * 1208c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 1218c2ecf20Sopenharmony_ci */ 1228c2ecf20Sopenharmony_ciint kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys, 1238c2ecf20Sopenharmony_ci enum kvm_pgtable_prot prot); 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci/** 1268c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table. 1278c2ecf20Sopenharmony_ci * @pgt: Uninitialised page-table structure to initialise. 1288c2ecf20Sopenharmony_ci * @kvm: KVM structure representing the guest virtual machine. 1298c2ecf20Sopenharmony_ci * 1308c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_ciint kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm *kvm); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci/** 1358c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table. 1368c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 1378c2ecf20Sopenharmony_ci * 1388c2ecf20Sopenharmony_ci * The page-table is assumed to be unreachable by any hardware walkers prior 1398c2ecf20Sopenharmony_ci * to freeing and therefore no TLB invalidation is performed. 1408c2ecf20Sopenharmony_ci */ 1418c2ecf20Sopenharmony_civoid kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/** 1448c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_map() - Install a mapping in a guest stage-2 page-table. 1458c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 1468c2ecf20Sopenharmony_ci * @addr: Intermediate physical address at which to place the mapping. 1478c2ecf20Sopenharmony_ci * @size: Size of the mapping. 1488c2ecf20Sopenharmony_ci * @phys: Physical address of the memory to map. 1498c2ecf20Sopenharmony_ci * @prot: Permissions and attributes for the mapping. 1508c2ecf20Sopenharmony_ci * @mc: Cache of pre-allocated GFP_PGTABLE_USER memory from which to 1518c2ecf20Sopenharmony_ci * allocate page-table pages. 1528c2ecf20Sopenharmony_ci * 1538c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored, @size is rounded-up to 1548c2ecf20Sopenharmony_ci * the next page boundary and @phys is rounded-down to the previous page 1558c2ecf20Sopenharmony_ci * boundary. 1568c2ecf20Sopenharmony_ci * 1578c2ecf20Sopenharmony_ci * If device attributes are not explicitly requested in @prot, then the 1588c2ecf20Sopenharmony_ci * mapping will be normal, cacheable. 1598c2ecf20Sopenharmony_ci * 1608c2ecf20Sopenharmony_ci * Note that this function will both coalesce existing table entries and split 1618c2ecf20Sopenharmony_ci * existing block mappings, relying on page-faults to fault back areas outside 1628c2ecf20Sopenharmony_ci * of the new mapping lazily. 1638c2ecf20Sopenharmony_ci * 1648c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 1658c2ecf20Sopenharmony_ci */ 1668c2ecf20Sopenharmony_ciint kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, 1678c2ecf20Sopenharmony_ci u64 phys, enum kvm_pgtable_prot prot, 1688c2ecf20Sopenharmony_ci struct kvm_mmu_memory_cache *mc); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci/** 1718c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_unmap() - Remove a mapping from a guest stage-2 page-table. 1728c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 1738c2ecf20Sopenharmony_ci * @addr: Intermediate physical address from which to remove the mapping. 1748c2ecf20Sopenharmony_ci * @size: Size of the mapping. 1758c2ecf20Sopenharmony_ci * 1768c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored and @size is rounded-up to 1778c2ecf20Sopenharmony_ci * the next page boundary. 1788c2ecf20Sopenharmony_ci * 1798c2ecf20Sopenharmony_ci * TLB invalidation is performed for each page-table entry cleared during the 1808c2ecf20Sopenharmony_ci * unmapping operation and the reference count for the page-table page 1818c2ecf20Sopenharmony_ci * containing the cleared entry is decremented, with unreferenced pages being 1828c2ecf20Sopenharmony_ci * freed. Unmapping a cacheable page will ensure that it is clean to the PoC if 1838c2ecf20Sopenharmony_ci * FWB is not supported by the CPU. 1848c2ecf20Sopenharmony_ci * 1858c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 1868c2ecf20Sopenharmony_ci */ 1878c2ecf20Sopenharmony_ciint kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/** 1908c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_wrprotect() - Write-protect guest stage-2 address range 1918c2ecf20Sopenharmony_ci * without TLB invalidation. 1928c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 1938c2ecf20Sopenharmony_ci * @addr: Intermediate physical address from which to write-protect, 1948c2ecf20Sopenharmony_ci * @size: Size of the range. 1958c2ecf20Sopenharmony_ci * 1968c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored and @size is rounded-up to 1978c2ecf20Sopenharmony_ci * the next page boundary. 1988c2ecf20Sopenharmony_ci * 1998c2ecf20Sopenharmony_ci * Note that it is the caller's responsibility to invalidate the TLB after 2008c2ecf20Sopenharmony_ci * calling this function to ensure that the updated permissions are visible 2018c2ecf20Sopenharmony_ci * to the CPUs. 2028c2ecf20Sopenharmony_ci * 2038c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 2048c2ecf20Sopenharmony_ci */ 2058c2ecf20Sopenharmony_ciint kvm_pgtable_stage2_wrprotect(struct kvm_pgtable *pgt, u64 addr, u64 size); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci/** 2088c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_mkyoung() - Set the access flag in a page-table entry. 2098c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 2108c2ecf20Sopenharmony_ci * @addr: Intermediate physical address to identify the page-table entry. 2118c2ecf20Sopenharmony_ci * 2128c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored. 2138c2ecf20Sopenharmony_ci * 2148c2ecf20Sopenharmony_ci * If there is a valid, leaf page-table entry used to translate @addr, then 2158c2ecf20Sopenharmony_ci * set the access flag in that entry. 2168c2ecf20Sopenharmony_ci * 2178c2ecf20Sopenharmony_ci * Return: The old page-table entry prior to setting the flag, 0 on failure. 2188c2ecf20Sopenharmony_ci */ 2198c2ecf20Sopenharmony_cikvm_pte_t kvm_pgtable_stage2_mkyoung(struct kvm_pgtable *pgt, u64 addr); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci/** 2228c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_mkold() - Clear the access flag in a page-table entry. 2238c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 2248c2ecf20Sopenharmony_ci * @addr: Intermediate physical address to identify the page-table entry. 2258c2ecf20Sopenharmony_ci * 2268c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored. 2278c2ecf20Sopenharmony_ci * 2288c2ecf20Sopenharmony_ci * If there is a valid, leaf page-table entry used to translate @addr, then 2298c2ecf20Sopenharmony_ci * clear the access flag in that entry. 2308c2ecf20Sopenharmony_ci * 2318c2ecf20Sopenharmony_ci * Note that it is the caller's responsibility to invalidate the TLB after 2328c2ecf20Sopenharmony_ci * calling this function to ensure that the updated permissions are visible 2338c2ecf20Sopenharmony_ci * to the CPUs. 2348c2ecf20Sopenharmony_ci * 2358c2ecf20Sopenharmony_ci * Return: The old page-table entry prior to clearing the flag, 0 on failure. 2368c2ecf20Sopenharmony_ci */ 2378c2ecf20Sopenharmony_cikvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci/** 2408c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_relax_perms() - Relax the permissions enforced by a 2418c2ecf20Sopenharmony_ci * page-table entry. 2428c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 2438c2ecf20Sopenharmony_ci * @addr: Intermediate physical address to identify the page-table entry. 2448c2ecf20Sopenharmony_ci * @prot: Additional permissions to grant for the mapping. 2458c2ecf20Sopenharmony_ci * 2468c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored. 2478c2ecf20Sopenharmony_ci * 2488c2ecf20Sopenharmony_ci * If there is a valid, leaf page-table entry used to translate @addr, then 2498c2ecf20Sopenharmony_ci * relax the permissions in that entry according to the read, write and 2508c2ecf20Sopenharmony_ci * execute permissions specified by @prot. No permissions are removed, and 2518c2ecf20Sopenharmony_ci * TLB invalidation is performed after updating the entry. 2528c2ecf20Sopenharmony_ci * 2538c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_ciint kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, 2568c2ecf20Sopenharmony_ci enum kvm_pgtable_prot prot); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci/** 2598c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_is_young() - Test whether a page-table entry has the 2608c2ecf20Sopenharmony_ci * access flag set. 2618c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 2628c2ecf20Sopenharmony_ci * @addr: Intermediate physical address to identify the page-table entry. 2638c2ecf20Sopenharmony_ci * 2648c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored. 2658c2ecf20Sopenharmony_ci * 2668c2ecf20Sopenharmony_ci * Return: True if the page-table entry has the access flag set, false otherwise. 2678c2ecf20Sopenharmony_ci */ 2688c2ecf20Sopenharmony_cibool kvm_pgtable_stage2_is_young(struct kvm_pgtable *pgt, u64 addr); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci/** 2718c2ecf20Sopenharmony_ci * kvm_pgtable_stage2_flush_range() - Clean and invalidate data cache to Point 2728c2ecf20Sopenharmony_ci * of Coherency for guest stage-2 address 2738c2ecf20Sopenharmony_ci * range. 2748c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init(). 2758c2ecf20Sopenharmony_ci * @addr: Intermediate physical address from which to flush. 2768c2ecf20Sopenharmony_ci * @size: Size of the range. 2778c2ecf20Sopenharmony_ci * 2788c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored and @size is rounded-up to 2798c2ecf20Sopenharmony_ci * the next page boundary. 2808c2ecf20Sopenharmony_ci * 2818c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 2828c2ecf20Sopenharmony_ci */ 2838c2ecf20Sopenharmony_ciint kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci/** 2868c2ecf20Sopenharmony_ci * kvm_pgtable_walk() - Walk a page-table. 2878c2ecf20Sopenharmony_ci * @pgt: Page-table structure initialised by kvm_pgtable_*_init(). 2888c2ecf20Sopenharmony_ci * @addr: Input address for the start of the walk. 2898c2ecf20Sopenharmony_ci * @size: Size of the range to walk. 2908c2ecf20Sopenharmony_ci * @walker: Walker callback description. 2918c2ecf20Sopenharmony_ci * 2928c2ecf20Sopenharmony_ci * The offset of @addr within a page is ignored and @size is rounded-up to 2938c2ecf20Sopenharmony_ci * the next page boundary. 2948c2ecf20Sopenharmony_ci * 2958c2ecf20Sopenharmony_ci * The walker will walk the page-table entries corresponding to the input 2968c2ecf20Sopenharmony_ci * address range specified, visiting entries according to the walker flags. 2978c2ecf20Sopenharmony_ci * Invalid entries are treated as leaf entries. Leaf entries are reloaded 2988c2ecf20Sopenharmony_ci * after invoking the walker callback, allowing the walker to descend into 2998c2ecf20Sopenharmony_ci * a newly installed table. 3008c2ecf20Sopenharmony_ci * 3018c2ecf20Sopenharmony_ci * Returning a negative error code from the walker callback function will 3028c2ecf20Sopenharmony_ci * terminate the walk immediately with the same error code. 3038c2ecf20Sopenharmony_ci * 3048c2ecf20Sopenharmony_ci * Return: 0 on success, negative error code on failure. 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_ciint kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, 3078c2ecf20Sopenharmony_ci struct kvm_pgtable_walker *walker); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci#endif /* __ARM64_KVM_PGTABLE_H__ */ 310