1
+ #include <linux/module.h>
1
2
#include <linux/kernel.h>
3
+ #include <linux/slab.h>
2
4
3
5
#include <asm/cputype.h>
4
6
#include <asm/idmap.h>
5
7
#include <asm/pgalloc.h>
6
8
#include <asm/pgtable.h>
7
9
#include <asm/sections.h>
8
10
#include <asm/system_info.h>
11
+ #include <asm/virt.h>
9
12
10
13
pgd_t * idmap_pgd ;
11
14
@@ -59,11 +62,17 @@ static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
59
62
} while (pud ++ , addr = next , addr != end );
60
63
}
61
64
62
- static void identity_mapping_add (pgd_t * pgd , unsigned long addr , unsigned long end )
65
+ static void identity_mapping_add (pgd_t * pgd , const char * text_start ,
66
+ const char * text_end , unsigned long prot )
63
67
{
64
- unsigned long prot , next ;
68
+ unsigned long addr , end ;
69
+ unsigned long next ;
70
+
71
+ addr = virt_to_phys (text_start );
72
+ end = virt_to_phys (text_end );
73
+
74
+ prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF ;
65
75
66
- prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF ;
67
76
if (cpu_architecture () <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale ())
68
77
prot |= PMD_BIT4 ;
69
78
@@ -74,28 +83,52 @@ static void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long e
74
83
} while (pgd ++ , addr = next , addr != end );
75
84
}
76
85
86
+ #if defined(CONFIG_ARM_VIRT_EXT ) && defined(CONFIG_ARM_LPAE )
87
+ pgd_t * hyp_pgd ;
88
+
89
+ extern char __hyp_idmap_text_start [], __hyp_idmap_text_end [];
90
+
91
+ static int __init init_static_idmap_hyp (void )
92
+ {
93
+ hyp_pgd = kzalloc (PTRS_PER_PGD * sizeof (pgd_t ), GFP_KERNEL );
94
+ if (!hyp_pgd )
95
+ return - ENOMEM ;
96
+
97
+ pr_info ("Setting up static HYP identity map for 0x%p - 0x%p\n" ,
98
+ __hyp_idmap_text_start , __hyp_idmap_text_end );
99
+ identity_mapping_add (hyp_pgd , __hyp_idmap_text_start ,
100
+ __hyp_idmap_text_end , PMD_SECT_AP1 );
101
+
102
+ return 0 ;
103
+ }
104
+ #else
105
+ static int __init init_static_idmap_hyp (void )
106
+ {
107
+ return 0 ;
108
+ }
109
+ #endif
110
+
77
111
extern char __idmap_text_start [], __idmap_text_end [];
78
112
79
113
static int __init init_static_idmap (void )
80
114
{
81
- phys_addr_t idmap_start , idmap_end ;
115
+ int ret ;
82
116
83
117
idmap_pgd = pgd_alloc (& init_mm );
84
118
if (!idmap_pgd )
85
119
return - ENOMEM ;
86
120
87
- /* Add an identity mapping for the physical address of the section. */
88
- idmap_start = virt_to_phys ((void * )__idmap_text_start );
89
- idmap_end = virt_to_phys ((void * )__idmap_text_end );
121
+ pr_info ("Setting up static identity map for 0x%p - 0x%p\n" ,
122
+ __idmap_text_start , __idmap_text_end );
123
+ identity_mapping_add (idmap_pgd , __idmap_text_start ,
124
+ __idmap_text_end , 0 );
90
125
91
- pr_info ("Setting up static identity map for 0x%llx - 0x%llx\n" ,
92
- (long long )idmap_start , (long long )idmap_end );
93
- identity_mapping_add (idmap_pgd , idmap_start , idmap_end );
126
+ ret = init_static_idmap_hyp ();
94
127
95
128
/* Flush L1 for the hardware to see this page table content */
96
129
flush_cache_louis ();
97
130
98
- return 0 ;
131
+ return ret ;
99
132
}
100
133
early_initcall (init_static_idmap );
101
134
0 commit comments