mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
Merge remote-tracking branch 'lts/linux-4.4.y' into linux-linaro-lsk-v4.4
Conflicts: early call high_memory in arch/arm64/mm/init.c
This commit is contained in:
commit
95d4cbea02
|
|
@ -2519,6 +2519,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
|
||||
nointroute [IA-64]
|
||||
|
||||
noinvpcid [X86] Disable the INVPCID cpu feature.
|
||||
|
||||
nojitter [IA-64] Disables jitter checking for ITC timers.
|
||||
|
||||
no-kvmclock [X86,KVM] Disable paravirtualized KVM clock driver
|
||||
|
|
@ -2553,6 +2555,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
nopat [X86] Disable PAT (page attribute table extension of
|
||||
pagetables) support.
|
||||
|
||||
nopcid [X86-64] Disable the PCID cpu feature.
|
||||
|
||||
norandmaps Don't use address space randomization. Equivalent to
|
||||
echo 0 > /proc/sys/kernel/randomize_va_space
|
||||
|
||||
|
|
|
|||
5
Makefile
5
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 107
|
||||
SUBLEVEL = 109
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
@ -782,6 +782,9 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
|
|||
# disable invalid "can't wrap" optimizations for signed / pointers
|
||||
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
|
||||
|
||||
# Make sure -fstack-check isn't enabled (like gentoo apparently did)
|
||||
KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,)
|
||||
|
||||
# conserve stack if available
|
||||
KBUILD_CFLAGS += $(call cc-option,-fconserve-stack)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* Copyright (C) 1996, Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
|
|
|||
|
|
@ -668,6 +668,7 @@ &mmc2 {
|
|||
ti,non-removable;
|
||||
bus-width = <4>;
|
||||
cap-power-off-card;
|
||||
keep-power-in-suspend;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc2_pins>;
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ pcie1: pcie@51000000 {
|
|||
device_type = "pci";
|
||||
ranges = <0x81000000 0 0 0x03000 0 0x00010000
|
||||
0x82000000 0 0x20013000 0x13000 0 0xffed000>;
|
||||
bus-range = <0x00 0xff>;
|
||||
#interrupt-cells = <1>;
|
||||
num-lanes = <1>;
|
||||
ti,hwmods = "pcie1";
|
||||
|
|
@ -262,6 +263,7 @@ pcie@51000000 {
|
|||
device_type = "pci";
|
||||
ranges = <0x81000000 0 0 0x03000 0 0x00010000
|
||||
0x82000000 0 0x30013000 0x13000 0 0xffed000>;
|
||||
bus-range = <0x00 0xff>;
|
||||
#interrupt-cells = <1>;
|
||||
num-lanes = <1>;
|
||||
ti,hwmods = "pcie2";
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ static inline void check_and_switch_context(struct mm_struct *mm,
|
|||
cpu_switch_mm(mm->pgd, mm);
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
#define finish_arch_post_lock_switch \
|
||||
finish_arch_post_lock_switch
|
||||
static inline void finish_arch_post_lock_switch(void)
|
||||
|
|
@ -82,6 +83,7 @@ static inline void finish_arch_post_lock_switch(void)
|
|||
preempt_enable_no_resched();
|
||||
}
|
||||
}
|
||||
#endif /* !MODULE */
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
|
|
|
|||
|
|
@ -774,13 +774,31 @@ static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_add
|
|||
__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
|
||||
* that the intention is to allow exporting memory allocated via the
|
||||
* coherent DMA APIs through the dma_buf API, which only accepts a
|
||||
* scattertable. This presents a couple of problems:
|
||||
* 1. Not all memory allocated via the coherent DMA APIs is backed by
|
||||
* a struct page
|
||||
* 2. Passing coherent DMA memory into the streaming APIs is not allowed
|
||||
* as we will try to flush the memory through a different alias to that
|
||||
* actually being used (and the flushes are redundant.)
|
||||
*/
|
||||
int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t handle, size_t size,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
|
||||
unsigned long pfn = dma_to_pfn(dev, handle);
|
||||
struct page *page;
|
||||
int ret;
|
||||
|
||||
/* If the PFN is not valid, we do not have a struct page */
|
||||
if (!pfn_valid(pfn))
|
||||
return -ENXIO;
|
||||
|
||||
page = pfn_to_page(pfn);
|
||||
|
||||
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -433,6 +433,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
|||
struct hlist_node *tmp;
|
||||
unsigned long flags, orig_ret_address = 0;
|
||||
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
|
||||
kprobe_opcode_t *correct_ret_addr = NULL;
|
||||
|
||||
INIT_HLIST_HEAD(&empty_rp);
|
||||
kretprobe_hash_lock(current, &head, &flags);
|
||||
|
|
@ -455,15 +456,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
|||
/* another task is sharing our hash bucket */
|
||||
continue;
|
||||
|
||||
if (ri->rp && ri->rp->handler) {
|
||||
__this_cpu_write(current_kprobe, &ri->rp->kp);
|
||||
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
ri->rp->handler(ri, regs);
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
|
||||
orig_ret_address = (unsigned long)ri->ret_addr;
|
||||
recycle_rp_inst(ri, &empty_rp);
|
||||
|
||||
if (orig_ret_address != trampoline_address)
|
||||
/*
|
||||
|
|
@ -475,6 +468,33 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
kretprobe_assert(ri, orig_ret_address, trampoline_address);
|
||||
|
||||
correct_ret_addr = ri->ret_addr;
|
||||
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
|
||||
if (ri->task != current)
|
||||
/* another task is sharing our hash bucket */
|
||||
continue;
|
||||
|
||||
orig_ret_address = (unsigned long)ri->ret_addr;
|
||||
if (ri->rp && ri->rp->handler) {
|
||||
__this_cpu_write(current_kprobe, &ri->rp->kp);
|
||||
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
ri->ret_addr = correct_ret_addr;
|
||||
ri->rp->handler(ri, regs);
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
|
||||
recycle_rp_inst(ri, &empty_rp);
|
||||
|
||||
if (orig_ret_address != trampoline_address)
|
||||
/*
|
||||
* This is the real return address. Any other
|
||||
* instances associated with this task are for
|
||||
* other calls deeper on the call stack
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
|
|
|
|||
|
|
@ -976,7 +976,10 @@ static void coverage_end(void)
|
|||
void __naked __kprobes_test_case_start(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"stmdb sp!, {r4-r11} \n\t"
|
||||
"mov r2, sp \n\t"
|
||||
"bic r3, r2, #7 \n\t"
|
||||
"mov sp, r3 \n\t"
|
||||
"stmdb sp!, {r2-r11} \n\t"
|
||||
"sub sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
|
||||
"bic r0, lr, #1 @ r0 = inline data \n\t"
|
||||
"mov r1, sp \n\t"
|
||||
|
|
@ -996,7 +999,8 @@ void __naked __kprobes_test_case_end_32(void)
|
|||
"movne pc, r0 \n\t"
|
||||
"mov r0, r4 \n\t"
|
||||
"add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
|
||||
"ldmia sp!, {r4-r11} \n\t"
|
||||
"ldmia sp!, {r2-r11} \n\t"
|
||||
"mov sp, r2 \n\t"
|
||||
"mov pc, r0 \n\t"
|
||||
);
|
||||
}
|
||||
|
|
@ -1012,7 +1016,8 @@ void __naked __kprobes_test_case_end_16(void)
|
|||
"bxne r0 \n\t"
|
||||
"mov r0, r4 \n\t"
|
||||
"add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
|
||||
"ldmia sp!, {r4-r11} \n\t"
|
||||
"ldmia sp!, {r2-r11} \n\t"
|
||||
"mov sp, r2 \n\t"
|
||||
"bx r0 \n\t"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ void __init arm64_memblock_init(void)
|
|||
|
||||
reserve_elfcorehdr();
|
||||
|
||||
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
|
||||
dma_contiguous_reserve(arm64_dma_phys_limit);
|
||||
|
||||
memblock_allow_resize();
|
||||
|
|
@ -445,7 +446,6 @@ void __init bootmem_init(void)
|
|||
sparse_init();
|
||||
zone_sizes_init(min, max);
|
||||
|
||||
high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
|
||||
max_pfn = max_low_pfn = max;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1777,7 +1777,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
SPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.s = ieee754sp_maddf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmsubf_op: {
|
||||
|
|
@ -1790,7 +1790,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
SPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.s = ieee754sp_msubf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case frint_op: {
|
||||
|
|
@ -1814,7 +1814,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.w = ieee754sp_2008class(fs);
|
||||
rfmt = w_fmt;
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmin_op: {
|
||||
|
|
@ -1826,7 +1826,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmin(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmina_op: {
|
||||
|
|
@ -1838,7 +1838,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmina(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmax_op: {
|
||||
|
|
@ -1850,7 +1850,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmax(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmaxa_op: {
|
||||
|
|
@ -1862,7 +1862,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmaxa(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fabs_op:
|
||||
|
|
@ -2095,7 +2095,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
DPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.d = ieee754dp_maddf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmsubf_op: {
|
||||
|
|
@ -2108,7 +2108,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
DPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.d = ieee754dp_msubf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case frint_op: {
|
||||
|
|
@ -2132,7 +2132,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.w = ieee754dp_2008class(fs);
|
||||
rfmt = w_fmt;
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmin_op: {
|
||||
|
|
@ -2144,7 +2144,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmin(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmina_op: {
|
||||
|
|
@ -2156,7 +2156,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmina(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmax_op: {
|
||||
|
|
@ -2168,7 +2168,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmax(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmaxa_op: {
|
||||
|
|
@ -2180,7 +2180,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmaxa(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fabs_op:
|
||||
|
|
|
|||
|
|
@ -401,8 +401,12 @@ static __u64 power_pmu_bhrb_to(u64 addr)
|
|||
int ret;
|
||||
__u64 target;
|
||||
|
||||
if (is_kernel_addr(addr))
|
||||
return branch_target((unsigned int *)addr);
|
||||
if (is_kernel_addr(addr)) {
|
||||
if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
|
||||
return 0;
|
||||
|
||||
return branch_target(&instr);
|
||||
}
|
||||
|
||||
/* Userspace: need copy instruction here then translate it */
|
||||
pagefault_disable();
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ config X86
|
|||
select ARCH_USE_CMPXCHG_LOCKREF if X86_64
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP
|
||||
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
|
||||
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
select ARCH_WANT_IPC_PARSE_VERSION if X86_32
|
||||
|
|
|
|||
|
|
@ -21,11 +21,13 @@
|
|||
# define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31))
|
||||
# define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31))
|
||||
# define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31))
|
||||
# define DISABLE_PCID 0
|
||||
#else
|
||||
# define DISABLE_VME 0
|
||||
# define DISABLE_K6_MTRR 0
|
||||
# define DISABLE_CYRIX_ARR 0
|
||||
# define DISABLE_CENTAUR_MCR 0
|
||||
# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
/*
|
||||
|
|
@ -35,7 +37,7 @@
|
|||
#define DISABLED_MASK1 0
|
||||
#define DISABLED_MASK2 0
|
||||
#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
|
||||
#define DISABLED_MASK4 0
|
||||
#define DISABLED_MASK4 (DISABLE_PCID)
|
||||
#define DISABLED_MASK5 0
|
||||
#define DISABLED_MASK6 0
|
||||
#define DISABLED_MASK7 0
|
||||
|
|
|
|||
|
|
@ -22,12 +22,8 @@ typedef struct {
|
|||
#ifdef CONFIG_SMP
|
||||
unsigned int irq_resched_count;
|
||||
unsigned int irq_call_count;
|
||||
/*
|
||||
* irq_tlb_count is double-counted in irq_call_count, so it must be
|
||||
* subtracted from irq_call_count when displaying irq_call_count
|
||||
*/
|
||||
unsigned int irq_tlb_count;
|
||||
#endif
|
||||
unsigned int irq_tlb_count;
|
||||
#ifdef CONFIG_X86_THERMAL_VECTOR
|
||||
unsigned int irq_thermal_count;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,12 +24,6 @@ typedef struct {
|
|||
atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */
|
||||
} mm_context_t;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void leave_mm(int cpu);
|
||||
#else
|
||||
static inline void leave_mm(int cpu)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_MMU_H */
|
||||
|
|
|
|||
|
|
@ -98,109 +98,16 @@ static inline void load_mm_ldt(struct mm_struct *mm)
|
|||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
unsigned cpu = smp_processor_id();
|
||||
extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk);
|
||||
|
||||
if (likely(prev != next)) {
|
||||
#ifdef CONFIG_SMP
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
||||
this_cpu_write(cpu_tlbstate.active_mm, next);
|
||||
#endif
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/*
|
||||
* Re-load page tables.
|
||||
*
|
||||
* This logic has an ordering constraint:
|
||||
*
|
||||
* CPU 0: Write to a PTE for 'next'
|
||||
* CPU 0: load bit 1 in mm_cpumask. if nonzero, send IPI.
|
||||
* CPU 1: set bit 1 in next's mm_cpumask
|
||||
* CPU 1: load from the PTE that CPU 0 writes (implicit)
|
||||
*
|
||||
* We need to prevent an outcome in which CPU 1 observes
|
||||
* the new PTE value and CPU 0 observes bit 1 clear in
|
||||
* mm_cpumask. (If that occurs, then the IPI will never
|
||||
* be sent, and CPU 0's TLB will contain a stale entry.)
|
||||
*
|
||||
* The bad outcome can occur if either CPU's load is
|
||||
* reordered before that CPU's store, so both CPUs must
|
||||
* execute full barriers to prevent this from happening.
|
||||
*
|
||||
* Thus, switch_mm needs a full barrier between the
|
||||
* store to mm_cpumask and any operation that could load
|
||||
* from next->pgd. TLB fills are special and can happen
|
||||
* due to instruction fetches or for no reason at all,
|
||||
* and neither LOCK nor MFENCE orders them.
|
||||
* Fortunately, load_cr3() is serializing and gives the
|
||||
* ordering guarantee we need.
|
||||
*
|
||||
*/
|
||||
load_cr3(next->pgd);
|
||||
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
|
||||
/* Stop flush ipis for the previous mm */
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(prev));
|
||||
|
||||
/* Load per-mm CR4 state */
|
||||
load_mm_cr4(next);
|
||||
|
||||
#ifdef CONFIG_MODIFY_LDT_SYSCALL
|
||||
/*
|
||||
* Load the LDT, if the LDT is different.
|
||||
*
|
||||
* It's possible that prev->context.ldt doesn't match
|
||||
* the LDT register. This can happen if leave_mm(prev)
|
||||
* was called and then modify_ldt changed
|
||||
* prev->context.ldt but suppressed an IPI to this CPU.
|
||||
* In this case, prev->context.ldt != NULL, because we
|
||||
* never set context.ldt to NULL while the mm still
|
||||
* exists. That means that next->context.ldt !=
|
||||
* prev->context.ldt, because mms never share an LDT.
|
||||
*/
|
||||
if (unlikely(prev->context.ldt != next->context.ldt))
|
||||
load_mm_ldt(next);
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
else {
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
||||
BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
|
||||
|
||||
if (!cpumask_test_cpu(cpu, mm_cpumask(next))) {
|
||||
/*
|
||||
* On established mms, the mm_cpumask is only changed
|
||||
* from irq context, from ptep_clear_flush() while in
|
||||
* lazy tlb mode, and here. Irqs are blocked during
|
||||
* schedule, protecting us from simultaneous changes.
|
||||
*/
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/*
|
||||
* We were in lazy tlb mode and leave_mm disabled
|
||||
* tlb flush IPI delivery. We must reload CR3
|
||||
* to make sure to use no freed page tables.
|
||||
*
|
||||
* As above, load_cr3() is serializing and orders TLB
|
||||
* fills with respect to the mm_cpumask write.
|
||||
*/
|
||||
load_cr3(next->pgd);
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
load_mm_cr4(next);
|
||||
load_mm_ldt(next);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
extern void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk);
|
||||
#define switch_mm_irqs_off switch_mm_irqs_off
|
||||
|
||||
#define activate_mm(prev, next) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -6,6 +6,55 @@
|
|||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/special_insns.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
static inline void __invpcid(unsigned long pcid, unsigned long addr,
|
||||
unsigned long type)
|
||||
{
|
||||
struct { u64 d[2]; } desc = { { pcid, addr } };
|
||||
|
||||
/*
|
||||
* The memory clobber is because the whole point is to invalidate
|
||||
* stale TLB entries and, especially if we're flushing global
|
||||
* mappings, we don't want the compiler to reorder any subsequent
|
||||
* memory accesses before the TLB flush.
|
||||
*
|
||||
* The hex opcode is invpcid (%ecx), %eax in 32-bit mode and
|
||||
* invpcid (%rcx), %rax in long mode.
|
||||
*/
|
||||
asm volatile (".byte 0x66, 0x0f, 0x38, 0x82, 0x01"
|
||||
: : "m" (desc), "a" (type), "c" (&desc) : "memory");
|
||||
}
|
||||
|
||||
#define INVPCID_TYPE_INDIV_ADDR 0
|
||||
#define INVPCID_TYPE_SINGLE_CTXT 1
|
||||
#define INVPCID_TYPE_ALL_INCL_GLOBAL 2
|
||||
#define INVPCID_TYPE_ALL_NON_GLOBAL 3
|
||||
|
||||
/* Flush all mappings for a given pcid and addr, not including globals. */
|
||||
static inline void invpcid_flush_one(unsigned long pcid,
|
||||
unsigned long addr)
|
||||
{
|
||||
__invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR);
|
||||
}
|
||||
|
||||
/* Flush all mappings for a given PCID, not including globals. */
|
||||
static inline void invpcid_flush_single_context(unsigned long pcid)
|
||||
{
|
||||
__invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT);
|
||||
}
|
||||
|
||||
/* Flush all mappings, including globals, for all PCIDs. */
|
||||
static inline void invpcid_flush_all(void)
|
||||
{
|
||||
__invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL);
|
||||
}
|
||||
|
||||
/* Flush all mappings for all PCIDs except globals. */
|
||||
static inline void invpcid_flush_all_nonglobals(void)
|
||||
{
|
||||
__invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
#include <asm/paravirt.h>
|
||||
|
|
@ -16,10 +65,8 @@
|
|||
#endif
|
||||
|
||||
struct tlb_state {
|
||||
#ifdef CONFIG_SMP
|
||||
struct mm_struct *active_mm;
|
||||
int state;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Access to this CR4 shadow and to H/W CR4 is protected by
|
||||
|
|
@ -111,6 +158,15 @@ static inline void __native_flush_tlb_global(void)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_INVPCID)) {
|
||||
/*
|
||||
* Using INVPCID is considerably faster than a pair of writes
|
||||
* to CR4 sandwiched inside an IRQ flag save/restore.
|
||||
*/
|
||||
invpcid_flush_all();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read-modify-write to CR4 - protect it from preemption and
|
||||
* from interrupts. (Use the raw variant because this code can
|
||||
|
|
@ -134,6 +190,14 @@ static inline void __flush_tlb_all(void)
|
|||
__flush_tlb_global();
|
||||
else
|
||||
__flush_tlb();
|
||||
|
||||
/*
|
||||
* Note: if we somehow had PCID but not PGE, then this wouldn't work --
|
||||
* we'd end up flushing kernel translations for the current ASID but
|
||||
* we might fail to flush kernel translations for other cached ASIDs.
|
||||
*
|
||||
* To avoid this issue, we force PCID off if PGE is off.
|
||||
*/
|
||||
}
|
||||
|
||||
static inline void __flush_tlb_one(unsigned long addr)
|
||||
|
|
@ -147,7 +211,6 @@ static inline void __flush_tlb_one(unsigned long addr)
|
|||
/*
|
||||
* TLB flushing:
|
||||
*
|
||||
* - flush_tlb() flushes the current mm struct TLBs
|
||||
* - flush_tlb_all() flushes all processes TLBs
|
||||
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
|
||||
* - flush_tlb_page(vma, vmaddr) flushes one page
|
||||
|
|
@ -159,84 +222,6 @@ static inline void __flush_tlb_one(unsigned long addr)
|
|||
* and page-granular flushes are available only on i486 and up.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
|
||||
/* "_up" is for UniProcessor.
|
||||
*
|
||||
* This is a helper for other header functions. *Not* intended to be called
|
||||
* directly. All global TLB flushes need to either call this, or to bump the
|
||||
* vm statistics themselves.
|
||||
*/
|
||||
static inline void __flush_tlb_up(void)
|
||||
{
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
|
||||
__flush_tlb();
|
||||
}
|
||||
|
||||
static inline void flush_tlb_all(void)
|
||||
{
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
|
||||
__flush_tlb_all();
|
||||
}
|
||||
|
||||
static inline void flush_tlb(void)
|
||||
{
|
||||
__flush_tlb_up();
|
||||
}
|
||||
|
||||
static inline void local_flush_tlb(void)
|
||||
{
|
||||
__flush_tlb_up();
|
||||
}
|
||||
|
||||
static inline void flush_tlb_mm(struct mm_struct *mm)
|
||||
{
|
||||
if (mm == current->active_mm)
|
||||
__flush_tlb_up();
|
||||
}
|
||||
|
||||
static inline void flush_tlb_page(struct vm_area_struct *vma,
|
||||
unsigned long addr)
|
||||
{
|
||||
if (vma->vm_mm == current->active_mm)
|
||||
__flush_tlb_one(addr);
|
||||
}
|
||||
|
||||
static inline void flush_tlb_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
if (vma->vm_mm == current->active_mm)
|
||||
__flush_tlb_up();
|
||||
}
|
||||
|
||||
static inline void flush_tlb_mm_range(struct mm_struct *mm,
|
||||
unsigned long start, unsigned long end, unsigned long vmflag)
|
||||
{
|
||||
if (mm == current->active_mm)
|
||||
__flush_tlb_up();
|
||||
}
|
||||
|
||||
static inline void native_flush_tlb_others(const struct cpumask *cpumask,
|
||||
struct mm_struct *mm,
|
||||
unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void reset_lazy_tlbstate(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void flush_tlb_kernel_range(unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
flush_tlb_all();
|
||||
}
|
||||
|
||||
#else /* SMP */
|
||||
|
||||
#include <asm/smp.h>
|
||||
|
||||
#define local_flush_tlb() __flush_tlb()
|
||||
|
||||
#define flush_tlb_mm(mm) flush_tlb_mm_range(mm, 0UL, TLB_FLUSH_ALL, 0UL)
|
||||
|
|
@ -245,13 +230,14 @@ static inline void flush_tlb_kernel_range(unsigned long start,
|
|||
flush_tlb_mm_range(vma->vm_mm, start, end, vma->vm_flags)
|
||||
|
||||
extern void flush_tlb_all(void);
|
||||
extern void flush_tlb_current_task(void);
|
||||
extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
|
||||
extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
|
||||
unsigned long end, unsigned long vmflag);
|
||||
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
|
||||
|
||||
#define flush_tlb() flush_tlb_current_task()
|
||||
static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a)
|
||||
{
|
||||
flush_tlb_mm_range(vma->vm_mm, a, a + PAGE_SIZE, VM_NONE);
|
||||
}
|
||||
|
||||
void native_flush_tlb_others(const struct cpumask *cpumask,
|
||||
struct mm_struct *mm,
|
||||
|
|
@ -266,14 +252,6 @@ static inline void reset_lazy_tlbstate(void)
|
|||
this_cpu_write(cpu_tlbstate.active_mm, &init_mm);
|
||||
}
|
||||
|
||||
#endif /* SMP */
|
||||
|
||||
/* Not inlined due to inc_irq_stat not being defined yet */
|
||||
#define flush_tlb_local() { \
|
||||
inc_irq_stat(irq_tlb_count); \
|
||||
local_flush_tlb(); \
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
#define flush_tlb_others(mask, mm, start, end) \
|
||||
native_flush_tlb_others(mask, mm, start, end)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@
|
|||
|
||||
void __init check_bugs(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* Regardless of whether PCID is enumerated, the SDM says
|
||||
* that it can't be enabled in 32-bit mode.
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_PCID);
|
||||
#endif
|
||||
|
||||
identify_boot_cpu();
|
||||
#ifndef CONFIG_SMP
|
||||
pr_info("CPU: ");
|
||||
|
|
|
|||
|
|
@ -162,6 +162,40 @@ static int __init x86_mpx_setup(char *s)
|
|||
}
|
||||
__setup("nompx", x86_mpx_setup);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
static int __init x86_pcid_setup(char *s)
|
||||
{
|
||||
/* require an exact match without trailing characters */
|
||||
if (strlen(s))
|
||||
return 0;
|
||||
|
||||
/* do not emit a message if the feature is not present */
|
||||
if (!boot_cpu_has(X86_FEATURE_PCID))
|
||||
return 1;
|
||||
|
||||
setup_clear_cpu_cap(X86_FEATURE_PCID);
|
||||
pr_info("nopcid: PCID feature disabled\n");
|
||||
return 1;
|
||||
}
|
||||
__setup("nopcid", x86_pcid_setup);
|
||||
#endif
|
||||
|
||||
static int __init x86_noinvpcid_setup(char *s)
|
||||
{
|
||||
/* noinvpcid doesn't accept parameters */
|
||||
if (s)
|
||||
return -EINVAL;
|
||||
|
||||
/* do not emit a message if the feature is not present */
|
||||
if (!boot_cpu_has(X86_FEATURE_INVPCID))
|
||||
return 0;
|
||||
|
||||
setup_clear_cpu_cap(X86_FEATURE_INVPCID);
|
||||
pr_info("noinvpcid: INVPCID feature disabled\n");
|
||||
return 0;
|
||||
}
|
||||
early_param("noinvpcid", x86_noinvpcid_setup);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
static int cachesize_override = -1;
|
||||
static int disable_x86_serial_nr = 1;
|
||||
|
|
@ -287,6 +321,25 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
|
|||
}
|
||||
}
|
||||
|
||||
static void setup_pcid(struct cpuinfo_x86 *c)
|
||||
{
|
||||
if (cpu_has(c, X86_FEATURE_PCID)) {
|
||||
if (cpu_has(c, X86_FEATURE_PGE)) {
|
||||
cr4_set_bits(X86_CR4_PCIDE);
|
||||
} else {
|
||||
/*
|
||||
* flush_tlb_all(), as currently implemented, won't
|
||||
* work if PCID is on but PGE is not. Since that
|
||||
* combination doesn't exist on real hardware, there's
|
||||
* no reason to try to fully support it, but it's
|
||||
* polite to avoid corrupting data if we're on
|
||||
* an improperly configured VM.
|
||||
*/
|
||||
clear_cpu_cap(c, X86_FEATURE_PCID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some CPU features depend on higher CPUID levels, which may not always
|
||||
* be available due to CPUID level capping or broken virtualization
|
||||
|
|
@ -918,6 +971,9 @@ static void identify_cpu(struct cpuinfo_x86 *c)
|
|||
setup_smep(c);
|
||||
setup_smap(c);
|
||||
|
||||
/* Set up PCID */
|
||||
setup_pcid(c);
|
||||
|
||||
/*
|
||||
* The vendor-specific functions might have changed features.
|
||||
* Now we do "generic changes."
|
||||
|
|
|
|||
|
|
@ -102,8 +102,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
|
|||
seq_puts(p, " Rescheduling interrupts\n");
|
||||
seq_printf(p, "%*s: ", prec, "CAL");
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "%10u ", irq_stats(j)->irq_call_count -
|
||||
irq_stats(j)->irq_tlb_count);
|
||||
seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
|
||||
seq_puts(p, " Function call interrupts\n");
|
||||
seq_printf(p, "%*s: ", prec, "TLB");
|
||||
for_each_online_cpu(j)
|
||||
|
|
|
|||
|
|
@ -93,6 +93,10 @@ void __noreturn machine_real_restart(unsigned int type)
|
|||
load_cr3(initial_page_table);
|
||||
#else
|
||||
write_cr3(real_mode_header->trampoline_pgd);
|
||||
|
||||
/* Exiting long mode will fail if CR4.PCIDE is set. */
|
||||
if (static_cpu_has(X86_FEATURE_PCID))
|
||||
cr4_clear_bits(X86_CR4_PCIDE);
|
||||
#endif
|
||||
|
||||
/* Jump to the identity-mapped low memory code */
|
||||
|
|
|
|||
|
|
@ -104,25 +104,16 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
|
|||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
CMOS_WRITE(0xa, 0xf);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
local_flush_tlb();
|
||||
pr_debug("1.\n");
|
||||
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
|
||||
start_eip >> 4;
|
||||
pr_debug("2.\n");
|
||||
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
|
||||
start_eip & 0xf;
|
||||
pr_debug("3.\n");
|
||||
}
|
||||
|
||||
static inline void smpboot_restore_warm_reset_vector(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Install writable page 0 entry to set BIOS data area.
|
||||
*/
|
||||
local_flush_tlb();
|
||||
|
||||
/*
|
||||
* Paranoid: Set warm reset code and vector here back
|
||||
* to default values.
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
|
|||
pte_unmap_unlock(pte, ptl);
|
||||
out:
|
||||
up_write(&mm->mmap_sem);
|
||||
flush_tlb();
|
||||
flush_tlb_mm_range(mm, 0xA0000, 0xA0000 + 32*PAGE_SIZE, 0UL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2383,9 +2383,21 @@ static int rsm_load_seg_64(struct x86_emulate_ctxt *ctxt, u64 smbase, int n)
|
|||
}
|
||||
|
||||
static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt,
|
||||
u64 cr0, u64 cr4)
|
||||
u64 cr0, u64 cr3, u64 cr4)
|
||||
{
|
||||
int bad;
|
||||
u64 pcid;
|
||||
|
||||
/* In order to later set CR4.PCIDE, CR3[11:0] must be zero. */
|
||||
pcid = 0;
|
||||
if (cr4 & X86_CR4_PCIDE) {
|
||||
pcid = cr3 & 0xfff;
|
||||
cr3 &= ~0xfff;
|
||||
}
|
||||
|
||||
bad = ctxt->ops->set_cr(ctxt, 3, cr3);
|
||||
if (bad)
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
|
||||
/*
|
||||
* First enable PAE, long mode needs it before CR0.PG = 1 is set.
|
||||
|
|
@ -2404,6 +2416,12 @@ static int rsm_enter_protected_mode(struct x86_emulate_ctxt *ctxt,
|
|||
bad = ctxt->ops->set_cr(ctxt, 4, cr4);
|
||||
if (bad)
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
if (pcid) {
|
||||
bad = ctxt->ops->set_cr(ctxt, 3, cr3 | pcid);
|
||||
if (bad)
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return X86EMUL_CONTINUE;
|
||||
|
|
@ -2414,11 +2432,11 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase)
|
|||
struct desc_struct desc;
|
||||
struct desc_ptr dt;
|
||||
u16 selector;
|
||||
u32 val, cr0, cr4;
|
||||
u32 val, cr0, cr3, cr4;
|
||||
int i;
|
||||
|
||||
cr0 = GET_SMSTATE(u32, smbase, 0x7ffc);
|
||||
ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u32, smbase, 0x7ff8));
|
||||
cr3 = GET_SMSTATE(u32, smbase, 0x7ff8);
|
||||
ctxt->eflags = GET_SMSTATE(u32, smbase, 0x7ff4) | X86_EFLAGS_FIXED;
|
||||
ctxt->_eip = GET_SMSTATE(u32, smbase, 0x7ff0);
|
||||
|
||||
|
|
@ -2460,14 +2478,14 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, u64 smbase)
|
|||
|
||||
ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7ef8));
|
||||
|
||||
return rsm_enter_protected_mode(ctxt, cr0, cr4);
|
||||
return rsm_enter_protected_mode(ctxt, cr0, cr3, cr4);
|
||||
}
|
||||
|
||||
static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
|
||||
{
|
||||
struct desc_struct desc;
|
||||
struct desc_ptr dt;
|
||||
u64 val, cr0, cr4;
|
||||
u64 val, cr0, cr3, cr4;
|
||||
u32 base3;
|
||||
u16 selector;
|
||||
int i, r;
|
||||
|
|
@ -2484,7 +2502,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
|
|||
ctxt->ops->set_dr(ctxt, 7, (val & DR7_VOLATILE) | DR7_FIXED_1);
|
||||
|
||||
cr0 = GET_SMSTATE(u64, smbase, 0x7f58);
|
||||
ctxt->ops->set_cr(ctxt, 3, GET_SMSTATE(u64, smbase, 0x7f50));
|
||||
cr3 = GET_SMSTATE(u64, smbase, 0x7f50);
|
||||
cr4 = GET_SMSTATE(u64, smbase, 0x7f48);
|
||||
ctxt->ops->set_smbase(ctxt, GET_SMSTATE(u32, smbase, 0x7f00));
|
||||
val = GET_SMSTATE(u64, smbase, 0x7ed0);
|
||||
|
|
@ -2512,7 +2530,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, u64 smbase)
|
|||
dt.address = GET_SMSTATE(u64, smbase, 0x7e68);
|
||||
ctxt->ops->set_gdt(ctxt, &dt);
|
||||
|
||||
r = rsm_enter_protected_mode(ctxt, cr0, cr4);
|
||||
r = rsm_enter_protected_mode(ctxt, cr0, cr3, cr4);
|
||||
if (r != X86EMUL_CONTINUE)
|
||||
return r;
|
||||
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,11 @@ static inline bool cpu_has_vmx_invvpid_global(void)
|
|||
return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_vmx_invvpid(void)
|
||||
{
|
||||
return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_vmx_ept(void)
|
||||
{
|
||||
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
||||
|
|
@ -6199,8 +6204,10 @@ static __init int hardware_setup(void)
|
|||
if (boot_cpu_has(X86_FEATURE_NX))
|
||||
kvm_enable_efer_bits(EFER_NX);
|
||||
|
||||
if (!cpu_has_vmx_vpid())
|
||||
if (!cpu_has_vmx_vpid() || !cpu_has_vmx_invvpid() ||
|
||||
!(cpu_has_vmx_invvpid_single() || cpu_has_vmx_invvpid_global()))
|
||||
enable_vpid = 0;
|
||||
|
||||
if (!cpu_has_vmx_shadow_vmcs())
|
||||
enable_shadow_vmcs = 0;
|
||||
if (enable_shadow_vmcs)
|
||||
|
|
|
|||
|
|
@ -6941,7 +6941,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
|
|||
#endif
|
||||
|
||||
kvm_rip_write(vcpu, regs->rip);
|
||||
kvm_set_rflags(vcpu, regs->rflags);
|
||||
kvm_set_rflags(vcpu, regs->rflags | X86_EFLAGS_FIXED);
|
||||
|
||||
vcpu->arch.exception.pending = false;
|
||||
|
||||
|
|
@ -8230,11 +8230,11 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
struct x86_exception fault;
|
||||
|
||||
trace_kvm_async_pf_ready(work->arch.token, work->gva);
|
||||
if (work->wakeup_all)
|
||||
work->arch.token = ~0; /* broadcast wakeup */
|
||||
else
|
||||
kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
|
||||
trace_kvm_async_pf_ready(work->arch.token, work->gva);
|
||||
|
||||
if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) &&
|
||||
!apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
|
||||
pat.o pgtable.o physaddr.o gup.o setup_nx.o
|
||||
pat.o pgtable.o physaddr.o gup.o setup_nx.o tlb.o
|
||||
|
||||
# Make sure __phys_addr has no stackprotector
|
||||
nostackp := $(call cc-option, -fno-stack-protector)
|
||||
|
|
@ -9,7 +9,6 @@ CFLAGS_setup_nx.o := $(nostackp)
|
|||
CFLAGS_fault.o := -I$(src)/../include/asm/trace
|
||||
|
||||
obj-$(CONFIG_X86_PAT) += pat_rbtree.o
|
||||
obj-$(CONFIG_SMP) += tlb.o
|
||||
|
||||
obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o
|
||||
|
||||
|
|
|
|||
|
|
@ -753,10 +753,8 @@ void __init zone_sizes_init(void)
|
|||
}
|
||||
|
||||
DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = {
|
||||
#ifdef CONFIG_SMP
|
||||
.active_mm = &init_mm,
|
||||
.state = 0,
|
||||
#endif
|
||||
.cr4 = ~0UL, /* fail hard if we screw up cr4 shadow initialization */
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cpu_tlbstate);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include <linux/debugfs.h>
|
||||
|
||||
/*
|
||||
* Smarter SMP flushing macros.
|
||||
* TLB flushing, formerly SMP-only
|
||||
* c/o Linus Torvalds.
|
||||
*
|
||||
* These mean you can really definitely utterly forget about
|
||||
|
|
@ -57,6 +57,109 @@ void leave_mm(int cpu)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(leave_mm);
|
||||
|
||||
void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
switch_mm_irqs_off(prev, next, tsk);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
unsigned cpu = smp_processor_id();
|
||||
|
||||
if (likely(prev != next)) {
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
||||
this_cpu_write(cpu_tlbstate.active_mm, next);
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/*
|
||||
* Re-load page tables.
|
||||
*
|
||||
* This logic has an ordering constraint:
|
||||
*
|
||||
* CPU 0: Write to a PTE for 'next'
|
||||
* CPU 0: load bit 1 in mm_cpumask. if nonzero, send IPI.
|
||||
* CPU 1: set bit 1 in next's mm_cpumask
|
||||
* CPU 1: load from the PTE that CPU 0 writes (implicit)
|
||||
*
|
||||
* We need to prevent an outcome in which CPU 1 observes
|
||||
* the new PTE value and CPU 0 observes bit 1 clear in
|
||||
* mm_cpumask. (If that occurs, then the IPI will never
|
||||
* be sent, and CPU 0's TLB will contain a stale entry.)
|
||||
*
|
||||
* The bad outcome can occur if either CPU's load is
|
||||
* reordered before that CPU's store, so both CPUs must
|
||||
* execute full barriers to prevent this from happening.
|
||||
*
|
||||
* Thus, switch_mm needs a full barrier between the
|
||||
* store to mm_cpumask and any operation that could load
|
||||
* from next->pgd. TLB fills are special and can happen
|
||||
* due to instruction fetches or for no reason at all,
|
||||
* and neither LOCK nor MFENCE orders them.
|
||||
* Fortunately, load_cr3() is serializing and gives the
|
||||
* ordering guarantee we need.
|
||||
*
|
||||
*/
|
||||
load_cr3(next->pgd);
|
||||
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
|
||||
/* Stop flush ipis for the previous mm */
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(prev));
|
||||
|
||||
/* Load per-mm CR4 state */
|
||||
load_mm_cr4(next);
|
||||
|
||||
#ifdef CONFIG_MODIFY_LDT_SYSCALL
|
||||
/*
|
||||
* Load the LDT, if the LDT is different.
|
||||
*
|
||||
* It's possible that prev->context.ldt doesn't match
|
||||
* the LDT register. This can happen if leave_mm(prev)
|
||||
* was called and then modify_ldt changed
|
||||
* prev->context.ldt but suppressed an IPI to this CPU.
|
||||
* In this case, prev->context.ldt != NULL, because we
|
||||
* never set context.ldt to NULL while the mm still
|
||||
* exists. That means that next->context.ldt !=
|
||||
* prev->context.ldt, because mms never share an LDT.
|
||||
*/
|
||||
if (unlikely(prev->context.ldt != next->context.ldt))
|
||||
load_mm_ldt(next);
|
||||
#endif
|
||||
} else {
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
||||
BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
|
||||
|
||||
if (!cpumask_test_cpu(cpu, mm_cpumask(next))) {
|
||||
/*
|
||||
* On established mms, the mm_cpumask is only changed
|
||||
* from irq context, from ptep_clear_flush() while in
|
||||
* lazy tlb mode, and here. Irqs are blocked during
|
||||
* schedule, protecting us from simultaneous changes.
|
||||
*/
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
|
||||
/*
|
||||
* We were in lazy tlb mode and leave_mm disabled
|
||||
* tlb flush IPI delivery. We must reload CR3
|
||||
* to make sure to use no freed page tables.
|
||||
*
|
||||
* As above, load_cr3() is serializing and orders TLB
|
||||
* fills with respect to the mm_cpumask write.
|
||||
*/
|
||||
load_cr3(next->pgd);
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
load_mm_cr4(next);
|
||||
load_mm_ldt(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The flush IPI assumes that a thread switch happens in this order:
|
||||
* [cpu0: the cpu that switches]
|
||||
|
|
@ -104,7 +207,7 @@ static void flush_tlb_func(void *info)
|
|||
|
||||
inc_irq_stat(irq_tlb_count);
|
||||
|
||||
if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm))
|
||||
if (f->flush_mm && f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm))
|
||||
return;
|
||||
|
||||
count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED);
|
||||
|
|
@ -158,23 +261,6 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
|
|||
smp_call_function_many(cpumask, flush_tlb_func, &info, 1);
|
||||
}
|
||||
|
||||
void flush_tlb_current_task(void)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
|
||||
|
||||
/* This is an implicit full barrier that synchronizes with switch_mm. */
|
||||
local_flush_tlb();
|
||||
|
||||
trace_tlb_flush(TLB_LOCAL_SHOOTDOWN, TLB_FLUSH_ALL);
|
||||
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
|
||||
flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* See Documentation/x86/tlb.txt for details. We choose 33
|
||||
* because it is large enough to cover the vast majority (at
|
||||
|
|
@ -195,6 +281,12 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
|
|||
unsigned long base_pages_to_flush = TLB_FLUSH_ALL;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
if ((end != TLB_FLUSH_ALL) && !(vmflag & VM_HUGETLB))
|
||||
base_pages_to_flush = (end - start) >> PAGE_SHIFT;
|
||||
if (base_pages_to_flush > tlb_single_page_flush_ceiling)
|
||||
base_pages_to_flush = TLB_FLUSH_ALL;
|
||||
|
||||
if (current->active_mm != mm) {
|
||||
/* Synchronize with switch_mm. */
|
||||
smp_mb();
|
||||
|
|
@ -211,15 +303,11 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if ((end != TLB_FLUSH_ALL) && !(vmflag & VM_HUGETLB))
|
||||
base_pages_to_flush = (end - start) >> PAGE_SHIFT;
|
||||
|
||||
/*
|
||||
* Both branches below are implicit full barriers (MOV to CR or
|
||||
* INVLPG) that synchronize with switch_mm.
|
||||
*/
|
||||
if (base_pages_to_flush > tlb_single_page_flush_ceiling) {
|
||||
base_pages_to_flush = TLB_FLUSH_ALL;
|
||||
if (base_pages_to_flush == TLB_FLUSH_ALL) {
|
||||
count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);
|
||||
local_flush_tlb();
|
||||
} else {
|
||||
|
|
@ -240,33 +328,6 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
|
|||
preempt_enable();
|
||||
}
|
||||
|
||||
void flush_tlb_page(struct vm_area_struct *vma, unsigned long start)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
if (current->active_mm == mm) {
|
||||
if (current->mm) {
|
||||
/*
|
||||
* Implicit full barrier (INVLPG) that synchronizes
|
||||
* with switch_mm.
|
||||
*/
|
||||
__flush_tlb_one(start);
|
||||
} else {
|
||||
leave_mm(smp_processor_id());
|
||||
|
||||
/* Synchronize with switch_mm. */
|
||||
smp_mb();
|
||||
}
|
||||
}
|
||||
|
||||
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
|
||||
flush_tlb_others(mm_cpumask(mm), mm, start, start + PAGE_SIZE);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void do_flush_tlb_all(void *info)
|
||||
{
|
||||
count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED);
|
||||
|
|
|
|||
|
|
@ -433,6 +433,12 @@ static void __init xen_init_cpuid_mask(void)
|
|||
~((1 << X86_FEATURE_MTRR) | /* disable MTRR */
|
||||
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
|
||||
|
||||
/*
|
||||
* Xen PV would need some work to support PCID: CR3 handling as well
|
||||
* as xen_flush_tlb_others() would need updating.
|
||||
*/
|
||||
cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_PCID % 32)); /* disable PCID */
|
||||
|
||||
if (!xen_initial_domain())
|
||||
cpuid_leaf1_edx_mask &=
|
||||
~((1 << X86_FEATURE_ACPI)); /* disable ACPI */
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ static int mcryptd_init_queue(struct mcryptd_queue *queue,
|
|||
pr_debug("cpu_queue #%d %p\n", cpu, queue->cpu_queue);
|
||||
crypto_init_queue(&cpu_queue->queue, max_cpu_qlen);
|
||||
INIT_WORK(&cpu_queue->work, mcryptd_queue_worker);
|
||||
spin_lock_init(&cpu_queue->q_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -103,15 +104,16 @@ static int mcryptd_enqueue_request(struct mcryptd_queue *queue,
|
|||
int cpu, err;
|
||||
struct mcryptd_cpu_queue *cpu_queue;
|
||||
|
||||
cpu = get_cpu();
|
||||
cpu_queue = this_cpu_ptr(queue->cpu_queue);
|
||||
rctx->tag.cpu = cpu;
|
||||
cpu_queue = raw_cpu_ptr(queue->cpu_queue);
|
||||
spin_lock(&cpu_queue->q_lock);
|
||||
cpu = smp_processor_id();
|
||||
rctx->tag.cpu = smp_processor_id();
|
||||
|
||||
err = crypto_enqueue_request(&cpu_queue->queue, request);
|
||||
pr_debug("enqueue request: cpu %d cpu_queue %p request %p\n",
|
||||
cpu, cpu_queue, request);
|
||||
spin_unlock(&cpu_queue->q_lock);
|
||||
queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
|
||||
put_cpu();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -164,16 +166,11 @@ static void mcryptd_queue_worker(struct work_struct *work)
|
|||
cpu_queue = container_of(work, struct mcryptd_cpu_queue, work);
|
||||
i = 0;
|
||||
while (i < MCRYPTD_BATCH || single_task_running()) {
|
||||
/*
|
||||
* preempt_disable/enable is used to prevent
|
||||
* being preempted by mcryptd_enqueue_request()
|
||||
*/
|
||||
local_bh_disable();
|
||||
preempt_disable();
|
||||
|
||||
spin_lock_bh(&cpu_queue->q_lock);
|
||||
backlog = crypto_get_backlog(&cpu_queue->queue);
|
||||
req = crypto_dequeue_request(&cpu_queue->queue);
|
||||
preempt_enable();
|
||||
local_bh_enable();
|
||||
spin_unlock_bh(&cpu_queue->q_lock);
|
||||
|
||||
if (!req) {
|
||||
mcryptd_opportunistic_flush();
|
||||
|
|
@ -188,7 +185,7 @@ static void mcryptd_queue_worker(struct work_struct *work)
|
|||
++i;
|
||||
}
|
||||
if (cpu_queue->queue.qlen)
|
||||
queue_work(kcrypto_wq, &cpu_queue->work);
|
||||
queue_work_on(smp_processor_id(), kcrypto_wq, &cpu_queue->work);
|
||||
}
|
||||
|
||||
void mcryptd_flusher(struct work_struct *__work)
|
||||
|
|
|
|||
|
|
@ -1020,7 +1020,7 @@ static ssize_t erst_reader(u64 *id, enum pstore_type_id *type, int *count,
|
|||
/* The record may be cleared by others, try read next record */
|
||||
if (len == -ENOENT)
|
||||
goto skip;
|
||||
else if (len < sizeof(*rcd)) {
|
||||
else if (len < 0 || len < sizeof(*rcd)) {
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1050,10 +1050,6 @@ static int btusb_open(struct hci_dev *hdev)
|
|||
return err;
|
||||
|
||||
data->intf->needs_remote_wakeup = 1;
|
||||
/* device specific wakeup source enabled and required for USB
|
||||
* remote wakeup while host is suspended
|
||||
*/
|
||||
device_wakeup_enable(&data->udev->dev);
|
||||
|
||||
if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
|
||||
goto done;
|
||||
|
|
@ -1117,7 +1113,6 @@ static int btusb_close(struct hci_dev *hdev)
|
|||
goto failed;
|
||||
|
||||
data->intf->needs_remote_wakeup = 0;
|
||||
device_wakeup_disable(&data->udev->dev);
|
||||
usb_autopm_put_interface(data->intf);
|
||||
|
||||
failed:
|
||||
|
|
|
|||
|
|
@ -160,6 +160,24 @@ static int powernv_cpuidle_driver_init(void)
|
|||
drv->state_count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* On the PowerNV platform cpu_present may be less than cpu_possible in
|
||||
* cases when firmware detects the CPU, but it is not available to the
|
||||
* OS. If CONFIG_HOTPLUG_CPU=n, then such CPUs are not hotplugable at
|
||||
* run time and hence cpu_devices are not created for those CPUs by the
|
||||
* generic topology_init().
|
||||
*
|
||||
* drv->cpumask defaults to cpu_possible_mask in
|
||||
* __cpuidle_driver_init(). This breaks cpuidle on PowerNV where
|
||||
* cpu_devices are not created for CPUs in cpu_possible_mask that
|
||||
* cannot be hot-added later at run time.
|
||||
*
|
||||
* Trying cpuidle_register_device() on a CPU without a cpu_device is
|
||||
* incorrect, so pass a correct CPU mask to the generic cpuidle driver.
|
||||
*/
|
||||
|
||||
drv->cpumask = (struct cpumask *)cpu_present_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
|||
return -EBUSY;
|
||||
}
|
||||
target_state = &drv->states[index];
|
||||
broadcast = false;
|
||||
}
|
||||
|
||||
/* Take note of the planned idle state. */
|
||||
|
|
|
|||
|
|
@ -613,6 +613,18 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev)
|
|||
struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Return if cpu_device is not setup for this CPU.
|
||||
*
|
||||
* This could happen if the arch did not set up cpu_device
|
||||
* since this CPU is not in cpu_present mask and the
|
||||
* driver did not send a correct CPU mask during registration.
|
||||
* Without this check we would end up passing bogus
|
||||
* value for &cpu_dev->kobj in kobject_init_and_add()
|
||||
*/
|
||||
if (!cpu_dev)
|
||||
return -ENODEV;
|
||||
|
||||
kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
|
||||
if (!kdev)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@
|
|||
#define PPC405EX_CE_RESET 0x00000008
|
||||
|
||||
#define CRYPTO4XX_CRYPTO_PRIORITY 300
|
||||
#define PPC4XX_LAST_PD 63
|
||||
#define PPC4XX_NUM_PD 64
|
||||
#define PPC4XX_LAST_GD 1023
|
||||
#define PPC4XX_NUM_PD 256
|
||||
#define PPC4XX_LAST_PD (PPC4XX_NUM_PD - 1)
|
||||
#define PPC4XX_NUM_GD 1024
|
||||
#define PPC4XX_LAST_SD 63
|
||||
#define PPC4XX_NUM_SD 64
|
||||
#define PPC4XX_LAST_GD (PPC4XX_NUM_GD - 1)
|
||||
#define PPC4XX_NUM_SD 256
|
||||
#define PPC4XX_LAST_SD (PPC4XX_NUM_SD - 1)
|
||||
#define PPC4XX_SD_BUFFER_SIZE 2048
|
||||
|
||||
#define PD_ENTRY_INUSE 1
|
||||
|
|
|
|||
|
|
@ -2053,6 +2053,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
|
||||
|
|
|
|||
|
|
@ -1021,6 +1021,7 @@
|
|||
|
||||
#define USB_VENDOR_ID_XIN_MO 0x16c0
|
||||
#define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE 0x05e1
|
||||
#define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1
|
||||
|
||||
#define USB_VENDOR_ID_XIROKU 0x1477
|
||||
#define USB_DEVICE_ID_XIROKU_SPX 0x1006
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ static int xinmo_event(struct hid_device *hdev, struct hid_field *field,
|
|||
|
||||
static const struct hid_device_id xinmo_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -646,6 +646,9 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
|
|||
else
|
||||
err = atk_read_value_new(sensor, value);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sensor->is_valid = true;
|
||||
sensor->last_updated = jiffies;
|
||||
sensor->cached_value = *value;
|
||||
|
|
|
|||
|
|
@ -579,10 +579,10 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
|
|||
ret = -EAGAIN;
|
||||
goto skip_cqe;
|
||||
}
|
||||
if (unlikely((CQE_WRID_MSN(hw_cqe) != (wq->rq.msn)))) {
|
||||
if (unlikely(!CQE_STATUS(hw_cqe) &&
|
||||
CQE_WRID_MSN(hw_cqe) != wq->rq.msn)) {
|
||||
t4_set_wq_in_error(wq);
|
||||
hw_cqe->header |= htonl(CQE_STATUS_V(T4_ERR_MSN));
|
||||
goto proc_cqe;
|
||||
hw_cqe->header |= cpu_to_be32(CQE_STATUS_V(T4_ERR_MSN));
|
||||
}
|
||||
goto proc_cqe;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ struct iser_fr_desc {
|
|||
struct list_head list;
|
||||
struct iser_reg_resources rsc;
|
||||
struct iser_pi_context *pi_ctx;
|
||||
struct list_head all_list;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -463,6 +464,7 @@ struct iser_fr_pool {
|
|||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
int size;
|
||||
struct list_head all_list;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -405,6 +405,7 @@ int iser_alloc_fastreg_pool(struct ib_conn *ib_conn,
|
|||
int i, ret;
|
||||
|
||||
INIT_LIST_HEAD(&fr_pool->list);
|
||||
INIT_LIST_HEAD(&fr_pool->all_list);
|
||||
spin_lock_init(&fr_pool->lock);
|
||||
fr_pool->size = 0;
|
||||
for (i = 0; i < cmds_max; i++) {
|
||||
|
|
@ -416,6 +417,7 @@ int iser_alloc_fastreg_pool(struct ib_conn *ib_conn,
|
|||
}
|
||||
|
||||
list_add_tail(&desc->list, &fr_pool->list);
|
||||
list_add_tail(&desc->all_list, &fr_pool->all_list);
|
||||
fr_pool->size++;
|
||||
}
|
||||
|
||||
|
|
@ -435,13 +437,13 @@ void iser_free_fastreg_pool(struct ib_conn *ib_conn)
|
|||
struct iser_fr_desc *desc, *tmp;
|
||||
int i = 0;
|
||||
|
||||
if (list_empty(&fr_pool->list))
|
||||
if (list_empty(&fr_pool->all_list))
|
||||
return;
|
||||
|
||||
iser_info("freeing conn %p fr pool\n", ib_conn);
|
||||
|
||||
list_for_each_entry_safe(desc, tmp, &fr_pool->list, list) {
|
||||
list_del(&desc->list);
|
||||
list_for_each_entry_safe(desc, tmp, &fr_pool->all_list, all_list) {
|
||||
list_del(&desc->all_list);
|
||||
iser_free_reg_res(&desc->rsc);
|
||||
if (desc->pi_ctx)
|
||||
iser_free_pi_ctx(desc->pi_ctx);
|
||||
|
|
|
|||
|
|
@ -1032,6 +1032,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
|
|||
sizeof(avmb1_carddef))))
|
||||
return -EFAULT;
|
||||
cdef.cardtype = AVM_CARDTYPE_B1;
|
||||
cdef.cardnr = 0;
|
||||
} else {
|
||||
if ((retval = copy_from_user(&cdef, data,
|
||||
sizeof(avmb1_extcarddef))))
|
||||
|
|
|
|||
|
|
@ -660,6 +660,7 @@ static int cros_ec_spi_probe(struct spi_device *spi)
|
|||
sizeof(struct ec_response_get_protocol_info);
|
||||
ec_dev->dout_size = sizeof(struct ec_host_request);
|
||||
|
||||
ec_spi->last_transfer_ns = ktime_get_ns();
|
||||
|
||||
err = cros_ec_register(ec_dev);
|
||||
if (err) {
|
||||
|
|
|
|||
|
|
@ -159,13 +159,18 @@ unsigned int twl4030_audio_get_mclk(void)
|
|||
EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
|
||||
|
||||
static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
|
||||
struct device_node *node)
|
||||
struct device_node *parent)
|
||||
{
|
||||
struct device_node *node;
|
||||
|
||||
if (pdata && pdata->codec)
|
||||
return true;
|
||||
|
||||
if (of_find_node_by_name(node, "codec"))
|
||||
node = of_get_child_by_name(parent, "codec");
|
||||
if (node) {
|
||||
of_node_put(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,12 +97,16 @@ static struct reg_sequence twl6040_patch[] = {
|
|||
};
|
||||
|
||||
|
||||
static bool twl6040_has_vibra(struct device_node *node)
|
||||
static bool twl6040_has_vibra(struct device_node *parent)
|
||||
{
|
||||
#ifdef CONFIG_OF
|
||||
if (of_find_node_by_name(node, "vibra"))
|
||||
struct device_node *node;
|
||||
|
||||
node = of_get_child_by_name(parent, "vibra");
|
||||
if (node) {
|
||||
of_node_put(node);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1329,6 +1329,9 @@ static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
|
|||
/* There should only be one entry, but go through the list
|
||||
* anyway
|
||||
*/
|
||||
if (afu->phb == NULL)
|
||||
return result;
|
||||
|
||||
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
|
||||
if (!afu_dev->driver)
|
||||
continue;
|
||||
|
|
@ -1369,6 +1372,10 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
|
|||
*/
|
||||
for (i = 0; i < adapter->slices; i++) {
|
||||
afu = adapter->afu[i];
|
||||
/*
|
||||
* Tell the AFU drivers; but we don't care what they
|
||||
* say, we're going away.
|
||||
*/
|
||||
cxl_vphb_error_detected(afu, state);
|
||||
}
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
|
|
@ -1492,6 +1499,9 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
|
|||
if (cxl_afu_select_best_mode(afu))
|
||||
goto err;
|
||||
|
||||
if (afu->phb == NULL)
|
||||
continue;
|
||||
|
||||
cxl_pci_vphb_reconfigure(afu);
|
||||
|
||||
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
|
||||
|
|
@ -1556,6 +1566,9 @@ static void cxl_pci_resume(struct pci_dev *pdev)
|
|||
for (i = 0; i < adapter->slices; i++) {
|
||||
afu = adapter->afu[i];
|
||||
|
||||
if (afu->phb == NULL)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
|
||||
if (afu_dev->driver && afu_dev->driver->err_handler &&
|
||||
afu_dev->driver->err_handler->resume)
|
||||
|
|
|
|||
|
|
@ -2014,6 +2014,18 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void bnxt_init_cp_rings(struct bnxt *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bp->cp_nr_rings; i++) {
|
||||
struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring;
|
||||
struct bnxt_ring_struct *ring = &cpr->cp_ring_struct;
|
||||
|
||||
ring->fw_ring_id = INVALID_HW_RING_ID;
|
||||
}
|
||||
}
|
||||
|
||||
static int bnxt_init_rx_rings(struct bnxt *bp)
|
||||
{
|
||||
int i, rc = 0;
|
||||
|
|
@ -3977,6 +3989,7 @@ static int bnxt_shutdown_nic(struct bnxt *bp, bool irq_re_init)
|
|||
|
||||
static int bnxt_init_nic(struct bnxt *bp, bool irq_re_init)
|
||||
{
|
||||
bnxt_init_cp_rings(bp);
|
||||
bnxt_init_rx_rings(bp);
|
||||
bnxt_init_tx_rings(bp);
|
||||
bnxt_init_ring_grps(bp, irq_re_init);
|
||||
|
|
|
|||
|
|
@ -14228,7 +14228,9 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
|
|||
/* Reset PHY, otherwise the read DMA engine will be in a mode that
|
||||
* breaks all requests to 256 bytes.
|
||||
*/
|
||||
if (tg3_asic_rev(tp) == ASIC_REV_57766)
|
||||
if (tg3_asic_rev(tp) == ASIC_REV_57766 ||
|
||||
tg3_asic_rev(tp) == ASIC_REV_5717 ||
|
||||
tg3_asic_rev(tp) == ASIC_REV_5719)
|
||||
reset_phy = true;
|
||||
|
||||
err = tg3_restart_hw(tp, reset_phy);
|
||||
|
|
|
|||
|
|
@ -1930,13 +1930,13 @@ static void
|
|||
bfa_ioc_send_enable(struct bfa_ioc *ioc)
|
||||
{
|
||||
struct bfi_ioc_ctrl_req enable_req;
|
||||
struct timeval tv;
|
||||
|
||||
bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
|
||||
bfa_ioc_portid(ioc));
|
||||
enable_req.clscode = htons(ioc->clscode);
|
||||
do_gettimeofday(&tv);
|
||||
enable_req.tv_sec = ntohl(tv.tv_sec);
|
||||
enable_req.rsvd = htons(0);
|
||||
/* overflow in 2106 */
|
||||
enable_req.tv_sec = ntohl(ktime_get_real_seconds());
|
||||
bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req));
|
||||
}
|
||||
|
||||
|
|
@ -1947,6 +1947,10 @@ bfa_ioc_send_disable(struct bfa_ioc *ioc)
|
|||
|
||||
bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
|
||||
bfa_ioc_portid(ioc));
|
||||
disable_req.clscode = htons(ioc->clscode);
|
||||
disable_req.rsvd = htons(0);
|
||||
/* overflow in 2106 */
|
||||
disable_req.tv_sec = ntohl(ktime_get_real_seconds());
|
||||
bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
|
|||
return PTR_ERR(kern_buf);
|
||||
|
||||
rc = sscanf(kern_buf, "%x:%x", &addr, &len);
|
||||
if (rc < 2) {
|
||||
if (rc < 2 || len > UINT_MAX >> 2) {
|
||||
netdev_warn(bnad->netdev, "failed to read user buffer\n");
|
||||
kfree(kern_buf);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface)
|
|||
struct fm10k_mbx_info *mbx = &vf_info->mbx;
|
||||
u16 glort = vf_info->glort;
|
||||
|
||||
/* process the SM mailbox first to drain outgoing messages */
|
||||
hw->mbx.ops.process(hw, &hw->mbx);
|
||||
|
||||
/* verify port mapping is valid, if not reset port */
|
||||
if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort))
|
||||
hw->iov.ops.reset_lport(hw, vf_info);
|
||||
|
|
|
|||
|
|
@ -4201,8 +4201,12 @@ static void i40e_napi_enable_all(struct i40e_vsi *vsi)
|
|||
if (!vsi->netdev)
|
||||
return;
|
||||
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
|
||||
napi_enable(&vsi->q_vectors[q_idx]->napi);
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
|
||||
struct i40e_q_vector *q_vector = vsi->q_vectors[q_idx];
|
||||
|
||||
if (q_vector->rx.ring || q_vector->tx.ring)
|
||||
napi_enable(&q_vector->napi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4216,8 +4220,12 @@ static void i40e_napi_disable_all(struct i40e_vsi *vsi)
|
|||
if (!vsi->netdev)
|
||||
return;
|
||||
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
|
||||
napi_disable(&vsi->q_vectors[q_idx]->napi);
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
|
||||
struct i40e_q_vector *q_vector = vsi->q_vectors[q_idx];
|
||||
|
||||
if (q_vector->rx.ring || q_vector->tx.ring)
|
||||
napi_disable(&q_vector->napi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3005,6 +3005,8 @@ static int igb_sw_init(struct igb_adapter *adapter)
|
|||
/* Setup and initialize a copy of the hw vlan table array */
|
||||
adapter->shadow_vfta = kcalloc(E1000_VLAN_FILTER_TBL_SIZE, sizeof(u32),
|
||||
GFP_ATOMIC);
|
||||
if (!adapter->shadow_vfta)
|
||||
return -ENOMEM;
|
||||
|
||||
/* This call may decrease the number of queues */
|
||||
if (igb_init_interrupt_scheme(adapter, true)) {
|
||||
|
|
|
|||
|
|
@ -3620,10 +3620,10 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
|
|||
fw_cmd.ver_build = build;
|
||||
fw_cmd.ver_sub = sub;
|
||||
fw_cmd.hdr.checksum = 0;
|
||||
fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
|
||||
(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
|
||||
fw_cmd.pad = 0;
|
||||
fw_cmd.pad2 = 0;
|
||||
fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
|
||||
(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
|
||||
|
||||
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
|
||||
ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
|
||||
|
|
|
|||
|
|
@ -564,6 +564,8 @@ static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
|
|||
/* convert offset from words to bytes */
|
||||
buffer.address = cpu_to_be32((offset + current_word) * 2);
|
||||
buffer.length = cpu_to_be16(words_to_read * 2);
|
||||
buffer.pad2 = 0;
|
||||
buffer.pad3 = 0;
|
||||
|
||||
status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
|
||||
sizeof(buffer),
|
||||
|
|
|
|||
|
|
@ -241,7 +241,8 @@ static int orion_mdio_probe(struct platform_device *pdev)
|
|||
dev->regs + MVMDIO_ERR_INT_MASK);
|
||||
|
||||
} else if (dev->err_interrupt == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
ret = -EPROBE_DEFER;
|
||||
goto out_mdio;
|
||||
}
|
||||
|
||||
mutex_init(&dev->lock);
|
||||
|
|
|
|||
|
|
@ -914,6 +914,10 @@ static void mvneta_port_disable(struct mvneta_port *pp)
|
|||
val &= ~MVNETA_GMAC0_PORT_ENABLE;
|
||||
mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
|
||||
|
||||
pp->link = 0;
|
||||
pp->duplex = -1;
|
||||
pp->speed = 0;
|
||||
|
||||
udelay(200);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -418,8 +418,9 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr
|
|||
memset(rd, 0, sizeof(*rd));
|
||||
rd->hw = hwmap + i;
|
||||
rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA);
|
||||
if (rd->buf == NULL ||
|
||||
!(busaddr = pci_map_single(pdev, rd->buf, len, dir))) {
|
||||
if (rd->buf)
|
||||
busaddr = pci_map_single(pdev, rd->buf, len, dir);
|
||||
if (rd->buf == NULL || pci_dma_mapping_error(pdev, busaddr)) {
|
||||
if (rd->buf) {
|
||||
net_err_ratelimited("%s: failed to create PCI-MAP for %p\n",
|
||||
__func__, rd->buf);
|
||||
|
|
@ -430,8 +431,7 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr
|
|||
rd = r->rd + j;
|
||||
busaddr = rd_get_addr(rd);
|
||||
rd_set_addr_status(rd, 0, 0);
|
||||
if (busaddr)
|
||||
pci_unmap_single(pdev, busaddr, len, dir);
|
||||
pci_unmap_single(pdev, busaddr, len, dir);
|
||||
kfree(rd->buf);
|
||||
rd->buf = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ static int at803x_set_wol(struct phy_device *phydev,
|
|||
mac = (const u8 *) ndev->dev_addr;
|
||||
|
||||
if (!is_valid_ether_addr(mac))
|
||||
return -EFAULT;
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
|
||||
|
|
|
|||
|
|
@ -541,6 +541,7 @@ static int ksz9031_read_status(struct phy_device *phydev)
|
|||
phydev->link = 0;
|
||||
if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev))
|
||||
phydev->drv->config_intr(phydev);
|
||||
return genphy_config_aneg(phydev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -410,6 +410,10 @@ static const struct usb_device_id products[] = {
|
|||
USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69),
|
||||
.driver_info = (unsigned long)&qmi_wwan_info,
|
||||
},
|
||||
{ /* Motorola Mapphone devices with MDM6600 */
|
||||
USB_VENDOR_AND_INTERFACE_INFO(0x22b8, USB_CLASS_VENDOR_SPEC, 0xfb, 0xff),
|
||||
.driver_info = (unsigned long)&qmi_wwan_info,
|
||||
},
|
||||
|
||||
/* 2. Combined interface devices matching on class+protocol */
|
||||
{ /* Huawei E367 and possibly others in "Windows mode" */
|
||||
|
|
@ -733,6 +737,7 @@ static const struct usb_device_id products[] = {
|
|||
{QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */
|
||||
{QMI_FIXED_INTF(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */
|
||||
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
|
||||
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
|
||||
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
|
||||
|
|
|
|||
|
|
@ -1207,6 +1207,7 @@ static void intr_callback(struct urb *urb)
|
|||
}
|
||||
} else {
|
||||
if (netif_carrier_ok(tp->netdev)) {
|
||||
netif_stop_queue(tp->netdev);
|
||||
set_bit(RTL8152_LINK_CHG, &tp->flags);
|
||||
schedule_delayed_work(&tp->schedule, 0);
|
||||
}
|
||||
|
|
@ -1277,6 +1278,7 @@ static int alloc_all_mem(struct r8152 *tp)
|
|||
spin_lock_init(&tp->rx_lock);
|
||||
spin_lock_init(&tp->tx_lock);
|
||||
INIT_LIST_HEAD(&tp->tx_free);
|
||||
INIT_LIST_HEAD(&tp->rx_done);
|
||||
skb_queue_head_init(&tp->tx_queue);
|
||||
skb_queue_head_init(&tp->rx_queue);
|
||||
|
||||
|
|
@ -3000,6 +3002,9 @@ static void set_carrier(struct r8152 *tp)
|
|||
napi_enable(&tp->napi);
|
||||
netif_wake_queue(netdev);
|
||||
netif_info(tp, link, netdev, "carrier on\n");
|
||||
} else if (netif_queue_stopped(netdev) &&
|
||||
skb_queue_len(&tp->tx_queue) < tp->tx_qlen) {
|
||||
netif_wake_queue(netdev);
|
||||
}
|
||||
} else {
|
||||
if (netif_carrier_ok(netdev)) {
|
||||
|
|
@ -3560,8 +3565,18 @@ static int rtl8152_resume(struct usb_interface *intf)
|
|||
clear_bit(SELECTIVE_SUSPEND, &tp->flags);
|
||||
napi_disable(&tp->napi);
|
||||
set_bit(WORK_ENABLE, &tp->flags);
|
||||
if (netif_carrier_ok(tp->netdev))
|
||||
rtl_start_rx(tp);
|
||||
|
||||
if (netif_carrier_ok(tp->netdev)) {
|
||||
if (rtl8152_get_speed(tp) & LINK_STATUS) {
|
||||
rtl_start_rx(tp);
|
||||
} else {
|
||||
netif_carrier_off(tp->netdev);
|
||||
tp->rtl_ops.disable(tp);
|
||||
netif_info(tp, link, tp->netdev,
|
||||
"linking down\n");
|
||||
}
|
||||
}
|
||||
|
||||
napi_enable(&tp->napi);
|
||||
} else {
|
||||
tp->rtl_ops.up(tp);
|
||||
|
|
|
|||
|
|
@ -1654,3 +1654,36 @@ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
|
|||
iounmap(base_addr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The design of the Diva management card in rp34x0 machines (rp3410, rp3440)
|
||||
* seems rushed, so that many built-in components simply don't work.
|
||||
* The following quirks disable the serial AUX port and the built-in ATI RV100
|
||||
* Radeon 7000 graphics card which both don't have any external connectors and
|
||||
* thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as
|
||||
* such makes those machines the only PARISC machines on which we can't use
|
||||
* ttyS0 as boot console.
|
||||
*/
|
||||
static void quirk_diva_ati_card(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
|
||||
dev->subsystem_device != 0x1292)
|
||||
return;
|
||||
|
||||
dev_info(&dev->dev, "Hiding Diva built-in ATI card");
|
||||
dev->device = 0;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY,
|
||||
quirk_diva_ati_card);
|
||||
|
||||
static void quirk_diva_aux_disable(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
|
||||
dev->subsystem_device != 0x1291)
|
||||
return;
|
||||
|
||||
dev_info(&dev->dev, "Hiding Diva built-in AUX serial device");
|
||||
dev->device = 0;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX,
|
||||
quirk_diva_aux_disable);
|
||||
|
|
|
|||
|
|
@ -161,7 +161,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
|
|||
pci_device_add(virtfn, virtfn->bus);
|
||||
mutex_unlock(&iov->dev->sriov->lock);
|
||||
|
||||
pci_bus_add_device(virtfn);
|
||||
sprintf(buf, "virtfn%u", id);
|
||||
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
|
||||
if (rc)
|
||||
|
|
@ -172,6 +171,8 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
|
|||
|
||||
kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
|
||||
|
||||
pci_bus_add_device(virtfn);
|
||||
|
||||
return 0;
|
||||
|
||||
failed2:
|
||||
|
|
|
|||
|
|
@ -944,7 +944,12 @@ static int pci_pm_thaw_noirq(struct device *dev)
|
|||
if (pci_has_legacy_pm_support(pci_dev))
|
||||
return pci_legacy_resume_early(dev);
|
||||
|
||||
pci_update_current_state(pci_dev, PCI_D0);
|
||||
/*
|
||||
* pci_restore_state() requires the device to be in D0 (because of MSI
|
||||
* restoration among other things), so force it into D0 in case the
|
||||
* driver's "freeze" callbacks put it into a low-power state directly.
|
||||
*/
|
||||
pci_set_power_state(pci_dev, PCI_D0);
|
||||
pci_restore_state(pci_dev);
|
||||
|
||||
if (drv && drv->pm && drv->pm->thaw_noirq)
|
||||
|
|
|
|||
|
|
@ -3850,6 +3850,10 @@ static bool pci_bus_resetable(struct pci_bus *bus)
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
|
||||
if (bus->self && (bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
|
||||
return false;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
|
||||
(dev->subordinate && !pci_bus_resetable(dev->subordinate)))
|
||||
|
|
|
|||
|
|
@ -388,7 +388,14 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
|
|||
* If the error is reported by an end point, we think this
|
||||
* error is related to the upstream link of the end point.
|
||||
*/
|
||||
pci_walk_bus(dev->bus, cb, &result_data);
|
||||
if (state == pci_channel_io_normal)
|
||||
/*
|
||||
* the error is non fatal so the bus is ok, just invoke
|
||||
* the callback for the function that logged the error.
|
||||
*/
|
||||
cb(dev, &result_data);
|
||||
else
|
||||
pci_walk_bus(dev->bus, cb, &result_data);
|
||||
}
|
||||
|
||||
return result_data.result;
|
||||
|
|
|
|||
|
|
@ -1338,6 +1338,22 @@ static void st_gpio_irq_unmask(struct irq_data *d)
|
|||
writel(BIT(d->hwirq), bank->base + REG_PIO_SET_PMASK);
|
||||
}
|
||||
|
||||
static int st_gpio_irq_request_resources(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
st_gpio_direction_input(gc, d->hwirq);
|
||||
|
||||
return gpiochip_lock_as_irq(gc, d->hwirq);
|
||||
}
|
||||
|
||||
static void st_gpio_irq_release_resources(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
gpiochip_unlock_as_irq(gc, d->hwirq);
|
||||
}
|
||||
|
||||
static int st_gpio_irq_set_type(struct irq_data *d, unsigned type)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
|
|
@ -1493,12 +1509,14 @@ static struct gpio_chip st_gpio_template = {
|
|||
};
|
||||
|
||||
static struct irq_chip st_gpio_irqchip = {
|
||||
.name = "GPIO",
|
||||
.irq_disable = st_gpio_irq_mask,
|
||||
.irq_mask = st_gpio_irq_mask,
|
||||
.irq_unmask = st_gpio_irq_unmask,
|
||||
.irq_set_type = st_gpio_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
.name = "GPIO",
|
||||
.irq_request_resources = st_gpio_irq_request_resources,
|
||||
.irq_release_resources = st_gpio_irq_release_resources,
|
||||
.irq_disable = st_gpio_irq_mask,
|
||||
.irq_mask = st_gpio_irq_mask,
|
||||
.irq_unmask = st_gpio_irq_unmask,
|
||||
.irq_set_type = st_gpio_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int st_gpiolib_register_bank(struct st_pinctrl *info,
|
||||
|
|
|
|||
|
|
@ -764,7 +764,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
|||
}
|
||||
|
||||
timerqueue_add(&rtc->timerqueue, &timer->node);
|
||||
if (!next) {
|
||||
if (!next || ktime_before(timer->node.expires, next->expires)) {
|
||||
struct rtc_wkalrm alarm;
|
||||
int err;
|
||||
alarm.time = rtc_ktime_to_tm(timer->node.expires);
|
||||
|
|
|
|||
|
|
@ -308,7 +308,8 @@ static int pl031_remove(struct amba_device *adev)
|
|||
|
||||
dev_pm_clear_wake_irq(&adev->dev);
|
||||
device_init_wakeup(&adev->dev, false);
|
||||
free_irq(adev->irq[0], ldata);
|
||||
if (adev->irq[0])
|
||||
free_irq(adev->irq[0], ldata);
|
||||
rtc_device_unregister(ldata->rtc);
|
||||
iounmap(ldata->base);
|
||||
kfree(ldata);
|
||||
|
|
@ -381,12 +382,13 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
goto out_no_rtc;
|
||||
}
|
||||
|
||||
if (request_irq(adev->irq[0], pl031_interrupt,
|
||||
vendor->irqflags, "rtc-pl031", ldata)) {
|
||||
ret = -EIO;
|
||||
goto out_no_irq;
|
||||
if (adev->irq[0]) {
|
||||
ret = request_irq(adev->irq[0], pl031_interrupt,
|
||||
vendor->irqflags, "rtc-pl031", ldata);
|
||||
if (ret)
|
||||
goto out_no_irq;
|
||||
dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
|
||||
}
|
||||
dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
|
||||
return 0;
|
||||
|
||||
out_no_irq:
|
||||
|
|
|
|||
|
|
@ -2680,17 +2680,13 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,
|
|||
char daddr[16];
|
||||
struct af_iucv_trans_hdr *iucv_hdr;
|
||||
|
||||
skb_pull(skb, 14);
|
||||
card->dev->header_ops->create(skb, card->dev, 0,
|
||||
card->dev->dev_addr, card->dev->dev_addr,
|
||||
card->dev->addr_len);
|
||||
skb_pull(skb, 14);
|
||||
iucv_hdr = (struct af_iucv_trans_hdr *)skb->data;
|
||||
memset(hdr, 0, sizeof(struct qeth_hdr));
|
||||
hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
|
||||
hdr->hdr.l3.ext_flags = 0;
|
||||
hdr->hdr.l3.length = skb->len;
|
||||
hdr->hdr.l3.length = skb->len - ETH_HLEN;
|
||||
hdr->hdr.l3.flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
|
||||
|
||||
iucv_hdr = (struct af_iucv_trans_hdr *) (skb->data + ETH_HLEN);
|
||||
memset(daddr, 0, sizeof(daddr));
|
||||
daddr[0] = 0xfe;
|
||||
daddr[1] = 0x80;
|
||||
|
|
@ -2873,10 +2869,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
|
||||
(skb_shinfo(skb)->nr_frags == 0)) {
|
||||
new_skb = skb;
|
||||
if (new_skb->protocol == ETH_P_AF_IUCV)
|
||||
data_offset = 0;
|
||||
else
|
||||
data_offset = ETH_HLEN;
|
||||
data_offset = ETH_HLEN;
|
||||
hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
|
||||
if (!hdr)
|
||||
goto tx_drop;
|
||||
|
|
|
|||
|
|
@ -1339,6 +1339,7 @@ static void release_offload_resources(struct cxgbi_sock *csk)
|
|||
csk, csk->state, csk->flags, csk->tid);
|
||||
|
||||
cxgbi_sock_free_cpl_skbs(csk);
|
||||
cxgbi_sock_purge_write_queue(csk);
|
||||
if (csk->wr_cred != csk->wr_max_cred) {
|
||||
cxgbi_sock_purge_wr_queue(csk);
|
||||
cxgbi_sock_reset_wr_list(csk);
|
||||
|
|
|
|||
|
|
@ -7491,7 +7491,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
did, vport->port_state, ndlp->nlp_flag);
|
||||
|
||||
phba->fc_stat.elsRcvPRLI++;
|
||||
if (vport->port_state < LPFC_DISC_AUTH) {
|
||||
if ((vport->port_state < LPFC_DISC_AUTH) &&
|
||||
(vport->fc_flag & FC_FABRIC)) {
|
||||
rjt_err = LSRJT_UNABLE_TPC;
|
||||
rjt_exp = LSEXP_NOTHING_MORE;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -4777,7 +4777,8 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
lpfc_cancel_retry_delay_tmo(vport, ndlp);
|
||||
if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
|
||||
!(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
|
||||
!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
|
||||
!(ndlp->nlp_flag & NLP_RPI_REGISTERED) &&
|
||||
phba->sli_rev != LPFC_SLI_REV4) {
|
||||
/* For this case we need to cleanup the default rpi
|
||||
* allocated by the firmware.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3180,7 +3180,7 @@ struct lpfc_mbx_get_port_name {
|
|||
#define MB_CEQ_STATUS_QUEUE_FLUSHING 0x4
|
||||
#define MB_CQE_STATUS_DMA_FAILED 0x5
|
||||
|
||||
#define LPFC_MBX_WR_CONFIG_MAX_BDE 8
|
||||
#define LPFC_MBX_WR_CONFIG_MAX_BDE 1
|
||||
struct lpfc_mbx_wr_object {
|
||||
struct mbox_header header;
|
||||
union {
|
||||
|
|
|
|||
|
|
@ -4588,6 +4588,11 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
|||
} else if (log_info == VIRTUAL_IO_FAILED_RETRY) {
|
||||
scmd->result = DID_RESET << 16;
|
||||
break;
|
||||
} else if ((scmd->device->channel == RAID_CHANNEL) &&
|
||||
(scsi_state == (MPI2_SCSI_STATE_TERMINATED |
|
||||
MPI2_SCSI_STATE_NO_SCSI_STATUS))) {
|
||||
scmd->result = DID_RESET << 16;
|
||||
break;
|
||||
}
|
||||
scmd->result = DID_SOFT_ERROR << 16;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
|
|||
while (remaining_words) {
|
||||
int n_words, tx_words, rx_words;
|
||||
u32 sr;
|
||||
int stalled;
|
||||
|
||||
n_words = min(remaining_words, xspi->buffer_size);
|
||||
|
||||
|
|
@ -299,7 +300,17 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
|
|||
|
||||
/* Read out all the data from the Rx FIFO */
|
||||
rx_words = n_words;
|
||||
stalled = 10;
|
||||
while (rx_words) {
|
||||
if (rx_words == n_words && !(stalled--) &&
|
||||
!(sr & XSPI_SR_TX_EMPTY_MASK) &&
|
||||
(sr & XSPI_SR_RX_EMPTY_MASK)) {
|
||||
dev_err(&spi->dev,
|
||||
"Detected stall. Check C_SPI_MODE and C_SPI_MEMORY\n");
|
||||
xspi_init_hw(xspi);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if ((sr & XSPI_SR_TX_EMPTY_MASK) && (rx_words > 1)) {
|
||||
xilinx_spi_rx(xspi);
|
||||
rx_words--;
|
||||
|
|
|
|||
|
|
@ -389,8 +389,11 @@ static int hisi_thermal_suspend(struct device *dev)
|
|||
static int hisi_thermal_resume(struct device *dev)
|
||||
{
|
||||
struct hisi_thermal_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(data->clk);
|
||||
ret = clk_prepare_enable(data->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data->irq_enabled = true;
|
||||
hisi_thermal_enable_bind_irq_sensor(data);
|
||||
|
|
|
|||
|
|
@ -1801,7 +1801,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|||
{
|
||||
struct n_tty_data *ldata = tty->disc_data;
|
||||
|
||||
if (!old || (old->c_lflag ^ tty->termios.c_lflag) & ICANON) {
|
||||
if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) {
|
||||
bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
|
||||
ldata->line_start = ldata->read_tail;
|
||||
if (!L_ICANON(tty) || !read_cnt(ldata)) {
|
||||
|
|
@ -2493,7 +2493,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
|
|||
return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
|
||||
case TIOCINQ:
|
||||
down_write(&tty->termios_rwsem);
|
||||
if (L_ICANON(tty))
|
||||
if (L_ICANON(tty) && !L_EXTPROC(tty))
|
||||
retval = inq_canon(ldata);
|
||||
else
|
||||
retval = read_cnt(ldata);
|
||||
|
|
|
|||
|
|
@ -973,7 +973,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
|||
case USB_SSP_CAP_TYPE:
|
||||
ssp_cap = (struct usb_ssp_cap_descriptor *)buffer;
|
||||
ssac = (le32_to_cpu(ssp_cap->bmAttributes) &
|
||||
USB_SSP_SUBLINK_SPEED_ATTRIBS) + 1;
|
||||
USB_SSP_SUBLINK_SPEED_ATTRIBS);
|
||||
if (length >= USB_DT_USB_SSP_CAP_SIZE(ssac))
|
||||
dev->bos->ssp_cap = ssp_cap;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -57,10 +57,11 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
/* Microsoft LifeCam-VX700 v2.0 */
|
||||
{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech HD Pro Webcams C920, C920-C and C930e */
|
||||
/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
|
||||
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
{ USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
{ USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
{ USB_DEVICE(0x046d, 0x085b), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Logitech ConferenceCam CC3000e */
|
||||
{ USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
|
@ -154,6 +155,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
/* Genesys Logic hub, internally used by KY-688 USB 3.1 Type-C Hub */
|
||||
{ USB_DEVICE(0x05e3, 0x0612), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* ELSA MicroLink 56K */
|
||||
{ USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
|
||||
{ USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
|
|
|
|||
|
|
@ -594,6 +594,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
|
||||
opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
|
||||
|
||||
/* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
|
||||
if (opts->streaming_maxburst &&
|
||||
(opts->streaming_maxpacket % 1024) != 0) {
|
||||
opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
|
||||
INFO(cdev, "overriding streaming_maxpacket to %d\n",
|
||||
opts->streaming_maxpacket);
|
||||
}
|
||||
|
||||
/* Fill in the FS/HS/SS Video Streaming specific descriptors from the
|
||||
* module parameters.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1534,7 +1534,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev,
|
|||
td = phys_to_virt(addr);
|
||||
addr2 = (dma_addr_t)td->next;
|
||||
pci_pool_free(dev->data_requests, td, addr);
|
||||
td->next = 0x00;
|
||||
addr = addr2;
|
||||
}
|
||||
req->chain_len = 1;
|
||||
|
|
|
|||
|
|
@ -184,6 +184,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
|||
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
|
||||
xhci->quirks |= XHCI_BROKEN_STREAMS;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
|
||||
pdev->device == 0x0014)
|
||||
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
|
||||
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
|
||||
pdev->device == 0x0015)
|
||||
xhci->quirks |= XHCI_RESET_ON_RESUME;
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
|
|||
static struct platform_driver usb_xhci_driver = {
|
||||
.probe = xhci_plat_probe,
|
||||
.remove = xhci_plat_remove,
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "xhci-hcd",
|
||||
.pm = DEV_PM_OPS,
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,7 @@ static const struct usb_device_id id_table_combined[] = {
|
|||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) },
|
||||
{ USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) },
|
||||
{ USB_DEVICE(AIRBUS_DS_VID, AIRBUS_DS_P8GR) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -913,6 +913,12 @@
|
|||
#define ICPDAS_I7561U_PID 0x0104
|
||||
#define ICPDAS_I7563U_PID 0x0105
|
||||
|
||||
/*
|
||||
* Airbus Defence and Space
|
||||
*/
|
||||
#define AIRBUS_DS_VID 0x1e8e /* Vendor ID */
|
||||
#define AIRBUS_DS_P8GR 0x6001 /* Tetra P8GR */
|
||||
|
||||
/*
|
||||
* RT Systems programming cables for various ham radios
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -236,6 +236,8 @@ static void option_instat_callback(struct urb *urb);
|
|||
/* These Quectel products use Qualcomm's vendor ID */
|
||||
#define QUECTEL_PRODUCT_UC20 0x9003
|
||||
#define QUECTEL_PRODUCT_UC15 0x9090
|
||||
/* These Yuga products use Qualcomm's vendor ID */
|
||||
#define YUGA_PRODUCT_CLM920_NC5 0x9625
|
||||
|
||||
#define QUECTEL_VENDOR_ID 0x2c7c
|
||||
/* These Quectel products use Quectel's vendor ID */
|
||||
|
|
@ -283,6 +285,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define TELIT_PRODUCT_LE922_USBCFG3 0x1043
|
||||
#define TELIT_PRODUCT_LE922_USBCFG5 0x1045
|
||||
#define TELIT_PRODUCT_ME910 0x1100
|
||||
#define TELIT_PRODUCT_ME910_DUAL_MODEM 0x1101
|
||||
#define TELIT_PRODUCT_LE920 0x1200
|
||||
#define TELIT_PRODUCT_LE910 0x1201
|
||||
#define TELIT_PRODUCT_LE910_USBCFG4 0x1206
|
||||
|
|
@ -648,6 +651,11 @@ static const struct option_blacklist_info telit_me910_blacklist = {
|
|||
.reserved = BIT(1) | BIT(3),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info telit_me910_dual_modem_blacklist = {
|
||||
.sendsetup = BIT(0),
|
||||
.reserved = BIT(3),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info telit_le910_blacklist = {
|
||||
.sendsetup = BIT(0),
|
||||
.reserved = BIT(1) | BIT(2),
|
||||
|
|
@ -677,6 +685,10 @@ static const struct option_blacklist_info cinterion_rmnet2_blacklist = {
|
|||
.reserved = BIT(4) | BIT(5),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info yuga_clm920_nc5_blacklist = {
|
||||
.reserved = BIT(1) | BIT(4),
|
||||
};
|
||||
|
||||
static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
||||
|
|
@ -1181,6 +1193,9 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
/* Yuga products use Qualcomm vendor ID */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5),
|
||||
.driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist },
|
||||
/* Quectel products using Quectel vendor ID */
|
||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
|
|
@ -1247,6 +1262,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||
.driver_info = (kernel_ulong_t)&telit_me910_blacklist },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||
.driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
|
||||
.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ static const struct usb_device_id id_table[] = {
|
|||
{DEVICE_SWI(0x1199, 0x9079)}, /* Sierra Wireless EM74xx */
|
||||
{DEVICE_SWI(0x1199, 0x907a)}, /* Sierra Wireless EM74xx QDL */
|
||||
{DEVICE_SWI(0x1199, 0x907b)}, /* Sierra Wireless EM74xx */
|
||||
{DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */
|
||||
{DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */
|
||||
{DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
|
||||
|
|
@ -346,6 +348,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
|
|||
break;
|
||||
case 2:
|
||||
dev_dbg(dev, "NMEA GPS interface found\n");
|
||||
sendsetup = true;
|
||||
break;
|
||||
case 3:
|
||||
dev_dbg(dev, "Modem port found\n");
|
||||
|
|
|
|||
|
|
@ -252,11 +252,12 @@ void stub_device_cleanup_urbs(struct stub_device *sdev)
|
|||
struct stub_priv *priv;
|
||||
struct urb *urb;
|
||||
|
||||
dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev);
|
||||
dev_dbg(&sdev->udev->dev, "Stub device cleaning up urbs\n");
|
||||
|
||||
while ((priv = stub_priv_pop(sdev))) {
|
||||
urb = priv->urb;
|
||||
dev_dbg(&sdev->udev->dev, "free urb %p\n", urb);
|
||||
dev_dbg(&sdev->udev->dev, "free urb seqnum %lu\n",
|
||||
priv->seqnum);
|
||||
usb_kill_urb(urb);
|
||||
|
||||
kmem_cache_free(stub_priv_cache, priv);
|
||||
|
|
|
|||
|
|
@ -230,9 +230,6 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev,
|
|||
if (priv->seqnum != pdu->u.cmd_unlink.seqnum)
|
||||
continue;
|
||||
|
||||
dev_info(&priv->urb->dev->dev, "unlink urb %p\n",
|
||||
priv->urb);
|
||||
|
||||
/*
|
||||
* This matched urb is not completed yet (i.e., be in
|
||||
* flight in usb hcd hardware/driver). Now we are
|
||||
|
|
@ -271,8 +268,8 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev,
|
|||
ret = usb_unlink_urb(priv->urb);
|
||||
if (ret != -EINPROGRESS)
|
||||
dev_err(&priv->urb->dev->dev,
|
||||
"failed to unlink a urb %p, ret %d\n",
|
||||
priv->urb, ret);
|
||||
"failed to unlink a urb # %lu, ret %d\n",
|
||||
priv->seqnum, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ static int stub_send_ret_submit(struct stub_device *sdev)
|
|||
|
||||
/* 1. setup usbip_header */
|
||||
setup_ret_submit_pdu(&pdu_header, urb);
|
||||
usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n",
|
||||
pdu_header.base.seqnum, urb);
|
||||
usbip_dbg_stub_tx("setup txdata seqnum: %d\n",
|
||||
pdu_header.base.seqnum);
|
||||
usbip_header_correct_endian(&pdu_header, 1);
|
||||
|
||||
iov[iovnum].iov_base = &pdu_header;
|
||||
|
|
|
|||
|
|
@ -467,9 +467,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
|||
int ret = 0;
|
||||
struct vhci_device *vdev;
|
||||
|
||||
usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
|
||||
hcd, urb, mem_flags);
|
||||
|
||||
/* patch to usb_sg_init() is in 2.5.60 */
|
||||
BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length);
|
||||
|
||||
|
|
@ -627,8 +624,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
struct vhci_priv *priv;
|
||||
struct vhci_device *vdev;
|
||||
|
||||
pr_info("dequeue a urb %p\n", urb);
|
||||
|
||||
spin_lock(&the_controller->lock);
|
||||
|
||||
priv = urb->hcpriv;
|
||||
|
|
@ -656,7 +651,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
/* tcp connection is closed */
|
||||
spin_lock(&vdev->priv_lock);
|
||||
|
||||
pr_info("device %p seems to be disconnected\n", vdev);
|
||||
list_del(&priv->list);
|
||||
kfree(priv);
|
||||
urb->hcpriv = NULL;
|
||||
|
|
@ -668,8 +662,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
* vhci_rx will receive RET_UNLINK and give back the URB.
|
||||
* Otherwise, we give back it here.
|
||||
*/
|
||||
pr_info("gives back urb %p\n", urb);
|
||||
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
|
||||
spin_unlock(&the_controller->lock);
|
||||
|
|
@ -698,8 +690,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
|
||||
unlink->unlink_seqnum = priv->seqnum;
|
||||
|
||||
pr_info("device %p seems to be still connected\n", vdev);
|
||||
|
||||
/* send cmd_unlink and try to cancel the pending URB in the
|
||||
* peer */
|
||||
list_add_tail(&unlink->list, &vdev->unlink_tx);
|
||||
|
|
|
|||
|
|
@ -37,24 +37,23 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
|
|||
urb = priv->urb;
|
||||
status = urb->status;
|
||||
|
||||
usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n",
|
||||
urb, priv, seqnum);
|
||||
usbip_dbg_vhci_rx("find urb seqnum %u\n", seqnum);
|
||||
|
||||
switch (status) {
|
||||
case -ENOENT:
|
||||
/* fall through */
|
||||
case -ECONNRESET:
|
||||
dev_info(&urb->dev->dev,
|
||||
"urb %p was unlinked %ssynchronuously.\n", urb,
|
||||
status == -ENOENT ? "" : "a");
|
||||
dev_dbg(&urb->dev->dev,
|
||||
"urb seq# %u was unlinked %ssynchronuously\n",
|
||||
seqnum, status == -ENOENT ? "" : "a");
|
||||
break;
|
||||
case -EINPROGRESS:
|
||||
/* no info output */
|
||||
break;
|
||||
default:
|
||||
dev_info(&urb->dev->dev,
|
||||
"urb %p may be in a error, status %d\n", urb,
|
||||
status);
|
||||
dev_dbg(&urb->dev->dev,
|
||||
"urb seq# %u may be in a error, status %d\n",
|
||||
seqnum, status);
|
||||
}
|
||||
|
||||
list_del(&priv->list);
|
||||
|
|
@ -78,8 +77,8 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
|
|||
spin_unlock(&vdev->priv_lock);
|
||||
|
||||
if (!urb) {
|
||||
pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
|
||||
pr_info("max seqnum %d\n",
|
||||
pr_err("cannot find a urb of seqnum %u max seqnum %d\n",
|
||||
pdu->base.seqnum,
|
||||
atomic_read(&the_controller->seqnum));
|
||||
usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
|
||||
return;
|
||||
|
|
@ -102,7 +101,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
|
|||
if (usbip_dbg_flag_vhci_rx)
|
||||
usbip_dump_urb(urb);
|
||||
|
||||
usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
|
||||
usbip_dbg_vhci_rx("now giveback urb %u\n", pdu->base.seqnum);
|
||||
|
||||
spin_lock(&the_controller->lock);
|
||||
usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
|
||||
|
|
@ -165,7 +164,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
|
|||
pr_info("the urb (seqnum %d) was already given back\n",
|
||||
pdu->base.seqnum);
|
||||
} else {
|
||||
usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
|
||||
usbip_dbg_vhci_rx("now giveback urb %d\n", pdu->base.seqnum);
|
||||
|
||||
/* If unlink is successful, status is -ECONNRESET */
|
||||
urb->status = pdu->u.ret_unlink.status;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
|
|||
memset(&msg, 0, sizeof(msg));
|
||||
memset(&iov, 0, sizeof(iov));
|
||||
|
||||
usbip_dbg_vhci_tx("setup txdata urb %p\n", urb);
|
||||
usbip_dbg_vhci_tx("setup txdata urb seqnum %lu\n",
|
||||
priv->seqnum);
|
||||
|
||||
/* 1. setup usbip_header */
|
||||
setup_cmd_submit_pdu(&pdu_header, urb);
|
||||
|
|
|
|||
|
|
@ -79,14 +79,17 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
|
|||
static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
|
||||
{
|
||||
unsigned int lth = pb->lth_brightness;
|
||||
int duty_cycle;
|
||||
u64 duty_cycle;
|
||||
|
||||
if (pb->levels)
|
||||
duty_cycle = pb->levels[brightness];
|
||||
else
|
||||
duty_cycle = brightness;
|
||||
|
||||
return (duty_cycle * (pb->period - lth) / pb->scale) + lth;
|
||||
duty_cycle *= pb->period - lth;
|
||||
do_div(duty_cycle, pb->scale);
|
||||
|
||||
return duty_cycle + lth;
|
||||
}
|
||||
|
||||
static int pwm_backlight_update_status(struct backlight_device *bl)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user