Merge 4.9.72 into android-4.9
Changes in 4.9.72 cxl: Check if vphb exists before iterating over AFU devices arm64: Initialise high_memory global variable earlier ALSA: hda - add support for docking station for HP 820 G2 ALSA: hda - add support for docking station for HP 840 G3 kvm: fix usage of uninit spinlock in avic_vm_destroy() HID: corsair: support for K65-K70 Rapidfire and Scimitar Pro RGB HID: corsair: Add driver Scimitar Pro RGB gaming mouse 1b1c:1b3e support to hid-corsair arm: kprobes: Fix the return address of multiple kretprobes arm: kprobes: Align stack to 8-bytes in test code nvme-loop: handle cpu unplug when re-establishing the controller cpuidle: Validate cpu_dev in cpuidle_add_sysfs() r8152: fix the list rx_done may be used without initialization crypto: deadlock between crypto_alg_sem/rtnl_mutex/genl_mutex vsock: track pkt owner vsock vhost-vsock: add pkt cancel capability vsock: cancel packets when failing to connect sch_dsmark: fix invalid skb_cow() usage bna: integer overflow bug in debugfs sctp: out_qlen should be updated when pruning unsent queue net: qmi_wwan: Add USB IDs for MDM6600 modem on Motorola Droid 4 hwmon: (max31790) Set correct PWM value usb: gadget: f_uvc: Sanity check wMaxPacketSize for SuperSpeed usb: gadget: udc: remove pointer dereference after free netfilter: nfnl_cthelper: fix runtime expectation policy updates netfilter: nfnl_cthelper: Fix memory leak iommu/exynos: Workaround FLPD cache flush issues for SYSMMU v5 r8152: fix the rx early size of RTL8153 tipc: fix nametbl deadlock at tipc_nametbl_unsubscribe inet: frag: release spinlock before calling icmp_send() pinctrl: st: add irq_request/release_resources callbacks scsi: lpfc: Fix PT2PT PRLI reject kvm: vmx: Flush TLB when the APIC-access address changes KVM: x86: correct async page present tracepoint KVM: VMX: Fix enable VPID conditions ARM: dts: ti: fix PCI bus dtc warnings hwmon: (asus_atk0110) fix uninitialized data access HID: xinmo: fix for out of range for THT 2P arcade controller. ASoC: STI: Fix reader substream pointer set r8152: prevent the driver from transmitting packets with carrier off s390/qeth: size calculation outbound buffers s390/qeth: no ETH header for outbound AF_IUCV bna: avoid writing uninitialized data into hw registers i40iw: Receive netdev events post INET_NOTIFIER state IB/core: Protect against self-requeue of a cq work item infiniband: Fix alignment of mmap cookies to support VIPT caching nbd: set queue timeout properly net: Do not allow negative values for busy_read and busy_poll sysctl interfaces IB/rxe: double free on error IB/rxe: increment msn only when completing a request i40e: Do not enable NAPI on q_vectors that have no rings RDMA/iser: Fix possible mr leak on device removal event irda: vlsi_ir: fix check for DMA mapping errors netfilter: nfnl_cthelper: fix a race when walk the nf_ct_helper_hash table netfilter: nf_nat_snmp: Fix panic when snmp_trap_helper fails to register ARM: dts: am335x-evmsk: adjust mmc2 param to allow suspend cpufreq: Fix creation of symbolic links to policy directories net: ipconfig: fix ic_close_devs() use-after-free KVM: pci-assign: do not map smm memory slot pages in vt-d page tables virtio-balloon: use actual number of stats for stats queue buffers virtio_balloon: prevent uninitialized variable use isdn: kcapi: avoid uninitialized data net: moxa: fix TX overrun memory leak xhci: plat: Register shutdown for xhci_plat netfilter: nfnetlink_queue: fix secctx memory leak Btrfs: fix an integer overflow check ARM: dma-mapping: disallow dma_get_sgtable() for non-kernel managed memory cpuidle: powernv: Pass correct drv->cpumask for registration bnxt_en: Fix NULL pointer dereference in reopen failure path backlight: pwm_bl: Fix overflow condition crypto: crypto4xx - increase context and scatter ring buffer elements rtc: pl031: make interrupt optional kvm, mm: account kvm related kmem slabs to kmemcg net: phy: at803x: Change error to EINVAL for invalid MAC PCI: Avoid bus reset if bridge itself is broken scsi: cxgb4i: fix Tx skb leak scsi: mpt3sas: Fix IO error occurs on pulling out a drive from RAID1 volume created on two SATA drive PCI: Create SR-IOV virtfn/physfn links before attaching driver PM / OPP: Move error message to debug level igb: check memory allocation failure ixgbe: fix use of uninitialized padding IB/rxe: check for allocation failure on elem PCI/AER: Report non-fatal errors only to the affected endpoint tracing: Exclude 'generic fields' from histograms ASoC: img-parallel-out: Add pm_runtime_get/put to set_fmt callback fm10k: fix mis-ordered parameters in declaration for .ndo_set_vf_bw scsi: lpfc: Fix secure firmware updates scsi: lpfc: PLOGI failures during NPIV testing vfio/pci: Virtualize Maximum Payload Size fm10k: ensure we process SM mbx when processing VF mbx net: ipv6: send NS for DAD when link operationally up staging: greybus: light: Release memory obtained by kasprintf clk: sunxi-ng: sun6i: Rename HDMI DDC clock to avoid name collision tcp: fix under-evaluated ssthresh in TCP Vegas rtc: set the alarm to the next expiring timer cpuidle: fix broadcast control when broadcast can not be entered thermal: hisilicon: Handle return value of clk_prepare_enable thermal/drivers/hisi: Fix missing interrupt enablement thermal/drivers/hisi: Fix kernel panic on alarm interrupt thermal/drivers/hisi: Simplify the temperature/step computation thermal/drivers/hisi: Fix multiple alarm interrupts firing MIPS: math-emu: Fix final emulation phase for certain instructions platform/x86: asus-wireless: send an EV_SYN/SYN_REPORT between state changes Revert "Bluetooth: btusb: driver to enable the usb-wakeup feature" bpf: adjust insn_aux_data when patching insns bpf: fix branch pruning logic bpf: reject out-of-bounds stack pointer calculation bpf: fix incorrect sign extension in check_alu_op() sparc32: Export vac_cache_size to fix build error Linux 4.9.72 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 71
|
||||
SUBLEVEL = 72
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -668,6 +668,7 @@
|
||||
ti,non-removable;
|
||||
bus-width = <4>;
|
||||
cap-power-off-card;
|
||||
keep-power-in-suspend;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc2_pins>;
|
||||
|
||||
|
||||
@@ -282,6 +282,7 @@
|
||||
device_type = "pci";
|
||||
ranges = <0x81000000 0 0 0x03000 0 0x00010000
|
||||
0x82000000 0 0x20013000 0x13000 0 0xffed000>;
|
||||
bus-range = <0x00 0xff>;
|
||||
#interrupt-cells = <1>;
|
||||
num-lanes = <1>;
|
||||
linux,pci-domain = <0>;
|
||||
@@ -318,6 +319,7 @@
|
||||
device_type = "pci";
|
||||
ranges = <0x81000000 0 0 0x03000 0 0x00010000
|
||||
0x82000000 0 0x30013000 0x13000 0 0xffed000>;
|
||||
bus-range = <0x00 0xff>;
|
||||
#interrupt-cells = <1>;
|
||||
num-lanes = <1>;
|
||||
linux,pci-domain = <1>;
|
||||
|
||||
@@ -930,13 +930,31 @@ static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_add
|
||||
__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
|
||||
* that the intention is to allow exporting memory allocated via the
|
||||
* coherent DMA APIs through the dma_buf API, which only accepts a
|
||||
* scattertable. This presents a couple of problems:
|
||||
* 1. Not all memory allocated via the coherent DMA APIs is backed by
|
||||
* a struct page
|
||||
* 2. Passing coherent DMA memory into the streaming APIs is not allowed
|
||||
* as we will try to flush the memory through a different alias to that
|
||||
* actually being used (and the flushes are redundant.)
|
||||
*/
|
||||
int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
|
||||
void *cpu_addr, dma_addr_t handle, size_t size,
|
||||
unsigned long attrs)
|
||||
{
|
||||
struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
|
||||
unsigned long pfn = dma_to_pfn(dev, handle);
|
||||
struct page *page;
|
||||
int ret;
|
||||
|
||||
/* If the PFN is not valid, we do not have a struct page */
|
||||
if (!pfn_valid(pfn))
|
||||
return -ENXIO;
|
||||
|
||||
page = pfn_to_page(pfn);
|
||||
|
||||
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
@@ -433,6 +433,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
||||
struct hlist_node *tmp;
|
||||
unsigned long flags, orig_ret_address = 0;
|
||||
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
|
||||
kprobe_opcode_t *correct_ret_addr = NULL;
|
||||
|
||||
INIT_HLIST_HEAD(&empty_rp);
|
||||
kretprobe_hash_lock(current, &head, &flags);
|
||||
@@ -455,15 +456,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
||||
/* another task is sharing our hash bucket */
|
||||
continue;
|
||||
|
||||
if (ri->rp && ri->rp->handler) {
|
||||
__this_cpu_write(current_kprobe, &ri->rp->kp);
|
||||
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
ri->rp->handler(ri, regs);
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
|
||||
orig_ret_address = (unsigned long)ri->ret_addr;
|
||||
recycle_rp_inst(ri, &empty_rp);
|
||||
|
||||
if (orig_ret_address != trampoline_address)
|
||||
/*
|
||||
@@ -475,6 +468,33 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
|
||||
}
|
||||
|
||||
kretprobe_assert(ri, orig_ret_address, trampoline_address);
|
||||
|
||||
correct_ret_addr = ri->ret_addr;
|
||||
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
|
||||
if (ri->task != current)
|
||||
/* another task is sharing our hash bucket */
|
||||
continue;
|
||||
|
||||
orig_ret_address = (unsigned long)ri->ret_addr;
|
||||
if (ri->rp && ri->rp->handler) {
|
||||
__this_cpu_write(current_kprobe, &ri->rp->kp);
|
||||
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
|
||||
ri->ret_addr = correct_ret_addr;
|
||||
ri->rp->handler(ri, regs);
|
||||
__this_cpu_write(current_kprobe, NULL);
|
||||
}
|
||||
|
||||
recycle_rp_inst(ri, &empty_rp);
|
||||
|
||||
if (orig_ret_address != trampoline_address)
|
||||
/*
|
||||
* This is the real return address. Any other
|
||||
* instances associated with this task are for
|
||||
* other calls deeper on the call stack
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
kretprobe_hash_unlock(current, &flags);
|
||||
|
||||
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
|
||||
|
||||
@@ -976,7 +976,10 @@ static void coverage_end(void)
|
||||
void __naked __kprobes_test_case_start(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"stmdb sp!, {r4-r11} \n\t"
|
||||
"mov r2, sp \n\t"
|
||||
"bic r3, r2, #7 \n\t"
|
||||
"mov sp, r3 \n\t"
|
||||
"stmdb sp!, {r2-r11} \n\t"
|
||||
"sub sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
|
||||
"bic r0, lr, #1 @ r0 = inline data \n\t"
|
||||
"mov r1, sp \n\t"
|
||||
@@ -996,7 +999,8 @@ void __naked __kprobes_test_case_end_32(void)
|
||||
"movne pc, r0 \n\t"
|
||||
"mov r0, r4 \n\t"
|
||||
"add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
|
||||
"ldmia sp!, {r4-r11} \n\t"
|
||||
"ldmia sp!, {r2-r11} \n\t"
|
||||
"mov sp, r2 \n\t"
|
||||
"mov pc, r0 \n\t"
|
||||
);
|
||||
}
|
||||
@@ -1012,7 +1016,8 @@ void __naked __kprobes_test_case_end_16(void)
|
||||
"bxne r0 \n\t"
|
||||
"mov r0, r4 \n\t"
|
||||
"add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t"
|
||||
"ldmia sp!, {r4-r11} \n\t"
|
||||
"ldmia sp!, {r2-r11} \n\t"
|
||||
"mov sp, r2 \n\t"
|
||||
"bx r0 \n\t"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -299,6 +299,7 @@ void __init arm64_memblock_init(void)
|
||||
arm64_dma_phys_limit = max_zone_dma_phys();
|
||||
else
|
||||
arm64_dma_phys_limit = PHYS_MASK + 1;
|
||||
high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
|
||||
dma_contiguous_reserve(arm64_dma_phys_limit);
|
||||
|
||||
memblock_allow_resize();
|
||||
@@ -325,7 +326,6 @@ void __init bootmem_init(void)
|
||||
sparse_init();
|
||||
zone_sizes_init(min, max);
|
||||
|
||||
high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
|
||||
memblock_dump_all();
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -1781,7 +1781,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
SPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.s = ieee754sp_maddf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmsubf_op: {
|
||||
@@ -1794,7 +1794,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
SPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.s = ieee754sp_msubf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case frint_op: {
|
||||
@@ -1818,7 +1818,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.w = ieee754sp_2008class(fs);
|
||||
rfmt = w_fmt;
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmin_op: {
|
||||
@@ -1830,7 +1830,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmin(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmina_op: {
|
||||
@@ -1842,7 +1842,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmina(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmax_op: {
|
||||
@@ -1854,7 +1854,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmax(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmaxa_op: {
|
||||
@@ -1866,7 +1866,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
SPFROMREG(ft, MIPSInst_FT(ir));
|
||||
SPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.s = ieee754sp_fmaxa(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fabs_op:
|
||||
@@ -2110,7 +2110,7 @@ copcsr:
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
DPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.d = ieee754dp_maddf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmsubf_op: {
|
||||
@@ -2123,7 +2123,7 @@ copcsr:
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
DPFROMREG(fd, MIPSInst_FD(ir));
|
||||
rv.d = ieee754dp_msubf(fd, fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case frint_op: {
|
||||
@@ -2147,7 +2147,7 @@ copcsr:
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.w = ieee754dp_2008class(fs);
|
||||
rfmt = w_fmt;
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmin_op: {
|
||||
@@ -2159,7 +2159,7 @@ copcsr:
|
||||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmin(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmina_op: {
|
||||
@@ -2171,7 +2171,7 @@ copcsr:
|
||||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmina(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmax_op: {
|
||||
@@ -2183,7 +2183,7 @@ copcsr:
|
||||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmax(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fmaxa_op: {
|
||||
@@ -2195,7 +2195,7 @@ copcsr:
|
||||
DPFROMREG(ft, MIPSInst_FT(ir));
|
||||
DPFROMREG(fs, MIPSInst_FS(ir));
|
||||
rv.d = ieee754dp_fmaxa(fs, ft);
|
||||
break;
|
||||
goto copcsr;
|
||||
}
|
||||
|
||||
case fabs_op:
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
enum mbus_module srmmu_modtype;
|
||||
static unsigned int hwbug_bitmask;
|
||||
int vac_cache_size;
|
||||
EXPORT_SYMBOL(vac_cache_size);
|
||||
int vac_line_size;
|
||||
|
||||
extern struct resource sparc_iomap;
|
||||
|
||||
+2
-2
@@ -5052,13 +5052,13 @@ int kvm_mmu_module_init(void)
|
||||
{
|
||||
pte_list_desc_cache = kmem_cache_create("pte_list_desc",
|
||||
sizeof(struct pte_list_desc),
|
||||
0, 0, NULL);
|
||||
0, SLAB_ACCOUNT, NULL);
|
||||
if (!pte_list_desc_cache)
|
||||
goto nomem;
|
||||
|
||||
mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header",
|
||||
sizeof(struct kvm_mmu_page),
|
||||
0, 0, NULL);
|
||||
0, SLAB_ACCOUNT, NULL);
|
||||
if (!mmu_page_header_cache)
|
||||
goto nomem;
|
||||
|
||||
|
||||
@@ -1382,6 +1382,9 @@ static void avic_vm_destroy(struct kvm *kvm)
|
||||
unsigned long flags;
|
||||
struct kvm_arch *vm_data = &kvm->arch;
|
||||
|
||||
if (!avic)
|
||||
return;
|
||||
|
||||
avic_free_vm_id(vm_data->avic_vm_id);
|
||||
|
||||
if (vm_data->avic_logical_id_table_page)
|
||||
|
||||
+25
-2
@@ -1199,6 +1199,11 @@ static inline bool cpu_has_vmx_invvpid_global(void)
|
||||
return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_vmx_invvpid(void)
|
||||
{
|
||||
return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
|
||||
}
|
||||
|
||||
static inline bool cpu_has_vmx_ept(void)
|
||||
{
|
||||
return vmcs_config.cpu_based_2nd_exec_ctrl &
|
||||
@@ -3816,6 +3821,12 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
|
||||
__vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid);
|
||||
}
|
||||
|
||||
static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (enable_ept)
|
||||
vmx_flush_tlb(vcpu);
|
||||
}
|
||||
|
||||
static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
|
||||
@@ -6428,8 +6439,10 @@ static __init int hardware_setup(void)
|
||||
if (boot_cpu_has(X86_FEATURE_NX))
|
||||
kvm_enable_efer_bits(EFER_NX);
|
||||
|
||||
if (!cpu_has_vmx_vpid())
|
||||
if (!cpu_has_vmx_vpid() || !cpu_has_vmx_invvpid() ||
|
||||
!(cpu_has_vmx_invvpid_single() || cpu_has_vmx_invvpid_global()))
|
||||
enable_vpid = 0;
|
||||
|
||||
if (!cpu_has_vmx_shadow_vmcs())
|
||||
enable_shadow_vmcs = 0;
|
||||
if (enable_shadow_vmcs)
|
||||
@@ -8494,6 +8507,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
|
||||
} else {
|
||||
sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
||||
sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
||||
vmx_flush_tlb_ept_only(vcpu);
|
||||
}
|
||||
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control);
|
||||
|
||||
@@ -8519,8 +8533,10 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa)
|
||||
*/
|
||||
if (!is_guest_mode(vcpu) ||
|
||||
!nested_cpu_has2(get_vmcs12(&vmx->vcpu),
|
||||
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES))
|
||||
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
|
||||
vmcs_write64(APIC_ACCESS_ADDR, hpa);
|
||||
vmx_flush_tlb_ept_only(vcpu);
|
||||
}
|
||||
}
|
||||
|
||||
static void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
|
||||
@@ -10092,6 +10108,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
|
||||
if (nested_cpu_has_ept(vmcs12)) {
|
||||
kvm_mmu_unload(vcpu);
|
||||
nested_ept_init_mmu_context(vcpu);
|
||||
} else if (nested_cpu_has2(vmcs12,
|
||||
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
|
||||
vmx_flush_tlb_ept_only(vcpu);
|
||||
}
|
||||
|
||||
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)
|
||||
@@ -10832,6 +10851,10 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
|
||||
vmx->nested.change_vmcs01_virtual_x2apic_mode = false;
|
||||
vmx_set_virtual_x2apic_mode(vcpu,
|
||||
vcpu->arch.apic_base & X2APIC_ENABLE);
|
||||
} else if (!nested_cpu_has_ept(vmcs12) &&
|
||||
nested_cpu_has2(vmcs12,
|
||||
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
|
||||
vmx_flush_tlb_ept_only(vcpu);
|
||||
}
|
||||
|
||||
/* This is needed for same reason as it was needed in prepare_vmcs02 */
|
||||
|
||||
+1
-1
@@ -8443,11 +8443,11 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
struct x86_exception fault;
|
||||
|
||||
trace_kvm_async_pf_ready(work->arch.token, work->gva);
|
||||
if (work->wakeup_all)
|
||||
work->arch.token = ~0; /* broadcast wakeup */
|
||||
else
|
||||
kvm_del_async_pf_gfn(vcpu, work->arch.gfn);
|
||||
trace_kvm_async_pf_ready(work->arch.token, work->gva);
|
||||
|
||||
if ((vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED) &&
|
||||
!apf_put_user(vcpu, KVM_PV_REASON_PAGE_READY)) {
|
||||
|
||||
@@ -331,7 +331,7 @@ int dev_pm_opp_get_opp_count(struct device *dev)
|
||||
opp_table = _find_opp_table(dev);
|
||||
if (IS_ERR(opp_table)) {
|
||||
count = PTR_ERR(opp_table);
|
||||
dev_err(dev, "%s: OPP table not found (%d)\n",
|
||||
dev_dbg(dev, "%s: OPP table not found (%d)\n",
|
||||
__func__, count);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
+4
-1
@@ -654,7 +654,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
||||
return nbd_size_set(nbd, bdev, nbd->blksize, arg);
|
||||
|
||||
case NBD_SET_TIMEOUT:
|
||||
nbd->tag_set.timeout = arg * HZ;
|
||||
if (arg) {
|
||||
nbd->tag_set.timeout = arg * HZ;
|
||||
blk_queue_rq_timeout(nbd->disk->queue, arg * HZ);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case NBD_SET_FLAGS:
|
||||
|
||||
@@ -1059,10 +1059,6 @@ static int btusb_open(struct hci_dev *hdev)
|
||||
}
|
||||
|
||||
data->intf->needs_remote_wakeup = 1;
|
||||
/* device specific wakeup source enabled and required for USB
|
||||
* remote wakeup while host is suspended
|
||||
*/
|
||||
device_wakeup_enable(&data->udev->dev);
|
||||
|
||||
if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
|
||||
goto done;
|
||||
@@ -1126,7 +1122,6 @@ static int btusb_close(struct hci_dev *hdev)
|
||||
goto failed;
|
||||
|
||||
data->intf->needs_remote_wakeup = 0;
|
||||
device_wakeup_disable(&data->udev->dev);
|
||||
usb_autopm_put_interface(data->intf);
|
||||
|
||||
failed:
|
||||
|
||||
@@ -608,7 +608,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
|
||||
0x150, 0, 4, 24, 2, BIT(31),
|
||||
CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "ddc", "osc24M", 0x150, BIT(30), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
|
||||
|
||||
|
||||
+21
-17
@@ -980,11 +980,19 @@ static struct kobj_type ktype_cpufreq = {
|
||||
.release = cpufreq_sysfs_release,
|
||||
};
|
||||
|
||||
static int add_cpu_dev_symlink(struct cpufreq_policy *policy,
|
||||
struct device *dev)
|
||||
static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu)
|
||||
{
|
||||
struct device *dev = get_cpu_device(cpu);
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (cpumask_test_and_set_cpu(cpu, policy->real_cpus))
|
||||
return;
|
||||
|
||||
dev_dbg(dev, "%s: Adding symlink\n", __func__);
|
||||
return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
|
||||
if (sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"))
|
||||
dev_err(dev, "cpufreq symlink creation failed\n");
|
||||
}
|
||||
|
||||
static void remove_cpu_dev_symlink(struct cpufreq_policy *policy,
|
||||
@@ -1246,10 +1254,10 @@ static int cpufreq_online(unsigned int cpu)
|
||||
policy->user_policy.min = policy->min;
|
||||
policy->user_policy.max = policy->max;
|
||||
|
||||
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
||||
for_each_cpu(j, policy->related_cpus)
|
||||
for_each_cpu(j, policy->related_cpus) {
|
||||
per_cpu(cpufreq_cpu_data, j) = policy;
|
||||
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
||||
add_cpu_dev_symlink(policy, j);
|
||||
}
|
||||
} else {
|
||||
policy->min = policy->user_policy.min;
|
||||
policy->max = policy->user_policy.max;
|
||||
@@ -1346,13 +1354,15 @@ out_exit_policy:
|
||||
|
||||
if (cpufreq_driver->exit)
|
||||
cpufreq_driver->exit(policy);
|
||||
|
||||
for_each_cpu(j, policy->real_cpus)
|
||||
remove_cpu_dev_symlink(policy, get_cpu_device(j));
|
||||
|
||||
out_free_policy:
|
||||
cpufreq_policy_free(policy, !new_policy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpufreq_offline(unsigned int cpu);
|
||||
|
||||
/**
|
||||
* cpufreq_add_dev - the cpufreq interface for a CPU device.
|
||||
* @dev: CPU device.
|
||||
@@ -1374,16 +1384,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
|
||||
|
||||
/* Create sysfs link on CPU registration */
|
||||
policy = per_cpu(cpufreq_cpu_data, cpu);
|
||||
if (!policy || cpumask_test_and_set_cpu(cpu, policy->real_cpus))
|
||||
return 0;
|
||||
if (policy)
|
||||
add_cpu_dev_symlink(policy, cpu);
|
||||
|
||||
ret = add_cpu_dev_symlink(policy, dev);
|
||||
if (ret) {
|
||||
cpumask_clear_cpu(cpu, policy->real_cpus);
|
||||
cpufreq_offline(cpu);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpufreq_offline(unsigned int cpu)
|
||||
|
||||
@@ -164,6 +164,24 @@ static int powernv_cpuidle_driver_init(void)
|
||||
drv->state_count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* On the PowerNV platform cpu_present may be less than cpu_possible in
|
||||
* cases when firmware detects the CPU, but it is not available to the
|
||||
* OS. If CONFIG_HOTPLUG_CPU=n, then such CPUs are not hotplugable at
|
||||
* run time and hence cpu_devices are not created for those CPUs by the
|
||||
* generic topology_init().
|
||||
*
|
||||
* drv->cpumask defaults to cpu_possible_mask in
|
||||
* __cpuidle_driver_init(). This breaks cpuidle on PowerNV where
|
||||
* cpu_devices are not created for CPUs in cpu_possible_mask that
|
||||
* cannot be hot-added later at run time.
|
||||
*
|
||||
* Trying cpuidle_register_device() on a CPU without a cpu_device is
|
||||
* incorrect, so pass a correct CPU mask to the generic cpuidle driver.
|
||||
*/
|
||||
|
||||
drv->cpumask = (struct cpumask *)cpu_present_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
||||
return -EBUSY;
|
||||
}
|
||||
target_state = &drv->states[index];
|
||||
broadcast = false;
|
||||
}
|
||||
|
||||
/* Take note of the planned idle state. */
|
||||
|
||||
@@ -613,6 +613,18 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev)
|
||||
struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu);
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Return if cpu_device is not setup for this CPU.
|
||||
*
|
||||
* This could happen if the arch did not set up cpu_device
|
||||
* since this CPU is not in cpu_present mask and the
|
||||
* driver did not send a correct CPU mask during registration.
|
||||
* Without this check we would end up passing bogus
|
||||
* value for &cpu_dev->kobj in kobject_init_and_add()
|
||||
*/
|
||||
if (!cpu_dev)
|
||||
return -ENODEV;
|
||||
|
||||
kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
|
||||
if (!kdev)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
#define PPC405EX_CE_RESET 0x00000008
|
||||
|
||||
#define CRYPTO4XX_CRYPTO_PRIORITY 300
|
||||
#define PPC4XX_LAST_PD 63
|
||||
#define PPC4XX_NUM_PD 64
|
||||
#define PPC4XX_LAST_GD 1023
|
||||
#define PPC4XX_NUM_PD 256
|
||||
#define PPC4XX_LAST_PD (PPC4XX_NUM_PD - 1)
|
||||
#define PPC4XX_NUM_GD 1024
|
||||
#define PPC4XX_LAST_SD 63
|
||||
#define PPC4XX_NUM_SD 64
|
||||
#define PPC4XX_LAST_GD (PPC4XX_NUM_GD - 1)
|
||||
#define PPC4XX_NUM_SD 256
|
||||
#define PPC4XX_LAST_SD (PPC4XX_NUM_SD - 1)
|
||||
#define PPC4XX_SD_BUFFER_SIZE 2048
|
||||
|
||||
#define PD_ENTRY_INUSE 1
|
||||
|
||||
@@ -190,6 +190,7 @@ config HID_CORSAIR
|
||||
|
||||
Supported devices:
|
||||
- Vengeance K90
|
||||
- Scimitar PRO RGB
|
||||
|
||||
config HID_PRODIKEYS
|
||||
tristate "Prodikeys PC-MIDI Keyboard support"
|
||||
|
||||
@@ -1872,6 +1872,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
|
||||
@@ -2106,6 +2107,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
*
|
||||
* Supported devices:
|
||||
* - Vengeance K90 Keyboard
|
||||
* - Scimitar PRO RGB Gaming Mouse
|
||||
*
|
||||
* Copyright (c) 2015 Clement Vuchener
|
||||
* Copyright (c) 2017 Oscar Campos
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -670,10 +672,51 @@ static int corsair_input_mapping(struct hid_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The report descriptor of Corsair Scimitar RGB Pro gaming mouse is
|
||||
* non parseable as they define two consecutive Logical Minimum for
|
||||
* the Usage Page (Consumer) in rdescs bytes 75 and 77 being 77 0x16
|
||||
* that should be obviousy 0x26 for Logical Magimum of 16 bits. This
|
||||
* prevents poper parsing of the report descriptor due Logical
|
||||
* Minimum being larger than Logical Maximum.
|
||||
*
|
||||
* This driver fixes the report descriptor for:
|
||||
* - USB ID b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse
|
||||
*/
|
||||
|
||||
static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int *rsize)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
|
||||
|
||||
if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
|
||||
/*
|
||||
* Corsair Scimitar RGB Pro report descriptor is broken and
|
||||
* defines two different Logical Minimum for the Consumer
|
||||
* Application. The byte 77 should be a 0x26 defining a 16
|
||||
* bits integer for the Logical Maximum but it is a 0x16
|
||||
* instead (Logical Minimum)
|
||||
*/
|
||||
switch (hdev->product) {
|
||||
case USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB:
|
||||
if (*rsize >= 172 && rdesc[75] == 0x15 && rdesc[77] == 0x16
|
||||
&& rdesc[78] == 0xff && rdesc[79] == 0x0f) {
|
||||
hid_info(hdev, "Fixing up report descriptor\n");
|
||||
rdesc[77] = 0x26;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return rdesc;
|
||||
}
|
||||
|
||||
static const struct hid_device_id corsair_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90),
|
||||
.driver_data = CORSAIR_USE_K90_MACRO |
|
||||
CORSAIR_USE_K90_BACKLIGHT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
|
||||
USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -686,10 +729,14 @@ static struct hid_driver corsair_driver = {
|
||||
.event = corsair_event,
|
||||
.remove = corsair_remove,
|
||||
.input_mapping = corsair_input_mapping,
|
||||
.report_fixup = corsair_mouse_report_fixup,
|
||||
};
|
||||
|
||||
module_hid_driver(corsair_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
/* Original K90 driver author */
|
||||
MODULE_AUTHOR("Clement Vuchener");
|
||||
/* Scimitar PRO RGB driver author */
|
||||
MODULE_AUTHOR("Oscar Campos");
|
||||
MODULE_DESCRIPTION("HID driver for Corsair devices");
|
||||
|
||||
@@ -277,6 +277,9 @@
|
||||
#define USB_DEVICE_ID_CORSAIR_K70RGB 0x1b13
|
||||
#define USB_DEVICE_ID_CORSAIR_STRAFE 0x1b15
|
||||
#define USB_DEVICE_ID_CORSAIR_K65RGB 0x1b17
|
||||
#define USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE 0x1b38
|
||||
#define USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE 0x1b39
|
||||
#define USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB 0x1b3e
|
||||
|
||||
#define USB_VENDOR_ID_CREATIVELABS 0x041e
|
||||
#define USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51 0x322c
|
||||
@@ -1077,6 +1080,7 @@
|
||||
|
||||
#define USB_VENDOR_ID_XIN_MO 0x16c0
|
||||
#define USB_DEVICE_ID_XIN_MO_DUAL_ARCADE 0x05e1
|
||||
#define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1
|
||||
|
||||
#define USB_VENDOR_ID_XIROKU 0x1477
|
||||
#define USB_DEVICE_ID_XIROKU_SPX 0x1006
|
||||
|
||||
@@ -46,6 +46,7 @@ static int xinmo_event(struct hid_device *hdev, struct hid_field *field,
|
||||
|
||||
static const struct hid_device_id xinmo_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_THT_2P_ARCADE) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -80,6 +80,9 @@ static const struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
|
||||
|
||||
@@ -646,6 +646,9 @@ static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
|
||||
else
|
||||
err = atk_read_value_new(sensor, value);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sensor->is_valid = true;
|
||||
sensor->last_updated = jiffies;
|
||||
sensor->cached_value = *value;
|
||||
|
||||
@@ -311,7 +311,7 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel,
|
||||
data->pwm[channel] = val << 8;
|
||||
err = i2c_smbus_write_word_swapped(client,
|
||||
MAX31790_REG_PWMOUT(channel),
|
||||
val);
|
||||
data->pwm[channel]);
|
||||
break;
|
||||
case hwmon_pwm_enable:
|
||||
fan_config = data->fan_config[channel];
|
||||
|
||||
@@ -196,7 +196,7 @@ void ib_free_cq(struct ib_cq *cq)
|
||||
irq_poll_disable(&cq->iop);
|
||||
break;
|
||||
case IB_POLL_WORKQUEUE:
|
||||
flush_work(&cq->work);
|
||||
cancel_work_sync(&cq->work);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
|
||||
@@ -159,6 +159,9 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
|
||||
return NOTIFY_DONE;
|
||||
|
||||
iwdev = &hdl->device;
|
||||
if (iwdev->init_state < INET_NOTIFIER)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
netdev = iwdev->ldev->netdev;
|
||||
upper_dev = netdev_master_upper_dev_get(netdev);
|
||||
if (netdev != event_netdev)
|
||||
@@ -231,6 +234,9 @@ int i40iw_inet6addr_event(struct notifier_block *notifier,
|
||||
return NOTIFY_DONE;
|
||||
|
||||
iwdev = &hdl->device;
|
||||
if (iwdev->init_state < INET_NOTIFIER)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
netdev = iwdev->ldev->netdev;
|
||||
if (netdev != event_netdev)
|
||||
return NOTIFY_DONE;
|
||||
@@ -280,6 +286,8 @@ int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void *
|
||||
if (!iwhdl)
|
||||
return NOTIFY_DONE;
|
||||
iwdev = &iwhdl->device;
|
||||
if (iwdev->init_state < INET_NOTIFIER)
|
||||
return NOTIFY_DONE;
|
||||
p = (__be32 *)neigh->primary_key;
|
||||
i40iw_copy_ip_ntohl(local_ipaddr, p);
|
||||
if (neigh->nud_state & NUD_VALID) {
|
||||
|
||||
@@ -170,9 +170,9 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi,
|
||||
|
||||
spin_lock_irq(&rdi->mmap_offset_lock);
|
||||
if (rdi->mmap_offset == 0)
|
||||
rdi->mmap_offset = PAGE_SIZE;
|
||||
rdi->mmap_offset = ALIGN(PAGE_SIZE, SHMLBA);
|
||||
ip->offset = rdi->mmap_offset;
|
||||
rdi->mmap_offset += size;
|
||||
rdi->mmap_offset += ALIGN(size, SHMLBA);
|
||||
spin_unlock_irq(&rdi->mmap_offset_lock);
|
||||
|
||||
INIT_LIST_HEAD(&ip->pending_mmaps);
|
||||
|
||||
@@ -156,10 +156,10 @@ struct rxe_mmap_info *rxe_create_mmap_info(struct rxe_dev *rxe,
|
||||
spin_lock_bh(&rxe->mmap_offset_lock);
|
||||
|
||||
if (rxe->mmap_offset == 0)
|
||||
rxe->mmap_offset = PAGE_SIZE;
|
||||
rxe->mmap_offset = ALIGN(PAGE_SIZE, SHMLBA);
|
||||
|
||||
ip->info.offset = rxe->mmap_offset;
|
||||
rxe->mmap_offset += size;
|
||||
rxe->mmap_offset += ALIGN(size, SHMLBA);
|
||||
|
||||
spin_unlock_bh(&rxe->mmap_offset_lock);
|
||||
|
||||
|
||||
@@ -412,6 +412,8 @@ void *rxe_alloc(struct rxe_pool *pool)
|
||||
elem = kmem_cache_zalloc(pool_cache(pool),
|
||||
(pool->flags & RXE_POOL_ATOMIC) ?
|
||||
GFP_ATOMIC : GFP_KERNEL);
|
||||
if (!elem)
|
||||
return NULL;
|
||||
|
||||
elem->pool = pool;
|
||||
kref_init(&elem->ref_cnt);
|
||||
|
||||
@@ -726,11 +726,11 @@ next_wqe:
|
||||
ret = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, &pkt, skb);
|
||||
if (ret) {
|
||||
qp->need_req_skb = 1;
|
||||
kfree_skb(skb);
|
||||
|
||||
rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
kfree_skb(skb);
|
||||
rxe_run_task(&qp->req.task, 1);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@@ -799,18 +799,17 @@ static enum resp_states execute(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
|
||||
/* Unreachable */
|
||||
WARN_ON(1);
|
||||
|
||||
/* We successfully processed this new request. */
|
||||
qp->resp.msn++;
|
||||
|
||||
/* next expected psn, read handles this separately */
|
||||
qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK;
|
||||
|
||||
qp->resp.opcode = pkt->opcode;
|
||||
qp->resp.status = IB_WC_SUCCESS;
|
||||
|
||||
if (pkt->mask & RXE_COMP_MASK)
|
||||
if (pkt->mask & RXE_COMP_MASK) {
|
||||
/* We successfully processed this new request. */
|
||||
qp->resp.msn++;
|
||||
return RESPST_COMPLETE;
|
||||
else if (qp_type(qp) == IB_QPT_RC)
|
||||
} else if (qp_type(qp) == IB_QPT_RC)
|
||||
return RESPST_ACKNOWLEDGE;
|
||||
else
|
||||
return RESPST_CLEANUP;
|
||||
|
||||
@@ -430,6 +430,7 @@ struct iser_fr_desc {
|
||||
struct list_head list;
|
||||
struct iser_reg_resources rsc;
|
||||
struct iser_pi_context *pi_ctx;
|
||||
struct list_head all_list;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -443,6 +444,7 @@ struct iser_fr_pool {
|
||||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
int size;
|
||||
struct list_head all_list;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -362,6 +362,7 @@ int iser_alloc_fastreg_pool(struct ib_conn *ib_conn,
|
||||
int i, ret;
|
||||
|
||||
INIT_LIST_HEAD(&fr_pool->list);
|
||||
INIT_LIST_HEAD(&fr_pool->all_list);
|
||||
spin_lock_init(&fr_pool->lock);
|
||||
fr_pool->size = 0;
|
||||
for (i = 0; i < cmds_max; i++) {
|
||||
@@ -373,6 +374,7 @@ int iser_alloc_fastreg_pool(struct ib_conn *ib_conn,
|
||||
}
|
||||
|
||||
list_add_tail(&desc->list, &fr_pool->list);
|
||||
list_add_tail(&desc->all_list, &fr_pool->all_list);
|
||||
fr_pool->size++;
|
||||
}
|
||||
|
||||
@@ -392,13 +394,13 @@ void iser_free_fastreg_pool(struct ib_conn *ib_conn)
|
||||
struct iser_fr_desc *desc, *tmp;
|
||||
int i = 0;
|
||||
|
||||
if (list_empty(&fr_pool->list))
|
||||
if (list_empty(&fr_pool->all_list))
|
||||
return;
|
||||
|
||||
iser_info("freeing conn %p fr pool\n", ib_conn);
|
||||
|
||||
list_for_each_entry_safe(desc, tmp, &fr_pool->list, list) {
|
||||
list_del(&desc->list);
|
||||
list_for_each_entry_safe(desc, tmp, &fr_pool->all_list, all_list) {
|
||||
list_del(&desc->all_list);
|
||||
iser_free_reg_res(&desc->rsc);
|
||||
if (desc->pi_ctx)
|
||||
iser_free_pi_ctx(desc->pi_ctx);
|
||||
|
||||
@@ -543,7 +543,10 @@ static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
|
||||
if (is_sysmmu_active(data) && data->version >= MAKE_MMU_VER(3, 3)) {
|
||||
clk_enable(data->clk_master);
|
||||
if (sysmmu_block(data)) {
|
||||
__sysmmu_tlb_invalidate_entry(data, iova, 1);
|
||||
if (data->version >= MAKE_MMU_VER(5, 0))
|
||||
__sysmmu_tlb_invalidate(data);
|
||||
else
|
||||
__sysmmu_tlb_invalidate_entry(data, iova, 1);
|
||||
sysmmu_unblock(data);
|
||||
}
|
||||
clk_disable(data->clk_master);
|
||||
|
||||
@@ -1032,6 +1032,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
|
||||
sizeof(avmb1_carddef))))
|
||||
return -EFAULT;
|
||||
cdef.cardtype = AVM_CARDTYPE_B1;
|
||||
cdef.cardnr = 0;
|
||||
} else {
|
||||
if ((retval = copy_from_user(&cdef, data,
|
||||
sizeof(avmb1_extcarddef))))
|
||||
|
||||
@@ -1758,6 +1758,9 @@ static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
|
||||
/* There should only be one entry, but go through the list
|
||||
* anyway
|
||||
*/
|
||||
if (afu->phb == NULL)
|
||||
return result;
|
||||
|
||||
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
|
||||
if (!afu_dev->driver)
|
||||
continue;
|
||||
@@ -1801,6 +1804,11 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
|
||||
/* Only participate in EEH if we are on a virtual PHB */
|
||||
if (afu->phb == NULL)
|
||||
return PCI_ERS_RESULT_NONE;
|
||||
|
||||
/*
|
||||
* Tell the AFU drivers; but we don't care what they
|
||||
* say, we're going away.
|
||||
*/
|
||||
cxl_vphb_error_detected(afu, state);
|
||||
}
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
@@ -1941,6 +1949,9 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
|
||||
if (cxl_afu_select_best_mode(afu))
|
||||
goto err;
|
||||
|
||||
if (afu->phb == NULL)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
|
||||
/* Reset the device context.
|
||||
* TODO: make this less disruptive
|
||||
@@ -2003,6 +2014,9 @@ static void cxl_pci_resume(struct pci_dev *pdev)
|
||||
for (i = 0; i < adapter->slices; i++) {
|
||||
afu = adapter->afu[i];
|
||||
|
||||
if (afu->phb == NULL)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
|
||||
if (afu_dev->driver && afu_dev->driver->err_handler &&
|
||||
afu_dev->driver->err_handler->resume)
|
||||
|
||||
@@ -2381,6 +2381,18 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bnxt_init_cp_rings(struct bnxt *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bp->cp_nr_rings; i++) {
|
||||
struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring;
|
||||
struct bnxt_ring_struct *ring = &cpr->cp_ring_struct;
|
||||
|
||||
ring->fw_ring_id = INVALID_HW_RING_ID;
|
||||
}
|
||||
}
|
||||
|
||||
static int bnxt_init_rx_rings(struct bnxt *bp)
|
||||
{
|
||||
int i, rc = 0;
|
||||
@@ -4700,6 +4712,7 @@ static int bnxt_shutdown_nic(struct bnxt *bp, bool irq_re_init)
|
||||
|
||||
static int bnxt_init_nic(struct bnxt *bp, bool irq_re_init)
|
||||
{
|
||||
bnxt_init_cp_rings(bp);
|
||||
bnxt_init_rx_rings(bp);
|
||||
bnxt_init_tx_rings(bp);
|
||||
bnxt_init_ring_grps(bp, irq_re_init);
|
||||
|
||||
@@ -1930,13 +1930,13 @@ static void
|
||||
bfa_ioc_send_enable(struct bfa_ioc *ioc)
|
||||
{
|
||||
struct bfi_ioc_ctrl_req enable_req;
|
||||
struct timeval tv;
|
||||
|
||||
bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
|
||||
bfa_ioc_portid(ioc));
|
||||
enable_req.clscode = htons(ioc->clscode);
|
||||
do_gettimeofday(&tv);
|
||||
enable_req.tv_sec = ntohl(tv.tv_sec);
|
||||
enable_req.rsvd = htons(0);
|
||||
/* overflow in 2106 */
|
||||
enable_req.tv_sec = ntohl(ktime_get_real_seconds());
|
||||
bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req));
|
||||
}
|
||||
|
||||
@@ -1947,6 +1947,10 @@ bfa_ioc_send_disable(struct bfa_ioc *ioc)
|
||||
|
||||
bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
|
||||
bfa_ioc_portid(ioc));
|
||||
disable_req.clscode = htons(ioc->clscode);
|
||||
disable_req.rsvd = htons(0);
|
||||
/* overflow in 2106 */
|
||||
disable_req.tv_sec = ntohl(ktime_get_real_seconds());
|
||||
bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req));
|
||||
}
|
||||
|
||||
|
||||
@@ -325,7 +325,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
|
||||
return PTR_ERR(kern_buf);
|
||||
|
||||
rc = sscanf(kern_buf, "%x:%x", &addr, &len);
|
||||
if (rc < 2) {
|
||||
if (rc < 2 || len > UINT_MAX >> 2) {
|
||||
netdev_warn(bnad->netdev, "failed to read user buffer\n");
|
||||
kfree(kern_buf);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -508,8 +508,8 @@ s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid);
|
||||
int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac);
|
||||
int fm10k_ndo_set_vf_vlan(struct net_device *netdev,
|
||||
int vf_idx, u16 vid, u8 qos, __be16 vlan_proto);
|
||||
int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, int rate,
|
||||
int unused);
|
||||
int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx,
|
||||
int __always_unused min_rate, int max_rate);
|
||||
int fm10k_ndo_get_vf_config(struct net_device *netdev,
|
||||
int vf_idx, struct ifla_vf_info *ivi);
|
||||
|
||||
|
||||
@@ -126,6 +126,9 @@ process_mbx:
|
||||
struct fm10k_mbx_info *mbx = &vf_info->mbx;
|
||||
u16 glort = vf_info->glort;
|
||||
|
||||
/* process the SM mailbox first to drain outgoing messages */
|
||||
hw->mbx.ops.process(hw, &hw->mbx);
|
||||
|
||||
/* verify port mapping is valid, if not reset port */
|
||||
if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort))
|
||||
hw->iov.ops.reset_lport(hw, vf_info);
|
||||
@@ -482,7 +485,7 @@ int fm10k_ndo_set_vf_vlan(struct net_device *netdev, int vf_idx, u16 vid,
|
||||
}
|
||||
|
||||
int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx,
|
||||
int __always_unused unused, int rate)
|
||||
int __always_unused min_rate, int max_rate)
|
||||
{
|
||||
struct fm10k_intfc *interface = netdev_priv(netdev);
|
||||
struct fm10k_iov_data *iov_data = interface->iov_data;
|
||||
@@ -493,14 +496,15 @@ int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx,
|
||||
return -EINVAL;
|
||||
|
||||
/* rate limit cannot be less than 10Mbs or greater than link speed */
|
||||
if (rate && ((rate < FM10K_VF_TC_MIN) || rate > FM10K_VF_TC_MAX))
|
||||
if (max_rate &&
|
||||
(max_rate < FM10K_VF_TC_MIN || max_rate > FM10K_VF_TC_MAX))
|
||||
return -EINVAL;
|
||||
|
||||
/* store values */
|
||||
iov_data->vf_info[vf_idx].rate = rate;
|
||||
iov_data->vf_info[vf_idx].rate = max_rate;
|
||||
|
||||
/* update hardware configuration */
|
||||
hw->iov.ops.configure_tc(hw, vf_idx, rate);
|
||||
hw->iov.ops.configure_tc(hw, vf_idx, max_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4217,8 +4217,12 @@ static void i40e_napi_enable_all(struct i40e_vsi *vsi)
|
||||
if (!vsi->netdev)
|
||||
return;
|
||||
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
|
||||
napi_enable(&vsi->q_vectors[q_idx]->napi);
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
|
||||
struct i40e_q_vector *q_vector = vsi->q_vectors[q_idx];
|
||||
|
||||
if (q_vector->rx.ring || q_vector->tx.ring)
|
||||
napi_enable(&q_vector->napi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4232,8 +4236,12 @@ static void i40e_napi_disable_all(struct i40e_vsi *vsi)
|
||||
if (!vsi->netdev)
|
||||
return;
|
||||
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++)
|
||||
napi_disable(&vsi->q_vectors[q_idx]->napi);
|
||||
for (q_idx = 0; q_idx < vsi->num_q_vectors; q_idx++) {
|
||||
struct i40e_q_vector *q_vector = vsi->q_vectors[q_idx];
|
||||
|
||||
if (q_vector->rx.ring || q_vector->tx.ring)
|
||||
napi_disable(&q_vector->napi);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3102,6 +3102,8 @@ static int igb_sw_init(struct igb_adapter *adapter)
|
||||
/* Setup and initialize a copy of the hw vlan table array */
|
||||
adapter->shadow_vfta = kcalloc(E1000_VLAN_FILTER_TBL_SIZE, sizeof(u32),
|
||||
GFP_ATOMIC);
|
||||
if (!adapter->shadow_vfta)
|
||||
return -ENOMEM;
|
||||
|
||||
/* This call may decrease the number of queues */
|
||||
if (igb_init_interrupt_scheme(adapter, true)) {
|
||||
|
||||
@@ -3696,10 +3696,10 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
|
||||
fw_cmd.ver_build = build;
|
||||
fw_cmd.ver_sub = sub;
|
||||
fw_cmd.hdr.checksum = 0;
|
||||
fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
|
||||
(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
|
||||
fw_cmd.pad = 0;
|
||||
fw_cmd.pad2 = 0;
|
||||
fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
|
||||
(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
|
||||
|
||||
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
|
||||
ret_val = ixgbe_host_interface_command(hw, &fw_cmd,
|
||||
|
||||
@@ -617,6 +617,8 @@ static s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
|
||||
/* convert offset from words to bytes */
|
||||
buffer.address = cpu_to_be32((offset + current_word) * 2);
|
||||
buffer.length = cpu_to_be16(words_to_read * 2);
|
||||
buffer.pad2 = 0;
|
||||
buffer.pad3 = 0;
|
||||
|
||||
status = ixgbe_host_interface_command(hw, &buffer,
|
||||
sizeof(buffer),
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/crc32c.h>
|
||||
#include <linux/circ_buf.h>
|
||||
|
||||
#include "moxart_ether.h"
|
||||
|
||||
@@ -278,6 +279,13 @@ rx_next:
|
||||
return rx;
|
||||
}
|
||||
|
||||
static int moxart_tx_queue_space(struct net_device *ndev)
|
||||
{
|
||||
struct moxart_mac_priv_t *priv = netdev_priv(ndev);
|
||||
|
||||
return CIRC_SPACE(priv->tx_head, priv->tx_tail, TX_DESC_NUM);
|
||||
}
|
||||
|
||||
static void moxart_tx_finished(struct net_device *ndev)
|
||||
{
|
||||
struct moxart_mac_priv_t *priv = netdev_priv(ndev);
|
||||
@@ -297,6 +305,9 @@ static void moxart_tx_finished(struct net_device *ndev)
|
||||
tx_tail = TX_NEXT(tx_tail);
|
||||
}
|
||||
priv->tx_tail = tx_tail;
|
||||
if (netif_queue_stopped(ndev) &&
|
||||
moxart_tx_queue_space(ndev) >= TX_WAKE_THRESHOLD)
|
||||
netif_wake_queue(ndev);
|
||||
}
|
||||
|
||||
static irqreturn_t moxart_mac_interrupt(int irq, void *dev_id)
|
||||
@@ -324,13 +335,18 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
struct moxart_mac_priv_t *priv = netdev_priv(ndev);
|
||||
void *desc;
|
||||
unsigned int len;
|
||||
unsigned int tx_head = priv->tx_head;
|
||||
unsigned int tx_head;
|
||||
u32 txdes1;
|
||||
int ret = NETDEV_TX_BUSY;
|
||||
|
||||
spin_lock_irq(&priv->txlock);
|
||||
|
||||
tx_head = priv->tx_head;
|
||||
desc = priv->tx_desc_base + (TX_REG_DESC_SIZE * tx_head);
|
||||
|
||||
spin_lock_irq(&priv->txlock);
|
||||
if (moxart_tx_queue_space(ndev) == 1)
|
||||
netif_stop_queue(ndev);
|
||||
|
||||
if (moxart_desc_read(desc + TX_REG_OFFSET_DESC0) & TX_DESC0_DMA_OWN) {
|
||||
net_dbg_ratelimited("no TX space for packet\n");
|
||||
priv->stats.tx_dropped++;
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#define TX_NEXT(N) (((N) + 1) & (TX_DESC_NUM_MASK))
|
||||
#define TX_BUF_SIZE 1600
|
||||
#define TX_BUF_SIZE_MAX (TX_DESC1_BUF_SIZE_MASK+1)
|
||||
#define TX_WAKE_THRESHOLD 16
|
||||
|
||||
#define RX_DESC_NUM 64
|
||||
#define RX_DESC_NUM_MASK (RX_DESC_NUM-1)
|
||||
|
||||
@@ -418,8 +418,9 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr
|
||||
memset(rd, 0, sizeof(*rd));
|
||||
rd->hw = hwmap + i;
|
||||
rd->buf = kmalloc(len, GFP_KERNEL|GFP_DMA);
|
||||
if (rd->buf == NULL ||
|
||||
!(busaddr = pci_map_single(pdev, rd->buf, len, dir))) {
|
||||
if (rd->buf)
|
||||
busaddr = pci_map_single(pdev, rd->buf, len, dir);
|
||||
if (rd->buf == NULL || pci_dma_mapping_error(pdev, busaddr)) {
|
||||
if (rd->buf) {
|
||||
net_err_ratelimited("%s: failed to create PCI-MAP for %p\n",
|
||||
__func__, rd->buf);
|
||||
@@ -430,8 +431,7 @@ static struct vlsi_ring *vlsi_alloc_ring(struct pci_dev *pdev, struct ring_descr
|
||||
rd = r->rd + j;
|
||||
busaddr = rd_get_addr(rd);
|
||||
rd_set_addr_status(rd, 0, 0);
|
||||
if (busaddr)
|
||||
pci_unmap_single(pdev, busaddr, len, dir);
|
||||
pci_unmap_single(pdev, busaddr, len, dir);
|
||||
kfree(rd->buf);
|
||||
rd->buf = NULL;
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ static int at803x_set_wol(struct phy_device *phydev,
|
||||
mac = (const u8 *) ndev->dev_addr;
|
||||
|
||||
if (!is_valid_ether_addr(mac))
|
||||
return -EFAULT;
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
|
||||
|
||||
@@ -582,6 +582,10 @@ static const struct usb_device_id products[] = {
|
||||
USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69),
|
||||
.driver_info = (unsigned long)&qmi_wwan_info,
|
||||
},
|
||||
{ /* Motorola Mapphone devices with MDM6600 */
|
||||
USB_VENDOR_AND_INTERFACE_INFO(0x22b8, USB_CLASS_VENDOR_SPEC, 0xfb, 0xff),
|
||||
.driver_info = (unsigned long)&qmi_wwan_info,
|
||||
},
|
||||
|
||||
/* 2. Combined interface devices matching on class+protocol */
|
||||
{ /* Huawei E367 and possibly others in "Windows mode" */
|
||||
|
||||
+21
-5
@@ -32,7 +32,7 @@
|
||||
#define NETNEXT_VERSION "08"
|
||||
|
||||
/* Information for net */
|
||||
#define NET_VERSION "8"
|
||||
#define NET_VERSION "9"
|
||||
|
||||
#define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION
|
||||
#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
|
||||
@@ -501,6 +501,8 @@ enum rtl_register_content {
|
||||
#define RTL8153_RMS RTL8153_MAX_PACKET
|
||||
#define RTL8152_TX_TIMEOUT (5 * HZ)
|
||||
#define RTL8152_NAPI_WEIGHT 64
|
||||
#define rx_reserved_size(x) ((x) + VLAN_ETH_HLEN + CRC_SIZE + \
|
||||
sizeof(struct rx_desc) + RX_ALIGN)
|
||||
|
||||
/* rtl8152 flags */
|
||||
enum rtl8152_flags {
|
||||
@@ -1292,6 +1294,7 @@ static void intr_callback(struct urb *urb)
|
||||
}
|
||||
} else {
|
||||
if (netif_carrier_ok(tp->netdev)) {
|
||||
netif_stop_queue(tp->netdev);
|
||||
set_bit(RTL8152_LINK_CHG, &tp->flags);
|
||||
schedule_delayed_work(&tp->schedule, 0);
|
||||
}
|
||||
@@ -1362,6 +1365,7 @@ static int alloc_all_mem(struct r8152 *tp)
|
||||
spin_lock_init(&tp->rx_lock);
|
||||
spin_lock_init(&tp->tx_lock);
|
||||
INIT_LIST_HEAD(&tp->tx_free);
|
||||
INIT_LIST_HEAD(&tp->rx_done);
|
||||
skb_queue_head_init(&tp->tx_queue);
|
||||
skb_queue_head_init(&tp->rx_queue);
|
||||
|
||||
@@ -2252,8 +2256,7 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)
|
||||
|
||||
static void r8153_set_rx_early_size(struct r8152 *tp)
|
||||
{
|
||||
u32 mtu = tp->netdev->mtu;
|
||||
u32 ocp_data = (agg_buf_sz - mtu - VLAN_ETH_HLEN - VLAN_HLEN) / 8;
|
||||
u32 ocp_data = (agg_buf_sz - rx_reserved_size(tp->netdev->mtu)) / 4;
|
||||
|
||||
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data);
|
||||
}
|
||||
@@ -3165,6 +3168,9 @@ static void set_carrier(struct r8152 *tp)
|
||||
napi_enable(&tp->napi);
|
||||
netif_wake_queue(netdev);
|
||||
netif_info(tp, link, netdev, "carrier on\n");
|
||||
} else if (netif_queue_stopped(netdev) &&
|
||||
skb_queue_len(&tp->tx_queue) < tp->tx_qlen) {
|
||||
netif_wake_queue(netdev);
|
||||
}
|
||||
} else {
|
||||
if (netif_carrier_ok(netdev)) {
|
||||
@@ -3698,8 +3704,18 @@ static int rtl8152_resume(struct usb_interface *intf)
|
||||
tp->rtl_ops.autosuspend_en(tp, false);
|
||||
napi_disable(&tp->napi);
|
||||
set_bit(WORK_ENABLE, &tp->flags);
|
||||
if (netif_carrier_ok(tp->netdev))
|
||||
rtl_start_rx(tp);
|
||||
|
||||
if (netif_carrier_ok(tp->netdev)) {
|
||||
if (rtl8152_get_speed(tp) & LINK_STATUS) {
|
||||
rtl_start_rx(tp);
|
||||
} else {
|
||||
netif_carrier_off(tp->netdev);
|
||||
tp->rtl_ops.disable(tp);
|
||||
netif_info(tp, link, tp->netdev,
|
||||
"linking down\n");
|
||||
}
|
||||
}
|
||||
|
||||
napi_enable(&tp->napi);
|
||||
clear_bit(SELECTIVE_SUSPEND, &tp->flags);
|
||||
smp_mb__after_atomic();
|
||||
|
||||
+50
-38
@@ -223,8 +223,6 @@ static void nvme_loop_submit_async_event(struct nvme_ctrl *arg, int aer_idx)
|
||||
static int nvme_loop_init_iod(struct nvme_loop_ctrl *ctrl,
|
||||
struct nvme_loop_iod *iod, unsigned int queue_idx)
|
||||
{
|
||||
BUG_ON(queue_idx >= ctrl->queue_count);
|
||||
|
||||
iod->req.cmd = &iod->cmd;
|
||||
iod->req.rsp = &iod->rsp;
|
||||
iod->queue = &ctrl->queues[queue_idx];
|
||||
@@ -314,6 +312,43 @@ free_ctrl:
|
||||
kfree(ctrl);
|
||||
}
|
||||
|
||||
static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < ctrl->queue_count; i++)
|
||||
nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
|
||||
}
|
||||
|
||||
static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl)
|
||||
{
|
||||
struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
|
||||
unsigned int nr_io_queues;
|
||||
int ret, i;
|
||||
|
||||
nr_io_queues = min(opts->nr_io_queues, num_online_cpus());
|
||||
ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
|
||||
if (ret || !nr_io_queues)
|
||||
return ret;
|
||||
|
||||
dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n", nr_io_queues);
|
||||
|
||||
for (i = 1; i <= nr_io_queues; i++) {
|
||||
ctrl->queues[i].ctrl = ctrl;
|
||||
ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
|
||||
if (ret)
|
||||
goto out_destroy_queues;
|
||||
|
||||
ctrl->queue_count++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_destroy_queues:
|
||||
nvme_loop_destroy_io_queues(ctrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
|
||||
{
|
||||
int error;
|
||||
@@ -385,17 +420,13 @@ out_free_sq:
|
||||
|
||||
static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl)
|
||||
{
|
||||
int i;
|
||||
|
||||
nvme_stop_keep_alive(&ctrl->ctrl);
|
||||
|
||||
if (ctrl->queue_count > 1) {
|
||||
nvme_stop_queues(&ctrl->ctrl);
|
||||
blk_mq_tagset_busy_iter(&ctrl->tag_set,
|
||||
nvme_cancel_request, &ctrl->ctrl);
|
||||
|
||||
for (i = 1; i < ctrl->queue_count; i++)
|
||||
nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
|
||||
nvme_loop_destroy_io_queues(ctrl);
|
||||
}
|
||||
|
||||
if (ctrl->ctrl.state == NVME_CTRL_LIVE)
|
||||
@@ -467,19 +498,14 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
|
||||
if (ret)
|
||||
goto out_disable;
|
||||
|
||||
for (i = 1; i <= ctrl->ctrl.opts->nr_io_queues; i++) {
|
||||
ctrl->queues[i].ctrl = ctrl;
|
||||
ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
|
||||
if (ret)
|
||||
goto out_free_queues;
|
||||
ret = nvme_loop_init_io_queues(ctrl);
|
||||
if (ret)
|
||||
goto out_destroy_admin;
|
||||
|
||||
ctrl->queue_count++;
|
||||
}
|
||||
|
||||
for (i = 1; i <= ctrl->ctrl.opts->nr_io_queues; i++) {
|
||||
for (i = 1; i < ctrl->queue_count; i++) {
|
||||
ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
|
||||
if (ret)
|
||||
goto out_free_queues;
|
||||
goto out_destroy_io;
|
||||
}
|
||||
|
||||
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
|
||||
@@ -492,9 +518,9 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work)
|
||||
|
||||
return;
|
||||
|
||||
out_free_queues:
|
||||
for (i = 1; i < ctrl->queue_count; i++)
|
||||
nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
|
||||
out_destroy_io:
|
||||
nvme_loop_destroy_io_queues(ctrl);
|
||||
out_destroy_admin:
|
||||
nvme_loop_destroy_admin_queue(ctrl);
|
||||
out_disable:
|
||||
dev_warn(ctrl->ctrl.device, "Removing after reset failure\n");
|
||||
@@ -533,25 +559,12 @@ static const struct nvme_ctrl_ops nvme_loop_ctrl_ops = {
|
||||
|
||||
static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
|
||||
{
|
||||
struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
|
||||
int ret, i;
|
||||
|
||||
ret = nvme_set_queue_count(&ctrl->ctrl, &opts->nr_io_queues);
|
||||
if (ret || !opts->nr_io_queues)
|
||||
ret = nvme_loop_init_io_queues(ctrl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n",
|
||||
opts->nr_io_queues);
|
||||
|
||||
for (i = 1; i <= opts->nr_io_queues; i++) {
|
||||
ctrl->queues[i].ctrl = ctrl;
|
||||
ret = nvmet_sq_init(&ctrl->queues[i].nvme_sq);
|
||||
if (ret)
|
||||
goto out_destroy_queues;
|
||||
|
||||
ctrl->queue_count++;
|
||||
}
|
||||
|
||||
memset(&ctrl->tag_set, 0, sizeof(ctrl->tag_set));
|
||||
ctrl->tag_set.ops = &nvme_loop_mq_ops;
|
||||
ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size;
|
||||
@@ -575,7 +588,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
|
||||
goto out_free_tagset;
|
||||
}
|
||||
|
||||
for (i = 1; i <= opts->nr_io_queues; i++) {
|
||||
for (i = 1; i < ctrl->queue_count; i++) {
|
||||
ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
|
||||
if (ret)
|
||||
goto out_cleanup_connect_q;
|
||||
@@ -588,8 +601,7 @@ out_cleanup_connect_q:
|
||||
out_free_tagset:
|
||||
blk_mq_free_tag_set(&ctrl->tag_set);
|
||||
out_destroy_queues:
|
||||
for (i = 1; i < ctrl->queue_count; i++)
|
||||
nvmet_sq_destroy(&ctrl->queues[i].nvme_sq);
|
||||
nvme_loop_destroy_io_queues(ctrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -164,7 +164,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
|
||||
pci_device_add(virtfn, virtfn->bus);
|
||||
mutex_unlock(&iov->dev->sriov->lock);
|
||||
|
||||
pci_bus_add_device(virtfn);
|
||||
sprintf(buf, "virtfn%u", id);
|
||||
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
|
||||
if (rc)
|
||||
@@ -175,6 +174,8 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset)
|
||||
|
||||
kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
|
||||
|
||||
pci_bus_add_device(virtfn);
|
||||
|
||||
return 0;
|
||||
|
||||
failed2:
|
||||
|
||||
@@ -4214,6 +4214,10 @@ static bool pci_bus_resetable(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
|
||||
if (bus->self && (bus->self->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET))
|
||||
return false;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
|
||||
(dev->subordinate && !pci_bus_resetable(dev->subordinate)))
|
||||
|
||||
@@ -390,7 +390,14 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
|
||||
* If the error is reported by an end point, we think this
|
||||
* error is related to the upstream link of the end point.
|
||||
*/
|
||||
pci_walk_bus(dev->bus, cb, &result_data);
|
||||
if (state == pci_channel_io_normal)
|
||||
/*
|
||||
* the error is non fatal so the bus is ok, just invoke
|
||||
* the callback for the function that logged the error.
|
||||
*/
|
||||
cb(dev, &result_data);
|
||||
else
|
||||
pci_walk_bus(dev->bus, cb, &result_data);
|
||||
}
|
||||
|
||||
return result_data.result;
|
||||
|
||||
@@ -1285,6 +1285,22 @@ static void st_gpio_irq_unmask(struct irq_data *d)
|
||||
writel(BIT(d->hwirq), bank->base + REG_PIO_SET_PMASK);
|
||||
}
|
||||
|
||||
static int st_gpio_irq_request_resources(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
st_gpio_direction_input(gc, d->hwirq);
|
||||
|
||||
return gpiochip_lock_as_irq(gc, d->hwirq);
|
||||
}
|
||||
|
||||
static void st_gpio_irq_release_resources(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
|
||||
gpiochip_unlock_as_irq(gc, d->hwirq);
|
||||
}
|
||||
|
||||
static int st_gpio_irq_set_type(struct irq_data *d, unsigned type)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
@@ -1438,12 +1454,14 @@ static struct gpio_chip st_gpio_template = {
|
||||
};
|
||||
|
||||
static struct irq_chip st_gpio_irqchip = {
|
||||
.name = "GPIO",
|
||||
.irq_disable = st_gpio_irq_mask,
|
||||
.irq_mask = st_gpio_irq_mask,
|
||||
.irq_unmask = st_gpio_irq_unmask,
|
||||
.irq_set_type = st_gpio_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
.name = "GPIO",
|
||||
.irq_request_resources = st_gpio_irq_request_resources,
|
||||
.irq_release_resources = st_gpio_irq_release_resources,
|
||||
.irq_disable = st_gpio_irq_mask,
|
||||
.irq_mask = st_gpio_irq_mask,
|
||||
.irq_unmask = st_gpio_irq_unmask,
|
||||
.irq_set_type = st_gpio_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int st_gpiolib_register_bank(struct st_pinctrl *info,
|
||||
|
||||
@@ -97,6 +97,7 @@ static void asus_wireless_notify(struct acpi_device *adev, u32 event)
|
||||
return;
|
||||
}
|
||||
input_report_key(data->idev, KEY_RFKILL, 1);
|
||||
input_sync(data->idev);
|
||||
input_report_key(data->idev, KEY_RFKILL, 0);
|
||||
input_sync(data->idev);
|
||||
}
|
||||
|
||||
@@ -772,7 +772,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
|
||||
}
|
||||
|
||||
timerqueue_add(&rtc->timerqueue, &timer->node);
|
||||
if (!next) {
|
||||
if (!next || ktime_before(timer->node.expires, next->expires)) {
|
||||
struct rtc_wkalrm alarm;
|
||||
int err;
|
||||
alarm.time = rtc_ktime_to_tm(timer->node.expires);
|
||||
|
||||
@@ -308,7 +308,8 @@ static int pl031_remove(struct amba_device *adev)
|
||||
|
||||
dev_pm_clear_wake_irq(&adev->dev);
|
||||
device_init_wakeup(&adev->dev, false);
|
||||
free_irq(adev->irq[0], ldata);
|
||||
if (adev->irq[0])
|
||||
free_irq(adev->irq[0], ldata);
|
||||
rtc_device_unregister(ldata->rtc);
|
||||
iounmap(ldata->base);
|
||||
kfree(ldata);
|
||||
@@ -381,12 +382,13 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
goto out_no_rtc;
|
||||
}
|
||||
|
||||
if (request_irq(adev->irq[0], pl031_interrupt,
|
||||
vendor->irqflags, "rtc-pl031", ldata)) {
|
||||
ret = -EIO;
|
||||
goto out_no_irq;
|
||||
if (adev->irq[0]) {
|
||||
ret = request_irq(adev->irq[0], pl031_interrupt,
|
||||
vendor->irqflags, "rtc-pl031", ldata);
|
||||
if (ret)
|
||||
goto out_no_irq;
|
||||
dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
|
||||
}
|
||||
dev_pm_set_wake_irq(&adev->dev, adev->irq[0]);
|
||||
return 0;
|
||||
|
||||
out_no_irq:
|
||||
|
||||
@@ -969,7 +969,8 @@ int qeth_bridgeport_query_ports(struct qeth_card *card,
|
||||
int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role);
|
||||
int qeth_bridgeport_an_set(struct qeth_card *card, int enable);
|
||||
int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
|
||||
int qeth_get_elements_no(struct qeth_card *, struct sk_buff *, int);
|
||||
int qeth_get_elements_no(struct qeth_card *card, struct sk_buff *skb,
|
||||
int extra_elems, int data_offset);
|
||||
int qeth_get_elements_for_frags(struct sk_buff *);
|
||||
int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
|
||||
struct sk_buff *, struct qeth_hdr *, int, int, int);
|
||||
|
||||
@@ -3842,6 +3842,7 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
|
||||
* @card: qeth card structure, to check max. elems.
|
||||
* @skb: SKB address
|
||||
* @extra_elems: extra elems needed, to check against max.
|
||||
* @data_offset: range starts at skb->data + data_offset
|
||||
*
|
||||
* Returns the number of pages, and thus QDIO buffer elements, needed to cover
|
||||
* skb data, including linear part and fragments. Checks if the result plus
|
||||
@@ -3849,10 +3850,10 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
|
||||
* Note: extra_elems is not included in the returned result.
|
||||
*/
|
||||
int qeth_get_elements_no(struct qeth_card *card,
|
||||
struct sk_buff *skb, int extra_elems)
|
||||
struct sk_buff *skb, int extra_elems, int data_offset)
|
||||
{
|
||||
int elements = qeth_get_elements_for_range(
|
||||
(addr_t)skb->data,
|
||||
(addr_t)skb->data + data_offset,
|
||||
(addr_t)skb->data + skb_headlen(skb)) +
|
||||
qeth_get_elements_for_frags(skb);
|
||||
|
||||
|
||||
@@ -865,7 +865,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
* chaining we can not send long frag lists
|
||||
*/
|
||||
if ((card->info.type != QETH_CARD_TYPE_IQD) &&
|
||||
!qeth_get_elements_no(card, new_skb, 0)) {
|
||||
!qeth_get_elements_no(card, new_skb, 0, 0)) {
|
||||
int lin_rc = skb_linearize(new_skb);
|
||||
|
||||
if (card->options.performance_stats) {
|
||||
@@ -910,7 +910,8 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
elements = qeth_get_elements_no(card, new_skb, elements_needed);
|
||||
elements = qeth_get_elements_no(card, new_skb, elements_needed,
|
||||
(data_offset > 0) ? data_offset : 0);
|
||||
if (!elements) {
|
||||
if (data_offset >= 0)
|
||||
kmem_cache_free(qeth_core_header_cache, hdr);
|
||||
|
||||
@@ -2612,17 +2612,13 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,
|
||||
char daddr[16];
|
||||
struct af_iucv_trans_hdr *iucv_hdr;
|
||||
|
||||
skb_pull(skb, 14);
|
||||
card->dev->header_ops->create(skb, card->dev, 0,
|
||||
card->dev->dev_addr, card->dev->dev_addr,
|
||||
card->dev->addr_len);
|
||||
skb_pull(skb, 14);
|
||||
iucv_hdr = (struct af_iucv_trans_hdr *)skb->data;
|
||||
memset(hdr, 0, sizeof(struct qeth_hdr));
|
||||
hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
|
||||
hdr->hdr.l3.ext_flags = 0;
|
||||
hdr->hdr.l3.length = skb->len;
|
||||
hdr->hdr.l3.length = skb->len - ETH_HLEN;
|
||||
hdr->hdr.l3.flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
|
||||
|
||||
iucv_hdr = (struct af_iucv_trans_hdr *) (skb->data + ETH_HLEN);
|
||||
memset(daddr, 0, sizeof(daddr));
|
||||
daddr[0] = 0xfe;
|
||||
daddr[1] = 0x80;
|
||||
@@ -2826,10 +2822,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
if ((card->info.type == QETH_CARD_TYPE_IQD) &&
|
||||
!skb_is_nonlinear(skb)) {
|
||||
new_skb = skb;
|
||||
if (new_skb->protocol == ETH_P_AF_IUCV)
|
||||
data_offset = 0;
|
||||
else
|
||||
data_offset = ETH_HLEN;
|
||||
data_offset = ETH_HLEN;
|
||||
hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
|
||||
if (!hdr)
|
||||
goto tx_drop;
|
||||
@@ -2870,7 +2863,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
*/
|
||||
if ((card->info.type != QETH_CARD_TYPE_IQD) &&
|
||||
((use_tso && !qeth_l3_get_elements_no_tso(card, new_skb, 1)) ||
|
||||
(!use_tso && !qeth_get_elements_no(card, new_skb, 0)))) {
|
||||
(!use_tso && !qeth_get_elements_no(card, new_skb, 0, 0)))) {
|
||||
int lin_rc = skb_linearize(new_skb);
|
||||
|
||||
if (card->options.performance_stats) {
|
||||
@@ -2912,7 +2905,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
elements = use_tso ?
|
||||
qeth_l3_get_elements_no_tso(card, new_skb, hdr_elements) :
|
||||
qeth_get_elements_no(card, new_skb, hdr_elements);
|
||||
qeth_get_elements_no(card, new_skb, hdr_elements,
|
||||
(data_offset > 0) ? data_offset : 0);
|
||||
if (!elements) {
|
||||
if (data_offset >= 0)
|
||||
kmem_cache_free(qeth_core_header_cache, hdr);
|
||||
|
||||
@@ -1347,6 +1347,7 @@ static void release_offload_resources(struct cxgbi_sock *csk)
|
||||
csk, csk->state, csk->flags, csk->tid);
|
||||
|
||||
cxgbi_sock_free_cpl_skbs(csk);
|
||||
cxgbi_sock_purge_write_queue(csk);
|
||||
if (csk->wr_cred != csk->wr_max_cred) {
|
||||
cxgbi_sock_purge_wr_queue(csk);
|
||||
cxgbi_sock_reset_wr_list(csk);
|
||||
|
||||
@@ -7782,7 +7782,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||
did, vport->port_state, ndlp->nlp_flag);
|
||||
|
||||
phba->fc_stat.elsRcvPRLI++;
|
||||
if (vport->port_state < LPFC_DISC_AUTH) {
|
||||
if ((vport->port_state < LPFC_DISC_AUTH) &&
|
||||
(vport->fc_flag & FC_FABRIC)) {
|
||||
rjt_err = LSRJT_UNABLE_TPC;
|
||||
rjt_exp = LSEXP_NOTHING_MORE;
|
||||
break;
|
||||
|
||||
@@ -4784,7 +4784,8 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||
lpfc_cancel_retry_delay_tmo(vport, ndlp);
|
||||
if ((ndlp->nlp_flag & NLP_DEFER_RM) &&
|
||||
!(ndlp->nlp_flag & NLP_REG_LOGIN_SEND) &&
|
||||
!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
|
||||
!(ndlp->nlp_flag & NLP_RPI_REGISTERED) &&
|
||||
phba->sli_rev != LPFC_SLI_REV4) {
|
||||
/* For this case we need to cleanup the default rpi
|
||||
* allocated by the firmware.
|
||||
*/
|
||||
|
||||
@@ -3232,7 +3232,7 @@ struct lpfc_mbx_get_port_name {
|
||||
#define MB_CEQ_STATUS_QUEUE_FLUSHING 0x4
|
||||
#define MB_CQE_STATUS_DMA_FAILED 0x5
|
||||
|
||||
#define LPFC_MBX_WR_CONFIG_MAX_BDE 8
|
||||
#define LPFC_MBX_WR_CONFIG_MAX_BDE 1
|
||||
struct lpfc_mbx_wr_object {
|
||||
struct mbox_header header;
|
||||
union {
|
||||
|
||||
@@ -4770,6 +4770,11 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
|
||||
} else if (log_info == VIRTUAL_IO_FAILED_RETRY) {
|
||||
scmd->result = DID_RESET << 16;
|
||||
break;
|
||||
} else if ((scmd->device->channel == RAID_CHANNEL) &&
|
||||
(scsi_state == (MPI2_SCSI_STATE_TERMINATED |
|
||||
MPI2_SCSI_STATE_NO_SCSI_STATUS))) {
|
||||
scmd->result = DID_RESET << 16;
|
||||
break;
|
||||
}
|
||||
scmd->result = DID_SOFT_ERROR << 16;
|
||||
break;
|
||||
|
||||
@@ -924,6 +924,8 @@ static void __gb_lights_led_unregister(struct gb_channel *channel)
|
||||
return;
|
||||
|
||||
led_classdev_unregister(cdev);
|
||||
kfree(cdev->name);
|
||||
cdev->name = NULL;
|
||||
channel->led = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
#define TEMP0_RST_MSK (0x1C)
|
||||
#define TEMP0_VALUE (0x28)
|
||||
|
||||
#define HISI_TEMP_BASE (-60)
|
||||
#define HISI_TEMP_BASE (-60000)
|
||||
#define HISI_TEMP_RESET (100000)
|
||||
#define HISI_TEMP_STEP (784)
|
||||
|
||||
#define HISI_MAX_SENSORS 4
|
||||
|
||||
@@ -61,19 +62,38 @@ struct hisi_thermal_data {
|
||||
void __iomem *regs;
|
||||
};
|
||||
|
||||
/* in millicelsius */
|
||||
static inline int _step_to_temp(int step)
|
||||
/*
|
||||
* The temperature computation on the tsensor is as follow:
|
||||
* Unit: millidegree Celsius
|
||||
* Step: 255/200 (0.7843)
|
||||
* Temperature base: -60°C
|
||||
*
|
||||
* The register is programmed in temperature steps, every step is 784
|
||||
* millidegree and begins at -60 000 m°C
|
||||
*
|
||||
* The temperature from the steps:
|
||||
*
|
||||
* Temp = TempBase + (steps x 784)
|
||||
*
|
||||
* and the steps from the temperature:
|
||||
*
|
||||
* steps = (Temp - TempBase) / 784
|
||||
*
|
||||
*/
|
||||
static inline int hisi_thermal_step_to_temp(int step)
|
||||
{
|
||||
/*
|
||||
* Every step equals (1 * 200) / 255 celsius, and finally
|
||||
* need convert to millicelsius.
|
||||
*/
|
||||
return (HISI_TEMP_BASE * 1000 + (step * 200000 / 255));
|
||||
return HISI_TEMP_BASE + (step * HISI_TEMP_STEP);
|
||||
}
|
||||
|
||||
static inline long _temp_to_step(long temp)
|
||||
static inline long hisi_thermal_temp_to_step(long temp)
|
||||
{
|
||||
return ((temp - HISI_TEMP_BASE * 1000) * 255) / 200000;
|
||||
return (temp - HISI_TEMP_BASE) / HISI_TEMP_STEP;
|
||||
}
|
||||
|
||||
static inline long hisi_thermal_round_temp(int temp)
|
||||
{
|
||||
return hisi_thermal_step_to_temp(
|
||||
hisi_thermal_temp_to_step(temp));
|
||||
}
|
||||
|
||||
static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data,
|
||||
@@ -99,7 +119,7 @@ static long hisi_thermal_get_sensor_temp(struct hisi_thermal_data *data,
|
||||
usleep_range(3000, 5000);
|
||||
|
||||
val = readl(data->regs + TEMP0_VALUE);
|
||||
val = _step_to_temp(val);
|
||||
val = hisi_thermal_step_to_temp(val);
|
||||
|
||||
mutex_unlock(&data->thermal_lock);
|
||||
|
||||
@@ -126,10 +146,11 @@ static void hisi_thermal_enable_bind_irq_sensor
|
||||
writel((sensor->id << 12), data->regs + TEMP0_CFG);
|
||||
|
||||
/* enable for interrupt */
|
||||
writel(_temp_to_step(sensor->thres_temp) | 0x0FFFFFF00,
|
||||
writel(hisi_thermal_temp_to_step(sensor->thres_temp) | 0x0FFFFFF00,
|
||||
data->regs + TEMP0_TH);
|
||||
|
||||
writel(_temp_to_step(HISI_TEMP_RESET), data->regs + TEMP0_RST_TH);
|
||||
writel(hisi_thermal_temp_to_step(HISI_TEMP_RESET),
|
||||
data->regs + TEMP0_RST_TH);
|
||||
|
||||
/* enable module */
|
||||
writel(0x1, data->regs + TEMP0_RST_MSK);
|
||||
@@ -230,7 +251,7 @@ static irqreturn_t hisi_thermal_alarm_irq_thread(int irq, void *dev)
|
||||
sensor = &data->sensors[data->irq_bind_sensor];
|
||||
|
||||
dev_crit(&data->pdev->dev, "THERMAL ALARM: T > %d\n",
|
||||
sensor->thres_temp / 1000);
|
||||
sensor->thres_temp);
|
||||
mutex_unlock(&data->thermal_lock);
|
||||
|
||||
for (i = 0; i < HISI_MAX_SENSORS; i++) {
|
||||
@@ -269,7 +290,7 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev,
|
||||
|
||||
for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) {
|
||||
if (trip[i].type == THERMAL_TRIP_PASSIVE) {
|
||||
sensor->thres_temp = trip[i].temperature;
|
||||
sensor->thres_temp = hisi_thermal_round_temp(trip[i].temperature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -317,15 +338,6 @@ static int hisi_thermal_probe(struct platform_device *pdev)
|
||||
if (data->irq < 0)
|
||||
return data->irq;
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, data->irq,
|
||||
hisi_thermal_alarm_irq,
|
||||
hisi_thermal_alarm_irq_thread,
|
||||
0, "hisi_thermal", data);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
data->clk = devm_clk_get(&pdev->dev, "thermal_clk");
|
||||
@@ -345,8 +357,7 @@ static int hisi_thermal_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
hisi_thermal_enable_bind_irq_sensor(data);
|
||||
irq_get_irqchip_state(data->irq, IRQCHIP_STATE_MASKED,
|
||||
&data->irq_enabled);
|
||||
data->irq_enabled = true;
|
||||
|
||||
for (i = 0; i < HISI_MAX_SENSORS; ++i) {
|
||||
ret = hisi_thermal_register_sensor(pdev, data,
|
||||
@@ -358,6 +369,17 @@ static int hisi_thermal_probe(struct platform_device *pdev)
|
||||
hisi_thermal_toggle_sensor(&data->sensors[i], true);
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, data->irq,
|
||||
hisi_thermal_alarm_irq,
|
||||
hisi_thermal_alarm_irq_thread,
|
||||
0, "hisi_thermal", data);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to request alarm irq: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
enable_irq(data->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -397,8 +419,11 @@ static int hisi_thermal_suspend(struct device *dev)
|
||||
static int hisi_thermal_resume(struct device *dev)
|
||||
{
|
||||
struct hisi_thermal_data *data = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(data->clk);
|
||||
ret = clk_prepare_enable(data->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data->irq_enabled = true;
|
||||
hisi_thermal_enable_bind_irq_sensor(data);
|
||||
|
||||
@@ -594,6 +594,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
|
||||
opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
|
||||
|
||||
/* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
|
||||
if (opts->streaming_maxburst &&
|
||||
(opts->streaming_maxpacket % 1024) != 0) {
|
||||
opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
|
||||
INFO(cdev, "overriding streaming_maxpacket to %d\n",
|
||||
opts->streaming_maxpacket);
|
||||
}
|
||||
|
||||
/* Fill in the FS/HS/SS Video Streaming specific descriptors from the
|
||||
* module parameters.
|
||||
*
|
||||
|
||||
@@ -1523,7 +1523,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev,
|
||||
td = phys_to_virt(addr);
|
||||
addr2 = (dma_addr_t)td->next;
|
||||
pci_pool_free(dev->data_requests, td, addr);
|
||||
td->next = 0x00;
|
||||
addr = addr2;
|
||||
}
|
||||
req->chain_len = 1;
|
||||
|
||||
@@ -335,6 +335,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
|
||||
static struct platform_driver usb_xhci_driver = {
|
||||
.probe = xhci_plat_probe,
|
||||
.remove = xhci_plat_remove,
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "xhci-hcd",
|
||||
.pm = DEV_PM_OPS,
|
||||
|
||||
@@ -851,11 +851,13 @@ static int __init init_pci_cap_exp_perm(struct perm_bits *perm)
|
||||
|
||||
/*
|
||||
* Allow writes to device control fields, except devctl_phantom,
|
||||
* which could confuse IOMMU, and the ARI bit in devctl2, which
|
||||
* which could confuse IOMMU, MPS, which can break communication
|
||||
* with other physical devices, and the ARI bit in devctl2, which
|
||||
* is set at probe time. FLR gets virtualized via our writefn.
|
||||
*/
|
||||
p_setw(perm, PCI_EXP_DEVCTL,
|
||||
PCI_EXP_DEVCTL_BCR_FLR, ~PCI_EXP_DEVCTL_PHANTOM);
|
||||
PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_PAYLOAD,
|
||||
~PCI_EXP_DEVCTL_PHANTOM);
|
||||
p_setw(perm, PCI_EXP_DEVCTL2, NO_VIRT, ~PCI_EXP_DEVCTL2_ARI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -218,6 +218,46 @@ vhost_transport_send_pkt(struct virtio_vsock_pkt *pkt)
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
vhost_transport_cancel_pkt(struct vsock_sock *vsk)
|
||||
{
|
||||
struct vhost_vsock *vsock;
|
||||
struct virtio_vsock_pkt *pkt, *n;
|
||||
int cnt = 0;
|
||||
LIST_HEAD(freeme);
|
||||
|
||||
/* Find the vhost_vsock according to guest context id */
|
||||
vsock = vhost_vsock_get(vsk->remote_addr.svm_cid);
|
||||
if (!vsock)
|
||||
return -ENODEV;
|
||||
|
||||
spin_lock_bh(&vsock->send_pkt_list_lock);
|
||||
list_for_each_entry_safe(pkt, n, &vsock->send_pkt_list, list) {
|
||||
if (pkt->vsk != vsk)
|
||||
continue;
|
||||
list_move(&pkt->list, &freeme);
|
||||
}
|
||||
spin_unlock_bh(&vsock->send_pkt_list_lock);
|
||||
|
||||
list_for_each_entry_safe(pkt, n, &freeme, list) {
|
||||
if (pkt->reply)
|
||||
cnt++;
|
||||
list_del(&pkt->list);
|
||||
virtio_transport_free_pkt(pkt);
|
||||
}
|
||||
|
||||
if (cnt) {
|
||||
struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX];
|
||||
int new_cnt;
|
||||
|
||||
new_cnt = atomic_sub_return(cnt, &vsock->queued_replies);
|
||||
if (new_cnt + cnt >= tx_vq->num && new_cnt < tx_vq->num)
|
||||
vhost_poll_queue(&tx_vq->poll);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct virtio_vsock_pkt *
|
||||
vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,
|
||||
unsigned int out, unsigned int in)
|
||||
@@ -669,6 +709,7 @@ static struct virtio_transport vhost_transport = {
|
||||
.release = virtio_transport_release,
|
||||
.connect = virtio_transport_connect,
|
||||
.shutdown = virtio_transport_shutdown,
|
||||
.cancel_pkt = vhost_transport_cancel_pkt,
|
||||
|
||||
.dgram_enqueue = virtio_transport_dgram_enqueue,
|
||||
.dgram_dequeue = virtio_transport_dgram_dequeue,
|
||||
|
||||
@@ -79,14 +79,17 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
|
||||
static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
|
||||
{
|
||||
unsigned int lth = pb->lth_brightness;
|
||||
int duty_cycle;
|
||||
u64 duty_cycle;
|
||||
|
||||
if (pb->levels)
|
||||
duty_cycle = pb->levels[brightness];
|
||||
else
|
||||
duty_cycle = brightness;
|
||||
|
||||
return (duty_cycle * (pb->period - lth) / pb->scale) + lth;
|
||||
duty_cycle *= pb->period - lth;
|
||||
do_div(duty_cycle, pb->scale);
|
||||
|
||||
return duty_cycle + lth;
|
||||
}
|
||||
|
||||
static int pwm_backlight_update_status(struct backlight_device *bl)
|
||||
|
||||
@@ -241,11 +241,11 @@ static inline void update_stat(struct virtio_balloon *vb, int idx,
|
||||
|
||||
#define pages_to_bytes(x) ((u64)(x) << PAGE_SHIFT)
|
||||
|
||||
static void update_balloon_stats(struct virtio_balloon *vb)
|
||||
static unsigned int update_balloon_stats(struct virtio_balloon *vb)
|
||||
{
|
||||
unsigned long events[NR_VM_EVENT_ITEMS];
|
||||
struct sysinfo i;
|
||||
int idx = 0;
|
||||
unsigned int idx = 0;
|
||||
long available;
|
||||
|
||||
all_vm_events(events);
|
||||
@@ -253,18 +253,22 @@ static void update_balloon_stats(struct virtio_balloon *vb)
|
||||
|
||||
available = si_mem_available();
|
||||
|
||||
#ifdef CONFIG_VM_EVENT_COUNTERS
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
|
||||
pages_to_bytes(events[PSWPIN]));
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT,
|
||||
pages_to_bytes(events[PSWPOUT]));
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]);
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]);
|
||||
#endif
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE,
|
||||
pages_to_bytes(i.freeram));
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT,
|
||||
pages_to_bytes(i.totalram));
|
||||
update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL,
|
||||
pages_to_bytes(available));
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -290,14 +294,14 @@ static void stats_handle_request(struct virtio_balloon *vb)
|
||||
{
|
||||
struct virtqueue *vq;
|
||||
struct scatterlist sg;
|
||||
unsigned int len;
|
||||
unsigned int len, num_stats;
|
||||
|
||||
update_balloon_stats(vb);
|
||||
num_stats = update_balloon_stats(vb);
|
||||
|
||||
vq = vb->stats_vq;
|
||||
if (!virtqueue_get_buf(vq, &len))
|
||||
return;
|
||||
sg_init_one(&sg, vb->stats, sizeof(vb->stats));
|
||||
sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
|
||||
virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
|
||||
virtqueue_kick(vq);
|
||||
}
|
||||
@@ -421,15 +425,16 @@ static int init_vqs(struct virtio_balloon *vb)
|
||||
vb->deflate_vq = vqs[1];
|
||||
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
|
||||
struct scatterlist sg;
|
||||
unsigned int num_stats;
|
||||
vb->stats_vq = vqs[2];
|
||||
|
||||
/*
|
||||
* Prime this virtqueue with one buffer so the hypervisor can
|
||||
* use it to signal us later (it can't be broken yet!).
|
||||
*/
|
||||
update_balloon_stats(vb);
|
||||
num_stats = update_balloon_stats(vb);
|
||||
|
||||
sg_init_one(&sg, vb->stats, sizeof vb->stats);
|
||||
sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
|
||||
if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
|
||||
< 0)
|
||||
BUG();
|
||||
|
||||
+6
-1
@@ -6196,8 +6196,13 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that we don't overflow at later allocations, we request
|
||||
* clone_sources_count + 1 items, and compare to unsigned long inside
|
||||
* access_ok.
|
||||
*/
|
||||
if (arg->clone_sources_count >
|
||||
ULLONG_MAX / sizeof(*arg->clone_sources)) {
|
||||
ULONG_MAX / sizeof(struct clone_root) - 1) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ struct bpf_verifier_state_list {
|
||||
|
||||
struct bpf_insn_aux_data {
|
||||
enum bpf_reg_type ptr_type; /* pointer type for load/store insns */
|
||||
bool seen; /* this insn was processed by the verifier */
|
||||
};
|
||||
|
||||
#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
|
||||
|
||||
@@ -48,6 +48,8 @@ struct virtio_vsock_pkt {
|
||||
struct virtio_vsock_hdr hdr;
|
||||
struct work_struct work;
|
||||
struct list_head list;
|
||||
/* socket refcnt not held, only use for cancellation */
|
||||
struct vsock_sock *vsk;
|
||||
void *buf;
|
||||
u32 len;
|
||||
u32 off;
|
||||
@@ -56,6 +58,7 @@ struct virtio_vsock_pkt {
|
||||
|
||||
struct virtio_vsock_pkt_info {
|
||||
u32 remote_cid, remote_port;
|
||||
struct vsock_sock *vsk;
|
||||
struct msghdr *msg;
|
||||
u32 pkt_len;
|
||||
u16 type;
|
||||
|
||||
@@ -100,6 +100,9 @@ struct vsock_transport {
|
||||
void (*destruct)(struct vsock_sock *);
|
||||
void (*release)(struct vsock_sock *);
|
||||
|
||||
/* Cancel all pending packets sent on vsock. */
|
||||
int (*cancel_pkt)(struct vsock_sock *vsk);
|
||||
|
||||
/* Connections. */
|
||||
int (*connect)(struct vsock_sock *);
|
||||
|
||||
|
||||
+96
-10
@@ -1790,10 +1790,17 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
||||
/* case: R = imm
|
||||
* remember the value we stored into this reg
|
||||
*/
|
||||
u64 imm;
|
||||
|
||||
if (BPF_CLASS(insn->code) == BPF_ALU64)
|
||||
imm = insn->imm;
|
||||
else
|
||||
imm = (u32)insn->imm;
|
||||
|
||||
regs[insn->dst_reg].type = CONST_IMM;
|
||||
regs[insn->dst_reg].imm = insn->imm;
|
||||
regs[insn->dst_reg].max_value = insn->imm;
|
||||
regs[insn->dst_reg].min_value = insn->imm;
|
||||
regs[insn->dst_reg].imm = imm;
|
||||
regs[insn->dst_reg].max_value = imm;
|
||||
regs[insn->dst_reg].min_value = imm;
|
||||
}
|
||||
|
||||
} else if (opcode > BPF_END) {
|
||||
@@ -1861,10 +1868,28 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
||||
((BPF_SRC(insn->code) == BPF_X &&
|
||||
regs[insn->src_reg].type == CONST_IMM) ||
|
||||
BPF_SRC(insn->code) == BPF_K)) {
|
||||
if (BPF_SRC(insn->code) == BPF_X)
|
||||
if (BPF_SRC(insn->code) == BPF_X) {
|
||||
/* check in case the register contains a big
|
||||
* 64-bit value
|
||||
*/
|
||||
if (regs[insn->src_reg].imm < -MAX_BPF_STACK ||
|
||||
regs[insn->src_reg].imm > MAX_BPF_STACK) {
|
||||
verbose("R%d value too big in R%d pointer arithmetic\n",
|
||||
insn->src_reg, insn->dst_reg);
|
||||
return -EACCES;
|
||||
}
|
||||
dst_reg->imm += regs[insn->src_reg].imm;
|
||||
else
|
||||
} else {
|
||||
/* safe against overflow: addition of 32-bit
|
||||
* numbers in 64-bit representation
|
||||
*/
|
||||
dst_reg->imm += insn->imm;
|
||||
}
|
||||
if (dst_reg->imm > 0 || dst_reg->imm < -MAX_BPF_STACK) {
|
||||
verbose("R%d out-of-bounds pointer arithmetic\n",
|
||||
insn->dst_reg);
|
||||
return -EACCES;
|
||||
}
|
||||
return 0;
|
||||
} else if (opcode == BPF_ADD &&
|
||||
BPF_CLASS(insn->code) == BPF_ALU64 &&
|
||||
@@ -2862,6 +2887,7 @@ static int do_check(struct bpf_verifier_env *env)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
env->insn_aux_data[insn_idx].seen = true;
|
||||
if (class == BPF_ALU || class == BPF_ALU64) {
|
||||
err = check_alu_op(env, insn);
|
||||
if (err)
|
||||
@@ -3059,6 +3085,7 @@ process_bpf_exit:
|
||||
return err;
|
||||
|
||||
insn_idx++;
|
||||
env->insn_aux_data[insn_idx].seen = true;
|
||||
} else {
|
||||
verbose("invalid BPF_LD mode\n");
|
||||
return -EINVAL;
|
||||
@@ -3210,6 +3237,63 @@ static void convert_pseudo_ld_imm64(struct bpf_verifier_env *env)
|
||||
insn->src_reg = 0;
|
||||
}
|
||||
|
||||
/* single env->prog->insni[off] instruction was replaced with the range
|
||||
* insni[off, off + cnt). Adjust corresponding insn_aux_data by copying
|
||||
* [0, off) and [off, end) to new locations, so the patched range stays zero
|
||||
*/
|
||||
static int adjust_insn_aux_data(struct bpf_verifier_env *env, u32 prog_len,
|
||||
u32 off, u32 cnt)
|
||||
{
|
||||
struct bpf_insn_aux_data *new_data, *old_data = env->insn_aux_data;
|
||||
int i;
|
||||
|
||||
if (cnt == 1)
|
||||
return 0;
|
||||
new_data = vzalloc(sizeof(struct bpf_insn_aux_data) * prog_len);
|
||||
if (!new_data)
|
||||
return -ENOMEM;
|
||||
memcpy(new_data, old_data, sizeof(struct bpf_insn_aux_data) * off);
|
||||
memcpy(new_data + off + cnt - 1, old_data + off,
|
||||
sizeof(struct bpf_insn_aux_data) * (prog_len - off - cnt + 1));
|
||||
for (i = off; i < off + cnt - 1; i++)
|
||||
new_data[i].seen = true;
|
||||
env->insn_aux_data = new_data;
|
||||
vfree(old_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off,
|
||||
const struct bpf_insn *patch, u32 len)
|
||||
{
|
||||
struct bpf_prog *new_prog;
|
||||
|
||||
new_prog = bpf_patch_insn_single(env->prog, off, patch, len);
|
||||
if (!new_prog)
|
||||
return NULL;
|
||||
if (adjust_insn_aux_data(env, new_prog->len, off, len))
|
||||
return NULL;
|
||||
return new_prog;
|
||||
}
|
||||
|
||||
/* The verifier does more data flow analysis than llvm and will not explore
|
||||
* branches that are dead at run time. Malicious programs can have dead code
|
||||
* too. Therefore replace all dead at-run-time code with nops.
|
||||
*/
|
||||
static void sanitize_dead_code(struct bpf_verifier_env *env)
|
||||
{
|
||||
struct bpf_insn_aux_data *aux_data = env->insn_aux_data;
|
||||
struct bpf_insn nop = BPF_MOV64_REG(BPF_REG_0, BPF_REG_0);
|
||||
struct bpf_insn *insn = env->prog->insnsi;
|
||||
const int insn_cnt = env->prog->len;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < insn_cnt; i++) {
|
||||
if (aux_data[i].seen)
|
||||
continue;
|
||||
memcpy(insn + i, &nop, sizeof(nop));
|
||||
}
|
||||
}
|
||||
|
||||
/* convert load instructions that access fields of 'struct __sk_buff'
|
||||
* into sequence of instructions that access fields of 'struct sk_buff'
|
||||
*/
|
||||
@@ -3229,10 +3313,10 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
|
||||
verbose("bpf verifier is misconfigured\n");
|
||||
return -EINVAL;
|
||||
} else if (cnt) {
|
||||
new_prog = bpf_patch_insn_single(env->prog, 0,
|
||||
insn_buf, cnt);
|
||||
new_prog = bpf_patch_insn_data(env, 0, insn_buf, cnt);
|
||||
if (!new_prog)
|
||||
return -ENOMEM;
|
||||
|
||||
env->prog = new_prog;
|
||||
delta += cnt - 1;
|
||||
}
|
||||
@@ -3253,7 +3337,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
|
||||
else
|
||||
continue;
|
||||
|
||||
if (env->insn_aux_data[i].ptr_type != PTR_TO_CTX)
|
||||
if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX)
|
||||
continue;
|
||||
|
||||
cnt = ops->convert_ctx_access(type, insn->dst_reg, insn->src_reg,
|
||||
@@ -3263,8 +3347,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
new_prog = bpf_patch_insn_single(env->prog, i + delta, insn_buf,
|
||||
cnt);
|
||||
new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
|
||||
if (!new_prog)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -3372,6 +3455,9 @@ skip_full_check:
|
||||
while (pop_stack(env, NULL) >= 0);
|
||||
free_states(env);
|
||||
|
||||
if (ret == 0)
|
||||
sanitize_dead_code(env);
|
||||
|
||||
if (ret == 0)
|
||||
/* program is valid, convert *(u32*)(ctx + off) accesses */
|
||||
ret = convert_ctx_accesses(env);
|
||||
|
||||
@@ -449,7 +449,7 @@ static int create_val_field(struct hist_trigger_data *hist_data,
|
||||
}
|
||||
|
||||
field = trace_find_event_field(file->event_call, field_name);
|
||||
if (!field) {
|
||||
if (!field || !field->size) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ static int create_key_field(struct hist_trigger_data *hist_data,
|
||||
}
|
||||
|
||||
field = trace_find_event_field(file->event_call, field_name);
|
||||
if (!field) {
|
||||
if (!field || !field->size) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -369,14 +369,16 @@ static struct ctl_table net_core_table[] = {
|
||||
.data = &sysctl_net_busy_poll,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &zero,
|
||||
},
|
||||
{
|
||||
.procname = "busy_read",
|
||||
.data = &sysctl_net_busy_read,
|
||||
.maxlen = sizeof(unsigned int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &zero,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
|
||||
+17
-8
@@ -198,6 +198,7 @@ static void ip_expire(unsigned long arg)
|
||||
qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
|
||||
net = container_of(qp->q.net, struct net, ipv4.frags);
|
||||
|
||||
rcu_read_lock();
|
||||
spin_lock(&qp->q.lock);
|
||||
|
||||
if (qp->q.flags & INET_FRAG_COMPLETE)
|
||||
@@ -207,7 +208,7 @@ static void ip_expire(unsigned long arg)
|
||||
__IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
|
||||
|
||||
if (!inet_frag_evicting(&qp->q)) {
|
||||
struct sk_buff *head = qp->q.fragments;
|
||||
struct sk_buff *clone, *head = qp->q.fragments;
|
||||
const struct iphdr *iph;
|
||||
int err;
|
||||
|
||||
@@ -216,32 +217,40 @@ static void ip_expire(unsigned long arg)
|
||||
if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !qp->q.fragments)
|
||||
goto out;
|
||||
|
||||
rcu_read_lock();
|
||||
head->dev = dev_get_by_index_rcu(net, qp->iif);
|
||||
if (!head->dev)
|
||||
goto out_rcu_unlock;
|
||||
goto out;
|
||||
|
||||
|
||||
/* skb has no dst, perform route lookup again */
|
||||
iph = ip_hdr(head);
|
||||
err = ip_route_input_noref(head, iph->daddr, iph->saddr,
|
||||
iph->tos, head->dev);
|
||||
if (err)
|
||||
goto out_rcu_unlock;
|
||||
goto out;
|
||||
|
||||
/* Only an end host needs to send an ICMP
|
||||
* "Fragment Reassembly Timeout" message, per RFC792.
|
||||
*/
|
||||
if (frag_expire_skip_icmp(qp->user) &&
|
||||
(skb_rtable(head)->rt_type != RTN_LOCAL))
|
||||
goto out_rcu_unlock;
|
||||
goto out;
|
||||
|
||||
clone = skb_clone(head, GFP_ATOMIC);
|
||||
|
||||
/* Send an ICMP "Fragment Reassembly Timeout" message. */
|
||||
icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
|
||||
out_rcu_unlock:
|
||||
rcu_read_unlock();
|
||||
if (clone) {
|
||||
spin_unlock(&qp->q.lock);
|
||||
icmp_send(clone, ICMP_TIME_EXCEEDED,
|
||||
ICMP_EXC_FRAGTIME, 0);
|
||||
consume_skb(clone);
|
||||
goto out_rcu_unlock;
|
||||
}
|
||||
}
|
||||
out:
|
||||
spin_unlock(&qp->q.lock);
|
||||
out_rcu_unlock:
|
||||
rcu_read_unlock();
|
||||
ipq_put(qp);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -306,7 +306,7 @@ static void __init ic_close_devs(void)
|
||||
while ((d = next)) {
|
||||
next = d->next;
|
||||
dev = d->dev;
|
||||
if ((!ic_dev || dev != ic_dev->dev) && !netdev_uses_dsa(dev)) {
|
||||
if (d != ic_dev && !netdev_uses_dsa(dev)) {
|
||||
pr_debug("IP-Config: Downing %s\n", dev->name);
|
||||
dev_change_flags(dev, d->flags);
|
||||
}
|
||||
|
||||
@@ -1260,16 +1260,6 @@ static const struct nf_conntrack_expect_policy snmp_exp_policy = {
|
||||
.timeout = 180,
|
||||
};
|
||||
|
||||
static struct nf_conntrack_helper snmp_helper __read_mostly = {
|
||||
.me = THIS_MODULE,
|
||||
.help = help,
|
||||
.expect_policy = &snmp_exp_policy,
|
||||
.name = "snmp",
|
||||
.tuple.src.l3num = AF_INET,
|
||||
.tuple.src.u.udp.port = cpu_to_be16(SNMP_PORT),
|
||||
.tuple.dst.protonum = IPPROTO_UDP,
|
||||
};
|
||||
|
||||
static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
|
||||
.me = THIS_MODULE,
|
||||
.help = help,
|
||||
@@ -1288,17 +1278,10 @@ static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
|
||||
|
||||
static int __init nf_nat_snmp_basic_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(nf_nat_snmp_hook != NULL);
|
||||
RCU_INIT_POINTER(nf_nat_snmp_hook, help);
|
||||
|
||||
ret = nf_conntrack_helper_register(&snmp_trap_helper);
|
||||
if (ret < 0) {
|
||||
nf_conntrack_helper_unregister(&snmp_helper);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
return nf_conntrack_helper_register(&snmp_trap_helper);
|
||||
}
|
||||
|
||||
static void __exit nf_nat_snmp_basic_fini(void)
|
||||
|
||||
@@ -158,7 +158,7 @@ EXPORT_SYMBOL_GPL(tcp_vegas_cwnd_event);
|
||||
|
||||
static inline u32 tcp_vegas_ssthresh(struct tcp_sock *tp)
|
||||
{
|
||||
return min(tp->snd_ssthresh, tp->snd_cwnd-1);
|
||||
return min(tp->snd_ssthresh, tp->snd_cwnd);
|
||||
}
|
||||
|
||||
static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 acked)
|
||||
|
||||
+6
-6
@@ -290,10 +290,10 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
|
||||
.keep_addr_on_down = 0,
|
||||
};
|
||||
|
||||
/* Check if a valid qdisc is available */
|
||||
static inline bool addrconf_qdisc_ok(const struct net_device *dev)
|
||||
/* Check if link is ready: is it up and is a valid qdisc available */
|
||||
static inline bool addrconf_link_ready(const struct net_device *dev)
|
||||
{
|
||||
return !qdisc_tx_is_noop(dev);
|
||||
return netif_oper_up(dev) && !qdisc_tx_is_noop(dev);
|
||||
}
|
||||
|
||||
static void addrconf_del_rs_timer(struct inet6_dev *idev)
|
||||
@@ -438,7 +438,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
|
||||
ndev->token = in6addr_any;
|
||||
|
||||
if (netif_running(dev) && addrconf_qdisc_ok(dev))
|
||||
if (netif_running(dev) && addrconf_link_ready(dev))
|
||||
ndev->if_flags |= IF_READY;
|
||||
|
||||
ipv6_mc_init_dev(ndev);
|
||||
@@ -3397,7 +3397,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
/* restore routes for permanent addresses */
|
||||
addrconf_permanent_addr(dev);
|
||||
|
||||
if (!addrconf_qdisc_ok(dev)) {
|
||||
if (!addrconf_link_ready(dev)) {
|
||||
/* device is not ready yet. */
|
||||
pr_info("ADDRCONF(NETDEV_UP): %s: link is not ready\n",
|
||||
dev->name);
|
||||
@@ -3412,7 +3412,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
||||
run_pending = 1;
|
||||
}
|
||||
} else if (event == NETDEV_CHANGE) {
|
||||
if (!addrconf_qdisc_ok(dev)) {
|
||||
if (!addrconf_link_ready(dev)) {
|
||||
/* device is still not ready. */
|
||||
break;
|
||||
}
|
||||
|
||||
+173
-100
@@ -32,6 +32,13 @@ MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
|
||||
MODULE_DESCRIPTION("nfnl_cthelper: User-space connection tracking helpers");
|
||||
|
||||
struct nfnl_cthelper {
|
||||
struct list_head list;
|
||||
struct nf_conntrack_helper helper;
|
||||
};
|
||||
|
||||
static LIST_HEAD(nfnl_cthelper_list);
|
||||
|
||||
static int
|
||||
nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,
|
||||
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||
@@ -205,18 +212,20 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
struct nf_conntrack_helper *helper;
|
||||
struct nfnl_cthelper *nfcth;
|
||||
int ret;
|
||||
|
||||
if (!tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_PRIV_DATA_LEN])
|
||||
return -EINVAL;
|
||||
|
||||
helper = kzalloc(sizeof(struct nf_conntrack_helper), GFP_KERNEL);
|
||||
if (helper == NULL)
|
||||
nfcth = kzalloc(sizeof(*nfcth), GFP_KERNEL);
|
||||
if (nfcth == NULL)
|
||||
return -ENOMEM;
|
||||
helper = &nfcth->helper;
|
||||
|
||||
ret = nfnl_cthelper_parse_expect_policy(helper, tb[NFCTH_POLICY]);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
goto err1;
|
||||
|
||||
strncpy(helper->name, nla_data(tb[NFCTH_NAME]), NF_CT_HELPER_NAME_LEN);
|
||||
helper->data_len = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
|
||||
@@ -247,12 +256,98 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
|
||||
|
||||
ret = nf_conntrack_helper_register(helper);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
goto err2;
|
||||
|
||||
list_add_tail(&nfcth->list, &nfnl_cthelper_list);
|
||||
return 0;
|
||||
err2:
|
||||
kfree(helper->expect_policy);
|
||||
err1:
|
||||
kfree(nfcth);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nfnl_cthelper_update_policy_one(const struct nf_conntrack_expect_policy *policy,
|
||||
struct nf_conntrack_expect_policy *new_policy,
|
||||
const struct nlattr *attr)
|
||||
{
|
||||
struct nlattr *tb[NFCTH_POLICY_MAX + 1];
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFCTH_POLICY_MAX, attr,
|
||||
nfnl_cthelper_expect_pol);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!tb[NFCTH_POLICY_NAME] ||
|
||||
!tb[NFCTH_POLICY_EXPECT_MAX] ||
|
||||
!tb[NFCTH_POLICY_EXPECT_TIMEOUT])
|
||||
return -EINVAL;
|
||||
|
||||
if (nla_strcmp(tb[NFCTH_POLICY_NAME], policy->name))
|
||||
return -EBUSY;
|
||||
|
||||
new_policy->max_expected =
|
||||
ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
|
||||
new_policy->timeout =
|
||||
ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT]));
|
||||
|
||||
return 0;
|
||||
err:
|
||||
kfree(helper);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nfnl_cthelper_update_policy_all(struct nlattr *tb[],
|
||||
struct nf_conntrack_helper *helper)
|
||||
{
|
||||
struct nf_conntrack_expect_policy new_policy[helper->expect_class_max + 1];
|
||||
struct nf_conntrack_expect_policy *policy;
|
||||
int i, err;
|
||||
|
||||
/* Check first that all policy attributes are well-formed, so we don't
|
||||
* leave things in inconsistent state on errors.
|
||||
*/
|
||||
for (i = 0; i < helper->expect_class_max + 1; i++) {
|
||||
|
||||
if (!tb[NFCTH_POLICY_SET + i])
|
||||
return -EINVAL;
|
||||
|
||||
err = nfnl_cthelper_update_policy_one(&helper->expect_policy[i],
|
||||
&new_policy[i],
|
||||
tb[NFCTH_POLICY_SET + i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
/* Now we can safely update them. */
|
||||
for (i = 0; i < helper->expect_class_max + 1; i++) {
|
||||
policy = (struct nf_conntrack_expect_policy *)
|
||||
&helper->expect_policy[i];
|
||||
policy->max_expected = new_policy->max_expected;
|
||||
policy->timeout = new_policy->timeout;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfnl_cthelper_update_policy(struct nf_conntrack_helper *helper,
|
||||
const struct nlattr *attr)
|
||||
{
|
||||
struct nlattr *tb[NFCTH_POLICY_SET_MAX + 1];
|
||||
unsigned int class_max;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
|
||||
nfnl_cthelper_expect_policy_set);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!tb[NFCTH_POLICY_SET_NUM])
|
||||
return -EINVAL;
|
||||
|
||||
class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
|
||||
if (helper->expect_class_max + 1 != class_max)
|
||||
return -EBUSY;
|
||||
|
||||
return nfnl_cthelper_update_policy_all(tb, helper);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -265,8 +360,7 @@ nfnl_cthelper_update(const struct nlattr * const tb[],
|
||||
return -EBUSY;
|
||||
|
||||
if (tb[NFCTH_POLICY]) {
|
||||
ret = nfnl_cthelper_parse_expect_policy(helper,
|
||||
tb[NFCTH_POLICY]);
|
||||
ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -295,7 +389,8 @@ static int nfnl_cthelper_new(struct net *net, struct sock *nfnl,
|
||||
const char *helper_name;
|
||||
struct nf_conntrack_helper *cur, *helper = NULL;
|
||||
struct nf_conntrack_tuple tuple;
|
||||
int ret = 0, i;
|
||||
struct nfnl_cthelper *nlcth;
|
||||
int ret = 0;
|
||||
|
||||
if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE])
|
||||
return -EINVAL;
|
||||
@@ -306,31 +401,22 @@ static int nfnl_cthelper_new(struct net *net, struct sock *nfnl,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < nf_ct_helper_hsize && !helper; i++) {
|
||||
hlist_for_each_entry_rcu(cur, &nf_ct_helper_hash[i], hnode) {
|
||||
list_for_each_entry(nlcth, &nfnl_cthelper_list, list) {
|
||||
cur = &nlcth->helper;
|
||||
|
||||
/* skip non-userspace conntrack helpers. */
|
||||
if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
|
||||
continue;
|
||||
if (strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
|
||||
continue;
|
||||
|
||||
if (strncmp(cur->name, helper_name,
|
||||
NF_CT_HELPER_NAME_LEN) != 0)
|
||||
continue;
|
||||
if ((tuple.src.l3num != cur->tuple.src.l3num ||
|
||||
tuple.dst.protonum != cur->tuple.dst.protonum))
|
||||
continue;
|
||||
|
||||
if ((tuple.src.l3num != cur->tuple.src.l3num ||
|
||||
tuple.dst.protonum != cur->tuple.dst.protonum))
|
||||
continue;
|
||||
if (nlh->nlmsg_flags & NLM_F_EXCL)
|
||||
return -EEXIST;
|
||||
|
||||
if (nlh->nlmsg_flags & NLM_F_EXCL) {
|
||||
ret = -EEXIST;
|
||||
goto err;
|
||||
}
|
||||
helper = cur;
|
||||
break;
|
||||
}
|
||||
helper = cur;
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (helper == NULL)
|
||||
ret = nfnl_cthelper_create(tb, &tuple);
|
||||
@@ -338,9 +424,6 @@ static int nfnl_cthelper_new(struct net *net, struct sock *nfnl,
|
||||
ret = nfnl_cthelper_update(tb, helper);
|
||||
|
||||
return ret;
|
||||
err:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -504,11 +587,12 @@ static int nfnl_cthelper_get(struct net *net, struct sock *nfnl,
|
||||
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
||||
const struct nlattr * const tb[])
|
||||
{
|
||||
int ret = -ENOENT, i;
|
||||
int ret = -ENOENT;
|
||||
struct nf_conntrack_helper *cur;
|
||||
struct sk_buff *skb2;
|
||||
char *helper_name = NULL;
|
||||
struct nf_conntrack_tuple tuple;
|
||||
struct nfnl_cthelper *nlcth;
|
||||
bool tuple_set = false;
|
||||
|
||||
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
||||
@@ -529,45 +613,39 @@ static int nfnl_cthelper_get(struct net *net, struct sock *nfnl,
|
||||
tuple_set = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < nf_ct_helper_hsize; i++) {
|
||||
hlist_for_each_entry_rcu(cur, &nf_ct_helper_hash[i], hnode) {
|
||||
list_for_each_entry(nlcth, &nfnl_cthelper_list, list) {
|
||||
cur = &nlcth->helper;
|
||||
if (helper_name &&
|
||||
strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
|
||||
continue;
|
||||
|
||||
/* skip non-userspace conntrack helpers. */
|
||||
if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
|
||||
continue;
|
||||
if (tuple_set &&
|
||||
(tuple.src.l3num != cur->tuple.src.l3num ||
|
||||
tuple.dst.protonum != cur->tuple.dst.protonum))
|
||||
continue;
|
||||
|
||||
if (helper_name && strncmp(cur->name, helper_name,
|
||||
NF_CT_HELPER_NAME_LEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (tuple_set &&
|
||||
(tuple.src.l3num != cur->tuple.src.l3num ||
|
||||
tuple.dst.protonum != cur->tuple.dst.protonum))
|
||||
continue;
|
||||
|
||||
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (skb2 == NULL) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).portid,
|
||||
nlh->nlmsg_seq,
|
||||
NFNL_MSG_TYPE(nlh->nlmsg_type),
|
||||
NFNL_MSG_CTHELPER_NEW, cur);
|
||||
if (ret <= 0) {
|
||||
kfree_skb(skb2);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
|
||||
MSG_DONTWAIT);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
|
||||
/* this avoids a loop in nfnetlink. */
|
||||
return ret == -EAGAIN ? -ENOBUFS : ret;
|
||||
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (skb2 == NULL) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).portid,
|
||||
nlh->nlmsg_seq,
|
||||
NFNL_MSG_TYPE(nlh->nlmsg_type),
|
||||
NFNL_MSG_CTHELPER_NEW, cur);
|
||||
if (ret <= 0) {
|
||||
kfree_skb(skb2);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
|
||||
MSG_DONTWAIT);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
|
||||
/* this avoids a loop in nfnetlink. */
|
||||
return ret == -EAGAIN ? -ENOBUFS : ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -578,10 +656,10 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
|
||||
{
|
||||
char *helper_name = NULL;
|
||||
struct nf_conntrack_helper *cur;
|
||||
struct hlist_node *tmp;
|
||||
struct nf_conntrack_tuple tuple;
|
||||
bool tuple_set = false, found = false;
|
||||
int i, j = 0, ret;
|
||||
struct nfnl_cthelper *nlcth, *n;
|
||||
int j = 0, ret;
|
||||
|
||||
if (tb[NFCTH_NAME])
|
||||
helper_name = nla_data(tb[NFCTH_NAME]);
|
||||
@@ -594,28 +672,27 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
|
||||
tuple_set = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < nf_ct_helper_hsize; i++) {
|
||||
hlist_for_each_entry_safe(cur, tmp, &nf_ct_helper_hash[i],
|
||||
hnode) {
|
||||
/* skip non-userspace conntrack helpers. */
|
||||
if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
|
||||
continue;
|
||||
list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
|
||||
cur = &nlcth->helper;
|
||||
j++;
|
||||
|
||||
j++;
|
||||
if (helper_name &&
|
||||
strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
|
||||
continue;
|
||||
|
||||
if (helper_name && strncmp(cur->name, helper_name,
|
||||
NF_CT_HELPER_NAME_LEN) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (tuple_set &&
|
||||
(tuple.src.l3num != cur->tuple.src.l3num ||
|
||||
tuple.dst.protonum != cur->tuple.dst.protonum))
|
||||
continue;
|
||||
if (tuple_set &&
|
||||
(tuple.src.l3num != cur->tuple.src.l3num ||
|
||||
tuple.dst.protonum != cur->tuple.dst.protonum))
|
||||
continue;
|
||||
|
||||
found = true;
|
||||
nf_conntrack_helper_unregister(cur);
|
||||
}
|
||||
found = true;
|
||||
nf_conntrack_helper_unregister(cur);
|
||||
kfree(cur->expect_policy);
|
||||
|
||||
list_del(&nlcth->list);
|
||||
kfree(nlcth);
|
||||
}
|
||||
|
||||
/* Make sure we return success if we flush and there is no helpers */
|
||||
return (found || j == 0) ? 0 : -ENOENT;
|
||||
}
|
||||
@@ -664,20 +741,16 @@ err_out:
|
||||
static void __exit nfnl_cthelper_exit(void)
|
||||
{
|
||||
struct nf_conntrack_helper *cur;
|
||||
struct hlist_node *tmp;
|
||||
int i;
|
||||
struct nfnl_cthelper *nlcth, *n;
|
||||
|
||||
nfnetlink_subsys_unregister(&nfnl_cthelper_subsys);
|
||||
|
||||
for (i=0; i<nf_ct_helper_hsize; i++) {
|
||||
hlist_for_each_entry_safe(cur, tmp, &nf_ct_helper_hash[i],
|
||||
hnode) {
|
||||
/* skip non-userspace conntrack helpers. */
|
||||
if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
|
||||
continue;
|
||||
list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
|
||||
cur = &nlcth->helper;
|
||||
|
||||
nf_conntrack_helper_unregister(cur);
|
||||
}
|
||||
nf_conntrack_helper_unregister(cur);
|
||||
kfree(cur->expect_policy);
|
||||
kfree(nlcth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -443,7 +443,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
skb = alloc_skb(size, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
skb_tx_error(entskb);
|
||||
return NULL;
|
||||
goto nlmsg_failure;
|
||||
}
|
||||
|
||||
nlh = nlmsg_put(skb, 0, 0,
|
||||
@@ -452,7 +452,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
if (!nlh) {
|
||||
skb_tx_error(entskb);
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
goto nlmsg_failure;
|
||||
}
|
||||
nfmsg = nlmsg_data(nlh);
|
||||
nfmsg->nfgen_family = entry->state.pf;
|
||||
@@ -598,12 +598,17 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
||||
}
|
||||
|
||||
nlh->nlmsg_len = skb->len;
|
||||
if (seclen)
|
||||
security_release_secctx(secdata, seclen);
|
||||
return skb;
|
||||
|
||||
nla_put_failure:
|
||||
skb_tx_error(entskb);
|
||||
kfree_skb(skb);
|
||||
net_err_ratelimited("nf_queue: error creating packet message\n");
|
||||
nlmsg_failure:
|
||||
if (seclen)
|
||||
security_release_secctx(secdata, seclen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,44 @@ EXPORT_SYMBOL_GPL(nl_table);
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
|
||||
|
||||
static struct lock_class_key nlk_cb_mutex_keys[MAX_LINKS];
|
||||
|
||||
static const char *const nlk_cb_mutex_key_strings[MAX_LINKS + 1] = {
|
||||
"nlk_cb_mutex-ROUTE",
|
||||
"nlk_cb_mutex-1",
|
||||
"nlk_cb_mutex-USERSOCK",
|
||||
"nlk_cb_mutex-FIREWALL",
|
||||
"nlk_cb_mutex-SOCK_DIAG",
|
||||
"nlk_cb_mutex-NFLOG",
|
||||
"nlk_cb_mutex-XFRM",
|
||||
"nlk_cb_mutex-SELINUX",
|
||||
"nlk_cb_mutex-ISCSI",
|
||||
"nlk_cb_mutex-AUDIT",
|
||||
"nlk_cb_mutex-FIB_LOOKUP",
|
||||
"nlk_cb_mutex-CONNECTOR",
|
||||
"nlk_cb_mutex-NETFILTER",
|
||||
"nlk_cb_mutex-IP6_FW",
|
||||
"nlk_cb_mutex-DNRTMSG",
|
||||
"nlk_cb_mutex-KOBJECT_UEVENT",
|
||||
"nlk_cb_mutex-GENERIC",
|
||||
"nlk_cb_mutex-17",
|
||||
"nlk_cb_mutex-SCSITRANSPORT",
|
||||
"nlk_cb_mutex-ECRYPTFS",
|
||||
"nlk_cb_mutex-RDMA",
|
||||
"nlk_cb_mutex-CRYPTO",
|
||||
"nlk_cb_mutex-SMC",
|
||||
"nlk_cb_mutex-23",
|
||||
"nlk_cb_mutex-24",
|
||||
"nlk_cb_mutex-25",
|
||||
"nlk_cb_mutex-26",
|
||||
"nlk_cb_mutex-27",
|
||||
"nlk_cb_mutex-28",
|
||||
"nlk_cb_mutex-29",
|
||||
"nlk_cb_mutex-30",
|
||||
"nlk_cb_mutex-31",
|
||||
"nlk_cb_mutex-MAX_LINKS"
|
||||
};
|
||||
|
||||
static int netlink_dump(struct sock *sk);
|
||||
static void netlink_skb_destructor(struct sk_buff *skb);
|
||||
|
||||
@@ -585,6 +623,9 @@ static int __netlink_create(struct net *net, struct socket *sock,
|
||||
} else {
|
||||
nlk->cb_mutex = &nlk->cb_def_mutex;
|
||||
mutex_init(nlk->cb_mutex);
|
||||
lockdep_set_class_and_name(nlk->cb_mutex,
|
||||
nlk_cb_mutex_keys + protocol,
|
||||
nlk_cb_mutex_key_strings[protocol]);
|
||||
}
|
||||
init_waitqueue_head(&nlk->wait);
|
||||
|
||||
|
||||
@@ -200,9 +200,13 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
pr_debug("%s(skb %p,sch %p,[qdisc %p])\n", __func__, skb, sch, p);
|
||||
|
||||
if (p->set_tc_index) {
|
||||
int wlen = skb_network_offset(skb);
|
||||
|
||||
switch (tc_skb_protocol(skb)) {
|
||||
case htons(ETH_P_IP):
|
||||
if (skb_cow_head(skb, sizeof(struct iphdr)))
|
||||
wlen += sizeof(struct iphdr);
|
||||
if (!pskb_may_pull(skb, wlen) ||
|
||||
skb_try_make_writable(skb, wlen))
|
||||
goto drop;
|
||||
|
||||
skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
|
||||
@@ -210,7 +214,9 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
break;
|
||||
|
||||
case htons(ETH_P_IPV6):
|
||||
if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
|
||||
wlen += sizeof(struct ipv6hdr);
|
||||
if (!pskb_may_pull(skb, wlen) ||
|
||||
skb_try_make_writable(skb, wlen))
|
||||
goto drop;
|
||||
|
||||
skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
|
||||
|
||||
+5
-6
@@ -382,17 +382,18 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
|
||||
}
|
||||
|
||||
static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
|
||||
struct sctp_sndrcvinfo *sinfo,
|
||||
struct list_head *queue, int msg_len)
|
||||
struct sctp_sndrcvinfo *sinfo, int msg_len)
|
||||
{
|
||||
struct sctp_outq *q = &asoc->outqueue;
|
||||
struct sctp_chunk *chk, *temp;
|
||||
|
||||
list_for_each_entry_safe(chk, temp, queue, list) {
|
||||
list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
|
||||
if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
|
||||
chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
|
||||
continue;
|
||||
|
||||
list_del_init(&chk->list);
|
||||
q->out_qlen -= chk->skb->len;
|
||||
asoc->sent_cnt_removable--;
|
||||
asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
|
||||
|
||||
@@ -431,9 +432,7 @@ void sctp_prsctp_prune(struct sctp_association *asoc,
|
||||
return;
|
||||
}
|
||||
|
||||
sctp_prsctp_prune_unsent(asoc, sinfo,
|
||||
&asoc->outqueue.out_chunk_list,
|
||||
msg_len);
|
||||
sctp_prsctp_prune_unsent(asoc, sinfo, msg_len);
|
||||
}
|
||||
|
||||
/* Mark all the eligible packets on a transport for retransmission. */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user