-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: arm32: sm: invalidate branch predictor #2047
Conversation
core/arch/arm/sm/sm_a32.S
Outdated
@@ -166,6 +166,10 @@ UNWIND( .cantunwind) | |||
b .sm_exit | |||
|
|||
.smc_from_nsec: | |||
/* Invalidate the branch predictor. */ | |||
write_bpiallis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Inner Shareable? Wouldn't write_bpiall
be enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I'll fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is late to apply the fix as the BTB speculation can occur on the unconditional branch at Line 258. BPIALL needs to be done prior to any branch instruction in Secure world. Its not easy to do this but we have an upcoming patch in ARM TF which will demonstrate this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soby-mathew , so you are saying this should be done before actually doing any jump from the vector table. Will this also affect the thread vector table? I'd guess that it doesn't affect that, agree?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, does it involve multiple vectors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenswi-linaro, the way we do it is to have ORR (Or ADD) instruction at each vector entry to encode a bit pattern into an available General Purpose register. We use the sp
for this and ensure the stack/whatever sp is pointing to is aligned so that the LSB can be used for the bit pattern encoding. Then the BPIALL is done and the bit pattern is extracted to get the vector entry. Finally we jump to the correct handler corresponding to the vector entry.
If the sp
is pointing to address that is naturally aligned to 256 bytes then ORR can be used to encode the bit pattern (one bit per vector entry). Else ADD can be used to encode values from 0 to 7 for each vector entry and the sp
needs to point to an address that is 8 byte aligned.
That's the general idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, clever. Thanks, I'll do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All branches are subject to prediction on some Arm CPUs.
ARM Technical Reference Manual for A57 on predicted instructions:
6.5.1 Predicted and non-predicted instructions
This section describes the instructions that the processor predicts.Unless otherwise specified, the list applies to A32, T32, and A64 instructions. As a general rule, the branch prediction hardware predicts all branch instructions regardless of the addressing mode, including:
- Conditional branches.
- Unconditional branches.
- Indirect branches.
- Branches that switch between ARM and Thumb states.
- PC destination data processing operations.
- BXJ, because of the inclusion of the trivial Jazelle implementation, this degenerates to a BX instruction. There is no BXJ instruction in A64.
However, the following branch instructions are not predicted:
- AArch32 instructions with the S suffix are not predicted because they are typically used when returning from exceptions and have side effects that can change privilege mode and Security state.
- All mode or Exception level changing instructions.
In Thumb state, you can make a branch that is normally encoded as unconditional conditional by including an If-Then (IT) block. It is then treated as a normal conditional branch.
see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488h/way1382448710808.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[oops - missed that Soby had already mentioned this in his comment]
Jens - we're also testing a _version that has less constraint on the SP alignment and only needs 3 bits of SP to encode the vector before invalidating the branch predictor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@athoelke thanks for the reference, quite helpful.
I suppose this section will need some rework however:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488h/way1382448710808.html
;-)
core/arch/arm/kernel/thread_a32.S
Outdated
.macro maybe_invalidate_bp | ||
#ifdef CFG_WITH_ARM_TRUSTED_FW | ||
/* Invalidate the branch predictor. */ | ||
write_bpiallis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is BP invalidate needed at all in this file when CFG_WITH_ARM_TRUSTED_FW=y
? Isn't EL3 supposed to take care of it if needed? (I'm referring to ARM-TF pull request 1214).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was asked to do it like this, I guess this was before ARM-software/arm-trusted-firmware#1214 existed.
@jbech-linaro, do you know if this is still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @jforissier is right here, we don't need to do it if it is done by Arm-TF. We need to make the branch invalidate when we are running our own monitor (and therefore responsible for the switch).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, let's drop this.
Update |
|
What about |
@jforissier, I'll fix |
Update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. The only comment being introducing a build flag so to apply this only for affected platforms ?
Update, add config flag default enabled for this workaround. |
core/arch/arm/arm.mk
Outdated
@@ -31,6 +31,12 @@ platform-hard-float-enabled := y | |||
endif | |||
endif | |||
|
|||
# Adds protection against CVE-2017-5715 also know as Spectre | |||
# (https://spectreattack.com) | |||
# See also https://developer.arm.com/-/media/Files/pdf/Cache_Speculation_Side-channels.pdf?revision=966364ce-10aa-4580-8431-7e4ed42fb90b&la=en |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may shorten the URL, the parameters are useless
Update |
|
|
What about entry via |
If build with secure monitor and CFG_CORE_WORKAROUND_SPECTRE_BP=y invalidate branch predictor on non-secure entry. Fixes CVE-2017-5715 Reviewed-by: Jerome Forissier <[email protected]> Reviewed-by: Joakim Bech <[email protected]> Signed-off-by: Jens Wiklander <[email protected]>
I'll create another PR for |
2a9d642
to
0b77e33
Compare
OK, sounds good. |
Rebased, squashed and tags applied. |
nop /* 0:000 FIQ */ | ||
|
||
/* Invalidate the branch predictor for the current processor. */ | ||
write_bpiall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this work on Cortex-A15?
#2055 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understand, not as intended at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BPIALL is not effective in invalidating the branch predictor on A15. An ICALLU with the ACTLR[0] set to 1 need to be done on Cortex-A15. The ARM TF advisory has been updated with this info. This would also mean the fix needs to detect the CPU type at runtime and apply the appropriate workaround.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in #2065
on non-secure entry.
entry.
Fixes CVE-2017-5715
Signed-off-by: Jens Wiklander [email protected]