Merge pull request #25 from MaxKrummenacher/4.9-1.0.x-imx-stable-merge
4.9 1.0.x imx stable merge
This commit is contained in:
commit
5b5a04065f
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 9
|
PATCHLEVEL = 9
|
||||||
SUBLEVEL = 84
|
SUBLEVEL = 87
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Roaring Lionus
|
NAME = Roaring Lionus
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&i2c1 {
|
&i2c1 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&i2c1_pins>;
|
||||||
clock-frequency = <2600000>;
|
clock-frequency = <2600000>;
|
||||||
|
|
||||||
twl: twl@48 {
|
twl: twl@48 {
|
||||||
|
@ -215,7 +217,12 @@
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
i2c1_pins: pinmux_i2c1_pins {
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
|
||||||
|
OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
|
||||||
|
>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&omap3_pmx_wkup {
|
&omap3_pmx_wkup {
|
||||||
|
|
|
@ -100,6 +100,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&i2c1 {
|
&i2c1 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&i2c1_pins>;
|
||||||
clock-frequency = <2600000>;
|
clock-frequency = <2600000>;
|
||||||
|
|
||||||
twl: twl@48 {
|
twl: twl@48 {
|
||||||
|
@ -207,6 +209,12 @@
|
||||||
OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
|
OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
i2c1_pins: pinmux_i2c1_pins {
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
|
||||||
|
OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
|
||||||
|
>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&uart2 {
|
&uart2 {
|
||||||
|
|
|
@ -215,7 +215,7 @@
|
||||||
reg = <0x2a>;
|
reg = <0x2a>;
|
||||||
VDDA-supply = <®_3p3v>;
|
VDDA-supply = <®_3p3v>;
|
||||||
VDDIO-supply = <®_3p3v>;
|
VDDIO-supply = <®_3p3v>;
|
||||||
clocks = <&sys_mclk 1>;
|
clocks = <&sys_mclk>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -187,7 +187,7 @@
|
||||||
reg = <0x0a>;
|
reg = <0x0a>;
|
||||||
VDDA-supply = <®_3p3v>;
|
VDDA-supply = <®_3p3v>;
|
||||||
VDDIO-supply = <®_3p3v>;
|
VDDIO-supply = <®_3p3v>;
|
||||||
clocks = <&sys_mclk 1>;
|
clocks = <&sys_mclk>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING
|
||||||
|
|
||||||
KVM=../../../../virt/kvm
|
KVM=../../../../virt/kvm
|
||||||
|
|
||||||
|
CFLAGS_ARMV7VE :=$(call cc-option, -march=armv7ve)
|
||||||
|
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
|
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
|
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
|
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
|
||||||
|
@ -14,7 +16,10 @@ obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += cp15-sr.o
|
obj-$(CONFIG_KVM_ARM_HOST) += cp15-sr.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += vfp.o
|
obj-$(CONFIG_KVM_ARM_HOST) += vfp.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o
|
obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o
|
||||||
|
CFLAGS_banked-sr.o += $(CFLAGS_ARMV7VE)
|
||||||
|
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += entry.o
|
obj-$(CONFIG_KVM_ARM_HOST) += entry.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o
|
obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += switch.o
|
obj-$(CONFIG_KVM_ARM_HOST) += switch.o
|
||||||
|
CFLAGS_switch.o += $(CFLAGS_ARMV7VE)
|
||||||
obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o
|
obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
|
|
||||||
#include <asm/kvm_hyp.h>
|
#include <asm/kvm_hyp.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gcc before 4.9 doesn't understand -march=armv7ve, so we have to
|
||||||
|
* trick the assembler.
|
||||||
|
*/
|
||||||
__asm__(".arch_extension virt");
|
__asm__(".arch_extension virt");
|
||||||
|
|
||||||
void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt)
|
void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt)
|
||||||
|
|
|
@ -1284,7 +1284,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vma_kernel_pagesize(vma) && !logging_active) {
|
if (vma_kernel_pagesize(vma) == PMD_SIZE && !logging_active) {
|
||||||
hugetlb = true;
|
hugetlb = true;
|
||||||
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
|
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -85,7 +85,11 @@
|
||||||
.pushsection .text.fixup,"ax"
|
.pushsection .text.fixup,"ax"
|
||||||
.align 4
|
.align 4
|
||||||
9001: mov r4, #-EFAULT
|
9001: mov r4, #-EFAULT
|
||||||
|
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
|
||||||
|
ldr r5, [sp, #9*4] @ *err_ptr
|
||||||
|
#else
|
||||||
ldr r5, [sp, #8*4] @ *err_ptr
|
ldr r5, [sp, #8*4] @ *err_ptr
|
||||||
|
#endif
|
||||||
str r4, [r5]
|
str r4, [r5]
|
||||||
ldmia sp, {r1, r2} @ retrieve dst, len
|
ldmia sp, {r1, r2} @ retrieve dst, len
|
||||||
add r2, r2, r1
|
add r2, r2, r1
|
||||||
|
|
|
@ -42,7 +42,7 @@ config MACH_ARMADA_375
|
||||||
depends on ARCH_MULTI_V7
|
depends on ARCH_MULTI_V7
|
||||||
select ARMADA_370_XP_IRQ
|
select ARMADA_370_XP_IRQ
|
||||||
select ARM_ERRATA_720789
|
select ARM_ERRATA_720789
|
||||||
select ARM_ERRATA_753970
|
select PL310_ERRATA_753970
|
||||||
select ARM_GIC
|
select ARM_GIC
|
||||||
select ARMADA_375_CLK
|
select ARMADA_375_CLK
|
||||||
select HAVE_ARM_SCU
|
select HAVE_ARM_SCU
|
||||||
|
@ -58,7 +58,7 @@ config MACH_ARMADA_38X
|
||||||
bool "Marvell Armada 380/385 boards"
|
bool "Marvell Armada 380/385 boards"
|
||||||
depends on ARCH_MULTI_V7
|
depends on ARCH_MULTI_V7
|
||||||
select ARM_ERRATA_720789
|
select ARM_ERRATA_720789
|
||||||
select ARM_ERRATA_753970
|
select PL310_ERRATA_753970
|
||||||
select ARM_GIC
|
select ARM_GIC
|
||||||
select ARMADA_370_XP_IRQ
|
select ARMADA_370_XP_IRQ
|
||||||
select ARMADA_38X_CLK
|
select ARMADA_38X_CLK
|
||||||
|
|
|
@ -50,7 +50,7 @@ static const char *handler[]= {
|
||||||
"Error"
|
"Error"
|
||||||
};
|
};
|
||||||
|
|
||||||
int show_unhandled_signals = 1;
|
int show_unhandled_signals = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump out the contents of some kernel memory nicely...
|
* Dump out the contents of some kernel memory nicely...
|
||||||
|
|
|
@ -234,8 +234,9 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
|
||||||
off = offsetof(struct bpf_array, map.max_entries);
|
off = offsetof(struct bpf_array, map.max_entries);
|
||||||
emit_a64_mov_i64(tmp, off, ctx);
|
emit_a64_mov_i64(tmp, off, ctx);
|
||||||
emit(A64_LDR32(tmp, r2, tmp), ctx);
|
emit(A64_LDR32(tmp, r2, tmp), ctx);
|
||||||
|
emit(A64_MOV(0, r3, r3), ctx);
|
||||||
emit(A64_CMP(0, r3, tmp), ctx);
|
emit(A64_CMP(0, r3, tmp), ctx);
|
||||||
emit(A64_B_(A64_COND_GE, jmp_offset), ctx);
|
emit(A64_B_(A64_COND_CS, jmp_offset), ctx);
|
||||||
|
|
||||||
/* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
|
/* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
|
||||||
* goto out;
|
* goto out;
|
||||||
|
@ -243,7 +244,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
|
||||||
*/
|
*/
|
||||||
emit_a64_mov_i64(tmp, MAX_TAIL_CALL_CNT, ctx);
|
emit_a64_mov_i64(tmp, MAX_TAIL_CALL_CNT, ctx);
|
||||||
emit(A64_CMP(1, tcc, tmp), ctx);
|
emit(A64_CMP(1, tcc, tmp), ctx);
|
||||||
emit(A64_B_(A64_COND_GT, jmp_offset), ctx);
|
emit(A64_B_(A64_COND_HI, jmp_offset), ctx);
|
||||||
emit(A64_ADD_I(1, tcc, tcc, 1), ctx);
|
emit(A64_ADD_I(1, tcc, tcc, 1), ctx);
|
||||||
|
|
||||||
/* prog = array->ptrs[index];
|
/* prog = array->ptrs[index];
|
||||||
|
|
|
@ -15,4 +15,5 @@ obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
|
||||||
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
|
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
|
||||||
|
|
||||||
# libgcc-style stuff needed in the kernel
|
# libgcc-style stuff needed in the kernel
|
||||||
obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o ucmpdi2.o
|
obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o multi3.o \
|
||||||
|
ucmpdi2.o
|
||||||
|
|
|
@ -9,10 +9,18 @@ typedef int word_type __attribute__ ((mode (__word__)));
|
||||||
struct DWstruct {
|
struct DWstruct {
|
||||||
int high, low;
|
int high, low;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TWstruct {
|
||||||
|
long long high, low;
|
||||||
|
};
|
||||||
#elif defined(__LITTLE_ENDIAN)
|
#elif defined(__LITTLE_ENDIAN)
|
||||||
struct DWstruct {
|
struct DWstruct {
|
||||||
int low, high;
|
int low, high;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TWstruct {
|
||||||
|
long long low, high;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
#error I feel sick.
|
#error I feel sick.
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,4 +30,13 @@ typedef union {
|
||||||
long long ll;
|
long long ll;
|
||||||
} DWunion;
|
} DWunion;
|
||||||
|
|
||||||
|
#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6)
|
||||||
|
typedef int ti_type __attribute__((mode(TI)));
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct TWstruct s;
|
||||||
|
ti_type ti;
|
||||||
|
} TWunion;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ASM_LIBGCC_H */
|
#endif /* __ASM_LIBGCC_H */
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <linux/export.h>
|
||||||
|
|
||||||
|
#include "libgcc.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GCC 7 suboptimally generates __multi3 calls for mips64r6, so for that
|
||||||
|
* specific case only we'll implement it here.
|
||||||
|
*
|
||||||
|
* See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ == 7)
|
||||||
|
|
||||||
|
/* multiply 64-bit values, low 64-bits returned */
|
||||||
|
static inline long long notrace dmulu(long long a, long long b)
|
||||||
|
{
|
||||||
|
long long res;
|
||||||
|
|
||||||
|
asm ("dmulu %0,%1,%2" : "=r" (res) : "r" (a), "r" (b));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* multiply 64-bit unsigned values, high 64-bits of 128-bit result returned */
|
||||||
|
static inline long long notrace dmuhu(long long a, long long b)
|
||||||
|
{
|
||||||
|
long long res;
|
||||||
|
|
||||||
|
asm ("dmuhu %0,%1,%2" : "=r" (res) : "r" (a), "r" (b));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* multiply 128-bit values, low 128-bits returned */
|
||||||
|
ti_type notrace __multi3(ti_type a, ti_type b)
|
||||||
|
{
|
||||||
|
TWunion res, aa, bb;
|
||||||
|
|
||||||
|
aa.ti = a;
|
||||||
|
bb.ti = b;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a * b = (a.lo * b.lo)
|
||||||
|
* + 2^64 * (a.hi * b.lo + a.lo * b.hi)
|
||||||
|
* [+ 2^128 * (a.hi * b.hi)]
|
||||||
|
*/
|
||||||
|
res.s.low = dmulu(aa.s.low, bb.s.low);
|
||||||
|
res.s.high = dmuhu(aa.s.low, bb.s.low);
|
||||||
|
res.s.high += dmulu(aa.s.high, bb.s.low);
|
||||||
|
res.s.high += dmulu(aa.s.low, bb.s.high);
|
||||||
|
|
||||||
|
return res.ti;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__multi3);
|
||||||
|
|
||||||
|
#endif /* 64BIT && CPU_MIPSR6 && GCC7 */
|
|
@ -25,6 +25,7 @@ void flush_user_icache_range_asm(unsigned long, unsigned long);
|
||||||
void flush_kernel_icache_range_asm(unsigned long, unsigned long);
|
void flush_kernel_icache_range_asm(unsigned long, unsigned long);
|
||||||
void flush_user_dcache_range_asm(unsigned long, unsigned long);
|
void flush_user_dcache_range_asm(unsigned long, unsigned long);
|
||||||
void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
|
void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
|
||||||
|
void purge_kernel_dcache_range_asm(unsigned long, unsigned long);
|
||||||
void flush_kernel_dcache_page_asm(void *);
|
void flush_kernel_dcache_page_asm(void *);
|
||||||
void flush_kernel_icache_page(void *);
|
void flush_kernel_icache_page(void *);
|
||||||
void flush_user_dcache_range(unsigned long, unsigned long);
|
void flush_user_dcache_range(unsigned long, unsigned long);
|
||||||
|
|
|
@ -464,10 +464,10 @@ EXPORT_SYMBOL(copy_user_page);
|
||||||
int __flush_tlb_range(unsigned long sid, unsigned long start,
|
int __flush_tlb_range(unsigned long sid, unsigned long start,
|
||||||
unsigned long end)
|
unsigned long end)
|
||||||
{
|
{
|
||||||
unsigned long flags, size;
|
unsigned long flags;
|
||||||
|
|
||||||
size = (end - start);
|
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
|
||||||
if (size >= parisc_tlb_flush_threshold) {
|
end - start >= parisc_tlb_flush_threshold) {
|
||||||
flush_tlb_all();
|
flush_tlb_all();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -538,13 +538,11 @@ void flush_cache_mm(struct mm_struct *mm)
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
pgd_t *pgd;
|
pgd_t *pgd;
|
||||||
|
|
||||||
/* Flush the TLB to avoid speculation if coherency is required. */
|
|
||||||
if (parisc_requires_coherency())
|
|
||||||
flush_tlb_all();
|
|
||||||
|
|
||||||
/* Flushing the whole cache on each cpu takes forever on
|
/* Flushing the whole cache on each cpu takes forever on
|
||||||
rp3440, etc. So, avoid it if the mm isn't too big. */
|
rp3440, etc. So, avoid it if the mm isn't too big. */
|
||||||
if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
|
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
|
||||||
|
mm_total_size(mm) >= parisc_cache_flush_threshold) {
|
||||||
|
flush_tlb_all();
|
||||||
flush_cache_all();
|
flush_cache_all();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -552,9 +550,9 @@ void flush_cache_mm(struct mm_struct *mm)
|
||||||
if (mm->context == mfsp(3)) {
|
if (mm->context == mfsp(3)) {
|
||||||
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
for (vma = mm->mmap; vma; vma = vma->vm_next) {
|
||||||
flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
|
flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
|
||||||
if ((vma->vm_flags & VM_EXEC) == 0)
|
if (vma->vm_flags & VM_EXEC)
|
||||||
continue;
|
flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
|
||||||
flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
|
flush_tlb_range(vma, vma->vm_start, vma->vm_end);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -598,14 +596,9 @@ flush_user_icache_range(unsigned long start, unsigned long end)
|
||||||
void flush_cache_range(struct vm_area_struct *vma,
|
void flush_cache_range(struct vm_area_struct *vma,
|
||||||
unsigned long start, unsigned long end)
|
unsigned long start, unsigned long end)
|
||||||
{
|
{
|
||||||
BUG_ON(!vma->vm_mm->context);
|
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
|
||||||
|
end - start >= parisc_cache_flush_threshold) {
|
||||||
/* Flush the TLB to avoid speculation if coherency is required. */
|
|
||||||
if (parisc_requires_coherency())
|
|
||||||
flush_tlb_range(vma, start, end);
|
flush_tlb_range(vma, start, end);
|
||||||
|
|
||||||
if ((end - start) >= parisc_cache_flush_threshold
|
|
||||||
|| vma->vm_mm->context != mfsp(3)) {
|
|
||||||
flush_cache_all();
|
flush_cache_all();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -613,6 +606,7 @@ void flush_cache_range(struct vm_area_struct *vma,
|
||||||
flush_user_dcache_range_asm(start, end);
|
flush_user_dcache_range_asm(start, end);
|
||||||
if (vma->vm_flags & VM_EXEC)
|
if (vma->vm_flags & VM_EXEC)
|
||||||
flush_user_icache_range_asm(start, end);
|
flush_user_icache_range_asm(start, end);
|
||||||
|
flush_tlb_range(vma, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -621,8 +615,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
|
||||||
BUG_ON(!vma->vm_mm->context);
|
BUG_ON(!vma->vm_mm->context);
|
||||||
|
|
||||||
if (pfn_valid(pfn)) {
|
if (pfn_valid(pfn)) {
|
||||||
if (parisc_requires_coherency())
|
flush_tlb_page(vma, vmaddr);
|
||||||
flush_tlb_page(vma, vmaddr);
|
|
||||||
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,21 +623,33 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
|
||||||
void flush_kernel_vmap_range(void *vaddr, int size)
|
void flush_kernel_vmap_range(void *vaddr, int size)
|
||||||
{
|
{
|
||||||
unsigned long start = (unsigned long)vaddr;
|
unsigned long start = (unsigned long)vaddr;
|
||||||
|
unsigned long end = start + size;
|
||||||
|
|
||||||
if ((unsigned long)size > parisc_cache_flush_threshold)
|
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
|
||||||
|
(unsigned long)size >= parisc_cache_flush_threshold) {
|
||||||
|
flush_tlb_kernel_range(start, end);
|
||||||
flush_data_cache();
|
flush_data_cache();
|
||||||
else
|
return;
|
||||||
flush_kernel_dcache_range_asm(start, start + size);
|
}
|
||||||
|
|
||||||
|
flush_kernel_dcache_range_asm(start, end);
|
||||||
|
flush_tlb_kernel_range(start, end);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(flush_kernel_vmap_range);
|
EXPORT_SYMBOL(flush_kernel_vmap_range);
|
||||||
|
|
||||||
void invalidate_kernel_vmap_range(void *vaddr, int size)
|
void invalidate_kernel_vmap_range(void *vaddr, int size)
|
||||||
{
|
{
|
||||||
unsigned long start = (unsigned long)vaddr;
|
unsigned long start = (unsigned long)vaddr;
|
||||||
|
unsigned long end = start + size;
|
||||||
|
|
||||||
if ((unsigned long)size > parisc_cache_flush_threshold)
|
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
|
||||||
|
(unsigned long)size >= parisc_cache_flush_threshold) {
|
||||||
|
flush_tlb_kernel_range(start, end);
|
||||||
flush_data_cache();
|
flush_data_cache();
|
||||||
else
|
return;
|
||||||
flush_kernel_dcache_range_asm(start, start + size);
|
}
|
||||||
|
|
||||||
|
purge_kernel_dcache_range_asm(start, end);
|
||||||
|
flush_tlb_kernel_range(start, end);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(invalidate_kernel_vmap_range);
|
EXPORT_SYMBOL(invalidate_kernel_vmap_range);
|
||||||
|
|
|
@ -1110,6 +1110,28 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
|
||||||
.procend
|
.procend
|
||||||
ENDPROC_CFI(flush_kernel_dcache_range_asm)
|
ENDPROC_CFI(flush_kernel_dcache_range_asm)
|
||||||
|
|
||||||
|
ENTRY_CFI(purge_kernel_dcache_range_asm)
|
||||||
|
.proc
|
||||||
|
.callinfo NO_CALLS
|
||||||
|
.entry
|
||||||
|
|
||||||
|
ldil L%dcache_stride, %r1
|
||||||
|
ldw R%dcache_stride(%r1), %r23
|
||||||
|
ldo -1(%r23), %r21
|
||||||
|
ANDCM %r26, %r21, %r26
|
||||||
|
|
||||||
|
1: cmpb,COND(<<),n %r26, %r25,1b
|
||||||
|
pdc,m %r23(%r26)
|
||||||
|
|
||||||
|
sync
|
||||||
|
syncdma
|
||||||
|
bv %r0(%r2)
|
||||||
|
nop
|
||||||
|
.exit
|
||||||
|
|
||||||
|
.procend
|
||||||
|
ENDPROC_CFI(purge_kernel_dcache_range_asm)
|
||||||
|
|
||||||
ENTRY_CFI(flush_user_icache_range_asm)
|
ENTRY_CFI(flush_user_icache_range_asm)
|
||||||
.proc
|
.proc
|
||||||
.callinfo NO_CALLS
|
.callinfo NO_CALLS
|
||||||
|
|
|
@ -245,6 +245,7 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
|
||||||
* goto out;
|
* goto out;
|
||||||
*/
|
*/
|
||||||
PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries));
|
PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries));
|
||||||
|
PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31);
|
||||||
PPC_CMPLW(b2p_index, b2p[TMP_REG_1]);
|
PPC_CMPLW(b2p_index, b2p[TMP_REG_1]);
|
||||||
PPC_BCC(COND_GE, out);
|
PPC_BCC(COND_GE, out);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/sh_eth.h>
|
||||||
#include <mach-se/mach/se.h>
|
#include <mach-se/mach/se.h>
|
||||||
#include <mach-se/mach/mrshpc.h>
|
#include <mach-se/mach/mrshpc.h>
|
||||||
#include <asm/machvec.h>
|
#include <asm/machvec.h>
|
||||||
|
@ -114,6 +115,11 @@ static struct platform_device heartbeat_device = {
|
||||||
#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
|
#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
|
||||||
defined(CONFIG_CPU_SUBTYPE_SH7712)
|
defined(CONFIG_CPU_SUBTYPE_SH7712)
|
||||||
/* SH771X Ethernet driver */
|
/* SH771X Ethernet driver */
|
||||||
|
static struct sh_eth_plat_data sh_eth_plat = {
|
||||||
|
.phy = PHY_ID,
|
||||||
|
.phy_interface = PHY_INTERFACE_MODE_MII,
|
||||||
|
};
|
||||||
|
|
||||||
static struct resource sh_eth0_resources[] = {
|
static struct resource sh_eth0_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.start = SH_ETH0_BASE,
|
.start = SH_ETH0_BASE,
|
||||||
|
@ -131,7 +137,7 @@ static struct platform_device sh_eth0_device = {
|
||||||
.name = "sh771x-ether",
|
.name = "sh771x-ether",
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.dev = {
|
.dev = {
|
||||||
.platform_data = PHY_ID,
|
.platform_data = &sh_eth_plat,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(sh_eth0_resources),
|
.num_resources = ARRAY_SIZE(sh_eth0_resources),
|
||||||
.resource = sh_eth0_resources,
|
.resource = sh_eth0_resources,
|
||||||
|
@ -154,7 +160,7 @@ static struct platform_device sh_eth1_device = {
|
||||||
.name = "sh771x-ether",
|
.name = "sh771x-ether",
|
||||||
.id = 1,
|
.id = 1,
|
||||||
.dev = {
|
.dev = {
|
||||||
.platform_data = PHY_ID,
|
.platform_data = &sh_eth_plat,
|
||||||
},
|
},
|
||||||
.num_resources = ARRAY_SIZE(sh_eth1_resources),
|
.num_resources = ARRAY_SIZE(sh_eth1_resources),
|
||||||
.resource = sh_eth1_resources,
|
.resource = sh_eth1_resources,
|
||||||
|
|
|
@ -176,13 +176,26 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
|
||||||
pushq %r8 /* pt_regs->r8 */
|
pushq %r8 /* pt_regs->r8 */
|
||||||
pushq %r9 /* pt_regs->r9 */
|
pushq %r9 /* pt_regs->r9 */
|
||||||
pushq %r10 /* pt_regs->r10 */
|
pushq %r10 /* pt_regs->r10 */
|
||||||
|
/*
|
||||||
|
* Clear extra registers that a speculation attack might
|
||||||
|
* otherwise want to exploit. Interleave XOR with PUSH
|
||||||
|
* for better uop scheduling:
|
||||||
|
*/
|
||||||
|
xorq %r10, %r10 /* nospec r10 */
|
||||||
pushq %r11 /* pt_regs->r11 */
|
pushq %r11 /* pt_regs->r11 */
|
||||||
|
xorq %r11, %r11 /* nospec r11 */
|
||||||
pushq %rbx /* pt_regs->rbx */
|
pushq %rbx /* pt_regs->rbx */
|
||||||
|
xorl %ebx, %ebx /* nospec rbx */
|
||||||
pushq %rbp /* pt_regs->rbp */
|
pushq %rbp /* pt_regs->rbp */
|
||||||
|
xorl %ebp, %ebp /* nospec rbp */
|
||||||
pushq %r12 /* pt_regs->r12 */
|
pushq %r12 /* pt_regs->r12 */
|
||||||
|
xorq %r12, %r12 /* nospec r12 */
|
||||||
pushq %r13 /* pt_regs->r13 */
|
pushq %r13 /* pt_regs->r13 */
|
||||||
|
xorq %r13, %r13 /* nospec r13 */
|
||||||
pushq %r14 /* pt_regs->r14 */
|
pushq %r14 /* pt_regs->r14 */
|
||||||
|
xorq %r14, %r14 /* nospec r14 */
|
||||||
pushq %r15 /* pt_regs->r15 */
|
pushq %r15 /* pt_regs->r15 */
|
||||||
|
xorq %r15, %r15 /* nospec r15 */
|
||||||
|
|
||||||
/* IRQs are off. */
|
/* IRQs are off. */
|
||||||
movq %rsp, %rdi
|
movq %rsp, %rdi
|
||||||
|
|
|
@ -128,6 +128,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
#ifndef __BPF__
|
||||||
/*
|
/*
|
||||||
* This output constraint should be used for any inline asm which has a "call"
|
* This output constraint should be used for any inline asm which has a "call"
|
||||||
* instruction. Otherwise the asm may be inserted before the frame pointer
|
* instruction. Otherwise the asm may be inserted before the frame pointer
|
||||||
|
@ -137,5 +138,6 @@
|
||||||
register unsigned long current_stack_pointer asm(_ASM_SP);
|
register unsigned long current_stack_pointer asm(_ASM_SP);
|
||||||
#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
|
#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_X86_ASM_H */
|
#endif /* _ASM_X86_ASM_H */
|
||||||
|
|
|
@ -3,12 +3,18 @@
|
||||||
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/atomic.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The x86 doesn't have a mmu context, but
|
* x86 has arch-specific MMU state beyond what lives in mm_struct.
|
||||||
* we put the segment information here.
|
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/*
|
||||||
|
* ctx_id uniquely identifies this mm_struct. A ctx_id will never
|
||||||
|
* be reused, and zero is not a valid ctx_id.
|
||||||
|
*/
|
||||||
|
u64 ctx_id;
|
||||||
|
|
||||||
#ifdef CONFIG_MODIFY_LDT_SYSCALL
|
#ifdef CONFIG_MODIFY_LDT_SYSCALL
|
||||||
struct ldt_struct *ldt;
|
struct ldt_struct *ldt;
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,6 +39,11 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
} mm_context_t;
|
} mm_context_t;
|
||||||
|
|
||||||
|
#define INIT_MM_CONTEXT(mm) \
|
||||||
|
.context = { \
|
||||||
|
.ctx_id = 1, \
|
||||||
|
}
|
||||||
|
|
||||||
void leave_mm(int cpu);
|
void leave_mm(int cpu);
|
||||||
|
|
||||||
#endif /* _ASM_X86_MMU_H */
|
#endif /* _ASM_X86_MMU_H */
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/paravirt.h>
|
#include <asm/paravirt.h>
|
||||||
#include <asm/mpx.h>
|
#include <asm/mpx.h>
|
||||||
|
|
||||||
|
extern atomic64_t last_mm_ctx_id;
|
||||||
|
|
||||||
#ifndef CONFIG_PARAVIRT
|
#ifndef CONFIG_PARAVIRT
|
||||||
static inline void paravirt_activate_mm(struct mm_struct *prev,
|
static inline void paravirt_activate_mm(struct mm_struct *prev,
|
||||||
struct mm_struct *next)
|
struct mm_struct *next)
|
||||||
|
@ -106,6 +109,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||||
static inline int init_new_context(struct task_struct *tsk,
|
static inline int init_new_context(struct task_struct *tsk,
|
||||||
struct mm_struct *mm)
|
struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
|
mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
|
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
|
||||||
if (cpu_feature_enabled(X86_FEATURE_OSPKE)) {
|
if (cpu_feature_enabled(X86_FEATURE_OSPKE)) {
|
||||||
/* pkey 0 is the default and always allocated */
|
/* pkey 0 is the default and always allocated */
|
||||||
|
|
|
@ -177,4 +177,41 @@ static inline void indirect_branch_prediction_barrier(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Below is used in the eBPF JIT compiler and emits the byte sequence
|
||||||
|
* for the following assembly:
|
||||||
|
*
|
||||||
|
* With retpolines configured:
|
||||||
|
*
|
||||||
|
* callq do_rop
|
||||||
|
* spec_trap:
|
||||||
|
* pause
|
||||||
|
* lfence
|
||||||
|
* jmp spec_trap
|
||||||
|
* do_rop:
|
||||||
|
* mov %rax,(%rsp)
|
||||||
|
* retq
|
||||||
|
*
|
||||||
|
* Without retpolines configured:
|
||||||
|
*
|
||||||
|
* jmp *%rax
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_RETPOLINE
|
||||||
|
# define RETPOLINE_RAX_BPF_JIT_SIZE 17
|
||||||
|
# define RETPOLINE_RAX_BPF_JIT() \
|
||||||
|
EMIT1_off32(0xE8, 7); /* callq do_rop */ \
|
||||||
|
/* spec_trap: */ \
|
||||||
|
EMIT2(0xF3, 0x90); /* pause */ \
|
||||||
|
EMIT3(0x0F, 0xAE, 0xE8); /* lfence */ \
|
||||||
|
EMIT2(0xEB, 0xF9); /* jmp spec_trap */ \
|
||||||
|
/* do_rop: */ \
|
||||||
|
EMIT4(0x48, 0x89, 0x04, 0x24); /* mov %rax,(%rsp) */ \
|
||||||
|
EMIT1(0xC3); /* retq */
|
||||||
|
#else
|
||||||
|
# define RETPOLINE_RAX_BPF_JIT_SIZE 2
|
||||||
|
# define RETPOLINE_RAX_BPF_JIT() \
|
||||||
|
EMIT2(0xFF, 0xE0); /* jmp *%rax */
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_X86_NOSPEC_BRANCH_H_ */
|
#endif /* _ASM_X86_NOSPEC_BRANCH_H_ */
|
||||||
|
|
|
@ -68,6 +68,8 @@ static inline void invpcid_flush_all_nonglobals(void)
|
||||||
struct tlb_state {
|
struct tlb_state {
|
||||||
struct mm_struct *active_mm;
|
struct mm_struct *active_mm;
|
||||||
int state;
|
int state;
|
||||||
|
/* last user mm's ctx id */
|
||||||
|
u64 last_ctx_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access to this CR4 shadow and to H/W CR4 is protected by
|
* Access to this CR4 shadow and to H/W CR4 is protected by
|
||||||
|
|
|
@ -93,8 +93,12 @@ out_data:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_apic_chip_data(struct apic_chip_data *data)
|
static void free_apic_chip_data(unsigned int virq, struct apic_chip_data *data)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
|
if (virq < nr_legacy_irqs())
|
||||||
|
legacy_irq_data[virq] = NULL;
|
||||||
|
#endif
|
||||||
if (data) {
|
if (data) {
|
||||||
free_cpumask_var(data->domain);
|
free_cpumask_var(data->domain);
|
||||||
free_cpumask_var(data->old_domain);
|
free_cpumask_var(data->old_domain);
|
||||||
|
@ -318,11 +322,7 @@ static void x86_vector_free_irqs(struct irq_domain *domain,
|
||||||
apic_data = irq_data->chip_data;
|
apic_data = irq_data->chip_data;
|
||||||
irq_domain_reset_irq_data(irq_data);
|
irq_domain_reset_irq_data(irq_data);
|
||||||
raw_spin_unlock_irqrestore(&vector_lock, flags);
|
raw_spin_unlock_irqrestore(&vector_lock, flags);
|
||||||
free_apic_chip_data(apic_data);
|
free_apic_chip_data(virq + i, apic_data);
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
|
||||||
if (virq + i < nr_legacy_irqs())
|
|
||||||
legacy_irq_data[virq + i] = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,7 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
|
||||||
err = assign_irq_vector_policy(virq + i, node, data, info);
|
err = assign_irq_vector_policy(virq + i, node, data, info);
|
||||||
if (err) {
|
if (err) {
|
||||||
irq_data->chip_data = NULL;
|
irq_data->chip_data = NULL;
|
||||||
free_apic_chip_data(data);
|
free_apic_chip_data(virq + i, data);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include <asm/debugreg.h>
|
#include <asm/debugreg.h>
|
||||||
#include <asm/kvm_para.h>
|
#include <asm/kvm_para.h>
|
||||||
#include <asm/irq_remapping.h>
|
#include <asm/irq_remapping.h>
|
||||||
|
#include <asm/microcode.h>
|
||||||
#include <asm/nospec-branch.h>
|
#include <asm/nospec-branch.h>
|
||||||
|
|
||||||
#include <asm/virtext.h>
|
#include <asm/virtext.h>
|
||||||
|
@ -4919,7 +4920,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
|
||||||
* being speculatively taken.
|
* being speculatively taken.
|
||||||
*/
|
*/
|
||||||
if (svm->spec_ctrl)
|
if (svm->spec_ctrl)
|
||||||
wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
|
native_wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"push %%" _ASM_BP "; \n\t"
|
"push %%" _ASM_BP "; \n\t"
|
||||||
|
@ -5028,11 +5029,11 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
|
||||||
* If the L02 MSR bitmap does not intercept the MSR, then we need to
|
* If the L02 MSR bitmap does not intercept the MSR, then we need to
|
||||||
* save it.
|
* save it.
|
||||||
*/
|
*/
|
||||||
if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
|
if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
|
||||||
rdmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
|
svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
|
||||||
|
|
||||||
if (svm->spec_ctrl)
|
if (svm->spec_ctrl)
|
||||||
wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
||||||
|
|
||||||
/* Eliminate branch target predictions from guest mode */
|
/* Eliminate branch target predictions from guest mode */
|
||||||
vmexit_fill_RSB();
|
vmexit_fill_RSB();
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include <asm/kexec.h>
|
#include <asm/kexec.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/irq_remapping.h>
|
#include <asm/irq_remapping.h>
|
||||||
|
#include <asm/microcode.h>
|
||||||
#include <asm/nospec-branch.h>
|
#include <asm/nospec-branch.h>
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
@ -8906,7 +8907,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||||
* being speculatively taken.
|
* being speculatively taken.
|
||||||
*/
|
*/
|
||||||
if (vmx->spec_ctrl)
|
if (vmx->spec_ctrl)
|
||||||
wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
|
native_wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
|
||||||
|
|
||||||
vmx->__launched = vmx->loaded_vmcs->launched;
|
vmx->__launched = vmx->loaded_vmcs->launched;
|
||||||
asm(
|
asm(
|
||||||
|
@ -9041,11 +9042,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
|
||||||
* If the L02 MSR bitmap does not intercept the MSR, then we need to
|
* If the L02 MSR bitmap does not intercept the MSR, then we need to
|
||||||
* save it.
|
* save it.
|
||||||
*/
|
*/
|
||||||
if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
|
if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
|
||||||
rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
|
vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
|
||||||
|
|
||||||
if (vmx->spec_ctrl)
|
if (vmx->spec_ctrl)
|
||||||
wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
||||||
|
|
||||||
/* Eliminate branch target predictions from guest mode */
|
/* Eliminate branch target predictions from guest mode */
|
||||||
vmexit_fill_RSB();
|
vmexit_fill_RSB();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
|
#include <asm/nospec-branch.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/uv/uv.h>
|
#include <asm/uv/uv.h>
|
||||||
|
@ -29,6 +30,8 @@
|
||||||
* Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi
|
* Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
|
||||||
|
|
||||||
struct flush_tlb_info {
|
struct flush_tlb_info {
|
||||||
struct mm_struct *flush_mm;
|
struct mm_struct *flush_mm;
|
||||||
unsigned long flush_start;
|
unsigned long flush_start;
|
||||||
|
@ -104,6 +107,28 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
||||||
unsigned cpu = smp_processor_id();
|
unsigned cpu = smp_processor_id();
|
||||||
|
|
||||||
if (likely(prev != next)) {
|
if (likely(prev != next)) {
|
||||||
|
u64 last_ctx_id = this_cpu_read(cpu_tlbstate.last_ctx_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Avoid user/user BTB poisoning by flushing the branch
|
||||||
|
* predictor when switching between processes. This stops
|
||||||
|
* one process from doing Spectre-v2 attacks on another.
|
||||||
|
*
|
||||||
|
* As an optimization, flush indirect branches only when
|
||||||
|
* switching into processes that disable dumping. This
|
||||||
|
* protects high value processes like gpg, without having
|
||||||
|
* too high performance overhead. IBPB is *expensive*!
|
||||||
|
*
|
||||||
|
* This will not flush branches when switching into kernel
|
||||||
|
* threads. It will also not flush if we switch to idle
|
||||||
|
* thread and back to the same process. It will flush if we
|
||||||
|
* switch to a different non-dumpable process.
|
||||||
|
*/
|
||||||
|
if (tsk && tsk->mm &&
|
||||||
|
tsk->mm->context.ctx_id != last_ctx_id &&
|
||||||
|
get_dumpable(tsk->mm) != SUID_DUMP_USER)
|
||||||
|
indirect_branch_prediction_barrier();
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_VMAP_STACK)) {
|
if (IS_ENABLED(CONFIG_VMAP_STACK)) {
|
||||||
/*
|
/*
|
||||||
* If our current stack is in vmalloc space and isn't
|
* If our current stack is in vmalloc space and isn't
|
||||||
|
@ -118,6 +143,14 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
||||||
set_pgd(pgd, init_mm.pgd[stack_pgd_index]);
|
set_pgd(pgd, init_mm.pgd[stack_pgd_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record last user mm's context id, so we can avoid
|
||||||
|
* flushing branch buffer with IBPB if we switch back
|
||||||
|
* to the same user.
|
||||||
|
*/
|
||||||
|
if (next != &init_mm)
|
||||||
|
this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id);
|
||||||
|
|
||||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
||||||
this_cpu_write(cpu_tlbstate.active_mm, next);
|
this_cpu_write(cpu_tlbstate.active_mm, next);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
#include <asm/nospec-branch.h>
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
|
|
||||||
int bpf_jit_enable __read_mostly;
|
int bpf_jit_enable __read_mostly;
|
||||||
|
@ -281,7 +282,7 @@ static void emit_bpf_tail_call(u8 **pprog)
|
||||||
EMIT2(0x89, 0xD2); /* mov edx, edx */
|
EMIT2(0x89, 0xD2); /* mov edx, edx */
|
||||||
EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */
|
EMIT3(0x39, 0x56, /* cmp dword ptr [rsi + 16], edx */
|
||||||
offsetof(struct bpf_array, map.max_entries));
|
offsetof(struct bpf_array, map.max_entries));
|
||||||
#define OFFSET1 43 /* number of bytes to jump */
|
#define OFFSET1 (41 + RETPOLINE_RAX_BPF_JIT_SIZE) /* number of bytes to jump */
|
||||||
EMIT2(X86_JBE, OFFSET1); /* jbe out */
|
EMIT2(X86_JBE, OFFSET1); /* jbe out */
|
||||||
label1 = cnt;
|
label1 = cnt;
|
||||||
|
|
||||||
|
@ -290,7 +291,7 @@ static void emit_bpf_tail_call(u8 **pprog)
|
||||||
*/
|
*/
|
||||||
EMIT2_off32(0x8B, 0x85, -STACKSIZE + 36); /* mov eax, dword ptr [rbp - 516] */
|
EMIT2_off32(0x8B, 0x85, -STACKSIZE + 36); /* mov eax, dword ptr [rbp - 516] */
|
||||||
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
|
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
|
||||||
#define OFFSET2 32
|
#define OFFSET2 (30 + RETPOLINE_RAX_BPF_JIT_SIZE)
|
||||||
EMIT2(X86_JA, OFFSET2); /* ja out */
|
EMIT2(X86_JA, OFFSET2); /* ja out */
|
||||||
label2 = cnt;
|
label2 = cnt;
|
||||||
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
|
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
|
||||||
|
@ -304,7 +305,7 @@ static void emit_bpf_tail_call(u8 **pprog)
|
||||||
* goto out;
|
* goto out;
|
||||||
*/
|
*/
|
||||||
EMIT3(0x48, 0x85, 0xC0); /* test rax,rax */
|
EMIT3(0x48, 0x85, 0xC0); /* test rax,rax */
|
||||||
#define OFFSET3 10
|
#define OFFSET3 (8 + RETPOLINE_RAX_BPF_JIT_SIZE)
|
||||||
EMIT2(X86_JE, OFFSET3); /* je out */
|
EMIT2(X86_JE, OFFSET3); /* je out */
|
||||||
label3 = cnt;
|
label3 = cnt;
|
||||||
|
|
||||||
|
@ -317,7 +318,7 @@ static void emit_bpf_tail_call(u8 **pprog)
|
||||||
* rdi == ctx (1st arg)
|
* rdi == ctx (1st arg)
|
||||||
* rax == prog->bpf_func + prologue_size
|
* rax == prog->bpf_func + prologue_size
|
||||||
*/
|
*/
|
||||||
EMIT2(0xFF, 0xE0); /* jmp rax */
|
RETPOLINE_RAX_BPF_JIT();
|
||||||
|
|
||||||
/* out: */
|
/* out: */
|
||||||
BUILD_BUG_ON(cnt - label1 != OFFSET1);
|
BUILD_BUG_ON(cnt - label1 != OFFSET1);
|
||||||
|
|
|
@ -472,7 +472,7 @@ static int nmi_setup(void)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
if (!cpu)
|
if (!IS_ENABLED(CONFIG_SMP) || !cpu)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
memcpy(per_cpu(cpu_msrs, cpu).counters,
|
memcpy(per_cpu(cpu_msrs, cpu).counters,
|
||||||
|
|
|
@ -79,7 +79,7 @@ static void intel_mid_power_off(void)
|
||||||
|
|
||||||
static void intel_mid_reboot(void)
|
static void intel_mid_reboot(void)
|
||||||
{
|
{
|
||||||
intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
|
intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long __init intel_mid_calibrate_tsc(void)
|
static unsigned long __init intel_mid_calibrate_tsc(void)
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/tick.h>
|
#include <linux/tick.h>
|
||||||
|
#include <linux/percpu-defs.h>
|
||||||
|
|
||||||
#include <xen/xen.h>
|
#include <xen/xen.h>
|
||||||
#include <xen/interface/xen.h>
|
#include <xen/interface/xen.h>
|
||||||
#include <xen/grant_table.h>
|
#include <xen/grant_table.h>
|
||||||
#include <xen/events.h>
|
#include <xen/events.h>
|
||||||
|
|
||||||
|
#include <asm/cpufeatures.h>
|
||||||
|
#include <asm/msr-index.h>
|
||||||
#include <asm/xen/hypercall.h>
|
#include <asm/xen/hypercall.h>
|
||||||
#include <asm/xen/page.h>
|
#include <asm/xen/page.h>
|
||||||
#include <asm/fixmap.h>
|
#include <asm/fixmap.h>
|
||||||
|
@ -68,6 +71,8 @@ static void xen_pv_post_suspend(int suspend_cancelled)
|
||||||
xen_mm_unpin_all();
|
xen_mm_unpin_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DEFINE_PER_CPU(u64, spec_ctrl);
|
||||||
|
|
||||||
void xen_arch_pre_suspend(void)
|
void xen_arch_pre_suspend(void)
|
||||||
{
|
{
|
||||||
if (xen_pv_domain())
|
if (xen_pv_domain())
|
||||||
|
@ -84,6 +89,9 @@ void xen_arch_post_suspend(int cancelled)
|
||||||
|
|
||||||
static void xen_vcpu_notify_restore(void *data)
|
static void xen_vcpu_notify_restore(void *data)
|
||||||
{
|
{
|
||||||
|
if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL))
|
||||||
|
wrmsrl(MSR_IA32_SPEC_CTRL, this_cpu_read(spec_ctrl));
|
||||||
|
|
||||||
/* Boot processor notified via generic timekeeping_resume() */
|
/* Boot processor notified via generic timekeeping_resume() */
|
||||||
if (smp_processor_id() == 0)
|
if (smp_processor_id() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -93,7 +101,15 @@ static void xen_vcpu_notify_restore(void *data)
|
||||||
|
|
||||||
static void xen_vcpu_notify_suspend(void *data)
|
static void xen_vcpu_notify_suspend(void *data)
|
||||||
{
|
{
|
||||||
|
u64 tmp;
|
||||||
|
|
||||||
tick_suspend_local();
|
tick_suspend_local();
|
||||||
|
|
||||||
|
if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) {
|
||||||
|
rdmsrl(MSR_IA32_SPEC_CTRL, tmp);
|
||||||
|
this_cpu_write(spec_ctrl, tmp);
|
||||||
|
wrmsrl(MSR_IA32_SPEC_CTRL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xen_arch_resume(void)
|
void xen_arch_resume(void)
|
||||||
|
|
|
@ -77,19 +77,75 @@ void __init zones_init(void)
|
||||||
free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
|
free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_HIGHMEM
|
||||||
|
static void __init free_area_high(unsigned long pfn, unsigned long end)
|
||||||
|
{
|
||||||
|
for (; pfn < end; pfn++)
|
||||||
|
free_highmem_page(pfn_to_page(pfn));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init free_highpages(void)
|
||||||
|
{
|
||||||
|
unsigned long max_low = max_low_pfn;
|
||||||
|
struct memblock_region *mem, *res;
|
||||||
|
|
||||||
|
reset_all_zones_managed_pages();
|
||||||
|
/* set highmem page free */
|
||||||
|
for_each_memblock(memory, mem) {
|
||||||
|
unsigned long start = memblock_region_memory_base_pfn(mem);
|
||||||
|
unsigned long end = memblock_region_memory_end_pfn(mem);
|
||||||
|
|
||||||
|
/* Ignore complete lowmem entries */
|
||||||
|
if (end <= max_low)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (memblock_is_nomap(mem))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Truncate partial highmem entries */
|
||||||
|
if (start < max_low)
|
||||||
|
start = max_low;
|
||||||
|
|
||||||
|
/* Find and exclude any reserved regions */
|
||||||
|
for_each_memblock(reserved, res) {
|
||||||
|
unsigned long res_start, res_end;
|
||||||
|
|
||||||
|
res_start = memblock_region_reserved_base_pfn(res);
|
||||||
|
res_end = memblock_region_reserved_end_pfn(res);
|
||||||
|
|
||||||
|
if (res_end < start)
|
||||||
|
continue;
|
||||||
|
if (res_start < start)
|
||||||
|
res_start = start;
|
||||||
|
if (res_start > end)
|
||||||
|
res_start = end;
|
||||||
|
if (res_end > end)
|
||||||
|
res_end = end;
|
||||||
|
if (res_start != start)
|
||||||
|
free_area_high(start, res_start);
|
||||||
|
start = res_end;
|
||||||
|
if (start == end)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And now free anything which remains */
|
||||||
|
if (start < end)
|
||||||
|
free_area_high(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void __init free_highpages(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize memory pages.
|
* Initialize memory pages.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void __init mem_init(void)
|
void __init mem_init(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HIGHMEM
|
free_highpages();
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
reset_all_zones_managed_pages();
|
|
||||||
for (tmp = max_low_pfn; tmp < max_pfn; tmp++)
|
|
||||||
free_highmem_page(pfn_to_page(tmp));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
max_mapnr = max_pfn - ARCH_PFN_OFFSET;
|
max_mapnr = max_pfn - ARCH_PFN_OFFSET;
|
||||||
high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
|
high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT);
|
||||||
|
|
|
@ -261,7 +261,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
|
||||||
sinfo->index);
|
sinfo->index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = public_key_verify_signature(p->pub, p->sig);
|
ret = public_key_verify_signature(p->pub, x509->sig);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
x509->signer = p;
|
x509->signer = p;
|
||||||
|
|
|
@ -93,9 +93,11 @@ int public_key_verify_signature(const struct public_key *pkey,
|
||||||
|
|
||||||
BUG_ON(!pkey);
|
BUG_ON(!pkey);
|
||||||
BUG_ON(!sig);
|
BUG_ON(!sig);
|
||||||
BUG_ON(!sig->digest);
|
|
||||||
BUG_ON(!sig->s);
|
BUG_ON(!sig->s);
|
||||||
|
|
||||||
|
if (!sig->digest)
|
||||||
|
return -ENOPKG;
|
||||||
|
|
||||||
alg_name = sig->pkey_algo;
|
alg_name = sig->pkey_algo;
|
||||||
if (strcmp(sig->pkey_algo, "rsa") == 0) {
|
if (strcmp(sig->pkey_algo, "rsa") == 0) {
|
||||||
/* The data wangled by the RSA algorithm is typically padded
|
/* The data wangled by the RSA algorithm is typically padded
|
||||||
|
|
|
@ -66,8 +66,9 @@ __setup("ca_keys=", ca_keys_setup);
|
||||||
*
|
*
|
||||||
* Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
|
* Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
|
||||||
* matching parent certificate in the trusted list, -EKEYREJECTED if the
|
* matching parent certificate in the trusted list, -EKEYREJECTED if the
|
||||||
* signature check fails or the key is blacklisted and some other error if
|
* signature check fails or the key is blacklisted, -ENOPKG if the signature
|
||||||
* there is a matching certificate but the signature check cannot be performed.
|
* uses unsupported crypto, or some other error if there is a matching
|
||||||
|
* certificate but the signature check cannot be performed.
|
||||||
*/
|
*/
|
||||||
int restrict_link_by_signature(struct key *trust_keyring,
|
int restrict_link_by_signature(struct key *trust_keyring,
|
||||||
const struct key_type *type,
|
const struct key_type *type,
|
||||||
|
@ -86,6 +87,8 @@ int restrict_link_by_signature(struct key *trust_keyring,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
sig = payload->data[asym_auth];
|
sig = payload->data[asym_auth];
|
||||||
|
if (!sig)
|
||||||
|
return -ENOPKG;
|
||||||
if (!sig->auth_ids[0] && !sig->auth_ids[1])
|
if (!sig->auth_ids[0] && !sig->auth_ids[1])
|
||||||
return -ENOKEY;
|
return -ENOKEY;
|
||||||
|
|
||||||
|
|
|
@ -2628,8 +2628,10 @@ static unsigned int binder_poll(struct file *filp,
|
||||||
binder_lock(__func__);
|
binder_lock(__func__);
|
||||||
|
|
||||||
thread = binder_get_thread(proc);
|
thread = binder_get_thread(proc);
|
||||||
if (!thread)
|
if (!thread) {
|
||||||
|
binder_unlock(__func__);
|
||||||
return POLLERR;
|
return POLLERR;
|
||||||
|
}
|
||||||
|
|
||||||
wait_for_proc_work = thread->transaction_stack == NULL &&
|
wait_for_proc_work = thread->transaction_stack == NULL &&
|
||||||
list_empty(&thread->todo) && thread->return_error == BR_OK;
|
list_empty(&thread->todo) && thread->return_error == BR_OK;
|
||||||
|
|
|
@ -458,7 +458,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int expected;
|
u32 expected;
|
||||||
|
|
||||||
if (!chip)
|
if (!chip)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
@ -475,7 +475,7 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
expected = be32_to_cpu(*(__be32 *)(buf + 2));
|
expected = be32_to_cpu(*(__be32 *)(buf + 2));
|
||||||
if (expected > count) {
|
if (expected > count || expected < TPM_HEADER_SIZE) {
|
||||||
size = -EIO;
|
size = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,12 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_size < 6 ||
|
||||||
|
in_size < be32_to_cpu(*((__be32 *) (priv->data_buffer + 2)))) {
|
||||||
|
mutex_unlock(&priv->buffer_mutex);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* atomic tpm command send and result receive. We only hold the ops
|
/* atomic tpm command send and result receive. We only hold the ops
|
||||||
* lock during this period so that the tpm can be unregistered even if
|
* lock during this period so that the tpm can be unregistered even if
|
||||||
* the char dev is held open.
|
* the char dev is held open.
|
||||||
|
|
|
@ -437,7 +437,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int expected, status;
|
int status;
|
||||||
|
u32 expected;
|
||||||
|
|
||||||
if (count < TPM_HEADER_SIZE) {
|
if (count < TPM_HEADER_SIZE) {
|
||||||
size = -EIO;
|
size = -EIO;
|
||||||
|
@ -452,7 +453,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected = be32_to_cpu(*(__be32 *)(buf + 2));
|
expected = be32_to_cpu(*(__be32 *)(buf + 2));
|
||||||
if ((size_t) expected > count) {
|
if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
|
||||||
size = -EIO;
|
size = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,7 +281,11 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
struct device *dev = chip->dev.parent;
|
struct device *dev = chip->dev.parent;
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
s32 rc;
|
s32 rc;
|
||||||
int expected, status, burst_count, retries, size = 0;
|
int status;
|
||||||
|
int burst_count;
|
||||||
|
int retries;
|
||||||
|
int size = 0;
|
||||||
|
u32 expected;
|
||||||
|
|
||||||
if (count < TPM_HEADER_SIZE) {
|
if (count < TPM_HEADER_SIZE) {
|
||||||
i2c_nuvoton_ready(chip); /* return to idle */
|
i2c_nuvoton_ready(chip); /* return to idle */
|
||||||
|
@ -323,7 +327,7 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
* to machine native
|
* to machine native
|
||||||
*/
|
*/
|
||||||
expected = be32_to_cpu(*(__be32 *) (buf + 2));
|
expected = be32_to_cpu(*(__be32 *) (buf + 2));
|
||||||
if (expected > count) {
|
if (expected > count || expected < size) {
|
||||||
dev_err(dev, "%s() expected > count\n", __func__);
|
dev_err(dev, "%s() expected > count\n", __func__);
|
||||||
size = -EIO;
|
size = -EIO;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -98,7 +98,7 @@ static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
|
static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
u8 *value)
|
const u8 *value)
|
||||||
{
|
{
|
||||||
struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
|
struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int expected, status;
|
int status;
|
||||||
|
u32 expected;
|
||||||
|
|
||||||
if (count < TPM_HEADER_SIZE) {
|
if (count < TPM_HEADER_SIZE) {
|
||||||
size = -EIO;
|
size = -EIO;
|
||||||
|
@ -223,7 +224,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected = be32_to_cpu(*(__be32 *) (buf + 2));
|
expected = be32_to_cpu(*(__be32 *) (buf + 2));
|
||||||
if (expected > count) {
|
if (expected > count || expected < TPM_HEADER_SIZE) {
|
||||||
size = -EIO;
|
size = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -256,7 +257,7 @@ out:
|
||||||
* tpm.c can skip polling for the data to be available as the interrupt is
|
* tpm.c can skip polling for the data to be available as the interrupt is
|
||||||
* waited for here
|
* waited for here
|
||||||
*/
|
*/
|
||||||
static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
|
static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||||
int rc, status, burstcnt;
|
int rc, status, burstcnt;
|
||||||
|
@ -345,7 +346,7 @@ static void disable_interrupts(struct tpm_chip *chip)
|
||||||
* tpm.c can skip polling for the data to be available as the interrupt is
|
* tpm.c can skip polling for the data to be available as the interrupt is
|
||||||
* waited for here
|
* waited for here
|
||||||
*/
|
*/
|
||||||
static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len)
|
static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
|
@ -98,7 +98,7 @@ struct tpm_tis_phy_ops {
|
||||||
int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
|
int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
u8 *result);
|
u8 *result);
|
||||||
int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
|
int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
u8 *value);
|
const u8 *value);
|
||||||
int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
|
int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
|
||||||
int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
|
int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
|
||||||
int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
|
int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
|
||||||
|
@ -128,7 +128,7 @@ static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
|
static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
|
||||||
u16 len, u8 *value)
|
u16 len, const u8 *value)
|
||||||
{
|
{
|
||||||
return data->phy_ops->write_bytes(data, addr, len, value);
|
return data->phy_ops->write_bytes(data, addr, len, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,7 @@
|
||||||
struct tpm_tis_spi_phy {
|
struct tpm_tis_spi_phy {
|
||||||
struct tpm_tis_data priv;
|
struct tpm_tis_data priv;
|
||||||
struct spi_device *spi_device;
|
struct spi_device *spi_device;
|
||||||
|
u8 *iobuf;
|
||||||
u8 tx_buf[4];
|
|
||||||
u8 rx_buf[4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data)
|
static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data)
|
||||||
|
@ -58,7 +56,7 @@ static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *da
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
u8 *buffer, u8 direction)
|
u8 *in, const u8 *out)
|
||||||
{
|
{
|
||||||
struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
|
struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -72,14 +70,14 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
while (len) {
|
while (len) {
|
||||||
transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
|
transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
|
||||||
|
|
||||||
phy->tx_buf[0] = direction | (transfer_len - 1);
|
phy->iobuf[0] = (in ? 0x80 : 0) | (transfer_len - 1);
|
||||||
phy->tx_buf[1] = 0xd4;
|
phy->iobuf[1] = 0xd4;
|
||||||
phy->tx_buf[2] = addr >> 8;
|
phy->iobuf[2] = addr >> 8;
|
||||||
phy->tx_buf[3] = addr;
|
phy->iobuf[3] = addr;
|
||||||
|
|
||||||
memset(&spi_xfer, 0, sizeof(spi_xfer));
|
memset(&spi_xfer, 0, sizeof(spi_xfer));
|
||||||
spi_xfer.tx_buf = phy->tx_buf;
|
spi_xfer.tx_buf = phy->iobuf;
|
||||||
spi_xfer.rx_buf = phy->rx_buf;
|
spi_xfer.rx_buf = phy->iobuf;
|
||||||
spi_xfer.len = 4;
|
spi_xfer.len = 4;
|
||||||
spi_xfer.cs_change = 1;
|
spi_xfer.cs_change = 1;
|
||||||
|
|
||||||
|
@ -89,9 +87,9 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if ((phy->rx_buf[3] & 0x01) == 0) {
|
if ((phy->iobuf[3] & 0x01) == 0) {
|
||||||
// handle SPI wait states
|
// handle SPI wait states
|
||||||
phy->tx_buf[0] = 0;
|
phy->iobuf[0] = 0;
|
||||||
|
|
||||||
for (i = 0; i < TPM_RETRY; i++) {
|
for (i = 0; i < TPM_RETRY; i++) {
|
||||||
spi_xfer.len = 1;
|
spi_xfer.len = 1;
|
||||||
|
@ -100,7 +98,7 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
ret = spi_sync_locked(phy->spi_device, &m);
|
ret = spi_sync_locked(phy->spi_device, &m);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
if (phy->rx_buf[0] & 0x01)
|
if (phy->iobuf[0] & 0x01)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,12 +112,12 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
spi_xfer.len = transfer_len;
|
spi_xfer.len = transfer_len;
|
||||||
spi_xfer.delay_usecs = 5;
|
spi_xfer.delay_usecs = 5;
|
||||||
|
|
||||||
if (direction) {
|
if (in) {
|
||||||
spi_xfer.tx_buf = NULL;
|
spi_xfer.tx_buf = NULL;
|
||||||
spi_xfer.rx_buf = buffer;
|
} else if (out) {
|
||||||
} else {
|
|
||||||
spi_xfer.tx_buf = buffer;
|
|
||||||
spi_xfer.rx_buf = NULL;
|
spi_xfer.rx_buf = NULL;
|
||||||
|
memcpy(phy->iobuf, out, transfer_len);
|
||||||
|
out += transfer_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_message_init(&m);
|
spi_message_init(&m);
|
||||||
|
@ -128,8 +126,12 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
if (in) {
|
||||||
|
memcpy(in, phy->iobuf, transfer_len);
|
||||||
|
in += transfer_len;
|
||||||
|
}
|
||||||
|
|
||||||
len -= transfer_len;
|
len -= transfer_len;
|
||||||
buffer += transfer_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -140,13 +142,13 @@ exit:
|
||||||
static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
|
static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
|
||||||
u16 len, u8 *result)
|
u16 len, u8 *result)
|
||||||
{
|
{
|
||||||
return tpm_tis_spi_transfer(data, addr, len, result, 0x80);
|
return tpm_tis_spi_transfer(data, addr, len, result, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
|
static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
|
||||||
u16 len, u8 *value)
|
u16 len, const u8 *value)
|
||||||
{
|
{
|
||||||
return tpm_tis_spi_transfer(data, addr, len, value, 0);
|
return tpm_tis_spi_transfer(data, addr, len, NULL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
|
static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
|
||||||
|
@ -195,6 +197,10 @@ static int tpm_tis_spi_probe(struct spi_device *dev)
|
||||||
|
|
||||||
phy->spi_device = dev;
|
phy->spi_device = dev;
|
||||||
|
|
||||||
|
phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
|
||||||
|
if (!phy->iobuf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops,
|
return tpm_tis_core_init(&dev->dev, &phy->priv, -1, &tpm_spi_phy_ops,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,7 +351,13 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
|
||||||
static int s3c_cpufreq_init(struct cpufreq_policy *policy)
|
static int s3c_cpufreq_init(struct cpufreq_policy *policy)
|
||||||
{
|
{
|
||||||
policy->clk = clk_arm;
|
policy->clk = clk_arm;
|
||||||
return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency);
|
|
||||||
|
policy->cpuinfo.transition_latency = cpu_cur.info->latency;
|
||||||
|
|
||||||
|
if (ftab)
|
||||||
|
return cpufreq_table_validate_and_show(policy, ftab);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init s3c_cpufreq_initclks(void)
|
static int __init s3c_cpufreq_initclks(void)
|
||||||
|
|
|
@ -453,9 +453,21 @@ static int dax_dev_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dax_dev_split(struct vm_area_struct *vma, unsigned long addr)
|
||||||
|
{
|
||||||
|
struct file *filp = vma->vm_file;
|
||||||
|
struct dax_dev *dax_dev = filp->private_data;
|
||||||
|
struct dax_region *dax_region = dax_dev->region;
|
||||||
|
|
||||||
|
if (!IS_ALIGNED(addr, dax_region->align))
|
||||||
|
return -EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct vm_operations_struct dax_dev_vm_ops = {
|
static const struct vm_operations_struct dax_dev_vm_ops = {
|
||||||
.fault = dax_dev_fault,
|
.fault = dax_dev_fault,
|
||||||
.pmd_fault = dax_dev_pmd_fault,
|
.pmd_fault = dax_dev_pmd_fault,
|
||||||
|
.split = dax_dev_split,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dax_mmap(struct file *filp, struct vm_area_struct *vma)
|
static int dax_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||||
|
|
|
@ -945,11 +945,11 @@ static void fsl_edma_irq_exit(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma)
|
static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < fsl_edma->dmamux_nr; i++)
|
for (i = 0; i < nr_clocks; i++)
|
||||||
clk_disable_unprepare(fsl_edma->muxclk[i]);
|
clk_disable_unprepare(fsl_edma->muxclk[i]);
|
||||||
|
|
||||||
if (fsl_edma->dmaclk)
|
if (fsl_edma->dmaclk)
|
||||||
|
@ -1057,25 +1057,25 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
|
||||||
fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res);
|
fsl_edma->muxbase[i] = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(fsl_edma->muxbase[i]))
|
if (IS_ERR(fsl_edma->muxbase[i])) {
|
||||||
|
/* on error: disable all previously enabled clks */
|
||||||
|
fsl_disable_clocks(fsl_edma, i);
|
||||||
return PTR_ERR(fsl_edma->muxbase[i]);
|
return PTR_ERR(fsl_edma->muxbase[i]);
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(clkname, "dmamux%d", i);
|
sprintf(clkname, "dmamux%d", i);
|
||||||
fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname);
|
fsl_edma->muxclk[i] = devm_clk_get(&pdev->dev, clkname);
|
||||||
if (IS_ERR(fsl_edma->muxclk[i])) {
|
if (IS_ERR(fsl_edma->muxclk[i])) {
|
||||||
dev_err(&pdev->dev, "Missing DMAMUX block clock.\n");
|
dev_err(&pdev->dev, "Missing DMAMUX block clock.\n");
|
||||||
|
/* on error: disable all previously enabled clks */
|
||||||
|
fsl_disable_clocks(fsl_edma, i);
|
||||||
return PTR_ERR(fsl_edma->muxclk[i]);
|
return PTR_ERR(fsl_edma->muxclk[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = clk_prepare_enable(fsl_edma->muxclk[i]);
|
ret = clk_prepare_enable(fsl_edma->muxclk[i]);
|
||||||
if (ret) {
|
if (ret)
|
||||||
/* disable only clks which were enabled on error */
|
/* on error: disable all previously enabled clks */
|
||||||
for (; i >= 0; i--)
|
fsl_disable_clocks(fsl_edma, i);
|
||||||
clk_disable_unprepare(fsl_edma->muxclk[i]);
|
|
||||||
|
|
||||||
dev_err(&pdev->dev, "DMAMUX clk block failed.\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,7 +1134,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"Can't register Freescale eDMA engine. (%d)\n", ret);
|
"Can't register Freescale eDMA engine. (%d)\n", ret);
|
||||||
fsl_disable_clocks(fsl_edma);
|
fsl_disable_clocks(fsl_edma, DMAMUX_NR);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1143,7 +1143,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"Can't register Freescale eDMA of_dma. (%d)\n", ret);
|
"Can't register Freescale eDMA of_dma. (%d)\n", ret);
|
||||||
dma_async_device_unregister(&fsl_edma->dma_dev);
|
dma_async_device_unregister(&fsl_edma->dma_dev);
|
||||||
fsl_disable_clocks(fsl_edma);
|
fsl_disable_clocks(fsl_edma, DMAMUX_NR);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,7 +1173,7 @@ static int fsl_edma_remove(struct platform_device *pdev)
|
||||||
fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
|
fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
|
||||||
of_dma_controller_free(np);
|
of_dma_controller_free(np);
|
||||||
dma_async_device_unregister(&fsl_edma->dma_dev);
|
dma_async_device_unregister(&fsl_edma->dma_dev);
|
||||||
fsl_disable_clocks(fsl_edma);
|
fsl_disable_clocks(fsl_edma, DMAMUX_NR);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,16 @@
|
||||||
|
|
||||||
#include "amd_acpi.h"
|
#include "amd_acpi.h"
|
||||||
|
|
||||||
|
#define AMDGPU_PX_QUIRK_FORCE_ATPX (1 << 0)
|
||||||
|
|
||||||
|
struct amdgpu_px_quirk {
|
||||||
|
u32 chip_vendor;
|
||||||
|
u32 chip_device;
|
||||||
|
u32 subsys_vendor;
|
||||||
|
u32 subsys_device;
|
||||||
|
u32 px_quirk_flags;
|
||||||
|
};
|
||||||
|
|
||||||
struct amdgpu_atpx_functions {
|
struct amdgpu_atpx_functions {
|
||||||
bool px_params;
|
bool px_params;
|
||||||
bool power_cntl;
|
bool power_cntl;
|
||||||
|
@ -35,6 +45,7 @@ struct amdgpu_atpx {
|
||||||
static struct amdgpu_atpx_priv {
|
static struct amdgpu_atpx_priv {
|
||||||
bool atpx_detected;
|
bool atpx_detected;
|
||||||
bool bridge_pm_usable;
|
bool bridge_pm_usable;
|
||||||
|
unsigned int quirks;
|
||||||
/* handle for device - and atpx */
|
/* handle for device - and atpx */
|
||||||
acpi_handle dhandle;
|
acpi_handle dhandle;
|
||||||
acpi_handle other_handle;
|
acpi_handle other_handle;
|
||||||
|
@ -205,13 +216,19 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
|
||||||
|
|
||||||
atpx->is_hybrid = false;
|
atpx->is_hybrid = false;
|
||||||
if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
|
if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
|
||||||
printk("ATPX Hybrid Graphics\n");
|
if (amdgpu_atpx_priv.quirks & AMDGPU_PX_QUIRK_FORCE_ATPX) {
|
||||||
/*
|
printk("ATPX Hybrid Graphics, forcing to ATPX\n");
|
||||||
* Disable legacy PM methods only when pcie port PM is usable,
|
atpx->functions.power_cntl = true;
|
||||||
* otherwise the device might fail to power off or power on.
|
atpx->is_hybrid = false;
|
||||||
*/
|
} else {
|
||||||
atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;
|
printk("ATPX Hybrid Graphics\n");
|
||||||
atpx->is_hybrid = true;
|
/*
|
||||||
|
* Disable legacy PM methods only when pcie port PM is usable,
|
||||||
|
* otherwise the device might fail to power off or power on.
|
||||||
|
*/
|
||||||
|
atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;
|
||||||
|
atpx->is_hybrid = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atpx->dgpu_req_power_for_displays = false;
|
atpx->dgpu_req_power_for_displays = false;
|
||||||
|
@ -547,6 +564,31 @@ static const struct vga_switcheroo_handler amdgpu_atpx_handler = {
|
||||||
.get_client_id = amdgpu_atpx_get_client_id,
|
.get_client_id = amdgpu_atpx_get_client_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
|
||||||
|
/* HG _PR3 doesn't seem to work on this A+A weston board */
|
||||||
|
{ 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||||
|
{ 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||||
|
{ 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
|
||||||
|
{ 0, 0, 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void amdgpu_atpx_get_quirks(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
const struct amdgpu_px_quirk *p = amdgpu_px_quirk_list;
|
||||||
|
|
||||||
|
/* Apply PX quirks */
|
||||||
|
while (p && p->chip_device != 0) {
|
||||||
|
if (pdev->vendor == p->chip_vendor &&
|
||||||
|
pdev->device == p->chip_device &&
|
||||||
|
pdev->subsystem_vendor == p->subsys_vendor &&
|
||||||
|
pdev->subsystem_device == p->subsys_device) {
|
||||||
|
amdgpu_atpx_priv.quirks |= p->px_quirk_flags;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_atpx_detect - detect whether we have PX
|
* amdgpu_atpx_detect - detect whether we have PX
|
||||||
*
|
*
|
||||||
|
@ -570,6 +612,7 @@ static bool amdgpu_atpx_detect(void)
|
||||||
|
|
||||||
parent_pdev = pci_upstream_bridge(pdev);
|
parent_pdev = pci_upstream_bridge(pdev);
|
||||||
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
|
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
|
||||||
|
amdgpu_atpx_get_quirks(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
|
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
|
||||||
|
@ -579,6 +622,7 @@ static bool amdgpu_atpx_detect(void)
|
||||||
|
|
||||||
parent_pdev = pci_upstream_bridge(pdev);
|
parent_pdev = pci_upstream_bridge(pdev);
|
||||||
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
|
d3_supported |= parent_pdev && parent_pdev->bridge_d3;
|
||||||
|
amdgpu_atpx_get_quirks(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_atpx && vga_count == 2) {
|
if (has_atpx && vga_count == 2) {
|
||||||
|
|
|
@ -1678,8 +1678,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||||
* ignore it */
|
* ignore it */
|
||||||
vga_client_register(adev->pdev, adev, NULL, amdgpu_vga_set_decode);
|
vga_client_register(adev->pdev, adev, NULL, amdgpu_vga_set_decode);
|
||||||
|
|
||||||
if (amdgpu_runtime_pm == 1)
|
|
||||||
runtime = true;
|
|
||||||
if (amdgpu_device_is_px(ddev))
|
if (amdgpu_device_is_px(ddev))
|
||||||
runtime = true;
|
runtime = true;
|
||||||
vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
|
vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
|
||||||
|
|
|
@ -3507,6 +3507,11 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
|
||||||
max_sclk = 75000;
|
max_sclk = 75000;
|
||||||
max_mclk = 80000;
|
max_mclk = 80000;
|
||||||
}
|
}
|
||||||
|
if ((adev->pdev->revision == 0xC3) ||
|
||||||
|
(adev->pdev->device == 0x6665)) {
|
||||||
|
max_sclk = 60000;
|
||||||
|
max_mclk = 80000;
|
||||||
|
}
|
||||||
} else if (adev->asic_type == CHIP_OLAND) {
|
} else if (adev->asic_type == CHIP_OLAND) {
|
||||||
if ((adev->pdev->revision == 0xC7) ||
|
if ((adev->pdev->revision == 0xC7) ||
|
||||||
(adev->pdev->revision == 0x80) ||
|
(adev->pdev->revision == 0x80) ||
|
||||||
|
|
|
@ -107,6 +107,9 @@ static const struct edid_quirk {
|
||||||
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
|
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
|
||||||
{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
|
{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
|
||||||
|
|
||||||
|
/* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
|
||||||
|
{ "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
|
||||||
|
|
||||||
/* Belinea 10 15 55 */
|
/* Belinea 10 15 55 */
|
||||||
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
|
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
|
||||||
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
|
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
|
||||||
|
|
|
@ -136,6 +136,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
pci->irq = pdev->irq;
|
pci->irq = pdev->irq;
|
||||||
|
|
||||||
|
/* Ensure MSI interrupts are armed, for the case where there are
|
||||||
|
* already interrupts pending (for whatever reason) at load time.
|
||||||
|
*/
|
||||||
|
if (pci->msi)
|
||||||
|
pci->func->msi_rearm(pci);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -818,6 +818,8 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
|
||||||
pr_info("Initializing pool allocator\n");
|
pr_info("Initializing pool allocator\n");
|
||||||
|
|
||||||
_manager = kzalloc(sizeof(*_manager), GFP_KERNEL);
|
_manager = kzalloc(sizeof(*_manager), GFP_KERNEL);
|
||||||
|
if (!_manager)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ttm_page_pool_init_locked(&_manager->wc_pool, GFP_HIGHUSER, "wc");
|
ttm_page_pool_init_locked(&_manager->wc_pool, GFP_HIGHUSER, "wc");
|
||||||
|
|
||||||
|
|
|
@ -2443,6 +2443,9 @@ static const struct hid_device_id hid_ignore_list[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
|
||||||
|
|
|
@ -608,6 +608,9 @@
|
||||||
#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033
|
#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033
|
||||||
#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035
|
#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035
|
||||||
#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038
|
#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038
|
||||||
|
#define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040
|
||||||
|
#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042
|
||||||
|
#define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043
|
||||||
#define USB_DEVICE_ID_LD_JWM 0x1080
|
#define USB_DEVICE_ID_LD_JWM 0x1080
|
||||||
#define USB_DEVICE_ID_LD_DMMP 0x1081
|
#define USB_DEVICE_ID_LD_DMMP 0x1081
|
||||||
#define USB_DEVICE_ID_LD_UMIP 0x1090
|
#define USB_DEVICE_ID_LD_UMIP 0x1090
|
||||||
|
|
|
@ -507,7 +507,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
|
||||||
i2c_dw_disable_int(dev);
|
i2c_dw_disable_int(dev);
|
||||||
|
|
||||||
/* Enable the adapter */
|
/* Enable the adapter */
|
||||||
__i2c_dw_enable(dev, true);
|
__i2c_dw_enable_and_wait(dev, true);
|
||||||
|
|
||||||
/* Clear and enable interrupts */
|
/* Clear and enable interrupts */
|
||||||
dw_readl(dev, DW_IC_CLR_INTR);
|
dw_readl(dev, DW_IC_CLR_INTR);
|
||||||
|
|
|
@ -47,6 +47,10 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
|
||||||
if (adis->trig == NULL)
|
if (adis->trig == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
adis->trig->dev.parent = &adis->spi->dev;
|
||||||
|
adis->trig->ops = &adis_trigger_ops;
|
||||||
|
iio_trigger_set_drvdata(adis->trig, adis);
|
||||||
|
|
||||||
ret = request_irq(adis->spi->irq,
|
ret = request_irq(adis->spi->irq,
|
||||||
&iio_trigger_generic_data_rdy_poll,
|
&iio_trigger_generic_data_rdy_poll,
|
||||||
IRQF_TRIGGER_RISING,
|
IRQF_TRIGGER_RISING,
|
||||||
|
@ -55,9 +59,6 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_trig;
|
goto error_free_trig;
|
||||||
|
|
||||||
adis->trig->dev.parent = &adis->spi->dev;
|
|
||||||
adis->trig->ops = &adis_trigger_ops;
|
|
||||||
iio_trigger_set_drvdata(adis->trig, adis);
|
|
||||||
ret = iio_trigger_register(adis->trig);
|
ret = iio_trigger_register(adis->trig);
|
||||||
|
|
||||||
indio_dev->trig = iio_trigger_get(adis->trig);
|
indio_dev->trig = iio_trigger_get(adis->trig);
|
||||||
|
|
|
@ -174,7 +174,7 @@ unsigned int iio_buffer_poll(struct file *filp,
|
||||||
struct iio_dev *indio_dev = filp->private_data;
|
struct iio_dev *indio_dev = filp->private_data;
|
||||||
struct iio_buffer *rb = indio_dev->buffer;
|
struct iio_buffer *rb = indio_dev->buffer;
|
||||||
|
|
||||||
if (!indio_dev->info)
|
if (!indio_dev->info || rb == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
poll_wait(filp, &rb->pollq, wait);
|
poll_wait(filp, &rb->pollq, wait);
|
||||||
|
|
|
@ -193,7 +193,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
||||||
sg_list_start = umem->sg_head.sgl;
|
sg_list_start = umem->sg_head.sgl;
|
||||||
|
|
||||||
while (npages) {
|
while (npages) {
|
||||||
ret = get_user_pages(cur_base,
|
ret = get_user_pages_longterm(cur_base,
|
||||||
min_t(unsigned long, npages,
|
min_t(unsigned long, npages,
|
||||||
PAGE_SIZE / sizeof (struct page *)),
|
PAGE_SIZE / sizeof (struct page *)),
|
||||||
gup_flags, page_list, vma_list);
|
gup_flags, page_list, vma_list);
|
||||||
|
|
|
@ -735,12 +735,21 @@ static int verify_command_mask(struct ib_device *ib_dev, __u32 command)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool verify_command_idx(u32 command, bool extended)
|
||||||
|
{
|
||||||
|
if (extended)
|
||||||
|
return command < ARRAY_SIZE(uverbs_ex_cmd_table);
|
||||||
|
|
||||||
|
return command < ARRAY_SIZE(uverbs_cmd_table);
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
|
static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
|
||||||
size_t count, loff_t *pos)
|
size_t count, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct ib_uverbs_file *file = filp->private_data;
|
struct ib_uverbs_file *file = filp->private_data;
|
||||||
struct ib_device *ib_dev;
|
struct ib_device *ib_dev;
|
||||||
struct ib_uverbs_cmd_hdr hdr;
|
struct ib_uverbs_cmd_hdr hdr;
|
||||||
|
bool extended_command;
|
||||||
__u32 command;
|
__u32 command;
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
int srcu_key;
|
int srcu_key;
|
||||||
|
@ -770,6 +779,15 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK;
|
command = hdr.command & IB_USER_VERBS_CMD_COMMAND_MASK;
|
||||||
|
flags = (hdr.command &
|
||||||
|
IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT;
|
||||||
|
|
||||||
|
extended_command = flags & IB_USER_VERBS_CMD_FLAG_EXTENDED;
|
||||||
|
if (!verify_command_idx(command, extended_command)) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (verify_command_mask(ib_dev, command)) {
|
if (verify_command_mask(ib_dev, command)) {
|
||||||
ret = -EOPNOTSUPP;
|
ret = -EOPNOTSUPP;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -781,12 +799,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = (hdr.command &
|
|
||||||
IB_USER_VERBS_CMD_FLAGS_MASK) >> IB_USER_VERBS_CMD_FLAGS_SHIFT;
|
|
||||||
|
|
||||||
if (!flags) {
|
if (!flags) {
|
||||||
if (command >= ARRAY_SIZE(uverbs_cmd_table) ||
|
if (!uverbs_cmd_table[command]) {
|
||||||
!uverbs_cmd_table[command]) {
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -807,8 +821,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
|
||||||
struct ib_udata uhw;
|
struct ib_udata uhw;
|
||||||
size_t written_count = count;
|
size_t written_count = count;
|
||||||
|
|
||||||
if (command >= ARRAY_SIZE(uverbs_ex_cmd_table) ||
|
if (!uverbs_ex_cmd_table[command]) {
|
||||||
!uverbs_ex_cmd_table[command]) {
|
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,7 +406,6 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
|
||||||
goto err_free_mr;
|
goto err_free_mr;
|
||||||
|
|
||||||
mr->max_pages = max_num_sg;
|
mr->max_pages = max_num_sg;
|
||||||
|
|
||||||
err = mlx4_mr_enable(dev->dev, &mr->mmr);
|
err = mlx4_mr_enable(dev->dev, &mr->mmr);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_pl;
|
goto err_free_pl;
|
||||||
|
@ -417,6 +416,7 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
|
||||||
return &mr->ibmr;
|
return &mr->ibmr;
|
||||||
|
|
||||||
err_free_pl:
|
err_free_pl:
|
||||||
|
mr->ibmr.device = pd->device;
|
||||||
mlx4_free_priv_pages(mr);
|
mlx4_free_priv_pages(mr);
|
||||||
err_free_mr:
|
err_free_mr:
|
||||||
(void) mlx4_mr_free(dev->dev, &mr->mmr);
|
(void) mlx4_mr_free(dev->dev, &mr->mmr);
|
||||||
|
|
|
@ -1648,6 +1648,7 @@ struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd,
|
||||||
MLX5_SET(mkc, mkc, access_mode, mr->access_mode);
|
MLX5_SET(mkc, mkc, access_mode, mr->access_mode);
|
||||||
MLX5_SET(mkc, mkc, umr_en, 1);
|
MLX5_SET(mkc, mkc, umr_en, 1);
|
||||||
|
|
||||||
|
mr->ibmr.device = pd->device;
|
||||||
err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen);
|
err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_destroy_psv;
|
goto err_destroy_psv;
|
||||||
|
|
|
@ -919,8 +919,8 @@ static int path_rec_start(struct net_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
|
static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr,
|
||||||
struct net_device *dev)
|
struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||||
struct ipoib_path *path;
|
struct ipoib_path *path;
|
||||||
|
@ -933,7 +933,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
++dev->stats.tx_dropped;
|
++dev->stats.tx_dropped;
|
||||||
dev_kfree_skb_any(skb);
|
dev_kfree_skb_any(skb);
|
||||||
return;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To avoid race condition, make sure that the
|
||||||
|
* neigh will be added only once.
|
||||||
|
*/
|
||||||
|
if (unlikely(!list_empty(&neigh->list))) {
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
return neigh;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = __path_find(dev, daddr + 4);
|
path = __path_find(dev, daddr + 4);
|
||||||
|
@ -971,7 +979,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
ipoib_send(dev, skb, path->ah, IPOIB_QPN(daddr));
|
ipoib_send(dev, skb, path->ah, IPOIB_QPN(daddr));
|
||||||
ipoib_neigh_put(neigh);
|
ipoib_neigh_put(neigh);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
neigh->ah = NULL;
|
neigh->ah = NULL;
|
||||||
|
@ -988,7 +996,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
ipoib_neigh_put(neigh);
|
ipoib_neigh_put(neigh);
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
err_path:
|
err_path:
|
||||||
ipoib_neigh_free(neigh);
|
ipoib_neigh_free(neigh);
|
||||||
|
@ -998,6 +1006,8 @@ err_drop:
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
ipoib_neigh_put(neigh);
|
ipoib_neigh_put(neigh);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
|
static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
|
||||||
|
@ -1103,8 +1113,9 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
case htons(ETH_P_TIPC):
|
case htons(ETH_P_TIPC):
|
||||||
neigh = ipoib_neigh_get(dev, phdr->hwaddr);
|
neigh = ipoib_neigh_get(dev, phdr->hwaddr);
|
||||||
if (unlikely(!neigh)) {
|
if (unlikely(!neigh)) {
|
||||||
neigh_add_path(skb, phdr->hwaddr, dev);
|
neigh = neigh_add_path(skb, phdr->hwaddr, dev);
|
||||||
return NETDEV_TX_OK;
|
if (likely(!neigh))
|
||||||
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case htons(ETH_P_ARP):
|
case htons(ETH_P_ARP):
|
||||||
|
|
|
@ -818,7 +818,10 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
if (!neigh) {
|
if (!neigh) {
|
||||||
neigh = ipoib_neigh_alloc(daddr, dev);
|
neigh = ipoib_neigh_alloc(daddr, dev);
|
||||||
if (neigh) {
|
/* Make sure that the neigh will be added only
|
||||||
|
* once to mcast list.
|
||||||
|
*/
|
||||||
|
if (neigh && list_empty(&neigh->list)) {
|
||||||
kref_get(&mcast->ah->ref);
|
kref_get(&mcast->ah->ref);
|
||||||
neigh->ah = mcast->ah;
|
neigh->ah = mcast->ah;
|
||||||
list_add_tail(&neigh->list, &mcast->neigh_list);
|
list_add_tail(&neigh->list, &mcast->neigh_list);
|
||||||
|
|
|
@ -616,7 +616,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
|
||||||
* Ensure that stores to Normal memory are visible to the
|
* Ensure that stores to Normal memory are visible to the
|
||||||
* other CPUs before issuing the IPI.
|
* other CPUs before issuing the IPI.
|
||||||
*/
|
*/
|
||||||
smp_wmb();
|
wmb();
|
||||||
|
|
||||||
for_each_cpu(cpu, mask) {
|
for_each_cpu(cpu, mask) {
|
||||||
unsigned long cluster_id = cpu_logical_map(cpu) & ~0xffUL;
|
unsigned long cluster_id = cpu_logical_map(cpu) & ~0xffUL;
|
||||||
|
|
|
@ -186,7 +186,7 @@ void led_blink_set(struct led_classdev *led_cdev,
|
||||||
unsigned long *delay_on,
|
unsigned long *delay_on,
|
||||||
unsigned long *delay_off)
|
unsigned long *delay_off)
|
||||||
{
|
{
|
||||||
del_timer_sync(&led_cdev->blink_timer);
|
led_stop_software_blink(led_cdev);
|
||||||
|
|
||||||
led_cdev->flags &= ~LED_BLINK_ONESHOT;
|
led_cdev->flags &= ~LED_BLINK_ONESHOT;
|
||||||
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
||||||
|
|
|
@ -302,6 +302,7 @@ static void do_region(int op, int op_flags, unsigned region,
|
||||||
special_cmd_max_sectors = q->limits.max_write_same_sectors;
|
special_cmd_max_sectors = q->limits.max_write_same_sectors;
|
||||||
if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_SAME) &&
|
if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_SAME) &&
|
||||||
special_cmd_max_sectors == 0) {
|
special_cmd_max_sectors == 0) {
|
||||||
|
atomic_inc(&io->count);
|
||||||
dec_count(io, region, -EOPNOTSUPP);
|
dec_count(io, region, -EOPNOTSUPP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8224,6 +8224,10 @@ static int remove_and_add_spares(struct mddev *mddev,
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
bool remove_some = false;
|
bool remove_some = false;
|
||||||
|
|
||||||
|
if (this && test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
||||||
|
/* Mustn't remove devices when resync thread is running */
|
||||||
|
return 0;
|
||||||
|
|
||||||
rdev_for_each(rdev, mddev) {
|
rdev_for_each(rdev, mddev) {
|
||||||
if ((this == NULL || rdev == this) &&
|
if ((this == NULL || rdev == this) &&
|
||||||
rdev->raid_disk >= 0 &&
|
rdev->raid_disk >= 0 &&
|
||||||
|
|
|
@ -1262,11 +1262,12 @@ static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan)
|
||||||
* New users must use I2C client binding directly!
|
* New users must use I2C client binding directly!
|
||||||
*/
|
*/
|
||||||
struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
|
struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
|
||||||
struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter)
|
struct i2c_adapter *i2c,
|
||||||
|
struct i2c_adapter **tuner_i2c_adapter)
|
||||||
{
|
{
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct i2c_board_info board_info;
|
struct i2c_board_info board_info;
|
||||||
struct m88ds3103_platform_data pdata;
|
struct m88ds3103_platform_data pdata = {};
|
||||||
|
|
||||||
pdata.clk = cfg->clock;
|
pdata.clk = cfg->clock;
|
||||||
pdata.i2c_wr_max = cfg->i2c_wr_max;
|
pdata.i2c_wr_max = cfg->i2c_wr_max;
|
||||||
|
@ -1409,6 +1410,8 @@ static int m88ds3103_probe(struct i2c_client *client,
|
||||||
case M88DS3103_CHIP_ID:
|
case M88DS3103_CHIP_ID:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
ret = -ENODEV;
|
||||||
|
dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id);
|
||||||
goto err_kfree;
|
goto err_kfree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,12 +185,13 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
|
||||||
dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
|
dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
|
||||||
data, size, dma->nr_pages);
|
data, size, dma->nr_pages);
|
||||||
|
|
||||||
err = get_user_pages(data & PAGE_MASK, dma->nr_pages,
|
err = get_user_pages_longterm(data & PAGE_MASK, dma->nr_pages,
|
||||||
flags, dma->pages, NULL);
|
flags, dma->pages, NULL);
|
||||||
|
|
||||||
if (err != dma->nr_pages) {
|
if (err != dma->nr_pages) {
|
||||||
dma->nr_pages = (err >= 0) ? err : 0;
|
dma->nr_pages = (err >= 0) ? err : 0;
|
||||||
dprintk(1, "get_user_pages: err=%d [%d]\n", err, dma->nr_pages);
|
dprintk(1, "get_user_pages_longterm: err=%d [%d]\n", err,
|
||||||
|
dma->nr_pages);
|
||||||
return err < 0 ? err : -EINVAL;
|
return err < 0 ? err : -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1763,7 +1763,7 @@ try_dmaread:
|
||||||
err = brcmstb_nand_verify_erased_page(mtd, chip, buf,
|
err = brcmstb_nand_verify_erased_page(mtd, chip, buf,
|
||||||
addr);
|
addr);
|
||||||
/* erased page bitflips corrected */
|
/* erased page bitflips corrected */
|
||||||
if (err > 0)
|
if (err >= 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1278,9 +1278,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle the block mark swapping */
|
|
||||||
block_mark_swapping(this, payload_virt, auxiliary_virt);
|
|
||||||
|
|
||||||
/* Loop over status bytes, accumulating ECC status. */
|
/* Loop over status bytes, accumulating ECC status. */
|
||||||
status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
|
status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
|
||||||
|
|
||||||
|
@ -1377,6 +1374,9 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
|
||||||
max_bitflips = max_t(unsigned int, max_bitflips, *status);
|
max_bitflips = max_t(unsigned int, max_bitflips, *status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle the block mark swapping */
|
||||||
|
block_mark_swapping(this, buf, auxiliary_virt);
|
||||||
|
|
||||||
if (oob_required) {
|
if (oob_required) {
|
||||||
/*
|
/*
|
||||||
* It's time to deliver the OOB bytes. See gpmi_ecc_read_oob()
|
* It's time to deliver the OOB bytes. See gpmi_ecc_read_oob()
|
||||||
|
|
|
@ -537,7 +537,7 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
data = be32_to_cpup((__be32 *)&cf->data[0]);
|
data = be32_to_cpup((__be32 *)&cf->data[0]);
|
||||||
flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[0]);
|
flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[0]);
|
||||||
}
|
}
|
||||||
if (cf->can_dlc > 3) {
|
if (cf->can_dlc > 4) {
|
||||||
data = be32_to_cpup((__be32 *)&cf->data[4]);
|
data = be32_to_cpup((__be32 *)&cf->data[4]);
|
||||||
flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[1]);
|
flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[1]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,39 +210,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pktlen = info & LEN_MASK;
|
/* Prepare the BD for next cycle. netif_receive_skb()
|
||||||
stats->rx_packets++;
|
* only if new skb was allocated and mapped to avoid holes
|
||||||
stats->rx_bytes += pktlen;
|
* in the RX fifo.
|
||||||
skb = rx_buff->skb;
|
*/
|
||||||
skb_put(skb, pktlen);
|
skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE);
|
||||||
skb->dev = ndev;
|
if (unlikely(!skb)) {
|
||||||
skb->protocol = eth_type_trans(skb, ndev);
|
if (net_ratelimit())
|
||||||
|
netdev_err(ndev, "cannot allocate skb\n");
|
||||||
dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
|
/* Return ownership to EMAC */
|
||||||
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
|
rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
|
||||||
|
|
||||||
/* Prepare the BD for next cycle */
|
|
||||||
rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
|
|
||||||
EMAC_BUFFER_SIZE);
|
|
||||||
if (unlikely(!rx_buff->skb)) {
|
|
||||||
stats->rx_errors++;
|
stats->rx_errors++;
|
||||||
/* Because receive_skb is below, increment rx_dropped */
|
|
||||||
stats->rx_dropped++;
|
stats->rx_dropped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* receive_skb only if new skb was allocated to avoid holes */
|
addr = dma_map_single(&ndev->dev, (void *)skb->data,
|
||||||
netif_receive_skb(skb);
|
|
||||||
|
|
||||||
addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
|
|
||||||
EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
|
EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
|
||||||
if (dma_mapping_error(&ndev->dev, addr)) {
|
if (dma_mapping_error(&ndev->dev, addr)) {
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
netdev_err(ndev, "cannot dma map\n");
|
netdev_err(ndev, "cannot map dma buffer\n");
|
||||||
dev_kfree_skb(rx_buff->skb);
|
dev_kfree_skb(skb);
|
||||||
|
/* Return ownership to EMAC */
|
||||||
|
rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
|
||||||
stats->rx_errors++;
|
stats->rx_errors++;
|
||||||
|
stats->rx_dropped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* unmap previosly mapped skb */
|
||||||
|
dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
|
||||||
|
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
pktlen = info & LEN_MASK;
|
||||||
|
stats->rx_packets++;
|
||||||
|
stats->rx_bytes += pktlen;
|
||||||
|
skb_put(rx_buff->skb, pktlen);
|
||||||
|
rx_buff->skb->dev = ndev;
|
||||||
|
rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev);
|
||||||
|
|
||||||
|
netif_receive_skb(rx_buff->skb);
|
||||||
|
|
||||||
|
rx_buff->skb = skb;
|
||||||
dma_unmap_addr_set(rx_buff, addr, addr);
|
dma_unmap_addr_set(rx_buff, addr, addr);
|
||||||
dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
|
dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
|
||||||
|
|
||||||
|
|
|
@ -3034,7 +3034,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
|
||||||
|
|
||||||
del_timer_sync(&bp->timer);
|
del_timer_sync(&bp->timer);
|
||||||
|
|
||||||
if (IS_PF(bp)) {
|
if (IS_PF(bp) && !BP_NOMCP(bp)) {
|
||||||
/* Set ALWAYS_ALIVE bit in shmem */
|
/* Set ALWAYS_ALIVE bit in shmem */
|
||||||
bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
|
bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
|
||||||
bnx2x_drv_pulse(bp);
|
bnx2x_drv_pulse(bp);
|
||||||
|
@ -3120,7 +3120,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
|
||||||
bp->cnic_loaded = false;
|
bp->cnic_loaded = false;
|
||||||
|
|
||||||
/* Clear driver version indication in shmem */
|
/* Clear driver version indication in shmem */
|
||||||
if (IS_PF(bp))
|
if (IS_PF(bp) && !BP_NOMCP(bp))
|
||||||
bnx2x_update_mng_version(bp);
|
bnx2x_update_mng_version(bp);
|
||||||
|
|
||||||
/* Check if there are pending parity attentions. If there are - set
|
/* Check if there are pending parity attentions. If there are - set
|
||||||
|
|
|
@ -9578,6 +9578,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
|
bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
|
||||||
|
|
||||||
|
/* If we read all 0xFFs, means we are in PCI error state and
|
||||||
|
* should bail out to avoid crashes on adapter's FW reads.
|
||||||
|
*/
|
||||||
|
if (bp->common.shmem_base == 0xFFFFFFFF) {
|
||||||
|
bp->flags |= NO_MCP_FLAG;
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
if (bp->common.shmem_base) {
|
if (bp->common.shmem_base) {
|
||||||
val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
|
val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
|
||||||
if (val & SHR_MEM_VALIDITY_MB)
|
if (val & SHR_MEM_VALIDITY_MB)
|
||||||
|
@ -14312,7 +14321,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
|
||||||
BNX2X_ERR("IO slot reset --> driver unload\n");
|
BNX2X_ERR("IO slot reset --> driver unload\n");
|
||||||
|
|
||||||
/* MCP should have been reset; Need to wait for validity */
|
/* MCP should have been reset; Need to wait for validity */
|
||||||
bnx2x_init_shmem(bp);
|
if (bnx2x_init_shmem(bp)) {
|
||||||
|
rtnl_unlock();
|
||||||
|
return PCI_ERS_RESULT_DISCONNECT;
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
|
if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
|
||||||
u32 v;
|
u32 v;
|
||||||
|
|
|
@ -68,7 +68,7 @@ static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id)
|
||||||
netdev_err(bp->dev, "vf ndo called though sriov is disabled\n");
|
netdev_err(bp->dev, "vf ndo called though sriov is disabled\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (vf_id >= bp->pf.max_vfs) {
|
if (vf_id >= bp->pf.active_vfs) {
|
||||||
netdev_err(bp->dev, "Invalid VF id %d\n", vf_id);
|
netdev_err(bp->dev, "Invalid VF id %d\n", vf_id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10049,6 +10049,16 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
|
||||||
|
|
||||||
tw32(GRC_MODE, tp->grc_mode | val);
|
tw32(GRC_MODE, tp->grc_mode | val);
|
||||||
|
|
||||||
|
/* On one of the AMD platform, MRRS is restricted to 4000 because of
|
||||||
|
* south bridge limitation. As a workaround, Driver is setting MRRS
|
||||||
|
* to 2048 instead of default 4096.
|
||||||
|
*/
|
||||||
|
if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
|
||||||
|
tp->pdev->subsystem_device == TG3PCI_SUBDEVICE_ID_DELL_5762) {
|
||||||
|
val = tr32(TG3PCI_DEV_STATUS_CTRL) & ~MAX_READ_REQ_MASK;
|
||||||
|
tw32(TG3PCI_DEV_STATUS_CTRL, val | MAX_READ_REQ_SIZE_2048);
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the timer prescalar register. Clock is always 66Mhz. */
|
/* Setup the timer prescalar register. Clock is always 66Mhz. */
|
||||||
val = tr32(GRC_MISC_CFG);
|
val = tr32(GRC_MISC_CFG);
|
||||||
val &= ~0xff;
|
val &= ~0xff;
|
||||||
|
@ -14228,7 +14238,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
|
||||||
*/
|
*/
|
||||||
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_5717 ||
|
||||||
tg3_asic_rev(tp) == ASIC_REV_5719)
|
tg3_asic_rev(tp) == ASIC_REV_5719 ||
|
||||||
|
tg3_asic_rev(tp) == ASIC_REV_5720)
|
||||||
reset_phy = true;
|
reset_phy = true;
|
||||||
|
|
||||||
err = tg3_restart_hw(tp, reset_phy);
|
err = tg3_restart_hw(tp, reset_phy);
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
#define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106
|
#define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106
|
||||||
#define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109
|
#define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109
|
||||||
#define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a
|
#define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a
|
||||||
|
#define TG3PCI_SUBDEVICE_ID_DELL_5762 0x07f0
|
||||||
#define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ
|
#define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ
|
||||||
#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c
|
#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c
|
||||||
#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a
|
#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a
|
||||||
|
@ -280,6 +281,9 @@
|
||||||
#define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */
|
#define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */
|
||||||
#define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */
|
#define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */
|
||||||
/* 0xa8 --> 0xb8 unused */
|
/* 0xa8 --> 0xb8 unused */
|
||||||
|
#define TG3PCI_DEV_STATUS_CTRL 0x000000b4
|
||||||
|
#define MAX_READ_REQ_SIZE_2048 0x00004000
|
||||||
|
#define MAX_READ_REQ_MASK 0x00007000
|
||||||
#define TG3PCI_DUAL_MAC_CTRL 0x000000b8
|
#define TG3PCI_DUAL_MAC_CTRL 0x000000b8
|
||||||
#define DUAL_MAC_CTRL_CH_MASK 0x00000003
|
#define DUAL_MAC_CTRL_CH_MASK 0x00000003
|
||||||
#define DUAL_MAC_CTRL_ID 0x00000004
|
#define DUAL_MAC_CTRL_ID 0x00000004
|
||||||
|
|
|
@ -2596,7 +2596,6 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EEPROM_STAT_ADDR 0x7bfc
|
#define EEPROM_STAT_ADDR 0x7bfc
|
||||||
#define VPD_SIZE 0x800
|
|
||||||
#define VPD_BASE 0x400
|
#define VPD_BASE 0x400
|
||||||
#define VPD_BASE_OLD 0
|
#define VPD_BASE_OLD 0
|
||||||
#define VPD_LEN 1024
|
#define VPD_LEN 1024
|
||||||
|
@ -2634,15 +2633,6 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
|
||||||
if (!vpd)
|
if (!vpd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* We have two VPD data structures stored in the adapter VPD area.
|
|
||||||
* By default, Linux calculates the size of the VPD area by traversing
|
|
||||||
* the first VPD area at offset 0x0, so we need to tell the OS what
|
|
||||||
* our real VPD size is.
|
|
||||||
*/
|
|
||||||
ret = pci_set_vpd_size(adapter->pdev, VPD_SIZE);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Card information normally starts at VPD_BASE but early cards had
|
/* Card information normally starts at VPD_BASE but early cards had
|
||||||
* it at 0.
|
* it at 0.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -314,11 +314,10 @@ static int ptp_gianfar_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
||||||
now = tmr_cnt_read(etsects);
|
now = tmr_cnt_read(etsects);
|
||||||
now += delta;
|
now += delta;
|
||||||
tmr_cnt_write(etsects, now);
|
tmr_cnt_write(etsects, now);
|
||||||
|
set_fipers(etsects);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&etsects->lock, flags);
|
spin_unlock_irqrestore(&etsects->lock, flags);
|
||||||
|
|
||||||
set_fipers(etsects);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -331,7 +331,8 @@ struct e1000_adapter {
|
||||||
enum e1000_state_t {
|
enum e1000_state_t {
|
||||||
__E1000_TESTING,
|
__E1000_TESTING,
|
||||||
__E1000_RESETTING,
|
__E1000_RESETTING,
|
||||||
__E1000_DOWN
|
__E1000_DOWN,
|
||||||
|
__E1000_DISABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef pr_fmt
|
#undef pr_fmt
|
||||||
|
|
|
@ -940,7 +940,7 @@ static int e1000_init_hw_struct(struct e1000_adapter *adapter,
|
||||||
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct e1000_adapter *adapter;
|
struct e1000_adapter *adapter = NULL;
|
||||||
struct e1000_hw *hw;
|
struct e1000_hw *hw;
|
||||||
|
|
||||||
static int cards_found;
|
static int cards_found;
|
||||||
|
@ -950,6 +950,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
u16 tmp = 0;
|
u16 tmp = 0;
|
||||||
u16 eeprom_apme_mask = E1000_EEPROM_APME;
|
u16 eeprom_apme_mask = E1000_EEPROM_APME;
|
||||||
int bars, need_ioport;
|
int bars, need_ioport;
|
||||||
|
bool disable_dev = false;
|
||||||
|
|
||||||
/* do not allocate ioport bars when not needed */
|
/* do not allocate ioport bars when not needed */
|
||||||
need_ioport = e1000_is_need_ioport(pdev);
|
need_ioport = e1000_is_need_ioport(pdev);
|
||||||
|
@ -1250,11 +1251,13 @@ err_mdio_ioremap:
|
||||||
iounmap(hw->ce4100_gbe_mdio_base_virt);
|
iounmap(hw->ce4100_gbe_mdio_base_virt);
|
||||||
iounmap(hw->hw_addr);
|
iounmap(hw->hw_addr);
|
||||||
err_ioremap:
|
err_ioremap:
|
||||||
|
disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags);
|
||||||
free_netdev(netdev);
|
free_netdev(netdev);
|
||||||
err_alloc_etherdev:
|
err_alloc_etherdev:
|
||||||
pci_release_selected_regions(pdev, bars);
|
pci_release_selected_regions(pdev, bars);
|
||||||
err_pci_reg:
|
err_pci_reg:
|
||||||
pci_disable_device(pdev);
|
if (!adapter || disable_dev)
|
||||||
|
pci_disable_device(pdev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1272,6 +1275,7 @@ static void e1000_remove(struct pci_dev *pdev)
|
||||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
|
bool disable_dev;
|
||||||
|
|
||||||
e1000_down_and_stop(adapter);
|
e1000_down_and_stop(adapter);
|
||||||
e1000_release_manageability(adapter);
|
e1000_release_manageability(adapter);
|
||||||
|
@ -1290,9 +1294,11 @@ static void e1000_remove(struct pci_dev *pdev)
|
||||||
iounmap(hw->flash_address);
|
iounmap(hw->flash_address);
|
||||||
pci_release_selected_regions(pdev, adapter->bars);
|
pci_release_selected_regions(pdev, adapter->bars);
|
||||||
|
|
||||||
|
disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags);
|
||||||
free_netdev(netdev);
|
free_netdev(netdev);
|
||||||
|
|
||||||
pci_disable_device(pdev);
|
if (disable_dev)
|
||||||
|
pci_disable_device(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5166,7 +5172,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
|
||||||
if (netif_running(netdev))
|
if (netif_running(netdev))
|
||||||
e1000_free_irq(adapter);
|
e1000_free_irq(adapter);
|
||||||
|
|
||||||
pci_disable_device(pdev);
|
if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5210,6 +5217,10 @@ static int e1000_resume(struct pci_dev *pdev)
|
||||||
pr_err("Cannot enable PCI device from suspend\n");
|
pr_err("Cannot enable PCI device from suspend\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* flush memory to make sure state is correct */
|
||||||
|
smp_mb__before_atomic();
|
||||||
|
clear_bit(__E1000_DISABLED, &adapter->flags);
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
|
|
||||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||||
|
@ -5284,7 +5295,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
|
||||||
|
|
||||||
if (netif_running(netdev))
|
if (netif_running(netdev))
|
||||||
e1000_down(adapter);
|
e1000_down(adapter);
|
||||||
pci_disable_device(pdev);
|
|
||||||
|
if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
|
||||||
|
pci_disable_device(pdev);
|
||||||
|
|
||||||
/* Request a slot slot reset. */
|
/* Request a slot slot reset. */
|
||||||
return PCI_ERS_RESULT_NEED_RESET;
|
return PCI_ERS_RESULT_NEED_RESET;
|
||||||
|
@ -5312,6 +5325,10 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
|
||||||
pr_err("Cannot re-enable PCI device after reset.\n");
|
pr_err("Cannot re-enable PCI device after reset.\n");
|
||||||
return PCI_ERS_RESULT_DISCONNECT;
|
return PCI_ERS_RESULT_DISCONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* flush memory to make sure state is correct */
|
||||||
|
smp_mb__before_atomic();
|
||||||
|
clear_bit(__E1000_DISABLED, &adapter->flags);
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
|
|
||||||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||||
|
|
|
@ -2670,10 +2670,30 @@ bool __i40e_chk_linearize(struct sk_buff *skb)
|
||||||
/* Walk through fragments adding latest fragment, testing it, and
|
/* Walk through fragments adding latest fragment, testing it, and
|
||||||
* then removing stale fragments from the sum.
|
* then removing stale fragments from the sum.
|
||||||
*/
|
*/
|
||||||
stale = &skb_shinfo(skb)->frags[0];
|
for (stale = &skb_shinfo(skb)->frags[0];; stale++) {
|
||||||
for (;;) {
|
int stale_size = skb_frag_size(stale);
|
||||||
|
|
||||||
sum += skb_frag_size(frag++);
|
sum += skb_frag_size(frag++);
|
||||||
|
|
||||||
|
/* The stale fragment may present us with a smaller
|
||||||
|
* descriptor than the actual fragment size. To account
|
||||||
|
* for that we need to remove all the data on the front and
|
||||||
|
* figure out what the remainder would be in the last
|
||||||
|
* descriptor associated with the fragment.
|
||||||
|
*/
|
||||||
|
if (stale_size > I40E_MAX_DATA_PER_TXD) {
|
||||||
|
int align_pad = -(stale->page_offset) &
|
||||||
|
(I40E_MAX_READ_REQ_SIZE - 1);
|
||||||
|
|
||||||
|
sum -= align_pad;
|
||||||
|
stale_size -= align_pad;
|
||||||
|
|
||||||
|
do {
|
||||||
|
sum -= I40E_MAX_DATA_PER_TXD_ALIGNED;
|
||||||
|
stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED;
|
||||||
|
} while (stale_size > I40E_MAX_DATA_PER_TXD);
|
||||||
|
}
|
||||||
|
|
||||||
/* if sum is negative we failed to make sufficient progress */
|
/* if sum is negative we failed to make sufficient progress */
|
||||||
if (sum < 0)
|
if (sum < 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -2681,7 +2701,7 @@ bool __i40e_chk_linearize(struct sk_buff *skb)
|
||||||
if (!nr_frags--)
|
if (!nr_frags--)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sum -= skb_frag_size(stale++);
|
sum -= stale_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1872,10 +1872,30 @@ bool __i40evf_chk_linearize(struct sk_buff *skb)
|
||||||
/* Walk through fragments adding latest fragment, testing it, and
|
/* Walk through fragments adding latest fragment, testing it, and
|
||||||
* then removing stale fragments from the sum.
|
* then removing stale fragments from the sum.
|
||||||
*/
|
*/
|
||||||
stale = &skb_shinfo(skb)->frags[0];
|
for (stale = &skb_shinfo(skb)->frags[0];; stale++) {
|
||||||
for (;;) {
|
int stale_size = skb_frag_size(stale);
|
||||||
|
|
||||||
sum += skb_frag_size(frag++);
|
sum += skb_frag_size(frag++);
|
||||||
|
|
||||||
|
/* The stale fragment may present us with a smaller
|
||||||
|
* descriptor than the actual fragment size. To account
|
||||||
|
* for that we need to remove all the data on the front and
|
||||||
|
* figure out what the remainder would be in the last
|
||||||
|
* descriptor associated with the fragment.
|
||||||
|
*/
|
||||||
|
if (stale_size > I40E_MAX_DATA_PER_TXD) {
|
||||||
|
int align_pad = -(stale->page_offset) &
|
||||||
|
(I40E_MAX_READ_REQ_SIZE - 1);
|
||||||
|
|
||||||
|
sum -= align_pad;
|
||||||
|
stale_size -= align_pad;
|
||||||
|
|
||||||
|
do {
|
||||||
|
sum -= I40E_MAX_DATA_PER_TXD_ALIGNED;
|
||||||
|
stale_size -= I40E_MAX_DATA_PER_TXD_ALIGNED;
|
||||||
|
} while (stale_size > I40E_MAX_DATA_PER_TXD);
|
||||||
|
}
|
||||||
|
|
||||||
/* if sum is negative we failed to make sufficient progress */
|
/* if sum is negative we failed to make sufficient progress */
|
||||||
if (sum < 0)
|
if (sum < 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1883,7 +1903,7 @@ bool __i40evf_chk_linearize(struct sk_buff *skb)
|
||||||
if (!nr_frags--)
|
if (!nr_frags--)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sum -= skb_frag_size(stale++);
|
sum -= stale_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1842,11 +1842,12 @@ static int mtk_hw_init(struct mtk_eth *eth)
|
||||||
/* set GE2 TUNE */
|
/* set GE2 TUNE */
|
||||||
regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
|
regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
|
||||||
|
|
||||||
/* GE1, Force 1000M/FD, FC ON */
|
/* Set linkdown as the default for each GMAC. Its own MCR would be set
|
||||||
mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0));
|
* up with the more appropriate value when mtk_phy_link_adjust call is
|
||||||
|
* being invoked.
|
||||||
/* GE2, Force 1000M/FD, FC ON */
|
*/
|
||||||
mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1));
|
for (i = 0; i < MTK_MAC_COUNT; i++)
|
||||||
|
mtk_w32(eth, 0, MTK_MAC_MCR(i));
|
||||||
|
|
||||||
/* Enable RX VLan Offloading */
|
/* Enable RX VLan Offloading */
|
||||||
mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
|
mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
|
||||||
|
|
|
@ -809,6 +809,7 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||||
bool dynamic)
|
bool dynamic)
|
||||||
{
|
{
|
||||||
char *sfd_pl;
|
char *sfd_pl;
|
||||||
|
u8 num_rec;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
|
sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
|
||||||
|
@ -818,9 +819,16 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||||
mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
|
mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
|
||||||
mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
|
mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
|
||||||
mac, fid, action, local_port);
|
mac, fid, action, local_port);
|
||||||
|
num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
|
||||||
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
|
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
|
||||||
kfree(sfd_pl);
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
|
||||||
|
err = -EBUSY;
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(sfd_pl);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,6 +853,7 @@ static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id,
|
||||||
bool adding, bool dynamic)
|
bool adding, bool dynamic)
|
||||||
{
|
{
|
||||||
char *sfd_pl;
|
char *sfd_pl;
|
||||||
|
u8 num_rec;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
|
sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
|
||||||
|
@ -855,9 +864,16 @@ static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id,
|
||||||
mlxsw_reg_sfd_uc_lag_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
|
mlxsw_reg_sfd_uc_lag_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
|
||||||
mac, fid, MLXSW_REG_SFD_REC_ACTION_NOP,
|
mac, fid, MLXSW_REG_SFD_REC_ACTION_NOP,
|
||||||
lag_vid, lag_id);
|
lag_vid, lag_id);
|
||||||
|
num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
|
||||||
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
|
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
|
||||||
kfree(sfd_pl);
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
|
||||||
|
err = -EBUSY;
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(sfd_pl);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,6 +907,7 @@ static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr,
|
||||||
u16 fid, u16 mid, bool adding)
|
u16 fid, u16 mid, bool adding)
|
||||||
{
|
{
|
||||||
char *sfd_pl;
|
char *sfd_pl;
|
||||||
|
u8 num_rec;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
|
sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
|
||||||
|
@ -900,7 +917,15 @@ static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr,
|
||||||
mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
|
mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
|
||||||
mlxsw_reg_sfd_mc_pack(sfd_pl, 0, addr, fid,
|
mlxsw_reg_sfd_mc_pack(sfd_pl, 0, addr, fid,
|
||||||
MLXSW_REG_SFD_REC_ACTION_NOP, mid);
|
MLXSW_REG_SFD_REC_ACTION_NOP, mid);
|
||||||
|
num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
|
||||||
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
|
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
|
||||||
|
err = -EBUSY;
|
||||||
|
|
||||||
|
out:
|
||||||
kfree(sfd_pl);
|
kfree(sfd_pl);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr,
|
||||||
{
|
{
|
||||||
u32 value = readl(ioaddr + PTP_TCR);
|
u32 value = readl(ioaddr + PTP_TCR);
|
||||||
unsigned long data;
|
unsigned long data;
|
||||||
|
u32 reg_value;
|
||||||
|
|
||||||
/* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second
|
/* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second
|
||||||
* formula = (1/ptp_clock) * 1000000000
|
* formula = (1/ptp_clock) * 1000000000
|
||||||
|
@ -54,10 +55,11 @@ static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr,
|
||||||
|
|
||||||
data &= PTP_SSIR_SSINC_MASK;
|
data &= PTP_SSIR_SSINC_MASK;
|
||||||
|
|
||||||
|
reg_value = data;
|
||||||
if (gmac4)
|
if (gmac4)
|
||||||
data = data << GMAC4_PTP_SSIR_SSINC_SHIFT;
|
reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT;
|
||||||
|
|
||||||
writel(data, ioaddr + PTP_SSIR);
|
writel(reg_value, ioaddr + PTP_SSIR);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1377,9 +1377,14 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unregister_netdev:
|
unregister_netdev:
|
||||||
|
/* macvlan_uninit would free the macvlan port */
|
||||||
unregister_netdevice(dev);
|
unregister_netdevice(dev);
|
||||||
|
return err;
|
||||||
destroy_macvlan_port:
|
destroy_macvlan_port:
|
||||||
if (create)
|
/* the macvlan port may be freed by macvlan_uninit when fail to register.
|
||||||
|
* so we destroy the macvlan port only when it's valid.
|
||||||
|
*/
|
||||||
|
if (create && macvlan_port_get_rtnl(dev))
|
||||||
macvlan_port_destroy(port->dev);
|
macvlan_port_destroy(port->dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,8 +118,10 @@ static int sun4i_mdio_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
data->regulator = devm_regulator_get(&pdev->dev, "phy");
|
data->regulator = devm_regulator_get(&pdev->dev, "phy");
|
||||||
if (IS_ERR(data->regulator)) {
|
if (IS_ERR(data->regulator)) {
|
||||||
if (PTR_ERR(data->regulator) == -EPROBE_DEFER)
|
if (PTR_ERR(data->regulator) == -EPROBE_DEFER) {
|
||||||
return -EPROBE_DEFER;
|
ret = -EPROBE_DEFER;
|
||||||
|
goto err_out_free_mdiobus;
|
||||||
|
}
|
||||||
|
|
||||||
dev_info(&pdev->dev, "no regulator found\n");
|
dev_info(&pdev->dev, "no regulator found\n");
|
||||||
data->regulator = NULL;
|
data->regulator = NULL;
|
||||||
|
|
|
@ -197,8 +197,11 @@ static int xgene_mdio_reset(struct xgene_mdio_pdata *pdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = xgene_enet_ecc_init(pdata);
|
ret = xgene_enet_ecc_init(pdata);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
if (pdata->dev->of_node)
|
||||||
|
clk_disable_unprepare(pdata->clk);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
xgene_gmac_reset(pdata);
|
xgene_gmac_reset(pdata);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -364,8 +367,10 @@ static int xgene_mdio_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mdio_bus = mdiobus_alloc();
|
mdio_bus = mdiobus_alloc();
|
||||||
if (!mdio_bus)
|
if (!mdio_bus) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto out_clk;
|
||||||
|
}
|
||||||
|
|
||||||
mdio_bus->name = "APM X-Gene MDIO bus";
|
mdio_bus->name = "APM X-Gene MDIO bus";
|
||||||
|
|
||||||
|
@ -394,7 +399,7 @@ static int xgene_mdio_probe(struct platform_device *pdev)
|
||||||
mdio_bus->phy_mask = ~0;
|
mdio_bus->phy_mask = ~0;
|
||||||
ret = mdiobus_register(mdio_bus);
|
ret = mdiobus_register(mdio_bus);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out_mdiobus;
|
||||||
|
|
||||||
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1,
|
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1,
|
||||||
acpi_register_phy, NULL, mdio_bus, NULL);
|
acpi_register_phy, NULL, mdio_bus, NULL);
|
||||||
|
@ -402,16 +407,20 @@ static int xgene_mdio_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out_mdiobus;
|
||||||
|
|
||||||
pdata->mdio_bus = mdio_bus;
|
pdata->mdio_bus = mdio_bus;
|
||||||
xgene_mdio_status = true;
|
xgene_mdio_status = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out:
|
out_mdiobus:
|
||||||
mdiobus_free(mdio_bus);
|
mdiobus_free(mdio_bus);
|
||||||
|
|
||||||
|
out_clk:
|
||||||
|
if (dev->of_node)
|
||||||
|
clk_disable_unprepare(pdata->clk);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -925,7 +925,7 @@ void phy_start(struct phy_device *phydev)
|
||||||
break;
|
break;
|
||||||
case PHY_HALTED:
|
case PHY_HALTED:
|
||||||
/* make sure interrupts are re-enabled for the PHY */
|
/* make sure interrupts are re-enabled for the PHY */
|
||||||
if (phydev->irq != PHY_POLL) {
|
if (phy_interrupt_is_valid(phydev)) {
|
||||||
err = phy_enable_interrupts(phydev);
|
err = phy_enable_interrupts(phydev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3157,6 +3157,15 @@ ppp_connect_channel(struct channel *pch, int unit)
|
||||||
goto outl;
|
goto outl;
|
||||||
|
|
||||||
ppp_lock(ppp);
|
ppp_lock(ppp);
|
||||||
|
spin_lock_bh(&pch->downl);
|
||||||
|
if (!pch->chan) {
|
||||||
|
/* Don't connect unregistered channels */
|
||||||
|
spin_unlock_bh(&pch->downl);
|
||||||
|
ppp_unlock(ppp);
|
||||||
|
ret = -ENOTCONN;
|
||||||
|
goto outl;
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&pch->downl);
|
||||||
if (pch->file.hdrlen > ppp->file.hdrlen)
|
if (pch->file.hdrlen > ppp->file.hdrlen)
|
||||||
ppp->file.hdrlen = pch->file.hdrlen;
|
ppp->file.hdrlen = pch->file.hdrlen;
|
||||||
hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */
|
hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */
|
||||||
|
|
|
@ -805,6 +805,7 @@ static const struct usb_device_id products[] = {
|
||||||
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
|
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
|
||||||
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
|
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
|
||||||
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
|
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
|
||||||
|
{QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */
|
||||||
{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
|
{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
|
||||||
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
|
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
|
||||||
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
|
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
|
||||||
|
@ -914,6 +915,7 @@ static const struct usb_device_id products[] = {
|
||||||
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
|
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
|
||||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
|
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
|
||||||
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
|
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
|
||||||
|
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
|
||||||
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
||||||
{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
|
{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
|
||||||
{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */
|
{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */
|
||||||
|
|
|
@ -574,7 +574,10 @@ static void ppp_timer(unsigned long arg)
|
||||||
ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
|
ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
proto->restart_counter--;
|
proto->restart_counter--;
|
||||||
} else
|
} else if (netif_carrier_ok(proto->dev))
|
||||||
|
ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
|
||||||
|
0, NULL);
|
||||||
|
else
|
||||||
ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0,
|
ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3154,7 +3154,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
|
||||||
if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
|
if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
res = -ENOMEM;
|
res = -ENOMEM;
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
|
@ -1345,6 +1345,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
|
||||||
|
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
|
|
||||||
|
xenbus_switch_state(dev, XenbusStateInitialising);
|
||||||
return netdev;
|
return netdev;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue