Skip to content

Commit

Permalink
Merge Stable Linux tag v4.9.81 into 4.9/yocto
Browse files Browse the repository at this point in the history
* Stable Linux tag v4.9.81 : (247 commits)
  Linux 4.9.81
  x86/microcode: Do the family check first
  drm: rcar-du: Fix race condition when disabling planes at CRTC stop
  drm: rcar-du: Use the VBK interrupt for vblank events
  ASoC: rsnd: avoid duplicate free_irq()
  ASoC: rsnd: don't call free_irq() on Parent SSI
  ASoC: simple-card: Fix misleading error message
  crypto: tcrypt - fix S/G table for test_aead_speed()
  KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL
  KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
  KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES
  KVM/x86: Add IBPB support
  KVM: VMX: make MSR bitmaps per-VCPU
  KVM: VMX: introduce alloc_loaded_vmcs
  KVM: nVMX: Eliminate vmcs02 pool
  KVM: nVMX: mark vmcs12 pages dirty on L2 exit
  KVM: nVMX: vmx_complete_nested_posted_interrupt() can't fail
  KVM: nVMX: kmap() can't fail
  x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL
  x86/pti: Mark constant arrays as __initconst
  ...

# Conflicts:
#	kernel/time/hrtimer.c
  • Loading branch information
andrewkim-pkt committed Feb 22, 2018
2 parents 9bb663f + 7f3bd8d commit c249d8e
Show file tree
Hide file tree
Showing 252 changed files with 3,091 additions and 1,258 deletions.
2 changes: 0 additions & 2 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2805,8 +2805,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
norandmaps Don't use address space randomization. Equivalent to
echo 0 > /proc/sys/kernel/randomize_va_space

noreplace-paravirt [X86,IA-64,PV_OPS] Don't patch paravirt_ops

noreplace-smp [X86-32,SMP] Don't replace SMP instructions
with UP alternatives

Expand Down
90 changes: 90 additions & 0 deletions Documentation/speculation.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
This document explains potential effects of speculation, and how undesirable
effects can be mitigated portably using common APIs.

===========
Speculation
===========

To improve performance and minimize average latencies, many contemporary CPUs
employ speculative execution techniques such as branch prediction, performing
work which may be discarded at a later stage.

Typically speculative execution cannot be observed from architectural state,
such as the contents of registers. However, in some cases it is possible to
observe its impact on microarchitectural state, such as the presence or
absence of data in caches. Such state may form side-channels which can be
observed to extract secret information.

For example, in the presence of branch prediction, it is possible for bounds
checks to be ignored by code which is speculatively executed. Consider the
following code:

int load_array(int *array, unsigned int index)
{
if (index >= MAX_ARRAY_ELEMS)
return 0;
else
return array[index];
}

Which, on arm64, may be compiled to an assembly sequence such as:

CMP <index>, #MAX_ARRAY_ELEMS
B.LT less
MOV <returnval>, #0
RET
less:
LDR <returnval>, [<array>, <index>]
RET

It is possible that a CPU mis-predicts the conditional branch, and
speculatively loads array[index], even if index >= MAX_ARRAY_ELEMS. This
value will subsequently be discarded, but the speculated load may affect
microarchitectural state which can be subsequently measured.

More complex sequences involving multiple dependent memory accesses may
result in sensitive information being leaked. Consider the following
code, building on the prior example:

int load_dependent_arrays(int *arr1, int *arr2, int index)
{
int val1, val2,

val1 = load_array(arr1, index);
val2 = load_array(arr2, val1);

return val2;
}

Under speculation, the first call to load_array() may return the value
of an out-of-bounds address, while the second call will influence
microarchitectural state dependent on this value. This may provide an
arbitrary read primitive.

====================================
Mitigating speculation side-channels
====================================

The kernel provides a generic API to ensure that bounds checks are
respected even under speculation. Architectures which are affected by
speculation-based side-channels are expected to implement these
primitives.

The array_index_nospec() helper in <linux/nospec.h> can be used to
prevent information from being leaked via side-channels.

A call to array_index_nospec(index, size) returns a sanitized index
value that is bounded to [0, size) even under cpu speculation
conditions.

This can be used to protect the earlier load_array() example:

int load_array(int *array, unsigned int index)
{
if (index >= MAX_ARRAY_ELEMS)
return 0;
else {
index = array_index_nospec(index, MAX_ARRAY_ELEMS);
return array[index];
}
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 78
SUBLEVEL = 81
EXTRAVERSION =
NAME = Roaring Lionus

Expand Down
4 changes: 2 additions & 2 deletions arch/arm/boot/dts/bcm-nsp.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@
timer@20200 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x20200 0x100>;
interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
clocks = <&periph_clk>;
};

twd-timer@20600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x20600 0x20>;
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
IRQ_TYPE_LEVEL_HIGH)>;
IRQ_TYPE_EDGE_RISING)>;
clocks = <&periph_clk>;
};

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1284,7 +1284,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
return -EFAULT;
}

if (is_vm_hugetlb_page(vma) && !logging_active) {
if (vma_kernel_pagesize(vma) && !logging_active) {
hugetlb = true;
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
} else {
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ config PPC
select ARCH_HAS_GCOV_PROFILE_ALL
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CMOS_UPDATE
select GENERIC_CPU_VULNERABILITIES if PPC_BOOK3S_64
select GENERIC_TIME_VSYSCALL_OLD
select GENERIC_CLOCKEVENTS
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
Expand Down
6 changes: 6 additions & 0 deletions arch/powerpc/include/asm/exception-64e.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

53 changes: 53 additions & 0 deletions arch/powerpc/include/asm/exception-64s.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,59 @@
#define EX_PPR 88 /* SMT thread status register (priority) */
#define EX_CTR 96

/*
* 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 \
RFI_FLUSH_SLOT; \
rfid; \
b rfi_flush_fallback

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

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

#define HRFI_TO_KERNEL \
hrfid

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

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

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

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

#ifdef CONFIG_RELOCATABLE
#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
Expand Down
15 changes: 15 additions & 0 deletions arch/powerpc/include/asm/feature-fixups.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,19 @@ void apply_feature_fixups(void);
void setup_feature_keys(void);
#endif

#define RFI_FLUSH_FIXUP_SECTION \
951: \
.pushsection __rfi_flush_fixup,"a"; \
.align 2; \
952: \
FTR_ENTRY_OFFSET 951b-952b; \
.popsection;


#ifndef __ASSEMBLY__

extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;

#endif

#endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
17 changes: 17 additions & 0 deletions arch/powerpc/include/asm/hvcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,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
Expand Down Expand Up @@ -306,6 +307,17 @@
#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
#define H_SET_MODE_RESOURCE_LE 4

/* 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

#ifndef __ASSEMBLY__

/**
Expand Down Expand Up @@ -433,6 +445,11 @@ static inline unsigned long cmo_get_page_size(void)
}
#endif /* CONFIG_PPC_PSERIES */

struct h_cpu_char_result {
u64 character;
u64 behaviour;
};

#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HVCALL_H */
10 changes: 10 additions & 0 deletions arch/powerpc/include/asm/paca.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,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[13] __aligned(0x80);
void *rfi_flush_fallback_area;
u64 l1d_flush_congruence;
u64 l1d_flush_sets;
#endif
};

#ifdef CONFIG_PPC_BOOK3S
Expand Down
14 changes: 14 additions & 0 deletions arch/powerpc/include/asm/plpar_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,18 @@ 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(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 */
13 changes: 13 additions & 0 deletions arch/powerpc/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,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 */
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ 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));
DEFINE(PACA_RFI_FLUSH_FALLBACK_AREA, offsetof(struct paca_struct, rfi_flush_fallback_area));
DEFINE(PACA_EXRFI, offsetof(struct paca_struct, exrfi));
DEFINE(PACA_L1D_FLUSH_CONGRUENCE, offsetof(struct paca_struct, l1d_flush_congruence));
DEFINE(PACA_L1D_FLUSH_SETS, offsetof(struct paca_struct, l1d_flush_sets));
#endif
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
Expand Down
30 changes: 27 additions & 3 deletions arch/powerpc/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,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 */

syscall_error:
Expand Down Expand Up @@ -859,7 +869,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)
Expand All @@ -872,8 +882,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 */

rfid
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
b . /* prevent speculative execution */

#endif /* CONFIG_PPC_BOOK3E */
Expand Down
Loading

0 comments on commit c249d8e

Please sign in to comment.