Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
28cdac66
Commit
28cdac66
authored
Jan 06, 2011
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pgt' (early part) into devel
parents
4073723a
36bb94ba
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
315 additions
and
332 deletions
+315
-332
arch/arm/include/asm/page.h
arch/arm/include/asm/page.h
+4
-2
arch/arm/include/asm/pgalloc.h
arch/arm/include/asm/pgalloc.h
+22
-28
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/pgtable.h
+155
-160
arch/arm/kernel/smp.c
arch/arm/kernel/smp.c
+0
-36
arch/arm/kernel/traps.c
arch/arm/kernel/traps.c
+6
-6
arch/arm/mm/Makefile
arch/arm/mm/Makefile
+2
-2
arch/arm/mm/fault-armv.c
arch/arm/mm/fault-armv.c
+1
-1
arch/arm/mm/fault.c
arch/arm/mm/fault.c
+1
-1
arch/arm/mm/idmap.c
arch/arm/mm/idmap.c
+67
-0
arch/arm/mm/mm.h
arch/arm/mm/mm.h
+1
-1
arch/arm/mm/mmu.c
arch/arm/mm/mmu.c
+13
-49
arch/arm/mm/pgd.c
arch/arm/mm/pgd.c
+18
-19
arch/arm/mm/proc-macros.S
arch/arm/mm/proc-macros.S
+15
-15
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-v7.S
+8
-10
arch/arm/mm/proc-xscale.S
arch/arm/mm/proc-xscale.S
+2
-2
No files found.
arch/arm/include/asm/page.h
View file @
28cdac66
...
...
@@ -151,13 +151,15 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern
void
copy_page
(
void
*
to
,
const
void
*
from
);
typedef
unsigned
long
pteval_t
;
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
typedef
struct
{
unsigned
long
pte
;
}
pte_t
;
typedef
struct
{
pteval_t
pte
;
}
pte_t
;
typedef
struct
{
unsigned
long
pmd
;
}
pmd_t
;
typedef
struct
{
unsigned
long
pgd
[
2
];
}
pgd_t
;
typedef
struct
{
unsigned
long
pgprot
;
}
pgprot_t
;
...
...
@@ -175,7 +177,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
/*
* .. while these make it easier on the compiler
*/
typedef
unsigned
long
pte_t
;
typedef
pteval_t
pte_t
;
typedef
unsigned
long
pmd_t
;
typedef
unsigned
long
pgd_t
[
2
];
typedef
unsigned
long
pgprot_t
;
...
...
arch/arm/include/asm/pgalloc.h
View file @
28cdac66
...
...
@@ -30,14 +30,16 @@
#define pmd_free(mm, pmd) do { } while (0)
#define pgd_populate(mm,pmd,pte) BUG()
extern
pgd_t
*
get_pgd_slow
(
struct
mm_struct
*
mm
);
extern
void
free_pgd_slow
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd
);
#define pgd_alloc(mm) get_pgd_slow(mm)
#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
extern
pgd_t
*
pgd_alloc
(
struct
mm_struct
*
mm
);
extern
void
pgd_free
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd
);
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
static
inline
void
clean_pte_table
(
pte_t
*
pte
)
{
clean_dcache_area
(
pte
+
PTE_HWTABLE_PTRS
,
PTE_HWTABLE_SIZE
);
}
/*
* Allocate one PTE table.
*
...
...
@@ -45,14 +47,14 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
* into one table thus:
*
* +------------+
* | h/w pt 0 |
* +------------+
* | h/w pt 1 |
* +------------+
* | Linux pt 0 |
* +------------+
* | Linux pt 1 |
* +------------+
* | h/w pt 0 |
* +------------+
* | h/w pt 1 |
* +------------+
*/
static
inline
pte_t
*
pte_alloc_one_kernel
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
...
...
@@ -60,10 +62,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
pte_t
*
pte
;
pte
=
(
pte_t
*
)
__get_free_page
(
PGALLOC_GFP
);
if
(
pte
)
{
clean_dcache_area
(
pte
,
sizeof
(
pte_t
)
*
PTRS_PER_PTE
);
pte
+=
PTRS_PER_PTE
;
}
if
(
pte
)
clean_pte_table
(
pte
);
return
pte
;
}
...
...
@@ -79,10 +79,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
pte
=
alloc_pages
(
PGALLOC_GFP
,
0
);
#endif
if
(
pte
)
{
if
(
!
PageHighMem
(
pte
))
{
void
*
page
=
page_address
(
pte
);
clean_dcache_area
(
page
,
sizeof
(
pte_t
)
*
PTRS_PER_PTE
);
}
if
(
!
PageHighMem
(
pte
))
clean_pte_table
(
page_address
(
pte
));
pgtable_page_ctor
(
pte
);
}
...
...
@@ -94,10 +92,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
*/
static
inline
void
pte_free_kernel
(
struct
mm_struct
*
mm
,
pte_t
*
pte
)
{
if
(
pte
)
{
pte
-=
PTRS_PER_PTE
;
if
(
pte
)
free_page
((
unsigned
long
)
pte
);
}
}
static
inline
void
pte_free
(
struct
mm_struct
*
mm
,
pgtable_t
pte
)
...
...
@@ -106,8 +102,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
__free_page
(
pte
);
}
static
inline
void
__pmd_populate
(
pmd_t
*
pmdp
,
unsigned
long
pmdval
)
static
inline
void
__pmd_populate
(
pmd_t
*
pmdp
,
phys_addr_t
pte
,
unsigned
long
prot
)
{
unsigned
long
pmdval
=
(
pte
+
PTE_HWTABLE_OFF
)
|
prot
;
pmdp
[
0
]
=
__pmd
(
pmdval
);
pmdp
[
1
]
=
__pmd
(
pmdval
+
256
*
sizeof
(
pte_t
));
flush_pmd_entry
(
pmdp
);
...
...
@@ -122,20 +120,16 @@ static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
static
inline
void
pmd_populate_kernel
(
struct
mm_struct
*
mm
,
pmd_t
*
pmdp
,
pte_t
*
ptep
)
{
unsigned
long
pte_ptr
=
(
unsigned
long
)
ptep
;
/*
* The pmd must be loaded with the physical
* address of the PTE table
* The pmd must be loaded with the physical address of the PTE table
*/
pte_ptr
-=
PTRS_PER_PTE
*
sizeof
(
void
*
);
__pmd_populate
(
pmdp
,
__pa
(
pte_ptr
)
|
_PAGE_KERNEL_TABLE
);
__pmd_populate
(
pmdp
,
__pa
(
ptep
),
_PAGE_KERNEL_TABLE
);
}
static
inline
void
pmd_populate
(
struct
mm_struct
*
mm
,
pmd_t
*
pmdp
,
pgtable_t
ptep
)
{
__pmd_populate
(
pmdp
,
page_to_p
fn
(
ptep
)
<<
PAGE_SHIFT
|
_PAGE_USER_TABLE
);
__pmd_populate
(
pmdp
,
page_to_p
hys
(
ptep
),
_PAGE_USER_TABLE
);
}
#define pmd_pgtable(pmd) pmd_page(pmd)
...
...
arch/arm/include/asm/pgtable.h
View file @
28cdac66
This diff is collapsed.
Click to expand it.
arch/arm/kernel/smp.c
View file @
28cdac66
...
...
@@ -55,42 +55,6 @@ enum ipi_msg_type {
IPI_CPU_STOP
,
};
static
inline
void
identity_mapping_add
(
pgd_t
*
pgd
,
unsigned
long
start
,
unsigned
long
end
)
{
unsigned
long
addr
,
prot
;
pmd_t
*
pmd
;
prot
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
;
if
(
cpu_architecture
()
<=
CPU_ARCH_ARMv5TEJ
&&
!
cpu_is_xscale
())
prot
|=
PMD_BIT4
;
for
(
addr
=
start
&
PGDIR_MASK
;
addr
<
end
;)
{
pmd
=
pmd_offset
(
pgd
+
pgd_index
(
addr
),
addr
);
pmd
[
0
]
=
__pmd
(
addr
|
prot
);
addr
+=
SECTION_SIZE
;
pmd
[
1
]
=
__pmd
(
addr
|
prot
);
addr
+=
SECTION_SIZE
;
flush_pmd_entry
(
pmd
);
outer_clean_range
(
__pa
(
pmd
),
__pa
(
pmd
+
1
));
}
}
static
inline
void
identity_mapping_del
(
pgd_t
*
pgd
,
unsigned
long
start
,
unsigned
long
end
)
{
unsigned
long
addr
;
pmd_t
*
pmd
;
for
(
addr
=
start
&
PGDIR_MASK
;
addr
<
end
;
addr
+=
PGDIR_SIZE
)
{
pmd
=
pmd_offset
(
pgd
+
pgd_index
(
addr
),
addr
);
pmd
[
0
]
=
__pmd
(
0
);
pmd
[
1
]
=
__pmd
(
0
);
clean_pmd_entry
(
pmd
);
outer_clean_range
(
__pa
(
pmd
),
__pa
(
pmd
+
1
));
}
}
int
__cpuinit
__cpu_up
(
unsigned
int
cpu
)
{
struct
cpuinfo_arm
*
ci
=
&
per_cpu
(
cpu_data
,
cpu
);
...
...
arch/arm/kernel/traps.c
View file @
28cdac66
...
...
@@ -710,19 +710,19 @@ void __readwrite_bug(const char *fn)
}
EXPORT_SYMBOL
(
__readwrite_bug
);
void
__pte_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
)
void
__pte_error
(
const
char
*
file
,
int
line
,
pte_t
pte
)
{
printk
(
"%s:%d: bad pte %08lx.
\n
"
,
file
,
line
,
val
);
printk
(
"%s:%d: bad pte %08lx.
\n
"
,
file
,
line
,
pte_val
(
pte
)
);
}
void
__pmd_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
)
void
__pmd_error
(
const
char
*
file
,
int
line
,
pmd_t
pmd
)
{
printk
(
"%s:%d: bad pmd %08lx.
\n
"
,
file
,
line
,
val
);
printk
(
"%s:%d: bad pmd %08lx.
\n
"
,
file
,
line
,
pmd_val
(
pmd
)
);
}
void
__pgd_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
)
void
__pgd_error
(
const
char
*
file
,
int
line
,
pgd_t
pgd
)
{
printk
(
"%s:%d: bad pgd %08lx.
\n
"
,
file
,
line
,
val
);
printk
(
"%s:%d: bad pgd %08lx.
\n
"
,
file
,
line
,
pgd_val
(
pgd
)
);
}
asmlinkage
void
__div0
(
void
)
...
...
arch/arm/mm/Makefile
View file @
28cdac66
...
...
@@ -5,8 +5,8 @@
obj-y
:=
dma-mapping.o extable.o fault.o init.o
\
iomap.o
obj-$(CONFIG_MMU)
+=
fault-armv.o flush.o i
oremap.o m
map.o
\
pgd.o mmu.o vmregion.o
obj-$(CONFIG_MMU)
+=
fault-armv.o flush.o i
dmap.o iore
map.o
\
mmap.o
pgd.o mmu.o vmregion.o
ifneq
($(CONFIG_MMU),y)
obj-y
+=
nommu.o
...
...
arch/arm/mm/fault-armv.c
View file @
28cdac66
...
...
@@ -26,7 +26,7 @@
#include "mm.h"
static
unsigned
long
shared_pte_mask
=
L_PTE_MT_BUFFERABLE
;
static
pteval_t
shared_pte_mask
=
L_PTE_MT_BUFFERABLE
;
#if __LINUX_ARM_ARCH__ < 6
/*
...
...
arch/arm/mm/fault.c
View file @
28cdac66
...
...
@@ -108,7 +108,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
pte
=
pte_offset_map
(
pmd
,
addr
);
printk
(
", *pte=%08lx"
,
pte_val
(
*
pte
));
printk
(
", *ppte=%08lx"
,
pte_val
(
pte
[
-
PTRS_PER_PTE
]));
printk
(
", *ppte=%08lx"
,
pte_val
(
pte
[
PTE_HWTABLE_PTRS
]));
pte_unmap
(
pte
);
}
while
(
0
);
...
...
arch/arm/mm/idmap.c
0 → 100644
View file @
28cdac66
#include <linux/kernel.h>
#include <asm/cputype.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
static
void
idmap_add_pmd
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
,
unsigned
long
prot
)
{
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
addr
=
(
addr
&
PMD_MASK
)
|
prot
;
pmd
[
0
]
=
__pmd
(
addr
);
addr
+=
SECTION_SIZE
;
pmd
[
1
]
=
__pmd
(
addr
);
flush_pmd_entry
(
pmd
);
}
void
identity_mapping_add
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
)
{
unsigned
long
prot
,
next
;
prot
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
;
if
(
cpu_architecture
()
<=
CPU_ARCH_ARMv5TEJ
&&
!
cpu_is_xscale
())
prot
|=
PMD_BIT4
;
pgd
+=
pgd_index
(
addr
);
do
{
next
=
pgd_addr_end
(
addr
,
end
);
idmap_add_pmd
(
pgd
,
addr
,
next
,
prot
);
}
while
(
pgd
++
,
addr
=
next
,
addr
!=
end
);
}
#ifdef CONFIG_SMP
static
void
idmap_del_pmd
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
)
{
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
pmd_clear
(
pmd
);
}
void
identity_mapping_del
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
)
{
unsigned
long
next
;
pgd
+=
pgd_index
(
addr
);
do
{
next
=
pgd_addr_end
(
addr
,
end
);
idmap_del_pmd
(
pgd
,
addr
,
next
);
}
while
(
pgd
++
,
addr
=
next
,
addr
!=
end
);
}
#endif
/*
* In order to soft-boot, we need to insert a 1:1 mapping in place of
* the user-mode pages. This will then ensure that we have predictable
* results when turning the mmu off
*/
void
setup_mm_for_reboot
(
char
mode
)
{
/*
* We need to access to user-mode page tables here. For kernel threads
* we don't have any user-mode mappings so we use the context that we
* "borrowed".
*/
identity_mapping_add
(
current
->
active_mm
->
pgd
,
0
,
TASK_SIZE
);
local_flush_tlb_all
();
}
arch/arm/mm/mm.h
View file @
28cdac66
...
...
@@ -16,7 +16,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
}
struct
mem_type
{
unsigned
in
t
prot_pte
;
pteval_
t
prot_pte
;
unsigned
int
prot_l1
;
unsigned
int
prot_sect
;
unsigned
int
domain
;
...
...
arch/arm/mm/mmu.c
View file @
28cdac66
...
...
@@ -63,7 +63,7 @@ struct cachepolicy {
const
char
policy
[
16
];
unsigned
int
cr_mask
;
unsigned
int
pmd
;
unsigned
in
t
pte
;
pteval_
t
pte
;
};
static
struct
cachepolicy
cache_policies
[]
__initdata
=
{
...
...
@@ -191,7 +191,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
}
#endif
#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_
WRITE
#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_
XN
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
static
struct
mem_type
mem_types
[]
=
{
...
...
@@ -236,19 +236,18 @@ static struct mem_type mem_types[] = {
},
[
MT_LOW_VECTORS
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_
EXEC
,
L_PTE_
RDONLY
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
domain
=
DOMAIN_USER
,
},
[
MT_HIGH_VECTORS
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_USER
|
L_PTE_
EXEC
,
L_PTE_USER
|
L_PTE_
RDONLY
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
domain
=
DOMAIN_USER
,
},
[
MT_MEMORY
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_WRITE
|
L_PTE_EXEC
,
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
,
.
domain
=
DOMAIN_KERNEL
,
...
...
@@ -259,21 +258,20 @@ static struct mem_type mem_types[] = {
},
[
MT_MEMORY_NONCACHED
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_
WRITE
|
L_PTE_EXEC
|
L_PTE_
MT_BUFFERABLE
,
L_PTE_MT_BUFFERABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
,
.
domain
=
DOMAIN_KERNEL
,
},
[
MT_MEMORY_DTCM
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_
WRITE
,
L_PTE_
XN
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_XN
,
.
domain
=
DOMAIN_KERNEL
,
},
[
MT_MEMORY_ITCM
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_WRITE
|
L_PTE_EXEC
,
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
domain
=
DOMAIN_KERNEL
,
},
...
...
@@ -480,7 +478,7 @@ static void __init build_mem_type_table(void)
pgprot_user
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
user_pgprot
);
pgprot_kernel
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_WRITE
|
kern_pgprot
);
L_PTE_DIRTY
|
kern_pgprot
);
mem_types
[
MT_LOW_VECTORS
].
prot_l1
|=
ecc_mask
;
mem_types
[
MT_HIGH_VECTORS
].
prot_l1
|=
ecc_mask
;
...
...
@@ -536,7 +534,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
{
if
(
pmd_none
(
*
pmd
))
{
pte_t
*
pte
=
early_alloc
(
2
*
PTRS_PER_PTE
*
sizeof
(
pte_t
));
__pmd_populate
(
pmd
,
__pa
(
pte
)
|
prot
);
__pmd_populate
(
pmd
,
__pa
(
pte
)
,
prot
);
}
BUG_ON
(
pmd_bad
(
*
pmd
));
return
pte_offset_kernel
(
pmd
,
addr
);
...
...
@@ -554,7 +552,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
}
static
void
__init
alloc_init_section
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
,
unsigned
long
phys
,
unsigned
long
end
,
phys_addr_t
phys
,
const
struct
mem_type
*
type
)
{
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
...
...
@@ -589,7 +587,8 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
static
void
__init
create_36bit_mapping
(
struct
map_desc
*
md
,
const
struct
mem_type
*
type
)
{
unsigned
long
phys
,
addr
,
length
,
end
;
unsigned
long
addr
,
length
,
end
;
phys_addr_t
phys
;
pgd_t
*
pgd
;
addr
=
md
->
virtual
;
...
...
@@ -1044,38 +1043,3 @@ void __init paging_init(struct machine_desc *mdesc)
empty_zero_page
=
virt_to_page
(
zero_page
);
__flush_dcache_page
(
NULL
,
empty_zero_page
);
}
/*
* In order to soft-boot, we need to insert a 1:1 mapping in place of
* the user-mode pages. This will then ensure that we have predictable
* results when turning the mmu off
*/
void
setup_mm_for_reboot
(
char
mode
)
{
unsigned
long
base_pmdval
;
pgd_t
*
pgd
;
int
i
;
/*
* We need to access to user-mode page tables here. For kernel threads
* we don't have any user-mode mappings so we use the context that we
* "borrowed".
*/
pgd
=
current
->
active_mm
->
pgd
;
base_pmdval
=
PMD_SECT_AP_WRITE
|
PMD_SECT_AP_READ
|
PMD_TYPE_SECT
;
if
(
cpu_architecture
()
<=
CPU_ARCH_ARMv5TEJ
&&
!
cpu_is_xscale
())
base_pmdval
|=
PMD_BIT4
;
for
(
i
=
0
;
i
<
FIRST_USER_PGD_NR
+
USER_PTRS_PER_PGD
;
i
++
,
pgd
++
)
{
unsigned
long
pmdval
=
(
i
<<
PGDIR_SHIFT
)
|
base_pmdval
;
pmd_t
*
pmd
;
pmd
=
pmd_off
(
pgd
,
i
<<
PGDIR_SHIFT
);
pmd
[
0
]
=
__pmd
(
pmdval
);
pmd
[
1
]
=
__pmd
(
pmdval
+
(
1
<<
(
PGDIR_SHIFT
-
1
)));
flush_pmd_entry
(
pmd
);
}
local_flush_tlb_all
();
}
arch/arm/mm/pgd.c
View file @
28cdac66
...
...
@@ -17,12 +17,10 @@
#include "mm.h"
#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
/*
* need to get a 16k page for level 1
*/
pgd_t
*
get_pgd_slow
(
struct
mm_struct
*
mm
)
pgd_t
*
pgd_alloc
(
struct
mm_struct
*
mm
)
{
pgd_t
*
new_pgd
,
*
init_pgd
;
pmd_t
*
new_pmd
,
*
init_pmd
;
...
...
@@ -32,14 +30,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if
(
!
new_pgd
)
goto
no_pgd
;
memset
(
new_pgd
,
0
,
FIRST_KERNEL_PGD_NR
*
sizeof
(
pgd_t
));
memset
(
new_pgd
,
0
,
USER_PTRS_PER_PGD
*
sizeof
(
pgd_t
));
/*
* Copy over the kernel and IO PGD entries
*/
init_pgd
=
pgd_offset_k
(
0
);
memcpy
(
new_pgd
+
FIRST_KERNEL_PGD_NR
,
init_pgd
+
FIRST_KERNEL_PGD_NR
,
(
PTRS_PER_PGD
-
FIRST_KERNEL_PGD_NR
)
*
sizeof
(
pgd_t
));
memcpy
(
new_pgd
+
USER_PTRS_PER_PGD
,
init_pgd
+
USER_PTRS_PER_PGD
,
(
PTRS_PER_PGD
-
USER_PTRS_PER_PGD
)
*
sizeof
(
pgd_t
));
clean_dcache_area
(
new_pgd
,
PTRS_PER_PGD
*
sizeof
(
pgd_t
));
...
...
@@ -73,28 +71,29 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
return
NULL
;
}
void
free_pgd_slow
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd
)
void
pgd_free
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd_base
)
{
pgd_t
*
pgd
;
pmd_t
*
pmd
;
pgtable_t
pte
;
if
(
!
pgd
)
if
(
!
pgd
_base
)
return
;
/* pgd is always present and good */
pmd
=
pmd_off
(
pgd
,
0
);
if
(
pmd_none
(
*
pmd
))
goto
free
;
if
(
pmd_bad
(
*
pmd
))
{
pmd_ERROR
(
*
pmd
);
pmd_clear
(
pmd
);
goto
free
;
}
pgd
=
pgd_base
+
pgd_index
(
0
);
if
(
pgd_none_or_clear_bad
(
pgd
))
goto
no_pgd
;
pmd
=
pmd_offset
(
pgd
,
0
);
if
(
pmd_none_or_clear_bad
(
pmd
))
goto
no_pmd
;
pte
=
pmd_pgtable
(
*
pmd
);
pmd_clear
(
pmd
);
pte_free
(
mm
,
pte
);
no_pmd:
pgd_clear
(
pgd
);
pmd_free
(
mm
,
pmd
);
free
:
free_pages
((
unsigned
long
)
pgd
,
2
);
no_pgd
:
free_pages
((
unsigned
long
)
pgd
_base
,
2
);
}
arch/arm/mm/proc-macros.S
View file @
28cdac66
...
...
@@ -91,7 +91,7 @@
#if L_PTE_SHARED != PTE_EXT_SHARED
#error PTE shared bit mismatch
#endif
#if (L_PTE_
EXEC+L_PTE_USER+L_PTE_WRITE
+L_PTE_DIRTY+L_PTE_YOUNG+\
#if (L_PTE_
XN+L_PTE_USER+L_PTE_RDONLY
+L_PTE_DIRTY+L_PTE_YOUNG+\
L_PTE_FILE
+
L_PTE_PRESENT
)
>
L_PTE_SHARED
#error Invalid Linux PTE bit settings
#endif
...
...
@@ -135,7 +135,7 @@
.
endm
.
macro
armv6_set_pte_ext
pfx
str
r1
,
[
r0
],
#
-
2048
@
linux
version
str
r1
,
[
r0
],
#
2048
@
linux
version
bic
r3
,
r1
,
#
0x000003fc
bic
r3
,
r3
,
#
PTE_TYPE_MASK
...
...
@@ -146,9 +146,9 @@
and
r2
,
r1
,
#
L_PTE_MT_MASK
ldr
r2
,
[
ip
,
r2
]
tst
r1
,
#
L_PTE_WRITE
tst
ne
r1
,
#
L_PTE_DIRT
Y
orr
eq
r3
,
r3
,
#
PTE_EXT_APX
eor
r1
,
r1
,
#
L_PTE_DIRTY
tst
r1
,
#
L_PTE_DIRTY
|
L_PTE_RDONL
Y
orr
ne
r3
,
r3
,
#
PTE_EXT_APX
tst
r1
,
#
L_PTE_USER
orrne
r3
,
r3
,
#
PTE_EXT_AP1
...
...
@@ -158,8 +158,8 @@
bicne
r3
,
r3
,
#
PTE_EXT_APX
|
PTE_EXT_AP0
#endif
tst
r1
,
#
L_PTE_
EXEC
orr
eq
r3
,
r3
,
#
PTE_EXT_XN
tst
r1
,
#
L_PTE_
XN
orr
ne
r3
,
r3
,
#
PTE_EXT_XN
orr
r3
,
r3
,
r2
...
...
@@ -187,9 +187,9 @@
*
1111
0xff
r
/
w
r
/
w
*/
.
macro
armv3_set_pte_ext
wc_disable
=
1
str
r1
,
[
r0
],
#
-
2048
@
linux
version
str
r1
,
[
r0
],
#
2048
@
linux
version
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_
WRITE
|
L_PTE_
DIRTY
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_DIRTY
bic
r2
,
r1
,
#
PTE_SMALL_AP_MASK
@
keep
C
,
B
bits
bic
r2
,
r2
,
#
PTE_TYPE_MASK
...
...
@@ -198,7 +198,7 @@
tst
r3
,
#
L_PTE_USER
@
user
?
orrne
r2
,
r2
,
#
PTE_SMALL_AP_URO_SRW
tst
r3
,
#
L_PTE_
WRITE
|
L_PTE_DIRTY
@
write
and
dirty
?
tst
r3
,
#
L_PTE_
RDONLY
|
L_PTE_DIRTY
@
write
and
dirty
?
orreq
r2
,
r2
,
#
PTE_SMALL_AP_UNO_SRW
tst
r3
,
#
L_PTE_PRESENT
|
L_PTE_YOUNG
@
present
and
young
?
...
...
@@ -210,7 +210,7 @@
bicne
r2
,
r2
,
#
PTE_BUFFERABLE
#endif
.
endif
str
r2
,
[
r0
]
@
hardware
version
str
r2
,
[
r0
]
@
hardware
version
.
endm
...
...
@@ -230,9 +230,9 @@
*
1111
11
r
/
w
r
/
w
*/
.
macro
xscale_set_pte_ext_prologue
str
r1
,
[
r0
]
,
#-
2048
@
linux
version
str
r1
,
[
r0
]
@
linux
version
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_
WRITE
|
L_PTE_
DIRTY
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_DIRTY
bic
r2
,
r1
,
#
PTE_SMALL_AP_MASK
@
keep
C
,
B
bits
orr
r2
,
r2
,
#
PTE_TYPE_EXT
@
extended
page
...
...
@@ -240,7 +240,7 @@
tst
r3
,
#
L_PTE_USER
@
user
?
orrne
r2
,
r2
,
#
PTE_EXT_AP_URO_SRW
@
yes
->
user
r
/
o
,
system
r
/
w
tst
r3
,
#
L_PTE_
WRITE
|
L_PTE_DIRTY
@
write
and
dirty
?
tst
r3
,
#
L_PTE_
RDONLY
|
L_PTE_DIRTY
@
write
and
dirty
?
orreq
r2
,
r2
,
#
PTE_EXT_AP_UNO_SRW
@
yes
->
user
n
/
a
,
system
r
/
w
@
combined
with
user
->
user
r
/
w
.
endm
...
...
@@ -249,7 +249,7 @@
tst
r3
,
#
L_PTE_PRESENT
|
L_PTE_YOUNG
@
present
and
young
?
movne
r2
,
#
0
@
no
->
fault
str
r2
,
[
r0
]
@
hardware
version
str
r2
,
[
r0
,
#
2048
]!
@
hardware
version
mov
ip
,
#
0
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
clean
L1
D
line
mcr
p15
,
0
,
ip
,
c7
,
c10
,
4
@
data
write
barrier
...
...
arch/arm/mm/proc-v7.S
View file @
28cdac66
...
...
@@ -124,15 +124,13 @@ ENDPROC(cpu_v7_switch_mm)
*
Set
a
level
2
translation
table
entry
.
*
*
-
ptep
-
pointer
to
level
2
translation
table
entry
*
(
hardware
version
is
stored
at
-
1024
bytes
)
*
(
hardware
version
is
stored
at
+
2048
bytes
)
*
-
pte
-
PTE
value
to
store
*
-
ext
-
value
for
extended
PTE
bits
*/
ENTRY
(
cpu_v7_set_pte_ext
)
#ifdef CONFIG_MMU
ARM
(
str
r1
,
[
r0
],
#-
2048
)
@
linux
version
THUMB
(
str
r1
,
[
r0
]
)
@
linux
version
THUMB
(
sub
r0
,
r0
,
#
2048
)
str
r1
,
[
r0
]
@
linux
version
bic
r3
,
r1
,
#
0x000003f0
bic
r3
,
r3
,
#
PTE_TYPE_MASK
...
...
@@ -142,9 +140,9 @@ ENTRY(cpu_v7_set_pte_ext)
tst
r1
,
#
1
<<
4
orrne
r3
,
r3
,
#
PTE_EXT_TEX
(
1
)
tst
r1
,
#
L_PTE_WRITE
tst
ne
r1
,
#
L_PTE_DIRTY
orr
eq
r3
,
r3
,
#
PTE_EXT_APX
eor
r1
,
r1
,
#
L_PTE_DIRTY
tst
r1
,
#
L_PTE_RDONLY
|
L_PTE_DIRTY
orr
ne
r3
,
r3
,
#
PTE_EXT_APX
tst
r1
,
#
L_PTE_USER
orrne
r3
,
r3
,
#
PTE_EXT_AP1
...
...
@@ -154,14 +152,14 @@ ENTRY(cpu_v7_set_pte_ext)
bicne
r3
,
r3
,
#
PTE_EXT_APX
|
PTE_EXT_AP0
#endif
tst
r1
,
#
L_PTE_
EXEC
orr
eq
r3
,
r3
,
#
PTE_EXT_XN
tst
r1
,
#
L_PTE_
XN
orr
ne
r3
,
r3
,
#
PTE_EXT_XN
tst
r1
,
#
L_PTE_YOUNG
tstne
r1
,
#
L_PTE_PRESENT
moveq
r3
,
#
0
str
r3
,
[
r0
]
str
r3
,
[
r0
,
#
2048
]!
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
flush_pte
#endif
mov
pc
,
lr
...
...
arch/arm/mm/proc-xscale.S
View file @
28cdac66
...
...
@@ -500,8 +500,8 @@ ENTRY(cpu_xscale_set_pte_ext)
@
@
Erratum
40
:
must
set
memory
to
write
-
through
for
user
read
-
only
pages
@
and
ip
,
r1
,
#(
L_PTE_MT_MASK
| L_PTE_USER |
L_PTE_
WRITE
)
&
~
(
4
<<
2
)
teq
ip
,
#
L_PTE_MT_WRITEBACK
|
L_PTE_USER
and
ip
,
r1
,
#(
L_PTE_MT_MASK
| L_PTE_USER |
L_PTE_
RDONLY
)
&
~
(
4
<<
2
)
teq
ip
,
#
L_PTE_MT_WRITEBACK
| L_PTE_USER
|
L_PTE_RDONLY
moveq
r1
,
#
L_PTE_MT_WRITETHROUGH
and
r1
,
r1
,
#
L_PTE_MT_MASK
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment