diff mbox

arm64: Implement branch predictor hardening for Falkor

Message ID 1515184139-23743-1-git-send-email-shankerd@codeaurora.org (mailing list archive)
State New, archived
Headers show

Commit Message

Shanker Donthineni Jan. 5, 2018, 8:28 p.m. UTC
Falkor is susceptible to branch predictor aliasing and can
theoretically be attacked by malicious code. This patch
implements a mitigation for these attacks, preventing any
malicious entries from affecting other victim contexts.

Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
---
 This patch has been verified using tip of
   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=kpti
        and
   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?h=v4.15-rc6&id=c622cc013cece073722592cff1ac6643a33b1622

 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/include/asm/kvm_asm.h |  2 ++
 arch/arm64/kernel/bpi.S          |  8 +++++++
 arch/arm64/kernel/cpu_errata.c   | 49 ++++++++++++++++++++++++++++++++++++++--
 arch/arm64/kvm/hyp/entry.S       | 12 ++++++++++
 arch/arm64/kvm/hyp/switch.c      | 10 ++++++++
 6 files changed, 81 insertions(+), 3 deletions(-)

Comments

Andrew Jones Jan. 8, 2018, 9:28 a.m. UTC | #1
Hi Shanker,

On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
...
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index cb0fb37..daf53a5 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -54,6 +54,8 @@ static int cpu_enable_trap_ctr_access(void *__unused)
>  
>  #ifdef CONFIG_KVM
>  extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];
> +extern char __qcom_hyp_sanitize_link_stack_start[];
> +extern char __qcom_hyp_sanitize_link_stack_end[];
>  
>  static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
>  				const char *hyp_vecs_end)
> @@ -96,8 +98,10 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
>  	spin_unlock(&bp_lock);
>  }
>  #else
> -#define __psci_hyp_bp_inval_start	NULL
> -#define __psci_hyp_bp_inval_end		NULL
> +#define __psci_hyp_bp_inval_start	   	NULL
> +#define __psci_hyp_bp_inval_end			NULL
> +#define __qcom_hyp_sanitize_link_stack_start	NULL
> +#define __qcom_hyp_sanitize_link_stack_start	NULL
                                          ^^ copy+paste error here

Thanks,
drew
Will Deacon Jan. 8, 2018, 5:09 p.m. UTC | #2
On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
> Falkor is susceptible to branch predictor aliasing and can
> theoretically be attacked by malicious code. This patch
> implements a mitigation for these attacks, preventing any
> malicious entries from affecting other victim contexts.

Thanks, Shanker. I'll pick this up (fixing the typo pointed out by Drew).
One comment below.

> Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
> ---
>  This patch has been verified using tip of
>    https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=kpti
>         and
>    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?h=v4.15-rc6&id=c622cc013cece073722592cff1ac6643a33b1622
> 
>  arch/arm64/include/asm/cpucaps.h |  3 ++-
>  arch/arm64/include/asm/kvm_asm.h |  2 ++
>  arch/arm64/kernel/bpi.S          |  8 +++++++
>  arch/arm64/kernel/cpu_errata.c   | 49 ++++++++++++++++++++++++++++++++++++++--
>  arch/arm64/kvm/hyp/entry.S       | 12 ++++++++++
>  arch/arm64/kvm/hyp/switch.c      | 10 ++++++++
>  6 files changed, 81 insertions(+), 3 deletions(-)

[...]

> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
> index 12ee62d..9c45c6a 100644
> --- a/arch/arm64/kvm/hyp/entry.S
> +++ b/arch/arm64/kvm/hyp/entry.S
> @@ -196,3 +196,15 @@ alternative_endif
>  
>  	eret
>  ENDPROC(__fpsimd_guest_restore)
> +
> +ENTRY(__qcom_hyp_sanitize_btac_predictors)
> +	/**
> +	 * Call SMC64 with Silicon provider serviceID 23<<8 (0xc2001700)
> +	 * 0xC2000000-0xC200FFFF: assigned to SiP Service Calls
> +	 * b15-b0: contains SiP functionID
> +	 */
> +	movz    x0, #0x1700
> +	movk    x0, #0xc200, lsl #16
> +	smc     #0
> +	ret

As I mentioned to Jayachandran for the Cavium patches [1], using an
unallocated SMC number like this may cause a problem for some platforms,
such as qemu. Using the PSCI GET_VERSION call avoids this issue, so I'm
relying on you to handle any breakage reports that arise from this change
then.

FWIW: we're currently looking into extending PSCI/SMCCC so that a
standardised mechanism can be implemented without the overhead of the
current register stacking requirements.

Cheers,

Will

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-January/552511.html
Shanker Donthineni Jan. 8, 2018, 5:22 p.m. UTC | #3
Hi Andrew,

On 01/08/2018 03:28 AM, Andrew Jones wrote:
> Hi Shanker,
> 
> On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
> ...
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index cb0fb37..daf53a5 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -54,6 +54,8 @@ static int cpu_enable_trap_ctr_access(void *__unused)
>>  
>>  #ifdef CONFIG_KVM
>>  extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];
>> +extern char __qcom_hyp_sanitize_link_stack_start[];
>> +extern char __qcom_hyp_sanitize_link_stack_end[];
>>  
>>  static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
>>  				const char *hyp_vecs_end)
>> @@ -96,8 +98,10 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
>>  	spin_unlock(&bp_lock);
>>  }
>>  #else
>> -#define __psci_hyp_bp_inval_start	NULL
>> -#define __psci_hyp_bp_inval_end		NULL
>> +#define __psci_hyp_bp_inval_start	   	NULL
>> +#define __psci_hyp_bp_inval_end			NULL
>> +#define __qcom_hyp_sanitize_link_stack_start	NULL
>> +#define __qcom_hyp_sanitize_link_stack_start	NULL
>                                           ^^ copy+paste error here

Thanks for catching typo, I'll fix in v2 patch. 

> 
> Thanks,
> drew
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Will Deacon Jan. 8, 2018, 6:44 p.m. UTC | #4
On Mon, Jan 08, 2018 at 05:09:33PM +0000, Will Deacon wrote:
> On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
> > Falkor is susceptible to branch predictor aliasing and can
> > theoretically be attacked by malicious code. This patch
> > implements a mitigation for these attacks, preventing any
> > malicious entries from affecting other victim contexts.
> 
> Thanks, Shanker. I'll pick this up (fixing the typo pointed out by Drew).

Note that MIDR_FALKOR doesn't exist in mainline, so I had to drop those
changes too. See the kpti branch for details.

If you'd like anything else done here, please send additional patches to me
and Catalin that we can apply on top of what we currently have. Note that
I'm in the air tomorrow, so won't be picking up email.

Cheers,

Will
Shanker Donthineni Jan. 8, 2018, 7:10 p.m. UTC | #5
Hi Will,

On 01/08/2018 12:44 PM, Will Deacon wrote:
> On Mon, Jan 08, 2018 at 05:09:33PM +0000, Will Deacon wrote:
>> On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
>>> Falkor is susceptible to branch predictor aliasing and can
>>> theoretically be attacked by malicious code. This patch
>>> implements a mitigation for these attacks, preventing any
>>> malicious entries from affecting other victim contexts.
>>
>> Thanks, Shanker. I'll pick this up (fixing the typo pointed out by Drew).
> 
> Note that MIDR_FALKOR doesn't exist in mainline, so I had to drop those
> changes too. See the kpti branch for details.
> 

The FALKOR MIDR patch is already available in the upstream kernel v4.15-rc7
    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?h=v4.15-rc7&id=c622cc013cece073722592cff1ac6643a33b1622

If you want I can resend the above patch in v2 series including typo fix.

> If you'd like anything else done here, please send additional patches to me
> and Catalin that we can apply on top of what we currently have. Note that
> I'm in the air tomorrow, so won't be picking up email.
> 
> Cheers,
> 
> Will
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Shanker Donthineni Jan. 8, 2018, 9:44 p.m. UTC | #6
Hi Will/Catalin,

Please drop https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/commit/?h=kpti&id=79ad24ef6c260efa0614896b15e67f4829448e32 in which you've removed FALKOR MIDR change. I've posted
v2 patch series including typo fix & FALKOR MIDR patch which is already available in upstream v4.15-rc7
branch. Please merge v2 patch.

On 01/08/2018 01:10 PM, Shanker Donthineni wrote:
> Hi Will,
> 
> On 01/08/2018 12:44 PM, Will Deacon wrote:
>> On Mon, Jan 08, 2018 at 05:09:33PM +0000, Will Deacon wrote:
>>> On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
>>>> Falkor is susceptible to branch predictor aliasing and can
>>>> theoretically be attacked by malicious code. This patch
>>>> implements a mitigation for these attacks, preventing any
>>>> malicious entries from affecting other victim contexts.
>>>
>>> Thanks, Shanker. I'll pick this up (fixing the typo pointed out by Drew).
>>
>> Note that MIDR_FALKOR doesn't exist in mainline, so I had to drop those
>> changes too. See the kpti branch for details.
>>
> 
> The FALKOR MIDR patch is already available in the upstream kernel v4.15-rc7
>     https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?h=v4.15-rc7&id=c622cc013cece073722592cff1ac6643a33b1622
> 
> If you want I can resend the above patch in v2 series including typo fix.
> 
>> If you'd like anything else done here, please send additional patches to me
>> and Catalin that we can apply on top of what we currently have. Note that
>> I'm in the air tomorrow, so won't be picking up email.
>>
>> Cheers,
>>
>> Will
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>
Will Deacon Jan. 9, 2018, 9:41 a.m. UTC | #7
You'll need to send a fixup patch. for-next/core is non-rebasing.

Will

On Mon, Jan 08, 2018 at 03:44:24PM -0600, Shanker Donthineni wrote:
> Hi Will/Catalin,
> 
> Please drop https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/commit/?h=kpti&id=79ad24ef6c260efa0614896b15e67f4829448e32 in which you've removed FALKOR MIDR change. I've posted
> v2 patch series including typo fix & FALKOR MIDR patch which is already available in upstream v4.15-rc7
> branch. Please merge v2 patch.
> 
> On 01/08/2018 01:10 PM, Shanker Donthineni wrote:
> > Hi Will,
> > 
> > On 01/08/2018 12:44 PM, Will Deacon wrote:
> >> On Mon, Jan 08, 2018 at 05:09:33PM +0000, Will Deacon wrote:
> >>> On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
> >>>> Falkor is susceptible to branch predictor aliasing and can
> >>>> theoretically be attacked by malicious code. This patch
> >>>> implements a mitigation for these attacks, preventing any
> >>>> malicious entries from affecting other victim contexts.
> >>>
> >>> Thanks, Shanker. I'll pick this up (fixing the typo pointed out by Drew).
> >>
> >> Note that MIDR_FALKOR doesn't exist in mainline, so I had to drop those
> >> changes too. See the kpti branch for details.
> >>
> > 
> > The FALKOR MIDR patch is already available in the upstream kernel v4.15-rc7
> >     https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?h=v4.15-rc7&id=c622cc013cece073722592cff1ac6643a33b1622
> > 
> > If you want I can resend the above patch in v2 series including typo fix.
> > 
> >> If you'd like anything else done here, please send additional patches to me
> >> and Catalin that we can apply on top of what we currently have. Note that
> >> I'm in the air tomorrow, so won't be picking up email.
> >>
> >> Cheers,
> >>
> >> Will
> >>
> >> _______________________________________________
> >> linux-arm-kernel mailing list
> >> linux-arm-kernel@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >>
> > 
> 
> -- 
> Shanker Donthineni
> Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
> Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Catalin Marinas Jan. 9, 2018, 11:05 a.m. UTC | #8
On Tue, Jan 09, 2018 at 09:41:46AM +0000, Will Deacon wrote:
> You'll need to send a fixup patch. for-next/core is non-rebasing.

I haven't pushed it out yet (will do this morning) but note that
for-next/core is based on 4.15-rc3.
diff mbox

Patch

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 51616e7..7049b48 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -43,7 +43,8 @@ 
 #define ARM64_SVE				22
 #define ARM64_UNMAP_KERNEL_AT_EL0		23
 #define ARM64_HARDEN_BRANCH_PREDICTOR		24
+#define ARM64_HARDEN_BP_POST_GUEST_EXIT		25
 
-#define ARM64_NCAPS				25
+#define ARM64_NCAPS				26
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ab4d0a9..24961b7 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -68,6 +68,8 @@ 
 
 extern u32 __init_stage2_translation(void);
 
+extern void __qcom_hyp_sanitize_btac_predictors(void);
+
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/kernel/bpi.S b/arch/arm64/kernel/bpi.S
index 2b10d52..44ffcda 100644
--- a/arch/arm64/kernel/bpi.S
+++ b/arch/arm64/kernel/bpi.S
@@ -77,3 +77,11 @@  ENTRY(__psci_hyp_bp_inval_start)
 	ldp	x2, x3, [sp], #16
 	ldp	x0, x1, [sp], #16
 ENTRY(__psci_hyp_bp_inval_end)
+
+ENTRY(__qcom_hyp_sanitize_link_stack_start)
+	stp     x29, x30, [sp, #-16]!
+	.rept	16
+	bl	. + 4
+	.endr
+	ldp	x29, x30, [sp], #16
+ENTRY(__qcom_hyp_sanitize_link_stack_end)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index cb0fb37..daf53a5 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -54,6 +54,8 @@  static int cpu_enable_trap_ctr_access(void *__unused)
 
 #ifdef CONFIG_KVM
 extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];
+extern char __qcom_hyp_sanitize_link_stack_start[];
+extern char __qcom_hyp_sanitize_link_stack_end[];
 
 static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
 				const char *hyp_vecs_end)
@@ -96,8 +98,10 @@  static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
 	spin_unlock(&bp_lock);
 }
 #else
-#define __psci_hyp_bp_inval_start	NULL
-#define __psci_hyp_bp_inval_end		NULL
+#define __psci_hyp_bp_inval_start	   	NULL
+#define __psci_hyp_bp_inval_end			NULL
+#define __qcom_hyp_sanitize_link_stack_start	NULL
+#define __qcom_hyp_sanitize_link_stack_start	NULL
 
 static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
 				      const char *hyp_vecs_start,
@@ -138,6 +142,29 @@  static int enable_psci_bp_hardening(void *data)
 
 	return 0;
 }
+
+static void qcom_link_stack_sanitization(void)
+{
+	u64 tmp;
+
+	asm volatile("mov	%0, x30		\n"
+		     ".rept	16		\n"
+		     "bl	. + 4		\n"
+		     ".endr			\n"
+		     "mov	x30, %0		\n"
+		     : "=&r" (tmp));
+}
+
+static int qcom_enable_link_stack_sanitization(void *data)
+{
+	const struct arm64_cpu_capabilities *entry = data;
+
+	install_bp_hardening_cb(entry, qcom_link_stack_sanitization,
+				__qcom_hyp_sanitize_link_stack_start,
+				__qcom_hyp_sanitize_link_stack_end);
+
+	return 0;
+}
 #endif	/* CONFIG_HARDEN_BRANCH_PREDICTOR */
 
 #define MIDR_RANGE(model, min, max) \
@@ -302,6 +329,24 @@  static int enable_psci_bp_hardening(void *data)
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
 		.enable = enable_psci_bp_hardening,
 	},
+	{
+		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
+		MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
+		.enable = qcom_enable_link_stack_sanitization,
+	},
+	{
+		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
+		MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
+		.enable = qcom_enable_link_stack_sanitization,
+	},
+	{
+		.capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
+		MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
+	},
+	{
+		.capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
+		MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index 12ee62d..9c45c6a 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -196,3 +196,15 @@  alternative_endif
 
 	eret
 ENDPROC(__fpsimd_guest_restore)
+
+ENTRY(__qcom_hyp_sanitize_btac_predictors)
+	/**
+	 * Call SMC64 with Silicon provider serviceID 23<<8 (0xc2001700)
+	 * 0xC2000000-0xC200FFFF: assigned to SiP Service Calls
+	 * b15-b0: contains SiP functionID
+	 */
+	movz    x0, #0x1700
+	movk    x0, #0xc200, lsl #16
+	smc     #0
+	ret
+ENDPROC(__qcom_hyp_sanitize_btac_predictors)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 4d273f6..7e37379 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -406,6 +406,16 @@  int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 		/* 0 falls through to be handled out of EL2 */
 	}
 
+	if (cpus_have_const_cap(ARM64_HARDEN_BP_POST_GUEST_EXIT)) {
+		u32 midr = read_cpuid_id();
+
+		/* Apply BTAC predictors mitigation to all Falkor chips */
+		if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) ||
+		    ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) {
+			__qcom_hyp_sanitize_btac_predictors();
+		}
+	}
+
 	fp_enabled = __fpsimd_enabled();
 
 	__sysreg_save_guest_state(guest_ctxt);