Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c92a90a5
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c92a90a5
编写于
4月 26, 2017
作者:
R
Russell King
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'fixes' and 'misc' into for-next
上级
6d805949
11ce4b33
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
210 addition
and
57 deletion
+210
-57
Documentation/devicetree/bindings/arm/l2c2x0.txt
Documentation/devicetree/bindings/arm/l2c2x0.txt
+3
-0
arch/arm/Kconfig
arch/arm/Kconfig
+1
-0
arch/arm/boot/dts/r7s72100.dtsi
arch/arm/boot/dts/r7s72100.dtsi
+11
-0
arch/arm/include/asm/cpufeature.h
arch/arm/include/asm/cpufeature.h
+38
-0
arch/arm/include/asm/fixmap.h
arch/arm/include/asm/fixmap.h
+1
-1
arch/arm/include/asm/module.h
arch/arm/include/asm/module.h
+7
-2
arch/arm/kernel/ftrace.c
arch/arm/kernel/ftrace.c
+6
-5
arch/arm/kernel/module-plts.c
arch/arm/kernel/module-plts.c
+60
-27
arch/arm/kernel/module.lds
arch/arm/kernel/module.lds
+1
-0
arch/arm/kernel/setup.c
arch/arm/kernel/setup.c
+2
-2
arch/arm/mach-shmobile/setup-r7s72100.c
arch/arm/mach-shmobile/setup-r7s72100.c
+2
-0
arch/arm/mm/cache-l2x0.c
arch/arm/mm/cache-l2x0.c
+11
-2
arch/arm/mm/dump.c
arch/arm/mm/dump.c
+44
-10
arch/arm/mm/init.c
arch/arm/mm/init.c
+8
-5
arch/arm/mm/mmu.c
arch/arm/mm/mmu.c
+13
-3
arch/arm/mm/proc-v7m.S
arch/arm/mm/proc-v7m.S
+2
-0
未找到文件。
Documentation/devicetree/bindings/arm/l2c2x0.txt
浏览文件 @
c92a90a5
...
...
@@ -90,6 +90,9 @@ Optional properties:
- arm,standby-mode: L2 standby mode enable. Value <0> (forcibly disable),
<1> (forcibly enable), property absent (OS specific behavior,
preferably retain firmware settings)
- arm,early-bresp-disable : Disable the CA9 optimization Early BRESP (PL310)
- arm,full-line-zero-disable : Disable the CA9 optimization Full line of zero
write (PL310)
Example:
...
...
arch/arm/Kconfig
浏览文件 @
c92a90a5
...
...
@@ -27,6 +27,7 @@ config ARM
select GENERIC_ALLOCATOR
select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GENERIC_CPU_AUTOPROBE
select GENERIC_EARLY_IOREMAP
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IRQ_PROBE
...
...
arch/arm/boot/dts/r7s72100.dtsi
浏览文件 @
c92a90a5
...
...
@@ -177,6 +177,7 @@
compatible = "arm,cortex-a9";
reg = <0>;
clock-frequency = <400000000>;
next-level-cache = <&L2>;
};
};
...
...
@@ -368,6 +369,16 @@
<0xe8202000 0x1000>;
};
L2: cache-controller@3ffff000 {
compatible = "arm,pl310-cache";
reg = <0x3ffff000 0x1000>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
arm,early-bresp-disable;
arm,full-line-zero-disable;
cache-unified;
cache-level = <2>;
};
i2c0: i2c@fcfee000 {
#address-cells = <1>;
#size-cells = <0>;
...
...
arch/arm/include/asm/cpufeature.h
0 → 100644
浏览文件 @
c92a90a5
/*
* Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_CPUFEATURE_H
#define __ASM_CPUFEATURE_H
#include <linux/log2.h>
#include <asm/hwcap.h>
/*
* Due to the fact that ELF_HWCAP is a 32-bit type on ARM, and given the number
* of optional CPU features it defines, ARM's CPU hardware capability bits have
* been distributed over separate elf_hwcap and elf_hwcap2 variables, each of
* which covers a subset of the available CPU features.
*
* Currently, only a few of those are suitable for automatic module loading
* (which is the primary use case of this facility) and those happen to be all
* covered by HWCAP2. So let's only cover those via the cpu_feature()
* convenience macro for now (which is used by module_cpu_feature_match()).
* However, all capabilities are exposed via the modalias, and can be matched
* using an explicit MODULE_DEVICE_TABLE() that uses __hwcap_feature() directly.
*/
#define MAX_CPU_FEATURES 64
#define __hwcap_feature(x) ilog2(HWCAP_ ## x)
#define __hwcap2_feature(x) (32 + ilog2(HWCAP2_ ## x))
#define cpu_feature(x) __hwcap2_feature(x)
static
inline
bool
cpu_have_feature
(
unsigned
int
num
)
{
return
num
<
32
?
elf_hwcap
&
BIT
(
num
)
:
elf_hwcap2
&
BIT
(
num
-
32
);
}
#endif
arch/arm/include/asm/fixmap.h
浏览文件 @
c92a90a5
...
...
@@ -41,7 +41,7 @@ static const enum fixed_addresses __end_of_fixed_addresses =
#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY)
#define FIXMAP_PAGE_NORMAL (
FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK
)
#define FIXMAP_PAGE_NORMAL (
pgprot_kernel | L_PTE_XN
)
#define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY)
/* Used by set_fixmap_(io|nocache), both meant for mapping a device */
...
...
arch/arm/include/asm/module.h
浏览文件 @
c92a90a5
...
...
@@ -18,13 +18,18 @@ enum {
};
#endif
struct
mod_plt_sec
{
struct
elf32_shdr
*
plt
;
int
plt_count
;
};
struct
mod_arch_specific
{
#ifdef CONFIG_ARM_UNWIND
struct
unwind_table
*
unwind
[
ARM_SEC_MAX
];
#endif
#ifdef CONFIG_ARM_MODULE_PLTS
struct
elf32_shdr
*
plt
;
int
plt_coun
t
;
struct
mod_plt_sec
core
;
struct
mod_plt_sec
ini
t
;
#endif
};
...
...
arch/arm/kernel/ftrace.c
浏览文件 @
c92a90a5
...
...
@@ -29,11 +29,6 @@
#endif
#ifdef CONFIG_DYNAMIC_FTRACE
#ifdef CONFIG_OLD_MCOUNT
#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
#define OLD_NOP 0xe1a00000
/* mov r0, r0 */
static
int
__ftrace_modify_code
(
void
*
data
)
{
...
...
@@ -51,6 +46,12 @@ void arch_ftrace_update_code(int command)
stop_machine
(
__ftrace_modify_code
,
&
command
,
NULL
);
}
#ifdef CONFIG_OLD_MCOUNT
#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
#define OLD_NOP 0xe1a00000
/* mov r0, r0 */
static
unsigned
long
ftrace_nop_replace
(
struct
dyn_ftrace
*
rec
)
{
return
rec
->
arch
.
old_mcount
?
OLD_NOP
:
NOP
;
...
...
arch/arm/kernel/module-plts.c
浏览文件 @
c92a90a5
/*
* Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
* Copyright (C) 2014
-2017
Linaro Ltd. <ard.biesheuvel@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -31,9 +31,17 @@ struct plt_entries {
u32
lit
[
PLT_ENT_COUNT
];
};
static
bool
in_init
(
const
struct
module
*
mod
,
unsigned
long
loc
)
{
return
loc
-
(
u32
)
mod
->
init_layout
.
base
<
mod
->
init_layout
.
size
;
}
u32
get_module_plt
(
struct
module
*
mod
,
unsigned
long
loc
,
Elf32_Addr
val
)
{
struct
plt_entries
*
plt
=
(
struct
plt_entries
*
)
mod
->
arch
.
plt
->
sh_addr
;
struct
mod_plt_sec
*
pltsec
=
!
in_init
(
mod
,
loc
)
?
&
mod
->
arch
.
core
:
&
mod
->
arch
.
init
;
struct
plt_entries
*
plt
=
(
struct
plt_entries
*
)
pltsec
->
plt
->
sh_addr
;
int
idx
=
0
;
/*
...
...
@@ -41,9 +49,9 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
* relocations are sorted, this will be the last entry we allocated.
* (if one exists).
*/
if
(
mod
->
arch
.
plt_count
>
0
)
{
plt
+=
(
mod
->
arch
.
plt_count
-
1
)
/
PLT_ENT_COUNT
;
idx
=
(
mod
->
arch
.
plt_count
-
1
)
%
PLT_ENT_COUNT
;
if
(
pltsec
->
plt_count
>
0
)
{
plt
+=
(
pltsec
->
plt_count
-
1
)
/
PLT_ENT_COUNT
;
idx
=
(
pltsec
->
plt_count
-
1
)
%
PLT_ENT_COUNT
;
if
(
plt
->
lit
[
idx
]
==
val
)
return
(
u32
)
&
plt
->
ldr
[
idx
];
...
...
@@ -53,8 +61,8 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
plt
++
;
}
mod
->
arch
.
plt_count
++
;
BUG_ON
(
mod
->
arch
.
plt_count
*
PLT_ENT_SIZE
>
mod
->
arch
.
plt
->
sh_size
);
pltsec
->
plt_count
++
;
BUG_ON
(
pltsec
->
plt_count
*
PLT_ENT_SIZE
>
pltsec
->
plt
->
sh_size
);
if
(
!
idx
)
/* Populate a new set of entries */
...
...
@@ -129,7 +137,7 @@ static bool duplicate_rel(Elf32_Addr base, const Elf32_Rel *rel, int num)
/* Count how many PLT entries we may need */
static
unsigned
int
count_plts
(
const
Elf32_Sym
*
syms
,
Elf32_Addr
base
,
const
Elf32_Rel
*
rel
,
int
num
)
const
Elf32_Rel
*
rel
,
int
num
,
Elf32_Word
dstidx
)
{
unsigned
int
ret
=
0
;
const
Elf32_Sym
*
s
;
...
...
@@ -144,13 +152,17 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
case
R_ARM_THM_JUMP24
:
/*
* We only have to consider branch targets that resolve
* to undefined symbols. This is not simply a heuristic,
* it is a fundamental limitation, since the PLT itself
* is part of the module, and needs to be within range
* as well, so modules can never grow beyond that limit.
* to symbols that are defined in a different section.
* This is not simply a heuristic, it is a fundamental
* limitation, since there is no guaranteed way to emit
* PLT entries sufficiently close to the branch if the
* section size exceeds the range of a branch
* instruction. So ignore relocations against defined
* symbols if they live in the same section as the
* relocation target.
*/
s
=
syms
+
ELF32_R_SYM
(
rel
[
i
].
r_info
);
if
(
s
->
st_shndx
!=
SHN_UNDEF
)
if
(
s
->
st_shndx
==
dstidx
)
break
;
/*
...
...
@@ -161,7 +173,12 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
* So we need to support them, but there is no need to
* take them into consideration when trying to optimize
* this code. So let's only check for duplicates when
* the addend is zero.
* the addend is zero. (Note that calls into the core
* module via init PLT entries could involve section
* relative symbol references with non-zero addends, for
* which we may end up emitting duplicates, but the init
* PLT is released along with the rest of the .init
* region as soon as module loading completes.)
*/
if
(
!
is_zero_addend_relocation
(
base
,
rel
+
i
)
||
!
duplicate_rel
(
base
,
rel
,
i
))
...
...
@@ -174,7 +191,8 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
int
module_frob_arch_sections
(
Elf_Ehdr
*
ehdr
,
Elf_Shdr
*
sechdrs
,
char
*
secstrings
,
struct
module
*
mod
)
{
unsigned
long
plts
=
0
;
unsigned
long
core_plts
=
0
;
unsigned
long
init_plts
=
0
;
Elf32_Shdr
*
s
,
*
sechdrs_end
=
sechdrs
+
ehdr
->
e_shnum
;
Elf32_Sym
*
syms
=
NULL
;
...
...
@@ -184,13 +202,15 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
*/
for
(
s
=
sechdrs
;
s
<
sechdrs_end
;
++
s
)
{
if
(
strcmp
(
".plt"
,
secstrings
+
s
->
sh_name
)
==
0
)
mod
->
arch
.
plt
=
s
;
mod
->
arch
.
core
.
plt
=
s
;
else
if
(
strcmp
(
".init.plt"
,
secstrings
+
s
->
sh_name
)
==
0
)
mod
->
arch
.
init
.
plt
=
s
;
else
if
(
s
->
sh_type
==
SHT_SYMTAB
)
syms
=
(
Elf32_Sym
*
)
s
->
sh_addr
;
}
if
(
!
mod
->
arch
.
plt
)
{
pr_err
(
"%s: module PLT section missing
\n
"
,
mod
->
name
);
if
(
!
mod
->
arch
.
core
.
plt
||
!
mod
->
arch
.
init
.
plt
)
{
pr_err
(
"%s: module PLT section
(s)
missing
\n
"
,
mod
->
name
);
return
-
ENOEXEC
;
}
if
(
!
syms
)
{
...
...
@@ -213,16 +233,29 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
/* sort by type and symbol index */
sort
(
rels
,
numrels
,
sizeof
(
Elf32_Rel
),
cmp_rel
,
NULL
);
plts
+=
count_plts
(
syms
,
dstsec
->
sh_addr
,
rels
,
numrels
);
if
(
strncmp
(
secstrings
+
dstsec
->
sh_name
,
".init"
,
5
)
!=
0
)
core_plts
+=
count_plts
(
syms
,
dstsec
->
sh_addr
,
rels
,
numrels
,
s
->
sh_info
);
else
init_plts
+=
count_plts
(
syms
,
dstsec
->
sh_addr
,
rels
,
numrels
,
s
->
sh_info
);
}
mod
->
arch
.
plt
->
sh_type
=
SHT_NOBITS
;
mod
->
arch
.
plt
->
sh_flags
=
SHF_EXECINSTR
|
SHF_ALLOC
;
mod
->
arch
.
plt
->
sh_addralign
=
L1_CACHE_BYTES
;
mod
->
arch
.
plt
->
sh_size
=
round_up
(
plts
*
PLT_ENT_SIZE
,
sizeof
(
struct
plt_entries
));
mod
->
arch
.
plt_count
=
0
;
pr_debug
(
"%s: plt=%x
\n
"
,
__func__
,
mod
->
arch
.
plt
->
sh_size
);
mod
->
arch
.
core
.
plt
->
sh_type
=
SHT_NOBITS
;
mod
->
arch
.
core
.
plt
->
sh_flags
=
SHF_EXECINSTR
|
SHF_ALLOC
;
mod
->
arch
.
core
.
plt
->
sh_addralign
=
L1_CACHE_BYTES
;
mod
->
arch
.
core
.
plt
->
sh_size
=
round_up
(
core_plts
*
PLT_ENT_SIZE
,
sizeof
(
struct
plt_entries
));
mod
->
arch
.
core
.
plt_count
=
0
;
mod
->
arch
.
init
.
plt
->
sh_type
=
SHT_NOBITS
;
mod
->
arch
.
init
.
plt
->
sh_flags
=
SHF_EXECINSTR
|
SHF_ALLOC
;
mod
->
arch
.
init
.
plt
->
sh_addralign
=
L1_CACHE_BYTES
;
mod
->
arch
.
init
.
plt
->
sh_size
=
round_up
(
init_plts
*
PLT_ENT_SIZE
,
sizeof
(
struct
plt_entries
));
mod
->
arch
.
init
.
plt_count
=
0
;
pr_debug
(
"%s: plt=%x, init.plt=%x
\n
"
,
__func__
,
mod
->
arch
.
core
.
plt
->
sh_size
,
mod
->
arch
.
init
.
plt
->
sh_size
);
return
0
;
}
arch/arm/kernel/module.lds
浏览文件 @
c92a90a5
SECTIONS {
.plt : { BYTE(0) }
.init.plt : { BYTE(0) }
}
arch/arm/kernel/setup.c
浏览文件 @
c92a90a5
...
...
@@ -80,7 +80,7 @@ __setup("fpe=", fpe_setup);
extern
void
init_default_cache_policy
(
unsigned
long
);
extern
void
paging_init
(
const
struct
machine_desc
*
desc
);
extern
void
early_
paging
_init
(
const
struct
machine_desc
*
);
extern
void
early_
mm
_init
(
const
struct
machine_desc
*
);
extern
void
adjust_lowmem_bounds
(
void
);
extern
enum
reboot_mode
reboot_mode
;
extern
void
setup_dma_zone
(
const
struct
machine_desc
*
desc
);
...
...
@@ -1088,7 +1088,7 @@ void __init setup_arch(char **cmdline_p)
parse_early_param
();
#ifdef CONFIG_MMU
early_
paging
_init
(
mdesc
);
early_
mm
_init
(
mdesc
);
#endif
setup_dma_zone
(
mdesc
);
xen_early_init
();
...
...
arch/arm/mach-shmobile/setup-r7s72100.c
浏览文件 @
c92a90a5
...
...
@@ -26,6 +26,8 @@ static const char *const r7s72100_boards_compat_dt[] __initconst = {
};
DT_MACHINE_START
(
R7S72100_DT
,
"Generic R7S72100 (Flattened Device Tree)"
)
.
l2c_aux_val
=
0
,
.
l2c_aux_mask
=
~
0
,
.
init_early
=
shmobile_init_delay
,
.
init_late
=
shmobile_init_late
,
.
dt_compat
=
r7s72100_boards_compat_dt
,
...
...
arch/arm/mm/cache-l2x0.c
浏览文件 @
c92a90a5
...
...
@@ -57,6 +57,9 @@ static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
struct
l2x0_regs
l2x0_saved_regs
;
static
bool
l2x0_bresp_disable
;
static
bool
l2x0_flz_disable
;
/*
* Common code for all cache controllers.
*/
...
...
@@ -620,7 +623,7 @@ static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
u32
aux
=
l2x0_saved_regs
.
aux_ctrl
;
if
(
rev
>=
L310_CACHE_ID_RTL_R2P0
)
{
if
(
cortex_a9
)
{
if
(
cortex_a9
&&
!
l2x0_bresp_disable
)
{
aux
|=
L310_AUX_CTRL_EARLY_BRESP
;
pr_info
(
"L2C-310 enabling early BRESP for Cortex-A9
\n
"
);
}
else
if
(
aux
&
L310_AUX_CTRL_EARLY_BRESP
)
{
...
...
@@ -629,7 +632,7 @@ static void __init l2c310_enable(void __iomem *base, unsigned num_lock)
}
}
if
(
cortex_a9
)
{
if
(
cortex_a9
&&
!
l2x0_flz_disable
)
{
u32
aux_cur
=
readl_relaxed
(
base
+
L2X0_AUX_CTRL
);
u32
acr
=
get_auxcr
();
...
...
@@ -1200,6 +1203,12 @@ static void __init l2c310_of_parse(const struct device_node *np,
*
aux_mask
&=
~
L2C_AUX_CTRL_PARITY_ENABLE
;
}
if
(
of_property_read_bool
(
np
,
"arm,early-bresp-disable"
))
l2x0_bresp_disable
=
true
;
if
(
of_property_read_bool
(
np
,
"arm,full-line-zero-disable"
))
l2x0_flz_disable
=
true
;
prefetch
=
l2x0_saved_regs
.
prefetch_ctrl
;
ret
=
of_property_read_u32
(
np
,
"arm,double-linefill"
,
&
val
);
...
...
arch/arm/mm/dump.c
浏览文件 @
c92a90a5
...
...
@@ -17,6 +17,7 @@
#include <linux/mm.h>
#include <linux/seq_file.h>
#include <asm/domain.h>
#include <asm/fixmap.h>
#include <asm/memory.h>
#include <asm/pgtable.h>
...
...
@@ -43,6 +44,7 @@ struct pg_state {
unsigned
long
start_address
;
unsigned
level
;
u64
current_prot
;
const
char
*
current_domain
;
};
struct
prot_bits
{
...
...
@@ -216,7 +218,8 @@ static void dump_prot(struct pg_state *st, const struct prot_bits *bits, size_t
}
}
static
void
note_page
(
struct
pg_state
*
st
,
unsigned
long
addr
,
unsigned
level
,
u64
val
)
static
void
note_page
(
struct
pg_state
*
st
,
unsigned
long
addr
,
unsigned
int
level
,
u64
val
,
const
char
*
domain
)
{
static
const
char
units
[]
=
"KMGTPE"
;
u64
prot
=
val
&
pg_level
[
level
].
mask
;
...
...
@@ -224,8 +227,10 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u
if
(
!
st
->
level
)
{
st
->
level
=
level
;
st
->
current_prot
=
prot
;
st
->
current_domain
=
domain
;
seq_printf
(
st
->
seq
,
"---[ %s ]---
\n
"
,
st
->
marker
->
name
);
}
else
if
(
prot
!=
st
->
current_prot
||
level
!=
st
->
level
||
domain
!=
st
->
current_domain
||
addr
>=
st
->
marker
[
1
].
start_address
)
{
const
char
*
unit
=
units
;
unsigned
long
delta
;
...
...
@@ -240,6 +245,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u
unit
++
;
}
seq_printf
(
st
->
seq
,
"%9lu%c"
,
delta
,
*
unit
);
if
(
st
->
current_domain
)
seq_printf
(
st
->
seq
,
" %s"
,
st
->
current_domain
);
if
(
pg_level
[
st
->
level
].
bits
)
dump_prot
(
st
,
pg_level
[
st
->
level
].
bits
,
pg_level
[
st
->
level
].
num
);
seq_printf
(
st
->
seq
,
"
\n
"
);
...
...
@@ -251,11 +258,13 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, u
}
st
->
start_address
=
addr
;
st
->
current_prot
=
prot
;
st
->
current_domain
=
domain
;
st
->
level
=
level
;
}
}
static
void
walk_pte
(
struct
pg_state
*
st
,
pmd_t
*
pmd
,
unsigned
long
start
)
static
void
walk_pte
(
struct
pg_state
*
st
,
pmd_t
*
pmd
,
unsigned
long
start
,
const
char
*
domain
)
{
pte_t
*
pte
=
pte_offset_kernel
(
pmd
,
0
);
unsigned
long
addr
;
...
...
@@ -263,25 +272,50 @@ static void walk_pte(struct pg_state *st, pmd_t *pmd, unsigned long start)
for
(
i
=
0
;
i
<
PTRS_PER_PTE
;
i
++
,
pte
++
)
{
addr
=
start
+
i
*
PAGE_SIZE
;
note_page
(
st
,
addr
,
4
,
pte_val
(
*
pte
));
note_page
(
st
,
addr
,
4
,
pte_val
(
*
pte
)
,
domain
);
}
}
static
const
char
*
get_domain_name
(
pmd_t
*
pmd
)
{
#ifndef CONFIG_ARM_LPAE
switch
(
pmd_val
(
*
pmd
)
&
PMD_DOMAIN_MASK
)
{
case
PMD_DOMAIN
(
DOMAIN_KERNEL
):
return
"KERNEL "
;
case
PMD_DOMAIN
(
DOMAIN_USER
):
return
"USER "
;
case
PMD_DOMAIN
(
DOMAIN_IO
):
return
"IO "
;
case
PMD_DOMAIN
(
DOMAIN_VECTORS
):
return
"VECTORS"
;
default:
return
"unknown"
;
}
#endif
return
NULL
;
}
static
void
walk_pmd
(
struct
pg_state
*
st
,
pud_t
*
pud
,
unsigned
long
start
)
{
pmd_t
*
pmd
=
pmd_offset
(
pud
,
0
);
unsigned
long
addr
;
unsigned
i
;
const
char
*
domain
;
for
(
i
=
0
;
i
<
PTRS_PER_PMD
;
i
++
,
pmd
++
)
{
addr
=
start
+
i
*
PMD_SIZE
;
domain
=
get_domain_name
(
pmd
);
if
(
pmd_none
(
*
pmd
)
||
pmd_large
(
*
pmd
)
||
!
pmd_present
(
*
pmd
))
note_page
(
st
,
addr
,
3
,
pmd_val
(
*
pmd
));
note_page
(
st
,
addr
,
3
,
pmd_val
(
*
pmd
)
,
domain
);
else
walk_pte
(
st
,
pmd
,
addr
);
walk_pte
(
st
,
pmd
,
addr
,
domain
);
if
(
SECTION_SIZE
<
PMD_SIZE
&&
pmd_large
(
pmd
[
1
]))
note_page
(
st
,
addr
+
SECTION_SIZE
,
3
,
pmd_val
(
pmd
[
1
]));
if
(
SECTION_SIZE
<
PMD_SIZE
&&
pmd_large
(
pmd
[
1
]))
{
addr
+=
SECTION_SIZE
;
pmd
++
;
domain
=
get_domain_name
(
pmd
);
note_page
(
st
,
addr
,
3
,
pmd_val
(
*
pmd
),
domain
);
}
}
}
...
...
@@ -296,7 +330,7 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
if
(
!
pud_none
(
*
pud
))
{
walk_pmd
(
st
,
pud
,
addr
);
}
else
{
note_page
(
st
,
addr
,
2
,
pud_val
(
*
pud
));
note_page
(
st
,
addr
,
2
,
pud_val
(
*
pud
)
,
NULL
);
}
}
}
...
...
@@ -317,11 +351,11 @@ static void walk_pgd(struct seq_file *m)
if
(
!
pgd_none
(
*
pgd
))
{
walk_pud
(
&
st
,
pgd
,
addr
);
}
else
{
note_page
(
&
st
,
addr
,
1
,
pgd_val
(
*
pgd
));
note_page
(
&
st
,
addr
,
1
,
pgd_val
(
*
pgd
)
,
NULL
);
}
}
note_page
(
&
st
,
0
,
0
,
0
);
note_page
(
&
st
,
0
,
0
,
0
,
NULL
);
}
static
int
ptdump_show
(
struct
seq_file
*
m
,
void
*
v
)
...
...
arch/arm/mm/init.c
浏览文件 @
c92a90a5
...
...
@@ -709,34 +709,37 @@ void set_section_perms(struct section_perm *perms, int n, bool set,
}
/**
* update_sections_early intended to be called only through stop_machine
* framework and executed by only one CPU while all other CPUs will spin and
* wait, so no locking is required in this function.
*/
static
void
update_sections_early
(
struct
section_perm
perms
[],
int
n
)
{
struct
task_struct
*
t
,
*
s
;
read_lock
(
&
tasklist_lock
);
for_each_process
(
t
)
{
if
(
t
->
flags
&
PF_KTHREAD
)
continue
;
for_each_thread
(
t
,
s
)
set_section_perms
(
perms
,
n
,
true
,
s
->
mm
);
}
read_unlock
(
&
tasklist_lock
);
set_section_perms
(
perms
,
n
,
true
,
current
->
active_mm
);
set_section_perms
(
perms
,
n
,
true
,
&
init_mm
);
}
int
__fix_kernmem_perms
(
void
*
unused
)
static
int
__fix_kernmem_perms
(
void
*
unused
)
{
update_sections_early
(
nx_perms
,
ARRAY_SIZE
(
nx_perms
));
return
0
;
}
void
fix_kernmem_perms
(
void
)
static
void
fix_kernmem_perms
(
void
)
{
stop_machine
(
__fix_kernmem_perms
,
NULL
,
NULL
);
}
int
__mark_rodata_ro
(
void
*
unused
)
static
int
__mark_rodata_ro
(
void
*
unused
)
{
update_sections_early
(
ro_perms
,
ARRAY_SIZE
(
ro_perms
));
return
0
;
...
...
arch/arm/mm/mmu.c
浏览文件 @
c92a90a5
...
...
@@ -414,6 +414,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
FIXADDR_END
);
BUG_ON
(
idx
>=
__end_of_fixed_addresses
);
/* we only support device mappings until pgprot_kernel has been set */
if
(
WARN_ON
(
pgprot_val
(
prot
)
!=
pgprot_val
(
FIXMAP_PAGE_IO
)
&&
pgprot_val
(
pgprot_kernel
)
==
0
))
return
;
if
(
pgprot_val
(
prot
))
set_pte_at
(
NULL
,
vaddr
,
pte
,
pfn_pte
(
phys
>>
PAGE_SHIFT
,
prot
));
...
...
@@ -1492,7 +1497,7 @@ pgtables_remap lpae_pgtables_remap_asm;
* early_paging_init() recreates boot time page table setup, allowing machines
* to switch over to a high (>4G) address space on LPAE systems
*/
void
__init
early_paging_init
(
const
struct
machine_desc
*
mdesc
)
static
void
__init
early_paging_init
(
const
struct
machine_desc
*
mdesc
)
{
pgtables_remap
*
lpae_pgtables_remap
;
unsigned
long
pa_pgd
;
...
...
@@ -1560,7 +1565,7 @@ void __init early_paging_init(const struct machine_desc *mdesc)
#else
void
__init
early_paging_init
(
const
struct
machine_desc
*
mdesc
)
static
void
__init
early_paging_init
(
const
struct
machine_desc
*
mdesc
)
{
long
long
offset
;
...
...
@@ -1616,7 +1621,6 @@ void __init paging_init(const struct machine_desc *mdesc)
{
void
*
zero_page
;
build_mem_type_table
();
prepare_page_table
();
map_lowmem
();
memblock_set_current_limit
(
arm_lowmem_limit
);
...
...
@@ -1636,3 +1640,9 @@ void __init paging_init(const struct machine_desc *mdesc)
empty_zero_page
=
virt_to_page
(
zero_page
);
__flush_dcache_page
(
NULL
,
empty_zero_page
);
}
void
__init
early_mm_init
(
const
struct
machine_desc
*
mdesc
)
{
build_mem_type_table
();
early_paging_init
(
mdesc
);
}
arch/arm/mm/proc-v7m.S
浏览文件 @
c92a90a5
...
...
@@ -135,9 +135,11 @@ __v7m_setup_cont:
dsb
mov
r6
,
lr
@
save
LR
ldr
sp
,
=
init_thread_union
+
THREAD_START_SP
stmia
sp
,
{
r0
-
r3
,
r12
}
cpsie
i
svc
#
0
1
:
cpsid
i
ldmia
sp
,
{
r0
-
r3
,
r12
}
str
r5
,
[
r12
,
#
11
*
4
]
@
restore
the
original
SVC
vector
entry
mov
lr
,
r6
@
restore
LR
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录