Commit cf43a078 authored by Juerg Haefliger's avatar Juerg Haefliger Committed by Stefan Bader

Revert "UBUNTU: SAUCE: powerpc: Secure memory rfi flush"

This reverts commit 76b01258.

CVE-2017-5754

BugLink: http://bugs.launchpad.net/bugs/1756121

The functionality of this commit is provided by the following upstream
patch series:
  * powerpc/64s: Allow control of RFI flush via debugfs
  * powerpc/64s: Wire up cpu_show_meltdown()
  * powerpc/powernv: Check device-tree for RFI flush settings
  * powerpc/pseries: Query hypervisor for RFI flush settings
  * powerpc/64s: Support disabling RFI flush with no_rfi_flush and nopti
  * powerpc/64s: Add support for RFI flush of L1-D cache
  * powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL
  * powerpc/64: Convert the syscall exit path to use RFI_TO_USER/KERNEL
  * powerpc/64: Convert fast_exception_return to use RFI_TO_USER/KERNEL
  * powerpc/64s: Simple RFI macro conversions
  * powerpc/64: Add macros for annotating the destination of rfid/hrfid
  * powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper
Signed-off-by: default avatarJuerg Haefliger <juergh@canonical.com>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
parent f34af9b4
......@@ -209,11 +209,5 @@ 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 */
......@@ -35,8 +35,6 @@
* implementations as possible.
*/
#include <asm/bug.h>
#define EX_R9 0
#define EX_R10 8
#define EX_R11 16
......@@ -52,72 +50,6 @@
#define EX_PPR 88 /* SMT thread status register (priority) */
#define EX_CTR 96
/*
* The nop instruction allows a secure memory protection instruction to be
* inserted with the rfi flush fixup.
*/
#define PREPARE_RFI_TO_USER \
RFI_FLUSH_FIXUP_SECTION; \
nop
#define PREPARE_RFI_TO_GUEST \
RFI_FLUSH_FIXUP_SECTION; \
nop
#define DEBUG_RFI
#ifdef DEBUG_RFI
#define CHECK_TARGET_MSR_PR(srr_reg, expected_pr) \
SET_SCRATCH0(r3); \
mfspr r3,srr_reg; \
extrdi r3,r3,1,63-MSR_PR_LG; \
666: tdnei r3,expected_pr; \
EMIT_BUG_ENTRY 666b,__FILE__,__LINE__,0; \
GET_SCRATCH0(r3);
#else
#define CHECK_TARGET_MSR_PR(srr_reg, expected_pr)
#endif
#define RFI_TO_KERNEL \
CHECK_TARGET_MSR_PR(SPRN_SRR1, 0); \
rfid
#define RFI_TO_USER \
CHECK_TARGET_MSR_PR(SPRN_SRR1, 1); \
PREPARE_RFI_TO_USER; \
rfid; \
b rfi_flush_fallback
#define RFI_TO_USER_OR_KERNEL \
PREPARE_RFI_TO_USER; \
rfid; \
b rfi_flush_fallback
#define RFI_TO_GUEST \
PREPARE_RFI_TO_GUEST; \
rfid; \
b rfi_flush_fallback
#define HRFI_TO_KERNEL \
CHECK_TARGET_MSR_PR(SPRN_HSRR1, 0); \
hrfid
#define HRFI_TO_USER \
CHECK_TARGET_MSR_PR(SPRN_HSRR1, 1); \
PREPARE_RFI_TO_USER; \
hrfid; \
b hrfi_flush_fallback
#define HRFI_TO_USER_OR_KERNEL \
PREPARE_RFI_TO_USER; \
hrfid; \
b hrfi_flush_fallback
#define HRFI_TO_GUEST \
PREPARE_RFI_TO_GUEST; \
hrfid; \
b hrfi_flush_fallback
#ifdef CONFIG_RELOCATABLE
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
ld r12,PACAKBASE(r13); /* get high part of &label */ \
......@@ -259,7 +191,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##RFI_TO_KERNEL; \
h##rfid; \
b . /* prevent speculative execution */
#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
__EXCEPTION_PROLOG_PSERIES_1(label, h)
......
......@@ -184,20 +184,4 @@ 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;
extern void do_rfi_flush_fixups(bool enable, unsigned int insn);
#endif
#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
......@@ -240,7 +240,6 @@
#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
......@@ -307,19 +306,6 @@
#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
#define H_SET_MODE_RESOURCE_LE 4
/* H_GET_CPU_CHARACTERISTICS return values */
#define H_GET_CPU_CHAR_CHAR_ORI31_SPEC_BAR PPC_BIT(0)
#define H_GET_CPU_CHAR_CHAR_BCCTR_SERIAL PPC_BIT(1)
#define H_GET_CPU_CHAR_CHAR_ORI30_L1_FLUSH PPC_BIT(2)
#define H_GET_CPU_CHAR_CHAR_MTTRIG2_L1_FLUSH PPC_BIT(3)
#define H_GET_CPU_CHAR_CHAR_L1D_PRIVATE PPC_BIT(4)
#define H_GET_CPU_CHAR_CHAR_BC_HINTS_HONORED PPC_BIT(5)
#define H_GET_CPU_CHAR_CHAR_MTTRID01_THR_CFG PPC_BIT(6)
#define H_GET_CPU_CHAR_BEHAV_FAV_SEC_VS_PERF PPC_BIT(0)
#define H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV PPC_BIT(1)
#define H_GET_CPU_CHAR_BEHAV_SPEC_BAR_BNDS_CHK PPC_BIT(2)
#ifndef __ASSEMBLY__
/**
......
......@@ -167,8 +167,6 @@ struct paca_struct {
#endif
#ifdef CONFIG_PPC_BOOK3S_64
void *rfi_flush_fallback_area;
/* Exclusive emergency stack pointer for machine check exception. */
void *mc_emergency_sp;
/*
......@@ -203,15 +201,6 @@ struct paca_struct {
#endif
struct kvmppc_host_state kvm_hstate;
#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[13] __aligned(0x80);
/* Number of consecutive 128 byte lines that must be loaded */
u64 l1d_flush_lines;
#endif
};
extern struct paca_struct *paca;
......
......@@ -323,20 +323,4 @@ static inline long plapr_set_watchpoint0(unsigned long dawr0, unsigned long dawr
return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR, dawr0, dawrx0);
}
static inline long plpar_get_cpu_characteristics(unsigned long *character,
unsigned long *behavior)
{
long rc;
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf);
if (character)
*character = retbuf[0];
if (behavior)
*behavior = retbuf[1];
return rc;
}
#endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */
......@@ -25,17 +25,6 @@ void check_for_initrd(void);
void initmem_init(void);
#define ARCH_PANIC_TIMEOUT 180
void rfi_flush_enable(bool enable);
enum l1d_flush_type {
L1D_FLUSH_NONE,
L1D_FLUSH_FALLBACK,
L1D_FLUSH_ORI,
L1D_FLUSH_MTTRIG,
};
void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_POWERPC_SETUP_H */
......
......@@ -243,9 +243,6 @@ int main(void)
#ifdef CONFIG_PPC_BOOK3S_64
DEFINE(PACAMCEMERGSP, offsetof(struct paca_struct, mc_emergency_sp));
DEFINE(PACA_IN_MCE, offsetof(struct paca_struct, in_mce));
OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area);
OFFSET(PACA_EXRFI, paca_struct, exrfi);
OFFSET(PACA_L1D_FLUSH_LINES, paca_struct, l1d_flush_lines);
#endif
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
......
......@@ -36,11 +36,6 @@
#include <asm/hw_irq.h>
#include <asm/context_tracking.h>
#include <asm/tm.h>
#ifdef CONFIG_PPC_BOOK3S
#include <asm/exception-64s.h>
#else
#include <asm/exception-64e.h>
#endif
/*
* System calls.
......@@ -230,23 +225,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
ACCOUNT_CPU_USER_EXIT(r11, r12)
HMT_MEDIUM_LOW_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_TO_KERNEL
RFI
b . /* prevent speculative execution */
syscall_error:
......@@ -368,7 +353,8 @@ tabort_syscall:
mtmsrd r10, 1
mtspr SPRN_SRR0, r11
mtspr SPRN_SRR1, r12
RFI_TO_USER
rfid
b . /* prevent speculative execution */
#endif
......@@ -901,7 +887,7 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ACCOUNT_CPU_USER_EXIT(r2, r4)
REST_GPR(13, r1)
1:
mtspr SPRN_SRR1,r3
ld r2,_CCR(r1)
......@@ -914,22 +900,8 @@ 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
ld r0,GPR0(r1)
ld r2,GPR2(r1)
ld r3,GPR3(r1)
ld r4,GPR4(r1)
ld r1,GPR1(r1)
RFI_TO_KERNEL
rfid
b . /* prevent speculative execution */
#endif /* CONFIG_PPC_BOOK3E */
......@@ -1105,7 +1077,7 @@ _GLOBAL(enter_rtas)
mtspr SPRN_SRR0,r5
mtspr SPRN_SRR1,r6
RFI_TO_KERNEL
rfid
b . /* prevent speculative execution */
rtas_return_loc:
......@@ -1130,7 +1102,7 @@ rtas_return_loc:
mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
RFI_TO_KERNEL
rfid
b . /* prevent speculative execution */
.align 3
......@@ -1201,7 +1173,7 @@ _GLOBAL(enter_prom)
LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
andc r11,r11,r12
mtsrr1 r11
RFI_TO_KERNEL
rfid
#endif /* CONFIG_PPC_BOOK3E */
1: /* Return from OF */
......
......@@ -46,7 +46,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
mtspr SPRN_SRR0,r10 ; \
ld r10,PACAKMSR(r13) ; \
mtspr SPRN_SRR1,r10 ; \
RFI_TO_KERNEL ; \
rfid ; \
b . ; /* prevent speculative execution */
#define SYSCALL_PSERIES_3 \
......@@ -54,7 +54,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \
1: mfspr r12,SPRN_SRR1 ; \
xori r12,r12,MSR_LE ; \
mtspr SPRN_SRR1,r12 ; \
RFI_TO_USER ; /* return to userspace */ \
rfid ; /* return to userspace */ \
b . ; /* prevent speculative execution */
#if defined(CONFIG_RELOCATABLE)
......@@ -507,7 +507,7 @@ BEGIN_FTR_SECTION
LOAD_HANDLER(r12, machine_check_handle_early)
1: mtspr SPRN_SRR0,r12
mtspr SPRN_SRR1,r11
RFI_TO_KERNEL
rfid
b . /* prevent speculative execution */
2:
/* Stack overflow. Stay on emergency stack and panic.
......@@ -666,7 +666,7 @@ masked_##_H##interrupt: \
ld r10,PACA_EXGEN+EX_R10(r13); \
ld r11,PACA_EXGEN+EX_R11(r13); \
GET_SCRATCH0(r13); \
##_H##RFI_TO_KERNEL; \
##_H##rfid; \
b .
MASKED_INTERRUPT()
......@@ -720,72 +720,6 @@ system_reset_fwnmi:
#endif /* CONFIG_PPC_PSERIES */
.globl rfi_flush_fallback
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)
mfctr r9
ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
ld r11,PACA_L1D_FLUSH_LINES(r13)
srdi r11,r11,2 /* Unrolled x4 */
mtctr r11
DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
/* XXX: Should an instruction synchronizing operation be done here? */
1:
/*
* The load adresses are at staggered offsets within cachelines,
* which suits some pipelines better (on others it should not
* hurt.
*/
ld r11,128*0+0(r10)
ld r11,128*1+8(r10)
ld r11,128*2+16(r10)
ld r11,128*3+24(r10)
addi r10,r10,(128 * 4)
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)
GET_SCRATCH0(r13);
rfid
.globl hrfi_flush_fallback
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)
mfctr r9
ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13)
ld r11,PACA_L1D_FLUSH_LINES(r13)
srdi r11,r11,2 /* Unrolled x4 */
mtctr r11
DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */
/* XXX: Should an instruction synchronizing operation be done here? */
1:
/*
* The load adresses are at staggered offsets within cachelines,
* which suits some pipelines better (on others it should not
* hurt.
*/
ld r11,128*0+0(r10)
ld r11,128*1+8(r10)
ld r11,128*2+16(r10)
ld r11,128*3+24(r10)
addi r10,r10,(128 * 4)
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)
GET_SCRATCH0(r13);
hrfid
#ifdef __DISABLED__
/*
* This is used for when the SLB miss handler has to go virtual,
......@@ -810,7 +744,7 @@ slb_miss_user_pseries:
mtspr SRR0,r12
mfspr r12,SRR1 /* and SRR1 */
mtspr SRR1,r10
rfid /* This code is disabled, hence no change */
rfid
b . /* prevent spec. execution */
#endif /* __DISABLED__ */
......@@ -824,7 +758,7 @@ kvmppc_skip_interrupt:
addi r13, r13, 4
mtspr SPRN_SRR0, r13
GET_SCRATCH0(r13)
RFI_TO_GUEST
rfid
b .
kvmppc_skip_Hinterrupt:
......@@ -836,7 +770,7 @@ kvmppc_skip_Hinterrupt:
addi r13, r13, 4
mtspr SPRN_HSRR0, r13
GET_SCRATCH0(r13)
RFI_TO_GUEST
hrfid
b .
#endif
......@@ -1126,7 +1060,7 @@ slb_miss_user_common:
ld r11,PACA_EXGEN+EX_R11(r13)
ld r12,PACA_EXGEN+EX_R12(r13)
ld r13,PACA_EXGEN+EX_R13(r13)
rfid /* Disabled code. No need to change */
rfid
b .
slb_miss_fault:
......@@ -1507,7 +1441,7 @@ machine_check_handle_early:
li r3,MSR_ME
andc r10,r10,r3 /* Turn off MSR_ME */
mtspr SPRN_SRR1,r10
RFI_TO_KERNEL
rfid
b .
2:
/*
......@@ -1525,7 +1459,7 @@ machine_check_handle_early:
*/
bl machine_check_queue_event
MACHINE_CHECK_HANDLER_WINDUP
RFI_TO_USER_OR_KERNEL
rfid
9:
/* Deliver the machine check to host kernel in V mode. */
MACHINE_CHECK_HANDLER_WINDUP
......@@ -1572,9 +1506,6 @@ slb_miss_realmode:
andi. r10,r12,MSR_RI /* check for unrecoverable exception */
beq- 2f
andi. r10,r12,MSR_PR /* check for exception from userspace */
beq 1f /* returning to kernel */
.machine push
.machine "power4"
mtcrf 0x80,r9
......@@ -1587,22 +1518,7 @@ slb_miss_realmode:
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 0x01,r9 /* slb_allocate uses cr0 and cr7 */
.machine pop
RESTORE_PPR_PACA(PACA_EXSLB, r9)
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_KERNEL
rfid
b . /* prevent speculative execution */
2: mfspr r11,SPRN_SRR0
......@@ -1611,7 +1527,7 @@ slb_miss_realmode:
mtspr SPRN_SRR0,r10
ld r10,PACAKMSR(r13)
mtspr SPRN_SRR1,r10
RFI_TO_KERNEL
rfid
b .
unrecov_slb:
......
......@@ -832,79 +832,3 @@ static int __init disable_hardlockup_detector(void)
}
early_initcall(disable_hardlockup_detector);
#endif
#ifdef CONFIG_PPC_BOOK3S_64
static enum l1d_flush_type l1d_flush_type;
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)
{
unsigned int insn;
if (rfi_flush == enable)
return;
switch (l1d_flush_type) {
case L1D_FLUSH_NONE:
insn = 0x60000000; /* nop */
break;
case L1D_FLUSH_FALLBACK:
insn = 0x48000008; /* b .+8 to fallback flush */
pr_info("rfi-fixups: Using fallback displacement flush\n");
break;
case L1D_FLUSH_ORI:
insn = 0x63de0000;
pr_info("rfi-fixups: Using ori type flush\n");
break;
case L1D_FLUSH_MTTRIG:
insn = 0x7c12dba6;
pr_info("rfi-fixups: Using mttrig type flush\n");
break;
default:
printk("rfi-fixups: No flush type detected, system may be vulnerable, update firmware.\n");
return;
}
do_rfi_flush_fixups(enable, insn);
if (enable)
on_each_cpu(do_nothing, NULL, 1);
rfi_flush = enable;
}
void __init setup_rfi_flush(enum l1d_flush_type type, bool enable)
{
if (type == L1D_FLUSH_FALLBACK) {
int cpu;
u64 l1d_size = ppc64_caches.dsize;
u64 limit = min(safe_stack_limit(), ppc64_rma_size);
/*
* 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) {
paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
paca[cpu].l1d_flush_lines = l1d_size / 128;
}
}
l1d_flush_type = type;
rfi_flush_enable(enable);
}
#endif /* CONFIG_PPC_BOOK3S_64 */
......@@ -18,10 +18,8 @@
#include <asm/smp.h>
#include <asm/pmc.h>
#include <asm/firmware.h>
#include <asm/ppc_asm.h>
#include "cacheinfo.h"
#include "setup.h"
#ifdef CONFIG_PPC64
#include <asm/paca.h>
......@@ -498,43 +496,6 @@ 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
......@@ -1097,9 +1058,6 @@ static int __init topology_init(void)
#ifdef CONFIG_PPC64
sysfs_create_dscr_default();
#ifdef CONFIG_PPC_BOOK3S
sysfs_create_rfi_flush();
#endif
#endif /* CONFIG_PPC64 */
return 0;
......
......@@ -72,15 +72,6 @@ SECTIONS
/* Read-only data */
RODATA
#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
......
......@@ -683,74 +683,6 @@ static int kvmppc_get_yield_count(struct kvm_vcpu *vcpu)
return yield_count;
}
static unsigned long characteristics, behaviour;
static bool have_characteristics;
struct hdat_to_papr_mapping {
unsigned long bit;
char *name;
bool is_behaviour;
};
static const struct hdat_to_papr_mapping mapping[] = {
{ .bit = H_GET_CPU_CHAR_CHAR_MTTRID01_THR_CFG, .name = "inst-thread-reconfig-control-trig0-1", },
{ .bit = H_GET_CPU_CHAR_CHAR_MTTRIG2_L1_FLUSH, .name = "inst-l1d-flush-trig2", },
{ .bit = H_GET_CPU_CHAR_CHAR_ORI30_L1_FLUSH, .name = "inst-l1d-flush-ori30,30,0", },
{ .bit = H_GET_CPU_CHAR_CHAR_ORI31_SPEC_BAR, .name = "inst-spec-barrier-ori31,31,0", },
{ .bit = H_GET_CPU_CHAR_CHAR_L1D_PRIVATE, .name = "fw-l1d-thread-split", },
{ .bit = H_GET_CPU_CHAR_CHAR_BCCTR_SERIAL, .name = "fw-bcctrl-serialized", },
//{ .bit = H_GET_CPU_CHAR_CHAR_BC_HINTS_HONORED, .name = ???, // FIXME Unknown name },
{ .bit = H_GET_CPU_CHAR_BEHAV_FAV_SEC_VS_PERF, .name = "speculation-policy-favor-security", .is_behaviour = true, },
{ .bit = H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV, .name = "needs-l1d-flush-msr-hv-1-to-0", .is_behaviour = true, },
{ .bit = H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV, .name = "needs-l1d-flush-msr-pr-0-to-1", .is_behaviour = true, },
{ .bit = H_GET_CPU_CHAR_BEHAV_SPEC_BAR_BNDS_CHK, .name = "needs-spec-barrier-for-bound-checks", .is_behaviour = true, },
};
static void init_cpu_characteristics(void)
{
struct device_node *np, *fw_features;
const struct hdat_to_papr_mapping *p;
int i;
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) {
have_characteristics = false;
return;
}
have_characteristics = true;
for (i = 0; i < ARRAY_SIZE(mapping); i++) {
p = &mapping[i];
np = of_get_child_by_name(fw_features, p->name);
if (np && of_property_read_bool(np, "enabled")) {
if (p->is_behaviour) {
behaviour |= p->bit;
} else {
characteristics |= p->bit;
}
}
of_node_put(np);
}
of_node_put(fw_features);
}
static int kvmppc_h_get_cpu_characteristics(struct kvm_vcpu *vcpu)
{
if (!have_characteristics)
return H_FUNCTION;
kvmppc_set_gpr(vcpu, 4, characteristics);
kvmppc_set_gpr(vcpu, 5, behaviour);
return H_SUCCESS;
}
int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
{
unsigned long req = kvmppc_get_gpr(vcpu, 3);
......@@ -862,7 +794,6 @@ static int kvmppc_hcall_impl_hv(unsigned long cmd)
case H_SET_MODE:
case H_LOGICAL_CI_LOAD:
case H_LOGICAL_CI_STORE:
case H_GET_CPU_CHARACTERISTICS:
#ifdef CONFIG_KVM_XICS
case H_XIRR:
case H_CPPR:
......@@ -1012,9 +943,6 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
r = RESUME_GUEST;
break;
case H_GET_CPU_CHARACTERISTICS:
ret = kvmppc_h_get_cpu_characteristics(vcpu);
break;
default:
kvmppc_dump_regs(vcpu);
printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n",
......@@ -3284,7 +3212,6 @@ static unsigned int default_hcall_list[] = {
H_PROD,
H_CONFER,
H_REGISTER_VPA,
H_GET_CPU_CHARACTERISTICS,
#ifdef CONFIG_KVM_XICS
H_EOI,
H_CPPR,
......@@ -3392,7 +3319,6 @@ static int kvmppc_book3s_init_hv(void)
kvm_ops_hv.owner = THIS_MODULE;
kvmppc_hv_ops = &kvm_ops_hv;
init_cpu_characteristics();
init_default_hcalls();
init_vcore_lists();
......
......@@ -65,7 +65,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline)
mtmsrd r0,1 /* clear RI in MSR */
mtsrr0 r5
mtsrr1 r6
RFI_TO_KERNEL
RFI
kvmppc_call_hv_entry:
ld r4, HSTATE_KVM_VCPU(r13)
......@@ -171,7 +171,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtsrr0 r8
mtsrr1 r7
beq cr1, 13f /* machine check */
RFI_TO_KERNEL
RFI
/* On POWER7, we have external interrupts set to use HSRR0/1 */
11: mtspr SPRN_HSRR0, r8
......@@ -989,7 +989,8 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ld r0, VCPU_GPR(R0)(r4)
ld r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
hrfid
b .
secondary_too_late:
......
......@@ -141,7 +141,7 @@ kvmppc_handler_skip_ins:
GET_SCRATCH0(r13)
/* And get back into the code */
RFI_TO_GUEST
RFI
#endif
/*
......@@ -164,6 +164,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline)
ori r5, r5, MSR_EE
mtsrr0 r7
mtsrr1 r6
RFI_TO_KERNEL
RFI
#include "book3s_segment.S"
......@@ -95,7 +95,6 @@
{H_GET_HCA_INFO, "H_GET_HCA_INFO"}, \
{H_GET_PERF_COUNT, "H_GET_PERF_COUNT"}, \
{H_MANAGE_TRACE, "H_MANAGE_TRACE"}, \
{H_GET_CPU_CHARACTERISTICS, "H_GET_CPU_CHARACTERISTICS"}, \
{H_FREE_LOGICAL_LAN_BUFFER, "H_FREE_LOGICAL_LAN_BUFFER"}, \
{H_QUERY_INT_STATE, "H_QUERY_INT_STATE"}, \
{H_POLL_PENDING, "H_POLL_PENDING"}, \
......
......@@ -113,33 +113,6 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
}
}
#ifdef CONFIG_PPC_BOOK3S_64
void do_rfi_flush_fixups(bool enable, unsigned int insn)
{
long *start, *end;
unsigned int *dest;
int i;
start = PTRRELOC(&__start___rfi_flush_fixup),
end = PTRRELOC(&__stop___rfi_flush_fixup);
for (i = 0; start < end; start++, i++) {
dest = (void *)start + *start;
pr_devel("RFI FLUSH FIXUP %s %lx\n", enable ? "enable" : "disable", (unsigned long)start);
if (!enable) {
pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, PPC_INST_NOP);
} else {
pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, insn);
}
}
printk(KERN_DEBUG "rfi-fixups: 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;
......
......@@ -35,65 +35,13 @@
#include <asm/opal.h>
#include <asm/kexec.h>
#include <asm/smp.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;
bool enable;
/* Default to fallback in case fw-features are not available */
type = L1D_FLUSH_FALLBACK;
enable = true;
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) {
/* Default to no flush, unless firmware says otherwise */
type = L1D_FLUSH_NONE;
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);
/* Don't enable unless firmware says so */
enable = false;
np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
if (np && of_property_read_bool(np, "enabled"))
enable = true;
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, "enabled"))
enable = true;
of_node_put(np);
of_node_put(fw_features);
}
setup_rfi_flush(type, enable);
}
static void __init pnv_setup_arch(void)
{
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
pnv_setup_rfi_flush();
/* Initialize SMP */
pnv_smp_init();
......
......@@ -499,32 +499,6 @@ static void __init find_and_init_phbs(void)
of_pci_check_probe_only();
}
static void pSeries_setup_rfi_flush(void)
{
unsigned long character, behaviour, rc;
enum l1d_flush_type type;
bool enable;
/* Default to fallback in case hcall is not available */
type = L1D_FLUSH_FALLBACK;
enable = true;
rc = plpar_get_cpu_characteristics(&character, &behaviour);
if (rc == H_SUCCESS) {
/* Default to no flush, unless firmware says otherwise */
type = L1D_FLUSH_NONE;
if (character & H_GET_CPU_CHAR_CHAR_MTTRIG2_L1_FLUSH)
type = L1D_FLUSH_MTTRIG;
if (character & H_GET_CPU_CHAR_CHAR_ORI30_L1_FLUSH)
type = L1D_FLUSH_ORI;
if (!(behaviour & H_GET_CPU_CHAR_BEHAV_L1_FLUSH_LOW_PRIV))
enable = false;
}
setup_rfi_flush(type, enable);
}
static void __init pSeries_setup_arch(void)
{
set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
......@@ -541,8 +515,6 @@ static void __init pSeries_setup_arch(void)
fwnmi_init();
pSeries_setup_rfi_flush();
/* By default, only probe PCI (can be overriden by rtas_pci) */
pci_add_flags(PCI_PROBE_ONLY);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment