mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
* linux-linaro-lsk-v4.4: (361 commits)
Linux 4.4.135
Revert "vti4: Don't override MTU passed on link creation via IFLA_MTU"
Linux 4.4.134
s390/ftrace: use expoline for indirect branches
kdb: make "mdr" command repeat
Bluetooth: btusb: Add device ID for RTL8822BE
ASoC: samsung: i2s: Ensure the RCLK rate is properly determined
regulator: of: Add a missing 'of_node_put()' in an error handling path of 'of_regulator_match()'
scsi: lpfc: Fix frequency of Release WQE CQEs
scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing
scsi: lpfc: Fix issue_lip if link is disabled
netlabel: If PF_INET6, check sk_buff ip header version
selftests/net: fixes psock_fanout eBPF test case
perf report: Fix memory corruption in --branch-history mode --branch-history
perf tests: Use arch__compare_symbol_names to compare symbols
x86/apic: Set up through-local-APIC mode on the boot CPU if 'noapic' specified
drm/rockchip: Respect page offset for PRIME mmap calls
MIPS: Octeon: Fix logging messages with spurious periods after newlines
audit: return on memory error to avoid null pointer dereference
crypto: sunxi-ss - Add MODULE_ALIAS to sun4i-ss
...
Conflicts:
arch/arm64/include/asm/assembler.h
Rebase LTS commit 348f043ab6
("arm64: Add work around for Arm Cortex-A55 Erratum 1024718").
fs/f2fs/namei.c
Rebase LTS commit 03bb758894
("do d_instantiate/unlock_new_inode combinations safely")
fs/proc/base.c
Trivial typo.
kernel/auditsc.c
Rebase LTS commit 9bb698bede
("audit: move calcs after alloc and check when logging set loginuid").
kernel/time/timekeeping.c
Rebase changes from AOSP commit 28850c79d071
("BACKPORT: time: Fix CLOCK_MONOTONIC_RAW sub-nanosecond accounting"), and
1d35c0438678 ("BACKPORT: time: Clean up CLOCK_MONOTONIC_RAW time handling").
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
This commit is contained in:
commit
3d5962249d
|
|
@ -112,9 +112,11 @@ $low_water_mark is expressed in blocks of size $data_block_size. If
|
|||
free space on the data device drops below this level then a dm event
|
||||
will be triggered which a userspace daemon should catch allowing it to
|
||||
extend the pool device. Only one such event will be sent.
|
||||
Resuming a device with a new table itself triggers an event so the
|
||||
userspace daemon can use this to detect a situation where a new table
|
||||
already exceeds the threshold.
|
||||
|
||||
No special event is triggered if a just resumed device's free space is below
|
||||
the low water mark. However, resuming a device always triggers an
|
||||
event; a userspace daemon should verify that free space exceeds the low
|
||||
water mark when handling this event.
|
||||
|
||||
A low water mark for the metadata device is maintained in the kernel and
|
||||
will trigger a dm event if free space on the metadata device drops below
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 132
|
||||
SUBLEVEL = 135
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
|
|||
|
|
@ -29,18 +29,10 @@
|
|||
: "r" (uaddr), "r"(oparg) \
|
||||
: "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -66,17 +58,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
* Atomic exchange.
|
||||
* Since it can be used to implement critical sections
|
||||
* it must clobber "memory" (also for interrupts in UP).
|
||||
*
|
||||
* The leading and the trailing memory barriers guarantee that these
|
||||
* operations are fully ordered.
|
||||
*
|
||||
*/
|
||||
|
||||
static inline unsigned long
|
||||
|
|
@ -18,6 +22,7 @@ ____xchg(_u8, volatile char *m, unsigned long val)
|
|||
{
|
||||
unsigned long ret, tmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %4,7,%3\n"
|
||||
" insbl %1,%4,%1\n"
|
||||
|
|
@ -42,6 +47,7 @@ ____xchg(_u16, volatile short *m, unsigned long val)
|
|||
{
|
||||
unsigned long ret, tmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %4,7,%3\n"
|
||||
" inswl %1,%4,%1\n"
|
||||
|
|
@ -66,6 +72,7 @@ ____xchg(_u32, volatile int *m, unsigned long val)
|
|||
{
|
||||
unsigned long dummy;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%4\n"
|
||||
" bis $31,%3,%1\n"
|
||||
|
|
@ -86,6 +93,7 @@ ____xchg(_u64, volatile long *m, unsigned long val)
|
|||
{
|
||||
unsigned long dummy;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%4\n"
|
||||
" bis $31,%3,%1\n"
|
||||
|
|
@ -127,10 +135,12 @@ ____xchg(, volatile void *ptr, unsigned long x, int size)
|
|||
* store NEW in MEM. Return the initial value in MEM. Success is
|
||||
* indicated by comparing RETURN with OLD.
|
||||
*
|
||||
* The memory barrier should be placed in SMP only when we actually
|
||||
* make the change. If we don't change anything (so if the returned
|
||||
* prev is equal to old) then we aren't acquiring anything new and
|
||||
* we don't need any memory barrier as far I can tell.
|
||||
* The leading and the trailing memory barriers guarantee that these
|
||||
* operations are fully ordered.
|
||||
*
|
||||
* The trailing memory barrier is placed in SMP unconditionally, in
|
||||
* order to guarantee that dependency ordering is preserved when a
|
||||
* dependency is headed by an unsuccessful operation.
|
||||
*/
|
||||
|
||||
static inline unsigned long
|
||||
|
|
@ -138,6 +148,7 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
|
|||
{
|
||||
unsigned long prev, tmp, cmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %5,7,%4\n"
|
||||
" insbl %1,%5,%1\n"
|
||||
|
|
@ -149,8 +160,8 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
|
|||
" or %1,%2,%2\n"
|
||||
" stq_c %2,0(%4)\n"
|
||||
" beq %2,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
|
|
@ -165,6 +176,7 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
|
|||
{
|
||||
unsigned long prev, tmp, cmp, addr64;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
" andnot %5,7,%4\n"
|
||||
" inswl %1,%5,%1\n"
|
||||
|
|
@ -176,8 +188,8 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
|
|||
" or %1,%2,%2\n"
|
||||
" stq_c %2,0(%4)\n"
|
||||
" beq %2,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
|
|
@ -192,6 +204,7 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
|
|||
{
|
||||
unsigned long prev, cmp;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
|
|
@ -199,8 +212,8 @@ ____cmpxchg(_u32, volatile int *m, int old, int new)
|
|||
" mov %4,%1\n"
|
||||
" stl_c %1,%2\n"
|
||||
" beq %1,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
|
|
@ -215,6 +228,7 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
|
|||
{
|
||||
unsigned long prev, cmp;
|
||||
|
||||
smp_mb();
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
|
|
@ -222,8 +236,8 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
|
|||
" mov %4,%1\n"
|
||||
" stq_c %1,%2\n"
|
||||
" beq %1,3f\n"
|
||||
__ASM__MB
|
||||
"2:\n"
|
||||
__ASM__MB
|
||||
".subsection 2\n"
|
||||
"3: br 1b\n"
|
||||
".previous"
|
||||
|
|
|
|||
|
|
@ -479,7 +479,6 @@ config ARC_CURR_IN_REG
|
|||
|
||||
config ARC_EMUL_UNALIGNED
|
||||
bool "Emulate unaligned memory access (userspace only)"
|
||||
default N
|
||||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_ARCH_UNALIGN_ALLOW
|
||||
depends on ISA_ARCOMPACT
|
||||
|
|
|
|||
|
|
@ -73,20 +73,11 @@
|
|||
|
||||
#endif
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
#ifndef CONFIG_ARC_HAS_LLSC
|
||||
preempt_disable(); /* to guarantee atomic r-m-w of futex op */
|
||||
#endif
|
||||
|
|
@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
preempt_enable();
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@ codec: sgtl5000@0a {
|
|||
clocks = <&clks 201>;
|
||||
VDDA-supply = <®_2p5v>;
|
||||
VDDIO-supply = <®_3p3v>;
|
||||
lrclk-strength = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -738,7 +738,7 @@ sysmgr: sysmgr@ffd08000 {
|
|||
timer@fffec600 {
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xfffec600 0x100>;
|
||||
interrupts = <1 13 0xf04>;
|
||||
interrupts = <1 13 0xf01>;
|
||||
clocks = <&mpu_periph_clk>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -530,4 +530,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
|
|||
#endif
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_KPROBES
|
||||
#define _ASM_NOKPROBE(entry) \
|
||||
.pushsection "_kprobe_blacklist", "aw" ; \
|
||||
.balign 4 ; \
|
||||
.long entry; \
|
||||
.popsection
|
||||
#else
|
||||
#define _ASM_NOKPROBE(entry)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ASSEMBLER_H__ */
|
||||
|
|
|
|||
|
|
@ -128,20 +128,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
|||
#endif /* !SMP */
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tmp;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
preempt_disable();
|
||||
#endif
|
||||
|
|
@ -172,17 +162,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
|||
preempt_enable();
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ struct mm_struct;
|
|||
|
||||
void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
|
||||
|
||||
extern char vdso_start, vdso_end;
|
||||
|
||||
extern unsigned int vdso_total_pages;
|
||||
|
||||
#else /* CONFIG_VDSO */
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/bug.h>
|
||||
|
|
@ -395,7 +396,8 @@ void unregister_undef_hook(struct undef_hook *hook)
|
|||
raw_spin_unlock_irqrestore(&undef_lock, flags);
|
||||
}
|
||||
|
||||
static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
|
||||
static nokprobe_inline
|
||||
int call_undef_hook(struct pt_regs *regs, unsigned int instr)
|
||||
{
|
||||
struct undef_hook *hook;
|
||||
unsigned long flags;
|
||||
|
|
@ -468,6 +470,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
|
|||
|
||||
arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
|
||||
}
|
||||
NOKPROBE_SYMBOL(do_undefinstr)
|
||||
|
||||
/*
|
||||
* Handle FIQ similarly to NMI on x86 systems.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
static struct page **vdso_text_pagelist;
|
||||
|
||||
extern char vdso_start[], vdso_end[];
|
||||
|
||||
/* Total number of pages needed for the data and text portions of the VDSO. */
|
||||
unsigned int vdso_total_pages __ro_after_init;
|
||||
|
||||
|
|
@ -179,13 +181,13 @@ static int __init vdso_init(void)
|
|||
unsigned int text_pages;
|
||||
int i;
|
||||
|
||||
if (memcmp(&vdso_start, "\177ELF", 4)) {
|
||||
if (memcmp(vdso_start, "\177ELF", 4)) {
|
||||
pr_err("VDSO is not a valid ELF object!\n");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
|
||||
pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start);
|
||||
text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
|
||||
pr_debug("vdso: %i text pages at base %p\n", text_pages, vdso_start);
|
||||
|
||||
/* Allocate the VDSO text pagelist */
|
||||
vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
|
||||
|
|
@ -200,7 +202,7 @@ static int __init vdso_init(void)
|
|||
for (i = 0; i < text_pages; i++) {
|
||||
struct page *page;
|
||||
|
||||
page = virt_to_page(&vdso_start + i * PAGE_SIZE);
|
||||
page = virt_to_page(vdso_start + i * PAGE_SIZE);
|
||||
vdso_text_pagelist[i] = page;
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +213,7 @@ static int __init vdso_init(void)
|
|||
|
||||
cntvct_ok = cntvct_functional();
|
||||
|
||||
patch_vdso(&vdso_start);
|
||||
patch_vdso(vdso_start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ ENTRY(__get_user_1)
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_1)
|
||||
_ASM_NOKPROBE(__get_user_1)
|
||||
|
||||
ENTRY(__get_user_2)
|
||||
check_uaccess r0, 2, r1, r2, __get_user_bad
|
||||
|
|
@ -58,6 +59,7 @@ rb .req r0
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_2)
|
||||
_ASM_NOKPROBE(__get_user_2)
|
||||
|
||||
ENTRY(__get_user_4)
|
||||
check_uaccess r0, 4, r1, r2, __get_user_bad
|
||||
|
|
@ -65,6 +67,7 @@ ENTRY(__get_user_4)
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_4)
|
||||
_ASM_NOKPROBE(__get_user_4)
|
||||
|
||||
ENTRY(__get_user_8)
|
||||
check_uaccess r0, 8, r1, r2, __get_user_bad8
|
||||
|
|
@ -78,6 +81,7 @@ ENTRY(__get_user_8)
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_8)
|
||||
_ASM_NOKPROBE(__get_user_8)
|
||||
|
||||
#ifdef __ARMEB__
|
||||
ENTRY(__get_user_32t_8)
|
||||
|
|
@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8)
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_32t_8)
|
||||
_ASM_NOKPROBE(__get_user_32t_8)
|
||||
|
||||
ENTRY(__get_user_64t_1)
|
||||
check_uaccess r0, 1, r1, r2, __get_user_bad8
|
||||
|
|
@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1)
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_64t_1)
|
||||
_ASM_NOKPROBE(__get_user_64t_1)
|
||||
|
||||
ENTRY(__get_user_64t_2)
|
||||
check_uaccess r0, 2, r1, r2, __get_user_bad8
|
||||
|
|
@ -114,6 +120,7 @@ rb .req r0
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_64t_2)
|
||||
_ASM_NOKPROBE(__get_user_64t_2)
|
||||
|
||||
ENTRY(__get_user_64t_4)
|
||||
check_uaccess r0, 4, r1, r2, __get_user_bad8
|
||||
|
|
@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4)
|
|||
mov r0, #0
|
||||
ret lr
|
||||
ENDPROC(__get_user_64t_4)
|
||||
_ASM_NOKPROBE(__get_user_64t_4)
|
||||
#endif
|
||||
|
||||
__get_user_bad8:
|
||||
|
|
@ -131,6 +139,8 @@ __get_user_bad:
|
|||
ret lr
|
||||
ENDPROC(__get_user_bad)
|
||||
ENDPROC(__get_user_bad8)
|
||||
_ASM_NOKPROBE(__get_user_bad)
|
||||
_ASM_NOKPROBE(__get_user_bad8)
|
||||
|
||||
.pushsection __ex_table, "a"
|
||||
.long 1b, __get_user_bad
|
||||
|
|
|
|||
|
|
@ -1031,17 +1031,17 @@ static int clk_debugfs_register_one(struct clk *c)
|
|||
return -ENOMEM;
|
||||
c->dent = d;
|
||||
|
||||
d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
|
||||
d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount);
|
||||
if (!d) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
|
||||
d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate);
|
||||
if (!d) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
|
||||
d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
|
||||
if (!d) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ static void omap_pm_end(void)
|
|||
cpu_idle_poll_ctrl(false);
|
||||
}
|
||||
|
||||
static void omap_pm_finish(void)
|
||||
static void omap_pm_wake(void)
|
||||
{
|
||||
if (cpu_is_omap34xx())
|
||||
omap_prcm_irq_complete();
|
||||
|
|
@ -241,7 +241,7 @@ static const struct platform_suspend_ops omap_pm_ops = {
|
|||
.begin = omap_pm_begin,
|
||||
.end = omap_pm_end,
|
||||
.enter = omap_pm_enter,
|
||||
.finish = omap_pm_finish,
|
||||
.wake = omap_pm_wake,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -136,12 +136,6 @@ static struct clock_event_device clockevent_gpt = {
|
|||
.tick_resume = omap2_gp_timer_shutdown,
|
||||
};
|
||||
|
||||
static struct property device_disabled = {
|
||||
.name = "status",
|
||||
.length = sizeof("disabled"),
|
||||
.value = "disabled",
|
||||
};
|
||||
|
||||
static const struct of_device_id omap_timer_match[] __initconst = {
|
||||
{ .compatible = "ti,omap2420-timer", },
|
||||
{ .compatible = "ti,omap3430-timer", },
|
||||
|
|
@ -183,8 +177,17 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
|
|||
of_get_property(np, "ti,timer-secure", NULL)))
|
||||
continue;
|
||||
|
||||
if (!of_device_is_compatible(np, "ti,omap-counter32k"))
|
||||
of_add_property(np, &device_disabled);
|
||||
if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
|
||||
struct property *prop;
|
||||
|
||||
prop = kzalloc(sizeof(*prop), GFP_KERNEL);
|
||||
if (!prop)
|
||||
return NULL;
|
||||
prop->name = "status";
|
||||
prop->value = "disabled";
|
||||
prop->length = strlen(prop->value);
|
||||
of_add_property(np, prop);
|
||||
}
|
||||
return np;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -854,11 +854,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
|
|||
timer->irq = irq->start;
|
||||
timer->pdev = pdev;
|
||||
|
||||
/* Skip pm_runtime_enable for OMAP1 */
|
||||
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_irq_safe(dev);
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_irq_safe(dev);
|
||||
|
||||
if (!timer->reserved) {
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
|
|
|
|||
|
|
@ -165,13 +165,14 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
|||
{
|
||||
unsigned long flags;
|
||||
struct kprobe *p = &op->kp;
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
struct kprobe_ctlblk *kcb;
|
||||
|
||||
/* Save skipped registers */
|
||||
regs->ARM_pc = (unsigned long)op->kp.addr;
|
||||
regs->ARM_ORIG_r0 = ~0UL;
|
||||
|
||||
local_irq_save(flags);
|
||||
kcb = get_kprobe_ctlblk();
|
||||
|
||||
if (kprobe_running()) {
|
||||
kprobes_inc_nmissed_count(&op->kp);
|
||||
|
|
@ -191,6 +192,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
|
|||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
NOKPROBE_SYMBOL(optimized_callback)
|
||||
|
||||
int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -430,6 +430,20 @@ config ARM64_ERRATUM_843419
|
|||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_ERRATUM_1024718
|
||||
bool "Cortex-A55: 1024718: Update of DBM/AP bits without break before make might result in incorrect update"
|
||||
default y
|
||||
help
|
||||
This option adds work around for Arm Cortex-A55 Erratum 1024718.
|
||||
|
||||
Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect
|
||||
update of the hardware dirty bit when the DBM/AP bits are updated
|
||||
without a break-before-make. The work around is to disable the usage
|
||||
of hardware DBM locally on the affected cores. CPUs not affected by
|
||||
erratum will continue to use the feature.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config CAVIUM_ERRATUM_22375
|
||||
bool "Cavium erratum 22375, 24313"
|
||||
default y
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <asm/cpufeature.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
|
|
@ -398,4 +399,43 @@ alternative_endif
|
|||
mrs \rd, sp_el0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Check the MIDR_EL1 of the current CPU for a given model and a range of
|
||||
* variant/revision. See asm/cputype.h for the macros used below.
|
||||
*
|
||||
* model: MIDR_CPU_PART of CPU
|
||||
* rv_min: Minimum of MIDR_CPU_VAR_REV()
|
||||
* rv_max: Maximum of MIDR_CPU_VAR_REV()
|
||||
* res: Result register.
|
||||
* tmp1, tmp2, tmp3: Temporary registers
|
||||
*
|
||||
* Corrupts: res, tmp1, tmp2, tmp3
|
||||
* Returns: 0, if the CPU id doesn't match. Non-zero otherwise
|
||||
*/
|
||||
.macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3
|
||||
mrs \res, midr_el1
|
||||
mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK)
|
||||
mov_q \tmp2, MIDR_CPU_PART_MASK
|
||||
and \tmp3, \res, \tmp2 // Extract model
|
||||
and \tmp1, \res, \tmp1 // rev & variant
|
||||
mov_q \tmp2, \model
|
||||
cmp \tmp3, \tmp2
|
||||
cset \res, eq
|
||||
cbz \res, .Ldone\@ // Model matches ?
|
||||
|
||||
.if (\rv_min != 0) // Skip min check if rv_min == 0
|
||||
mov_q \tmp3, \rv_min
|
||||
cmp \tmp1, \tmp3
|
||||
cset \res, ge
|
||||
.endif // \rv_min != 0
|
||||
/* Skip rv_max check if rv_min == rv_max && rv_min != 0 */
|
||||
.if ((\rv_min != \rv_max) || \rv_min == 0)
|
||||
mov_q \tmp2, \rv_max
|
||||
cmp \tmp1, \tmp2
|
||||
cset \tmp2, le
|
||||
and \res, \res, \tmp2
|
||||
.endif
|
||||
.Ldone\@:
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_ASSEMBLER_H */
|
||||
|
|
|
|||
|
|
@ -51,7 +51,15 @@
|
|||
#define MIDR_IMPLEMENTOR(midr) \
|
||||
(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
|
||||
|
||||
#define MIDR_CPU_MODEL(imp, partnum) \
|
||||
#define MIDR_CPU_VAR_REV(var, rev) \
|
||||
(((var) << MIDR_VARIANT_SHIFT) | (rev))
|
||||
|
||||
#define MIDR_CPU_PART_MASK \
|
||||
(MIDR_IMPLEMENTOR_MASK | \
|
||||
MIDR_ARCHITECTURE_MASK | \
|
||||
MIDR_PARTNUM_MASK)
|
||||
|
||||
#define MIDR_CPU_PART(imp, partnum) \
|
||||
(((imp) << MIDR_IMPLEMENTOR_SHIFT) | \
|
||||
(0xf << MIDR_ARCHITECTURE_SHIFT) | \
|
||||
((partnum) << MIDR_PARTNUM_SHIFT))
|
||||
|
|
@ -75,14 +83,16 @@
|
|||
#define ARM_CPU_PART_FOUNDATION 0xD00
|
||||
#define ARM_CPU_PART_CORTEX_A57 0xD07
|
||||
#define ARM_CPU_PART_CORTEX_A53 0xD03
|
||||
#define ARM_CPU_PART_CORTEX_A55 0xD05
|
||||
|
||||
#define APM_CPU_PART_POTENZA 0x000
|
||||
|
||||
#define CAVIUM_CPU_PART_THUNDERX 0x0A1
|
||||
|
||||
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
|
||||
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
|
||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
|
||||
#define MIDR_CORTEX_A55 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
|
||||
#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
|
||||
#define MIDR_THUNDERX MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
|
|
|||
|
|
@ -48,20 +48,10 @@ do { \
|
|||
} while (0)
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (int)(encoded_op << 8) >> 20;
|
||||
int cmparg = (int)(encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tmp;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1U << (oparg & 0x1f);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -91,17 +81,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,8 +123,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
|
|||
" cbnz %w1, 1f\n"
|
||||
" add %w1, %w0, %3\n"
|
||||
" casa %w0, %w1, %2\n"
|
||||
" and %w1, %w1, #0xffff\n"
|
||||
" eor %w1, %w1, %w0, lsr #16\n"
|
||||
" sub %w1, %w1, %3\n"
|
||||
" eor %w1, %w1, %w0\n"
|
||||
"1:")
|
||||
: "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
|
||||
: "I" (1 << TICKET_SHIFT)
|
||||
|
|
|
|||
|
|
@ -247,6 +247,11 @@ ENTRY(__cpu_setup)
|
|||
cbz x9, 2f
|
||||
cmp x9, #2
|
||||
b.lt 1f
|
||||
#ifdef CONFIG_ARM64_ERRATUM_1024718
|
||||
/* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */
|
||||
cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4
|
||||
cbnz x1, 1f
|
||||
#endif
|
||||
orr x10, x10, #TCR_HD // hardware Dirty flag update
|
||||
1: orr x10, x10, #TCR_HA // hardware Access flag update
|
||||
2:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
#include <asm/errno.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr);
|
||||
extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr);
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
|
|
|
|||
|
|
@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o
|
|||
/*
|
||||
* do the futex operations
|
||||
*/
|
||||
int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS; break;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
|
||||
} /* end futex_atomic_op_inuser() */
|
||||
} /* end arch_futex_atomic_op_inuser() */
|
||||
|
|
|
|||
|
|
@ -31,18 +31,9 @@
|
|||
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -72,30 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,18 +45,9 @@ do { \
|
|||
} while (0)
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -84,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,11 @@ static struct platform_device mcf_fec0 = {
|
|||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mcf_fec0_resources),
|
||||
.resource = mcf_fec0_resources,
|
||||
.dev.platform_data = FEC_PDATA,
|
||||
.dev = {
|
||||
.dma_mask = &mcf_fec0.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = FEC_PDATA,
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef MCFFEC_BASE1
|
||||
|
|
@ -167,7 +171,11 @@ static struct platform_device mcf_fec1 = {
|
|||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mcf_fec1_resources),
|
||||
.resource = mcf_fec1_resources,
|
||||
.dev.platform_data = FEC_PDATA,
|
||||
.dev = {
|
||||
.dma_mask = &mcf_fec1.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = FEC_PDATA,
|
||||
}
|
||||
};
|
||||
#endif /* MCFFEC_BASE1 */
|
||||
#endif /* CONFIG_FEC */
|
||||
|
|
|
|||
|
|
@ -29,18 +29,9 @@
|
|||
})
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -66,30 +57,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2240,7 +2240,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
|||
|
||||
parent_irq = irq_of_parse_and_map(ciu_node, 0);
|
||||
if (!parent_irq) {
|
||||
pr_err("ERROR: Couldn't acquire parent_irq for %s\n.",
|
||||
pr_err("ERROR: Couldn't acquire parent_irq for %s\n",
|
||||
ciu_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -2252,7 +2252,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
|||
|
||||
addr = of_get_address(ciu_node, 0, NULL, NULL);
|
||||
if (!addr) {
|
||||
pr_err("ERROR: Couldn't acquire reg(0) %s\n.", ciu_node->name);
|
||||
pr_err("ERROR: Couldn't acquire reg(0) %s\n", ciu_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
host_data->raw_reg = (u64)phys_to_virt(
|
||||
|
|
@ -2260,7 +2260,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
|||
|
||||
addr = of_get_address(ciu_node, 1, NULL, NULL);
|
||||
if (!addr) {
|
||||
pr_err("ERROR: Couldn't acquire reg(1) %s\n.", ciu_node->name);
|
||||
pr_err("ERROR: Couldn't acquire reg(1) %s\n", ciu_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
host_data->en_reg = (u64)phys_to_virt(
|
||||
|
|
@ -2268,7 +2268,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
|||
|
||||
r = of_property_read_u32(ciu_node, "cavium,max-bits", &val);
|
||||
if (r) {
|
||||
pr_err("ERROR: Couldn't read cavium,max-bits from %s\n.",
|
||||
pr_err("ERROR: Couldn't read cavium,max-bits from %s\n",
|
||||
ciu_node->name);
|
||||
return r;
|
||||
}
|
||||
|
|
@ -2278,7 +2278,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
|||
&octeon_irq_domain_cib_ops,
|
||||
host_data);
|
||||
if (!cib_domain) {
|
||||
pr_err("ERROR: Couldn't irq_domain_add_linear()\n.");
|
||||
pr_err("ERROR: Couldn't irq_domain_add_linear()\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,18 +83,9 @@
|
|||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@
|
|||
#define AR71XX_AHB_DIV_MASK 0x7
|
||||
|
||||
#define AR724X_PLL_REG_CPU_CONFIG 0x00
|
||||
#define AR724X_PLL_REG_PCIE_CONFIG 0x18
|
||||
#define AR724X_PLL_REG_PCIE_CONFIG 0x10
|
||||
|
||||
#define AR724X_PLL_FB_SHIFT 0
|
||||
#define AR724X_PLL_FB_MASK 0x3ff
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ static int fpr_get_msa(struct task_struct *target,
|
|||
/*
|
||||
* Copy the floating-point context to the supplied NT_PRFPREG buffer.
|
||||
* Choose the appropriate helper for general registers, and then copy
|
||||
* the FCSR register separately.
|
||||
* the FCSR and FIR registers separately.
|
||||
*/
|
||||
static int fpr_get(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
|
|
@ -490,6 +490,7 @@ static int fpr_get(struct task_struct *target,
|
|||
void *kbuf, void __user *ubuf)
|
||||
{
|
||||
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||
const int fir_pos = fcr31_pos + sizeof(u32);
|
||||
int err;
|
||||
|
||||
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
|
||||
|
|
@ -502,6 +503,12 @@ static int fpr_get(struct task_struct *target,
|
|||
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.fpu.fcr31,
|
||||
fcr31_pos, fcr31_pos + sizeof(u32));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
|
||||
&boot_cpu_data.fpu_id,
|
||||
fir_pos, fir_pos + sizeof(u32));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -550,7 +557,8 @@ static int fpr_set_msa(struct task_struct *target,
|
|||
/*
|
||||
* Copy the supplied NT_PRFPREG buffer to the floating-point context.
|
||||
* Choose the appropriate helper for general registers, and then copy
|
||||
* the FCSR register separately.
|
||||
* the FCSR register separately. Ignore the incoming FIR register
|
||||
* contents though, as the register is read-only.
|
||||
*
|
||||
* We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
|
||||
* which is supposed to have been guaranteed by the kernel before
|
||||
|
|
@ -564,6 +572,7 @@ static int fpr_set(struct task_struct *target,
|
|||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
|
||||
const int fir_pos = fcr31_pos + sizeof(u32);
|
||||
u32 fcr31;
|
||||
int err;
|
||||
|
||||
|
|
@ -591,6 +600,11 @@ static int fpr_set(struct task_struct *target,
|
|||
ptrace_setfcr31(target, fcr31);
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
err = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
|
||||
fir_pos,
|
||||
fir_pos + sizeof(u32));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -815,7 +829,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
fregs = get_fpu_regs(child);
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
|
|
@ -904,7 +918,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
|
||||
init_fp_ctx(child);
|
||||
#ifdef CONFIG_32BIT
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|||
break;
|
||||
}
|
||||
fregs = get_fpu_regs(child);
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
|
|
@ -203,7 +203,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|||
sizeof(child->thread.fpu));
|
||||
child->thread.fpu.fcr31 = 0;
|
||||
}
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
* The odd registers are actually the high
|
||||
* order bits of the values stored in the even
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
|||
{ "cache", VCPU_STAT(cache_exits), KVM_STAT_VCPU },
|
||||
{ "signal", VCPU_STAT(signal_exits), KVM_STAT_VCPU },
|
||||
{ "interrupt", VCPU_STAT(int_exits), KVM_STAT_VCPU },
|
||||
{ "cop_unsuable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
|
||||
{ "cop_unusable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU },
|
||||
{ "tlbmod", VCPU_STAT(tlbmod_exits), KVM_STAT_VCPU },
|
||||
{ "tlbmiss_ld", VCPU_STAT(tlbmiss_ld_exits), KVM_STAT_VCPU },
|
||||
{ "tlbmiss_st", VCPU_STAT(tlbmiss_st_exits), KVM_STAT_VCPU },
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void)
|
|||
|
||||
#define RBTX4939_MAX_7SEGLEDS 8
|
||||
|
||||
#if IS_ENABLED(CONFIG_LEDS_CLASS)
|
||||
#if IS_BUILTIN(CONFIG_LEDS_CLASS)
|
||||
static u8 led_val[RBTX4939_MAX_7SEGLEDS];
|
||||
struct rbtx4939_led_data {
|
||||
struct led_classdev cdev;
|
||||
|
|
@ -261,7 +261,7 @@ static inline void rbtx4939_led_setup(void)
|
|||
|
||||
static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_LEDS_CLASS)
|
||||
#if IS_BUILTIN(CONFIG_LEDS_CLASS)
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
/* bit7: reserved for LED class */
|
||||
|
|
|
|||
|
|
@ -32,20 +32,11 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
|
|||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
|
||||
{
|
||||
unsigned long int flags;
|
||||
u32 val;
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -98,17 +89,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,10 @@
|
|||
#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000)
|
||||
#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000)
|
||||
#define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000)
|
||||
#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000)
|
||||
#define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000)
|
||||
#define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000)
|
||||
#define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000)
|
||||
#define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000)
|
||||
#define FW_FEATURE_OPALv3 ASM_CONST(0x0000000400000000)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
|
@ -70,8 +68,7 @@ enum {
|
|||
FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
|
||||
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN,
|
||||
FW_FEATURE_PSERIES_ALWAYS = 0,
|
||||
FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 |
|
||||
FW_FEATURE_OPALv3,
|
||||
FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
|
||||
FW_FEATURE_POWERNV_ALWAYS = 0,
|
||||
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
|
||||
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
|
||||
|
|
|
|||
|
|
@ -31,18 +31,10 @@
|
|||
: "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
|
||||
: "cr0", "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
|
|
@ -68,17 +60,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ static inline bool arch_irq_work_has_interrupt(void)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
extern void arch_irq_work_raise(void);
|
||||
|
||||
#endif /* _ASM_POWERPC_IRQ_WORK_H */
|
||||
|
|
|
|||
|
|
@ -217,14 +217,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
unsigned short maj;
|
||||
unsigned short min;
|
||||
|
||||
/* We only show online cpus: disable preempt (overzealous, I
|
||||
* knew) to prevent cpu going down. */
|
||||
preempt_disable();
|
||||
if (!cpu_online(cpu_id)) {
|
||||
preempt_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
pvr = per_cpu(cpu_pvr, cpu_id);
|
||||
#else
|
||||
|
|
@ -329,9 +321,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
#ifdef CONFIG_SMP
|
||||
seq_printf(m, "\n");
|
||||
#endif
|
||||
|
||||
preempt_enable();
|
||||
|
||||
/* If this is the last cpu, print the summary */
|
||||
if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids)
|
||||
show_cpuinfo_summary(m);
|
||||
|
|
|
|||
|
|
@ -3002,15 +3002,17 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
|
|||
goto up_out;
|
||||
|
||||
psize = vma_kernel_pagesize(vma);
|
||||
porder = __ilog2(psize);
|
||||
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
||||
/* We can handle 4k, 64k or 16M pages in the VRMA */
|
||||
err = -EINVAL;
|
||||
if (!(psize == 0x1000 || psize == 0x10000 ||
|
||||
psize == 0x1000000))
|
||||
goto out_srcu;
|
||||
if (psize >= 0x1000000)
|
||||
psize = 0x1000000;
|
||||
else if (psize >= 0x10000)
|
||||
psize = 0x10000;
|
||||
else
|
||||
psize = 0x1000;
|
||||
porder = __ilog2(psize);
|
||||
|
||||
/* Update VRMASD field in the LPCR */
|
||||
senc = slb_pgsize_encoding(psize);
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@ static int numa_setup_cpu(unsigned long lcpu)
|
|||
nid = of_node_to_nid_single(cpu);
|
||||
|
||||
out_present:
|
||||
if (nid < 0 || !node_online(nid))
|
||||
if (nid < 0 || !node_possible(nid))
|
||||
nid = first_online_node;
|
||||
|
||||
map_cpu_to_node(lcpu, nid);
|
||||
|
|
@ -951,6 +951,32 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
|
|||
NODE_DATA(nid)->node_spanned_pages = spanned_pages;
|
||||
}
|
||||
|
||||
static void __init find_possible_nodes(void)
|
||||
{
|
||||
struct device_node *rtas;
|
||||
u32 numnodes, i;
|
||||
|
||||
if (min_common_depth <= 0)
|
||||
return;
|
||||
|
||||
rtas = of_find_node_by_path("/rtas");
|
||||
if (!rtas)
|
||||
return;
|
||||
|
||||
if (of_property_read_u32_index(rtas,
|
||||
"ibm,max-associativity-domains",
|
||||
min_common_depth, &numnodes))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < numnodes; i++) {
|
||||
if (!node_possible(i))
|
||||
node_set(i, node_possible_map);
|
||||
}
|
||||
|
||||
out:
|
||||
of_node_put(rtas);
|
||||
}
|
||||
|
||||
void __init initmem_init(void)
|
||||
{
|
||||
int nid, cpu;
|
||||
|
|
@ -966,12 +992,15 @@ void __init initmem_init(void)
|
|||
memblock_dump_all();
|
||||
|
||||
/*
|
||||
* Reduce the possible NUMA nodes to the online NUMA nodes,
|
||||
* since we do not support node hotplug. This ensures that we
|
||||
* lower the maximum NUMA node ID to what is actually present.
|
||||
* Modify the set of possible NUMA nodes to reflect information
|
||||
* available about the set of online nodes, and the set of nodes
|
||||
* that we expect to make use of for this platform's affinity
|
||||
* calculations.
|
||||
*/
|
||||
nodes_and(node_possible_map, node_possible_map, node_online_map);
|
||||
|
||||
find_possible_nodes();
|
||||
|
||||
for_each_online_node(nid) {
|
||||
unsigned long start_pfn, end_pfn;
|
||||
|
||||
|
|
@ -1304,6 +1333,40 @@ static long vphn_get_associativity(unsigned long cpu,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static inline int find_and_online_cpu_nid(int cpu)
|
||||
{
|
||||
__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
|
||||
int new_nid;
|
||||
|
||||
/* Use associativity from first thread for all siblings */
|
||||
vphn_get_associativity(cpu, associativity);
|
||||
new_nid = associativity_to_nid(associativity);
|
||||
if (new_nid < 0 || !node_possible(new_nid))
|
||||
new_nid = first_online_node;
|
||||
|
||||
if (NODE_DATA(new_nid) == NULL) {
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
/*
|
||||
* Need to ensure that NODE_DATA is initialized for a node from
|
||||
* available memory (see memblock_alloc_try_nid). If unable to
|
||||
* init the node, then default to nearest node that has memory
|
||||
* installed.
|
||||
*/
|
||||
if (try_online_node(new_nid))
|
||||
new_nid = first_online_node;
|
||||
#else
|
||||
/*
|
||||
* Default to using the nearest node that has memory installed.
|
||||
* Otherwise, it would be necessary to patch the kernel MM code
|
||||
* to deal with more memoryless-node error conditions.
|
||||
*/
|
||||
new_nid = first_online_node;
|
||||
#endif
|
||||
}
|
||||
|
||||
return new_nid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the CPU maps and sysfs entries for a single CPU when its NUMA
|
||||
* characteristics change. This function doesn't perform any locking and is
|
||||
|
|
@ -1369,7 +1432,6 @@ int arch_update_cpu_topology(void)
|
|||
{
|
||||
unsigned int cpu, sibling, changed = 0;
|
||||
struct topology_update_data *updates, *ud;
|
||||
__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
|
||||
cpumask_t updated_cpus;
|
||||
struct device *dev;
|
||||
int weight, new_nid, i = 0;
|
||||
|
|
@ -1404,11 +1466,7 @@ int arch_update_cpu_topology(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Use associativity from first thread for all siblings */
|
||||
vphn_get_associativity(cpu, associativity);
|
||||
new_nid = associativity_to_nid(associativity);
|
||||
if (new_nid < 0 || !node_online(new_nid))
|
||||
new_nid = first_online_node;
|
||||
new_nid = find_and_online_cpu_nid(cpu);
|
||||
|
||||
if (new_nid == numa_cpu_lookup_table[cpu]) {
|
||||
cpumask_andnot(&cpu_associativity_changes_mask,
|
||||
|
|
|
|||
|
|
@ -329,6 +329,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
|
||||
PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
|
||||
break;
|
||||
case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */
|
||||
PPC_LWZ_OFFS(r_A, r_skb, K);
|
||||
break;
|
||||
case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */
|
||||
PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -448,6 +448,16 @@ static void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
|
|||
/* invalid entry */
|
||||
continue;
|
||||
|
||||
/*
|
||||
* BHRB rolling buffer could very much contain the kernel
|
||||
* addresses at this point. Check the privileges before
|
||||
* exporting it to userspace (avoid exposure of regions
|
||||
* where we could have speculative execution)
|
||||
*/
|
||||
if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN) &&
|
||||
is_kernel_addr(addr))
|
||||
continue;
|
||||
|
||||
/* Branches are read most recent first (ie. mfbhrb 0 is
|
||||
* the most recent branch).
|
||||
* There are two types of valid entries:
|
||||
|
|
@ -1188,6 +1198,7 @@ static void power_pmu_disable(struct pmu *pmu)
|
|||
*/
|
||||
write_mmcr0(cpuhw, val);
|
||||
mb();
|
||||
isync();
|
||||
|
||||
/*
|
||||
* Disable instruction sampling if it was enabled
|
||||
|
|
@ -1196,12 +1207,26 @@ static void power_pmu_disable(struct pmu *pmu)
|
|||
mtspr(SPRN_MMCRA,
|
||||
cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
|
||||
mb();
|
||||
isync();
|
||||
}
|
||||
|
||||
cpuhw->disabled = 1;
|
||||
cpuhw->n_added = 0;
|
||||
|
||||
ebb_switch_out(mmcr0);
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
/*
|
||||
* These are readable by userspace, may contain kernel
|
||||
* addresses and are not switched by context switch, so clear
|
||||
* them now to avoid leaking anything to userspace in general
|
||||
* including to another process.
|
||||
*/
|
||||
if (ppmu->flags & PPMU_ARCH_207S) {
|
||||
mtspr(SPRN_SDAR, 0);
|
||||
mtspr(SPRN_SIAR, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ static int pnv_eeh_init(void)
|
|||
struct pci_controller *hose;
|
||||
struct pnv_phb *phb;
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
|
||||
pr_warn("%s: OPALv3 is required !\n",
|
||||
if (!firmware_has_feature(FW_FEATURE_OPAL)) {
|
||||
pr_warn("%s: OPAL is required !\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ static int __init pnv_init_idle_states(void)
|
|||
if (cpuidle_disable != IDLE_NO_OVERRIDE)
|
||||
goto out;
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_OPALv3))
|
||||
if (!firmware_has_feature(FW_FEATURE_OPAL))
|
||||
goto out;
|
||||
|
||||
power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index)
|
|||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* This can be called in the panic path with interrupts off, so use
|
||||
* mdelay in that case.
|
||||
*/
|
||||
static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
|
||||
{
|
||||
s64 rc = OPAL_BUSY;
|
||||
|
|
@ -58,10 +62,16 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
|
|||
while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
|
||||
rc = opal_write_nvram(__pa(buf), count, off);
|
||||
if (rc == OPAL_BUSY_EVENT) {
|
||||
msleep(OPAL_BUSY_DELAY_MS);
|
||||
if (in_interrupt() || irqs_disabled())
|
||||
mdelay(OPAL_BUSY_DELAY_MS);
|
||||
else
|
||||
msleep(OPAL_BUSY_DELAY_MS);
|
||||
opal_poll_events(NULL);
|
||||
} else if (rc == OPAL_BUSY) {
|
||||
msleep(OPAL_BUSY_DELAY_MS);
|
||||
if (in_interrupt() || irqs_disabled())
|
||||
mdelay(OPAL_BUSY_DELAY_MS);
|
||||
else
|
||||
msleep(OPAL_BUSY_DELAY_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ static const struct scom_controller opal_scom_controller = {
|
|||
|
||||
static int opal_xscom_init(void)
|
||||
{
|
||||
if (firmware_has_feature(FW_FEATURE_OPALv3))
|
||||
if (firmware_has_feature(FW_FEATURE_OPAL))
|
||||
scom_init(&opal_scom_controller);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,16 +98,11 @@ int __init early_init_dt_scan_opal(unsigned long node,
|
|||
pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n",
|
||||
opal.size, sizep, runtimesz);
|
||||
|
||||
powerpc_firmware_features |= FW_FEATURE_OPAL;
|
||||
if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
|
||||
powerpc_firmware_features |= FW_FEATURE_OPALv2;
|
||||
powerpc_firmware_features |= FW_FEATURE_OPALv3;
|
||||
pr_info("OPAL V3 detected !\n");
|
||||
} else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) {
|
||||
powerpc_firmware_features |= FW_FEATURE_OPALv2;
|
||||
pr_info("OPAL V2 detected !\n");
|
||||
powerpc_firmware_features |= FW_FEATURE_OPAL;
|
||||
pr_info("OPAL detected !\n");
|
||||
} else {
|
||||
pr_info("OPAL V1 detected !\n");
|
||||
panic("OPAL != V3 detected, no longer supported.\n");
|
||||
}
|
||||
|
||||
/* Reinit all cores with the right endian */
|
||||
|
|
@ -352,17 +347,15 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
|
|||
* enough room and be done with it
|
||||
*/
|
||||
spin_lock_irqsave(&opal_write_lock, flags);
|
||||
if (firmware_has_feature(FW_FEATURE_OPALv2)) {
|
||||
rc = opal_console_write_buffer_space(vtermno, &olen);
|
||||
len = be64_to_cpu(olen);
|
||||
if (rc || len < total_len) {
|
||||
spin_unlock_irqrestore(&opal_write_lock, flags);
|
||||
/* Closed -> drop characters */
|
||||
if (rc)
|
||||
return total_len;
|
||||
opal_poll_events(NULL);
|
||||
return -EAGAIN;
|
||||
}
|
||||
rc = opal_console_write_buffer_space(vtermno, &olen);
|
||||
len = be64_to_cpu(olen);
|
||||
if (rc || len < total_len) {
|
||||
spin_unlock_irqrestore(&opal_write_lock, flags);
|
||||
/* Closed -> drop characters */
|
||||
if (rc)
|
||||
return total_len;
|
||||
opal_poll_events(NULL);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* We still try to handle partial completions, though they
|
||||
|
|
@ -696,10 +689,7 @@ static int __init opal_init(void)
|
|||
}
|
||||
|
||||
/* Register OPAL consoles if any ports */
|
||||
if (firmware_has_feature(FW_FEATURE_OPALv2))
|
||||
consoles = of_find_node_by_path("/ibm,opal/consoles");
|
||||
else
|
||||
consoles = of_node_get(opal_node);
|
||||
consoles = of_find_node_by_path("/ibm,opal/consoles");
|
||||
if (consoles) {
|
||||
for_each_child_of_node(consoles, np) {
|
||||
if (strcmp(np->name, "serial"))
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
|
||||
if (!firmware_has_feature(FW_FEATURE_OPAL)) {
|
||||
pr_info(" Firmware too old to support M64 window\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,12 +140,8 @@ static void pnv_show_cpuinfo(struct seq_file *m)
|
|||
if (root)
|
||||
model = of_get_property(root, "model", NULL);
|
||||
seq_printf(m, "machine\t\t: PowerNV %s\n", model);
|
||||
if (firmware_has_feature(FW_FEATURE_OPALv3))
|
||||
seq_printf(m, "firmware\t: OPAL v3\n");
|
||||
else if (firmware_has_feature(FW_FEATURE_OPALv2))
|
||||
seq_printf(m, "firmware\t: OPAL v2\n");
|
||||
else if (firmware_has_feature(FW_FEATURE_OPAL))
|
||||
seq_printf(m, "firmware\t: OPAL v1\n");
|
||||
if (firmware_has_feature(FW_FEATURE_OPAL))
|
||||
seq_printf(m, "firmware\t: OPAL\n");
|
||||
else
|
||||
seq_printf(m, "firmware\t: BML\n");
|
||||
of_node_put(root);
|
||||
|
|
@ -274,9 +270,9 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
|
|||
{
|
||||
xics_kexec_teardown_cpu(secondary);
|
||||
|
||||
/* On OPAL v3, we return all CPUs to firmware */
|
||||
/* On OPAL, we return all CPUs to firmware */
|
||||
|
||||
if (!firmware_has_feature(FW_FEATURE_OPALv3))
|
||||
if (!firmware_has_feature(FW_FEATURE_OPAL))
|
||||
return;
|
||||
|
||||
if (secondary) {
|
||||
|
|
|
|||
|
|
@ -61,14 +61,15 @@ static int pnv_smp_kick_cpu(int nr)
|
|||
unsigned long start_here =
|
||||
__pa(ppc_function_entry(generic_secondary_smp_init));
|
||||
long rc;
|
||||
uint8_t status;
|
||||
|
||||
BUG_ON(nr < 0 || nr >= NR_CPUS);
|
||||
|
||||
/*
|
||||
* If we already started or OPALv2 is not supported, we just
|
||||
* If we already started or OPAL is not supported, we just
|
||||
* kick the CPU via the PACA
|
||||
*/
|
||||
if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2))
|
||||
if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPAL))
|
||||
goto kick;
|
||||
|
||||
/*
|
||||
|
|
@ -77,55 +78,42 @@ static int pnv_smp_kick_cpu(int nr)
|
|||
* first time. OPAL v3 allows us to query OPAL to know if it
|
||||
* has the CPUs, so we do that
|
||||
*/
|
||||
if (firmware_has_feature(FW_FEATURE_OPALv3)) {
|
||||
uint8_t status;
|
||||
rc = opal_query_cpu_status(pcpu, &status);
|
||||
if (rc != OPAL_SUCCESS) {
|
||||
pr_warn("OPAL Error %ld querying CPU %d state\n", rc, nr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = opal_query_cpu_status(pcpu, &status);
|
||||
/*
|
||||
* Already started, just kick it, probably coming from
|
||||
* kexec and spinning
|
||||
*/
|
||||
if (status == OPAL_THREAD_STARTED)
|
||||
goto kick;
|
||||
|
||||
/*
|
||||
* Available/inactive, let's kick it
|
||||
*/
|
||||
if (status == OPAL_THREAD_INACTIVE) {
|
||||
pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu);
|
||||
rc = opal_start_cpu(pcpu, start_here);
|
||||
if (rc != OPAL_SUCCESS) {
|
||||
pr_warn("OPAL Error %ld querying CPU %d state\n",
|
||||
rc, nr);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Already started, just kick it, probably coming from
|
||||
* kexec and spinning
|
||||
*/
|
||||
if (status == OPAL_THREAD_STARTED)
|
||||
goto kick;
|
||||
|
||||
/*
|
||||
* Available/inactive, let's kick it
|
||||
*/
|
||||
if (status == OPAL_THREAD_INACTIVE) {
|
||||
pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n",
|
||||
nr, pcpu);
|
||||
rc = opal_start_cpu(pcpu, start_here);
|
||||
if (rc != OPAL_SUCCESS) {
|
||||
pr_warn("OPAL Error %ld starting CPU %d\n",
|
||||
rc, nr);
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* An unavailable CPU (or any other unknown status)
|
||||
* shouldn't be started. It should also
|
||||
* not be in the possible map but currently it can
|
||||
* happen
|
||||
*/
|
||||
pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
|
||||
" (status %d)...\n", nr, pcpu, status);
|
||||
pr_warn("OPAL Error %ld starting CPU %d\n", rc, nr);
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* On OPAL v2, we just kick it and hope for the best,
|
||||
* we must not test the error from opal_start_cpu() or
|
||||
* we would fail to get CPUs from kexec.
|
||||
* An unavailable CPU (or any other unknown status)
|
||||
* shouldn't be started. It should also
|
||||
* not be in the possible map but currently it can
|
||||
* happen
|
||||
*/
|
||||
opal_start_cpu(pcpu, start_here);
|
||||
pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable"
|
||||
" (status %d)...\n", nr, pcpu, status);
|
||||
return -ENODEV;
|
||||
}
|
||||
kick:
|
||||
|
||||
kick:
|
||||
return smp_generic_kick_cpu(nr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ static inline u32 mpic_physmask(u32 cpumask)
|
|||
int i;
|
||||
u32 mask = 0;
|
||||
|
||||
for (i = 0; i < min(32, NR_CPUS); ++i, cpumask >>= 1)
|
||||
for (i = 0; i < min(32, NR_CPUS) && cpu_possible(i); ++i, cpumask >>= 1)
|
||||
mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
|
||||
return mask;
|
||||
}
|
||||
|
|
|
|||
108
arch/s390/include/asm/alternative-asm.h
Normal file
108
arch/s390/include/asm/alternative-asm.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_S390_ALTERNATIVE_ASM_H
|
||||
#define _ASM_S390_ALTERNATIVE_ASM_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Check the length of an instruction sequence. The length may not be larger
|
||||
* than 254 bytes and it has to be divisible by 2.
|
||||
*/
|
||||
.macro alt_len_check start,end
|
||||
.if ( \end - \start ) > 254
|
||||
.error "cpu alternatives does not support instructions blocks > 254 bytes\n"
|
||||
.endif
|
||||
.if ( \end - \start ) % 2
|
||||
.error "cpu alternatives instructions length is odd\n"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Issue one struct alt_instr descriptor entry (need to put it into
|
||||
* the section .altinstructions, see below). This entry contains
|
||||
* enough information for the alternatives patching code to patch an
|
||||
* instruction. See apply_alternatives().
|
||||
*/
|
||||
.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
|
||||
.long \orig_start - .
|
||||
.long \alt_start - .
|
||||
.word \feature
|
||||
.byte \orig_end - \orig_start
|
||||
.byte \alt_end - \alt_start
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Fill up @bytes with nops. The macro emits 6-byte nop instructions
|
||||
* for the bulk of the area, possibly followed by a 4-byte and/or
|
||||
* a 2-byte nop if the size of the area is not divisible by 6.
|
||||
*/
|
||||
.macro alt_pad_fill bytes
|
||||
.fill ( \bytes ) / 6, 6, 0xc0040000
|
||||
.fill ( \bytes ) % 6 / 4, 4, 0x47000000
|
||||
.fill ( \bytes ) % 6 % 4 / 2, 2, 0x0700
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Fill up @bytes with nops. If the number of bytes is larger
|
||||
* than 6, emit a jg instruction to branch over all nops, then
|
||||
* fill an area of size (@bytes - 6) with nop instructions.
|
||||
*/
|
||||
.macro alt_pad bytes
|
||||
.if ( \bytes > 0 )
|
||||
.if ( \bytes > 6 )
|
||||
jg . + \bytes
|
||||
alt_pad_fill \bytes - 6
|
||||
.else
|
||||
alt_pad_fill \bytes
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr. ".skip" directive takes care of proper instruction padding
|
||||
* in case @newinstr is longer than @oldinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE oldinstr, newinstr, feature
|
||||
.pushsection .altinstr_replacement,"ax"
|
||||
770: \newinstr
|
||||
771: .popsection
|
||||
772: \oldinstr
|
||||
773: alt_len_check 770b, 771b
|
||||
alt_len_check 772b, 773b
|
||||
alt_pad ( ( 771b - 770b ) - ( 773b - 772b ) )
|
||||
774: .pushsection .altinstructions,"a"
|
||||
alt_entry 772b, 774b, 770b, 771b, \feature
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr. ".skip" directive takes care of proper instruction padding
|
||||
* in case @newinstr is longer than @oldinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
|
||||
.pushsection .altinstr_replacement,"ax"
|
||||
770: \newinstr1
|
||||
771: \newinstr2
|
||||
772: .popsection
|
||||
773: \oldinstr
|
||||
774: alt_len_check 770b, 771b
|
||||
alt_len_check 771b, 772b
|
||||
alt_len_check 773b, 774b
|
||||
.if ( 771b - 770b > 772b - 771b )
|
||||
alt_pad ( ( 771b - 770b ) - ( 774b - 773b ) )
|
||||
.else
|
||||
alt_pad ( ( 772b - 771b ) - ( 774b - 773b ) )
|
||||
.endif
|
||||
775: .pushsection .altinstructions,"a"
|
||||
alt_entry 773b, 775b, 770b, 771b,\feature1
|
||||
alt_entry 773b, 775b, 771b, 772b,\feature2
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_S390_ALTERNATIVE_ASM_H */
|
||||
|
|
@ -21,17 +21,12 @@
|
|||
: "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
|
||||
"m" (*uaddr) : "cc");
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, newval, ret;
|
||||
|
||||
load_kernel_asce();
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
pagefault_disable();
|
||||
switch (op) {
|
||||
|
|
@ -60,17 +55,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
}
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
195
arch/s390/include/asm/nospec-insn.h
Normal file
195
arch/s390/include/asm/nospec-insn.h
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_S390_NOSPEC_ASM_H
|
||||
#define _ASM_S390_NOSPEC_ASM_H
|
||||
|
||||
#include <asm/alternative-asm.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_EXPOLINE
|
||||
|
||||
_LC_BR_R1 = __LC_BR_R1
|
||||
|
||||
/*
|
||||
* The expoline macros are used to create thunks in the same format
|
||||
* as gcc generates them. The 'comdat' section flag makes sure that
|
||||
* the various thunks are merged into a single copy.
|
||||
*/
|
||||
.macro __THUNK_PROLOG_NAME name
|
||||
.pushsection .text.\name,"axG",@progbits,\name,comdat
|
||||
.globl \name
|
||||
.hidden \name
|
||||
.type \name,@function
|
||||
\name:
|
||||
.cfi_startproc
|
||||
.endm
|
||||
|
||||
.macro __THUNK_EPILOG
|
||||
.cfi_endproc
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro __THUNK_PROLOG_BR r1,r2
|
||||
__THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
|
||||
.endm
|
||||
|
||||
.macro __THUNK_PROLOG_BC d0,r1,r2
|
||||
__THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1
|
||||
.endm
|
||||
|
||||
.macro __THUNK_BR r1,r2
|
||||
jg __s390x_indirect_jump_r\r2\()use_r\r1
|
||||
.endm
|
||||
|
||||
.macro __THUNK_BC d0,r1,r2
|
||||
jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1
|
||||
.endm
|
||||
|
||||
.macro __THUNK_BRASL r1,r2,r3
|
||||
brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2
|
||||
.endm
|
||||
|
||||
.macro __DECODE_RR expand,reg,ruse
|
||||
.set __decode_fail,1
|
||||
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \reg,%r\r1
|
||||
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \ruse,%r\r2
|
||||
\expand \r1,\r2
|
||||
.set __decode_fail,0
|
||||
.endif
|
||||
.endr
|
||||
.endif
|
||||
.endr
|
||||
.if __decode_fail == 1
|
||||
.error "__DECODE_RR failed"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro __DECODE_RRR expand,rsave,rtarget,ruse
|
||||
.set __decode_fail,1
|
||||
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \rsave,%r\r1
|
||||
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \rtarget,%r\r2
|
||||
.irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \ruse,%r\r3
|
||||
\expand \r1,\r2,\r3
|
||||
.set __decode_fail,0
|
||||
.endif
|
||||
.endr
|
||||
.endif
|
||||
.endr
|
||||
.endif
|
||||
.endr
|
||||
.if __decode_fail == 1
|
||||
.error "__DECODE_RRR failed"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro __DECODE_DRR expand,disp,reg,ruse
|
||||
.set __decode_fail,1
|
||||
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \reg,%r\r1
|
||||
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
.ifc \ruse,%r\r2
|
||||
\expand \disp,\r1,\r2
|
||||
.set __decode_fail,0
|
||||
.endif
|
||||
.endr
|
||||
.endif
|
||||
.endr
|
||||
.if __decode_fail == 1
|
||||
.error "__DECODE_DRR failed"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro __THUNK_EX_BR reg,ruse
|
||||
# Be very careful when adding instructions to this macro!
|
||||
# The ALTERNATIVE replacement code has a .+10 which targets
|
||||
# the "br \reg" after the code has been patched.
|
||||
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
||||
exrl 0,555f
|
||||
j .
|
||||
#else
|
||||
.ifc \reg,%r1
|
||||
ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
|
||||
j .
|
||||
.else
|
||||
larl \ruse,555f
|
||||
ex 0,0(\ruse)
|
||||
j .
|
||||
.endif
|
||||
#endif
|
||||
555: br \reg
|
||||
.endm
|
||||
|
||||
.macro __THUNK_EX_BC disp,reg,ruse
|
||||
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
||||
exrl 0,556f
|
||||
j .
|
||||
#else
|
||||
larl \ruse,556f
|
||||
ex 0,0(\ruse)
|
||||
j .
|
||||
#endif
|
||||
556: b \disp(\reg)
|
||||
.endm
|
||||
|
||||
.macro GEN_BR_THUNK reg,ruse=%r1
|
||||
__DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
|
||||
__THUNK_EX_BR \reg,\ruse
|
||||
__THUNK_EPILOG
|
||||
.endm
|
||||
|
||||
.macro GEN_B_THUNK disp,reg,ruse=%r1
|
||||
__DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse
|
||||
__THUNK_EX_BC \disp,\reg,\ruse
|
||||
__THUNK_EPILOG
|
||||
.endm
|
||||
|
||||
.macro BR_EX reg,ruse=%r1
|
||||
557: __DECODE_RR __THUNK_BR,\reg,\ruse
|
||||
.pushsection .s390_indirect_branches,"a",@progbits
|
||||
.long 557b-.
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro B_EX disp,reg,ruse=%r1
|
||||
558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse
|
||||
.pushsection .s390_indirect_branches,"a",@progbits
|
||||
.long 558b-.
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro BASR_EX rsave,rtarget,ruse=%r1
|
||||
559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
|
||||
.pushsection .s390_indirect_branches,"a",@progbits
|
||||
.long 559b-.
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
#else
|
||||
.macro GEN_BR_THUNK reg,ruse=%r1
|
||||
.endm
|
||||
|
||||
.macro GEN_B_THUNK disp,reg,ruse=%r1
|
||||
.endm
|
||||
|
||||
.macro BR_EX reg,ruse=%r1
|
||||
br \reg
|
||||
.endm
|
||||
|
||||
.macro B_EX disp,reg,ruse=%r1
|
||||
b \disp(\reg)
|
||||
.endm
|
||||
|
||||
.macro BASR_EX rsave,rtarget,ruse=%r1
|
||||
basr \rsave,\rtarget
|
||||
.endm
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_S390_NOSPEC_ASM_H */
|
||||
|
|
@ -49,6 +49,7 @@ obj-y += nospec-branch.o
|
|||
|
||||
extra-y += head.o head64.o vmlinux.lds
|
||||
|
||||
obj-$(CONFIG_SYSFS) += nospec-sysfs.o
|
||||
CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE)
|
||||
|
||||
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ int main(void)
|
|||
OFFSET(__LC_MACHINE_FLAGS, _lowcore, machine_flags);
|
||||
OFFSET(__LC_GMAP, _lowcore, gmap);
|
||||
OFFSET(__LC_PASTE, _lowcore, paste);
|
||||
OFFSET(__LC_BR_R1, _lowcore, br_r1_trampoline);
|
||||
/* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
|
||||
OFFSET(__LC_DUMP_REIPL, _lowcore, ipib);
|
||||
/* hardware defined lowcore locations 0x1000 - 0x18ff */
|
||||
|
|
|
|||
|
|
@ -8,18 +8,22 @@
|
|||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/sigp.h>
|
||||
|
||||
GEN_BR_THUNK %r9
|
||||
GEN_BR_THUNK %r14
|
||||
|
||||
ENTRY(s390_base_mcck_handler)
|
||||
basr %r13,0
|
||||
0: lg %r15,__LC_PANIC_STACK # load panic stack
|
||||
aghi %r15,-STACK_FRAME_OVERHEAD
|
||||
larl %r1,s390_base_mcck_handler_fn
|
||||
lg %r1,0(%r1)
|
||||
ltgr %r1,%r1
|
||||
lg %r9,0(%r1)
|
||||
ltgr %r9,%r9
|
||||
jz 1f
|
||||
basr %r14,%r1
|
||||
BASR_EX %r14,%r9
|
||||
1: la %r1,4095
|
||||
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
|
||||
lpswe __LC_MCK_OLD_PSW
|
||||
|
|
@ -36,10 +40,10 @@ ENTRY(s390_base_ext_handler)
|
|||
basr %r13,0
|
||||
0: aghi %r15,-STACK_FRAME_OVERHEAD
|
||||
larl %r1,s390_base_ext_handler_fn
|
||||
lg %r1,0(%r1)
|
||||
ltgr %r1,%r1
|
||||
lg %r9,0(%r1)
|
||||
ltgr %r9,%r9
|
||||
jz 1f
|
||||
basr %r14,%r1
|
||||
BASR_EX %r14,%r9
|
||||
1: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC
|
||||
ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
|
||||
lpswe __LC_EXT_OLD_PSW
|
||||
|
|
@ -56,10 +60,10 @@ ENTRY(s390_base_pgm_handler)
|
|||
basr %r13,0
|
||||
0: aghi %r15,-STACK_FRAME_OVERHEAD
|
||||
larl %r1,s390_base_pgm_handler_fn
|
||||
lg %r1,0(%r1)
|
||||
ltgr %r1,%r1
|
||||
lg %r9,0(%r1)
|
||||
ltgr %r9,%r9
|
||||
jz 1f
|
||||
basr %r14,%r1
|
||||
BASR_EX %r14,%r9
|
||||
lmg %r0,%r15,__LC_SAVE_AREA_SYNC
|
||||
lpswe __LC_PGM_OLD_PSW
|
||||
1: lpswe disabled_wait_psw-0b(%r13)
|
||||
|
|
@ -116,7 +120,7 @@ ENTRY(diag308_reset)
|
|||
larl %r4,.Lcontinue_psw # Restore PSW flags
|
||||
lpswe 0(%r4)
|
||||
.Lcontinue:
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
.align 16
|
||||
.Lrestart_psw:
|
||||
.long 0x00080000,0x80000000 + .Lrestart_part2
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <asm/vx-insn.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
|
||||
__PT_R0 = __PT_GPRS
|
||||
__PT_R1 = __PT_GPRS + 8
|
||||
|
|
@ -225,74 +226,16 @@ _PIF_WORK = (_PIF_PER_TRAP)
|
|||
.popsection
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_EXPOLINE
|
||||
|
||||
.macro GEN_BR_THUNK name,reg,tmp
|
||||
.section .text.\name,"axG",@progbits,\name,comdat
|
||||
.globl \name
|
||||
.hidden \name
|
||||
.type \name,@function
|
||||
\name:
|
||||
.cfi_startproc
|
||||
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
||||
exrl 0,0f
|
||||
#else
|
||||
larl \tmp,0f
|
||||
ex 0,0(\tmp)
|
||||
#endif
|
||||
j .
|
||||
0: br \reg
|
||||
.cfi_endproc
|
||||
.endm
|
||||
|
||||
GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
|
||||
GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1
|
||||
GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11
|
||||
|
||||
.macro BASR_R14_R9
|
||||
0: brasl %r14,__s390x_indirect_jump_r1use_r9
|
||||
.pushsection .s390_indirect_branches,"a",@progbits
|
||||
.long 0b-.
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro BR_R1USE_R14
|
||||
0: jg __s390x_indirect_jump_r1use_r14
|
||||
.pushsection .s390_indirect_branches,"a",@progbits
|
||||
.long 0b-.
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro BR_R11USE_R14
|
||||
0: jg __s390x_indirect_jump_r11use_r14
|
||||
.pushsection .s390_indirect_branches,"a",@progbits
|
||||
.long 0b-.
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
#else /* CONFIG_EXPOLINE */
|
||||
|
||||
.macro BASR_R14_R9
|
||||
basr %r14,%r9
|
||||
.endm
|
||||
|
||||
.macro BR_R1USE_R14
|
||||
br %r14
|
||||
.endm
|
||||
|
||||
.macro BR_R11USE_R14
|
||||
br %r14
|
||||
.endm
|
||||
|
||||
#endif /* CONFIG_EXPOLINE */
|
||||
|
||||
GEN_BR_THUNK %r9
|
||||
GEN_BR_THUNK %r14
|
||||
GEN_BR_THUNK %r14,%r11
|
||||
|
||||
.section .kprobes.text, "ax"
|
||||
|
||||
ENTRY(__bpon)
|
||||
.globl __bpon
|
||||
BPON
|
||||
BR_R1USE_R14
|
||||
BR_EX %r14
|
||||
|
||||
/*
|
||||
* Scheduler resume function, called by switch_to
|
||||
|
|
@ -322,7 +265,7 @@ ENTRY(__switch_to)
|
|||
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
|
||||
jz 0f
|
||||
.insn s,0xb2800000,__LC_LPP # set program parameter
|
||||
0: BR_R1USE_R14
|
||||
0: BR_EX %r14
|
||||
|
||||
.L__critical_start:
|
||||
|
||||
|
|
@ -388,7 +331,7 @@ sie_exit:
|
|||
xgr %r5,%r5
|
||||
lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
|
||||
lg %r2,__SF_EMPTY+16(%r15) # return exit reason code
|
||||
BR_R1USE_R14
|
||||
BR_EX %r14
|
||||
.Lsie_fault:
|
||||
lghi %r14,-EFAULT
|
||||
stg %r14,__SF_EMPTY+16(%r15) # set exit reason code
|
||||
|
|
@ -445,7 +388,7 @@ ENTRY(system_call)
|
|||
lgf %r9,0(%r8,%r10) # get system call add.
|
||||
TSTMSK __TI_flags(%r12),_TIF_TRACE
|
||||
jnz .Lsysc_tracesys
|
||||
BASR_R14_R9 # call sys_xxxx
|
||||
BASR_EX %r14,%r9 # call sys_xxxx
|
||||
stg %r2,__PT_R2(%r11) # store return value
|
||||
|
||||
.Lsysc_return:
|
||||
|
|
@ -585,7 +528,7 @@ ENTRY(system_call)
|
|||
lmg %r3,%r7,__PT_R3(%r11)
|
||||
stg %r7,STACK_FRAME_OVERHEAD(%r15)
|
||||
lg %r2,__PT_ORIG_GPR2(%r11)
|
||||
BASR_R14_R9 # call sys_xxx
|
||||
BASR_EX %r14,%r9 # call sys_xxx
|
||||
stg %r2,__PT_R2(%r11) # store return value
|
||||
.Lsysc_tracenogo:
|
||||
TSTMSK __TI_flags(%r12),_TIF_TRACE
|
||||
|
|
@ -609,7 +552,7 @@ ENTRY(ret_from_fork)
|
|||
lmg %r9,%r10,__PT_R9(%r11) # load gprs
|
||||
ENTRY(kernel_thread_starter)
|
||||
la %r2,0(%r10)
|
||||
BASR_R14_R9
|
||||
BASR_EX %r14,%r9
|
||||
j .Lsysc_tracenogo
|
||||
|
||||
/*
|
||||
|
|
@ -685,7 +628,7 @@ ENTRY(pgm_check_handler)
|
|||
je .Lpgm_return
|
||||
lgf %r9,0(%r10,%r1) # load address of handler routine
|
||||
lgr %r2,%r11 # pass pointer to pt_regs
|
||||
BASR_R14_R9 # branch to interrupt-handler
|
||||
BASR_EX %r14,%r9 # branch to interrupt-handler
|
||||
.Lpgm_return:
|
||||
LOCKDEP_SYS_EXIT
|
||||
tm __PT_PSW+1(%r11),0x01 # returning to user ?
|
||||
|
|
@ -962,7 +905,7 @@ ENTRY(psw_idle)
|
|||
stpt __TIMER_IDLE_ENTER(%r2)
|
||||
.Lpsw_idle_lpsw:
|
||||
lpswe __SF_EMPTY(%r15)
|
||||
BR_R1USE_R14
|
||||
BR_EX %r14
|
||||
.Lpsw_idle_end:
|
||||
|
||||
/*
|
||||
|
|
@ -1007,7 +950,7 @@ ENTRY(save_fpu_regs)
|
|||
.Lsave_fpu_regs_done:
|
||||
oi __LC_CPU_FLAGS+7,_CIF_FPU
|
||||
.Lsave_fpu_regs_exit:
|
||||
BR_R1USE_R14
|
||||
BR_EX %r14
|
||||
.Lsave_fpu_regs_end:
|
||||
|
||||
/*
|
||||
|
|
@ -1054,7 +997,7 @@ load_fpu_regs:
|
|||
.Lload_fpu_regs_done:
|
||||
ni __LC_CPU_FLAGS+7,255-_CIF_FPU
|
||||
.Lload_fpu_regs_exit:
|
||||
BR_R1USE_R14
|
||||
BR_EX %r14
|
||||
.Lload_fpu_regs_end:
|
||||
|
||||
.L__critical_end:
|
||||
|
|
@ -1227,7 +1170,7 @@ cleanup_critical:
|
|||
jl 0f
|
||||
clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end
|
||||
jl .Lcleanup_load_fpu_regs
|
||||
0: BR_R11USE_R14
|
||||
0: BR_EX %r14
|
||||
|
||||
.align 8
|
||||
.Lcleanup_table:
|
||||
|
|
@ -1257,7 +1200,7 @@ cleanup_critical:
|
|||
ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
|
||||
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
|
||||
larl %r9,sie_exit # skip forward to sie_exit
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14
|
||||
#endif
|
||||
|
||||
.Lcleanup_system_call:
|
||||
|
|
@ -1315,7 +1258,7 @@ cleanup_critical:
|
|||
stg %r15,56(%r11) # r15 stack pointer
|
||||
# set new psw address and exit
|
||||
larl %r9,.Lsysc_do_svc
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
.Lcleanup_system_call_insn:
|
||||
.quad system_call
|
||||
.quad .Lsysc_stmg
|
||||
|
|
@ -1325,7 +1268,7 @@ cleanup_critical:
|
|||
|
||||
.Lcleanup_sysc_tif:
|
||||
larl %r9,.Lsysc_tif
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
|
||||
.Lcleanup_sysc_restore:
|
||||
# check if stpt has been executed
|
||||
|
|
@ -1342,14 +1285,14 @@ cleanup_critical:
|
|||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
.Lcleanup_sysc_restore_insn:
|
||||
.quad .Lsysc_exit_timer
|
||||
.quad .Lsysc_done - 4
|
||||
|
||||
.Lcleanup_io_tif:
|
||||
larl %r9,.Lio_tif
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
|
||||
.Lcleanup_io_restore:
|
||||
# check if stpt has been executed
|
||||
|
|
@ -1363,7 +1306,7 @@ cleanup_critical:
|
|||
mvc 0(64,%r11),__PT_R8(%r9)
|
||||
lmg %r0,%r7,__PT_R0(%r9)
|
||||
1: lmg %r8,%r9,__LC_RETURN_PSW
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
.Lcleanup_io_restore_insn:
|
||||
.quad .Lio_exit_timer
|
||||
.quad .Lio_done - 4
|
||||
|
|
@ -1415,17 +1358,17 @@ cleanup_critical:
|
|||
# prepare return psw
|
||||
nihh %r8,0xfcfd # clear irq & wait state bits
|
||||
lg %r9,48(%r11) # return from psw_idle
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
.Lcleanup_idle_insn:
|
||||
.quad .Lpsw_idle_lpsw
|
||||
|
||||
.Lcleanup_save_fpu_regs:
|
||||
larl %r9,save_fpu_regs
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
|
||||
.Lcleanup_load_fpu_regs:
|
||||
larl %r9,load_fpu_regs
|
||||
BR_R11USE_R14
|
||||
BR_EX %r14,%r11
|
||||
|
||||
/*
|
||||
* Integer constants
|
||||
|
|
|
|||
|
|
@ -173,10 +173,9 @@ void do_softirq_own_stack(void)
|
|||
new -= STACK_FRAME_OVERHEAD;
|
||||
((struct stack_frame *) new)->back_chain = old;
|
||||
asm volatile(" la 15,0(%0)\n"
|
||||
" basr 14,%2\n"
|
||||
" brasl 14,__do_softirq\n"
|
||||
" la 15,0(%1)\n"
|
||||
: : "a" (new), "a" (old),
|
||||
"a" (__do_softirq)
|
||||
: : "a" (new), "a" (old)
|
||||
: "0", "1", "2", "3", "4", "5", "14",
|
||||
"cc", "memory" );
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,12 +8,16 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
GEN_BR_THUNK %r1
|
||||
GEN_BR_THUNK %r14
|
||||
|
||||
.section .kprobes.text, "ax"
|
||||
|
||||
ENTRY(ftrace_stub)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
|
||||
#define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE)
|
||||
#define STACK_PTREGS (STACK_FRAME_OVERHEAD)
|
||||
|
|
@ -21,7 +25,7 @@ ENTRY(ftrace_stub)
|
|||
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
|
||||
|
||||
ENTRY(_mcount)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
|
||||
ENTRY(ftrace_caller)
|
||||
.globl ftrace_regs_caller
|
||||
|
|
@ -49,7 +53,7 @@ ENTRY(ftrace_caller)
|
|||
#endif
|
||||
lgr %r3,%r14
|
||||
la %r5,STACK_PTREGS(%r15)
|
||||
basr %r14,%r1
|
||||
BASR_EX %r14,%r1
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
# The j instruction gets runtime patched to a nop instruction.
|
||||
# See ftrace_enable_ftrace_graph_caller.
|
||||
|
|
@ -64,7 +68,7 @@ ftrace_graph_caller_end:
|
|||
#endif
|
||||
lg %r1,(STACK_PTREGS_PSW+8)(%r15)
|
||||
lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15)
|
||||
br %r1
|
||||
BR_EX %r1
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
|
|
@ -77,6 +81,6 @@ ENTRY(return_to_handler)
|
|||
aghi %r15,STACK_FRAME_OVERHEAD
|
||||
lgr %r14,%r2
|
||||
lmg %r2,%r5,32(%r15)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,24 +44,6 @@ static int __init nospec_report(void)
|
|||
}
|
||||
arch_initcall(nospec_report);
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
ssize_t cpu_show_spectre_v1(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v2(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
|
||||
return sprintf(buf, "Mitigation: execute trampolines\n");
|
||||
if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
|
||||
return sprintf(buf, "Mitigation: limited branch prediction.\n");
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXPOLINE
|
||||
|
||||
int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
|
||||
|
|
@ -112,7 +94,6 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
|
|||
s32 *epo;
|
||||
|
||||
/* Second part of the instruction replace is always a nop */
|
||||
memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4);
|
||||
for (epo = start; epo < end; epo++) {
|
||||
instr = (u8 *) epo + *epo;
|
||||
if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04)
|
||||
|
|
@ -133,18 +114,34 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
|
|||
br = thunk + (*(int *)(thunk + 2)) * 2;
|
||||
else
|
||||
continue;
|
||||
if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0)
|
||||
/* Check for unconditional branch 0x07f? or 0x47f???? */
|
||||
if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0)
|
||||
continue;
|
||||
|
||||
memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4);
|
||||
switch (type) {
|
||||
case BRCL_EXPOLINE:
|
||||
/* brcl to thunk, replace with br + nop */
|
||||
insnbuf[0] = br[0];
|
||||
insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
|
||||
if (br[0] == 0x47) {
|
||||
/* brcl to b, replace with bc + nopr */
|
||||
insnbuf[2] = br[2];
|
||||
insnbuf[3] = br[3];
|
||||
} else {
|
||||
/* brcl to br, replace with bcr + nop */
|
||||
}
|
||||
break;
|
||||
case BRASL_EXPOLINE:
|
||||
/* brasl to thunk, replace with basr + nop */
|
||||
insnbuf[0] = 0x0d;
|
||||
insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
|
||||
if (br[0] == 0x47) {
|
||||
/* brasl to b, replace with bas + nopr */
|
||||
insnbuf[0] = 0x4d;
|
||||
insnbuf[2] = br[2];
|
||||
insnbuf[3] = br[3];
|
||||
} else {
|
||||
/* brasl to br, replace with basr + nop */
|
||||
insnbuf[0] = 0x0d;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
21
arch/s390/kernel/nospec-sysfs.c
Normal file
21
arch/s390/kernel/nospec-sysfs.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/device.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <asm/facility.h>
|
||||
#include <asm/nospec-branch.h>
|
||||
|
||||
ssize_t cpu_show_spectre_v1(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "Mitigation: __user pointer sanitization\n");
|
||||
}
|
||||
|
||||
ssize_t cpu_show_spectre_v2(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
|
||||
return sprintf(buf, "Mitigation: execute trampolines\n");
|
||||
if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
|
||||
return sprintf(buf, "Mitigation: limited branch prediction\n");
|
||||
return sprintf(buf, "Vulnerable\n");
|
||||
}
|
||||
|
|
@ -744,6 +744,10 @@ static int __hw_perf_event_init(struct perf_event *event)
|
|||
*/
|
||||
rate = 0;
|
||||
if (attr->freq) {
|
||||
if (!attr->sample_freq) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
rate = freq_to_sample_rate(&si, attr->sample_freq);
|
||||
rate = hw_limit_rate(&si, rate);
|
||||
attr->freq = 0;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,11 @@
|
|||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
#include <asm/sigp.h>
|
||||
|
||||
GEN_BR_THUNK %r14
|
||||
|
||||
#
|
||||
# store_status
|
||||
#
|
||||
|
|
@ -62,7 +65,7 @@ ENTRY(store_status)
|
|||
st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1)
|
||||
larl %r2,store_status
|
||||
stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
|
||||
.section .bss
|
||||
.align 8
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <asm/ptrace.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
#include <asm/sigp.h>
|
||||
|
||||
/*
|
||||
|
|
@ -23,6 +24,8 @@
|
|||
* (see below) in the resume process.
|
||||
* This function runs with disabled interrupts.
|
||||
*/
|
||||
GEN_BR_THUNK %r14
|
||||
|
||||
.section .text
|
||||
ENTRY(swsusp_arch_suspend)
|
||||
stmg %r6,%r15,__SF_GPRS(%r15)
|
||||
|
|
@ -102,7 +105,7 @@ ENTRY(swsusp_arch_suspend)
|
|||
spx 0x318(%r1)
|
||||
lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
|
||||
lghi %r2,0
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
|
||||
/*
|
||||
* Restore saved memory image to correct place and restore register context.
|
||||
|
|
@ -196,11 +199,10 @@ pgm_check_entry:
|
|||
larl %r15,init_thread_union
|
||||
ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER)
|
||||
larl %r2,.Lpanic_string
|
||||
larl %r3,_sclp_print_early
|
||||
lghi %r1,0
|
||||
sam31
|
||||
sigp %r1,%r0,SIGP_SET_ARCHITECTURE
|
||||
basr %r14,%r3
|
||||
brasl %r14,_sclp_print_early
|
||||
larl %r3,.Ldisabled_wait_31
|
||||
lpsw 0(%r3)
|
||||
4:
|
||||
|
|
@ -266,7 +268,7 @@ restore_registers:
|
|||
/* Return 0 */
|
||||
lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
|
||||
lghi %r2,0
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
|
||||
.section .data..nosave,"aw",@progbits
|
||||
.align 8
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
|
||||
GEN_BR_THUNK %r14
|
||||
|
||||
/*
|
||||
* memset implementation
|
||||
|
|
@ -38,7 +41,7 @@ ENTRY(memset)
|
|||
.Lmemset_clear_rest:
|
||||
larl %r3,.Lmemset_xc
|
||||
ex %r4,0(%r3)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
.Lmemset_fill:
|
||||
stc %r3,0(%r2)
|
||||
cghi %r4,1
|
||||
|
|
@ -55,7 +58,7 @@ ENTRY(memset)
|
|||
.Lmemset_fill_rest:
|
||||
larl %r3,.Lmemset_mvc
|
||||
ex %r4,0(%r3)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
.Lmemset_xc:
|
||||
xc 0(1,%r1),0(%r1)
|
||||
.Lmemset_mvc:
|
||||
|
|
@ -77,7 +80,7 @@ ENTRY(memcpy)
|
|||
.Lmemcpy_rest:
|
||||
larl %r5,.Lmemcpy_mvc
|
||||
ex %r4,0(%r5)
|
||||
br %r14
|
||||
BR_EX %r14
|
||||
.Lmemcpy_loop:
|
||||
mvc 0(256,%r1),0(%r3)
|
||||
la %r1,256(%r1)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/nospec-insn.h>
|
||||
#include "bpf_jit.h"
|
||||
|
||||
/*
|
||||
|
|
@ -53,7 +54,7 @@ ENTRY(sk_load_##NAME##_pos); \
|
|||
clg %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */ \
|
||||
jh sk_load_##NAME##_slow; \
|
||||
LOAD %r14,-SIZE(%r3,%r12); /* Get data from skb */ \
|
||||
b OFF_OK(%r6); /* Return */ \
|
||||
B_EX OFF_OK,%r6; /* Return */ \
|
||||
\
|
||||
sk_load_##NAME##_slow:; \
|
||||
lgr %r2,%r7; /* Arg1 = skb pointer */ \
|
||||
|
|
@ -63,11 +64,14 @@ sk_load_##NAME##_slow:; \
|
|||
brasl %r14,skb_copy_bits; /* Get data from skb */ \
|
||||
LOAD %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */ \
|
||||
ltgr %r2,%r2; /* Set cc to (%r2 != 0) */ \
|
||||
br %r6; /* Return */
|
||||
BR_EX %r6; /* Return */
|
||||
|
||||
sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */
|
||||
sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */
|
||||
|
||||
GEN_BR_THUNK %r6
|
||||
GEN_B_THUNK OFF_OK,%r6
|
||||
|
||||
/*
|
||||
* Load 1 byte from SKB (optimized version)
|
||||
*/
|
||||
|
|
@ -79,7 +83,7 @@ ENTRY(sk_load_byte_pos)
|
|||
clg %r3,STK_OFF_HLEN(%r15) # Offset >= hlen?
|
||||
jnl sk_load_byte_slow
|
||||
llgc %r14,0(%r3,%r12) # Get byte from skb
|
||||
b OFF_OK(%r6) # Return OK
|
||||
B_EX OFF_OK,%r6 # Return OK
|
||||
|
||||
sk_load_byte_slow:
|
||||
lgr %r2,%r7 # Arg1 = skb pointer
|
||||
|
|
@ -89,7 +93,7 @@ sk_load_byte_slow:
|
|||
brasl %r14,skb_copy_bits # Get data from skb
|
||||
llgc %r14,STK_OFF_TMP(%r15) # Load result from temp buffer
|
||||
ltgr %r2,%r2 # Set cc to (%r2 != 0)
|
||||
br %r6 # Return cc
|
||||
BR_EX %r6 # Return cc
|
||||
|
||||
#define sk_negative_common(NAME, SIZE, LOAD) \
|
||||
sk_load_##NAME##_slow_neg:; \
|
||||
|
|
@ -103,7 +107,7 @@ sk_load_##NAME##_slow_neg:; \
|
|||
jz bpf_error; \
|
||||
LOAD %r14,0(%r2); /* Get data from pointer */ \
|
||||
xr %r3,%r3; /* Set cc to zero */ \
|
||||
br %r6; /* Return cc */
|
||||
BR_EX %r6; /* Return cc */
|
||||
|
||||
sk_negative_common(word, 4, llgf)
|
||||
sk_negative_common(half, 2, llgh)
|
||||
|
|
@ -112,4 +116,4 @@ sk_negative_common(byte, 1, llgc)
|
|||
bpf_error:
|
||||
# force a return 0 from jit handler
|
||||
ltgr %r15,%r15 # Set condition code
|
||||
br %r6
|
||||
BR_EX %r6
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include <linux/bpf.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/dis.h>
|
||||
#include <asm/facility.h>
|
||||
#include <asm/nospec-branch.h>
|
||||
#include "bpf_jit.h"
|
||||
|
||||
int bpf_jit_enable __read_mostly;
|
||||
|
|
@ -41,6 +43,8 @@ struct bpf_jit {
|
|||
int base_ip; /* Base address for literal pool */
|
||||
int ret0_ip; /* Address of return 0 */
|
||||
int exit_ip; /* Address of exit */
|
||||
int r1_thunk_ip; /* Address of expoline thunk for 'br %r1' */
|
||||
int r14_thunk_ip; /* Address of expoline thunk for 'br %r14' */
|
||||
int tail_call_start; /* Tail call start offset */
|
||||
int labels[1]; /* Labels for local jumps */
|
||||
};
|
||||
|
|
@ -248,6 +252,19 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
|
|||
REG_SET_SEEN(b2); \
|
||||
})
|
||||
|
||||
#define EMIT6_PCREL_RILB(op, b, target) \
|
||||
({ \
|
||||
int rel = (target - jit->prg) / 2; \
|
||||
_EMIT6(op | reg_high(b) << 16 | rel >> 16, rel & 0xffff); \
|
||||
REG_SET_SEEN(b); \
|
||||
})
|
||||
|
||||
#define EMIT6_PCREL_RIL(op, target) \
|
||||
({ \
|
||||
int rel = (target - jit->prg) / 2; \
|
||||
_EMIT6(op | rel >> 16, rel & 0xffff); \
|
||||
})
|
||||
|
||||
#define _EMIT6_IMM(op, imm) \
|
||||
({ \
|
||||
unsigned int __imm = (imm); \
|
||||
|
|
@ -475,8 +492,45 @@ static void bpf_jit_epilogue(struct bpf_jit *jit)
|
|||
EMIT4(0xb9040000, REG_2, BPF_REG_0);
|
||||
/* Restore registers */
|
||||
save_restore_regs(jit, REGS_RESTORE);
|
||||
if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) {
|
||||
jit->r14_thunk_ip = jit->prg;
|
||||
/* Generate __s390_indirect_jump_r14 thunk */
|
||||
if (test_facility(35)) {
|
||||
/* exrl %r0,.+10 */
|
||||
EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10);
|
||||
} else {
|
||||
/* larl %r1,.+14 */
|
||||
EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
|
||||
/* ex 0,0(%r1) */
|
||||
EMIT4_DISP(0x44000000, REG_0, REG_1, 0);
|
||||
}
|
||||
/* j . */
|
||||
EMIT4_PCREL(0xa7f40000, 0);
|
||||
}
|
||||
/* br %r14 */
|
||||
_EMIT2(0x07fe);
|
||||
|
||||
if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable &&
|
||||
(jit->seen & SEEN_FUNC)) {
|
||||
jit->r1_thunk_ip = jit->prg;
|
||||
/* Generate __s390_indirect_jump_r1 thunk */
|
||||
if (test_facility(35)) {
|
||||
/* exrl %r0,.+10 */
|
||||
EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10);
|
||||
/* j . */
|
||||
EMIT4_PCREL(0xa7f40000, 0);
|
||||
/* br %r1 */
|
||||
_EMIT2(0x07f1);
|
||||
} else {
|
||||
/* larl %r1,.+14 */
|
||||
EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
|
||||
/* ex 0,S390_lowcore.br_r1_tampoline */
|
||||
EMIT4_DISP(0x44000000, REG_0, REG_0,
|
||||
offsetof(struct _lowcore, br_r1_trampoline));
|
||||
/* j . */
|
||||
EMIT4_PCREL(0xa7f40000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -980,8 +1034,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
/* lg %w1,<d(imm)>(%l) */
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L,
|
||||
EMIT_CONST_U64(func));
|
||||
/* basr %r14,%w1 */
|
||||
EMIT2(0x0d00, REG_14, REG_W1);
|
||||
if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) {
|
||||
/* brasl %r14,__s390_indirect_jump_r1 */
|
||||
EMIT6_PCREL_RILB(0xc0050000, REG_14, jit->r1_thunk_ip);
|
||||
} else {
|
||||
/* basr %r14,%w1 */
|
||||
EMIT2(0x0d00, REG_14, REG_W1);
|
||||
}
|
||||
/* lgr %b0,%r2: load return value into %b0 */
|
||||
EMIT4(0xb9040000, BPF_REG_0, REG_2);
|
||||
if (bpf_helper_changes_skb_data((void *)func)) {
|
||||
|
|
|
|||
|
|
@ -10,20 +10,11 @@
|
|||
/* XXX: UP variants, fix for SH-4A and SMP.. */
|
||||
#include <asm/futex-irq.h>
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -49,17 +40,8 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ debug_trap:
|
|||
mov.l @r8, r8
|
||||
jsr @r8
|
||||
nop
|
||||
bra __restore_all
|
||||
bra ret_from_exception
|
||||
nop
|
||||
CFI_ENDPROC
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,11 @@ ATOMIC_OP(xor)
|
|||
#define atomic64_add_negative(i, v) (atomic64_add_return(i, v) < 0)
|
||||
|
||||
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
static inline int atomic_xchg(atomic_t *v, int new)
|
||||
{
|
||||
return xchg(&v->counter, new);
|
||||
}
|
||||
|
||||
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,22 +29,14 @@
|
|||
: "r" (uaddr), "r" (oparg), "i" (-EFAULT) \
|
||||
: "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tem;
|
||||
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))))
|
||||
return -EFAULT;
|
||||
if (unlikely((((unsigned long) uaddr) & 0x3UL)))
|
||||
return -EINVAL;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -69,17 +61,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
|
||||
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
|
||||
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
|
||||
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
|
||||
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
|
||||
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
|
||||
default: ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,12 +106,9 @@
|
|||
lock = __atomic_hashed_lock((int __force *)uaddr)
|
||||
#endif
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int uninitialized_var(val), ret;
|
||||
|
||||
__futex_prolog();
|
||||
|
|
@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
/* The 32-bit futex code makes this assumption, so validate it here. */
|
||||
BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
|
|
@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
}
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (val == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (val != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (val < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (val >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (val <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (val > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = val;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -364,7 +364,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
|
|||
if (status != EFI_SUCCESS)
|
||||
goto free_struct;
|
||||
|
||||
memcpy(rom->romdata, pci->romimage, pci->romsize);
|
||||
memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
|
||||
pci->romsize);
|
||||
return status;
|
||||
|
||||
free_struct:
|
||||
|
|
@ -470,7 +471,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
|
|||
if (status != EFI_SUCCESS)
|
||||
goto free_struct;
|
||||
|
||||
memcpy(rom->romdata, pci->romimage, pci->romsize);
|
||||
memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
|
||||
pci->romsize);
|
||||
return status;
|
||||
|
||||
free_struct:
|
||||
|
|
|
|||
|
|
@ -41,20 +41,11 @@
|
|||
"+m" (*uaddr), "=&r" (tem) \
|
||||
: "r" (oparg), "i" (-EFAULT), "1" (0))
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret, tem;
|
||||
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -80,30 +71,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (!ret) {
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1368,7 +1368,7 @@ void setup_local_APIC(void)
|
|||
* TODO: set up through-local-APIC from through-I/O-APIC? --macro
|
||||
*/
|
||||
value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
|
||||
if (!cpu && (pic_mode || !value)) {
|
||||
if (!cpu && (pic_mode || !value || skip_ioapic_setup)) {
|
||||
value = APIC_DM_EXTINT;
|
||||
apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/of_pci.h>
|
||||
|
|
@ -199,19 +200,22 @@ static struct of_ioapic_type of_ioapic_type[] =
|
|||
static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
unsigned int nr_irqs, void *arg)
|
||||
{
|
||||
struct of_phandle_args *irq_data = (void *)arg;
|
||||
struct irq_fwspec *fwspec = (struct irq_fwspec *)arg;
|
||||
struct of_ioapic_type *it;
|
||||
struct irq_alloc_info tmp;
|
||||
int type_index;
|
||||
|
||||
if (WARN_ON(irq_data->args_count < 2))
|
||||
return -EINVAL;
|
||||
if (irq_data->args[1] >= ARRAY_SIZE(of_ioapic_type))
|
||||
if (WARN_ON(fwspec->param_count < 2))
|
||||
return -EINVAL;
|
||||
|
||||
it = &of_ioapic_type[irq_data->args[1]];
|
||||
type_index = fwspec->param[1];
|
||||
if (type_index >= ARRAY_SIZE(of_ioapic_type))
|
||||
return -EINVAL;
|
||||
|
||||
it = &of_ioapic_type[type_index];
|
||||
ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity);
|
||||
tmp.ioapic_id = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain));
|
||||
tmp.ioapic_pin = irq_data->args[0];
|
||||
tmp.ioapic_pin = fwspec->param[0];
|
||||
|
||||
return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp);
|
||||
}
|
||||
|
|
@ -276,14 +280,15 @@ static void __init x86_flattree_get_config(void)
|
|||
|
||||
map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
|
||||
|
||||
initial_boot_params = dt = early_memremap(initial_dtb, map_len);
|
||||
size = of_get_flat_dt_size();
|
||||
dt = early_memremap(initial_dtb, map_len);
|
||||
size = fdt_totalsize(dt);
|
||||
if (map_len < size) {
|
||||
early_memunmap(dt, map_len);
|
||||
initial_boot_params = dt = early_memremap(initial_dtb, size);
|
||||
dt = early_memremap(initial_dtb, size);
|
||||
map_len = size;
|
||||
}
|
||||
|
||||
early_init_dt_verify(dt);
|
||||
unflatten_and_copy_device_tree();
|
||||
early_memunmap(dt, map_len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,12 +71,17 @@ static void load_segments(void)
|
|||
static void machine_kexec_free_page_tables(struct kimage *image)
|
||||
{
|
||||
free_page((unsigned long)image->arch.pgd);
|
||||
image->arch.pgd = NULL;
|
||||
#ifdef CONFIG_X86_PAE
|
||||
free_page((unsigned long)image->arch.pmd0);
|
||||
image->arch.pmd0 = NULL;
|
||||
free_page((unsigned long)image->arch.pmd1);
|
||||
image->arch.pmd1 = NULL;
|
||||
#endif
|
||||
free_page((unsigned long)image->arch.pte0);
|
||||
image->arch.pte0 = NULL;
|
||||
free_page((unsigned long)image->arch.pte1);
|
||||
image->arch.pte1 = NULL;
|
||||
}
|
||||
|
||||
static int machine_kexec_alloc_page_tables(struct kimage *image)
|
||||
|
|
@ -93,7 +98,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
|
|||
!image->arch.pmd0 || !image->arch.pmd1 ||
|
||||
#endif
|
||||
!image->arch.pte0 || !image->arch.pte1) {
|
||||
machine_kexec_free_page_tables(image);
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,11 @@ static struct kexec_file_ops *kexec_file_loaders[] = {
|
|||
static void free_transition_pgtable(struct kimage *image)
|
||||
{
|
||||
free_page((unsigned long)image->arch.pud);
|
||||
image->arch.pud = NULL;
|
||||
free_page((unsigned long)image->arch.pmd);
|
||||
image->arch.pmd = NULL;
|
||||
free_page((unsigned long)image->arch.pte);
|
||||
image->arch.pte = NULL;
|
||||
}
|
||||
|
||||
static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
|
||||
|
|
@ -79,7 +82,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
|
|||
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
|
||||
return 0;
|
||||
err:
|
||||
free_transition_pgtable(image);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1344,6 +1344,7 @@ static void remove_siblinginfo(int cpu)
|
|||
cpumask_clear(topology_core_cpumask(cpu));
|
||||
c->phys_proc_id = 0;
|
||||
c->cpu_core_id = 0;
|
||||
c->booted_cores = 0;
|
||||
cpumask_clear_cpu(cpu, cpu_sibling_setup_mask);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,8 +288,16 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu)
|
|||
if (!kvm_vcpu_has_lapic(vcpu))
|
||||
return;
|
||||
|
||||
/*
|
||||
* KVM emulates 82093AA datasheet (with in-kernel IOAPIC implementation)
|
||||
* which doesn't have EOI register; Some buggy OSes (e.g. Windows with
|
||||
* Hyper-V role) disable EOI broadcast in lapic not checking for IOAPIC
|
||||
* version first and level-triggered interrupts never get EOIed in
|
||||
* IOAPIC.
|
||||
*/
|
||||
feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0);
|
||||
if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))))
|
||||
if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))) &&
|
||||
!ioapic_in_kernel(vcpu->kvm))
|
||||
v |= APIC_LVR_DIRECTED_EOI;
|
||||
apic_set_reg(apic, APIC_LVR, v);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2319,6 +2319,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
|
|||
return;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(vmx->emulation_required);
|
||||
|
||||
if (kvm_exception_is_soft(nr)) {
|
||||
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
|
||||
vmx->vcpu.arch.event_exit_inst_len);
|
||||
|
|
@ -6037,12 +6039,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (err != EMULATE_DONE) {
|
||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
||||
vcpu->run->internal.ndata = 0;
|
||||
return 0;
|
||||
}
|
||||
if (err != EMULATE_DONE)
|
||||
goto emulation_error;
|
||||
|
||||
if (vmx->emulation_required && !vmx->rmode.vm86_active &&
|
||||
vcpu->arch.exception.pending)
|
||||
goto emulation_error;
|
||||
|
||||
if (vcpu->arch.halt_request) {
|
||||
vcpu->arch.halt_request = 0;
|
||||
|
|
@ -6058,6 +6060,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
|
|||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
emulation_error:
|
||||
vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
||||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
|
||||
vcpu->run->internal.ndata = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __grow_ple_window(int val)
|
||||
|
|
|
|||
|
|
@ -3973,13 +3973,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
|||
mutex_unlock(&kvm->lock);
|
||||
break;
|
||||
case KVM_XEN_HVM_CONFIG: {
|
||||
struct kvm_xen_hvm_config xhc;
|
||||
r = -EFAULT;
|
||||
if (copy_from_user(&kvm->arch.xen_hvm_config, argp,
|
||||
sizeof(struct kvm_xen_hvm_config)))
|
||||
if (copy_from_user(&xhc, argp, sizeof(xhc)))
|
||||
goto out;
|
||||
r = -EINVAL;
|
||||
if (kvm->arch.xen_hvm_config.flags)
|
||||
if (xhc.flags)
|
||||
goto out;
|
||||
memcpy(&kvm->arch.xen_hvm_config, &xhc, sizeof(xhc));
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlb.h>
|
||||
|
|
@ -600,6 +601,10 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
|
|||
(mtrr != MTRR_TYPE_WRBACK))
|
||||
return 0;
|
||||
|
||||
/* Bail out if we are we on a populated non-leaf entry: */
|
||||
if (pud_present(*pud) && !pud_huge(*pud))
|
||||
return 0;
|
||||
|
||||
prot = pgprot_4k_2_large(prot);
|
||||
|
||||
set_pte((pte_t *)pud, pfn_pte(
|
||||
|
|
@ -628,6 +633,10 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Bail out if we are we on a populated non-leaf entry: */
|
||||
if (pmd_present(*pmd) && !pmd_huge(*pmd))
|
||||
return 0;
|
||||
|
||||
prot = pgprot_4k_2_large(prot);
|
||||
|
||||
set_pte((pte_t *)pmd, pfn_pte(
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ static inline void resume_init_first_level_page_table(pgd_t *pg_dir)
|
|||
#endif
|
||||
}
|
||||
|
||||
int swsusp_arch_resume(void)
|
||||
asmlinkage int swsusp_arch_resume(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static int set_up_temporary_mappings(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int swsusp_arch_resume(void)
|
||||
asmlinkage int swsusp_arch_resume(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
|
|
|||
|
|
@ -1316,8 +1316,6 @@ void xen_flush_tlb_all(void)
|
|||
struct mmuext_op *op;
|
||||
struct multicall_space mcs;
|
||||
|
||||
trace_xen_mmu_flush_tlb_all(0);
|
||||
|
||||
preempt_disable();
|
||||
|
||||
mcs = xen_mc_entry(sizeof(*op));
|
||||
|
|
@ -1335,8 +1333,6 @@ static void xen_flush_tlb(void)
|
|||
struct mmuext_op *op;
|
||||
struct multicall_space mcs;
|
||||
|
||||
trace_xen_mmu_flush_tlb(0);
|
||||
|
||||
preempt_disable();
|
||||
|
||||
mcs = xen_mc_entry(sizeof(*op));
|
||||
|
|
|
|||
|
|
@ -44,18 +44,10 @@
|
|||
: "r" (uaddr), "I" (-EFAULT), "r" (oparg) \
|
||||
: "memory")
|
||||
|
||||
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
int op = (encoded_op >> 28) & 7;
|
||||
int cmp = (encoded_op >> 24) & 15;
|
||||
int oparg = (encoded_op << 8) >> 20;
|
||||
int cmparg = (encoded_op << 20) >> 20;
|
||||
int oldval = 0, ret;
|
||||
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
|
||||
oparg = 1 << oparg;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
#if !XCHAL_HAVE_S32C1I
|
||||
return -ENOSYS;
|
||||
|
|
@ -89,19 +81,10 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
|
|||
|
||||
pagefault_enable();
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!ret)
|
||||
*oval = oldval;
|
||||
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ: return (oldval == cmparg);
|
||||
case FUTEX_OP_CMP_NE: return (oldval != cmparg);
|
||||
case FUTEX_OP_CMP_LT: return (oldval < cmparg);
|
||||
case FUTEX_OP_CMP_GE: return (oldval >= cmparg);
|
||||
case FUTEX_OP_CMP_LE: return (oldval <= cmparg);
|
||||
case FUTEX_OP_CMP_GT: return (oldval > cmparg);
|
||||
}
|
||||
|
||||
return -ENOSYS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ static void round_robin_cpu(unsigned int tsk_index)
|
|||
cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
|
||||
if (cpumask_empty(tmp)) {
|
||||
mutex_unlock(&round_robin_lock);
|
||||
free_cpumask_var(tmp);
|
||||
return;
|
||||
}
|
||||
for_each_cpu(cpu, tmp) {
|
||||
|
|
@ -125,6 +126,8 @@ static void round_robin_cpu(unsigned int tsk_index)
|
|||
mutex_unlock(&round_robin_lock);
|
||||
|
||||
set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
|
||||
|
||||
free_cpumask_var(tmp);
|
||||
}
|
||||
|
||||
static void exit_round_robin(unsigned int tsk_index)
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ u32 acpi_ev_fixed_event_detect(void)
|
|||
u32 fixed_status;
|
||||
u32 fixed_enable;
|
||||
u32 i;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_NAME(ev_fixed_event_detect);
|
||||
|
||||
|
|
@ -211,8 +212,12 @@ u32 acpi_ev_fixed_event_detect(void)
|
|||
* Read the fixed feature status and enable registers, as all the cases
|
||||
* depend on their values. Ignore errors here.
|
||||
*/
|
||||
(void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
|
||||
(void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
|
||||
status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
|
||||
status |=
|
||||
acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (int_status);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
|
||||
"Fixed Event Block: Enable %08X Status %08X\n",
|
||||
|
|
|
|||
|
|
@ -308,6 +308,14 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
|
|||
/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
|
||||
|
||||
status = AE_OK;
|
||||
} else if (ACPI_FAILURE(status)) {
|
||||
|
||||
/* If return_object exists, delete it */
|
||||
|
||||
if (info->return_object) {
|
||||
acpi_ut_remove_reference(info->return_object);
|
||||
info->return_object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (ignore_ppc) {
|
||||
if (ignore_ppc || !pr->performance) {
|
||||
/*
|
||||
* Only when it is notification event, the _OST object
|
||||
* will be evaluated. Otherwise it is skipped.
|
||||
|
|
|
|||
|
|
@ -4187,6 +4187,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|||
/* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
|
||||
{ "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, },
|
||||
|
||||
/* Some Sandisk SSDs lock up hard with NCQ enabled. Reported on
|
||||
SD7SN6S256G and SD8SN8U256G */
|
||||
{ "SanDisk SD[78]SN*G", NULL, ATA_HORKAGE_NONCQ, },
|
||||
|
||||
/* devices which puke on READ_NATIVE_MAX */
|
||||
{ "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
|
||||
{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
|
||||
|
|
@ -4247,6 +4251,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|||
{ "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, },
|
||||
|
||||
/* devices that don't properly handle queued TRIM commands */
|
||||
{ "Micron_M500IT_*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
||||
{ "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
||||
{ "Crucial_CT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ static int pcd_block_open(struct block_device *bdev, fmode_t mode)
|
|||
struct pcd_unit *cd = bdev->bd_disk->private_data;
|
||||
int ret;
|
||||
|
||||
check_disk_change(bdev);
|
||||
|
||||
mutex_lock(&pcd_mutex);
|
||||
ret = cdrom_open(&cd->info, bdev, mode);
|
||||
mutex_unlock(&pcd_mutex);
|
||||
|
|
|
|||
|
|
@ -336,6 +336,9 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3494), .driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* Additional Realtek 8723BU Bluetooth devices */
|
||||
{ USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* Additional Realtek 8821AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
|
||||
|
|
@ -343,6 +346,9 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* Additional Realtek 8822BE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* Silicon Wave based devices */
|
||||
{ USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user