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