diff mbox

[2/6] s390: implement nospec_[load|ptr]

Message ID 1516182519-10623-3-git-send-email-schwidefsky@de.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Martin Schwidefsky Jan. 17, 2018, 9:48 a.m. UTC
Implement nospec_load() and nospec_ptr() for s390 with the new
gmb() barrier between the boundary condition and the load that
may not be done speculatively.

Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
 arch/s390/include/asm/barrier.h | 38 ++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/alternative.c  |  7 +++++++
 2 files changed, 45 insertions(+)

Comments

Jiri Kosina Jan. 17, 2018, 12:41 p.m. UTC | #1
On Wed, 17 Jan 2018, Martin Schwidefsky wrote:

> Implement nospec_load() and nospec_ptr() for s390 with the new
> gmb() barrier between the boundary condition and the load that
> may not be done speculatively.

FWIW the naming seems to be changing constantly. The latest patchset from 
Dan Williams [1] uses ifence_...().

[1] lkml.kernel.org/r/151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com
David Hildenbrand Jan. 17, 2018, 1:58 p.m. UTC | #2
On 17.01.2018 10:48, Martin Schwidefsky wrote:
> Implement nospec_load() and nospec_ptr() for s390 with the new
> gmb() barrier between the boundary condition and the load that
> may not be done speculatively.
> 
> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
> ---
>  arch/s390/include/asm/barrier.h | 38 ++++++++++++++++++++++++++++++++++++++
>  arch/s390/kernel/alternative.c  |  7 +++++++
>  2 files changed, 45 insertions(+)
> 
> diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
> index 1043260..b8836a6 100644
> --- a/arch/s390/include/asm/barrier.h
> +++ b/arch/s390/include/asm/barrier.h
> @@ -8,6 +8,8 @@
>  #ifndef __ASM_BARRIER_H
>  #define __ASM_BARRIER_H
>  
> +#include <asm/alternative.h>
> +
>  /*
>   * Force strict CPU ordering.
>   * And yes, this is required on UP too when we're talking
> @@ -23,6 +25,42 @@
>  
>  #define mb() do {  asm volatile(__ASM_BARRIER : : : "memory"); } while (0)
>  
> +static inline void gmb(void)
> +{
> +	asm volatile(
> +		ALTERNATIVE("", ".long 0xb2e8f000", 81)
> +		: : : "memory");
> +}

Just to be sure:

There are now 2 new facilities:

81 and 82.

Is 82 just the virtualization (SIE) support for 81?
Christian Borntraeger Jan. 17, 2018, 2:04 p.m. UTC | #3
On 01/17/2018 02:58 PM, David Hildenbrand wrote:
> On 17.01.2018 10:48, Martin Schwidefsky wrote:
>> Implement nospec_load() and nospec_ptr() for s390 with the new
>> gmb() barrier between the boundary condition and the load that
>> may not be done speculatively.
>>
>> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
>> ---
>>  arch/s390/include/asm/barrier.h | 38 ++++++++++++++++++++++++++++++++++++++
>>  arch/s390/kernel/alternative.c  |  7 +++++++
>>  2 files changed, 45 insertions(+)
>>
>> diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
>> index 1043260..b8836a6 100644
>> --- a/arch/s390/include/asm/barrier.h
>> +++ b/arch/s390/include/asm/barrier.h
>> @@ -8,6 +8,8 @@
>>  #ifndef __ASM_BARRIER_H
>>  #define __ASM_BARRIER_H
>>  
>> +#include <asm/alternative.h>
>> +
>>  /*
>>   * Force strict CPU ordering.
>>   * And yes, this is required on UP too when we're talking
>> @@ -23,6 +25,42 @@
>>  
>>  #define mb() do {  asm volatile(__ASM_BARRIER : : : "memory"); } while (0)
>>  
>> +static inline void gmb(void)
>> +{
>> +	asm volatile(
>> +		ALTERNATIVE("", ".long 0xb2e8f000", 81)
>> +		: : : "memory");
>> +}
> 
> Just to be sure:
> 
> There are now 2 new facilities:
> 
> 81 and 82.
> 
> Is 82 just the virtualization (SIE) support for 81?

81 is for ppa15 (see this patch) and 82 is for ppa12 and 13 (see patch 3).
In KVM we want to provide both (and let the guest decide what to do).
Jon Masters Jan. 17, 2018, 2:52 p.m. UTC | #4
On 01/17/2018 07:41 AM, Jiri Kosina wrote:
> On Wed, 17 Jan 2018, Martin Schwidefsky wrote:
> 
>> Implement nospec_load() and nospec_ptr() for s390 with the new
>> gmb() barrier between the boundary condition and the load that
>> may not be done speculatively.

Thanks for the patches, Martin et al. I tested various earlier versions
and will run these latest ones through some tests and add a tested by.

> FWIW the naming seems to be changing constantly. The latest patchset from 
> Dan Williams [1] uses ifence_...().
> 
> [1] lkml.kernel.org/r/151586744180.5820.13215059696964205856.stgit@dwillia2-desk3.amr.corp.intel.com

This is getting a little silly. Not to bikeshed this to death, but
obviously gmb (what was that ever supposed to stand for, global?) was
the wrong name. We favored seb (speculative execution barrier), etc.
Still, "ifence"? What is that supposed to mean? That sounds very
architecture specific vs. what we're actually trying to ensure, which is
that we don't speculatively load a pointer.

Jon.
diff mbox

Patch

diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
index 1043260..b8836a6 100644
--- a/arch/s390/include/asm/barrier.h
+++ b/arch/s390/include/asm/barrier.h
@@ -8,6 +8,8 @@ 
 #ifndef __ASM_BARRIER_H
 #define __ASM_BARRIER_H
 
+#include <asm/alternative.h>
+
 /*
  * Force strict CPU ordering.
  * And yes, this is required on UP too when we're talking
@@ -23,6 +25,42 @@ 
 
 #define mb() do {  asm volatile(__ASM_BARRIER : : : "memory"); } while (0)
 
+static inline void gmb(void)
+{
+	asm volatile(
+		ALTERNATIVE("", ".long 0xb2e8f000", 81)
+		: : : "memory");
+}
+#define gmb gmb
+
+#define nospec_ptr(ptr, lo, hi)					\
+({								\
+	typeof (ptr) __ptr = (ptr);				\
+	typeof (ptr) __lo = (lo);				\
+	typeof (ptr) __hi = (hi);				\
+	typeof (ptr) __vptr = NULL;				\
+								\
+	if (__lo <= __ptr && __ptr < __hi) {			\
+		gmb();						\
+		__vptr = __ptr;					\
+	}							\
+	__vptr;							\
+})
+
+#define nospec_load(ptr, lo, hi)				\
+({								\
+	typeof (ptr) __ptr = (ptr);				\
+	typeof (ptr) __lo = (lo);				\
+	typeof (ptr) __hi = (hi);				\
+	typeof (*ptr) __v = (typeof(*__ptr))(unsigned long) 0;	\
+								\
+	if (__lo <= __ptr && __ptr < __hi) {			\
+		gmb();						\
+		__v = *__ptr;					\
+	}							\
+	__v;							\
+})
+
 #define rmb()				barrier()
 #define wmb()				barrier()
 #define dma_rmb()			mb()
diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c
index 1abf4f3..33d2e88 100644
--- a/arch/s390/kernel/alternative.c
+++ b/arch/s390/kernel/alternative.c
@@ -15,6 +15,13 @@  static int __init disable_alternative_instructions(char *str)
 
 early_param("noaltinstr", disable_alternative_instructions);
 
+static int __init nogmb_setup_early(char *str)
+{
+	__clear_facility(81, S390_lowcore.alt_stfle_fac_list);
+	return 0;
+}
+early_param("nogmb", nogmb_setup_early);
+
 struct brcl_insn {
 	u16 opc;
 	s32 disp;