1c0ef6326SSuzuki K Poulose /* 2c0ef6326SSuzuki K Poulose * Copyright (C) 2016 - ARM Ltd 3c0ef6326SSuzuki K Poulose * 4c0ef6326SSuzuki K Poulose * stage2 page table helpers 5c0ef6326SSuzuki K Poulose * 6c0ef6326SSuzuki K Poulose * This program is free software; you can redistribute it and/or modify 7c0ef6326SSuzuki K Poulose * it under the terms of the GNU General Public License version 2 as 8c0ef6326SSuzuki K Poulose * published by the Free Software Foundation. 9c0ef6326SSuzuki K Poulose * 10c0ef6326SSuzuki K Poulose * This program is distributed in the hope that it will be useful, 11c0ef6326SSuzuki K Poulose * but WITHOUT ANY WARRANTY; without even the implied warranty of 12c0ef6326SSuzuki K Poulose * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13c0ef6326SSuzuki K Poulose * GNU General Public License for more details. 14c0ef6326SSuzuki K Poulose * 15c0ef6326SSuzuki K Poulose * You should have received a copy of the GNU General Public License 16c0ef6326SSuzuki K Poulose * along with this program. If not, see <http://www.gnu.org/licenses/>. 17c0ef6326SSuzuki K Poulose */ 18c0ef6326SSuzuki K Poulose 19c0ef6326SSuzuki K Poulose #ifndef __ARM64_S2_PGTABLE_H_ 20c0ef6326SSuzuki K Poulose #define __ARM64_S2_PGTABLE_H_ 21c0ef6326SSuzuki K Poulose 22c0ef6326SSuzuki K Poulose #include <asm/pgtable.h> 23c0ef6326SSuzuki K Poulose 24c0ef6326SSuzuki K Poulose /* 25c0ef6326SSuzuki K Poulose * In the case where PGDIR_SHIFT is larger than KVM_PHYS_SHIFT, we can address 26c0ef6326SSuzuki K Poulose * the entire IPA input range with a single pgd entry, and we would only need 27c0ef6326SSuzuki K Poulose * one pgd entry. Note that in this case, the pgd is actually not used by 28c0ef6326SSuzuki K Poulose * the MMU for Stage-2 translations, but is merely a fake pgd used as a data 29c0ef6326SSuzuki K Poulose * structure for the kernel pgtable macros to work. 30c0ef6326SSuzuki K Poulose */ 31c0ef6326SSuzuki K Poulose #if PGDIR_SHIFT > KVM_PHYS_SHIFT 32c0ef6326SSuzuki K Poulose #define PTRS_PER_S2_PGD_SHIFT 0 33c0ef6326SSuzuki K Poulose #else 34c0ef6326SSuzuki K Poulose #define PTRS_PER_S2_PGD_SHIFT (KVM_PHYS_SHIFT - PGDIR_SHIFT) 35c0ef6326SSuzuki K Poulose #endif 36c0ef6326SSuzuki K Poulose #define PTRS_PER_S2_PGD (1 << PTRS_PER_S2_PGD_SHIFT) 37c0ef6326SSuzuki K Poulose 38c0ef6326SSuzuki K Poulose /* 39c0ef6326SSuzuki K Poulose * If we are concatenating first level stage-2 page tables, we would have less 40c0ef6326SSuzuki K Poulose * than or equal to 16 pointers in the fake PGD, because that's what the 41c0ef6326SSuzuki K Poulose * architecture allows. In this case, (4 - CONFIG_PGTABLE_LEVELS) 42c0ef6326SSuzuki K Poulose * represents the first level for the host, and we add 1 to go to the next 43c0ef6326SSuzuki K Poulose * level (which uses contatenation) for the stage-2 tables. 44c0ef6326SSuzuki K Poulose */ 45c0ef6326SSuzuki K Poulose #if PTRS_PER_S2_PGD <= 16 46c0ef6326SSuzuki K Poulose #define KVM_PREALLOC_LEVEL (4 - CONFIG_PGTABLE_LEVELS + 1) 47c0ef6326SSuzuki K Poulose #else 48c0ef6326SSuzuki K Poulose #define KVM_PREALLOC_LEVEL (0) 49c0ef6326SSuzuki K Poulose #endif 50c0ef6326SSuzuki K Poulose 51c0ef6326SSuzuki K Poulose #define stage2_pgd_none(pgd) pgd_none(pgd) 52c0ef6326SSuzuki K Poulose #define stage2_pgd_clear(pgd) pgd_clear(pgd) 53c0ef6326SSuzuki K Poulose #define stage2_pgd_present(pgd) pgd_present(pgd) 54c0ef6326SSuzuki K Poulose #define stage2_pgd_populate(pgd, pud) pgd_populate(NULL, pgd, pud) 55c0ef6326SSuzuki K Poulose #define stage2_pud_offset(pgd, address) pud_offset(pgd, address) 56c0ef6326SSuzuki K Poulose #define stage2_pud_free(pud) pud_free(NULL, pud) 57c0ef6326SSuzuki K Poulose 58c0ef6326SSuzuki K Poulose #define stage2_pud_none(pud) pud_none(pud) 59c0ef6326SSuzuki K Poulose #define stage2_pud_clear(pud) pud_clear(pud) 60c0ef6326SSuzuki K Poulose #define stage2_pud_present(pud) pud_present(pud) 61c0ef6326SSuzuki K Poulose #define stage2_pud_populate(pud, pmd) pud_populate(NULL, pud, pmd) 62c0ef6326SSuzuki K Poulose #define stage2_pmd_offset(pud, address) pmd_offset(pud, address) 63c0ef6326SSuzuki K Poulose #define stage2_pmd_free(pmd) pmd_free(NULL, pmd) 64c0ef6326SSuzuki K Poulose 65c0ef6326SSuzuki K Poulose #define stage2_pud_huge(pud) pud_huge(pud) 66c0ef6326SSuzuki K Poulose 67c0ef6326SSuzuki K Poulose #define stage2_pgd_addr_end(address, end) pgd_addr_end(address, end) 68c0ef6326SSuzuki K Poulose #define stage2_pud_addr_end(address, end) pud_addr_end(address, end) 69c0ef6326SSuzuki K Poulose #define stage2_pmd_addr_end(address, end) pmd_addr_end(address, end) 70c0ef6326SSuzuki K Poulose 71c0ef6326SSuzuki K Poulose #define stage2_pte_table_empty(ptep) kvm_page_empty(ptep) 72c0ef6326SSuzuki K Poulose #ifdef __PGTABLE_PMD_FOLDED 73c0ef6326SSuzuki K Poulose #define stage2_pmd_table_empty(pmdp) (0) 74c0ef6326SSuzuki K Poulose #else 75c0ef6326SSuzuki K Poulose #define stage2_pmd_table_empty(pmdp) ((KVM_PREALLOC_LEVEL < 2) && kvm_page_empty(pmdp)) 76c0ef6326SSuzuki K Poulose #endif 77c0ef6326SSuzuki K Poulose 78c0ef6326SSuzuki K Poulose #ifdef __PGTABLE_PUD_FOLDED 79c0ef6326SSuzuki K Poulose #define stage2_pud_table_empty(pudp) (0) 80c0ef6326SSuzuki K Poulose #else 81c0ef6326SSuzuki K Poulose #define stage2_pud_table_empty(pudp) ((KVM_PREALLOC_LEVEL < 1) && kvm_page_empty(pudp)) 82c0ef6326SSuzuki K Poulose #endif 83c0ef6326SSuzuki K Poulose 84c0ef6326SSuzuki K Poulose #define stage2_pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1)) 85c0ef6326SSuzuki K Poulose 86c0ef6326SSuzuki K Poulose #endif /* __ARM64_S2_PGTABLE_H_ */ 87