Merge 4.19.13 into android-4.19
Changes in 4.19.13 iomap: Revert "fs/iomap.c: get/put the page in iomap_page_create/release()" Revert "vfs: Allow userns root to call mknod on owned filesystems." USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data xhci: Don't prevent USB2 bus suspend in state check intended for USB3 only USB: xhci: fix 'broken_suspend' placement in struct xchi_hcd USB: serial: option: add GosunCn ZTE WeLink ME3630 USB: serial: option: add HP lt4132 USB: serial: option: add Simcom SIM7500/SIM7600 (MBIM mode) USB: serial: option: add Fibocom NL668 series USB: serial: option: add Telit LN940 series ubifs: Handle re-linking of inodes correctly while recovery scsi: t10-pi: Return correct ref tag when queue has no integrity profile scsi: sd: use mempool for discard special page mmc: core: Reset HPI enabled state during re-init and in case of errors mmc: core: Allow BKOPS and CACHE ctrl even if no HPI support mmc: core: Use a minimum 1600ms timeout when enabling CACHE ctrl mmc: omap_hsmmc: fix DMA API warning gpio: max7301: fix driver for use with CONFIG_VMAP_STACK gpiolib-acpi: Only defer request_irq for GpioInt ACPI event handlers posix-timers: Fix division by zero bug KVM: X86: Fix NULL deref in vcpu_scan_ioapic kvm: x86: Add AMD's EX_CFG to the list of ignored MSRs KVM: Fix UAF in nested posted interrupt processing Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels futex: Cure exit race x86/mtrr: Don't copy uninitialized gentry fields back to userspace x86/mm: Fix decoy address handling vs 32-bit builds x86/vdso: Pass --eh-frame-hdr to the linker x86/intel_rdt: Ensure a CPU remains online for the region's pseudo-locking sequence panic: avoid deadlocks in re-entrant console drivers mm: add mm_pxd_folded checks to pgtable_bytes accounting functions mm: make the __PAGETABLE_PxD_FOLDED defines non-empty mm: introduce mm_[p4d|pud|pmd]_folded xfrm_user: fix freeing of xfrm states on acquire rtlwifi: Fix leak of skb when processing C2H_BT_INFO iwlwifi: mvm: don't send GEO_TX_POWER_LIMIT to old firmwares Revert "mwifiex: restructure rx_reorder_tbl_lock usage" iwlwifi: add new cards for 9560, 9462, 9461 and killer series media: ov5640: Fix set format regression mm, memory_hotplug: initialize struct pages for the full memory section mm: thp: fix flags for pmd migration when split mm, page_alloc: fix has_unmovable_pages for HugePages mm: don't miss the last page because of round-off error Input: elantech - disable elan-i2c for P52 and P72 proc/sysctl: don't return ENOMEM on lookup when a table is unregistering drm/ioctl: Fix Spectre v1 vulnerabilities Linux 4.19.13 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 12
|
||||
SUBLEVEL = 13
|
||||
EXTRAVERSION =
|
||||
NAME = "People's Front"
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifndef _ASM_PGTABLE_2LEVEL_H
|
||||
#define _ASM_PGTABLE_2LEVEL_H
|
||||
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
|
||||
/*
|
||||
* Hardware-wise, we have a two level page table structure, where the first
|
||||
|
||||
@@ -55,12 +55,12 @@
|
||||
*/
|
||||
#ifdef CONFIG_SUN3
|
||||
#define PTRS_PER_PTE 16
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
#define PTRS_PER_PMD 1
|
||||
#define PTRS_PER_PGD 2048
|
||||
#elif defined(CONFIG_COLDFIRE)
|
||||
#define PTRS_PER_PTE 512
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
#define PTRS_PER_PMD 1
|
||||
#define PTRS_PER_PGD 1024
|
||||
#else
|
||||
|
||||
@@ -63,7 +63,7 @@ extern int mem_init_done;
|
||||
|
||||
#include <asm-generic/4level-fixup.h>
|
||||
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#ifndef _ASMNDS32_PGTABLE_H
|
||||
#define _ASMNDS32_PGTABLE_H
|
||||
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
#include <asm-generic/4level-fixup.h>
|
||||
#include <asm-generic/sizes.h>
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
|
||||
#if CONFIG_PGTABLE_LEVELS == 3
|
||||
#define BITS_PER_PMD (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY)
|
||||
#else
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
#define BITS_PER_PMD 0
|
||||
#endif
|
||||
#define PTRS_PER_PMD (1UL << BITS_PER_PMD)
|
||||
|
||||
@@ -171,7 +171,8 @@ quiet_cmd_vdso = VDSO $@
|
||||
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
||||
|
||||
VDSO_LDFLAGS = -shared $(call ld-option, --hash-style=both) \
|
||||
$(call ld-option, --build-id) -Bsymbolic
|
||||
$(call ld-option, --build-id) $(call ld-option, --eh-frame-hdr) \
|
||||
-Bsymbolic
|
||||
GCOV_PROFILE := n
|
||||
|
||||
#
|
||||
|
||||
@@ -389,6 +389,7 @@
|
||||
#define MSR_F15H_NB_PERF_CTR 0xc0010241
|
||||
#define MSR_F15H_PTSC 0xc0010280
|
||||
#define MSR_F15H_IC_CFG 0xc0011021
|
||||
#define MSR_F15H_EX_CFG 0xc001102c
|
||||
|
||||
/* Fam 10h MSRs */
|
||||
#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/kernfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -310,9 +311,11 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
|
||||
return -EINVAL;
|
||||
buf[nbytes - 1] = '\0';
|
||||
|
||||
cpus_read_lock();
|
||||
rdtgrp = rdtgroup_kn_lock_live(of->kn);
|
||||
if (!rdtgrp) {
|
||||
rdtgroup_kn_unlock(of->kn);
|
||||
cpus_read_unlock();
|
||||
return -ENOENT;
|
||||
}
|
||||
rdt_last_cmd_clear();
|
||||
@@ -367,6 +370,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
|
||||
|
||||
out:
|
||||
rdtgroup_kn_unlock(of->kn);
|
||||
cpus_read_unlock();
|
||||
return ret ?: nbytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +165,8 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
|
||||
struct mtrr_gentry gentry;
|
||||
void __user *arg = (void __user *) __arg;
|
||||
|
||||
memset(&gentry, 0, sizeof(gentry));
|
||||
|
||||
switch (cmd) {
|
||||
case MTRRIOC_ADD_ENTRY:
|
||||
case MTRRIOC_SET_ENTRY:
|
||||
|
||||
@@ -11471,6 +11471,8 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
|
||||
kunmap(vmx->nested.pi_desc_page);
|
||||
kvm_release_page_dirty(vmx->nested.pi_desc_page);
|
||||
vmx->nested.pi_desc_page = NULL;
|
||||
vmx->nested.pi_desc = NULL;
|
||||
vmcs_write64(POSTED_INTR_DESC_ADDR, -1ull);
|
||||
}
|
||||
page = kvm_vcpu_gpa_to_page(vcpu, vmcs12->posted_intr_desc_addr);
|
||||
if (is_error_page(page))
|
||||
|
||||
@@ -2343,6 +2343,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
case MSR_AMD64_PATCH_LOADER:
|
||||
case MSR_AMD64_BU_CFG2:
|
||||
case MSR_AMD64_DC_CFG:
|
||||
case MSR_F15H_EX_CFG:
|
||||
break;
|
||||
|
||||
case MSR_IA32_UCODE_REV:
|
||||
@@ -2638,6 +2639,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
case MSR_AMD64_BU_CFG2:
|
||||
case MSR_IA32_PERF_CTL:
|
||||
case MSR_AMD64_DC_CFG:
|
||||
case MSR_F15H_EX_CFG:
|
||||
msr_info->data = 0;
|
||||
break;
|
||||
case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
|
||||
@@ -7304,7 +7306,7 @@ void kvm_make_scan_ioapic_request(struct kvm *kvm)
|
||||
|
||||
static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!kvm_apic_hw_enabled(vcpu->arch.apic))
|
||||
if (!kvm_apic_present(vcpu))
|
||||
return;
|
||||
|
||||
bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
|
||||
|
||||
@@ -519,8 +519,13 @@ static u64 sanitize_phys(u64 address)
|
||||
* for a "decoy" virtual address (bit 63 clear) passed to
|
||||
* set_memory_X(). __pa() on a "decoy" address results in a
|
||||
* physical address with bit 63 set.
|
||||
*
|
||||
* Decoy addresses are not present for 32-bit builds, see
|
||||
* set_mce_nospec().
|
||||
*/
|
||||
return address & __PHYSICAL_MASK;
|
||||
if (IS_ENABLED(CONFIG_X86_64))
|
||||
return address & __PHYSICAL_MASK;
|
||||
return address;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -546,7 +551,11 @@ int reserve_memtype(u64 start, u64 end, enum page_cache_mode req_type,
|
||||
|
||||
start = sanitize_phys(start);
|
||||
end = sanitize_phys(end);
|
||||
BUG_ON(start >= end); /* end is exclusive */
|
||||
if (start >= end) {
|
||||
WARN(1, "%s failed: [mem %#010Lx-%#010Lx], req %s\n", __func__,
|
||||
start, end - 1, cattr_name(req_type));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pat_enabled()) {
|
||||
/* This is identical to page table setting without PAT */
|
||||
|
||||
@@ -25,7 +25,7 @@ static int max7301_spi_write(struct device *dev, unsigned int reg,
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
|
||||
|
||||
return spi_write(spi, (const u8 *)&word, sizeof(word));
|
||||
return spi_write_then_read(spi, &word, sizeof(word), NULL, 0);
|
||||
}
|
||||
|
||||
/* A read from the MAX7301 means two transfers; here, one message each */
|
||||
@@ -37,14 +37,8 @@ static int max7301_spi_read(struct device *dev, unsigned int reg)
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
|
||||
word = 0x8000 | (reg << 8);
|
||||
ret = spi_write(spi, (const u8 *)&word, sizeof(word));
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* This relies on the fact, that a transfer with NULL tx_buf shifts out
|
||||
* zero bytes (=NOOP for MAX7301)
|
||||
*/
|
||||
ret = spi_read(spi, (u8 *)&word, sizeof(word));
|
||||
ret = spi_write_then_read(spi, &word, sizeof(word), &word,
|
||||
sizeof(word));
|
||||
if (ret)
|
||||
return ret;
|
||||
return word & 0xff;
|
||||
|
||||
@@ -23,11 +23,28 @@
|
||||
|
||||
#include "gpiolib.h"
|
||||
|
||||
/**
|
||||
* struct acpi_gpio_event - ACPI GPIO event handler data
|
||||
*
|
||||
* @node: list-entry of the events list of the struct acpi_gpio_chip
|
||||
* @handle: handle of ACPI method to execute when the IRQ triggers
|
||||
* @handler: irq_handler to pass to request_irq when requesting the IRQ
|
||||
* @pin: GPIO pin number on the gpio_chip
|
||||
* @irq: Linux IRQ number for the event, for request_ / free_irq
|
||||
* @irqflags: flags to pass to request_irq when requesting the IRQ
|
||||
* @irq_is_wake: If the ACPI flags indicate the IRQ is a wakeup source
|
||||
* @is_requested: True if request_irq has been done
|
||||
* @desc: gpio_desc for the GPIO pin for this event
|
||||
*/
|
||||
struct acpi_gpio_event {
|
||||
struct list_head node;
|
||||
acpi_handle handle;
|
||||
irq_handler_t handler;
|
||||
unsigned int pin;
|
||||
unsigned int irq;
|
||||
unsigned long irqflags;
|
||||
bool irq_is_wake;
|
||||
bool irq_requested;
|
||||
struct gpio_desc *desc;
|
||||
};
|
||||
|
||||
@@ -53,10 +70,10 @@ struct acpi_gpio_chip {
|
||||
|
||||
/*
|
||||
* For gpiochips which call acpi_gpiochip_request_interrupts() before late_init
|
||||
* (so builtin drivers) we register the ACPI GpioInt event handlers from a
|
||||
* (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
|
||||
* late_initcall_sync handler, so that other builtin drivers can register their
|
||||
* OpRegions before the event handlers can run. This list contains gpiochips
|
||||
* for which the acpi_gpiochip_request_interrupts() has been deferred.
|
||||
* for which the acpi_gpiochip_request_irqs() call has been deferred.
|
||||
*/
|
||||
static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
|
||||
static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
|
||||
@@ -137,8 +154,42 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource);
|
||||
|
||||
static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
|
||||
void *context)
|
||||
static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
|
||||
struct acpi_gpio_event *event)
|
||||
{
|
||||
int ret, value;
|
||||
|
||||
ret = request_threaded_irq(event->irq, NULL, event->handler,
|
||||
event->irqflags, "ACPI:Event", event);
|
||||
if (ret) {
|
||||
dev_err(acpi_gpio->chip->parent,
|
||||
"Failed to setup interrupt handler for %d\n",
|
||||
event->irq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->irq_is_wake)
|
||||
enable_irq_wake(event->irq);
|
||||
|
||||
event->irq_requested = true;
|
||||
|
||||
/* Make sure we trigger the initial state of edge-triggered IRQs */
|
||||
value = gpiod_get_raw_value_cansleep(event->desc);
|
||||
if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
|
||||
((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
|
||||
event->handler(event->irq, event);
|
||||
}
|
||||
|
||||
static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio)
|
||||
{
|
||||
struct acpi_gpio_event *event;
|
||||
|
||||
list_for_each_entry(event, &acpi_gpio->events, node)
|
||||
acpi_gpiochip_request_irq(acpi_gpio, event);
|
||||
}
|
||||
|
||||
static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
|
||||
void *context)
|
||||
{
|
||||
struct acpi_gpio_chip *acpi_gpio = context;
|
||||
struct gpio_chip *chip = acpi_gpio->chip;
|
||||
@@ -147,8 +198,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
|
||||
struct acpi_gpio_event *event;
|
||||
irq_handler_t handler = NULL;
|
||||
struct gpio_desc *desc;
|
||||
unsigned long irqflags;
|
||||
int ret, pin, irq, value;
|
||||
int ret, pin, irq;
|
||||
|
||||
if (!acpi_gpio_get_irq_resource(ares, &agpio))
|
||||
return AE_OK;
|
||||
@@ -179,8 +229,6 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
|
||||
|
||||
gpiod_direction_input(desc);
|
||||
|
||||
value = gpiod_get_value_cansleep(desc);
|
||||
|
||||
ret = gpiochip_lock_as_irq(chip, pin);
|
||||
if (ret) {
|
||||
dev_err(chip->parent, "Failed to lock GPIO as interrupt\n");
|
||||
@@ -193,64 +241,42 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
|
||||
goto fail_unlock_irq;
|
||||
}
|
||||
|
||||
irqflags = IRQF_ONESHOT;
|
||||
if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
|
||||
if (agpio->polarity == ACPI_ACTIVE_HIGH)
|
||||
irqflags |= IRQF_TRIGGER_HIGH;
|
||||
else
|
||||
irqflags |= IRQF_TRIGGER_LOW;
|
||||
} else {
|
||||
switch (agpio->polarity) {
|
||||
case ACPI_ACTIVE_HIGH:
|
||||
irqflags |= IRQF_TRIGGER_RISING;
|
||||
break;
|
||||
case ACPI_ACTIVE_LOW:
|
||||
irqflags |= IRQF_TRIGGER_FALLING;
|
||||
break;
|
||||
default:
|
||||
irqflags |= IRQF_TRIGGER_RISING |
|
||||
IRQF_TRIGGER_FALLING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||
if (!event)
|
||||
goto fail_unlock_irq;
|
||||
|
||||
event->irqflags = IRQF_ONESHOT;
|
||||
if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
|
||||
if (agpio->polarity == ACPI_ACTIVE_HIGH)
|
||||
event->irqflags |= IRQF_TRIGGER_HIGH;
|
||||
else
|
||||
event->irqflags |= IRQF_TRIGGER_LOW;
|
||||
} else {
|
||||
switch (agpio->polarity) {
|
||||
case ACPI_ACTIVE_HIGH:
|
||||
event->irqflags |= IRQF_TRIGGER_RISING;
|
||||
break;
|
||||
case ACPI_ACTIVE_LOW:
|
||||
event->irqflags |= IRQF_TRIGGER_FALLING;
|
||||
break;
|
||||
default:
|
||||
event->irqflags |= IRQF_TRIGGER_RISING |
|
||||
IRQF_TRIGGER_FALLING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event->handle = evt_handle;
|
||||
event->handler = handler;
|
||||
event->irq = irq;
|
||||
event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE;
|
||||
event->pin = pin;
|
||||
event->desc = desc;
|
||||
|
||||
ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
|
||||
"ACPI:Event", event);
|
||||
if (ret) {
|
||||
dev_err(chip->parent,
|
||||
"Failed to setup interrupt handler for %d\n",
|
||||
event->irq);
|
||||
goto fail_free_event;
|
||||
}
|
||||
|
||||
if (agpio->wake_capable == ACPI_WAKE_CAPABLE)
|
||||
enable_irq_wake(irq);
|
||||
|
||||
list_add_tail(&event->node, &acpi_gpio->events);
|
||||
|
||||
/*
|
||||
* Make sure we trigger the initial state of the IRQ when using RISING
|
||||
* or FALLING. Note we run the handlers on late_init, the AML code
|
||||
* may refer to OperationRegions from other (builtin) drivers which
|
||||
* may be probed after us.
|
||||
*/
|
||||
if (((irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
|
||||
((irqflags & IRQF_TRIGGER_FALLING) && value == 0))
|
||||
handler(event->irq, event);
|
||||
|
||||
return AE_OK;
|
||||
|
||||
fail_free_event:
|
||||
kfree(event);
|
||||
fail_unlock_irq:
|
||||
gpiochip_unlock_as_irq(chip, pin);
|
||||
fail_free_desc:
|
||||
@@ -287,6 +313,9 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
acpi_walk_resources(handle, "_AEI",
|
||||
acpi_gpiochip_alloc_event, acpi_gpio);
|
||||
|
||||
mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
|
||||
defer = !acpi_gpio_deferred_req_irqs_done;
|
||||
if (defer)
|
||||
@@ -297,8 +326,7 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
|
||||
if (defer)
|
||||
return;
|
||||
|
||||
acpi_walk_resources(handle, "_AEI",
|
||||
acpi_gpiochip_request_interrupt, acpi_gpio);
|
||||
acpi_gpiochip_request_irqs(acpi_gpio);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_gpiochip_request_interrupts);
|
||||
|
||||
@@ -335,10 +363,13 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
|
||||
list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
|
||||
struct gpio_desc *desc;
|
||||
|
||||
if (irqd_is_wakeup_set(irq_get_irq_data(event->irq)))
|
||||
disable_irq_wake(event->irq);
|
||||
if (event->irq_requested) {
|
||||
if (event->irq_is_wake)
|
||||
disable_irq_wake(event->irq);
|
||||
|
||||
free_irq(event->irq, event);
|
||||
}
|
||||
|
||||
free_irq(event->irq, event);
|
||||
desc = event->desc;
|
||||
if (WARN_ON(IS_ERR(desc)))
|
||||
continue;
|
||||
@@ -1204,23 +1235,16 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
|
||||
return con_id == NULL;
|
||||
}
|
||||
|
||||
/* Run deferred acpi_gpiochip_request_interrupts() */
|
||||
static int acpi_gpio_handle_deferred_request_interrupts(void)
|
||||
/* Run deferred acpi_gpiochip_request_irqs() */
|
||||
static int acpi_gpio_handle_deferred_request_irqs(void)
|
||||
{
|
||||
struct acpi_gpio_chip *acpi_gpio, *tmp;
|
||||
|
||||
mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
|
||||
list_for_each_entry_safe(acpi_gpio, tmp,
|
||||
&acpi_gpio_deferred_req_irqs_list,
|
||||
deferred_req_irqs_list_entry) {
|
||||
acpi_handle handle;
|
||||
|
||||
handle = ACPI_HANDLE(acpi_gpio->chip->parent);
|
||||
acpi_walk_resources(handle, "_AEI",
|
||||
acpi_gpiochip_request_interrupt, acpi_gpio);
|
||||
|
||||
list_del_init(&acpi_gpio->deferred_req_irqs_list_entry);
|
||||
}
|
||||
deferred_req_irqs_list_entry)
|
||||
acpi_gpiochip_request_irqs(acpi_gpio);
|
||||
|
||||
acpi_gpio_deferred_req_irqs_done = true;
|
||||
mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
|
||||
@@ -1228,4 +1252,4 @@ static int acpi_gpio_handle_deferred_request_interrupts(void)
|
||||
return 0;
|
||||
}
|
||||
/* We must use _sync so that this runs after the first deferred_probe run */
|
||||
late_initcall_sync(acpi_gpio_handle_deferred_request_interrupts);
|
||||
late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
/**
|
||||
* DOC: getunique and setversion story
|
||||
@@ -794,13 +795,17 @@ long drm_ioctl(struct file *filp,
|
||||
|
||||
if (is_driver_ioctl) {
|
||||
/* driver ioctl */
|
||||
if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls)
|
||||
unsigned int index = nr - DRM_COMMAND_BASE;
|
||||
|
||||
if (index >= dev->driver->num_ioctls)
|
||||
goto err_i1;
|
||||
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
|
||||
index = array_index_nospec(index, dev->driver->num_ioctls);
|
||||
ioctl = &dev->driver->ioctls[index];
|
||||
} else {
|
||||
/* core ioctl */
|
||||
if (nr >= DRM_CORE_IOCTL_COUNT)
|
||||
goto err_i1;
|
||||
nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
|
||||
ioctl = &drm_ioctls[nr];
|
||||
}
|
||||
|
||||
@@ -882,6 +887,7 @@ bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
|
||||
|
||||
if (nr >= DRM_CORE_IOCTL_COUNT)
|
||||
return false;
|
||||
nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT);
|
||||
|
||||
*flags = drm_ioctls[nr].flags;
|
||||
return true;
|
||||
|
||||
@@ -316,6 +316,8 @@ static ssize_t out_intr_mask_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
|
||||
return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
|
||||
}
|
||||
@@ -329,6 +331,8 @@ static ssize_t out_read_index_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
|
||||
return sprintf(buf, "%d\n", outbound.current_read_index);
|
||||
}
|
||||
@@ -343,6 +347,8 @@ static ssize_t out_write_index_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
|
||||
return sprintf(buf, "%d\n", outbound.current_write_index);
|
||||
}
|
||||
@@ -357,6 +363,8 @@ static ssize_t out_read_bytes_avail_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
|
||||
return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
|
||||
}
|
||||
@@ -371,6 +379,8 @@ static ssize_t out_write_bytes_avail_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound);
|
||||
return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
|
||||
}
|
||||
@@ -384,6 +394,8 @@ static ssize_t in_intr_mask_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
|
||||
return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
|
||||
}
|
||||
@@ -397,6 +409,8 @@ static ssize_t in_read_index_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
|
||||
return sprintf(buf, "%d\n", inbound.current_read_index);
|
||||
}
|
||||
@@ -410,6 +424,8 @@ static ssize_t in_write_index_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
|
||||
return sprintf(buf, "%d\n", inbound.current_write_index);
|
||||
}
|
||||
@@ -424,6 +440,8 @@ static ssize_t in_read_bytes_avail_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
|
||||
return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
|
||||
}
|
||||
@@ -438,6 +456,8 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
|
||||
|
||||
if (!hv_dev->channel)
|
||||
return -ENODEV;
|
||||
if (hv_dev->channel->state != CHANNEL_OPENED_STATE)
|
||||
return -EINVAL;
|
||||
hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
|
||||
return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
|
||||
}
|
||||
|
||||
@@ -1767,6 +1767,18 @@ static int elantech_smbus = IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) ?
|
||||
module_param_named(elantech_smbus, elantech_smbus, int, 0644);
|
||||
MODULE_PARM_DESC(elantech_smbus, "Use a secondary bus for the Elantech device.");
|
||||
|
||||
static const char * const i2c_blacklist_pnp_ids[] = {
|
||||
/*
|
||||
* These are known to not be working properly as bits are missing
|
||||
* in elan_i2c.
|
||||
*/
|
||||
"LEN2131", /* ThinkPad P52 w/ NFC */
|
||||
"LEN2132", /* ThinkPad P52 */
|
||||
"LEN2133", /* ThinkPad P72 w/ NFC */
|
||||
"LEN2134", /* ThinkPad P72 */
|
||||
NULL
|
||||
};
|
||||
|
||||
static int elantech_create_smbus(struct psmouse *psmouse,
|
||||
struct elantech_device_info *info,
|
||||
bool leave_breadcrumbs)
|
||||
@@ -1802,10 +1814,12 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
|
||||
|
||||
if (elantech_smbus == ELANTECH_SMBUS_NOT_SET) {
|
||||
/*
|
||||
* New ICs are enabled by default.
|
||||
* New ICs are enabled by default, unless mentioned in
|
||||
* i2c_blacklist_pnp_ids.
|
||||
* Old ICs are up to the user to decide.
|
||||
*/
|
||||
if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
|
||||
if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) ||
|
||||
psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids))
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
@@ -2020,6 +2020,7 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
|
||||
struct ov5640_dev *sensor = to_ov5640_dev(sd);
|
||||
const struct ov5640_mode_info *new_mode;
|
||||
struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
|
||||
struct v4l2_mbus_framefmt *fmt;
|
||||
int ret;
|
||||
|
||||
if (format->pad != 0)
|
||||
@@ -2037,22 +2038,20 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||
struct v4l2_mbus_framefmt *fmt =
|
||||
v4l2_subdev_get_try_format(sd, cfg, 0);
|
||||
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
|
||||
fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
|
||||
else
|
||||
fmt = &sensor->fmt;
|
||||
|
||||
*fmt = *mbus_fmt;
|
||||
goto out;
|
||||
}
|
||||
*fmt = *mbus_fmt;
|
||||
|
||||
if (new_mode != sensor->current_mode) {
|
||||
sensor->current_mode = new_mode;
|
||||
sensor->pending_mode_change = true;
|
||||
}
|
||||
if (mbus_fmt->code != sensor->fmt.code) {
|
||||
sensor->fmt = *mbus_fmt;
|
||||
if (mbus_fmt->code != sensor->fmt.code)
|
||||
sensor->pending_fmt_change = true;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&sensor->lock);
|
||||
return ret;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "pwrseq.h"
|
||||
|
||||
#define DEFAULT_CMD6_TIMEOUT_MS 500
|
||||
#define MIN_CACHE_EN_TIMEOUT_MS 1600
|
||||
|
||||
static const unsigned int tran_exp[] = {
|
||||
10000, 100000, 1000000, 10000000,
|
||||
@@ -526,8 +527,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
||||
card->cid.year += 16;
|
||||
|
||||
/* check whether the eMMC card supports BKOPS */
|
||||
if (!mmc_card_broken_hpi(card) &&
|
||||
ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
|
||||
if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
|
||||
card->ext_csd.bkops = 1;
|
||||
card->ext_csd.man_bkops_en =
|
||||
(ext_csd[EXT_CSD_BKOPS_EN] &
|
||||
@@ -1782,20 +1782,26 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
||||
if (err) {
|
||||
pr_warn("%s: Enabling HPI failed\n",
|
||||
mmc_hostname(card->host));
|
||||
card->ext_csd.hpi_en = 0;
|
||||
err = 0;
|
||||
} else
|
||||
} else {
|
||||
card->ext_csd.hpi_en = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If cache size is higher than 0, this indicates
|
||||
* the existence of cache and it can be turned on.
|
||||
* If cache size is higher than 0, this indicates the existence of cache
|
||||
* and it can be turned on. Note that some eMMCs from Micron has been
|
||||
* reported to need ~800 ms timeout, while enabling the cache after
|
||||
* sudden power failure tests. Let's extend the timeout to a minimum of
|
||||
* DEFAULT_CACHE_EN_TIMEOUT_MS and do it for all cards.
|
||||
*/
|
||||
if (!mmc_card_broken_hpi(card) &&
|
||||
card->ext_csd.cache_size > 0) {
|
||||
if (card->ext_csd.cache_size > 0) {
|
||||
unsigned int timeout_ms = MIN_CACHE_EN_TIMEOUT_MS;
|
||||
|
||||
timeout_ms = max(card->ext_csd.generic_cmd6_time, timeout_ms);
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_CACHE_CTRL, 1,
|
||||
card->ext_csd.generic_cmd6_time);
|
||||
EXT_CSD_CACHE_CTRL, 1, timeout_ms);
|
||||
if (err && err != -EBADMSG)
|
||||
goto free_card;
|
||||
|
||||
|
||||
@@ -2066,7 +2066,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
|
||||
mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
|
||||
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
|
||||
mmc->max_seg_size = mmc->max_req_size;
|
||||
|
||||
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
|
||||
MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE | MMC_CAP_CMD23;
|
||||
@@ -2096,6 +2095,17 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
|
||||
goto err_irq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Limit the maximum segment size to the lower of the request size
|
||||
* and the DMA engine device segment size limits. In reality, with
|
||||
* 32-bit transfers, the DMA engine can do longer segments than this
|
||||
* but there is no way to represent that in the DMA model - if we
|
||||
* increase this figure here, we get warnings from the DMA API debug.
|
||||
*/
|
||||
mmc->max_seg_size = min3(mmc->max_req_size,
|
||||
dma_get_max_seg_size(host->rx_chan->device->dev),
|
||||
dma_get_max_seg_size(host->tx_chan->device->dev));
|
||||
|
||||
/* Request IRQ for MMC operations */
|
||||
ret = devm_request_irq(&pdev->dev, host->irq, omap_hsmmc_irq, 0,
|
||||
mmc_hostname(mmc), host);
|
||||
|
||||
@@ -2807,6 +2807,12 @@ static int hso_get_config_data(struct usb_interface *interface)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* check if we have a valid interface */
|
||||
if (if_num > 16) {
|
||||
kfree(config_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (config_data[if_num]) {
|
||||
case 0x0:
|
||||
result = 0;
|
||||
@@ -2877,10 +2883,18 @@ static int hso_probe(struct usb_interface *interface,
|
||||
|
||||
/* Get the interface/port specification from either driver_info or from
|
||||
* the device itself */
|
||||
if (id->driver_info)
|
||||
if (id->driver_info) {
|
||||
/* if_num is controlled by the device, driver_info is a 0 terminated
|
||||
* array. Make sure, the access is in bounds! */
|
||||
for (i = 0; i <= if_num; ++i)
|
||||
if (((u32 *)(id->driver_info))[i] == 0)
|
||||
goto exit;
|
||||
port_spec = ((u32 *)(id->driver_info))[if_num];
|
||||
else
|
||||
} else {
|
||||
port_spec = hso_get_config_data(interface);
|
||||
if (port_spec < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Check if we need to switch to alt interfaces prior to port
|
||||
* configuration */
|
||||
|
||||
@@ -868,6 +868,15 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
||||
int ret, i, j;
|
||||
u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT);
|
||||
|
||||
/*
|
||||
* This command is not supported on earlier firmware versions.
|
||||
* Unfortunately, we don't have a TLV API flag to rely on, so
|
||||
* rely on the major version which is in the first byte of
|
||||
* ucode_ver.
|
||||
*/
|
||||
if (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) < 41)
|
||||
return 0;
|
||||
|
||||
ret = iwl_mvm_sar_get_wgds_table(mvm);
|
||||
if (ret < 0) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
|
||||
@@ -518,6 +518,56 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
|
||||
{IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)},
|
||||
|
||||
/* 9000 Series */
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x00A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0230, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x02A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x2030, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x2034, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x4030, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x4034, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_soc)},
|
||||
{IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x2526, 0x0018, iwl9260_2ac_cfg)},
|
||||
|
||||
@@ -696,11 +696,10 @@ void mwifiex_11n_delba(struct mwifiex_private *priv, int tid)
|
||||
"Send delba to tid=%d, %pM\n",
|
||||
tid, rx_reor_tbl_ptr->ta);
|
||||
mwifiex_send_delba(priv, tid, rx_reor_tbl_ptr->ta, 0);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
return;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,8 +103,6 @@ static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload)
|
||||
* There could be holes in the buffer, which are skipped by the function.
|
||||
* Since the buffer is linear, the function uses rotation to simulate
|
||||
* circular buffer.
|
||||
*
|
||||
* The caller must hold rx_reorder_tbl_lock spinlock.
|
||||
*/
|
||||
static void
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
@@ -113,21 +111,25 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
{
|
||||
int pkt_to_send, i;
|
||||
void *rx_tmp_ptr;
|
||||
unsigned long flags;
|
||||
|
||||
pkt_to_send = (start_win > tbl->start_win) ?
|
||||
min((start_win - tbl->start_win), tbl->win_size) :
|
||||
tbl->win_size;
|
||||
|
||||
for (i = 0; i < pkt_to_send; ++i) {
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
rx_tmp_ptr = NULL;
|
||||
if (tbl->rx_reorder_ptr[i]) {
|
||||
rx_tmp_ptr = tbl->rx_reorder_ptr[i];
|
||||
tbl->rx_reorder_ptr[i] = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
if (rx_tmp_ptr)
|
||||
mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
/*
|
||||
* We don't have a circular buffer, hence use rotation to simulate
|
||||
* circular buffer
|
||||
@@ -138,6 +140,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
tbl->start_win = start_win;
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -147,8 +150,6 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
* The start window is adjusted automatically when a hole is located.
|
||||
* Since the buffer is linear, the function uses rotation to simulate
|
||||
* circular buffer.
|
||||
*
|
||||
* The caller must hold rx_reorder_tbl_lock spinlock.
|
||||
*/
|
||||
static void
|
||||
mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
@@ -156,15 +157,22 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
{
|
||||
int i, j, xchg;
|
||||
void *rx_tmp_ptr;
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < tbl->win_size; ++i) {
|
||||
if (!tbl->rx_reorder_ptr[i])
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
if (!tbl->rx_reorder_ptr[i]) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
break;
|
||||
}
|
||||
rx_tmp_ptr = tbl->rx_reorder_ptr[i];
|
||||
tbl->rx_reorder_ptr[i] = NULL;
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
/*
|
||||
* We don't have a circular buffer, hence use rotation to simulate
|
||||
* circular buffer
|
||||
@@ -177,6 +185,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
}
|
||||
}
|
||||
tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -184,8 +193,6 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
*
|
||||
* The function stops the associated timer and dispatches all the
|
||||
* pending packets in the Rx reorder table before deletion.
|
||||
*
|
||||
* The caller must hold rx_reorder_tbl_lock spinlock.
|
||||
*/
|
||||
static void
|
||||
mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
|
||||
@@ -211,7 +218,11 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
|
||||
|
||||
del_timer_sync(&tbl->timer_context.timer);
|
||||
tbl->timer_context.timer_is_set = false;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
list_del(&tbl->list);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
kfree(tbl->rx_reorder_ptr);
|
||||
kfree(tbl);
|
||||
|
||||
@@ -224,17 +235,22 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
|
||||
/*
|
||||
* This function returns the pointer to an entry in Rx reordering
|
||||
* table which matches the given TA/TID pair.
|
||||
*
|
||||
* The caller must hold rx_reorder_tbl_lock spinlock.
|
||||
*/
|
||||
struct mwifiex_rx_reorder_tbl *
|
||||
mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
|
||||
{
|
||||
struct mwifiex_rx_reorder_tbl *tbl;
|
||||
unsigned long flags;
|
||||
|
||||
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
|
||||
if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid)
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) {
|
||||
if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
return tbl;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -251,9 +267,14 @@ void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
list_for_each_entry_safe(tbl, tmp, &priv->rx_reorder_tbl_ptr, list)
|
||||
if (!memcmp(tbl->ta, ta, ETH_ALEN))
|
||||
list_for_each_entry_safe(tbl, tmp, &priv->rx_reorder_tbl_ptr, list) {
|
||||
if (!memcmp(tbl->ta, ta, ETH_ALEN)) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
mwifiex_del_rx_reorder_entry(priv, tbl);
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
return;
|
||||
@@ -262,18 +283,24 @@ void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
|
||||
/*
|
||||
* This function finds the last sequence number used in the packets
|
||||
* buffered in Rx reordering table.
|
||||
*
|
||||
* The caller must hold rx_reorder_tbl_lock spinlock.
|
||||
*/
|
||||
static int
|
||||
mwifiex_11n_find_last_seq_num(struct reorder_tmr_cnxt *ctx)
|
||||
{
|
||||
struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr = ctx->ptr;
|
||||
struct mwifiex_private *priv = ctx->priv;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i)
|
||||
if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i) {
|
||||
if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -291,22 +318,17 @@ mwifiex_flush_data(struct timer_list *t)
|
||||
struct reorder_tmr_cnxt *ctx =
|
||||
from_timer(ctx, t, timer);
|
||||
int start_win, seq_num;
|
||||
unsigned long flags;
|
||||
|
||||
ctx->timer_is_set = false;
|
||||
spin_lock_irqsave(&ctx->priv->rx_reorder_tbl_lock, flags);
|
||||
seq_num = mwifiex_11n_find_last_seq_num(ctx);
|
||||
|
||||
if (seq_num < 0) {
|
||||
spin_unlock_irqrestore(&ctx->priv->rx_reorder_tbl_lock, flags);
|
||||
if (seq_num < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
mwifiex_dbg(ctx->priv->adapter, INFO, "info: flush data %d\n", seq_num);
|
||||
start_win = (ctx->ptr->start_win + seq_num + 1) & (MAX_TID_VALUE - 1);
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(ctx->priv, ctx->ptr,
|
||||
start_win);
|
||||
spin_unlock_irqrestore(&ctx->priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -333,14 +355,11 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
|
||||
* If we get a TID, ta pair which is already present dispatch all the
|
||||
* the packets and move the window size until the ssn
|
||||
*/
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
|
||||
if (tbl) {
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, seq_num);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
/* if !tbl then create one */
|
||||
new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL);
|
||||
if (!new_node)
|
||||
@@ -551,20 +570,16 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
|
||||
int prev_start_win, start_win, end_win, win_size;
|
||||
u16 pkt_index;
|
||||
bool init_window_shift = false;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
|
||||
if (!tbl) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
if (pkt_type != PKT_TYPE_BAR)
|
||||
mwifiex_11n_dispatch_pkt(priv, payload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((pkt_type == PKT_TYPE_AMSDU) && !tbl->amsdu) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
mwifiex_11n_dispatch_pkt(priv, payload);
|
||||
return ret;
|
||||
}
|
||||
@@ -651,8 +666,6 @@ done:
|
||||
if (!tbl->timer_context.timer_is_set ||
|
||||
prev_start_win != tbl->start_win)
|
||||
mwifiex_11n_rxreorder_timer_restart(tbl);
|
||||
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -681,18 +694,14 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
|
||||
peer_mac, tid, initiator);
|
||||
|
||||
if (cleanup_rx_reorder_tbl) {
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
|
||||
peer_mac);
|
||||
if (!tbl) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
mwifiex_dbg(priv->adapter, EVENT,
|
||||
"event: TID, TA not found in table\n");
|
||||
return;
|
||||
}
|
||||
mwifiex_del_rx_reorder_entry(priv, tbl);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
} else {
|
||||
ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac);
|
||||
if (!ptx_tbl) {
|
||||
@@ -726,7 +735,6 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
|
||||
int tid, win_size;
|
||||
struct mwifiex_rx_reorder_tbl *tbl;
|
||||
uint16_t block_ack_param_set;
|
||||
unsigned long flags;
|
||||
|
||||
block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
|
||||
|
||||
@@ -740,20 +748,17 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
|
||||
mwifiex_dbg(priv->adapter, ERROR, "ADDBA RSP: failed %pM tid=%d)\n",
|
||||
add_ba_rsp->peer_mac_addr, tid);
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
|
||||
add_ba_rsp->peer_mac_addr);
|
||||
if (tbl)
|
||||
mwifiex_del_rx_reorder_entry(priv, tbl);
|
||||
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
win_size = (block_ack_param_set & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
|
||||
>> BLOCKACKPARAM_WINSIZE_POS;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
|
||||
add_ba_rsp->peer_mac_addr);
|
||||
if (tbl) {
|
||||
@@ -764,7 +769,6 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
|
||||
else
|
||||
tbl->amsdu = false;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
mwifiex_dbg(priv->adapter, CMD,
|
||||
"cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n",
|
||||
@@ -804,8 +808,11 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
list_for_each_entry_safe(del_tbl_ptr, tmp_node,
|
||||
&priv->rx_reorder_tbl_ptr, list)
|
||||
&priv->rx_reorder_tbl_ptr, list) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
@@ -929,7 +936,6 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
|
||||
int tlv_buf_left = len;
|
||||
int ret;
|
||||
u8 *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
mwifiex_dbg_dump(priv->adapter, EVT_D, "RXBA_SYNC event:",
|
||||
event_buf, len);
|
||||
@@ -949,18 +955,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
|
||||
tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num,
|
||||
tlv_bitmap_len);
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
rx_reor_tbl_ptr =
|
||||
mwifiex_11n_get_rx_reorder_tbl(priv, tlv_rxba->tid,
|
||||
tlv_rxba->mac);
|
||||
if (!rx_reor_tbl_ptr) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
mwifiex_dbg(priv->adapter, ERROR,
|
||||
"Can not find rx_reorder_tbl!");
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
for (i = 0; i < tlv_bitmap_len; i++) {
|
||||
for (j = 0 ; j < 8; j++) {
|
||||
|
||||
@@ -421,15 +421,12 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
if (!priv->ap_11n_enabled ||
|
||||
(!mwifiex_11n_get_rx_reorder_tbl(priv, uap_rx_pd->priority, ta) &&
|
||||
(le16_to_cpu(uap_rx_pd->rx_pkt_type) != PKT_TYPE_AMSDU))) {
|
||||
ret = mwifiex_handle_uap_rx_forward(priv, skb);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
/* Reorder and send to kernel */
|
||||
pkt_type = (u8)le16_to_cpu(uap_rx_pd->rx_pkt_type);
|
||||
|
||||
@@ -2289,6 +2289,7 @@ void rtl_c2hcmd_enqueue(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
|
||||
if (rtl_c2h_fast_cmd(hw, skb)) {
|
||||
rtl_c2h_content_parsing(hw, skb);
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ static DEFINE_MUTEX(sd_ref_mutex);
|
||||
|
||||
static struct kmem_cache *sd_cdb_cache;
|
||||
static mempool_t *sd_cdb_pool;
|
||||
static mempool_t *sd_page_pool;
|
||||
|
||||
static const char *sd_cache_types[] = {
|
||||
"write through", "none", "write back",
|
||||
@@ -758,9 +759,10 @@ static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
|
||||
unsigned int data_len = 24;
|
||||
char *buf;
|
||||
|
||||
rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
|
||||
rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
|
||||
if (!rq->special_vec.bv_page)
|
||||
return BLKPREP_DEFER;
|
||||
clear_highpage(rq->special_vec.bv_page);
|
||||
rq->special_vec.bv_offset = 0;
|
||||
rq->special_vec.bv_len = data_len;
|
||||
rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
|
||||
@@ -791,9 +793,10 @@ static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap)
|
||||
u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
|
||||
u32 data_len = sdp->sector_size;
|
||||
|
||||
rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
|
||||
rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
|
||||
if (!rq->special_vec.bv_page)
|
||||
return BLKPREP_DEFER;
|
||||
clear_highpage(rq->special_vec.bv_page);
|
||||
rq->special_vec.bv_offset = 0;
|
||||
rq->special_vec.bv_len = data_len;
|
||||
rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
|
||||
@@ -821,9 +824,10 @@ static int sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap)
|
||||
u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
|
||||
u32 data_len = sdp->sector_size;
|
||||
|
||||
rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
|
||||
rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
|
||||
if (!rq->special_vec.bv_page)
|
||||
return BLKPREP_DEFER;
|
||||
clear_highpage(rq->special_vec.bv_page);
|
||||
rq->special_vec.bv_offset = 0;
|
||||
rq->special_vec.bv_len = data_len;
|
||||
rq->rq_flags |= RQF_SPECIAL_PAYLOAD;
|
||||
@@ -1287,7 +1291,7 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
|
||||
u8 *cmnd;
|
||||
|
||||
if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
|
||||
__free_page(rq->special_vec.bv_page);
|
||||
mempool_free(rq->special_vec.bv_page, sd_page_pool);
|
||||
|
||||
if (SCpnt->cmnd != scsi_req(rq)->cmd) {
|
||||
cmnd = SCpnt->cmnd;
|
||||
@@ -3635,6 +3639,13 @@ static int __init init_sd(void)
|
||||
goto err_out_cache;
|
||||
}
|
||||
|
||||
sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
|
||||
if (!sd_page_pool) {
|
||||
printk(KERN_ERR "sd: can't init discard page pool\n");
|
||||
err = -ENOMEM;
|
||||
goto err_out_ppool;
|
||||
}
|
||||
|
||||
err = scsi_register_driver(&sd_template.gendrv);
|
||||
if (err)
|
||||
goto err_out_driver;
|
||||
@@ -3642,6 +3653,9 @@ static int __init init_sd(void)
|
||||
return 0;
|
||||
|
||||
err_out_driver:
|
||||
mempool_destroy(sd_page_pool);
|
||||
|
||||
err_out_ppool:
|
||||
mempool_destroy(sd_cdb_pool);
|
||||
|
||||
err_out_cache:
|
||||
@@ -3668,6 +3682,7 @@ static void __exit exit_sd(void)
|
||||
|
||||
scsi_unregister_driver(&sd_template.gendrv);
|
||||
mempool_destroy(sd_cdb_pool);
|
||||
mempool_destroy(sd_page_pool);
|
||||
kmem_cache_destroy(sd_cdb_cache);
|
||||
|
||||
class_unregister(&sd_disk_class);
|
||||
|
||||
@@ -1507,7 +1507,8 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
|
||||
portsc_buf[port_index] = 0;
|
||||
|
||||
/* Bail out if a USB3 port has a new device in link training */
|
||||
if ((t1 & PORT_PLS_MASK) == XDEV_POLLING) {
|
||||
if ((hcd->speed >= HCD_USB3) &&
|
||||
(t1 & PORT_PLS_MASK) == XDEV_POLLING) {
|
||||
bus_state->bus_suspended = 0;
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_dbg(xhci, "Bus suspend bailout, port in polling\n");
|
||||
|
||||
@@ -1860,6 +1860,8 @@ struct xhci_hcd {
|
||||
unsigned sw_lpm_support:1;
|
||||
/* support xHCI 1.0 spec USB2 hardware LPM */
|
||||
unsigned hw_lpm_support:1;
|
||||
/* Broken Suspend flag for SNPS Suspend resume issue */
|
||||
unsigned broken_suspend:1;
|
||||
/* cached usb2 extened protocol capabilites */
|
||||
u32 *ext_caps;
|
||||
unsigned int num_ext_caps;
|
||||
@@ -1877,8 +1879,6 @@ struct xhci_hcd {
|
||||
void *dbc;
|
||||
/* platform-specific data -- must come last */
|
||||
unsigned long priv[0] __aligned(sizeof(s64));
|
||||
/* Broken Suspend flag for SNPS Suspend resume issue */
|
||||
u8 broken_suspend;
|
||||
};
|
||||
|
||||
/* Platform specific overrides to generic XHCI hc_driver ops */
|
||||
|
||||
@@ -1164,6 +1164,10 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1900), /* Telit LN940 (QMI) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
|
||||
.driver_info = RSVD(1) },
|
||||
@@ -1328,6 +1332,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(4) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0602, 0xff) }, /* GosunCn ZTE WeLink ME3630 (MBIM mode) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
|
||||
.driver_info = RSVD(4) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
|
||||
@@ -1531,6 +1536,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(2) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */
|
||||
.driver_info = RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) },
|
||||
@@ -1758,6 +1764,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
|
||||
.driver_info = RSVD(5) | RSVD(6) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */
|
||||
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
|
||||
.driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) },
|
||||
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D),
|
||||
@@ -1940,7 +1947,14 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD200, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* HP lt2523 (Novatel E371) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* HP lt2523 (Novatel E371) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x10) }, /* HP lt4132 (Huawei ME906s-158) */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x12) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x13) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x14) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x1b) },
|
||||
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 */
|
||||
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
||||
@@ -117,12 +117,6 @@ iomap_page_create(struct inode *inode, struct page *page)
|
||||
atomic_set(&iop->read_count, 0);
|
||||
atomic_set(&iop->write_count, 0);
|
||||
bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE);
|
||||
|
||||
/*
|
||||
* migrate_page_move_mapping() assumes that pages with private data have
|
||||
* their count elevated by 1.
|
||||
*/
|
||||
get_page(page);
|
||||
set_page_private(page, (unsigned long)iop);
|
||||
SetPagePrivate(page);
|
||||
return iop;
|
||||
@@ -139,7 +133,6 @@ iomap_page_release(struct page *page)
|
||||
WARN_ON_ONCE(atomic_read(&iop->write_count));
|
||||
ClearPagePrivate(page);
|
||||
set_page_private(page, 0);
|
||||
put_page(page);
|
||||
kfree(iop);
|
||||
}
|
||||
|
||||
|
||||
@@ -3735,8 +3735,7 @@ int vfs_mknod2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, u
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if ((S_ISCHR(mode) || S_ISBLK(mode)) &&
|
||||
!ns_capable(dentry->d_sb->s_user_ns, CAP_MKNOD))
|
||||
if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
|
||||
return -EPERM;
|
||||
|
||||
if (!dir->i_op->mknod)
|
||||
|
||||
@@ -464,7 +464,7 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
|
||||
|
||||
inode = new_inode(sb);
|
||||
if (!inode)
|
||||
goto out;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
inode->i_ino = get_next_ino();
|
||||
|
||||
@@ -474,8 +474,7 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
|
||||
if (unlikely(head->unregistering)) {
|
||||
spin_unlock(&sysctl_lock);
|
||||
iput(inode);
|
||||
inode = NULL;
|
||||
goto out;
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
ei->sysctl = head;
|
||||
ei->sysctl_entry = table;
|
||||
@@ -500,7 +499,6 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
|
||||
if (root->set_ownership)
|
||||
root->set_ownership(head, table, &inode->i_uid, &inode->i_gid);
|
||||
|
||||
out:
|
||||
return inode;
|
||||
}
|
||||
|
||||
@@ -549,10 +547,11 @@ static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = ERR_PTR(-ENOMEM);
|
||||
inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
|
||||
if (!inode)
|
||||
if (IS_ERR(inode)) {
|
||||
err = ERR_CAST(inode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
d_set_d_op(dentry, &proc_sys_dentry_operations);
|
||||
err = d_splice_alias(inode, dentry);
|
||||
@@ -685,7 +684,7 @@ static bool proc_sys_fill_cache(struct file *file,
|
||||
if (d_in_lookup(child)) {
|
||||
struct dentry *res;
|
||||
inode = proc_sys_make_inode(dir->d_sb, head, table);
|
||||
if (!inode) {
|
||||
if (IS_ERR(inode)) {
|
||||
d_lookup_done(child);
|
||||
dput(child);
|
||||
return false;
|
||||
|
||||
@@ -209,6 +209,38 @@ static int trun_remove_range(struct ubifs_info *c, struct replay_entry *r)
|
||||
return ubifs_tnc_remove_range(c, &min_key, &max_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* inode_still_linked - check whether inode in question will be re-linked.
|
||||
* @c: UBIFS file-system description object
|
||||
* @rino: replay entry to test
|
||||
*
|
||||
* O_TMPFILE files can be re-linked, this means link count goes from 0 to 1.
|
||||
* This case needs special care, otherwise all references to the inode will
|
||||
* be removed upon the first replay entry of an inode with link count 0
|
||||
* is found.
|
||||
*/
|
||||
static bool inode_still_linked(struct ubifs_info *c, struct replay_entry *rino)
|
||||
{
|
||||
struct replay_entry *r;
|
||||
|
||||
ubifs_assert(c, rino->deletion);
|
||||
ubifs_assert(c, key_type(c, &rino->key) == UBIFS_INO_KEY);
|
||||
|
||||
/*
|
||||
* Find the most recent entry for the inode behind @rino and check
|
||||
* whether it is a deletion.
|
||||
*/
|
||||
list_for_each_entry_reverse(r, &c->replay_list, list) {
|
||||
ubifs_assert(c, r->sqnum >= rino->sqnum);
|
||||
if (key_inum(c, &r->key) == key_inum(c, &rino->key))
|
||||
return r->deletion == 0;
|
||||
|
||||
}
|
||||
|
||||
ubifs_assert(c, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* apply_replay_entry - apply a replay entry to the TNC.
|
||||
* @c: UBIFS file-system description object
|
||||
@@ -236,6 +268,11 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
|
||||
{
|
||||
ino_t inum = key_inum(c, &r->key);
|
||||
|
||||
if (inode_still_linked(c, r)) {
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
err = ubifs_tnc_remove_ino(c, inum);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define _4LEVEL_FIXUP_H
|
||||
|
||||
#define __ARCH_HAS_4LEVEL_HACK
|
||||
#define __PAGETABLE_PUD_FOLDED
|
||||
#define __PAGETABLE_PUD_FOLDED 1
|
||||
|
||||
#define PUD_SHIFT PGDIR_SHIFT
|
||||
#define PUD_SIZE PGDIR_SIZE
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define _5LEVEL_FIXUP_H
|
||||
|
||||
#define __ARCH_HAS_5LEVEL_HACK
|
||||
#define __PAGETABLE_P4D_FOLDED
|
||||
#define __PAGETABLE_P4D_FOLDED 1
|
||||
|
||||
#define P4D_SHIFT PGDIR_SHIFT
|
||||
#define P4D_SIZE PGDIR_SIZE
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm-generic/5level-fixup.h>
|
||||
|
||||
#define __PAGETABLE_PUD_FOLDED
|
||||
#define __PAGETABLE_PUD_FOLDED 1
|
||||
|
||||
/*
|
||||
* Having the pud type consist of a pgd gets the size right, and allows
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define __PAGETABLE_P4D_FOLDED
|
||||
#define __PAGETABLE_P4D_FOLDED 1
|
||||
|
||||
typedef struct { pgd_t pgd; } p4d_t;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
struct mm_struct;
|
||||
|
||||
#define __PAGETABLE_PMD_FOLDED
|
||||
#define __PAGETABLE_PMD_FOLDED 1
|
||||
|
||||
/*
|
||||
* Having the pmd type consist of a pud gets the size right, and allows
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#else
|
||||
#include <asm-generic/pgtable-nop4d.h>
|
||||
|
||||
#define __PAGETABLE_PUD_FOLDED
|
||||
#define __PAGETABLE_PUD_FOLDED 1
|
||||
|
||||
/*
|
||||
* Having the pud type consist of a p4d gets the size right, and allows
|
||||
|
||||
@@ -1127,4 +1127,20 @@ static inline bool arch_has_pfn_modify_check(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On some architectures it depends on the mm if the p4d/pud or pmd
|
||||
* layer of the page table hierarchy is folded or not.
|
||||
*/
|
||||
#ifndef mm_p4d_folded
|
||||
#define mm_p4d_folded(mm) __is_defined(__PAGETABLE_P4D_FOLDED)
|
||||
#endif
|
||||
|
||||
#ifndef mm_pud_folded
|
||||
#define mm_pud_folded(mm) __is_defined(__PAGETABLE_PUD_FOLDED)
|
||||
#endif
|
||||
|
||||
#ifndef mm_pmd_folded
|
||||
#define mm_pmd_folded(mm) __is_defined(__PAGETABLE_PMD_FOLDED)
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_GENERIC_PGTABLE_H */
|
||||
|
||||
@@ -281,4 +281,7 @@ static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor)
|
||||
}
|
||||
#endif /* mul_u64_u32_div */
|
||||
|
||||
#define DIV64_U64_ROUND_UP(ll, d) \
|
||||
({ u64 _tmp = (d); div64_u64((ll) + _tmp - 1, _tmp); })
|
||||
|
||||
#endif /* _LINUX_MATH64_H */
|
||||
|
||||
@@ -1724,11 +1724,15 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address);
|
||||
|
||||
static inline void mm_inc_nr_puds(struct mm_struct *mm)
|
||||
{
|
||||
if (mm_pud_folded(mm))
|
||||
return;
|
||||
atomic_long_add(PTRS_PER_PUD * sizeof(pud_t), &mm->pgtables_bytes);
|
||||
}
|
||||
|
||||
static inline void mm_dec_nr_puds(struct mm_struct *mm)
|
||||
{
|
||||
if (mm_pud_folded(mm))
|
||||
return;
|
||||
atomic_long_sub(PTRS_PER_PUD * sizeof(pud_t), &mm->pgtables_bytes);
|
||||
}
|
||||
#endif
|
||||
@@ -1748,11 +1752,15 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
|
||||
|
||||
static inline void mm_inc_nr_pmds(struct mm_struct *mm)
|
||||
{
|
||||
if (mm_pmd_folded(mm))
|
||||
return;
|
||||
atomic_long_add(PTRS_PER_PMD * sizeof(pmd_t), &mm->pgtables_bytes);
|
||||
}
|
||||
|
||||
static inline void mm_dec_nr_pmds(struct mm_struct *mm)
|
||||
{
|
||||
if (mm_pmd_folded(mm))
|
||||
return;
|
||||
atomic_long_sub(PTRS_PER_PMD * sizeof(pmd_t), &mm->pgtables_bytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,12 +39,13 @@ struct t10_pi_tuple {
|
||||
|
||||
static inline u32 t10_pi_ref_tag(struct request *rq)
|
||||
{
|
||||
unsigned int shift = ilog2(queue_logical_block_size(rq->q));
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
||||
return blk_rq_pos(rq) >>
|
||||
(rq->q->integrity.interval_exp - 9) & 0xffffffff;
|
||||
#else
|
||||
return -1U;
|
||||
if (rq->q->integrity.interval_exp)
|
||||
shift = rq->q->integrity.interval_exp;
|
||||
#endif
|
||||
return blk_rq_pos(rq) >> (shift - SECTOR_SHIFT) & 0xffffffff;
|
||||
}
|
||||
|
||||
extern const struct blk_integrity_profile t10_pi_type1_crc;
|
||||
|
||||
@@ -1552,6 +1552,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk,
|
||||
int (*func)(struct xfrm_state *, int, void*), void *);
|
||||
void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
|
||||
struct xfrm_state *xfrm_state_alloc(struct net *net);
|
||||
void xfrm_state_free(struct xfrm_state *x);
|
||||
struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
|
||||
const xfrm_address_t *saddr,
|
||||
const struct flowi *fl,
|
||||
|
||||
@@ -1148,11 +1148,65 @@ out_error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int handle_exit_race(u32 __user *uaddr, u32 uval,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
u32 uval2;
|
||||
|
||||
/*
|
||||
* If PF_EXITPIDONE is not yet set, then try again.
|
||||
*/
|
||||
if (tsk && !(tsk->flags & PF_EXITPIDONE))
|
||||
return -EAGAIN;
|
||||
|
||||
/*
|
||||
* Reread the user space value to handle the following situation:
|
||||
*
|
||||
* CPU0 CPU1
|
||||
*
|
||||
* sys_exit() sys_futex()
|
||||
* do_exit() futex_lock_pi()
|
||||
* futex_lock_pi_atomic()
|
||||
* exit_signals(tsk) No waiters:
|
||||
* tsk->flags |= PF_EXITING; *uaddr == 0x00000PID
|
||||
* mm_release(tsk) Set waiter bit
|
||||
* exit_robust_list(tsk) { *uaddr = 0x80000PID;
|
||||
* Set owner died attach_to_pi_owner() {
|
||||
* *uaddr = 0xC0000000; tsk = get_task(PID);
|
||||
* } if (!tsk->flags & PF_EXITING) {
|
||||
* ... attach();
|
||||
* tsk->flags |= PF_EXITPIDONE; } else {
|
||||
* if (!(tsk->flags & PF_EXITPIDONE))
|
||||
* return -EAGAIN;
|
||||
* return -ESRCH; <--- FAIL
|
||||
* }
|
||||
*
|
||||
* Returning ESRCH unconditionally is wrong here because the
|
||||
* user space value has been changed by the exiting task.
|
||||
*
|
||||
* The same logic applies to the case where the exiting task is
|
||||
* already gone.
|
||||
*/
|
||||
if (get_futex_value_locked(&uval2, uaddr))
|
||||
return -EFAULT;
|
||||
|
||||
/* If the user space value has changed, try again. */
|
||||
if (uval2 != uval)
|
||||
return -EAGAIN;
|
||||
|
||||
/*
|
||||
* The exiting task did not have a robust list, the robust list was
|
||||
* corrupted or the user space value in *uaddr is simply bogus.
|
||||
* Give up and tell user space.
|
||||
*/
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the task for the TID provided from user space and attach to
|
||||
* it after doing proper sanity checks.
|
||||
*/
|
||||
static int attach_to_pi_owner(u32 uval, union futex_key *key,
|
||||
static int attach_to_pi_owner(u32 __user *uaddr, u32 uval, union futex_key *key,
|
||||
struct futex_pi_state **ps)
|
||||
{
|
||||
pid_t pid = uval & FUTEX_TID_MASK;
|
||||
@@ -1162,12 +1216,15 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key,
|
||||
/*
|
||||
* We are the first waiter - try to look up the real owner and attach
|
||||
* the new pi_state to it, but bail out when TID = 0 [1]
|
||||
*
|
||||
* The !pid check is paranoid. None of the call sites should end up
|
||||
* with pid == 0, but better safe than sorry. Let the caller retry
|
||||
*/
|
||||
if (!pid)
|
||||
return -ESRCH;
|
||||
return -EAGAIN;
|
||||
p = find_get_task_by_vpid(pid);
|
||||
if (!p)
|
||||
return -ESRCH;
|
||||
return handle_exit_race(uaddr, uval, NULL);
|
||||
|
||||
if (unlikely(p->flags & PF_KTHREAD)) {
|
||||
put_task_struct(p);
|
||||
@@ -1187,7 +1244,7 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key,
|
||||
* set, we know that the task has finished the
|
||||
* cleanup:
|
||||
*/
|
||||
int ret = (p->flags & PF_EXITPIDONE) ? -ESRCH : -EAGAIN;
|
||||
int ret = handle_exit_race(uaddr, uval, p);
|
||||
|
||||
raw_spin_unlock_irq(&p->pi_lock);
|
||||
put_task_struct(p);
|
||||
@@ -1244,7 +1301,7 @@ static int lookup_pi_state(u32 __user *uaddr, u32 uval,
|
||||
* We are the first waiter - try to look up the owner based on
|
||||
* @uval and attach to it.
|
||||
*/
|
||||
return attach_to_pi_owner(uval, key, ps);
|
||||
return attach_to_pi_owner(uaddr, uval, key, ps);
|
||||
}
|
||||
|
||||
static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval)
|
||||
@@ -1352,7 +1409,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
|
||||
* attach to the owner. If that fails, no harm done, we only
|
||||
* set the FUTEX_WAITERS bit in the user space variable.
|
||||
*/
|
||||
return attach_to_pi_owner(uval, key, ps);
|
||||
return attach_to_pi_owner(uaddr, newval, key, ps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/kmsg_dump.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/vt_kern.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/ftrace.h>
|
||||
@@ -233,7 +234,10 @@ void panic(const char *fmt, ...)
|
||||
if (_crash_kexec_post_notifiers)
|
||||
__crash_kexec(NULL);
|
||||
|
||||
bust_spinlocks(0);
|
||||
#ifdef CONFIG_VT
|
||||
unblank_screen();
|
||||
#endif
|
||||
console_unblank();
|
||||
|
||||
/*
|
||||
* We may have ended up stopping the CPU holding the lock (in
|
||||
|
||||
@@ -289,9 +289,6 @@ static void common_hrtimer_rearm(struct k_itimer *timr)
|
||||
{
|
||||
struct hrtimer *timer = &timr->it.real.timer;
|
||||
|
||||
if (!timr->it_interval)
|
||||
return;
|
||||
|
||||
timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(),
|
||||
timr->it_interval);
|
||||
hrtimer_restart(timer);
|
||||
@@ -317,7 +314,7 @@ void posixtimer_rearm(struct siginfo *info)
|
||||
if (!timr)
|
||||
return;
|
||||
|
||||
if (timr->it_requeue_pending == info->si_sys_private) {
|
||||
if (timr->it_interval && timr->it_requeue_pending == info->si_sys_private) {
|
||||
timr->kclock->timer_rearm(timr);
|
||||
|
||||
timr->it_active = 1;
|
||||
|
||||
@@ -2127,23 +2127,25 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
||||
*/
|
||||
old_pmd = pmdp_invalidate(vma, haddr, pmd);
|
||||
|
||||
#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
|
||||
pmd_migration = is_pmd_migration_entry(old_pmd);
|
||||
if (pmd_migration) {
|
||||
if (unlikely(pmd_migration)) {
|
||||
swp_entry_t entry;
|
||||
|
||||
entry = pmd_to_swp_entry(old_pmd);
|
||||
page = pfn_to_page(swp_offset(entry));
|
||||
} else
|
||||
#endif
|
||||
write = is_write_migration_entry(entry);
|
||||
young = false;
|
||||
soft_dirty = pmd_swp_soft_dirty(old_pmd);
|
||||
} else {
|
||||
page = pmd_page(old_pmd);
|
||||
if (pmd_dirty(old_pmd))
|
||||
SetPageDirty(page);
|
||||
write = pmd_write(old_pmd);
|
||||
young = pmd_young(old_pmd);
|
||||
soft_dirty = pmd_soft_dirty(old_pmd);
|
||||
}
|
||||
VM_BUG_ON_PAGE(!page_count(page), page);
|
||||
page_ref_add(page, HPAGE_PMD_NR - 1);
|
||||
if (pmd_dirty(old_pmd))
|
||||
SetPageDirty(page);
|
||||
write = pmd_write(old_pmd);
|
||||
young = pmd_young(old_pmd);
|
||||
soft_dirty = pmd_soft_dirty(old_pmd);
|
||||
|
||||
/*
|
||||
* Withdraw the table only after we mark the pmd entry invalid.
|
||||
|
||||
@@ -5550,6 +5550,18 @@ not_early:
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SPARSEMEM
|
||||
/*
|
||||
* If the zone does not span the rest of the section then
|
||||
* we should at least initialize those pages. Otherwise we
|
||||
* could blow up on a poisoned page in some paths which depend
|
||||
* on full sections being initialized (e.g. memory hotplug).
|
||||
*/
|
||||
while (end_pfn % PAGES_PER_SECTION) {
|
||||
__init_single_page(pfn_to_page(end_pfn), end_pfn, zone, nid);
|
||||
end_pfn++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __meminit zone_init_free_lists(struct zone *zone)
|
||||
@@ -7722,11 +7734,14 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
|
||||
* handle each tail page individually in migration.
|
||||
*/
|
||||
if (PageHuge(page)) {
|
||||
struct page *head = compound_head(page);
|
||||
unsigned int skip_pages;
|
||||
|
||||
if (!hugepage_migration_supported(page_hstate(page)))
|
||||
if (!hugepage_migration_supported(page_hstate(head)))
|
||||
goto unmovable;
|
||||
|
||||
iter = round_up(iter + 1, 1<<compound_order(page)) - 1;
|
||||
skip_pages = (1 << compound_order(head)) - (page - head);
|
||||
iter += skip_pages - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -2456,9 +2456,11 @@ out:
|
||||
/*
|
||||
* Scan types proportional to swappiness and
|
||||
* their relative recent reclaim efficiency.
|
||||
* Make sure we don't miss the last page
|
||||
* because of a round-off error.
|
||||
*/
|
||||
scan = div64_u64(scan * fraction[file],
|
||||
denominator);
|
||||
scan = DIV64_U64_ROUND_UP(scan * fraction[file],
|
||||
denominator);
|
||||
break;
|
||||
case SCAN_FILE:
|
||||
case SCAN_ANON:
|
||||
|
||||
@@ -426,6 +426,12 @@ static void xfrm_put_mode(struct xfrm_mode *mode)
|
||||
module_put(mode->owner);
|
||||
}
|
||||
|
||||
void xfrm_state_free(struct xfrm_state *x)
|
||||
{
|
||||
kmem_cache_free(xfrm_state_cache, x);
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_state_free);
|
||||
|
||||
static void xfrm_state_gc_destroy(struct xfrm_state *x)
|
||||
{
|
||||
tasklet_hrtimer_cancel(&x->mtimer);
|
||||
@@ -452,7 +458,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
|
||||
}
|
||||
xfrm_dev_state_free(x);
|
||||
security_xfrm_state_free(x);
|
||||
kmem_cache_free(xfrm_state_cache, x);
|
||||
xfrm_state_free(x);
|
||||
}
|
||||
|
||||
static void xfrm_state_gc_task(struct work_struct *work)
|
||||
|
||||
@@ -2288,13 +2288,13 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
||||
}
|
||||
|
||||
kfree(x);
|
||||
xfrm_state_free(x);
|
||||
kfree(xp);
|
||||
|
||||
return 0;
|
||||
|
||||
free_state:
|
||||
kfree(x);
|
||||
xfrm_state_free(x);
|
||||
nomem:
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user