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
Kirill Smelkov
linux
Commits
83208329
Commit
83208329
authored
Apr 13, 2021
by
Marc Zyngier
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'arm64/for-next/vhe-only' into kvmarm-master/next
Signed-off-by:
Marc Zyngier
<
maz@kernel.org
>
parents
e6290032
2d726d0d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
89 additions
and
29 deletions
+89
-29
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/kernel-parameters.txt
+1
-2
arch/arm64/Kconfig
arch/arm64/Kconfig
+0
-13
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/cpufeature.h
+17
-0
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpufeature.c
+6
-4
arch/arm64/kernel/head.S
arch/arm64/kernel/head.S
+36
-3
arch/arm64/kernel/hyp-stub.S
arch/arm64/kernel/hyp-stub.S
+4
-6
arch/arm64/kernel/idreg-override.c
arch/arm64/kernel/idreg-override.c
+25
-1
No files found.
Documentation/admin-guide/kernel-parameters.txt
View file @
83208329
...
...
@@ -2279,8 +2279,7 @@
state is kept private from the host.
Not valid if the kernel is running in EL2.
Defaults to VHE/nVHE based on hardware support and
the value of CONFIG_ARM64_VHE.
Defaults to VHE/nVHE based on hardware support.
kvm-arm.vgic_v3_group0_trap=
[KVM,ARM] Trap guest accesses to GICv3 group-0
...
...
arch/arm64/Kconfig
View file @
83208329
...
...
@@ -1416,19 +1416,6 @@ config ARM64_USE_LSE_ATOMICS
built with binutils >= 2.25 in order for the new instructions
to be used.
config ARM64_VHE
bool "Enable support for Virtualization Host Extensions (VHE)"
default y
help
Virtualization Host Extensions (VHE) allow the kernel to run
directly at EL2 (instead of EL1) on processors that support
it. This leads to better performance for KVM, as they reduce
the cost of the world switch.
Selecting this option allows the VHE feature to be detected
at runtime, and does not affect processors that do not
implement this feature.
endmenu
menu "ARMv8.2 architectural features"
...
...
arch/arm64/include/asm/cpufeature.h
View file @
83208329
...
...
@@ -63,6 +63,23 @@ struct arm64_ftr_bits {
s64
safe_val
;
/* safe value for FTR_EXACT features */
};
/*
* Describe the early feature override to the core override code:
*
* @val Values that are to be merged into the final
* sanitised value of the register. Only the bitfields
* set to 1 in @mask are valid
* @mask Mask of the features that are overridden by @val
*
* A @mask field set to full-1 indicates that the corresponding field
* in @val is a valid override.
*
* A @mask field set to full-0 with the corresponding @val field set
* to full-0 denotes that this field has no override
*
* A @mask field set to full-0 with the corresponding @val field set
* to full-1 denotes thath this field has an invalid override.
*/
struct
arm64_ftr_override
{
u64
val
;
u64
mask
;
...
...
arch/arm64/kernel/cpufeature.c
View file @
83208329
...
...
@@ -808,6 +808,12 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)
reg
->
name
,
ftrp
->
shift
+
ftrp
->
width
-
1
,
ftrp
->
shift
,
str
,
tmp
);
}
else
if
((
ftr_mask
&
reg
->
override
->
val
)
==
ftr_mask
)
{
reg
->
override
->
val
&=
~
ftr_mask
;
pr_warn
(
"%s[%d:%d]: impossible override, ignored
\n
"
,
reg
->
name
,
ftrp
->
shift
+
ftrp
->
width
-
1
,
ftrp
->
shift
);
}
val
=
arm64_ftr_set_value
(
ftrp
,
val
,
ftr_new
);
...
...
@@ -1616,7 +1622,6 @@ int get_cpu_with_amu_feat(void)
}
#endif
#ifdef CONFIG_ARM64_VHE
static
bool
runs_at_el2
(
const
struct
arm64_cpu_capabilities
*
entry
,
int
__unused
)
{
return
is_kernel_in_hyp_mode
();
...
...
@@ -1635,7 +1640,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
if
(
!
alternative_is_applied
(
ARM64_HAS_VIRT_HOST_EXTN
))
write_sysreg
(
read_sysreg
(
tpidr_el1
),
tpidr_el2
);
}
#endif
static
void
cpu_has_fwb
(
const
struct
arm64_cpu_capabilities
*
__unused
)
{
...
...
@@ -1838,7 +1842,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.
type
=
ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE
,
.
matches
=
has_no_hw_prefetch
,
},
#ifdef CONFIG_ARM64_VHE
{
.
desc
=
"Virtualization Host Extensions"
,
.
capability
=
ARM64_HAS_VIRT_HOST_EXTN
,
...
...
@@ -1846,7 +1849,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.
matches
=
runs_at_el2
,
.
cpu_enable
=
cpu_copy_el2regs
,
},
#endif
/* CONFIG_ARM64_VHE */
{
.
desc
=
"32-bit EL0 Support"
,
.
capability
=
ARM64_HAS_32BIT_EL0
,
...
...
arch/arm64/kernel/head.S
View file @
83208329
...
...
@@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr)
*
booted
in
EL1
or
EL2
respectively
.
*/
SYM_FUNC_START
(
init_kernel_el
)
mov_q
x0
,
INIT_SCTLR_EL1_MMU_OFF
msr
sctlr_el1
,
x0
mrs
x0
,
CurrentEL
cmp
x0
,
#
CurrentEL_EL2
b.eq
init_el2
SYM_INNER_LABEL
(
init_el1
,
SYM_L_LOCAL
)
mov_q
x0
,
INIT_SCTLR_EL1_MMU_OFF
msr
sctlr_el1
,
x0
isb
mov_q
x0
,
INIT_PSTATE_EL1
msr
spsr_el1
,
x0
...
...
@@ -504,9 +503,43 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
msr
vbar_el2
,
x0
isb
/
*
*
Fruity
CPUs
seem
to
have
HCR_EL2
.E2
H
set
to
RES1
,
*
making
it
impossible
to
start
in
nVHE
mode
.
Is
that
*
compliant
with
the
architecture
?
Absolutely
not
!
*/
mrs
x0
,
hcr_el2
and
x0
,
x0
,
#
HCR_E2H
cbz
x0
,
1
f
/
*
Switching
to
VHE
requires
a
sane
SCTLR_EL1
as
a
start
*/
mov_q
x0
,
INIT_SCTLR_EL1_MMU_OFF
msr_s
SYS_SCTLR_EL12
,
x0
/
*
*
Force
an
eret
into
a
helper
"function"
,
and
let
it
return
*
to
our
original
caller
...
This
makes
sure
that
we
have
*
initialised
the
basic
PSTATE
state
.
*/
mov
x0
,
#
INIT_PSTATE_EL2
msr
spsr_el1
,
x0
adr
x0
,
__cpu_stick_to_vhe
msr
elr_el1
,
x0
eret
1
:
mov_q
x0
,
INIT_SCTLR_EL1_MMU_OFF
msr
sctlr_el1
,
x0
msr
elr_el2
,
lr
mov
w0
,
#
BOOT_CPU_MODE_EL2
eret
__cpu_stick_to_vhe
:
mov
x0
,
#
HVC_VHE_RESTART
hvc
#
0
mov
x0
,
#
BOOT_CPU_MODE_EL2
ret
SYM_FUNC_END
(
init_kernel_el
)
/*
...
...
arch/arm64/kernel/hyp-stub.S
View file @
83208329
...
...
@@ -27,12 +27,12 @@ SYM_CODE_START(__hyp_stub_vectors)
ventry
el2_fiq_invalid
//
FIQ
EL2t
ventry
el2_error_invalid
//
Error
EL2t
ventry
el
2_sync_invalid
//
Synchronous
EL2h
ventry
el
x_sync
//
Synchronous
EL2h
ventry
el2_irq_invalid
//
IRQ
EL2h
ventry
el2_fiq_invalid
//
FIQ
EL2h
ventry
el2_error_invalid
//
Error
EL2h
ventry
el
1
_sync
//
Synchronous
64
-
bit
EL1
ventry
el
x
_sync
//
Synchronous
64
-
bit
EL1
ventry
el1_irq_invalid
//
IRQ
64
-
bit
EL1
ventry
el1_fiq_invalid
//
FIQ
64
-
bit
EL1
ventry
el1_error_invalid
//
Error
64
-
bit
EL1
...
...
@@ -45,7 +45,7 @@ SYM_CODE_END(__hyp_stub_vectors)
.
align
11
SYM_CODE_START_LOCAL
(
el
1
_sync
)
SYM_CODE_START_LOCAL
(
el
x
_sync
)
cmp
x0
,
#
HVC_SET_VECTORS
b.ne
1
f
msr
vbar_el2
,
x1
...
...
@@ -71,7 +71,7 @@ SYM_CODE_START_LOCAL(el1_sync)
9
:
mov
x0
,
xzr
eret
SYM_CODE_END
(
el
1
_sync
)
SYM_CODE_END
(
el
x
_sync
)
//
nVHE
?
No
way
!
Give
me
the
real
thing
!
SYM_CODE_START_LOCAL
(
mutate_to_vhe
)
...
...
@@ -225,7 +225,6 @@ SYM_FUNC_END(__hyp_reset_vectors)
*
Entry
point
to
switch
to
VHE
if
deemed
capable
*/
SYM_FUNC_START
(
switch_to_vhe
)
#ifdef CONFIG_ARM64_VHE
//
Need
to
have
booted
at
EL2
adr_l
x1
,
__boot_cpu_mode
ldr
w0
,
[
x1
]
...
...
@@ -241,6 +240,5 @@ SYM_FUNC_START(switch_to_vhe)
mov
x0
,
#
HVC_VHE_RESTART
hvc
#
0
1
:
#endif
ret
SYM_FUNC_END
(
switch_to_vhe
)
arch/arm64/kernel/idreg-override.c
View file @
83208329
...
...
@@ -25,14 +25,26 @@ struct ftr_set_desc {
struct
{
char
name
[
FTR_DESC_FIELD_LEN
];
u8
shift
;
bool
(
*
filter
)(
u64
val
);
}
fields
[];
};
static
bool
__init
mmfr1_vh_filter
(
u64
val
)
{
/*
* If we ever reach this point while running VHE, we're
* guaranteed to be on one of these funky, VHE-stuck CPUs. If
* the user was trying to force nVHE on us, proceed with
* attitude adjustment.
*/
return
!
(
is_kernel_in_hyp_mode
()
&&
val
==
0
);
}
static
const
struct
ftr_set_desc
mmfr1
__initconst
=
{
.
name
=
"id_aa64mmfr1"
,
.
override
=
&
id_aa64mmfr1_override
,
.
fields
=
{
{
"vh"
,
ID_AA64MMFR1_VHE_SHIFT
},
{
"vh"
,
ID_AA64MMFR1_VHE_SHIFT
,
mmfr1_vh_filter
},
{}
},
};
...
...
@@ -124,6 +136,18 @@ static void __init match_options(const char *cmdline)
if
(
find_field
(
cmdline
,
regs
[
i
],
f
,
&
v
))
continue
;
/*
* If an override gets filtered out, advertise
* it by setting the value to 0xf, but
* clearing the mask... Yes, this is fragile.
*/
if
(
regs
[
i
]
->
fields
[
f
].
filter
&&
!
regs
[
i
]
->
fields
[
f
].
filter
(
v
))
{
regs
[
i
]
->
override
->
val
|=
mask
;
regs
[
i
]
->
override
->
mask
&=
~
mask
;
continue
;
}
regs
[
i
]
->
override
->
val
&=
~
mask
;
regs
[
i
]
->
override
->
val
|=
(
v
<<
shift
)
&
mask
;
regs
[
i
]
->
override
->
mask
|=
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