Merge branch 'core/urgent' into sched/core

Merge in asm goto fix, to be able to apply the asm/rmwcc.h fix.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2013-10-11 07:39:37 +02:00
Родитель 3354781a21 3f0116c323
Коммит ec0ad3d01f
72 изменённых файлов: 457 добавлений и 203 удалений

Просмотреть файл

@ -296,10 +296,15 @@ archprepare:
# Convert bzImage to zImage # Convert bzImage to zImage
bzImage: zImage bzImage: zImage
zImage Image xipImage bootpImage uImage: vmlinux BOOT_TARGETS = zImage Image xipImage bootpImage uImage
INSTALL_TARGETS = zinstall uinstall install
PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
zinstall uinstall install: vmlinux $(INSTALL_TARGETS):
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
%.dtb: | scripts %.dtb: | scripts

Просмотреть файл

@ -95,24 +95,24 @@ initrd:
@test "$(INITRD)" != "" || \ @test "$(INITRD)" != "" || \
(echo You must specify INITRD; exit -1) (echo You must specify INITRD; exit -1)
install: $(obj)/Image install:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
$(obj)/Image System.map "$(INSTALL_PATH)" $(obj)/Image System.map "$(INSTALL_PATH)"
zinstall: $(obj)/zImage zinstall:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
$(obj)/zImage System.map "$(INSTALL_PATH)" $(obj)/zImage System.map "$(INSTALL_PATH)"
uinstall: $(obj)/uImage uinstall:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
$(obj)/uImage System.map "$(INSTALL_PATH)" $(obj)/uImage System.map "$(INSTALL_PATH)"
zi: zi:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
$(obj)/zImage System.map "$(INSTALL_PATH)" $(obj)/zImage System.map "$(INSTALL_PATH)"
i: i:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \
$(obj)/Image System.map "$(INSTALL_PATH)" $(obj)/Image System.map "$(INSTALL_PATH)"
subdir- := bootp compressed dts subdir- := bootp compressed dts

Просмотреть файл

@ -20,6 +20,20 @@
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
# #
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script # User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi

Просмотреть файл

@ -16,7 +16,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\n\t" asm_volatile_goto("1:\n\t"
JUMP_LABEL_NOP "\n\t" JUMP_LABEL_NOP "\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"
".word 1b, %l[l_yes], %c0\n\t" ".word 1b, %l[l_yes], %c0\n\t"

Просмотреть файл

@ -22,7 +22,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\tnop\n\t" asm_volatile_goto("1:\tnop\n\t"
"nop\n\t" "nop\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"
WORD_INSN " 1b, %l[l_yes], %0\n\t" WORD_INSN " 1b, %l[l_yes], %0\n\t"

Просмотреть файл

@ -19,7 +19,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\n\t" asm_volatile_goto("1:\n\t"
"nop\n\t" "nop\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"
JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"

Просмотреть файл

@ -495,14 +495,15 @@ void __do_irq(struct pt_regs *regs)
void do_IRQ(struct pt_regs *regs) void do_IRQ(struct pt_regs *regs)
{ {
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
struct thread_info *curtp, *irqtp; struct thread_info *curtp, *irqtp, *sirqtp;
/* Switch to the irq stack to handle this */ /* Switch to the irq stack to handle this */
curtp = current_thread_info(); curtp = current_thread_info();
irqtp = hardirq_ctx[raw_smp_processor_id()]; irqtp = hardirq_ctx[raw_smp_processor_id()];
sirqtp = softirq_ctx[raw_smp_processor_id()];
/* Already there ? */ /* Already there ? */
if (unlikely(curtp == irqtp)) { if (unlikely(curtp == irqtp || curtp == sirqtp)) {
__do_irq(regs); __do_irq(regs);
set_irq_regs(old_regs); set_irq_regs(old_regs);
return; return;

Просмотреть файл

@ -1066,7 +1066,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
mfspr r8, SPRN_DSCR mfspr r8, SPRN_DSCR
ld r7, HSTATE_DSCR(r13) ld r7, HSTATE_DSCR(r13)
std r8, VCPU_DSCR(r7) std r8, VCPU_DSCR(r9)
mtspr SPRN_DSCR, r7 mtspr SPRN_DSCR, r7
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)

Просмотреть файл

@ -332,6 +332,13 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
unsigned long hva; unsigned long hva;
int pfnmap = 0; int pfnmap = 0;
int tsize = BOOK3E_PAGESZ_4K; int tsize = BOOK3E_PAGESZ_4K;
int ret = 0;
unsigned long mmu_seq;
struct kvm *kvm = vcpu_e500->vcpu.kvm;
/* used to check for invalidations in progress */
mmu_seq = kvm->mmu_notifier_seq;
smp_rmb();
/* /*
* Translate guest physical to true physical, acquiring * Translate guest physical to true physical, acquiring
@ -449,6 +456,12 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1); gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1);
} }
spin_lock(&kvm->mmu_lock);
if (mmu_notifier_retry(kvm, mmu_seq)) {
ret = -EAGAIN;
goto out;
}
kvmppc_e500_ref_setup(ref, gtlbe, pfn); kvmppc_e500_ref_setup(ref, gtlbe, pfn);
kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,
@ -457,10 +470,13 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
/* Clear i-cache for new pages */ /* Clear i-cache for new pages */
kvmppc_mmu_flush_icache(pfn); kvmppc_mmu_flush_icache(pfn);
out:
spin_unlock(&kvm->mmu_lock);
/* Drop refcount on page, so that mmu notifiers can clear it */ /* Drop refcount on page, so that mmu notifiers can clear it */
kvm_release_pfn_clean(pfn); kvm_release_pfn_clean(pfn);
return 0; return ret;
} }
/* XXX only map the one-one case, for now use TLB0 */ /* XXX only map the one-one case, for now use TLB0 */

Просмотреть файл

@ -15,7 +15,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("0: brcl 0,0\n" asm_volatile_goto("0: brcl 0,0\n"
".pushsection __jump_table, \"aw\"\n" ".pushsection __jump_table, \"aw\"\n"
ASM_ALIGN "\n" ASM_ALIGN "\n"
ASM_PTR " 0b, %l[label], %0\n" ASM_PTR " 0b, %l[label], %0\n"

Просмотреть файл

@ -40,28 +40,26 @@ static inline void *load_real_addr(void *addr)
} }
/* /*
* Copy up to one page to vmalloc or real memory * Copy real to virtual or real memory
*/ */
static ssize_t copy_page_real(void *buf, void *src, size_t csize) static int copy_from_realmem(void *dest, void *src, size_t count)
{ {
size_t size; unsigned long size;
int rc;
if (is_vmalloc_addr(buf)) { if (!count)
BUG_ON(csize >= PAGE_SIZE); return 0;
/* If buf is not page aligned, copy first part */ if (!is_vmalloc_or_module_addr(dest))
size = min(roundup(__pa(buf), PAGE_SIZE) - __pa(buf), csize); return memcpy_real(dest, src, count);
if (size) { do {
if (memcpy_real(load_real_addr(buf), src, size)) size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK));
return -EFAULT; if (memcpy_real(load_real_addr(dest), src, size))
buf += size; return -EFAULT;
src += size; count -= size;
} dest += size;
/* Copy second part */ src += size;
size = csize - size; } while (count);
return (size) ? memcpy_real(load_real_addr(buf), src, size) : 0; return 0;
} else {
return memcpy_real(buf, src, csize);
}
} }
/* /*
@ -114,7 +112,7 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize,
rc = copy_to_user_real((void __force __user *) buf, rc = copy_to_user_real((void __force __user *) buf,
(void *) src, csize); (void *) src, csize);
else else
rc = copy_page_real(buf, (void *) src, csize); rc = copy_from_realmem(buf, (void *) src, csize);
return (rc == 0) ? rc : csize; return (rc == 0) ? rc : csize;
} }
@ -210,7 +208,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count)
if (OLDMEM_BASE) { if (OLDMEM_BASE) {
if ((unsigned long) src < OLDMEM_SIZE) { if ((unsigned long) src < OLDMEM_SIZE) {
copied = min(count, OLDMEM_SIZE - (unsigned long) src); copied = min(count, OLDMEM_SIZE - (unsigned long) src);
rc = memcpy_real(dest, src + OLDMEM_BASE, copied); rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied);
if (rc) if (rc)
return rc; return rc;
} }
@ -223,7 +221,7 @@ int copy_from_oldmem(void *dest, void *src, size_t count)
return rc; return rc;
} }
} }
return memcpy_real(dest + copied, src + copied, count - copied); return copy_from_realmem(dest + copied, src + copied, count - copied);
} }
/* /*

Просмотреть файл

@ -266,6 +266,7 @@ sysc_sigpending:
tm __TI_flags+3(%r12),_TIF_SYSCALL tm __TI_flags+3(%r12),_TIF_SYSCALL
jno sysc_return jno sysc_return
lm %r2,%r7,__PT_R2(%r11) # load svc arguments lm %r2,%r7,__PT_R2(%r11) # load svc arguments
l %r10,__TI_sysc_table(%r12) # 31 bit system call table
xr %r8,%r8 # svc 0 returns -ENOSYS xr %r8,%r8 # svc 0 returns -ENOSYS
clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2) clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
jnl sysc_nr_ok # invalid svc number -> do svc 0 jnl sysc_nr_ok # invalid svc number -> do svc 0

Просмотреть файл

@ -297,6 +297,7 @@ sysc_sigpending:
tm __TI_flags+7(%r12),_TIF_SYSCALL tm __TI_flags+7(%r12),_TIF_SYSCALL
jno sysc_return jno sysc_return
lmg %r2,%r7,__PT_R2(%r11) # load svc arguments lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
lg %r10,__TI_sysc_table(%r12) # address of system call table
lghi %r8,0 # svc 0 returns -ENOSYS lghi %r8,0 # svc 0 returns -ENOSYS
llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number
cghi %r1,NR_syscalls cghi %r1,NR_syscalls

Просмотреть файл

@ -67,6 +67,11 @@ static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn)
case 0xac: /* stnsm */ case 0xac: /* stnsm */
case 0xad: /* stosm */ case 0xad: /* stosm */
return -EINVAL; return -EINVAL;
case 0xc6:
switch (insn[0] & 0x0f) {
case 0x00: /* exrl */
return -EINVAL;
}
} }
switch (insn[0]) { switch (insn[0]) {
case 0x0101: /* pr */ case 0x0101: /* pr */
@ -180,7 +185,6 @@ static int __kprobes is_insn_relative_long(kprobe_opcode_t *insn)
break; break;
case 0xc6: case 0xc6:
switch (insn[0] & 0x0f) { switch (insn[0] & 0x0f) {
case 0x00: /* exrl */
case 0x02: /* pfdrl */ case 0x02: /* pfdrl */
case 0x04: /* cghrl */ case 0x04: /* cghrl */
case 0x05: /* chrl */ case 0x05: /* chrl */

Просмотреть файл

@ -9,7 +9,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:\n\t" asm_volatile_goto("1:\n\t"
"nop\n\t" "nop\n\t"
"nop\n\t" "nop\n\t"
".pushsection __jump_table, \"aw\"\n\t" ".pushsection __jump_table, \"aw\"\n\t"

Просмотреть файл

@ -166,7 +166,7 @@ static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
* *
* Atomically sets @v to @i and returns old @v * Atomically sets @v to @i and returns old @v
*/ */
static inline u64 atomic64_xchg(atomic64_t *v, u64 n) static inline long long atomic64_xchg(atomic64_t *v, long long n)
{ {
return xchg64(&v->counter, n); return xchg64(&v->counter, n);
} }
@ -180,7 +180,8 @@ static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
* Atomically checks if @v holds @o and replaces it with @n if so. * Atomically checks if @v holds @o and replaces it with @n if so.
* Returns the old value at @v. * Returns the old value at @v.
*/ */
static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n) static inline long long atomic64_cmpxchg(atomic64_t *v, long long o,
long long n)
{ {
return cmpxchg64(&v->counter, o, n); return cmpxchg64(&v->counter, o, n);
} }

Просмотреть файл

@ -80,7 +80,7 @@ static inline void atomic_set(atomic_t *v, int n)
/* A 64bit atomic type */ /* A 64bit atomic type */
typedef struct { typedef struct {
u64 __aligned(8) counter; long long counter;
} atomic64_t; } atomic64_t;
#define ATOMIC64_INIT(val) { (val) } #define ATOMIC64_INIT(val) { (val) }
@ -91,14 +91,14 @@ typedef struct {
* *
* Atomically reads the value of @v. * Atomically reads the value of @v.
*/ */
static inline u64 atomic64_read(const atomic64_t *v) static inline long long atomic64_read(const atomic64_t *v)
{ {
/* /*
* Requires an atomic op to read both 32-bit parts consistently. * Requires an atomic op to read both 32-bit parts consistently.
* Casting away const is safe since the atomic support routines * Casting away const is safe since the atomic support routines
* do not write to memory if the value has not been modified. * do not write to memory if the value has not been modified.
*/ */
return _atomic64_xchg_add((u64 *)&v->counter, 0); return _atomic64_xchg_add((long long *)&v->counter, 0);
} }
/** /**
@ -108,7 +108,7 @@ static inline u64 atomic64_read(const atomic64_t *v)
* *
* Atomically adds @i to @v. * Atomically adds @i to @v.
*/ */
static inline void atomic64_add(u64 i, atomic64_t *v) static inline void atomic64_add(long long i, atomic64_t *v)
{ {
_atomic64_xchg_add(&v->counter, i); _atomic64_xchg_add(&v->counter, i);
} }
@ -120,7 +120,7 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
* *
* Atomically adds @i to @v and returns @i + @v * Atomically adds @i to @v and returns @i + @v
*/ */
static inline u64 atomic64_add_return(u64 i, atomic64_t *v) static inline long long atomic64_add_return(long long i, atomic64_t *v)
{ {
smp_mb(); /* barrier for proper semantics */ smp_mb(); /* barrier for proper semantics */
return _atomic64_xchg_add(&v->counter, i) + i; return _atomic64_xchg_add(&v->counter, i) + i;
@ -135,7 +135,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
* Atomically adds @a to @v, so long as @v was not already @u. * Atomically adds @a to @v, so long as @v was not already @u.
* Returns non-zero if @v was not @u, and zero otherwise. * Returns non-zero if @v was not @u, and zero otherwise.
*/ */
static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) static inline long long atomic64_add_unless(atomic64_t *v, long long a,
long long u)
{ {
smp_mb(); /* barrier for proper semantics */ smp_mb(); /* barrier for proper semantics */
return _atomic64_xchg_add_unless(&v->counter, a, u) != u; return _atomic64_xchg_add_unless(&v->counter, a, u) != u;
@ -151,7 +152,7 @@ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
* atomic64_set() can't be just a raw store, since it would be lost if it * atomic64_set() can't be just a raw store, since it would be lost if it
* fell between the load and store of one of the other atomic ops. * fell between the load and store of one of the other atomic ops.
*/ */
static inline void atomic64_set(atomic64_t *v, u64 n) static inline void atomic64_set(atomic64_t *v, long long n)
{ {
_atomic64_xchg(&v->counter, n); _atomic64_xchg(&v->counter, n);
} }
@ -236,11 +237,13 @@ extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
extern struct __get_user __atomic_or(volatile int *p, int *lock, int n); extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n); extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n); extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n); extern long long __atomic64_cmpxchg(volatile long long *p, int *lock,
extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n); long long o, long long n);
extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n); extern long long __atomic64_xchg(volatile long long *p, int *lock, long long n);
extern u64 __atomic64_xchg_add_unless(volatile u64 *p, extern long long __atomic64_xchg_add(volatile long long *p, int *lock,
int *lock, u64 o, u64 n); long long n);
extern long long __atomic64_xchg_add_unless(volatile long long *p,
int *lock, long long o, long long n);
/* Return failure from the atomic wrappers. */ /* Return failure from the atomic wrappers. */
struct __get_user __atomic_bad_address(int __user *addr); struct __get_user __atomic_bad_address(int __user *addr);

Просмотреть файл

@ -35,10 +35,10 @@ int _atomic_xchg(int *ptr, int n);
int _atomic_xchg_add(int *v, int i); int _atomic_xchg_add(int *v, int i);
int _atomic_xchg_add_unless(int *v, int a, int u); int _atomic_xchg_add_unless(int *v, int a, int u);
int _atomic_cmpxchg(int *ptr, int o, int n); int _atomic_cmpxchg(int *ptr, int o, int n);
u64 _atomic64_xchg(u64 *v, u64 n); long long _atomic64_xchg(long long *v, long long n);
u64 _atomic64_xchg_add(u64 *v, u64 i); long long _atomic64_xchg_add(long long *v, long long i);
u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u); long long _atomic64_xchg_add_unless(long long *v, long long a, long long u);
u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n); long long _atomic64_cmpxchg(long long *v, long long o, long long n);
#define xchg(ptr, n) \ #define xchg(ptr, n) \
({ \ ({ \
@ -53,7 +53,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
if (sizeof(*(ptr)) != 4) \ if (sizeof(*(ptr)) != 4) \
__cmpxchg_called_with_bad_pointer(); \ __cmpxchg_called_with_bad_pointer(); \
smp_mb(); \ smp_mb(); \
(typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, (int)n); \ (typeof(*(ptr)))_atomic_cmpxchg((int *)ptr, (int)o, \
(int)n); \
}) })
#define xchg64(ptr, n) \ #define xchg64(ptr, n) \
@ -61,7 +62,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
if (sizeof(*(ptr)) != 8) \ if (sizeof(*(ptr)) != 8) \
__xchg_called_with_bad_pointer(); \ __xchg_called_with_bad_pointer(); \
smp_mb(); \ smp_mb(); \
(typeof(*(ptr)))_atomic64_xchg((u64 *)(ptr), (u64)(n)); \ (typeof(*(ptr)))_atomic64_xchg((long long *)(ptr), \
(long long)(n)); \
}) })
#define cmpxchg64(ptr, o, n) \ #define cmpxchg64(ptr, o, n) \
@ -69,7 +71,8 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
if (sizeof(*(ptr)) != 8) \ if (sizeof(*(ptr)) != 8) \
__cmpxchg_called_with_bad_pointer(); \ __cmpxchg_called_with_bad_pointer(); \
smp_mb(); \ smp_mb(); \
(typeof(*(ptr)))_atomic64_cmpxchg((u64 *)ptr, (u64)o, (u64)n); \ (typeof(*(ptr)))_atomic64_cmpxchg((long long *)ptr, \
(long long)o, (long long)n); \
}) })
#else #else
@ -81,10 +84,11 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
switch (sizeof(*(ptr))) { \ switch (sizeof(*(ptr))) { \
case 4: \ case 4: \
__x = (typeof(__x))(unsigned long) \ __x = (typeof(__x))(unsigned long) \
__insn_exch4((ptr), (u32)(unsigned long)(n)); \ __insn_exch4((ptr), \
(u32)(unsigned long)(n)); \
break; \ break; \
case 8: \ case 8: \
__x = (typeof(__x)) \ __x = (typeof(__x)) \
__insn_exch((ptr), (unsigned long)(n)); \ __insn_exch((ptr), (unsigned long)(n)); \
break; \ break; \
default: \ default: \
@ -103,10 +107,12 @@ u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n);
switch (sizeof(*(ptr))) { \ switch (sizeof(*(ptr))) { \
case 4: \ case 4: \
__x = (typeof(__x))(unsigned long) \ __x = (typeof(__x))(unsigned long) \
__insn_cmpexch4((ptr), (u32)(unsigned long)(n)); \ __insn_cmpexch4((ptr), \
(u32)(unsigned long)(n)); \
break; \ break; \
case 8: \ case 8: \
__x = (typeof(__x))__insn_cmpexch((ptr), (u64)(n)); \ __x = (typeof(__x))__insn_cmpexch((ptr), \
(long long)(n)); \
break; \ break; \
default: \ default: \
__cmpxchg_called_with_bad_pointer(); \ __cmpxchg_called_with_bad_pointer(); \

Просмотреть файл

@ -15,9 +15,37 @@
#ifndef _ASM_TILE_PERCPU_H #ifndef _ASM_TILE_PERCPU_H
#define _ASM_TILE_PERCPU_H #define _ASM_TILE_PERCPU_H
register unsigned long __my_cpu_offset __asm__("tp"); register unsigned long my_cpu_offset_reg asm("tp");
#define __my_cpu_offset __my_cpu_offset
#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp)) #ifdef CONFIG_PREEMPT
/*
* For full preemption, we can't just use the register variable
* directly, since we need barrier() to hazard against it, causing the
* compiler to reload anything computed from a previous "tp" value.
* But we also don't want to use volatile asm, since we'd like the
* compiler to be able to cache the value across multiple percpu reads.
* So we use a fake stack read as a hazard against barrier().
* The 'U' constraint is like 'm' but disallows postincrement.
*/
static inline unsigned long __my_cpu_offset(void)
{
unsigned long tp;
register unsigned long *sp asm("sp");
asm("move %0, tp" : "=r" (tp) : "U" (*sp));
return tp;
}
#define __my_cpu_offset __my_cpu_offset()
#else
/*
* We don't need to hazard against barrier() since "tp" doesn't ever
* change with PREEMPT_NONE, and with PREEMPT_VOLUNTARY it only
* changes at function call points, at which we are already re-reading
* the value of "tp" due to "my_cpu_offset_reg" being a global variable.
*/
#define __my_cpu_offset my_cpu_offset_reg
#endif
#define set_my_cpu_offset(tp) (my_cpu_offset_reg = (tp))
#include <asm-generic/percpu.h> #include <asm-generic/percpu.h>

Просмотреть файл

@ -66,7 +66,7 @@ static struct hardwall_type hardwall_types[] = {
0, 0,
"udn", "udn",
LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list), LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list),
__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock), __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_UDN].lock),
NULL NULL
}, },
#ifndef __tilepro__ #ifndef __tilepro__
@ -77,7 +77,7 @@ static struct hardwall_type hardwall_types[] = {
1, /* disabled pending hypervisor support */ 1, /* disabled pending hypervisor support */
"idn", "idn",
LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list), LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list),
__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock), __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IDN].lock),
NULL NULL
}, },
{ /* access to user-space IPI */ { /* access to user-space IPI */
@ -87,7 +87,7 @@ static struct hardwall_type hardwall_types[] = {
0, 0,
"ipi", "ipi",
LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list), LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list),
__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock), __SPIN_LOCK_UNLOCKED(hardwall_types[HARDWALL_IPI].lock),
NULL NULL
}, },
#endif #endif

Просмотреть файл

@ -815,6 +815,9 @@ STD_ENTRY(interrupt_return)
} }
bzt r28, 1f bzt r28, 1f
bnz r29, 1f bnz r29, 1f
/* Disable interrupts explicitly for preemption. */
IRQ_DISABLE(r20,r21)
TRACE_IRQS_OFF
jal preempt_schedule_irq jal preempt_schedule_irq
FEEDBACK_REENTER(interrupt_return) FEEDBACK_REENTER(interrupt_return)
1: 1:

Просмотреть файл

@ -841,6 +841,9 @@ STD_ENTRY(interrupt_return)
} }
beqzt r28, 1f beqzt r28, 1f
bnez r29, 1f bnez r29, 1f
/* Disable interrupts explicitly for preemption. */
IRQ_DISABLE(r20,r21)
TRACE_IRQS_OFF
jal preempt_schedule_irq jal preempt_schedule_irq
FEEDBACK_REENTER(interrupt_return) FEEDBACK_REENTER(interrupt_return)
1: 1:

Просмотреть файл

@ -23,6 +23,7 @@
#include <linux/mmzone.h> #include <linux/mmzone.h>
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/string.h>
#include <asm/backtrace.h> #include <asm/backtrace.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
@ -332,21 +333,18 @@ static void describe_addr(struct KBacktraceIterator *kbt,
} }
if (vma->vm_file) { if (vma->vm_file) {
char *s;
p = d_path(&vma->vm_file->f_path, buf, bufsize); p = d_path(&vma->vm_file->f_path, buf, bufsize);
if (IS_ERR(p)) if (IS_ERR(p))
p = "?"; p = "?";
s = strrchr(p, '/'); name = kbasename(p);
if (s)
p = s+1;
} else { } else {
p = "anon"; name = "anon";
} }
/* Generate a string description of the vma info. */ /* Generate a string description of the vma info. */
namelen = strlen(p); namelen = strlen(name);
remaining = (bufsize - 1) - namelen; remaining = (bufsize - 1) - namelen;
memmove(buf, p, namelen); memmove(buf, name, namelen);
snprintf(buf + namelen, remaining, "[%lx+%lx] ", snprintf(buf + namelen, remaining, "[%lx+%lx] ",
vma->vm_start, vma->vm_end - vma->vm_start); vma->vm_start, vma->vm_end - vma->vm_start);
} }

Просмотреть файл

@ -107,19 +107,19 @@ unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask)
EXPORT_SYMBOL(_atomic_xor); EXPORT_SYMBOL(_atomic_xor);
u64 _atomic64_xchg(u64 *v, u64 n) long long _atomic64_xchg(long long *v, long long n)
{ {
return __atomic64_xchg(v, __atomic_setup(v), n); return __atomic64_xchg(v, __atomic_setup(v), n);
} }
EXPORT_SYMBOL(_atomic64_xchg); EXPORT_SYMBOL(_atomic64_xchg);
u64 _atomic64_xchg_add(u64 *v, u64 i) long long _atomic64_xchg_add(long long *v, long long i)
{ {
return __atomic64_xchg_add(v, __atomic_setup(v), i); return __atomic64_xchg_add(v, __atomic_setup(v), i);
} }
EXPORT_SYMBOL(_atomic64_xchg_add); EXPORT_SYMBOL(_atomic64_xchg_add);
u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u) long long _atomic64_xchg_add_unless(long long *v, long long a, long long u)
{ {
/* /*
* Note: argument order is switched here since it is easier * Note: argument order is switched here since it is easier
@ -130,7 +130,7 @@ u64 _atomic64_xchg_add_unless(u64 *v, u64 a, u64 u)
} }
EXPORT_SYMBOL(_atomic64_xchg_add_unless); EXPORT_SYMBOL(_atomic64_xchg_add_unless);
u64 _atomic64_cmpxchg(u64 *v, u64 o, u64 n) long long _atomic64_cmpxchg(long long *v, long long o, long long n)
{ {
return __atomic64_cmpxchg(v, __atomic_setup(v), o, n); return __atomic64_cmpxchg(v, __atomic_setup(v), o, n);
} }

Просмотреть файл

@ -374,7 +374,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
* Catch too early usage of this before alternatives * Catch too early usage of this before alternatives
* have run. * have run.
*/ */
asm goto("1: jmp %l[t_warn]\n" asm_volatile_goto("1: jmp %l[t_warn]\n"
"2:\n" "2:\n"
".section .altinstructions,\"a\"\n" ".section .altinstructions,\"a\"\n"
" .long 1b - .\n" " .long 1b - .\n"
@ -388,7 +388,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
#endif #endif
asm goto("1: jmp %l[t_no]\n" asm_volatile_goto("1: jmp %l[t_no]\n"
"2:\n" "2:\n"
".section .altinstructions,\"a\"\n" ".section .altinstructions,\"a\"\n"
" .long 1b - .\n" " .long 1b - .\n"
@ -453,7 +453,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
* have. Thus, we force the jump to the widest, 4-byte, signed relative * have. Thus, we force the jump to the widest, 4-byte, signed relative
* offset even though the last would often fit in less bytes. * offset even though the last would often fit in less bytes.
*/ */
asm goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n" asm_volatile_goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n"
"2:\n" "2:\n"
".section .altinstructions,\"a\"\n" ".section .altinstructions,\"a\"\n"
" .long 1b - .\n" /* src offset */ " .long 1b - .\n" /* src offset */

Просмотреть файл

@ -18,7 +18,7 @@
static __always_inline bool arch_static_branch(struct static_key *key) static __always_inline bool arch_static_branch(struct static_key *key)
{ {
asm goto("1:" asm_volatile_goto("1:"
".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t" ".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t"
".pushsection __jump_table, \"aw\" \n\t" ".pushsection __jump_table, \"aw\" \n\t"
_ASM_ALIGN "\n\t" _ASM_ALIGN "\n\t"

Просмотреть файл

@ -20,7 +20,7 @@
static inline void __mutex_fastpath_lock(atomic_t *v, static inline void __mutex_fastpath_lock(atomic_t *v,
void (*fail_fn)(atomic_t *)) void (*fail_fn)(atomic_t *))
{ {
asm volatile goto(LOCK_PREFIX " decl %0\n" asm_volatile_goto(LOCK_PREFIX " decl %0\n"
" jns %l[exit]\n" " jns %l[exit]\n"
: : "m" (v->counter) : : "m" (v->counter)
: "memory", "cc" : "memory", "cc"
@ -75,7 +75,7 @@ static inline int __mutex_fastpath_lock_retval(atomic_t *count)
static inline void __mutex_fastpath_unlock(atomic_t *v, static inline void __mutex_fastpath_unlock(atomic_t *v,
void (*fail_fn)(atomic_t *)) void (*fail_fn)(atomic_t *))
{ {
asm volatile goto(LOCK_PREFIX " incl %0\n" asm_volatile_goto(LOCK_PREFIX " incl %0\n"
" jg %l[exit]\n" " jg %l[exit]\n"
: : "m" (v->counter) : : "m" (v->counter)
: "memory", "cc" : "memory", "cc"

Просмотреть файл

@ -1888,10 +1888,7 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc;
userpg->pmc_width = x86_pmu.cntval_bits; userpg->pmc_width = x86_pmu.cntval_bits;
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) if (!sched_clock_stable)
return;
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
return; return;
userpg->cap_user_time = 1; userpg->cap_user_time = 1;
@ -1899,10 +1896,8 @@ void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now)
userpg->time_shift = CYC2NS_SCALE_FACTOR; userpg->time_shift = CYC2NS_SCALE_FACTOR;
userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
if (sched_clock_stable && !check_tsc_disabled()) { userpg->cap_user_time_zero = 1;
userpg->cap_user_time_zero = 1; userpg->time_zero = this_cpu_read(cyc2ns_offset);
userpg->time_zero = this_cpu_read(cyc2ns_offset);
}
} }
/* /*

Просмотреть файл

@ -3255,25 +3255,29 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
static void ept_load_pdptrs(struct kvm_vcpu *vcpu) static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
{ {
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
if (!test_bit(VCPU_EXREG_PDPTR, if (!test_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_dirty)) (unsigned long *)&vcpu->arch.regs_dirty))
return; return;
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
vmcs_write64(GUEST_PDPTR0, vcpu->arch.mmu.pdptrs[0]); vmcs_write64(GUEST_PDPTR0, mmu->pdptrs[0]);
vmcs_write64(GUEST_PDPTR1, vcpu->arch.mmu.pdptrs[1]); vmcs_write64(GUEST_PDPTR1, mmu->pdptrs[1]);
vmcs_write64(GUEST_PDPTR2, vcpu->arch.mmu.pdptrs[2]); vmcs_write64(GUEST_PDPTR2, mmu->pdptrs[2]);
vmcs_write64(GUEST_PDPTR3, vcpu->arch.mmu.pdptrs[3]); vmcs_write64(GUEST_PDPTR3, mmu->pdptrs[3]);
} }
} }
static void ept_save_pdptrs(struct kvm_vcpu *vcpu) static void ept_save_pdptrs(struct kvm_vcpu *vcpu)
{ {
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
vcpu->arch.mmu.pdptrs[0] = vmcs_read64(GUEST_PDPTR0); mmu->pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
vcpu->arch.mmu.pdptrs[1] = vmcs_read64(GUEST_PDPTR1); mmu->pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
vcpu->arch.mmu.pdptrs[2] = vmcs_read64(GUEST_PDPTR2); mmu->pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
vcpu->arch.mmu.pdptrs[3] = vmcs_read64(GUEST_PDPTR3); mmu->pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
} }
__set_bit(VCPU_EXREG_PDPTR, __set_bit(VCPU_EXREG_PDPTR,
@ -7777,10 +7781,6 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1); vmcs_write64(GUEST_PDPTR1, vmcs12->guest_pdptr1);
vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2); vmcs_write64(GUEST_PDPTR2, vmcs12->guest_pdptr2);
vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3); vmcs_write64(GUEST_PDPTR3, vmcs12->guest_pdptr3);
__clear_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_avail);
__clear_bit(VCPU_EXREG_PDPTR,
(unsigned long *)&vcpu->arch.regs_dirty);
} }
kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp); kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->guest_rsp);

Просмотреть файл

@ -640,7 +640,7 @@ struct timer_rand_state {
*/ */
void add_device_randomness(const void *buf, unsigned int size) void add_device_randomness(const void *buf, unsigned int size)
{ {
unsigned long time = get_cycles() ^ jiffies; unsigned long time = random_get_entropy() ^ jiffies;
mix_pool_bytes(&input_pool, buf, size, NULL); mix_pool_bytes(&input_pool, buf, size, NULL);
mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
@ -677,7 +677,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
goto out; goto out;
sample.jiffies = jiffies; sample.jiffies = jiffies;
sample.cycles = get_cycles(); sample.cycles = random_get_entropy();
sample.num = num; sample.num = num;
mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL);
@ -744,7 +744,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness);
struct pt_regs *regs = get_irq_regs(); struct pt_regs *regs = get_irq_regs();
unsigned long now = jiffies; unsigned long now = jiffies;
__u32 input[4], cycles = get_cycles(); __u32 input[4], cycles = random_get_entropy();
input[0] = cycles ^ jiffies; input[0] = cycles ^ jiffies;
input[1] = irq; input[1] = irq;
@ -1459,12 +1459,11 @@ struct ctl_table random_table[] = {
static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
static int __init random_int_secret_init(void) int random_int_secret_init(void)
{ {
get_random_bytes(random_int_secret, sizeof(random_int_secret)); get_random_bytes(random_int_secret, sizeof(random_int_secret));
return 0; return 0;
} }
late_initcall(random_int_secret_init);
/* /*
* Get a random word for internal kernel use only. Similar to urandom but * Get a random word for internal kernel use only. Similar to urandom but
@ -1483,7 +1482,7 @@ unsigned int get_random_int(void)
hash = get_cpu_var(get_random_int_hash); hash = get_cpu_var(get_random_int_hash);
hash[0] += current->pid + jiffies + get_cycles(); hash[0] += current->pid + jiffies + random_get_entropy();
md5_transform(hash, random_int_secret); md5_transform(hash, random_int_secret);
ret = hash[0]; ret = hash[0];
put_cpu_var(get_random_int_hash); put_cpu_var(get_random_int_hash);

Просмотреть файл

@ -241,6 +241,7 @@ config HID_HOLTEK
- Sharkoon Drakonia / Perixx MX-2000 gaming mice - Sharkoon Drakonia / Perixx MX-2000 gaming mice
- Tracer Sniper TRM-503 / NOVA Gaming Slider X200 / - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 /
Zalman ZM-GM1 Zalman ZM-GM1
- SHARKOON DarkGlider Gaming mouse
config HOLTEK_FF config HOLTEK_FF
bool "Holtek On Line Grip force feedback support" bool "Holtek On Line Grip force feedback support"

Просмотреть файл

@ -1715,6 +1715,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },

Просмотреть файл

@ -27,6 +27,7 @@
* - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000 * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000
* - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200
* and Zalman ZM-GM1 * and Zalman ZM-GM1
* - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse
*/ */
static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@ -46,6 +47,7 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
} }
break; break;
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A: case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A:
case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081:
if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f
&& rdesc[111] == 0xff && rdesc[112] == 0x7f) { && rdesc[111] == 0xff && rdesc[112] == 0x7f) {
hid_info(hdev, "Fixing up report descriptor\n"); hid_info(hdev, "Fixing up report descriptor\n");
@ -63,6 +65,8 @@ static const struct hid_device_id holtek_mouse_devices[] = {
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
{ } { }
}; };
MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); MODULE_DEVICE_TABLE(hid, holtek_mouse_devices);

Просмотреть файл

@ -450,6 +450,7 @@
#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081
#define USB_VENDOR_ID_IMATION 0x0718 #define USB_VENDOR_ID_IMATION 0x0718
#define USB_DEVICE_ID_DISC_STAKKA 0xd000 #define USB_DEVICE_ID_DISC_STAKKA 0xd000

Просмотреть файл

@ -382,7 +382,7 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp,
} }
#define PROFILE_ATTR(number) \ #define PROFILE_ATTR(number) \
static struct bin_attribute bin_attr_profile##number = { \ static struct bin_attribute bin_attr_profile##number = { \
.attr = { .name = "profile##number", .mode = 0660 }, \ .attr = { .name = "profile" #number, .mode = 0660 }, \
.size = sizeof(struct kone_profile), \ .size = sizeof(struct kone_profile), \
.read = kone_sysfs_read_profilex, \ .read = kone_sysfs_read_profilex, \
.write = kone_sysfs_write_profilex, \ .write = kone_sysfs_write_profilex, \

Просмотреть файл

@ -229,13 +229,13 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
#define PROFILE_ATTR(number) \ #define PROFILE_ATTR(number) \
static struct bin_attribute bin_attr_profile##number##_settings = { \ static struct bin_attribute bin_attr_profile##number##_settings = { \
.attr = { .name = "profile##number##_settings", .mode = 0440 }, \ .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \
.size = KONEPLUS_SIZE_PROFILE_SETTINGS, \ .size = KONEPLUS_SIZE_PROFILE_SETTINGS, \
.read = koneplus_sysfs_read_profilex_settings, \ .read = koneplus_sysfs_read_profilex_settings, \
.private = &profile_numbers[number-1], \ .private = &profile_numbers[number-1], \
}; \ }; \
static struct bin_attribute bin_attr_profile##number##_buttons = { \ static struct bin_attribute bin_attr_profile##number##_buttons = { \
.attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
.size = KONEPLUS_SIZE_PROFILE_BUTTONS, \ .size = KONEPLUS_SIZE_PROFILE_BUTTONS, \
.read = koneplus_sysfs_read_profilex_buttons, \ .read = koneplus_sysfs_read_profilex_buttons, \
.private = &profile_numbers[number-1], \ .private = &profile_numbers[number-1], \

Просмотреть файл

@ -257,13 +257,13 @@ static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
#define PROFILE_ATTR(number) \ #define PROFILE_ATTR(number) \
static struct bin_attribute bin_attr_profile##number##_settings = { \ static struct bin_attribute bin_attr_profile##number##_settings = { \
.attr = { .name = "profile##number##_settings", .mode = 0440 }, \ .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \
.size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \ .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \
.read = kovaplus_sysfs_read_profilex_settings, \ .read = kovaplus_sysfs_read_profilex_settings, \
.private = &profile_numbers[number-1], \ .private = &profile_numbers[number-1], \
}; \ }; \
static struct bin_attribute bin_attr_profile##number##_buttons = { \ static struct bin_attribute bin_attr_profile##number##_buttons = { \
.attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
.size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \ .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \
.read = kovaplus_sysfs_read_profilex_buttons, \ .read = kovaplus_sysfs_read_profilex_buttons, \
.private = &profile_numbers[number-1], \ .private = &profile_numbers[number-1], \

Просмотреть файл

@ -225,13 +225,13 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
#define PROFILE_ATTR(number) \ #define PROFILE_ATTR(number) \
static struct bin_attribute bin_attr_profile##number##_settings = { \ static struct bin_attribute bin_attr_profile##number##_settings = { \
.attr = { .name = "profile##number##_settings", .mode = 0440 }, \ .attr = { .name = "profile" #number "_settings", .mode = 0440 }, \
.size = PYRA_SIZE_PROFILE_SETTINGS, \ .size = PYRA_SIZE_PROFILE_SETTINGS, \
.read = pyra_sysfs_read_profilex_settings, \ .read = pyra_sysfs_read_profilex_settings, \
.private = &profile_numbers[number-1], \ .private = &profile_numbers[number-1], \
}; \ }; \
static struct bin_attribute bin_attr_profile##number##_buttons = { \ static struct bin_attribute bin_attr_profile##number##_buttons = { \
.attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
.size = PYRA_SIZE_PROFILE_BUTTONS, \ .size = PYRA_SIZE_PROFILE_BUTTONS, \
.read = pyra_sysfs_read_profilex_buttons, \ .read = pyra_sysfs_read_profilex_buttons, \
.private = &profile_numbers[number-1], \ .private = &profile_numbers[number-1], \

Просмотреть файл

@ -119,12 +119,22 @@ static const struct wiimod_ops wiimod_keys = {
* the rumble motor, this flag shouldn't be set. * the rumble motor, this flag shouldn't be set.
*/ */
/* used by wiimod_rumble and wiipro_rumble */
static void wiimod_rumble_worker(struct work_struct *work)
{
struct wiimote_data *wdata = container_of(work, struct wiimote_data,
rumble_worker);
spin_lock_irq(&wdata->state.lock);
wiiproto_req_rumble(wdata, wdata->state.cache_rumble);
spin_unlock_irq(&wdata->state.lock);
}
static int wiimod_rumble_play(struct input_dev *dev, void *data, static int wiimod_rumble_play(struct input_dev *dev, void *data,
struct ff_effect *eff) struct ff_effect *eff)
{ {
struct wiimote_data *wdata = input_get_drvdata(dev); struct wiimote_data *wdata = input_get_drvdata(dev);
__u8 value; __u8 value;
unsigned long flags;
/* /*
* The wiimote supports only a single rumble motor so if any magnitude * The wiimote supports only a single rumble motor so if any magnitude
@ -137,9 +147,10 @@ static int wiimod_rumble_play(struct input_dev *dev, void *data,
else else
value = 0; value = 0;
spin_lock_irqsave(&wdata->state.lock, flags); /* Locking state.lock here might deadlock with input_event() calls.
wiiproto_req_rumble(wdata, value); * schedule_work acts as barrier. Merging multiple changes is fine. */
spin_unlock_irqrestore(&wdata->state.lock, flags); wdata->state.cache_rumble = value;
schedule_work(&wdata->rumble_worker);
return 0; return 0;
} }
@ -147,6 +158,8 @@ static int wiimod_rumble_play(struct input_dev *dev, void *data,
static int wiimod_rumble_probe(const struct wiimod_ops *ops, static int wiimod_rumble_probe(const struct wiimod_ops *ops,
struct wiimote_data *wdata) struct wiimote_data *wdata)
{ {
INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker);
set_bit(FF_RUMBLE, wdata->input->ffbit); set_bit(FF_RUMBLE, wdata->input->ffbit);
if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play)) if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play))
return -ENOMEM; return -ENOMEM;
@ -159,6 +172,8 @@ static void wiimod_rumble_remove(const struct wiimod_ops *ops,
{ {
unsigned long flags; unsigned long flags;
cancel_work_sync(&wdata->rumble_worker);
spin_lock_irqsave(&wdata->state.lock, flags); spin_lock_irqsave(&wdata->state.lock, flags);
wiiproto_req_rumble(wdata, 0); wiiproto_req_rumble(wdata, 0);
spin_unlock_irqrestore(&wdata->state.lock, flags); spin_unlock_irqrestore(&wdata->state.lock, flags);
@ -1731,7 +1746,6 @@ static int wiimod_pro_play(struct input_dev *dev, void *data,
{ {
struct wiimote_data *wdata = input_get_drvdata(dev); struct wiimote_data *wdata = input_get_drvdata(dev);
__u8 value; __u8 value;
unsigned long flags;
/* /*
* The wiimote supports only a single rumble motor so if any magnitude * The wiimote supports only a single rumble motor so if any magnitude
@ -1744,9 +1758,10 @@ static int wiimod_pro_play(struct input_dev *dev, void *data,
else else
value = 0; value = 0;
spin_lock_irqsave(&wdata->state.lock, flags); /* Locking state.lock here might deadlock with input_event() calls.
wiiproto_req_rumble(wdata, value); * schedule_work acts as barrier. Merging multiple changes is fine. */
spin_unlock_irqrestore(&wdata->state.lock, flags); wdata->state.cache_rumble = value;
schedule_work(&wdata->rumble_worker);
return 0; return 0;
} }
@ -1756,6 +1771,8 @@ static int wiimod_pro_probe(const struct wiimod_ops *ops,
{ {
int ret, i; int ret, i;
INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker);
wdata->extension.input = input_allocate_device(); wdata->extension.input = input_allocate_device();
if (!wdata->extension.input) if (!wdata->extension.input)
return -ENOMEM; return -ENOMEM;
@ -1817,12 +1834,13 @@ static void wiimod_pro_remove(const struct wiimod_ops *ops,
if (!wdata->extension.input) if (!wdata->extension.input)
return; return;
input_unregister_device(wdata->extension.input);
wdata->extension.input = NULL;
cancel_work_sync(&wdata->rumble_worker);
spin_lock_irqsave(&wdata->state.lock, flags); spin_lock_irqsave(&wdata->state.lock, flags);
wiiproto_req_rumble(wdata, 0); wiiproto_req_rumble(wdata, 0);
spin_unlock_irqrestore(&wdata->state.lock, flags); spin_unlock_irqrestore(&wdata->state.lock, flags);
input_unregister_device(wdata->extension.input);
wdata->extension.input = NULL;
} }
static const struct wiimod_ops wiimod_pro = { static const struct wiimod_ops wiimod_pro = {

Просмотреть файл

@ -133,13 +133,15 @@ struct wiimote_state {
__u8 *cmd_read_buf; __u8 *cmd_read_buf;
__u8 cmd_read_size; __u8 cmd_read_size;
/* calibration data */ /* calibration/cache data */
__u16 calib_bboard[4][3]; __u16 calib_bboard[4][3];
__u8 cache_rumble;
}; };
struct wiimote_data { struct wiimote_data {
struct hid_device *hdev; struct hid_device *hdev;
struct input_dev *input; struct input_dev *input;
struct work_struct rumble_worker;
struct led_classdev *leds[4]; struct led_classdev *leds[4];
struct input_dev *accel; struct input_dev *accel;
struct input_dev *ir; struct input_dev *ir;

Просмотреть файл

@ -308,18 +308,25 @@ static int hidraw_fasync(int fd, struct file *file, int on)
static void drop_ref(struct hidraw *hidraw, int exists_bit) static void drop_ref(struct hidraw *hidraw, int exists_bit)
{ {
if (exists_bit) { if (exists_bit) {
hid_hw_close(hidraw->hid);
hidraw->exist = 0; hidraw->exist = 0;
if (hidraw->open) if (hidraw->open) {
hid_hw_close(hidraw->hid);
wake_up_interruptible(&hidraw->wait); wake_up_interruptible(&hidraw->wait);
}
} else { } else {
--hidraw->open; --hidraw->open;
} }
if (!hidraw->open) {
if (!hidraw->open && !hidraw->exist) { if (!hidraw->exist) {
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); device_destroy(hidraw_class,
hidraw_table[hidraw->minor] = NULL; MKDEV(hidraw_major, hidraw->minor));
kfree(hidraw); hidraw_table[hidraw->minor] = NULL;
kfree(hidraw);
} else {
/* close device for last reader */
hid_hw_power(hidraw->hid, PM_HINT_NORMAL);
hid_hw_close(hidraw->hid);
}
} }
} }

Просмотреть файл

@ -615,7 +615,7 @@ static const struct file_operations uhid_fops = {
static struct miscdevice uhid_misc = { static struct miscdevice uhid_misc = {
.fops = &uhid_fops, .fops = &uhid_fops,
.minor = MISC_DYNAMIC_MINOR, .minor = UHID_MINOR,
.name = UHID_NAME, .name = UHID_NAME,
}; };
@ -634,4 +634,5 @@ module_exit(uhid_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem"); MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
MODULE_ALIAS_MISCDEV(UHID_MINOR);
MODULE_ALIAS("devname:" UHID_NAME); MODULE_ALIAS("devname:" UHID_NAME);

Просмотреть файл

@ -230,6 +230,7 @@ static int send_argument(const char *key)
static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
{ {
u8 status, data = 0;
int i; int i;
if (send_command(cmd) || send_argument(key)) { if (send_command(cmd) || send_argument(key)) {
@ -237,6 +238,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
return -EIO; return -EIO;
} }
/* This has no effect on newer (2012) SMCs */
if (send_byte(len, APPLESMC_DATA_PORT)) { if (send_byte(len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: read len fail\n", key); pr_warn("%.4s: read len fail\n", key);
return -EIO; return -EIO;
@ -250,6 +252,17 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
buffer[i] = inb(APPLESMC_DATA_PORT); buffer[i] = inb(APPLESMC_DATA_PORT);
} }
/* Read the data port until bit0 is cleared */
for (i = 0; i < 16; i++) {
udelay(APPLESMC_MIN_WAIT);
status = inb(APPLESMC_CMD_PORT);
if (!(status & 0x01))
break;
data = inb(APPLESMC_DATA_PORT);
}
if (i)
pr_warn("flushed %d bytes, last value is: %d\n", i, data);
return 0; return 0;
} }

Просмотреть файл

@ -996,6 +996,7 @@ static void request_write(struct cached_dev *dc, struct search *s)
closure_bio_submit(bio, cl, s->d); closure_bio_submit(bio, cl, s->d);
} else { } else {
bch_writeback_add(dc); bch_writeback_add(dc);
s->op.cache_bio = bio;
if (bio->bi_rw & REQ_FLUSH) { if (bio->bi_rw & REQ_FLUSH) {
/* Also need to send a flush to the backing device */ /* Also need to send a flush to the backing device */
@ -1008,8 +1009,6 @@ static void request_write(struct cached_dev *dc, struct search *s)
flush->bi_private = cl; flush->bi_private = cl;
closure_bio_submit(flush, cl, s->d); closure_bio_submit(flush, cl, s->d);
} else {
s->op.cache_bio = bio;
} }
} }
out: out:

Просмотреть файл

@ -168,12 +168,25 @@ static inline int write_disable(struct m25p *flash)
*/ */
static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable)
{ {
int status;
bool need_wren = false;
switch (JEDEC_MFR(jedec_id)) { switch (JEDEC_MFR(jedec_id)) {
case CFI_MFR_MACRONIX:
case CFI_MFR_ST: /* Micron, actually */ case CFI_MFR_ST: /* Micron, actually */
/* Some Micron need WREN command; all will accept it */
need_wren = true;
case CFI_MFR_MACRONIX:
case 0xEF /* winbond */: case 0xEF /* winbond */:
if (need_wren)
write_enable(flash);
flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
return spi_write(flash->spi, flash->command, 1); status = spi_write(flash->spi, flash->command, 1);
if (need_wren)
write_disable(flash);
return status;
default: default:
/* Spansion style */ /* Spansion style */
flash->command[0] = OPCODE_BRWR; flash->command[0] = OPCODE_BRWR;

Просмотреть файл

@ -2869,10 +2869,8 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
len = le16_to_cpu(p->ext_param_page_length) * 16; len = le16_to_cpu(p->ext_param_page_length) * 16;
ep = kmalloc(len, GFP_KERNEL); ep = kmalloc(len, GFP_KERNEL);
if (!ep) { if (!ep)
ret = -ENOMEM; return -ENOMEM;
goto ext_out;
}
/* Send our own NAND_CMD_PARAM. */ /* Send our own NAND_CMD_PARAM. */
chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
@ -2920,7 +2918,7 @@ static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
} }
pr_info("ONFI extended param page detected.\n"); pr_info("ONFI extended param page detected.\n");
return 0; ret = 0;
ext_out: ext_out:
kfree(ep); kfree(ep);

Просмотреть файл

@ -145,9 +145,11 @@ bool __init sclp_has_linemode(void)
if (sccb->header.response_code != 0x20) if (sccb->header.response_code != 0x20)
return 0; return 0;
if (sccb->sclp_send_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)) if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
return 1; return 0;
return 0; if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
return 0;
return 1;
} }
bool __init sclp_has_vt220(void) bool __init sclp_has_vt220(void)

Просмотреть файл

@ -810,7 +810,7 @@ static void tty3270_resize_work(struct work_struct *work)
struct winsize ws; struct winsize ws;
screen = tty3270_alloc_screen(tp->n_rows, tp->n_cols); screen = tty3270_alloc_screen(tp->n_rows, tp->n_cols);
if (!screen) if (IS_ERR(screen))
return; return;
/* Switch to new output size */ /* Switch to new output size */
spin_lock_bh(&tp->view.lock); spin_lock_bh(&tp->view.lock);

Просмотреть файл

@ -1583,7 +1583,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
/* Initialize the hardware */ /* Initialize the hardware */
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) if (ret)
goto out_unmap_regs; goto out_free_irq;
spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
if (as->caps.has_wdrbt) { if (as->caps.has_wdrbt) {
@ -1614,6 +1614,7 @@ out_free_dma:
spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
clk_disable_unprepare(clk); clk_disable_unprepare(clk);
out_free_irq:
free_irq(irq, master); free_irq(irq, master);
out_unmap_regs: out_unmap_regs:
iounmap(as->regs); iounmap(as->regs);

Просмотреть файл

@ -226,7 +226,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
dev_name(&pdev->dev), hw); dev_name(&pdev->dev), hw);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Can't request IRQ\n"); dev_err(&pdev->dev, "Can't request IRQ\n");
clk_put(hw->spi_clk);
goto clk_out; goto clk_out;
} }
@ -247,7 +246,6 @@ err_out:
gpio_free(hw->chipselect[i]); gpio_free(hw->chipselect[i]);
spi_master_put(master); spi_master_put(master);
kfree(master);
return ret; return ret;
} }
@ -263,7 +261,6 @@ static int spi_clps711x_remove(struct platform_device *pdev)
gpio_free(hw->chipselect[i]); gpio_free(hw->chipselect[i]);
spi_unregister_master(master); spi_unregister_master(master);
kfree(master);
return 0; return 0;
} }

Просмотреть файл

@ -476,15 +476,9 @@ static int dspi_probe(struct platform_device *pdev)
master->bus_num = bus_num; master->bus_num = bus_num;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "can't get platform resource\n");
ret = -EINVAL;
goto out_master_put;
}
dspi->base = devm_ioremap_resource(&pdev->dev, res); dspi->base = devm_ioremap_resource(&pdev->dev, res);
if (!dspi->base) { if (IS_ERR(dspi->base)) {
ret = -EINVAL; ret = PTR_ERR(dspi->base);
goto out_master_put; goto out_master_put;
} }

Просмотреть файл

@ -522,8 +522,10 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
psc_num = master->bus_num; psc_num = master->bus_num;
snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
clk = devm_clk_get(dev, clk_name); clk = devm_clk_get(dev, clk_name);
if (IS_ERR(clk)) if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto free_irq; goto free_irq;
}
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) if (ret)
goto free_irq; goto free_irq;

Просмотреть файл

@ -546,8 +546,17 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
if (pm_runtime_suspended(&drv_data->pdev->dev)) if (pm_runtime_suspended(&drv_data->pdev->dev))
return IRQ_NONE; return IRQ_NONE;
sccr1_reg = read_SSCR1(reg); /*
* If the device is not yet in RPM suspended state and we get an
* interrupt that is meant for another device, check if status bits
* are all set to one. That means that the device is already
* powered off.
*/
status = read_SSSR(reg); status = read_SSSR(reg);
if (status == ~0)
return IRQ_NONE;
sccr1_reg = read_SSCR1(reg);
/* Ignore possible writes if we don't need to write */ /* Ignore possible writes if we don't need to write */
if (!(sccr1_reg & SSCR1_TIE)) if (!(sccr1_reg & SSCR1_TIE))

Просмотреть файл

@ -1428,6 +1428,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
sdd->regs + S3C64XX_SPI_INT_EN); sdd->regs + S3C64XX_SPI_INT_EN);
pm_runtime_enable(&pdev->dev);
if (spi_register_master(master)) { if (spi_register_master(master)) {
dev_err(&pdev->dev, "cannot register SPI master\n"); dev_err(&pdev->dev, "cannot register SPI master\n");
ret = -EBUSY; ret = -EBUSY;
@ -1440,8 +1442,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
mem_res, mem_res,
sdd->rx_dma.dmach, sdd->tx_dma.dmach); sdd->rx_dma.dmach, sdd->tx_dma.dmach);
pm_runtime_enable(&pdev->dev);
return 0; return 0;
err3: err3:

Просмотреть файл

@ -296,6 +296,8 @@ static int hspi_probe(struct platform_device *pdev)
goto error1; goto error1;
} }
pm_runtime_enable(&pdev->dev);
master->num_chipselect = 1; master->num_chipselect = 1;
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->setup = hspi_setup; master->setup = hspi_setup;
@ -309,8 +311,6 @@ static int hspi_probe(struct platform_device *pdev)
goto error1; goto error1;
} }
pm_runtime_enable(&pdev->dev);
return 0; return 0;
error1: error1:

Просмотреть файл

@ -802,6 +802,12 @@ static int hpwdt_init_one(struct pci_dev *dev,
return -ENODEV; return -ENODEV;
} }
/*
* Ignore all auxilary iLO devices with the following PCI ID
*/
if (dev->subsystem_device == 0x1979)
return -ENODEV;
if (pci_enable_device(dev)) { if (pci_enable_device(dev)) {
dev_warn(&dev->dev, dev_warn(&dev->dev,
"Not possible to enable PCI Device: 0x%x:0x%x.\n", "Not possible to enable PCI Device: 0x%x:0x%x.\n",

Просмотреть файл

@ -65,6 +65,21 @@
#define __visible __attribute__((externally_visible)) #define __visible __attribute__((externally_visible))
#endif #endif
/*
* GCC 'asm goto' miscompiles certain code sequences:
*
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
*
* Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
* Fixed in GCC 4.8.2 and later versions.
*
* (asm goto is automatically volatile - the naming reflects this.)
*/
#if GCC_VERSION <= 40801
# define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
#else
# define asm_volatile_goto(x...) do { asm goto(x); } while (0)
#endif
#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
#if GCC_VERSION >= 40400 #if GCC_VERSION >= 40400

Просмотреть файл

@ -45,6 +45,7 @@
#define MAPPER_CTRL_MINOR 236 #define MAPPER_CTRL_MINOR 236
#define LOOP_CTRL_MINOR 237 #define LOOP_CTRL_MINOR 237
#define VHOST_NET_MINOR 238 #define VHOST_NET_MINOR 238
#define UHID_MINOR 239
#define MISC_DYNAMIC_MINOR 255 #define MISC_DYNAMIC_MINOR 255
struct device; struct device;

Просмотреть файл

@ -294,9 +294,31 @@ struct ring_buffer;
*/ */
struct perf_event { struct perf_event {
#ifdef CONFIG_PERF_EVENTS #ifdef CONFIG_PERF_EVENTS
struct list_head group_entry; /*
* entry onto perf_event_context::event_list;
* modifications require ctx->lock
* RCU safe iterations.
*/
struct list_head event_entry; struct list_head event_entry;
/*
* XXX: group_entry and sibling_list should be mutually exclusive;
* either you're a sibling on a group, or you're the group leader.
* Rework the code to always use the same list element.
*
* Locked for modification by both ctx->mutex and ctx->lock; holding
* either sufficies for read.
*/
struct list_head group_entry;
struct list_head sibling_list; struct list_head sibling_list;
/*
* We need storage to track the entries in perf_pmu_migrate_context; we
* cannot use the event_entry because of RCU and we want to keep the
* group in tact which avoids us using the other two entries.
*/
struct list_head migrate_entry;
struct hlist_node hlist_entry; struct hlist_node hlist_entry;
int nr_siblings; int nr_siblings;
int group_flags; int group_flags;

Просмотреть файл

@ -17,6 +17,7 @@ extern void add_interrupt_randomness(int irq, int irq_flags);
extern void get_random_bytes(void *buf, int nbytes); extern void get_random_bytes(void *buf, int nbytes);
extern void get_random_bytes_arch(void *buf, int nbytes); extern void get_random_bytes_arch(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]); void generate_random_uuid(unsigned char uuid_out[16]);
extern int random_int_secret_init(void);
#ifndef MODULE #ifndef MODULE
extern const struct file_operations random_fops, urandom_fops; extern const struct file_operations random_fops, urandom_fops;

Просмотреть файл

@ -64,6 +64,20 @@
#include <asm/timex.h> #include <asm/timex.h>
#ifndef random_get_entropy
/*
* The random_get_entropy() function is used by the /dev/random driver
* in order to extract entropy via the relative unpredictability of
* when an interrupt takes places versus a high speed, fine-grained
* timing source or cycle counter. Since it will be occurred on every
* single interrupt, it must have a very low cost/overhead.
*
* By default we use get_cycles() for this purpose, but individual
* architectures may override this in their asm/timex.h header file.
*/
#define random_get_entropy() get_cycles()
#endif
/* /*
* SHIFT_PLL is used as a dampening factor to define how much we * SHIFT_PLL is used as a dampening factor to define how much we
* adjust the frequency correction for a given offset in PLL mode. * adjust the frequency correction for a given offset in PLL mode.

Просмотреть файл

@ -76,6 +76,7 @@
#include <linux/elevator.h> #include <linux/elevator.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
#include <linux/context_tracking.h> #include <linux/context_tracking.h>
#include <linux/random.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bugs.h> #include <asm/bugs.h>
@ -780,6 +781,7 @@ static void __init do_basic_setup(void)
do_ctors(); do_ctors();
usermodehelper_enable(); usermodehelper_enable();
do_initcalls(); do_initcalls();
random_int_secret_init();
} }
static void __init do_pre_smp_initcalls(void) static void __init do_pre_smp_initcalls(void)

Просмотреть файл

@ -7234,15 +7234,15 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
perf_remove_from_context(event); perf_remove_from_context(event);
unaccount_event_cpu(event, src_cpu); unaccount_event_cpu(event, src_cpu);
put_ctx(src_ctx); put_ctx(src_ctx);
list_add(&event->event_entry, &events); list_add(&event->migrate_entry, &events);
} }
mutex_unlock(&src_ctx->mutex); mutex_unlock(&src_ctx->mutex);
synchronize_rcu(); synchronize_rcu();
mutex_lock(&dst_ctx->mutex); mutex_lock(&dst_ctx->mutex);
list_for_each_entry_safe(event, tmp, &events, event_entry) { list_for_each_entry_safe(event, tmp, &events, migrate_entry) {
list_del(&event->event_entry); list_del(&event->migrate_entry);
if (event->state >= PERF_EVENT_STATE_OFF) if (event->state >= PERF_EVENT_STATE_OFF)
event->state = PERF_EVENT_STATE_INACTIVE; event->state = PERF_EVENT_STATE_INACTIVE;
account_event_cpu(event, dst_cpu); account_event_cpu(event, dst_cpu);

Просмотреть файл

@ -592,7 +592,7 @@ static void kobject_release(struct kref *kref)
{ {
struct kobject *kobj = container_of(kref, struct kobject, kref); struct kobject *kobj = container_of(kref, struct kobject, kref);
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
pr_debug("kobject: '%s' (%p): %s, parent %p (delayed)\n", pr_info("kobject: '%s' (%p): %s, parent %p (delayed)\n",
kobject_name(kobj), kobj, __func__, kobj->parent); kobject_name(kobj), kobj, __func__, kobj->parent);
INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
schedule_delayed_work(&kobj->release, HZ); schedule_delayed_work(&kobj->release, HZ);

Просмотреть файл

@ -770,6 +770,7 @@ check: $(OUTPUT)common-cmds.h
install-bin: all install-bin: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
ifndef NO_LIBPERL ifndef NO_LIBPERL
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'

Просмотреть файл

@ -457,6 +457,7 @@ static int __run_perf_stat(int argc, const char **argv)
perror("failed to prepare workload"); perror("failed to prepare workload");
return -1; return -1;
} }
child_pid = evsel_list->workload.pid;
} }
if (group) if (group)

Просмотреть файл

@ -219,7 +219,7 @@ define SOURCE_LIBAUDIT
int main(void) int main(void)
{ {
printf(\"error message: %s\n\", audit_errno_to_name(0)); printf(\"error message: %s\", audit_errno_to_name(0));
return audit_open(); return audit_open();
} }
endef endef

Просмотреть файл

@ -426,7 +426,7 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
* @die_mem: a buffer for result DIE * @die_mem: a buffer for result DIE
* *
* Search a non-inlined function DIE which includes @addr. Stores the * Search a non-inlined function DIE which includes @addr. Stores the
* DIE to @die_mem and returns it if found. Returns NULl if failed. * DIE to @die_mem and returns it if found. Returns NULL if failed.
*/ */
Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
Dwarf_Die *die_mem) Dwarf_Die *die_mem)
@ -454,15 +454,32 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
} }
/** /**
* die_find_inlinefunc - Search an inlined function at given address * die_find_top_inlinefunc - Search the top inlined function at given address
* @cu_die: a CU DIE which including @addr * @sp_die: a subprogram DIE which including @addr
* @addr: target address * @addr: target address
* @die_mem: a buffer for result DIE * @die_mem: a buffer for result DIE
* *
* Search an inlined function DIE which includes @addr. Stores the * Search an inlined function DIE which includes @addr. Stores the
* DIE to @die_mem and returns it if found. Returns NULl if failed. * DIE to @die_mem and returns it if found. Returns NULL if failed.
* Even if several inlined functions are expanded recursively, this
* doesn't trace it down, and returns the topmost one.
*/
Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
Dwarf_Die *die_mem)
{
return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
}
/**
* die_find_inlinefunc - Search an inlined function at given address
* @sp_die: a subprogram DIE which including @addr
* @addr: target address
* @die_mem: a buffer for result DIE
*
* Search an inlined function DIE which includes @addr. Stores the
* DIE to @die_mem and returns it if found. Returns NULL if failed.
* If several inlined functions are expanded recursively, this trace * If several inlined functions are expanded recursively, this trace
* it and returns deepest one. * it down and returns deepest one.
*/ */
Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
Dwarf_Die *die_mem) Dwarf_Die *die_mem)

Просмотреть файл

@ -79,7 +79,11 @@ extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
Dwarf_Die *die_mem); Dwarf_Die *die_mem);
/* Search an inlined function including given address */ /* Search the top inlined function including given address */
extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
Dwarf_Die *die_mem);
/* Search the deepest inlined function including given address */
extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
Dwarf_Die *die_mem); Dwarf_Die *die_mem);

Просмотреть файл

@ -2768,6 +2768,18 @@ int perf_session__read_header(struct perf_session *session)
if (perf_file_header__read(&f_header, header, fd) < 0) if (perf_file_header__read(&f_header, header, fd) < 0)
return -EINVAL; return -EINVAL;
/*
* Sanity check that perf.data was written cleanly; data size is
* initialized to 0 and updated only if the on_exit function is run.
* If data size is still 0 then the file contains only partial
* information. Just warn user and process it as much as it can.
*/
if (f_header.data.size == 0) {
pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
"Was the 'perf record' command properly terminated?\n",
session->filename);
}
nr_attrs = f_header.attrs.size / f_header.attr_size; nr_attrs = f_header.attrs.size / f_header.attr_size;
lseek(fd, f_header.attrs.offset, SEEK_SET); lseek(fd, f_header.attrs.offset, SEEK_SET);

Просмотреть файл

@ -1327,8 +1327,8 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
struct perf_probe_point *ppt) struct perf_probe_point *ppt)
{ {
Dwarf_Die cudie, spdie, indie; Dwarf_Die cudie, spdie, indie;
Dwarf_Addr _addr, baseaddr; Dwarf_Addr _addr = 0, baseaddr = 0;
const char *fname = NULL, *func = NULL, *tmp; const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp;
int baseline = 0, lineno = 0, ret = 0; int baseline = 0, lineno = 0, ret = 0;
/* Adjust address with bias */ /* Adjust address with bias */
@ -1349,27 +1349,36 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
/* Find a corresponding function (name, baseline and baseaddr) */ /* Find a corresponding function (name, baseline and baseaddr) */
if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
/* Get function entry information */ /* Get function entry information */
tmp = dwarf_diename(&spdie); func = basefunc = dwarf_diename(&spdie);
if (!tmp || if (!func ||
dwarf_entrypc(&spdie, &baseaddr) != 0 || dwarf_entrypc(&spdie, &baseaddr) != 0 ||
dwarf_decl_line(&spdie, &baseline) != 0) dwarf_decl_line(&spdie, &baseline) != 0) {
lineno = 0;
goto post; goto post;
func = tmp; }
if (addr == (unsigned long)baseaddr) if (addr == (unsigned long)baseaddr) {
/* Function entry - Relative line number is 0 */ /* Function entry - Relative line number is 0 */
lineno = baseline; lineno = baseline;
else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, fname = dwarf_decl_file(&spdie);
&indie)) { goto post;
}
/* Track down the inline functions step by step */
while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr,
&indie)) {
/* There is an inline function */
if (dwarf_entrypc(&indie, &_addr) == 0 && if (dwarf_entrypc(&indie, &_addr) == 0 &&
_addr == addr) _addr == addr) {
/* /*
* addr is at an inline function entry. * addr is at an inline function entry.
* In this case, lineno should be the call-site * In this case, lineno should be the call-site
* line number. * line number. (overwrite lineinfo)
*/ */
lineno = die_get_call_lineno(&indie); lineno = die_get_call_lineno(&indie);
else { fname = die_get_call_file(&indie);
break;
} else {
/* /*
* addr is in an inline function body. * addr is in an inline function body.
* Since lineno points one of the lines * Since lineno points one of the lines
@ -1377,19 +1386,27 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
* be the entry line of the inline function. * be the entry line of the inline function.
*/ */
tmp = dwarf_diename(&indie); tmp = dwarf_diename(&indie);
if (tmp && if (!tmp ||
dwarf_decl_line(&spdie, &baseline) == 0) dwarf_decl_line(&indie, &baseline) != 0)
func = tmp; break;
func = tmp;
spdie = indie;
} }
} }
/* Verify the lineno and baseline are in a same file */
tmp = dwarf_decl_file(&spdie);
if (!tmp || strcmp(tmp, fname) != 0)
lineno = 0;
} }
post: post:
/* Make a relative line number or an offset */ /* Make a relative line number or an offset */
if (lineno) if (lineno)
ppt->line = lineno - baseline; ppt->line = lineno - baseline;
else if (func) else if (basefunc) {
ppt->offset = addr - (unsigned long)baseaddr; ppt->offset = addr - (unsigned long)baseaddr;
func = basefunc;
}
/* Duplicate strings */ /* Duplicate strings */
if (func) { if (func) {

Просмотреть файл

@ -256,6 +256,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
tool->sample = process_event_sample_stub; tool->sample = process_event_sample_stub;
if (tool->mmap == NULL) if (tool->mmap == NULL)
tool->mmap = process_event_stub; tool->mmap = process_event_stub;
if (tool->mmap2 == NULL)
tool->mmap2 = process_event_stub;
if (tool->comm == NULL) if (tool->comm == NULL)
tool->comm = process_event_stub; tool->comm = process_event_stub;
if (tool->fork == NULL) if (tool->fork == NULL)
@ -1310,7 +1312,7 @@ int __perf_session__process_events(struct perf_session *session,
file_offset = page_offset; file_offset = page_offset;
head = data_offset - page_offset; head = data_offset - page_offset;
if (data_offset + data_size < file_size) if (data_size && (data_offset + data_size < file_size))
file_size = data_offset + data_size; file_size = data_offset + data_size;
progress_next = file_size / 16; progress_next = file_size / 16;