2018-01-08 16:55:45

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 01/11] powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper

From: Michael Neuling <[email protected]>

A new hypervisor call has been defined to communicate various
characteristics of the CPU to guests. Add definitions for the hcall
number, flags and a wrapper function.

Signed-off-by: Michael Neuling <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/include/asm/hvcall.h | 17 +++++++++++++++++
arch/powerpc/include/asm/plpar_wrappers.h | 14 ++++++++++++++
2 files changed, 31 insertions(+)

diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index a409177be8bd..f0461618bf7b 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -241,6 +241,7 @@
#define H_GET_HCA_INFO 0x1B8
#define H_GET_PERF_COUNT 0x1BC
#define H_MANAGE_TRACE 0x1C0
+#define H_GET_CPU_CHARACTERISTICS 0x1C8
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
#define H_QUERY_INT_STATE 0x1E4
#define H_POLL_PENDING 0x1D8
@@ -330,6 +331,17 @@
#define H_SIGNAL_SYS_RESET_ALL_OTHERS -2
/* >= 0 values are CPU number */

+/* H_GET_CPU_CHARACTERISTICS return values */
+#define H_CPU_CHAR_SPEC_BAR_ORI31 (1ull << 63) // IBM bit 0
+#define H_CPU_CHAR_BCCTRL_SERIALISED (1ull << 62) // IBM bit 1
+#define H_CPU_CHAR_L1D_FLUSH_ORI30 (1ull << 61) // IBM bit 2
+#define H_CPU_CHAR_L1D_FLUSH_TRIG2 (1ull << 60) // IBM bit 3
+#define H_CPU_CHAR_L1D_THREAD_PRIV (1ull << 59) // IBM bit 4
+
+#define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0
+#define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1
+#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2
+
/* Flag values used in H_REGISTER_PROC_TBL hcall */
#define PROC_TABLE_OP_MASK 0x18
#define PROC_TABLE_DEREG 0x10
@@ -436,6 +448,11 @@ static inline unsigned int get_longbusy_msecs(int longbusy_rc)
}
}

+struct h_cpu_char_result {
+ u64 character;
+ u64 behaviour;
+};
+
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h
index 7f01b22fa6cb..55eddf50d149 100644
--- a/arch/powerpc/include/asm/plpar_wrappers.h
+++ b/arch/powerpc/include/asm/plpar_wrappers.h
@@ -326,4 +326,18 @@ static inline long plapr_signal_sys_reset(long cpu)
return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu);
}

+static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p)
+{
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+ long rc;
+
+ rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf);
+ if (rc == H_SUCCESS) {
+ p->character = retbuf[0];
+ p->behaviour = retbuf[1];
+ }
+
+ return rc;
+}
+
#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
--
2.14.3


2018-01-08 16:55:50

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 03/11] powerpc/64s: Simple RFI macro conversions

From: Nicholas Piggin <[email protected]>

This commit does simple conversions of rfi/rfid to the new macros that
include the expected destination context. By simple we mean cases
where there is a single well known destination context, and it's
simply a matter of substituting the instruction for the appropriate
macro.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/include/asm/exception-64s.h | 4 ++--
arch/powerpc/kernel/entry_64.S | 14 +++++++++-----
arch/powerpc/kernel/exceptions-64s.S | 24 ++++++++++++------------
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 9 ++++-----
arch/powerpc/kvm/book3s_rmhandlers.S | 7 +++++--
arch/powerpc/kvm/book3s_segment.S | 4 ++--
6 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 1af427a3c74f..dfc56daed98b 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -247,7 +247,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
mtspr SPRN_##h##SRR0,r12; \
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
mtspr SPRN_##h##SRR1,r10; \
- h##rfid; \
+ h##RFI_TO_KERNEL; \
b . /* prevent speculative execution */
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
__EXCEPTION_PROLOG_PSERIES_1(label, h)
@@ -261,7 +261,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
mtspr SPRN_##h##SRR0,r12; \
mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
mtspr SPRN_##h##SRR1,r10; \
- h##rfid; \
+ h##RFI_TO_KERNEL; \
b . /* prevent speculative execution */

#define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 36878b6ee8b8..567d8f487f2f 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -37,6 +37,11 @@
#include <asm/tm.h>
#include <asm/ppc-opcode.h>
#include <asm/export.h>
+#ifdef CONFIG_PPC_BOOK3S
+#include <asm/exception-64s.h>
+#else
+#include <asm/exception-64e.h>
+#endif

/*
* System calls.
@@ -397,8 +402,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
mtmsrd r10, 1
mtspr SPRN_SRR0, r11
mtspr SPRN_SRR1, r12
-
- rfid
+ RFI_TO_USER
b . /* prevent speculative execution */
#endif
_ASM_NOKPROBE_SYMBOL(system_call_common);
@@ -1077,7 +1081,7 @@ __enter_rtas:

mtspr SPRN_SRR0,r5
mtspr SPRN_SRR1,r6
- rfid
+ RFI_TO_KERNEL
b . /* prevent speculative execution */

rtas_return_loc:
@@ -1102,7 +1106,7 @@ rtas_return_loc:

mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
- rfid
+ RFI_TO_KERNEL
b . /* prevent speculative execution */
_ASM_NOKPROBE_SYMBOL(__enter_rtas)
_ASM_NOKPROBE_SYMBOL(rtas_return_loc)
@@ -1175,7 +1179,7 @@ _GLOBAL(enter_prom)
LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
andc r11,r11,r12
mtsrr1 r11
- rfid
+ RFI_TO_KERNEL
#endif /* CONFIG_PPC_BOOK3E */

1: /* Return from OF */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e441b469dc8f..5502b0147c4e 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -256,7 +256,7 @@ BEGIN_FTR_SECTION
LOAD_HANDLER(r12, machine_check_handle_early)
1: mtspr SPRN_SRR0,r12
mtspr SPRN_SRR1,r11
- rfid
+ RFI_TO_KERNEL
b . /* prevent speculative execution */
2:
/* Stack overflow. Stay on emergency stack and panic.
@@ -445,7 +445,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
li r3,MSR_ME
andc r10,r10,r3 /* Turn off MSR_ME */
mtspr SPRN_SRR1,r10
- rfid
+ RFI_TO_KERNEL
b .
2:
/*
@@ -463,7 +463,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
*/
bl machine_check_queue_event
MACHINE_CHECK_HANDLER_WINDUP
- rfid
+ RFI_TO_USER_OR_KERNEL
9:
/* Deliver the machine check to host kernel in V mode. */
MACHINE_CHECK_HANDLER_WINDUP
@@ -651,7 +651,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
mtspr SPRN_SRR0,r10
ld r10,PACAKMSR(r13)
mtspr SPRN_SRR1,r10
- rfid
+ RFI_TO_KERNEL
b .

8: std r3,PACA_EXSLB+EX_DAR(r13)
@@ -662,7 +662,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
mtspr SPRN_SRR0,r10
ld r10,PACAKMSR(r13)
mtspr SPRN_SRR1,r10
- rfid
+ RFI_TO_KERNEL
b .

EXC_COMMON_BEGIN(unrecov_slb)
@@ -901,7 +901,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
mtspr SPRN_SRR0,r10 ; \
ld r10,PACAKMSR(r13) ; \
mtspr SPRN_SRR1,r10 ; \
- rfid ; \
+ RFI_TO_KERNEL ; \
b . ; /* prevent speculative execution */

#ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH
@@ -917,7 +917,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
xori r12,r12,MSR_LE ; \
mtspr SPRN_SRR1,r12 ; \
mr r13,r9 ; \
- rfid ; /* return to userspace */ \
+ RFI_TO_USER ; /* return to userspace */ \
b . ; /* prevent speculative execution */
#else
#define SYSCALL_FASTENDIAN_TEST
@@ -1063,7 +1063,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early)
mtcr r11
REST_GPR(11, r1)
ld r1,GPR1(r1)
- hrfid
+ HRFI_TO_USER_OR_KERNEL

1: mtcr r11
REST_GPR(11, r1)
@@ -1314,7 +1314,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
ld r11,PACA_EXGEN+EX_R11(r13)
ld r12,PACA_EXGEN+EX_R12(r13)
ld r13,PACA_EXGEN+EX_R13(r13)
- HRFID
+ HRFI_TO_UNKNOWN
b .
#endif

@@ -1418,7 +1418,7 @@ masked_##_H##interrupt: \
ld r10,PACA_EXGEN+EX_R10(r13); \
ld r11,PACA_EXGEN+EX_R11(r13); \
/* returns to kernel where r13 must be set up, so don't restore it */ \
- ##_H##rfid; \
+ ##_H##RFI_TO_KERNEL; \
b .; \
MASKED_DEC_HANDLER(_H)

@@ -1441,7 +1441,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt)
addi r13, r13, 4
mtspr SPRN_SRR0, r13
GET_SCRATCH0(r13)
- rfid
+ RFI_TO_KERNEL
b .

TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
@@ -1453,7 +1453,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
addi r13, r13, 4
mtspr SPRN_HSRR0, r13
GET_SCRATCH0(r13)
- hrfid
+ HRFI_TO_KERNEL
b .
#endif

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 2659844784b8..9c61f736c75b 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -79,7 +79,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline)
mtmsrd r0,1 /* clear RI in MSR */
mtsrr0 r5
mtsrr1 r6
- RFI
+ RFI_TO_KERNEL

kvmppc_call_hv_entry:
BEGIN_FTR_SECTION
@@ -199,7 +199,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtmsrd r6, 1 /* Clear RI in MSR */
mtsrr0 r8
mtsrr1 r7
- RFI
+ RFI_TO_KERNEL

/* Virtual-mode return */
.Lvirt_return:
@@ -1167,8 +1167,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)

ld r0, VCPU_GPR(R0)(r4)
ld r4, VCPU_GPR(R4)(r4)
-
- hrfid
+ HRFI_TO_GUEST
b .

secondary_too_late:
@@ -3320,7 +3319,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
ld r4, PACAKMSR(r13)
mtspr SPRN_SRR0, r3
mtspr SPRN_SRR1, r4
- rfid
+ RFI_TO_KERNEL
9: addi r3, r1, STACK_FRAME_OVERHEAD
bl kvmppc_bad_interrupt
b 9b
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
index 42a4b237df5f..34a5adeff084 100644
--- a/arch/powerpc/kvm/book3s_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_rmhandlers.S
@@ -46,6 +46,9 @@

#define FUNC(name) name

+#define RFI_TO_KERNEL RFI
+#define RFI_TO_GUEST RFI
+
.macro INTERRUPT_TRAMPOLINE intno

.global kvmppc_trampoline_\intno
@@ -141,7 +144,7 @@ kvmppc_handler_skip_ins:
GET_SCRATCH0(r13)

/* And get back into the code */
- RFI
+ RFI_TO_KERNEL
#endif

/*
@@ -164,6 +167,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline)
ori r5, r5, MSR_EE
mtsrr0 r7
mtsrr1 r6
- RFI
+ RFI_TO_KERNEL

#include "book3s_segment.S"
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
index 2a2b96d53999..93a180ceefad 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -156,7 +156,7 @@ no_dcbz32_on:
PPC_LL r9, SVCPU_R9(r3)
PPC_LL r3, (SVCPU_R3)(r3)

- RFI
+ RFI_TO_GUEST
kvmppc_handler_trampoline_enter_end:


@@ -407,5 +407,5 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
cmpwi r12, BOOK3S_INTERRUPT_DOORBELL
beqa BOOK3S_INTERRUPT_DOORBELL

- RFI
+ RFI_TO_KERNEL
kvmppc_handler_trampoline_exit_end:
--
2.14.3

2018-01-08 16:55:56

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

From: Nicholas Piggin <[email protected]>

Expose the state of the RFI flush (enabled/disabled) via sysfs, and
allow it to be enabled/dissabled at runtime.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/kernel/setup.h | 2 ++
arch/powerpc/kernel/sysfs.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)

diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
index 21c18071d9d5..493b03b0a966 100644
--- a/arch/powerpc/kernel/setup.h
+++ b/arch/powerpc/kernel/setup.h
@@ -61,4 +61,6 @@ void kvm_cma_reserve(void);
static inline void kvm_cma_reserve(void) { };
#endif

+extern bool rfi_flush;
+
#endif /* __ARCH_POWERPC_KERNEL_SETUP_H */
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index b8d4a1dac39f..8c19d014cffc 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -20,6 +20,7 @@
#include <asm/firmware.h>

#include "cacheinfo.h"
+#include "setup.h"

#ifdef CONFIG_PPC64
#include <asm/paca.h>
@@ -496,6 +497,43 @@ static DEVICE_ATTR(spurr, 0400, show_spurr, NULL);
static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
static DEVICE_ATTR(pir, 0400, show_pir, NULL);

+#ifdef CONFIG_PPC_BOOK3S_64
+static ssize_t show_rfi_flush(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", rfi_flush ? 1 : 0);
+}
+
+static ssize_t __used store_rfi_flush(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int val;
+ int ret = 0;
+
+ ret = sscanf(buf, "%d", &val);
+ if (ret != 1)
+ return -EINVAL;
+
+ if (val == 1)
+ rfi_flush_enable(true);
+ else if (val == 0)
+ rfi_flush_enable(false);
+ else
+ return -EINVAL;
+
+ return count;
+}
+
+static DEVICE_ATTR(rfi_flush, 0600,
+ show_rfi_flush, store_rfi_flush);
+
+static void sysfs_create_rfi_flush(void)
+{
+ device_create_file(cpu_subsys.dev_root, &dev_attr_rfi_flush);
+}
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
/*
* This is the system wide DSCR register default value. Any
* change to this default value through the sysfs interface
@@ -1047,6 +1085,9 @@ static int __init topology_init(void)
WARN_ON(r < 0);
#ifdef CONFIG_PPC64
sysfs_create_dscr_default();
+#ifdef CONFIG_PPC_BOOK3S
+ sysfs_create_rfi_flush();
+#endif
#endif /* CONFIG_PPC64 */

return 0;
--
2.14.3

2018-01-08 16:56:07

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 11/11] powerpc/powernv: Check device-tree for RFI flush settings

From: Oliver O'Halloran <[email protected]>

New device-tree properties are available which tell the hypervisor
settings related to the RFI flush. Use them to determine the
appropriate flush instruction to use, and whether the flush is
required.

Signed-off-by: Oliver O'Halloran <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/platforms/powernv/setup.c | 49 ++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 1edfbc1e40f4..4fb21e17504a 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -37,13 +37,62 @@
#include <asm/kexec.h>
#include <asm/smp.h>
#include <asm/tm.h>
+#include <asm/setup.h>

#include "powernv.h"

+static void pnv_setup_rfi_flush(void)
+{
+ struct device_node *np, *fw_features;
+ enum l1d_flush_type type;
+ int enable;
+
+ /* Default to fallback in case fw-features are not available */
+ type = L1D_FLUSH_FALLBACK;
+ enable = 1;
+
+ np = of_find_node_by_name(NULL, "ibm,opal");
+ fw_features = of_get_child_by_name(np, "fw-features");
+ of_node_put(np);
+
+ if (fw_features) {
+ np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
+ if (np && of_property_read_bool(np, "enabled"))
+ type = L1D_FLUSH_MTTRIG;
+
+ of_node_put(np);
+
+ np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
+ if (np && of_property_read_bool(np, "enabled"))
+ type = L1D_FLUSH_ORI;
+
+ of_node_put(np);
+
+ /* Enable unless firmware says NOT to */
+ enable = 2;
+ np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
+ if (np && of_property_read_bool(np, "disabled"))
+ enable--;
+
+ of_node_put(np);
+
+ np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1");
+ if (np && of_property_read_bool(np, "disabled"))
+ enable--;
+
+ of_node_put(np);
+ of_node_put(fw_features);
+ }
+
+ setup_rfi_flush(type, enable > 0);
+}
+
static void __init pnv_setup_arch(void)
{
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);

+ pnv_setup_rfi_flush();
+
/* Initialize SMP */
pnv_smp_init();

--
2.14.3

2018-01-08 16:55:54

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache

On some CPUs we can prevent the Meltdown vulnerability by flushing the
L1-D cache on exit from kernel to user mode, and from hypervisor to
guest.

This is known to be the case on at least Power7, Power8 and Power9. At
this time we do not know the status of the vulnerability on other CPUs
such as the 970 (Apple G5), pasemi CPUs (AmigaOne X1000) or Freescale
CPUs. As more information comes to light we can enable this, or other
mechanisms on those CPUs.

The vulnerability occurs when the load of an architecturally
inaccessible memory region (eg. userspace load of kernel memory) is
speculatively executed to the point where its result can influence the
address of a subsequent speculatively executed load.

In order for that to happen, the first load must hit in the L1,
because before the load is sent to the L2 the permission check is
performed. Therefore if no kernel addresses hit in the L1 the
vulnerability can not occur. We can ensure that is the case by
flushing the L1 whenever we return to userspace. Similarly for
hypervisor vs guest.

In order to flush the L1-D cache on exit, we add a section of nops at
each (h)rfi location that returns to a lower privileged context, and
patch that with some sequence. Newer firmwares are able to advertise
to us that there is a special nop instruction that flushes the L1-D.
If we do not see that advertised, we fall back to doing a displacement
flush in software.

For guest kernels we support migration between some CPU versions, and
different CPUs may use different flush instructions. So that we are
prepared to migrate to a machine with a different flush instruction
activated, we may have to patch more than one flush instruction at
boot if the hypervisor tells us to.

In the end this patch is mostly the work of Nicholas Piggin and
Michael Ellerman. However a cast of thousands contributed to analysis
of the issue, earlier versions of the patch, back ports testing etc.
Many thanks to all of them.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/include/asm/exception-64s.h | 40 ++++++++++++---
arch/powerpc/include/asm/feature-fixups.h | 13 +++++
arch/powerpc/include/asm/paca.h | 10 ++++
arch/powerpc/include/asm/setup.h | 13 +++++
arch/powerpc/kernel/asm-offsets.c | 5 ++
arch/powerpc/kernel/exceptions-64s.S | 82 +++++++++++++++++++++++++++++++
arch/powerpc/kernel/setup_64.c | 75 ++++++++++++++++++++++++++++
arch/powerpc/kernel/vmlinux.lds.S | 9 ++++
arch/powerpc/lib/feature-fixups.c | 41 ++++++++++++++++
9 files changed, 280 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index dfc56daed98b..7197b179c1b1 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -74,34 +74,58 @@
*/
#define EX_R3 EX_DAR

-/* Macros for annotating the expected destination of (h)rfid */
+/*
+ * Macros for annotating the expected destination of (h)rfid
+ *
+ * The nop instructions allow us to insert one or more instructions to flush the
+ * L1-D cache when returning to userspace or a guest.
+ */
+#define RFI_FLUSH_SLOT \
+ RFI_FLUSH_FIXUP_SECTION; \
+ nop; \
+ nop; \
+ nop

#define RFI_TO_KERNEL \
rfid

#define RFI_TO_USER \
- rfid
+ RFI_FLUSH_SLOT; \
+ rfid; \
+ b rfi_flush_fallback

#define RFI_TO_USER_OR_KERNEL \
- rfid
+ RFI_FLUSH_SLOT; \
+ rfid; \
+ b rfi_flush_fallback

#define RFI_TO_GUEST \
- rfid
+ RFI_FLUSH_SLOT; \
+ rfid; \
+ b rfi_flush_fallback

#define HRFI_TO_KERNEL \
hrfid

#define HRFI_TO_USER \
- hrfid
+ RFI_FLUSH_SLOT; \
+ hrfid; \
+ b hrfi_flush_fallback

#define HRFI_TO_USER_OR_KERNEL \
- hrfid
+ RFI_FLUSH_SLOT; \
+ hrfid; \
+ b hrfi_flush_fallback

#define HRFI_TO_GUEST \
- hrfid
+ RFI_FLUSH_SLOT; \
+ hrfid; \
+ b hrfi_flush_fallback

#define HRFI_TO_UNKNOWN \
- hrfid
+ RFI_FLUSH_SLOT; \
+ hrfid; \
+ b hrfi_flush_fallback

#ifdef CONFIG_RELOCATABLE
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
index 8f88f771cc55..1e82eb3caabd 100644
--- a/arch/powerpc/include/asm/feature-fixups.h
+++ b/arch/powerpc/include/asm/feature-fixups.h
@@ -187,7 +187,20 @@ label##3: \
FTR_ENTRY_OFFSET label##1b-label##3b; \
.popsection;

+#define RFI_FLUSH_FIXUP_SECTION \
+951: \
+ .pushsection __rfi_flush_fixup,"a"; \
+ .align 2; \
+952: \
+ FTR_ENTRY_OFFSET 951b-952b; \
+ .popsection;
+
+
#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
+
void apply_feature_fixups(void);
void setup_feature_keys(void);
#endif
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 3892db93b837..23ac7fc0af23 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -232,6 +232,16 @@ struct paca_struct {
struct sibling_subcore_state *sibling_subcore_state;
#endif
#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+ /*
+ * rfi fallback flush must be in its own cacheline to prevent
+ * other paca data leaking into the L1d
+ */
+ u64 exrfi[EX_SIZE] __aligned(0x80);
+ void *rfi_flush_fallback_area;
+ u64 l1d_flush_congruence;
+ u64 l1d_flush_sets;
+#endif
};

extern void copy_mm_to_paca(struct mm_struct *mm);
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index cf00ec26303a..469b7fdc9be4 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -39,6 +39,19 @@ static inline void pseries_big_endian_exceptions(void) {}
static inline void pseries_little_endian_exceptions(void) {}
#endif /* CONFIG_PPC_PSERIES */

+void rfi_flush_enable(bool enable);
+
+/* These are bit flags */
+enum l1d_flush_type {
+ L1D_FLUSH_NONE = 0x1,
+ L1D_FLUSH_FALLBACK = 0x2,
+ L1D_FLUSH_ORI = 0x4,
+ L1D_FLUSH_MTTRIG = 0x8,
+};
+
+void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
+void do_rfi_flush_fixups(enum l1d_flush_type types);
+
#endif /* !__ASSEMBLY__ */

#endif /* _ASM_POWERPC_SETUP_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 3f6316bcde4e..a6c72f720e8a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -237,6 +237,11 @@ int main(void)
OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp);
OFFSET(PACA_IN_MCE, paca_struct, in_mce);
OFFSET(PACA_IN_NMI, paca_struct, in_nmi);
+ OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area);
+ OFFSET(PACA_EXRFI, paca_struct, exrfi);
+ OFFSET(PACA_L1D_FLUSH_CONGRUENCE, paca_struct, l1d_flush_congruence);
+ OFFSET(PACA_L1D_FLUSH_SETS, paca_struct, l1d_flush_sets);
+
#endif
OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
OFFSET(PACAKEXECSTATE, paca_struct, kexec_state);
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index ed356194f09c..f7ebaac5849b 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1449,6 +1449,88 @@ masked_##_H##interrupt: \
b .; \
MASKED_DEC_HANDLER(_H)

+TRAMP_REAL_BEGIN(rfi_flush_fallback)
+ SET_SCRATCH0(r13);
+ GET_PACA(r13);
+ std r9,PACA_EXRFI+EX_R9(r13)
+ std r10,PACA_EXRFI+EX_R10(r13)
+ std r11,PACA_EXRFI+EX_R11(r13)
+ std r12,PACA_EXRFI+EX_R12(r13)
+ std r8,PACA_EXRFI+EX_R13(r13)
+ mfctr r9
+ ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
+ ld r11,PACA_L1D_FLUSH_SETS(r13)
+ ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
+ /*
+ * The load adresses are at staggered offsets within cachelines,
+ * which suits some pipelines better (on others it should not
+ * hurt.
+ */
+ addi r12,r12,8
+ mtctr r11
+ DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
+
+ /* order ld/st prior to dcbt stop all streams with flushing */
+ sync
+1: li r8,0
+ .rept 8 /* 8-way set associative */
+ ldx r11,r10,r8
+ add r8,r8,r12
+ add r8,r8,r11 /* r11 will be 0, but this creates a dependency */
+ .endr
+ addi r10,r10,128 /* 128 byte cache line */
+ bdnz 1b
+
+ mtctr r9
+ ld r9,PACA_EXRFI+EX_R9(r13)
+ ld r10,PACA_EXRFI+EX_R10(r13)
+ ld r11,PACA_EXRFI+EX_R11(r13)
+ ld r12,PACA_EXRFI+EX_R12(r13)
+ ld r8,PACA_EXRFI+EX_R13(r13)
+ GET_SCRATCH0(r13);
+ rfid
+
+TRAMP_REAL_BEGIN(hrfi_flush_fallback)
+ SET_SCRATCH0(r13);
+ GET_PACA(r13);
+ std r9,PACA_EXRFI+EX_R9(r13)
+ std r10,PACA_EXRFI+EX_R10(r13)
+ std r11,PACA_EXRFI+EX_R11(r13)
+ std r12,PACA_EXRFI+EX_R12(r13)
+ std r8,PACA_EXRFI+EX_R13(r13)
+ mfctr r9
+ ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
+ ld r11,PACA_L1D_FLUSH_SETS(r13)
+ ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
+ /*
+ * The load adresses are at staggered offsets within cachelines,
+ * which suits some pipelines better (on others it should not
+ * hurt.
+ */
+ addi r12,r12,8
+ mtctr r11
+ DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
+
+ /* order ld/st prior to dcbt stop all streams with flushing */
+ sync
+1: li r8,0
+ .rept 8 /* 8-way set associative */
+ ldx r11,r10,r8
+ add r8,r8,r12
+ add r8,r8,r11 /* r11 will be 0, but this creates a dependency */
+ .endr
+ addi r10,r10,128 /* 128 byte cache line */
+ bdnz 1b
+
+ mtctr r9
+ ld r9,PACA_EXRFI+EX_R9(r13)
+ ld r10,PACA_EXRFI+EX_R10(r13)
+ ld r11,PACA_EXRFI+EX_R11(r13)
+ ld r12,PACA_EXRFI+EX_R12(r13)
+ ld r8,PACA_EXRFI+EX_R13(r13)
+ GET_SCRATCH0(r13);
+ hrfid
+
/*
* Real mode exceptions actually use this too, but alternate
* instruction code patches (which end up in the common .text area)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index d3124c302146..d26b11816b8f 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -799,3 +799,78 @@ static int __init disable_hardlockup_detector(void)
return 0;
}
early_initcall(disable_hardlockup_detector);
+
+#ifdef CONFIG_PPC_BOOK3S_64
+static enum l1d_flush_type enabled_flush_types;
+static void *l1d_flush_fallback_area;
+bool rfi_flush;
+
+static void do_nothing(void *unused)
+{
+ /*
+ * We don't need to do the flush explicitly, just enter+exit kernel is
+ * sufficient, the RFI exit handlers will do the right thing.
+ */
+}
+
+void rfi_flush_enable(bool enable)
+{
+ if (rfi_flush == enable)
+ return;
+
+ if (enable) {
+ do_rfi_flush_fixups(enabled_flush_types);
+ on_each_cpu(do_nothing, NULL, 1);
+ } else
+ do_rfi_flush_fixups(L1D_FLUSH_NONE);
+
+ rfi_flush = enable;
+}
+
+void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)
+{
+ if (types & L1D_FLUSH_FALLBACK) {
+ int cpu;
+ u64 l1d_size = ppc64_caches.l1d.size;
+ u64 limit = min(safe_stack_limit(), ppc64_rma_size);
+
+ pr_info("rfi-flush: Using fallback displacement flush\n");
+
+ /*
+ * Align to L1d size, and size it at 2x L1d size, to
+ * catch possible hardware prefetch runoff. We don't
+ * have a recipe for load patterns to reliably avoid
+ * the prefetcher.
+ */
+ l1d_flush_fallback_area =
+ __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit));
+ memset(l1d_flush_fallback_area, 0, l1d_size * 2);
+
+ for_each_possible_cpu(cpu) {
+ /*
+ * The fallback flush is currently coded for 8-way
+ * associativity. Different associativity is possible,
+ * but it will be treated as 8-way and may not evict
+ * the lines as effectively.
+ *
+ * 128 byte lines are mandatory.
+ */
+ u64 c = l1d_size / 8;
+
+ paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
+ paca[cpu].l1d_flush_congruence = c;
+ paca[cpu].l1d_flush_sets = c / 128;
+ }
+ }
+
+ if (types & L1D_FLUSH_ORI)
+ pr_info("rfi-flush: Using ori type flush\n");
+
+ if (types & L1D_FLUSH_MTTRIG)
+ pr_info("rfi-flush: Using mttrig type flush\n");
+
+ enabled_flush_types = types;
+
+ rfi_flush_enable(enable);
+}
+#endif /* CONFIG_PPC_BOOK3S_64 */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 51e4ec92ade1..6507138ebe10 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -132,6 +132,15 @@ SECTIONS
/* Read-only data */
RO_DATA(PAGE_SIZE)

+#ifdef CONFIG_PPC64
+ . = ALIGN(8);
+ __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
+ __start___rfi_flush_fixup = .;
+ *(__rfi_flush_fixup)
+ __stop___rfi_flush_fixup = .;
+ }
+#endif
+
EXCEPTION_TABLE(0)

NOTES :kernel :notes
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 41cf5ae273cf..a95ea007d654 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
}
}

+#ifdef CONFIG_PPC_BOOK3S_64
+void do_rfi_flush_fixups(enum l1d_flush_type types)
+{
+ unsigned int instrs[3], *dest;
+ long *start, *end;
+ int i;
+
+ start = PTRRELOC(&__start___rfi_flush_fixup),
+ end = PTRRELOC(&__stop___rfi_flush_fixup);
+
+ instrs[0] = 0x60000000; /* nop */
+ instrs[1] = 0x60000000; /* nop */
+ instrs[2] = 0x60000000; /* nop */
+
+ if (types & L1D_FLUSH_FALLBACK)
+ /* b .+16 to fallback flush */
+ instrs[0] = 0x48000010;
+
+ i = 0;
+ if (types & L1D_FLUSH_ORI) {
+ instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
+ instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/
+ }
+
+ if (types & L1D_FLUSH_MTTRIG)
+ instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */
+
+ for (i = 0; start < end; start++, i++) {
+ dest = (void *)start + *start;
+
+ pr_devel("patching dest %lx\n", (unsigned long)dest);
+
+ patch_instruction(dest, instrs[0]);
+ patch_instruction(dest + 1, instrs[1]);
+ patch_instruction(dest + 2, instrs[2]);
+ }
+
+ printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
+}
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
{
long *start, *end;
--
2.14.3

2018-01-08 16:56:22

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 10/11] powerpc/pseries: Query hypervisor for RFI flush settings

From: Michael Neuling <[email protected]>

A new hypervisor call is available which tells the guest settings
related to the RFI flush. Use it to query the appropriate flush
instruction(s), and whether the flush is required.

Signed-off-by: Michael Neuling <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/platforms/pseries/setup.c | 35 ++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 28b286df0e91..db76963e693d 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -459,6 +459,39 @@ static void __init find_and_init_phbs(void)
of_pci_check_probe_only();
}

+static void pseries_setup_rfi_flush(void)
+{
+ struct h_cpu_char_result result;
+ enum l1d_flush_type types;
+ bool enable;
+ long rc;
+
+ /* Enable by default */
+ enable = true;
+
+ rc = plpar_get_cpu_characteristics(&result);
+ if (rc == H_SUCCESS) {
+ types = L1D_FLUSH_NONE;
+
+ if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
+ types |= L1D_FLUSH_MTTRIG;
+ if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30)
+ types |= L1D_FLUSH_ORI;
+
+ /* Use fallback if nothing set in hcall */
+ if (types == L1D_FLUSH_NONE)
+ types = L1D_FLUSH_FALLBACK;
+
+ if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
+ enable = false;
+ } else {
+ /* Default to fallback if case hcall is not available */
+ types = L1D_FLUSH_FALLBACK;
+ }
+
+ setup_rfi_flush(types, enable);
+}
+
static void __init pSeries_setup_arch(void)
{
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
@@ -476,6 +509,8 @@ static void __init pSeries_setup_arch(void)

fwnmi_init();

+ pseries_setup_rfi_flush();
+
/* By default, only probe PCI (can be overridden by rtas_pci) */
pci_add_flags(PCI_PROBE_ONLY);

--
2.14.3

2018-01-08 16:56:48

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 08/11] powerpc/64s: Support disabling RFI flush with no_rfi_flush and nopti

Because there may be some performance overhead of the RFI flush, add
kernel command line options to disable it.

We add a sensibly named 'no_rfi_flush' option, but we also hijack the
x86 option 'nopti'. The RFI flush is not the same as KPTI, but if we
see 'nopti' we can guess that the user is trying to avoid any overhead
of Meltdown mitigations, and it means we don't have to educate every
one about a different command line option.

Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/kernel/setup_64.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index d26b11816b8f..8f90b0b4f5ac 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -803,8 +803,29 @@ early_initcall(disable_hardlockup_detector);
#ifdef CONFIG_PPC_BOOK3S_64
static enum l1d_flush_type enabled_flush_types;
static void *l1d_flush_fallback_area;
+static bool no_rfi_flush;
bool rfi_flush;

+static int __init handle_no_rfi_flush(char *p)
+{
+ pr_info("rfi-flush: disabled on command line.");
+ no_rfi_flush = true;
+ return 0;
+}
+early_param("no_rfi_flush", handle_no_rfi_flush);
+
+/*
+ * The RFI flush is not KPTI, but because users will see doco that says to use
+ * nopti we hijack that option here to also disable the RFI flush.
+ */
+static int __init handle_no_pti(char *p)
+{
+ pr_info("rfi-flush: disabling due to 'nopti' on command line.\n");
+ handle_no_rfi_flush(NULL);
+ return 0;
+}
+early_param("nopti", handle_no_pti);
+
static void do_nothing(void *unused)
{
/*
@@ -871,6 +892,7 @@ void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)

enabled_flush_types = types;

- rfi_flush_enable(enable);
+ if (!no_rfi_flush)
+ rfi_flush_enable(enable);
}
#endif /* CONFIG_PPC_BOOK3S_64 */
--
2.14.3

2018-01-08 16:57:44

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 06/11] powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL

From: Nicholas Piggin <[email protected]>

In the SLB miss handler we may be returning to user or kernel. We need
to add a check early on and save the result in the cr4 register, and
then we bifurcate the return path based on that.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/kernel/exceptions-64s.S | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 5502b0147c4e..ed356194f09c 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -598,6 +598,9 @@ EXC_COMMON_BEGIN(slb_miss_common)
stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
std r10,PACA_EXSLB+EX_LR(r13) /* save LR */

+ andi. r9,r11,MSR_PR // Check for exception from userspace
+ cmpdi cr4,r9,MSR_PR // And save the result in CR4 for later
+
/*
* Test MSR_RI before calling slb_allocate_realmode, because the
* MSR in r11 gets clobbered. However we still want to allocate
@@ -624,9 +627,32 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)

/* All done -- return from exception. */

+ bne cr4,1f /* returning to kernel */
+
+.machine push
+.machine "power4"
+ mtcrf 0x80,r9
+ mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */
+ mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */
+ mtcrf 0x02,r9 /* I/D indication is in cr6 */
+ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
+.machine pop
+
+ RESTORE_CTR(r9, PACA_EXSLB)
+ RESTORE_PPR_PACA(PACA_EXSLB, r9)
+ mr r3,r12
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ RFI_TO_USER
+ b . /* prevent speculative execution */
+1:
.machine push
.machine "power4"
mtcrf 0x80,r9
+ mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */
mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */
mtcrf 0x02,r9 /* I/D indication is in cr6 */
mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
@@ -640,9 +666,10 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
ld r11,PACA_EXSLB+EX_R11(r13)
ld r12,PACA_EXSLB+EX_R12(r13)
ld r13,PACA_EXSLB+EX_R13(r13)
- rfid
+ RFI_TO_KERNEL
b . /* prevent speculative execution */

+
2: std r3,PACA_EXSLB+EX_DAR(r13)
mr r3,r12
mfspr r11,SPRN_SRR0
--
2.14.3

2018-01-08 16:55:48

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 04/11] powerpc/64: Convert the syscall exit path to use RFI_TO_USER/KERNEL

From: Nicholas Piggin <[email protected]>

In the syscall exit path we may be returning to user or kernel
context. We already have a test for that, because we conditionally
restore r13. So use that existing test and branch, and bifurcate the
return based on that.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/kernel/entry_64.S | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 567d8f487f2f..b20c6cb0fa7f 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -267,13 +267,23 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)

ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
+ ld r2,GPR2(r1)
+ ld r1,GPR1(r1)
+ mtlr r4
+ mtcr r5
+ mtspr SPRN_SRR0,r7
+ mtspr SPRN_SRR1,r8
+ RFI_TO_USER
+ b . /* prevent speculative execution */
+
+ /* exit to kernel */
1: ld r2,GPR2(r1)
ld r1,GPR1(r1)
mtlr r4
mtcr r5
mtspr SPRN_SRR0,r7
mtspr SPRN_SRR1,r8
- RFI
+ RFI_TO_KERNEL
b . /* prevent speculative execution */

.Lsyscall_error:
--
2.14.3

2018-01-08 16:58:10

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 05/11] powerpc/64: Convert fast_exception_return to use RFI_TO_USER/KERNEL

From: Nicholas Piggin <[email protected]>

Similar to the syscall return path, in fast_exception_return we may be
returning to user or kernel context. We already have a test for that,
because we conditionally restore r13. So use that existing test and
branch, and bifurcate the return based on that.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/kernel/entry_64.S | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index b20c6cb0fa7f..fde89f04f276 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -892,7 +892,7 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
REST_GPR(13, r1)
-1:
+
mtspr SPRN_SRR1,r3

ld r2,_CCR(r1)
@@ -905,8 +905,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ld r3,GPR3(r1)
ld r4,GPR4(r1)
ld r1,GPR1(r1)
+ RFI_TO_USER
+ b . /* prevent speculative execution */
+
+1: mtspr SPRN_SRR1,r3
+
+ ld r2,_CCR(r1)
+ mtcrf 0xFF,r2
+ ld r2,_NIP(r1)
+ mtspr SPRN_SRR0,r2

- rfid
+ ld r0,GPR0(r1)
+ ld r2,GPR2(r1)
+ ld r3,GPR3(r1)
+ ld r4,GPR4(r1)
+ ld r1,GPR1(r1)
+ RFI_TO_KERNEL
b . /* prevent speculative execution */

#endif /* CONFIG_PPC_BOOK3E */
--
2.14.3

2018-01-08 16:59:19

by Michael Ellerman

[permalink] [raw]
Subject: [PATCH 02/11] powerpc/64: Add macros for annotating the destination of rfid/hrfid

From: Nicholas Piggin <[email protected]>

The rfid/hrfid ((Hypervisor) Return From Interrupt) instruction is
used for switching from the kernel to userspace, and from the
hypervisor to the guest kernel. However it can and is also used for
other transitions, eg. from real mode kernel code to virtual mode
kernel code, and it's not always clear from the code what the
destination context is.

To make it clearer when reading the code, add macros which encode the
expected destination context.

Signed-off-by: Nicholas Piggin <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
---
arch/powerpc/include/asm/exception-64e.h | 6 ++++++
arch/powerpc/include/asm/exception-64s.h | 29 +++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)

diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
index a703452d67b6..555e22d5e07f 100644
--- a/arch/powerpc/include/asm/exception-64e.h
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -209,5 +209,11 @@ exc_##label##_book3e:
ori r3,r3,vector_offset@l; \
mtspr SPRN_IVOR##vector_number,r3;

+#define RFI_TO_KERNEL \
+ rfi
+
+#define RFI_TO_USER \
+ rfi
+
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index b27205297e1d..1af427a3c74f 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -74,6 +74,35 @@
*/
#define EX_R3 EX_DAR

+/* Macros for annotating the expected destination of (h)rfid */
+
+#define RFI_TO_KERNEL \
+ rfid
+
+#define RFI_TO_USER \
+ rfid
+
+#define RFI_TO_USER_OR_KERNEL \
+ rfid
+
+#define RFI_TO_GUEST \
+ rfid
+
+#define HRFI_TO_KERNEL \
+ hrfid
+
+#define HRFI_TO_USER \
+ hrfid
+
+#define HRFI_TO_USER_OR_KERNEL \
+ hrfid
+
+#define HRFI_TO_GUEST \
+ hrfid
+
+#define HRFI_TO_UNKNOWN \
+ hrfid
+
#ifdef CONFIG_RELOCATABLE
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
--
2.14.3

2018-01-08 17:10:03

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 03/11] powerpc/64s: Simple RFI macro conversions

On Tue, Jan 09, 2018 at 03:54:45AM +1100, Michael Ellerman wrote:
> diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
> index 42a4b237df5f..34a5adeff084 100644
> --- a/arch/powerpc/kvm/book3s_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_rmhandlers.S
> @@ -46,6 +46,9 @@
>
> #define FUNC(name) name
>
> +#define RFI_TO_KERNEL RFI
> +#define RFI_TO_GUEST RFI
> +
> .macro INTERRUPT_TRAMPOLINE intno
>
> .global kvmppc_trampoline_\intno

Leftovers? The previous patch seems to define all that in common
headers, why redefine here again?

2018-01-08 17:20:59

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

On Tue, 9 Jan 2018, Michael Ellerman wrote:

Sorry, I wasn't aware about your efforts and did not cc you. I've just
queued a more generic sysfs interface for this whole mess:

https://lkml.kernel.org/r/[email protected]

It should be simple to extend for write and it would be great if all
affected architectures could share it.

Thanks,

tglx

2018-01-08 21:01:30

by Paul Mackerras

[permalink] [raw]
Subject: Re: [PATCH 03/11] powerpc/64s: Simple RFI macro conversions

On Mon, Jan 08, 2018 at 06:09:51PM +0100, Peter Zijlstra wrote:
> On Tue, Jan 09, 2018 at 03:54:45AM +1100, Michael Ellerman wrote:
> > diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
> > index 42a4b237df5f..34a5adeff084 100644
> > --- a/arch/powerpc/kvm/book3s_rmhandlers.S
> > +++ b/arch/powerpc/kvm/book3s_rmhandlers.S
> > @@ -46,6 +46,9 @@
> >
> > #define FUNC(name) name
> >
> > +#define RFI_TO_KERNEL RFI
> > +#define RFI_TO_GUEST RFI
> > +
> > .macro INTERRUPT_TRAMPOLINE intno
> >
> > .global kvmppc_trampoline_\intno
>
> Leftovers? The previous patch seems to define all that in common
> headers, why redefine here again?

Not leftovers - this is for the sake of 32-bit compiles. There is
code in this file and in book3s_segment.S which gets used both for
32-bit and 64-bit kernels, and this is supplying a definition on
32-bit platforms. Without this, 32-bit builds that have PR KVM
configured will fail.

Paul.

2018-01-08 21:57:53

by Tyrel Datwyler

[permalink] [raw]
Subject: Re: [PATCH 11/11] powerpc/powernv: Check device-tree for RFI flush settings

On 01/08/2018 08:54 AM, Michael Ellerman wrote:
> From: Oliver O'Halloran <[email protected]>
>
> New device-tree properties are available which tell the hypervisor
> settings related to the RFI flush. Use them to determine the
> appropriate flush instruction to use, and whether the flush is
> required.
>
> Signed-off-by: Oliver O'Halloran <[email protected]>
> Signed-off-by: Michael Ellerman <[email protected]>

Reviewed-by: Tyrel Datwyler <[email protected]>

2018-01-08 22:04:20

by Michael Ellerman

[permalink] [raw]
Subject: Re: [PATCH 03/11] powerpc/64s: Simple RFI macro conversions

Paul Mackerras <[email protected]> writes:

> On Mon, Jan 08, 2018 at 06:09:51PM +0100, Peter Zijlstra wrote:
>> On Tue, Jan 09, 2018 at 03:54:45AM +1100, Michael Ellerman wrote:
>> > diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
>> > index 42a4b237df5f..34a5adeff084 100644
>> > --- a/arch/powerpc/kvm/book3s_rmhandlers.S
>> > +++ b/arch/powerpc/kvm/book3s_rmhandlers.S
>> > @@ -46,6 +46,9 @@
>> >
>> > #define FUNC(name) name
>> >
>> > +#define RFI_TO_KERNEL RFI
>> > +#define RFI_TO_GUEST RFI
>> > +
>> > .macro INTERRUPT_TRAMPOLINE intno
>> >
>> > .global kvmppc_trampoline_\intno
>>
>> Leftovers? The previous patch seems to define all that in common
>> headers, why redefine here again?
>
> Not leftovers - this is for the sake of 32-bit compiles. There is
> code in this file and in book3s_segment.S which gets used both for
> 32-bit and 64-bit kernels, and this is supplying a definition on
> 32-bit platforms. Without this, 32-bit builds that have PR KVM
> configured will fail.

Yep.

I was going to put all the RFI macros in a single header, and we could
then have the dummy versions in there as would the usual pattern. But at
this stage it would just complicate life for people doing distro
backports, so I'll do that as a cleanup once it's all merged.

cheers

2018-01-08 22:10:08

by Michael Ellerman

[permalink] [raw]
Subject: Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

Thomas Gleixner <[email protected]> writes:

> On Tue, 9 Jan 2018, Michael Ellerman wrote:
>
> Sorry, I wasn't aware about your efforts and did not cc you. I've just
> queued a more generic sysfs interface for this whole mess:

No worries.

> https://lkml.kernel.org/r/[email protected]
>
> It should be simple to extend for write and it would be great if all
> affected architectures could share it.

As you say this has all been a bit of a mess, and as a result we already
have people running kernels with this patch, so we don't want to remove
the 'rfi_flush' file.

But we will certainly add support on powerpc for the files you have
created, in addition to 'rfi_flush'.

cheers

2018-01-09 06:06:27

by Jon Masters

[permalink] [raw]
Subject: Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

On 01/08/2018 05:09 PM, Michael Ellerman wrote:
> Thomas Gleixner <[email protected]> writes:
>
>> On Tue, 9 Jan 2018, Michael Ellerman wrote:
>>
>> Sorry, I wasn't aware about your efforts and did not cc you. I've just
>> queued a more generic sysfs interface for this whole mess:
>
> No worries.
>
>> https://lkml.kernel.org/r/[email protected]
>>
>> It should be simple to extend for write and it would be great if all
>> affected architectures could share it.
>
> As you say this has all been a bit of a mess

Indeed. All of us wish this went very differently.

I've been testing various versions of these patches since before the
holidays. For those doing backports to older kernels, a note that the
IBM team added OOL (Out Of Line) exception handlers and reworked all of
that code over the years since older kernels (e.g. 3.10) so you might
get problems on those if you enable the debug entry. I've got notes on
how to backport the OOL exceptions to older kernels if anyone cares.

> and as a result we already have people running kernels with this patch,
> so we don't want to remove the 'rfi_flush' file.

Knowing that the IBM team was going to post with this sysfs interface,
our trees contain the rfi_flush file. I mentioned it to some folks on
this end (because we know we don't want to add things in sysfs
generally, debugfs is a good substitute, per Andrea, and I raised this
with him yesterday as a concern in the backport here) but in the end it
seemed reasonable to pull this in because it was what got posted, and as
Michael says, it's gone into other distro kernels beyond just ours.

> But we will certainly add support on powerpc for the files you have
> created, in addition to 'rfi_flush'.

Thanks,

Jon.

--
Computer Architect | Sent from my Fedora powered laptop

2018-01-09 07:03:07

by Joel Stanley

[permalink] [raw]
Subject: Re: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache

On Mon, Jan 8, 2018 at 8:54 AM, Michael Ellerman <[email protected]> wrote:
> On some CPUs we can prevent the Meltdown vulnerability by flushing the
> L1-D cache on exit from kernel to user mode, and from hypervisor to
> guest.

Super minor nitpicks below. Don't let this hold up your work.

> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1449,6 +1449,88 @@ masked_##_H##interrupt: \
> b .; \
> MASKED_DEC_HANDLER(_H)
>
> +TRAMP_REAL_BEGIN(rfi_flush_fallback)
> + SET_SCRATCH0(r13);
> + GET_PACA(r13);
> + std r9,PACA_EXRFI+EX_R9(r13)
> + std r10,PACA_EXRFI+EX_R10(r13)
> + std r11,PACA_EXRFI+EX_R11(r13)
> + std r12,PACA_EXRFI+EX_R12(r13)
> + std r8,PACA_EXRFI+EX_R13(r13)
> + mfctr r9
> + ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
> + ld r11,PACA_L1D_FLUSH_SETS(r13)
> + ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
> + /*
> + * The load adresses are at staggered offsets within cachelines,
> + * which suits some pipelines better (on others it should not
> + * hurt.

Nit: missing ) on the last line.

> + */
> + addi r12,r12,8
> + mtctr r11
> + DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
> +

> --- a/arch/powerpc/lib/feature-fixups.c
> +++ b/arch/powerpc/lib/feature-fixups.c
> @@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
> }
> }
>
> +#ifdef CONFIG_PPC_BOOK3S_64
> +void do_rfi_flush_fixups(enum l1d_flush_type types)
> +{
> + unsigned int instrs[3], *dest;
> + long *start, *end;
> + int i;
> +
> + start = PTRRELOC(&__start___rfi_flush_fixup),
> + end = PTRRELOC(&__stop___rfi_flush_fixup);
> +
> + instrs[0] = 0x60000000; /* nop */
> + instrs[1] = 0x60000000; /* nop */
> + instrs[2] = 0x60000000; /* nop */
> +
> + if (types & L1D_FLUSH_FALLBACK)

This looked a bit confusing on first read. Do we ever get
L1D_FLUSH_FALLBACK and the other types? If not, could it be made
clearer?

if ( types & L1D_FLUSH_FALLBACK)
/* stuff */
else
/* other types */


> + /* b .+16 to fallback flush */
> + instrs[0] = 0x48000010;
> +
> + i = 0;
> + if (types & L1D_FLUSH_ORI) {
> + instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
> + instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/
> + }
> +
> + if (types & L1D_FLUSH_MTTRIG)
> + instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */
> +
> + for (i = 0; start < end; start++, i++) {
> + dest = (void *)start + *start;
> +
> + pr_devel("patching dest %lx\n", (unsigned long)dest);
> +
> + patch_instruction(dest, instrs[0]);
> + patch_instruction(dest + 1, instrs[1]);
> + patch_instruction(dest + 2, instrs[2]);
> + }
> +
> + printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
> +}
> +#endif /* CONFIG_PPC_BOOK3S_64 */
> +
> void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
> {
> long *start, *end;
> --
> 2.14.3
>

2018-01-09 08:06:47

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

On Tue, Jan 09, 2018 at 03:54:51AM +1100, Michael Ellerman wrote:
> From: Nicholas Piggin <[email protected]>
>
> Expose the state of the RFI flush (enabled/disabled) via sysfs, and
> allow it to be enabled/dissabled at runtime.
>
> Signed-off-by: Nicholas Piggin <[email protected]>
> Signed-off-by: Michael Ellerman <[email protected]>
> ---
> arch/powerpc/kernel/setup.h | 2 ++
> arch/powerpc/kernel/sysfs.c | 41 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 43 insertions(+)

You forgot a Documentation/ABI/ update for a new sysfs file :(

> diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
> index 21c18071d9d5..493b03b0a966 100644
> --- a/arch/powerpc/kernel/setup.h
> +++ b/arch/powerpc/kernel/setup.h
> @@ -61,4 +61,6 @@ void kvm_cma_reserve(void);
> static inline void kvm_cma_reserve(void) { };
> #endif
>
> +extern bool rfi_flush;
> +
> #endif /* __ARCH_POWERPC_KERNEL_SETUP_H */
> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
> index b8d4a1dac39f..8c19d014cffc 100644
> --- a/arch/powerpc/kernel/sysfs.c
> +++ b/arch/powerpc/kernel/sysfs.c
> @@ -20,6 +20,7 @@
> #include <asm/firmware.h>
>
> #include "cacheinfo.h"
> +#include "setup.h"
>
> #ifdef CONFIG_PPC64
> #include <asm/paca.h>
> @@ -496,6 +497,43 @@ static DEVICE_ATTR(spurr, 0400, show_spurr, NULL);
> static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
> static DEVICE_ATTR(pir, 0400, show_pir, NULL);
>
> +#ifdef CONFIG_PPC_BOOK3S_64
> +static ssize_t show_rfi_flush(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%d\n", rfi_flush ? 1 : 0);
> +}
> +
> +static ssize_t __used store_rfi_flush(struct device *dev,
> + struct device_attribute *attr, const char *buf,
> + size_t count)
> +{
> + int val;
> + int ret = 0;
> +
> + ret = sscanf(buf, "%d", &val);
> + if (ret != 1)
> + return -EINVAL;
> +
> + if (val == 1)
> + rfi_flush_enable(true);
> + else if (val == 0)
> + rfi_flush_enable(false);
> + else
> + return -EINVAL;
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR(rfi_flush, 0600,
> + show_rfi_flush, store_rfi_flush);

DEVICE_ATTR_RW()? And why 0600? That's odd.

> +
> +static void sysfs_create_rfi_flush(void)
> +{
> + device_create_file(cpu_subsys.dev_root, &dev_attr_rfi_flush);

No error checking?

And as Thomas said, why not just use the generic infrastructure he
created instead? That way there is some form of unity here for the same
exact issue.

At least he documented the api :)

thanks,

greg k-h

2018-01-09 08:07:27

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

On Tue, Jan 09, 2018 at 01:06:23AM -0500, Jon Masters wrote:
> Knowing that the IBM team was going to post with this sysfs interface,
> our trees contain the rfi_flush file. I mentioned it to some folks on
> this end (because we know we don't want to add things in sysfs
> generally, debugfs is a good substitute, per Andrea, and I raised this
> with him yesterday as a concern in the backport here) but in the end it
> seemed reasonable to pull this in because it was what got posted, and as
> Michael says, it's gone into other distro kernels beyond just ours.

What distro kernels end up enabling does not really reflect on what we
end up doing in mainline. The api for this should NOT be arch-specific
if at all possible, that way lies madness. Do you want to write
userspace tools to handle the 60+ different arch implementations?

Don't let the fragmentation problems of the period in which no one was
allowed to talk to each other, result in a unchangable mess, that would
be insane.

thanks,

greg k-h

2018-01-09 08:11:12

by Jon Masters

[permalink] [raw]
Subject: Re: [PATCH 09/11] powerpc/64s: Allow control of RFI flush via sysfs

On 01/09/2018 03:05 AM, Greg KH wrote:
> On Tue, Jan 09, 2018 at 01:06:23AM -0500, Jon Masters wrote:
>> Knowing that the IBM team was going to post with this sysfs interface,
>> our trees contain the rfi_flush file. I mentioned it to some folks on
>> this end (because we know we don't want to add things in sysfs
>> generally, debugfs is a good substitute, per Andrea, and I raised this
>> with him yesterday as a concern in the backport here) but in the end it
>> seemed reasonable to pull this in because it was what got posted, and as
>> Michael says, it's gone into other distro kernels beyond just ours.
>
> What distro kernels end up enabling does not really reflect on what we
> end up doing in mainline. The api for this should NOT be arch-specific
> if at all possible, that way lies madness. Do you want to write
> userspace tools to handle the 60+ different arch implementations?
>
> Don't let the fragmentation problems of the period in which no one was
> allowed to talk to each other, result in a unchangable mess, that would
> be insane.

Totally fine :) Just saying we tried to do reasonable things with what
we had. Whatever happens upstream in the end is, of course, what we'll
make sure fits into updates that go into the likes of RHEL.

Jon.

--
Computer Architect | Sent from my Fedora powered laptop

2018-01-09 16:05:18

by Michael Ellerman

[permalink] [raw]
Subject: Re: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache

Joel Stanley <[email protected]> writes:

> On Mon, Jan 8, 2018 at 8:54 AM, Michael Ellerman <[email protected]> wrote:
>> On some CPUs we can prevent the Meltdown vulnerability by flushing the
>> L1-D cache on exit from kernel to user mode, and from hypervisor to
>> guest.
>
> Super minor nitpicks below. Don't let this hold up your work.
>
>> --- a/arch/powerpc/kernel/exceptions-64s.S
>> +++ b/arch/powerpc/kernel/exceptions-64s.S
>> @@ -1449,6 +1449,88 @@ masked_##_H##interrupt: \
>> b .; \
>> MASKED_DEC_HANDLER(_H)
>>
>> +TRAMP_REAL_BEGIN(rfi_flush_fallback)
>> + SET_SCRATCH0(r13);
>> + GET_PACA(r13);
>> + std r9,PACA_EXRFI+EX_R9(r13)
>> + std r10,PACA_EXRFI+EX_R10(r13)
>> + std r11,PACA_EXRFI+EX_R11(r13)
>> + std r12,PACA_EXRFI+EX_R12(r13)
>> + std r8,PACA_EXRFI+EX_R13(r13)
>> + mfctr r9
>> + ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
>> + ld r11,PACA_L1D_FLUSH_SETS(r13)
>> + ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13)
>> + /*
>> + * The load adresses are at staggered offsets within cachelines,
>> + * which suits some pipelines better (on others it should not
>> + * hurt.
>
> Nit: missing ) on the last line.

Thanks.

>> --- a/arch/powerpc/lib/feature-fixups.c
>> +++ b/arch/powerpc/lib/feature-fixups.c
>> @@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
>> }
>> }
>>
>> +#ifdef CONFIG_PPC_BOOK3S_64
>> +void do_rfi_flush_fixups(enum l1d_flush_type types)
>> +{
>> + unsigned int instrs[3], *dest;
>> + long *start, *end;
>> + int i;
>> +
>> + start = PTRRELOC(&__start___rfi_flush_fixup),
>> + end = PTRRELOC(&__stop___rfi_flush_fixup);
>> +
>> + instrs[0] = 0x60000000; /* nop */
>> + instrs[1] = 0x60000000; /* nop */
>> + instrs[2] = 0x60000000; /* nop */
>> +
>> + if (types & L1D_FLUSH_FALLBACK)
>
> This looked a bit confusing on first read. Do we ever get
> L1D_FLUSH_FALLBACK and the other types? If not, could it be made
> clearer?
>
> if ( types & L1D_FLUSH_FALLBACK)
> /* stuff */
> else
> /* other types */

Yeah that would make more sense.

I'm going to merge it as-is because that's whats been tested, and given
the time of day I'm likely to break it if I try and refactor it. So we
can clean it up once it's merged.

cheers

2018-01-11 02:25:46

by Michael Ellerman

[permalink] [raw]
Subject: Re: [01/11] powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper

On Mon, 2018-01-08 at 16:54:43 UTC, Michael Ellerman wrote:
> From: Michael Neuling <[email protected]>
>
> A new hypervisor call has been defined to communicate various
> characteristics of the CPU to guests. Add definitions for the hcall
> number, flags and a wrapper function.
>
> Signed-off-by: Michael Neuling <[email protected]>
> Signed-off-by: Michael Ellerman <[email protected]>

Series applied to powerpc fixes.

https://git.kernel.org/powerpc/c/191eccb1580939fb0d47deb405b82a

cheers

2018-01-25 09:11:41

by Christian Zigotzky

[permalink] [raw]
Subject: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache

FYI:

A-EON AmigaOne X1000 (CPU P.A. Semi PWRficient PA6T-1682M with two PA6T
cores):

/sys/devices/system/cpu/vulnerabilities/

-r--r--r-- 1 root root 4096 Jan 25 09:38 meltdown
-r--r--r-- 1 root root 4096 Jan 25 09:38 spectre_v1
-r--r--r-- 1 root root 4096 Jan 25 09:38 spectre_v2

meltdown Vulnerable
spectre_v1 Not affected
spectre_v2 Not affected


On 08 January 2018 at 5:54PM, Michael Ellerman wrote:
> At this time we do not know the status of the vulnerability on other CPUs
> such as the 970 (Apple G5), pasemi CPUs (AmigaOne X1000) or Freescale
> CPUs.


2018-01-30 02:11:46

by Michael Ellerman

[permalink] [raw]
Subject: Re: [PATCH 07/11] powerpc/64s: Add support for RFI flush of L1-D cache

Christian Zigotzky <[email protected]> writes:

> FYI:
>
> A-EON AmigaOne X1000 (CPU P.A. Semi PWRficient PA6T-1682M with two PA6T
> cores):
>
> /sys/devices/system/cpu/vulnerabilities/
>
> -r--r--r-- 1 root root 4096 Jan 25 09:38 meltdown
> -r--r--r-- 1 root root 4096 Jan 25 09:38 spectre_v1
> -r--r--r-- 1 root root 4096 Jan 25 09:38 spectre_v2
>
> meltdown Vulnerable
> spectre_v1 Not affected
> spectre_v2 Not affected

Which may or may not be true, this is still all a work in progress.

cheers