mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-04 18:19:28 +09:00
Merge 6.1.140 into android14-6.1-lts
Changes in 6.1.140 binfmt: Fix whitespace issues binfmt_elf: Support segments with 0 filesz and misaligned starts binfmt_elf: elf_bss no longer used by load_elf_binary() selftests/exec: load_address: conform test to TAP format output binfmt_elf: Leave a gap between .bss and brk selftests/exec: Build both static and non-static load_address tests binfmt_elf: Calculate total_size earlier binfmt_elf: Honor PT_LOAD alignment for static PIE binfmt_elf: Move brk for static PIE even if ASLR disabled platform/x86: asus-wmi: Fix wlan_ctrl_by_user detection tracing: probes: Fix a possible race in trace_probe_log APIs tpm: tis: Double the timeout B to 4s iio: adc: ad7266: Fix potential timestamp alignment issue. drm/amd: Stop evicting resources on APUs in suspend drm/amdgpu: Fix the runtime resume failure issue drm/amdgpu: trigger flr_work if reading pf2vf data failed drm/amd: Add Suspend/Hibernate notification callback support Revert "drm/amd: Stop evicting resources on APUs in suspend" iio: adc: ad7768-1: Fix insufficient alignment of timestamp. iio: chemical: sps30: use aligned_s64 for timestamp clocksource/i8253: Use raw_spinlock_irqsave() in clockevent_i8253_disable() RDMA/rxe: Fix slab-use-after-free Read in rxe_queue_cleanup bug HID: thrustmaster: fix memory leak in thrustmaster_interrupts() HID: uclogic: Add NULL check in uclogic_input_configured() nfs: handle failure of nfs_get_lock_context in unlock path spi: loopback-test: Do not split 1024-byte hexdumps net_sched: Flush gso_skb list too during ->change() net: mctp: Ensure keys maintain only one ref to corresponding dev net: cadence: macb: Fix a possible deadlock in macb_halt_tx. net: dsa: sja1105: discard incoming frames in BR_STATE_LISTENING nvme-pci: make nvme_pci_npages_prp() __always_inline nvme-pci: acquire cq_poll_lock in nvme_poll_irqdisable ALSA: sh: SND_AICA should depend on SH_DMA_API net/mlx5e: Disable MACsec offload for uplink representor profile qlcnic: fix memory leak in qlcnic_sriov_channel_cfg_cmd() regulator: max20086: fix invalid memory access octeontx2-pf: macsec: Fix incorrect max transmit size in TX secy net/tls: fix kernel panic when alloc_page failed NFSv4/pnfs: Reset the layout state after a layoutreturn dmaengine: Revert "dmaengine: dmatest: Fix dmatest waiting less when interrupted" LoongArch: Fix MAX_REG_OFFSET calculation btrfs: fix discard worker infinite loop after disabling discard drm/amd/display: Correct the reply value when AUX write incomplete drm/amd/display: Avoid flooding unnecessary info messages ACPI: PPTT: Fix processor subtable walk ALSA: es1968: Add error handling for snd_pcm_hw_constraint_pow2() ALSA: usb-audio: Add sample rate quirk for Audioengine D1 ALSA: usb-audio: Add sample rate quirk for Microdia JP001 USB Camera dma-buf: insert memory barrier before updating num_fences hv_netvsc: Use vmbus_sendpacket_mpb_desc() to send VMBus messages hv_netvsc: Preserve contiguous PFN grouping in the page buffer array hv_netvsc: Remove rmsg_pgcnt Drivers: hv: Allow vmbus_sendpacket_mpb_desc() to create multiple ranges Drivers: hv: vmbus: Remove vmbus_sendpacket_pagebuffer() ftrace: Fix preemption accounting for stacktrace trigger command ftrace: Fix preemption accounting for stacktrace filter command tracing: samples: Initialize trace_array_printk() with the correct function phy: Fix error handling in tegra_xusb_port_init phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind phy: renesas: rcar-gen3-usb2: Set timing registers only once scsi: sd_zbc: block: Respect bio vector limits for REPORT ZONES buffer smb: client: fix memory leak during error handling for POSIX mkdir wifi: mt76: disable napi on driver removal net: qede: Initialize qede_ll_ops with designated initializer dmaengine: ti: k3-udma: Add missing locking dmaengine: ti: k3-udma: Use cap_mask directly from dma_device structure instead of a local copy dmaengine: idxd: fix memory leak in error handling path of idxd_setup_wqs dmaengine: idxd: fix memory leak in error handling path of idxd_setup_engines dmaengine: idxd: fix memory leak in error handling path of idxd_setup_groups dmaengine: idxd: Add missing cleanup for early error out in idxd_setup_internals dmaengine: idxd: Add missing cleanups in cleanup internals dmaengine: idxd: Add missing idxd cleanup to fix memory leak in remove call dmaengine: idxd: fix memory leak in error handling path of idxd_alloc dmaengine: idxd: fix memory leak in error handling path of idxd_pci_probe usb: typec: ucsi: displayport: Fix deadlock usb: typec: altmodes/displayport: create sysfs nodes as driver's default device attribute group usb: typec: fix potential array underflow in ucsi_ccg_sync_control() usb: typec: fix pm usage counter imbalance in ucsi_ccg_sync_control() selftests/mm: compaction_test: support platform with huge mount of memory mm/vmscan: fix a bug calling wakeup_kswapd() with a wrong zone index riscv: mm: Fix the out of bound issue of vmemmap address bpf, arm64: Fix trampoline for BPF_TRAMP_F_CALL_ORIG bpf, arm64: Fix address emission with tag-based KASAN enabled LoongArch: Explicitly specify code model in Makefile hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio sctp: add mutual exclusion in proc_sctp_do_udp_port() btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info() netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx netfilter: nf_tables: wait for rcu grace period on net_device removal netfilter: nf_tables: do not defer rule destruction via call_rcu arm64/sme: Always exit sme_alloc() early with existing storage platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled it bnxt_en: Fix receive ring space parameters when XDP is active ipv6: Fix potential uninit-value access in __ip6_make_skb() ipv4: Fix uninit-value access in __ip_make_skb() spi: cadence-qspi: fix pointer reference in runtime PM hooks drm/amdgpu: fix pm notifier handling x86/modules: Set VM_FLUSH_RESET_PERMS in module_alloc() Linux 6.1.140 Change-Id: Ieb4e51eea0bf366d869913439bc2a4c35d77334c 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 = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 139
|
||||
SUBLEVEL = 140
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
||||
@@ -1234,8 +1234,10 @@ void fpsimd_release_task(struct task_struct *dead_task)
|
||||
*/
|
||||
void sme_alloc(struct task_struct *task, bool flush)
|
||||
{
|
||||
if (task->thread.za_state && flush) {
|
||||
memset(task->thread.za_state, 0, za_state_size(task));
|
||||
if (task->thread.za_state) {
|
||||
if (flush)
|
||||
memset(task->thread.za_state, 0,
|
||||
za_state_size(task));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1942,7 +1942,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
|
||||
emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx);
|
||||
|
||||
if (flags & BPF_TRAMP_F_CALL_ORIG) {
|
||||
emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
|
||||
/* for the first pass, assume the worst case */
|
||||
if (!ctx->image)
|
||||
ctx->idx += 4;
|
||||
else
|
||||
emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
|
||||
emit_call((const u64)__bpf_tramp_enter, ctx);
|
||||
}
|
||||
|
||||
@@ -1986,7 +1990,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
|
||||
|
||||
if (flags & BPF_TRAMP_F_CALL_ORIG) {
|
||||
im->ip_epilogue = ctx->image + ctx->idx;
|
||||
emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
|
||||
/* for the first pass, assume the worst case */
|
||||
if (!ctx->image)
|
||||
ctx->idx += 4;
|
||||
else
|
||||
emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
|
||||
emit_call((const u64)__bpf_tramp_exit, ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ endif
|
||||
|
||||
ifdef CONFIG_64BIT
|
||||
ld-emul = $(64bit-emul)
|
||||
cflags-y += -mabi=lp64s
|
||||
cflags-y += -mabi=lp64s -mcmodel=normal
|
||||
endif
|
||||
|
||||
cflags-y += -pipe -msoft-float
|
||||
|
||||
@@ -54,7 +54,7 @@ static inline void instruction_pointer_set(struct pt_regs *regs, unsigned long v
|
||||
|
||||
/* Query offset/name of register from its name/offset */
|
||||
extern int regs_query_register_offset(const char *name);
|
||||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
|
||||
#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last) - sizeof(unsigned long))
|
||||
|
||||
/**
|
||||
* regs_get_register() - get register value from its offset
|
||||
|
||||
@@ -115,6 +115,7 @@ struct kernel_mapping {
|
||||
|
||||
extern struct kernel_mapping kernel_map;
|
||||
extern phys_addr_t phys_ram_base;
|
||||
extern unsigned long vmemmap_start_pfn;
|
||||
|
||||
#define is_kernel_mapping(x) \
|
||||
((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
* Define vmemmap for pfn_to_page & page_to_pfn calls. Needed if kernel
|
||||
* is configured with CONFIG_SPARSEMEM_VMEMMAP enabled.
|
||||
*/
|
||||
#define vmemmap ((struct page *)VMEMMAP_START - (phys_ram_base >> PAGE_SHIFT))
|
||||
#define vmemmap ((struct page *)VMEMMAP_START - vmemmap_start_pfn)
|
||||
|
||||
#define PCI_IO_SIZE SZ_16M
|
||||
#define PCI_IO_END VMEMMAP_START
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/hugetlb.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/sparsemem.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/soc.h>
|
||||
@@ -52,6 +53,13 @@ EXPORT_SYMBOL(pgtable_l5_enabled);
|
||||
phys_addr_t phys_ram_base __ro_after_init;
|
||||
EXPORT_SYMBOL(phys_ram_base);
|
||||
|
||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
#define VMEMMAP_ADDR_ALIGN (1ULL << SECTION_SIZE_BITS)
|
||||
|
||||
unsigned long vmemmap_start_pfn __ro_after_init;
|
||||
EXPORT_SYMBOL(vmemmap_start_pfn);
|
||||
#endif
|
||||
|
||||
unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
|
||||
__page_aligned_bss;
|
||||
EXPORT_SYMBOL(empty_zero_page);
|
||||
@@ -210,8 +218,12 @@ static void __init setup_bootmem(void)
|
||||
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
|
||||
|
||||
phys_ram_end = memblock_end_of_DRAM();
|
||||
if (!IS_ENABLED(CONFIG_XIP_KERNEL))
|
||||
if (!IS_ENABLED(CONFIG_XIP_KERNEL)) {
|
||||
phys_ram_base = memblock_start_of_DRAM();
|
||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Reserve physical address space that would be mapped to virtual
|
||||
* addresses greater than (void *)(-PAGE_SIZE) because:
|
||||
@@ -946,6 +958,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
|
||||
kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);
|
||||
|
||||
phys_ram_base = CONFIG_PHYS_RAM_BASE;
|
||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
|
||||
#endif
|
||||
kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE;
|
||||
kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_start);
|
||||
|
||||
|
||||
@@ -415,8 +415,6 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
|
||||
/* ALLOC_TRAMP flags lets us know we created it */
|
||||
ops->flags |= FTRACE_OPS_FL_ALLOC_TRAMP;
|
||||
|
||||
set_vm_flush_reset_perms(trampoline);
|
||||
|
||||
if (likely(system_state != SYSTEM_BOOTING))
|
||||
set_memory_ro((unsigned long)trampoline, npages);
|
||||
set_memory_x((unsigned long)trampoline, npages);
|
||||
|
||||
@@ -427,7 +427,6 @@ void *alloc_insn_page(void)
|
||||
if (!page)
|
||||
return NULL;
|
||||
|
||||
set_vm_flush_reset_perms(page);
|
||||
/*
|
||||
* First make the page read-only, and only then make it executable to
|
||||
* prevent it from being W+X in between.
|
||||
|
||||
@@ -74,10 +74,11 @@ void *module_alloc(unsigned long size)
|
||||
return NULL;
|
||||
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN,
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, gfp_mask,
|
||||
PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, gfp_mask, PAGE_KERNEL,
|
||||
VM_FLUSH_RESET_PERMS | VM_DEFER_KMEMLEAK,
|
||||
NUMA_NO_NODE, __builtin_return_address(0));
|
||||
|
||||
if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
|
||||
vfree(p);
|
||||
return NULL;
|
||||
|
||||
@@ -579,7 +579,7 @@ struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
|
||||
{
|
||||
struct bio *bio;
|
||||
|
||||
if (nr_vecs > UIO_MAXIOV)
|
||||
if (nr_vecs > BIO_MAX_INLINE_VECS)
|
||||
return NULL;
|
||||
return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask);
|
||||
}
|
||||
|
||||
@@ -219,16 +219,18 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
|
||||
sizeof(struct acpi_table_pptt));
|
||||
proc_sz = sizeof(struct acpi_pptt_processor);
|
||||
|
||||
while ((unsigned long)entry + proc_sz < table_end) {
|
||||
/* ignore subtable types that are smaller than a processor node */
|
||||
while ((unsigned long)entry + proc_sz <= table_end) {
|
||||
cpu_node = (struct acpi_pptt_processor *)entry;
|
||||
|
||||
if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
|
||||
cpu_node->parent == node_entry)
|
||||
return 0;
|
||||
if (entry->length == 0)
|
||||
return 0;
|
||||
|
||||
entry = ACPI_ADD_PTR(struct acpi_subtable_header, entry,
|
||||
entry->length);
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -261,15 +263,18 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he
|
||||
proc_sz = sizeof(struct acpi_pptt_processor);
|
||||
|
||||
/* find the processor structure associated with this cpuid */
|
||||
while ((unsigned long)entry + proc_sz < table_end) {
|
||||
while ((unsigned long)entry + proc_sz <= table_end) {
|
||||
cpu_node = (struct acpi_pptt_processor *)entry;
|
||||
|
||||
if (entry->length == 0) {
|
||||
pr_warn("Invalid zero length subtable\n");
|
||||
break;
|
||||
}
|
||||
/* entry->length may not equal proc_sz, revalidate the processor structure length */
|
||||
if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
|
||||
acpi_cpu_id == cpu_node->acpi_processor_id &&
|
||||
(unsigned long)entry + entry->length <= table_end &&
|
||||
entry->length == proc_sz + cpu_node->number_of_priv_resources * sizeof(u32) &&
|
||||
acpi_pptt_leaf_node(table_hdr, cpu_node)) {
|
||||
return (struct acpi_pptt_processor *)entry;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ enum tis_int_flags {
|
||||
enum tis_defaults {
|
||||
TIS_MEM_LEN = 0x5000,
|
||||
TIS_SHORT_TIMEOUT = 750, /* ms */
|
||||
TIS_LONG_TIMEOUT = 2000, /* 2 sec */
|
||||
TIS_LONG_TIMEOUT = 4000, /* 4 secs */
|
||||
TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */
|
||||
TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ int __init clocksource_i8253_init(void)
|
||||
#ifdef CONFIG_CLKEVT_I8253
|
||||
void clockevent_i8253_disable(void)
|
||||
{
|
||||
raw_spin_lock(&i8253_lock);
|
||||
guard(raw_spinlock_irqsave)(&i8253_lock);
|
||||
|
||||
/*
|
||||
* Writing the MODE register should stop the counter, according to
|
||||
@@ -132,8 +132,6 @@ void clockevent_i8253_disable(void)
|
||||
outb_p(0, PIT_CH0);
|
||||
|
||||
outb_p(0x30, PIT_MODE);
|
||||
|
||||
raw_spin_unlock(&i8253_lock);
|
||||
}
|
||||
|
||||
static int pit_shutdown(struct clock_event_device *evt)
|
||||
|
||||
@@ -308,8 +308,9 @@ void dma_resv_add_fence(struct dma_resv *obj, struct dma_fence *fence,
|
||||
count++;
|
||||
|
||||
dma_resv_list_set(fobj, i, fence, usage);
|
||||
/* pointer update must be visible before we extend the num_fences */
|
||||
smp_store_mb(fobj->num_fences, count);
|
||||
/* fence update must be visible before we extend the num_fences */
|
||||
smp_wmb();
|
||||
fobj->num_fences = count;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_resv_add_fence);
|
||||
|
||||
|
||||
@@ -827,9 +827,9 @@ static int dmatest_func(void *data)
|
||||
} else {
|
||||
dma_async_issue_pending(chan);
|
||||
|
||||
wait_event_timeout(thread->done_wait,
|
||||
done->done,
|
||||
msecs_to_jiffies(params->timeout));
|
||||
wait_event_freezable_timeout(thread->done_wait,
|
||||
done->done,
|
||||
msecs_to_jiffies(params->timeout));
|
||||
|
||||
status = dma_async_is_tx_complete(chan, cookie, NULL,
|
||||
NULL);
|
||||
|
||||
@@ -140,6 +140,25 @@ static void idxd_cleanup_interrupts(struct idxd_device *idxd)
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
static void idxd_clean_wqs(struct idxd_device *idxd)
|
||||
{
|
||||
struct idxd_wq *wq;
|
||||
struct device *conf_dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < idxd->max_wqs; i++) {
|
||||
wq = idxd->wqs[i];
|
||||
if (idxd->hw.wq_cap.op_config)
|
||||
bitmap_free(wq->opcap_bmap);
|
||||
kfree(wq->wqcfg);
|
||||
conf_dev = wq_confdev(wq);
|
||||
put_device(conf_dev);
|
||||
kfree(wq);
|
||||
}
|
||||
bitmap_free(idxd->wq_enable_map);
|
||||
kfree(idxd->wqs);
|
||||
}
|
||||
|
||||
static int idxd_setup_wqs(struct idxd_device *idxd)
|
||||
{
|
||||
struct device *dev = &idxd->pdev->dev;
|
||||
@@ -154,8 +173,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
|
||||
|
||||
idxd->wq_enable_map = bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, dev_to_node(dev));
|
||||
if (!idxd->wq_enable_map) {
|
||||
kfree(idxd->wqs);
|
||||
return -ENOMEM;
|
||||
rc = -ENOMEM;
|
||||
goto err_bitmap;
|
||||
}
|
||||
|
||||
for (i = 0; i < idxd->max_wqs; i++) {
|
||||
@@ -174,10 +193,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
|
||||
conf_dev->bus = &dsa_bus_type;
|
||||
conf_dev->type = &idxd_wq_device_type;
|
||||
rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id);
|
||||
if (rc < 0) {
|
||||
put_device(conf_dev);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
mutex_init(&wq->wq_lock);
|
||||
init_waitqueue_head(&wq->err_queue);
|
||||
@@ -188,7 +205,6 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
|
||||
wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
|
||||
wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
|
||||
if (!wq->wqcfg) {
|
||||
put_device(conf_dev);
|
||||
rc = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
@@ -196,9 +212,8 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
|
||||
if (idxd->hw.wq_cap.op_config) {
|
||||
wq->opcap_bmap = bitmap_zalloc(IDXD_MAX_OPCAP_BITS, GFP_KERNEL);
|
||||
if (!wq->opcap_bmap) {
|
||||
put_device(conf_dev);
|
||||
rc = -ENOMEM;
|
||||
goto err;
|
||||
goto err_opcap_bmap;
|
||||
}
|
||||
bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS);
|
||||
}
|
||||
@@ -207,15 +222,46 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
err_opcap_bmap:
|
||||
kfree(wq->wqcfg);
|
||||
|
||||
err:
|
||||
put_device(conf_dev);
|
||||
kfree(wq);
|
||||
|
||||
while (--i >= 0) {
|
||||
wq = idxd->wqs[i];
|
||||
if (idxd->hw.wq_cap.op_config)
|
||||
bitmap_free(wq->opcap_bmap);
|
||||
kfree(wq->wqcfg);
|
||||
conf_dev = wq_confdev(wq);
|
||||
put_device(conf_dev);
|
||||
kfree(wq);
|
||||
|
||||
}
|
||||
bitmap_free(idxd->wq_enable_map);
|
||||
|
||||
err_bitmap:
|
||||
kfree(idxd->wqs);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void idxd_clean_engines(struct idxd_device *idxd)
|
||||
{
|
||||
struct idxd_engine *engine;
|
||||
struct device *conf_dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < idxd->max_engines; i++) {
|
||||
engine = idxd->engines[i];
|
||||
conf_dev = engine_confdev(engine);
|
||||
put_device(conf_dev);
|
||||
kfree(engine);
|
||||
}
|
||||
kfree(idxd->engines);
|
||||
}
|
||||
|
||||
static int idxd_setup_engines(struct idxd_device *idxd)
|
||||
{
|
||||
struct idxd_engine *engine;
|
||||
@@ -246,6 +292,7 @@ static int idxd_setup_engines(struct idxd_device *idxd)
|
||||
rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id);
|
||||
if (rc < 0) {
|
||||
put_device(conf_dev);
|
||||
kfree(engine);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -259,10 +306,26 @@ static int idxd_setup_engines(struct idxd_device *idxd)
|
||||
engine = idxd->engines[i];
|
||||
conf_dev = engine_confdev(engine);
|
||||
put_device(conf_dev);
|
||||
kfree(engine);
|
||||
}
|
||||
kfree(idxd->engines);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void idxd_clean_groups(struct idxd_device *idxd)
|
||||
{
|
||||
struct idxd_group *group;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < idxd->max_groups; i++) {
|
||||
group = idxd->groups[i];
|
||||
put_device(group_confdev(group));
|
||||
kfree(group);
|
||||
}
|
||||
kfree(idxd->groups);
|
||||
}
|
||||
|
||||
static int idxd_setup_groups(struct idxd_device *idxd)
|
||||
{
|
||||
struct device *dev = &idxd->pdev->dev;
|
||||
@@ -293,6 +356,7 @@ static int idxd_setup_groups(struct idxd_device *idxd)
|
||||
rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id);
|
||||
if (rc < 0) {
|
||||
put_device(conf_dev);
|
||||
kfree(group);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -312,27 +376,25 @@ static int idxd_setup_groups(struct idxd_device *idxd)
|
||||
while (--i >= 0) {
|
||||
group = idxd->groups[i];
|
||||
put_device(group_confdev(group));
|
||||
kfree(group);
|
||||
}
|
||||
kfree(idxd->groups);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void idxd_cleanup_internals(struct idxd_device *idxd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < idxd->max_groups; i++)
|
||||
put_device(group_confdev(idxd->groups[i]));
|
||||
for (i = 0; i < idxd->max_engines; i++)
|
||||
put_device(engine_confdev(idxd->engines[i]));
|
||||
for (i = 0; i < idxd->max_wqs; i++)
|
||||
put_device(wq_confdev(idxd->wqs[i]));
|
||||
idxd_clean_groups(idxd);
|
||||
idxd_clean_engines(idxd);
|
||||
idxd_clean_wqs(idxd);
|
||||
destroy_workqueue(idxd->wq);
|
||||
}
|
||||
|
||||
static int idxd_setup_internals(struct idxd_device *idxd)
|
||||
{
|
||||
struct device *dev = &idxd->pdev->dev;
|
||||
int rc, i;
|
||||
int rc;
|
||||
|
||||
init_waitqueue_head(&idxd->cmd_waitq);
|
||||
|
||||
@@ -357,14 +419,11 @@ static int idxd_setup_internals(struct idxd_device *idxd)
|
||||
return 0;
|
||||
|
||||
err_wkq_create:
|
||||
for (i = 0; i < idxd->max_groups; i++)
|
||||
put_device(group_confdev(idxd->groups[i]));
|
||||
idxd_clean_groups(idxd);
|
||||
err_group:
|
||||
for (i = 0; i < idxd->max_engines; i++)
|
||||
put_device(engine_confdev(idxd->engines[i]));
|
||||
idxd_clean_engines(idxd);
|
||||
err_engine:
|
||||
for (i = 0; i < idxd->max_wqs; i++)
|
||||
put_device(wq_confdev(idxd->wqs[i]));
|
||||
idxd_clean_wqs(idxd);
|
||||
err_wqs:
|
||||
return rc;
|
||||
}
|
||||
@@ -460,6 +519,17 @@ static void idxd_read_caps(struct idxd_device *idxd)
|
||||
multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4);
|
||||
}
|
||||
|
||||
static void idxd_free(struct idxd_device *idxd)
|
||||
{
|
||||
if (!idxd)
|
||||
return;
|
||||
|
||||
put_device(idxd_confdev(idxd));
|
||||
bitmap_free(idxd->opcap_bmap);
|
||||
ida_free(&idxd_ida, idxd->id);
|
||||
kfree(idxd);
|
||||
}
|
||||
|
||||
static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -477,28 +547,34 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
|
||||
idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type);
|
||||
idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL);
|
||||
if (idxd->id < 0)
|
||||
return NULL;
|
||||
goto err_ida;
|
||||
|
||||
idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev));
|
||||
if (!idxd->opcap_bmap) {
|
||||
ida_free(&idxd_ida, idxd->id);
|
||||
return NULL;
|
||||
}
|
||||
if (!idxd->opcap_bmap)
|
||||
goto err_opcap;
|
||||
|
||||
device_initialize(conf_dev);
|
||||
conf_dev->parent = dev;
|
||||
conf_dev->bus = &dsa_bus_type;
|
||||
conf_dev->type = idxd->data->dev_type;
|
||||
rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id);
|
||||
if (rc < 0) {
|
||||
put_device(conf_dev);
|
||||
return NULL;
|
||||
}
|
||||
if (rc < 0)
|
||||
goto err_name;
|
||||
|
||||
spin_lock_init(&idxd->dev_lock);
|
||||
spin_lock_init(&idxd->cmd_lock);
|
||||
|
||||
return idxd;
|
||||
|
||||
err_name:
|
||||
put_device(conf_dev);
|
||||
bitmap_free(idxd->opcap_bmap);
|
||||
err_opcap:
|
||||
ida_free(&idxd_ida, idxd->id);
|
||||
err_ida:
|
||||
kfree(idxd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int idxd_enable_system_pasid(struct idxd_device *idxd)
|
||||
@@ -651,7 +727,7 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
err:
|
||||
pci_iounmap(pdev, idxd->reg_base);
|
||||
err_iomap:
|
||||
put_device(idxd_confdev(idxd));
|
||||
idxd_free(idxd);
|
||||
err_idxd_alloc:
|
||||
pci_disable_device(pdev);
|
||||
return rc;
|
||||
@@ -714,6 +790,7 @@ static void idxd_remove(struct pci_dev *pdev)
|
||||
destroy_workqueue(idxd->wq);
|
||||
perfmon_pmu_remove(idxd);
|
||||
put_device(idxd_confdev(idxd));
|
||||
idxd_free(idxd);
|
||||
}
|
||||
|
||||
static struct pci_driver idxd_pci_driver = {
|
||||
|
||||
@@ -1088,8 +1088,11 @@ static void udma_check_tx_completion(struct work_struct *work)
|
||||
u32 residue_diff;
|
||||
ktime_t time_diff;
|
||||
unsigned long delay;
|
||||
unsigned long flags;
|
||||
|
||||
while (1) {
|
||||
spin_lock_irqsave(&uc->vc.lock, flags);
|
||||
|
||||
if (uc->desc) {
|
||||
/* Get previous residue and time stamp */
|
||||
residue_diff = uc->tx_drain.residue;
|
||||
@@ -1124,6 +1127,8 @@ static void udma_check_tx_completion(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&uc->vc.lock, flags);
|
||||
|
||||
usleep_range(ktime_to_us(delay),
|
||||
ktime_to_us(delay) + 10);
|
||||
continue;
|
||||
@@ -1140,6 +1145,8 @@ static void udma_check_tx_completion(struct work_struct *work)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&uc->vc.lock, flags);
|
||||
}
|
||||
|
||||
static irqreturn_t udma_ring_irq_handler(int irq, void *data)
|
||||
@@ -4209,7 +4216,6 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec,
|
||||
struct of_dma *ofdma)
|
||||
{
|
||||
struct udma_dev *ud = ofdma->of_dma_data;
|
||||
dma_cap_mask_t mask = ud->ddev.cap_mask;
|
||||
struct udma_filter_param filter_param;
|
||||
struct dma_chan *chan;
|
||||
|
||||
@@ -4241,7 +4247,7 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec,
|
||||
}
|
||||
}
|
||||
|
||||
chan = __dma_request_channel(&mask, udma_dma_filter_fn, &filter_param,
|
||||
chan = __dma_request_channel(&ud->ddev.cap_mask, udma_dma_filter_fn, &filter_param,
|
||||
ofdma->of_node);
|
||||
if (!chan) {
|
||||
dev_err(ud->dev, "get channel fail in %s.\n", __func__);
|
||||
|
||||
@@ -781,6 +781,7 @@ struct amdgpu_device {
|
||||
bool need_swiotlb;
|
||||
bool accel_working;
|
||||
struct notifier_block acpi_nb;
|
||||
struct notifier_block pm_nb;
|
||||
struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS];
|
||||
struct debugfs_blob_wrapper debugfs_vbios_blob;
|
||||
struct debugfs_blob_wrapper debugfs_discovery_blob;
|
||||
|
||||
@@ -139,6 +139,10 @@ const char *amdgpu_asic_name[] = {
|
||||
"LAST",
|
||||
};
|
||||
|
||||
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev);
|
||||
static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode,
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* DOC: pcie_replay_count
|
||||
*
|
||||
@@ -3990,6 +3994,11 @@ fence_driver_init:
|
||||
|
||||
amdgpu_device_check_iommu_direct_map(adev);
|
||||
|
||||
adev->pm_nb.notifier_call = amdgpu_device_pm_notifier;
|
||||
r = register_pm_notifier(&adev->pm_nb);
|
||||
if (r)
|
||||
goto failed;
|
||||
|
||||
return 0;
|
||||
|
||||
release_ras_con:
|
||||
@@ -4051,6 +4060,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
adev->shutdown = true;
|
||||
|
||||
unregister_pm_notifier(&adev->pm_nb);
|
||||
|
||||
/* make sure IB test finished before entering exclusive mode
|
||||
* to avoid preemption on IB test
|
||||
* */
|
||||
@@ -4181,6 +4192,33 @@ static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
|
||||
/*
|
||||
* Suspend & resume.
|
||||
*/
|
||||
/**
|
||||
* amdgpu_device_pm_notifier - Notification block for Suspend/Hibernate events
|
||||
* @nb: notifier block
|
||||
* @mode: suspend mode
|
||||
* @data: data
|
||||
*
|
||||
* This function is called when the system is about to suspend or hibernate.
|
||||
* It is used to set the appropriate flags so that eviction can be optimized
|
||||
* in the pm prepare callback.
|
||||
*/
|
||||
static int amdgpu_device_pm_notifier(struct notifier_block *nb, unsigned long mode,
|
||||
void *data)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(nb, struct amdgpu_device, pm_nb);
|
||||
|
||||
switch (mode) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
adev->in_s4 = true;
|
||||
break;
|
||||
case PM_POST_HIBERNATION:
|
||||
adev->in_s4 = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_prepare - prepare for device suspend
|
||||
*
|
||||
@@ -4631,6 +4669,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
|
||||
retry:
|
||||
amdgpu_amdkfd_pre_reset(adev);
|
||||
|
||||
amdgpu_device_stop_pending_resets(adev);
|
||||
|
||||
if (from_hypervisor)
|
||||
r = amdgpu_virt_request_full_gpu(adev, true);
|
||||
else
|
||||
@@ -5502,11 +5542,12 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
tmp_adev->asic_reset_res = r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop all pending non scheduler resets. Scheduler resets
|
||||
* were already dropped during drm_sched_stop
|
||||
*/
|
||||
amdgpu_device_stop_pending_resets(tmp_adev);
|
||||
if (!amdgpu_sriov_vf(tmp_adev))
|
||||
/*
|
||||
* Drop all pending non scheduler resets. Scheduler resets
|
||||
* were already dropped during drm_sched_stop
|
||||
*/
|
||||
amdgpu_device_stop_pending_resets(tmp_adev);
|
||||
}
|
||||
|
||||
tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter));
|
||||
|
||||
@@ -2468,7 +2468,6 @@ static int amdgpu_pmops_freeze(struct device *dev)
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
adev->in_s4 = true;
|
||||
r = amdgpu_device_suspend(drm_dev, true);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -2481,13 +2480,8 @@ static int amdgpu_pmops_freeze(struct device *dev)
|
||||
static int amdgpu_pmops_thaw(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
r = amdgpu_device_resume(drm_dev, true);
|
||||
adev->in_s4 = false;
|
||||
|
||||
return r;
|
||||
return amdgpu_device_resume(drm_dev, true);
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_poweroff(struct device *dev)
|
||||
@@ -2500,9 +2494,6 @@ static int amdgpu_pmops_poweroff(struct device *dev)
|
||||
static int amdgpu_pmops_restore(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
|
||||
adev->in_s4 = false;
|
||||
|
||||
return amdgpu_device_resume(drm_dev, true);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "vi.h"
|
||||
#include "soc15.h"
|
||||
#include "nv.h"
|
||||
@@ -456,7 +457,7 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)
|
||||
return -EINVAL;
|
||||
|
||||
if (pf2vf_info->size > 1024) {
|
||||
DRM_ERROR("invalid pf2vf message size\n");
|
||||
dev_err(adev->dev, "invalid pf2vf message size: 0x%x\n", pf2vf_info->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -467,7 +468,9 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)
|
||||
adev->virt.fw_reserve.p_pf2vf, pf2vf_info->size,
|
||||
adev->virt.fw_reserve.checksum_key, checksum);
|
||||
if (checksum != checkval) {
|
||||
DRM_ERROR("invalid pf2vf message\n");
|
||||
dev_err(adev->dev,
|
||||
"invalid pf2vf message: header checksum=0x%x calculated checksum=0x%x\n",
|
||||
checksum, checkval);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -481,7 +484,9 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)
|
||||
adev->virt.fw_reserve.p_pf2vf, pf2vf_info->size,
|
||||
0, checksum);
|
||||
if (checksum != checkval) {
|
||||
DRM_ERROR("invalid pf2vf message\n");
|
||||
dev_err(adev->dev,
|
||||
"invalid pf2vf message: header checksum=0x%x calculated checksum=0x%x\n",
|
||||
checksum, checkval);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -517,7 +522,7 @@ static int amdgpu_virt_read_pf2vf_data(struct amdgpu_device *adev)
|
||||
((struct amd_sriov_msg_pf2vf_info *)pf2vf_info)->uuid;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("invalid pf2vf version\n");
|
||||
dev_err(adev->dev, "invalid pf2vf version: 0x%x\n", pf2vf_info->version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -617,8 +622,21 @@ static void amdgpu_virt_update_vf2pf_work_item(struct work_struct *work)
|
||||
int ret;
|
||||
|
||||
ret = amdgpu_virt_read_pf2vf_data(adev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
adev->virt.vf2pf_update_retry_cnt++;
|
||||
if ((adev->virt.vf2pf_update_retry_cnt >= AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT) &&
|
||||
amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev)) {
|
||||
if (amdgpu_reset_domain_schedule(adev->reset_domain,
|
||||
&adev->virt.flr_work))
|
||||
return;
|
||||
else
|
||||
dev_err(adev->dev, "Failed to queue work! at %s", __func__);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
adev->virt.vf2pf_update_retry_cnt = 0;
|
||||
amdgpu_virt_write_vf2pf_data(adev);
|
||||
|
||||
out:
|
||||
@@ -639,6 +657,7 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
|
||||
adev->virt.fw_reserve.p_pf2vf = NULL;
|
||||
adev->virt.fw_reserve.p_vf2pf = NULL;
|
||||
adev->virt.vf2pf_update_interval_ms = 0;
|
||||
adev->virt.vf2pf_update_retry_cnt = 0;
|
||||
|
||||
if (adev->mman.fw_vram_usage_va != NULL) {
|
||||
/* go through this logic in ip_init and reset to init workqueue*/
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
/* tonga/fiji use this offset */
|
||||
#define mmBIF_IOV_FUNC_IDENTIFIER 0x1503
|
||||
|
||||
#define AMDGPU_VF2PF_UPDATE_MAX_RETRY_LIMIT 30
|
||||
|
||||
enum amdgpu_sriov_vf_mode {
|
||||
SRIOV_VF_MODE_BARE_METAL = 0,
|
||||
SRIOV_VF_MODE_ONE_VF,
|
||||
@@ -250,6 +252,7 @@ struct amdgpu_virt {
|
||||
/* vf2pf message */
|
||||
struct delayed_work vf2pf_work;
|
||||
uint32_t vf2pf_update_interval_ms;
|
||||
int vf2pf_update_retry_cnt;
|
||||
|
||||
/* multimedia bandwidth config */
|
||||
bool is_mm_bw_enabled;
|
||||
|
||||
@@ -276,6 +276,8 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
|
||||
timeout -= 10;
|
||||
} while (timeout > 1);
|
||||
|
||||
dev_warn(adev->dev, "waiting IDH_FLR_NOTIFICATION_CMPL timeout\n");
|
||||
|
||||
flr_done:
|
||||
atomic_set(&adev->reset_domain->in_gpu_reset, 0);
|
||||
up_write(&adev->reset_domain->sem);
|
||||
|
||||
@@ -300,6 +300,8 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
|
||||
timeout -= 10;
|
||||
} while (timeout > 1);
|
||||
|
||||
dev_warn(adev->dev, "waiting IDH_FLR_NOTIFICATION_CMPL timeout\n");
|
||||
|
||||
flr_done:
|
||||
atomic_set(&adev->reset_domain->in_gpu_reset, 0);
|
||||
up_write(&adev->reset_domain->sem);
|
||||
|
||||
@@ -10707,7 +10707,8 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(
|
||||
/* The reply is stored in the top nibble of the command. */
|
||||
payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF;
|
||||
|
||||
if (!payload->write && p_notify->aux_reply.length)
|
||||
/*write req may receive a byte indicating partially written number as well*/
|
||||
if (p_notify->aux_reply.length)
|
||||
memcpy(payload->data, p_notify->aux_reply.data,
|
||||
p_notify->aux_reply.length);
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
enum aux_return_code_type operation_result;
|
||||
struct amdgpu_device *adev;
|
||||
struct ddc_service *ddc;
|
||||
uint8_t copy[16];
|
||||
|
||||
if (WARN_ON(msg->size > 16))
|
||||
return -E2BIG;
|
||||
@@ -81,6 +82,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
(msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0;
|
||||
payload.defer_delay = 0;
|
||||
|
||||
if (payload.write) {
|
||||
memcpy(copy, msg->buffer, msg->size);
|
||||
payload.data = copy;
|
||||
}
|
||||
|
||||
result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
|
||||
&operation_result);
|
||||
|
||||
@@ -104,9 +110,9 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
*/
|
||||
if (payload.write && result >= 0) {
|
||||
if (result) {
|
||||
/*one byte indicating partially written bytes. Force 0 to retry*/
|
||||
drm_info(adev_to_drm(adev), "amdgpu: AUX partially written\n");
|
||||
result = 0;
|
||||
/*one byte indicating partially written bytes*/
|
||||
drm_dbg_dp(adev_to_drm(adev), "amdgpu: AUX partially written\n");
|
||||
result = payload.data[0];
|
||||
} else if (!payload.reply[0])
|
||||
/*I2C_ACK|AUX_ACK*/
|
||||
result = msg->size;
|
||||
@@ -131,11 +137,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
|
||||
break;
|
||||
}
|
||||
|
||||
drm_info(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result);
|
||||
drm_dbg_dp(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result);
|
||||
}
|
||||
|
||||
if (payload.reply[0])
|
||||
drm_info(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.",
|
||||
drm_dbg_dp(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.",
|
||||
payload.reply[0]);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -174,6 +174,7 @@ static void thrustmaster_interrupts(struct hid_device *hdev)
|
||||
u8 ep_addr[2] = {b_ep, 0};
|
||||
|
||||
if (!usb_check_int_endpoints(usbif, ep_addr)) {
|
||||
kfree(send_buf);
|
||||
hid_err(hdev, "Unexpected non-int endpoint\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -142,11 +142,12 @@ static int uclogic_input_configured(struct hid_device *hdev,
|
||||
suffix = "System Control";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (suffix)
|
||||
} else {
|
||||
hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
|
||||
"%s %s", hdev->name, suffix);
|
||||
if (!hi->input->name)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1114,68 +1114,10 @@ int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
|
||||
EXPORT_SYMBOL(vmbus_sendpacket);
|
||||
|
||||
/*
|
||||
* vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
|
||||
* packets using a GPADL Direct packet type. This interface allows you
|
||||
* to control notifying the host. This will be useful for sending
|
||||
* batched data. Also the sender can control the send flags
|
||||
* explicitly.
|
||||
*/
|
||||
int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
|
||||
struct hv_page_buffer pagebuffers[],
|
||||
u32 pagecount, void *buffer, u32 bufferlen,
|
||||
u64 requestid)
|
||||
{
|
||||
int i;
|
||||
struct vmbus_channel_packet_page_buffer desc;
|
||||
u32 descsize;
|
||||
u32 packetlen;
|
||||
u32 packetlen_aligned;
|
||||
struct kvec bufferlist[3];
|
||||
u64 aligned_data = 0;
|
||||
|
||||
if (pagecount > MAX_PAGE_BUFFER_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Adjust the size down since vmbus_channel_packet_page_buffer is the
|
||||
* largest size we support
|
||||
*/
|
||||
descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
|
||||
((MAX_PAGE_BUFFER_COUNT - pagecount) *
|
||||
sizeof(struct hv_page_buffer));
|
||||
packetlen = descsize + bufferlen;
|
||||
packetlen_aligned = ALIGN(packetlen, sizeof(u64));
|
||||
|
||||
/* Setup the descriptor */
|
||||
desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
|
||||
desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
|
||||
desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */
|
||||
desc.length8 = (u16)(packetlen_aligned >> 3);
|
||||
desc.transactionid = VMBUS_RQST_ERROR; /* will be updated in hv_ringbuffer_write() */
|
||||
desc.reserved = 0;
|
||||
desc.rangecount = pagecount;
|
||||
|
||||
for (i = 0; i < pagecount; i++) {
|
||||
desc.range[i].len = pagebuffers[i].len;
|
||||
desc.range[i].offset = pagebuffers[i].offset;
|
||||
desc.range[i].pfn = pagebuffers[i].pfn;
|
||||
}
|
||||
|
||||
bufferlist[0].iov_base = &desc;
|
||||
bufferlist[0].iov_len = descsize;
|
||||
bufferlist[1].iov_base = buffer;
|
||||
bufferlist[1].iov_len = bufferlen;
|
||||
bufferlist[2].iov_base = &aligned_data;
|
||||
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
||||
|
||||
return hv_ringbuffer_write(channel, bufferlist, 3, requestid, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
|
||||
|
||||
/*
|
||||
* vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
|
||||
* vmbus_sendpacket_mpb_desc - Send one or more multi-page buffer packets
|
||||
* using a GPADL Direct packet type.
|
||||
* The buffer includes the vmbus descriptor.
|
||||
* The desc argument must include space for the VMBus descriptor. The
|
||||
* rangecount field must already be set.
|
||||
*/
|
||||
int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
||||
struct vmbus_packet_mpb_array *desc,
|
||||
@@ -1197,7 +1139,6 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
||||
desc->length8 = (u16)(packetlen_aligned >> 3);
|
||||
desc->transactionid = VMBUS_RQST_ERROR; /* will be updated in hv_ringbuffer_write() */
|
||||
desc->reserved = 0;
|
||||
desc->rangecount = 1;
|
||||
|
||||
bufferlist[0].iov_base = desc;
|
||||
bufferlist[0].iov_len = desc_size;
|
||||
|
||||
@@ -44,7 +44,7 @@ struct ad7266_state {
|
||||
*/
|
||||
struct {
|
||||
__be16 sample[2];
|
||||
s64 timestamp;
|
||||
aligned_s64 timestamp;
|
||||
} data __aligned(IIO_DMA_MINALIGN);
|
||||
};
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ struct ad7768_state {
|
||||
union {
|
||||
struct {
|
||||
__be32 chan;
|
||||
s64 timestamp;
|
||||
aligned_s64 timestamp;
|
||||
} scan;
|
||||
__be32 d32;
|
||||
u8 d8[2];
|
||||
|
||||
@@ -108,7 +108,7 @@ static irqreturn_t sps30_trigger_handler(int irq, void *p)
|
||||
int ret;
|
||||
struct {
|
||||
s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
|
||||
s64 ts;
|
||||
aligned_s64 ts;
|
||||
} scan;
|
||||
|
||||
mutex_lock(&state->lock);
|
||||
|
||||
@@ -71,11 +71,8 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
|
||||
|
||||
err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata,
|
||||
cq->queue->buf, cq->queue->buf_size, &cq->queue->ip);
|
||||
if (err) {
|
||||
vfree(cq->queue->buf);
|
||||
kfree(cq->queue);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
cq->is_user = uresp;
|
||||
|
||||
|
||||
@@ -2083,6 +2083,7 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
|
||||
switch (state) {
|
||||
case BR_STATE_DISABLED:
|
||||
case BR_STATE_BLOCKING:
|
||||
case BR_STATE_LISTENING:
|
||||
/* From UM10944 description of DRPDTAG (why put this there?):
|
||||
* "Management traffic flows to the port regardless of the state
|
||||
* of the INGRESS flag". So BPDUs are still be allowed to pass.
|
||||
@@ -2092,11 +2093,6 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
|
||||
mac[port].egress = false;
|
||||
mac[port].dyn_learn = false;
|
||||
break;
|
||||
case BR_STATE_LISTENING:
|
||||
mac[port].ingress = true;
|
||||
mac[port].egress = false;
|
||||
mac[port].dyn_learn = false;
|
||||
break;
|
||||
case BR_STATE_LEARNING:
|
||||
mac[port].ingress = true;
|
||||
mac[port].egress = false;
|
||||
|
||||
@@ -4041,7 +4041,7 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||
struct net_device *dev = bp->dev;
|
||||
|
||||
if (page_mode) {
|
||||
bp->flags &= ~BNXT_FLAG_AGG_RINGS;
|
||||
bp->flags &= ~(BNXT_FLAG_AGG_RINGS | BNXT_FLAG_NO_AGG_RINGS);
|
||||
bp->flags |= BNXT_FLAG_RX_PAGE_MODE;
|
||||
|
||||
if (bp->xdp_prog->aux->xdp_has_frags)
|
||||
@@ -12799,6 +12799,14 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
|
||||
bnxt_close_nic(bp, true, false);
|
||||
|
||||
dev->mtu = new_mtu;
|
||||
|
||||
/* MTU change may change the AGG ring settings if an XDP multi-buffer
|
||||
* program is attached. We need to set the AGG rings settings and
|
||||
* rx_skb_func accordingly.
|
||||
*/
|
||||
if (READ_ONCE(bp->xdp_prog))
|
||||
bnxt_set_rx_skb_mode(bp, true);
|
||||
|
||||
bnxt_set_ring_params(bp);
|
||||
|
||||
if (netif_running(dev))
|
||||
|
||||
@@ -962,22 +962,15 @@ static void macb_update_stats(struct macb *bp)
|
||||
|
||||
static int macb_halt_tx(struct macb *bp)
|
||||
{
|
||||
unsigned long halt_time, timeout;
|
||||
u32 status;
|
||||
u32 status;
|
||||
|
||||
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT));
|
||||
|
||||
timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT);
|
||||
do {
|
||||
halt_time = jiffies;
|
||||
status = macb_readl(bp, TSR);
|
||||
if (!(status & MACB_BIT(TGO)))
|
||||
return 0;
|
||||
|
||||
udelay(250);
|
||||
} while (time_before(halt_time, timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
/* Poll TSR until TGO is cleared or timeout. */
|
||||
return read_poll_timeout_atomic(macb_readl, status,
|
||||
!(status & MACB_BIT(TGO)),
|
||||
250, MACB_HALT_TIMEOUT, false,
|
||||
bp, TSR);
|
||||
}
|
||||
|
||||
static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb, int budget)
|
||||
|
||||
@@ -428,7 +428,8 @@ static int cn10k_mcs_write_tx_secy(struct otx2_nic *pfvf,
|
||||
if (sw_tx_sc->encrypt)
|
||||
sectag_tci |= (MCS_TCI_E | MCS_TCI_C);
|
||||
|
||||
policy = FIELD_PREP(MCS_TX_SECY_PLCY_MTU, secy->netdev->mtu);
|
||||
policy = FIELD_PREP(MCS_TX_SECY_PLCY_MTU,
|
||||
pfvf->netdev->mtu + OTX2_ETH_HLEN);
|
||||
/* Write SecTag excluding AN bits(1..0) */
|
||||
policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_TCI, sectag_tci >> 2);
|
||||
policy |= FIELD_PREP(MCS_TX_SECY_PLCY_ST_OFFSET, tag_offset);
|
||||
|
||||
@@ -4023,6 +4023,10 @@ static netdev_features_t mlx5e_fix_uplink_rep_features(struct net_device *netdev
|
||||
if (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
|
||||
netdev_warn(netdev, "Disabling HW_VLAN CTAG FILTERING, not supported in switchdev mode\n");
|
||||
|
||||
features &= ~NETIF_F_HW_MACSEC;
|
||||
if (netdev->features & NETIF_F_HW_MACSEC)
|
||||
netdev_warn(netdev, "Disabling HW MACsec offload, not supported in switchdev mode\n");
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ static struct pci_driver qede_pci_driver = {
|
||||
};
|
||||
|
||||
static struct qed_eth_cb_ops qede_ll_ops = {
|
||||
{
|
||||
.common = {
|
||||
#ifdef CONFIG_RFS_ACCEL
|
||||
.arfs_filter_op = qede_arfs_filter_op,
|
||||
#endif
|
||||
|
||||
@@ -1484,8 +1484,11 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_o
|
||||
}
|
||||
|
||||
cmd_op = (cmd.rsp.arg[0] & 0xff);
|
||||
if (cmd.rsp.arg[0] >> 25 == 2)
|
||||
return 2;
|
||||
if (cmd.rsp.arg[0] >> 25 == 2) {
|
||||
ret = 2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
|
||||
set_bit(QLC_BC_VF_STATE, &vf->state);
|
||||
else
|
||||
|
||||
@@ -156,7 +156,6 @@ struct hv_netvsc_packet {
|
||||
u8 cp_partial; /* partial copy into send buffer */
|
||||
|
||||
u8 rmsg_size; /* RNDIS header and PPI size */
|
||||
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
|
||||
u8 page_buf_cnt;
|
||||
|
||||
u16 q_idx;
|
||||
@@ -891,6 +890,18 @@ struct nvsp_message {
|
||||
sizeof(struct nvsp_message))
|
||||
#define NETVSC_MIN_IN_MSG_SIZE sizeof(struct vmpacket_descriptor)
|
||||
|
||||
/* Maximum # of contiguous data ranges that can make up a trasmitted packet.
|
||||
* Typically it's the max SKB fragments plus 2 for the rndis packet and the
|
||||
* linear portion of the SKB. But if MAX_SKB_FRAGS is large, the value may
|
||||
* need to be limited to MAX_PAGE_BUFFER_COUNT, which is the max # of entries
|
||||
* in a GPA direct packet sent to netvsp over VMBus.
|
||||
*/
|
||||
#if MAX_SKB_FRAGS + 2 < MAX_PAGE_BUFFER_COUNT
|
||||
#define MAX_DATA_RANGES (MAX_SKB_FRAGS + 2)
|
||||
#else
|
||||
#define MAX_DATA_RANGES MAX_PAGE_BUFFER_COUNT
|
||||
#endif
|
||||
|
||||
/* Estimated requestor size:
|
||||
* out_ring_size/min_out_msg_size + in_ring_size/min_in_msg_size
|
||||
*/
|
||||
|
||||
@@ -980,8 +980,7 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device,
|
||||
+ pend_size;
|
||||
int i;
|
||||
u32 padding = 0;
|
||||
u32 page_count = packet->cp_partial ? packet->rmsg_pgcnt :
|
||||
packet->page_buf_cnt;
|
||||
u32 page_count = packet->cp_partial ? 1 : packet->page_buf_cnt;
|
||||
u32 remain;
|
||||
|
||||
/* Add padding */
|
||||
@@ -1082,6 +1081,42 @@ static int netvsc_dma_map(struct hv_device *hv_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Build an "array" of mpb entries describing the data to be transferred
|
||||
* over VMBus. After the desc header fields, each "array" entry is variable
|
||||
* size, and each entry starts after the end of the previous entry. The
|
||||
* "offset" and "len" fields for each entry imply the size of the entry.
|
||||
*
|
||||
* The pfns are in HV_HYP_PAGE_SIZE, because all communication with Hyper-V
|
||||
* uses that granularity, even if the system page size of the guest is larger.
|
||||
* Each entry in the input "pb" array must describe a contiguous range of
|
||||
* guest physical memory so that the pfns are sequential if the range crosses
|
||||
* a page boundary. The offset field must be < HV_HYP_PAGE_SIZE.
|
||||
*/
|
||||
static inline void netvsc_build_mpb_array(struct hv_page_buffer *pb,
|
||||
u32 page_buffer_count,
|
||||
struct vmbus_packet_mpb_array *desc,
|
||||
u32 *desc_size)
|
||||
{
|
||||
struct hv_mpb_array *mpb_entry = &desc->range;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < page_buffer_count; i++) {
|
||||
u32 offset = pb[i].offset;
|
||||
u32 len = pb[i].len;
|
||||
|
||||
mpb_entry->offset = offset;
|
||||
mpb_entry->len = len;
|
||||
|
||||
for (j = 0; j < HVPFN_UP(offset + len); j++)
|
||||
mpb_entry->pfn_array[j] = pb[i].pfn + j;
|
||||
|
||||
mpb_entry = (struct hv_mpb_array *)&mpb_entry->pfn_array[j];
|
||||
}
|
||||
|
||||
desc->rangecount = page_buffer_count;
|
||||
*desc_size = (char *)mpb_entry - (char *)desc;
|
||||
}
|
||||
|
||||
static inline int netvsc_send_pkt(
|
||||
struct hv_device *device,
|
||||
struct hv_netvsc_packet *packet,
|
||||
@@ -1124,8 +1159,11 @@ static inline int netvsc_send_pkt(
|
||||
|
||||
packet->dma_range = NULL;
|
||||
if (packet->page_buf_cnt) {
|
||||
struct vmbus_channel_packet_page_buffer desc;
|
||||
u32 desc_size;
|
||||
|
||||
if (packet->cp_partial)
|
||||
pb += packet->rmsg_pgcnt;
|
||||
pb++;
|
||||
|
||||
ret = netvsc_dma_map(ndev_ctx->device_ctx, packet, pb);
|
||||
if (ret) {
|
||||
@@ -1133,11 +1171,12 @@ static inline int netvsc_send_pkt(
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = vmbus_sendpacket_pagebuffer(out_channel,
|
||||
pb, packet->page_buf_cnt,
|
||||
&nvmsg, sizeof(nvmsg),
|
||||
req_id);
|
||||
|
||||
netvsc_build_mpb_array(pb, packet->page_buf_cnt,
|
||||
(struct vmbus_packet_mpb_array *)&desc,
|
||||
&desc_size);
|
||||
ret = vmbus_sendpacket_mpb_desc(out_channel,
|
||||
(struct vmbus_packet_mpb_array *)&desc,
|
||||
desc_size, &nvmsg, sizeof(nvmsg), req_id);
|
||||
if (ret)
|
||||
netvsc_dma_unmap(ndev_ctx->device_ctx, packet);
|
||||
} else {
|
||||
@@ -1286,7 +1325,7 @@ int netvsc_send(struct net_device *ndev,
|
||||
packet->send_buf_index = section_index;
|
||||
|
||||
if (packet->cp_partial) {
|
||||
packet->page_buf_cnt -= packet->rmsg_pgcnt;
|
||||
packet->page_buf_cnt--;
|
||||
packet->total_data_buflen = msd_len + packet->rmsg_size;
|
||||
} else {
|
||||
packet->page_buf_cnt = 0;
|
||||
|
||||
@@ -325,43 +325,10 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
|
||||
return txq;
|
||||
}
|
||||
|
||||
static u32 fill_pg_buf(unsigned long hvpfn, u32 offset, u32 len,
|
||||
struct hv_page_buffer *pb)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
hvpfn += offset >> HV_HYP_PAGE_SHIFT;
|
||||
offset = offset & ~HV_HYP_PAGE_MASK;
|
||||
|
||||
while (len > 0) {
|
||||
unsigned long bytes;
|
||||
|
||||
bytes = HV_HYP_PAGE_SIZE - offset;
|
||||
if (bytes > len)
|
||||
bytes = len;
|
||||
pb[j].pfn = hvpfn;
|
||||
pb[j].offset = offset;
|
||||
pb[j].len = bytes;
|
||||
|
||||
offset += bytes;
|
||||
len -= bytes;
|
||||
|
||||
if (offset == HV_HYP_PAGE_SIZE && len) {
|
||||
hvpfn++;
|
||||
offset = 0;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return j + 1;
|
||||
}
|
||||
|
||||
static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
|
||||
struct hv_netvsc_packet *packet,
|
||||
struct hv_page_buffer *pb)
|
||||
{
|
||||
u32 slots_used = 0;
|
||||
char *data = skb->data;
|
||||
int frags = skb_shinfo(skb)->nr_frags;
|
||||
int i;
|
||||
|
||||
@@ -370,28 +337,27 @@ static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
|
||||
* 2. skb linear data
|
||||
* 3. skb fragment data
|
||||
*/
|
||||
slots_used += fill_pg_buf(virt_to_hvpfn(hdr),
|
||||
offset_in_hvpage(hdr),
|
||||
len,
|
||||
&pb[slots_used]);
|
||||
|
||||
pb[0].offset = offset_in_hvpage(hdr);
|
||||
pb[0].len = len;
|
||||
pb[0].pfn = virt_to_hvpfn(hdr);
|
||||
packet->rmsg_size = len;
|
||||
packet->rmsg_pgcnt = slots_used;
|
||||
|
||||
slots_used += fill_pg_buf(virt_to_hvpfn(data),
|
||||
offset_in_hvpage(data),
|
||||
skb_headlen(skb),
|
||||
&pb[slots_used]);
|
||||
pb[1].offset = offset_in_hvpage(skb->data);
|
||||
pb[1].len = skb_headlen(skb);
|
||||
pb[1].pfn = virt_to_hvpfn(skb->data);
|
||||
|
||||
for (i = 0; i < frags; i++) {
|
||||
skb_frag_t *frag = skb_shinfo(skb)->frags + i;
|
||||
struct hv_page_buffer *cur_pb = &pb[i + 2];
|
||||
u64 pfn = page_to_hvpfn(skb_frag_page(frag));
|
||||
u32 offset = skb_frag_off(frag);
|
||||
|
||||
slots_used += fill_pg_buf(page_to_hvpfn(skb_frag_page(frag)),
|
||||
skb_frag_off(frag),
|
||||
skb_frag_size(frag),
|
||||
&pb[slots_used]);
|
||||
cur_pb->offset = offset_in_hvpage(offset);
|
||||
cur_pb->len = skb_frag_size(frag);
|
||||
cur_pb->pfn = pfn + (offset >> HV_HYP_PAGE_SHIFT);
|
||||
}
|
||||
return slots_used;
|
||||
return frags + 2;
|
||||
}
|
||||
|
||||
static int count_skb_frag_slots(struct sk_buff *skb)
|
||||
@@ -482,7 +448,7 @@ static int netvsc_xmit(struct sk_buff *skb, struct net_device *net, bool xdp_tx)
|
||||
struct net_device *vf_netdev;
|
||||
u32 rndis_msg_size;
|
||||
u32 hash;
|
||||
struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT];
|
||||
struct hv_page_buffer pb[MAX_DATA_RANGES];
|
||||
|
||||
/* If VF is present and up then redirect packets to it.
|
||||
* Skip the VF if it is marked down or has no carrier.
|
||||
|
||||
@@ -225,8 +225,7 @@ static int rndis_filter_send_request(struct rndis_device *dev,
|
||||
struct rndis_request *req)
|
||||
{
|
||||
struct hv_netvsc_packet *packet;
|
||||
struct hv_page_buffer page_buf[2];
|
||||
struct hv_page_buffer *pb = page_buf;
|
||||
struct hv_page_buffer pb;
|
||||
int ret;
|
||||
|
||||
/* Setup the packet to send it */
|
||||
@@ -235,27 +234,14 @@ static int rndis_filter_send_request(struct rndis_device *dev,
|
||||
packet->total_data_buflen = req->request_msg.msg_len;
|
||||
packet->page_buf_cnt = 1;
|
||||
|
||||
pb[0].pfn = virt_to_phys(&req->request_msg) >>
|
||||
HV_HYP_PAGE_SHIFT;
|
||||
pb[0].len = req->request_msg.msg_len;
|
||||
pb[0].offset = offset_in_hvpage(&req->request_msg);
|
||||
|
||||
/* Add one page_buf when request_msg crossing page boundary */
|
||||
if (pb[0].offset + pb[0].len > HV_HYP_PAGE_SIZE) {
|
||||
packet->page_buf_cnt++;
|
||||
pb[0].len = HV_HYP_PAGE_SIZE -
|
||||
pb[0].offset;
|
||||
pb[1].pfn = virt_to_phys((void *)&req->request_msg
|
||||
+ pb[0].len) >> HV_HYP_PAGE_SHIFT;
|
||||
pb[1].offset = 0;
|
||||
pb[1].len = req->request_msg.msg_len -
|
||||
pb[0].len;
|
||||
}
|
||||
pb.pfn = virt_to_phys(&req->request_msg) >> HV_HYP_PAGE_SHIFT;
|
||||
pb.len = req->request_msg.msg_len;
|
||||
pb.offset = offset_in_hvpage(&req->request_msg);
|
||||
|
||||
trace_rndis_send(dev->ndev, 0, &req->request_msg);
|
||||
|
||||
rcu_read_lock_bh();
|
||||
ret = netvsc_send(dev->ndev, packet, NULL, pb, NULL, false);
|
||||
ret = netvsc_send(dev->ndev, packet, NULL, &pb, NULL, false);
|
||||
rcu_read_unlock_bh();
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -789,6 +789,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
|
||||
int i;
|
||||
|
||||
mt76_worker_disable(&dev->tx_worker);
|
||||
napi_disable(&dev->tx_napi);
|
||||
netif_napi_del(&dev->tx_napi);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->phys); i++) {
|
||||
|
||||
@@ -376,7 +376,7 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
|
||||
* as it only leads to a small amount of wasted memory for the lifetime of
|
||||
* the I/O.
|
||||
*/
|
||||
static int nvme_pci_npages_prp(void)
|
||||
static __always_inline int nvme_pci_npages_prp(void)
|
||||
{
|
||||
unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
|
||||
unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
|
||||
@@ -1154,7 +1154,9 @@ static void nvme_poll_irqdisable(struct nvme_queue *nvmeq)
|
||||
WARN_ON_ONCE(test_bit(NVMEQ_POLLED, &nvmeq->flags));
|
||||
|
||||
disable_irq(pci_irq_vector(pdev, nvmeq->cq_vector));
|
||||
spin_lock(&nvmeq->cq_poll_lock);
|
||||
nvme_poll_cq(nvmeq, NULL);
|
||||
spin_unlock(&nvmeq->cq_poll_lock);
|
||||
enable_irq(pci_irq_vector(pdev, nvmeq->cq_vector));
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,6 @@ struct rcar_gen3_phy {
|
||||
struct rcar_gen3_chan *ch;
|
||||
u32 int_enable_bits;
|
||||
bool initialized;
|
||||
bool otg_initialized;
|
||||
bool powered;
|
||||
};
|
||||
|
||||
@@ -311,16 +310,15 @@ static bool rcar_gen3_is_any_rphy_initialized(struct rcar_gen3_chan *ch)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rcar_gen3_needs_init_otg(struct rcar_gen3_chan *ch)
|
||||
static bool rcar_gen3_is_any_otg_rphy_initialized(struct rcar_gen3_chan *ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_OF_PHYS; i++) {
|
||||
if (ch->rphys[i].otg_initialized)
|
||||
return false;
|
||||
for (enum rcar_gen3_phy_index i = PHY_INDEX_BOTH_HC; i <= PHY_INDEX_EHCI;
|
||||
i++) {
|
||||
if (ch->rphys[i].initialized)
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rcar_gen3_are_all_rphys_power_off(struct rcar_gen3_chan *ch)
|
||||
@@ -342,7 +340,7 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
|
||||
bool is_b_device;
|
||||
enum phy_mode cur_mode, new_mode;
|
||||
|
||||
if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
|
||||
if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
|
||||
return -EIO;
|
||||
|
||||
if (sysfs_streq(buf, "host"))
|
||||
@@ -380,7 +378,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
|
||||
{
|
||||
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
|
||||
|
||||
if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
|
||||
if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
|
||||
return -EIO;
|
||||
|
||||
return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
|
||||
@@ -393,6 +391,9 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
|
||||
void __iomem *usb2_base = ch->base;
|
||||
u32 val;
|
||||
|
||||
if (!ch->is_otg_channel || rcar_gen3_is_any_otg_rphy_initialized(ch))
|
||||
return;
|
||||
|
||||
/* Should not use functions of read-modify-write a register */
|
||||
val = readl(usb2_base + USB2_LINECTRL1);
|
||||
val = (val & ~USB2_LINECTRL1_DP_RPD) | USB2_LINECTRL1_DPRPD_EN |
|
||||
@@ -453,16 +454,16 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
|
||||
val = readl(usb2_base + USB2_INT_ENABLE);
|
||||
val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits;
|
||||
writel(val, usb2_base + USB2_INT_ENABLE);
|
||||
writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
|
||||
writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
|
||||
|
||||
/* Initialize otg part */
|
||||
if (channel->is_otg_channel) {
|
||||
if (rcar_gen3_needs_init_otg(channel))
|
||||
rcar_gen3_init_otg(channel);
|
||||
rphy->otg_initialized = true;
|
||||
if (!rcar_gen3_is_any_rphy_initialized(channel)) {
|
||||
writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
|
||||
writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
|
||||
}
|
||||
|
||||
/* Initialize otg part (only if we initialize a PHY with IRQs). */
|
||||
if (rphy->int_enable_bits)
|
||||
rcar_gen3_init_otg(channel);
|
||||
|
||||
rphy->initialized = true;
|
||||
|
||||
return 0;
|
||||
@@ -477,9 +478,6 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
|
||||
|
||||
rphy->initialized = false;
|
||||
|
||||
if (channel->is_otg_channel)
|
||||
rphy->otg_initialized = false;
|
||||
|
||||
val = readl(usb2_base + USB2_INT_ENABLE);
|
||||
val &= ~rphy->int_enable_bits;
|
||||
if (!rcar_gen3_is_any_rphy_initialized(channel))
|
||||
|
||||
@@ -542,16 +542,16 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
|
||||
|
||||
err = dev_set_name(&port->dev, "%s-%u", name, index);
|
||||
if (err < 0)
|
||||
goto unregister;
|
||||
goto put_device;
|
||||
|
||||
err = device_add(&port->dev);
|
||||
if (err < 0)
|
||||
goto unregister;
|
||||
goto put_device;
|
||||
|
||||
return 0;
|
||||
|
||||
unregister:
|
||||
device_unregister(&port->dev);
|
||||
put_device:
|
||||
put_device(&port->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -834,6 +834,10 @@ static int __maybe_unused amd_pmc_suspend_handler(struct device *dev)
|
||||
{
|
||||
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
|
||||
|
||||
/*
|
||||
* Must be called only from the same set of dev_pm_ops handlers
|
||||
* as i8042_pm_suspend() is called: currently just from .suspend.
|
||||
*/
|
||||
if (pdev->cpu_id == AMD_CPU_ID_CZN) {
|
||||
int rc = amd_pmc_czn_wa_irq1(pdev);
|
||||
|
||||
@@ -846,7 +850,9 @@ static int __maybe_unused amd_pmc_suspend_handler(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL);
|
||||
static const struct dev_pm_ops amd_pmc_pm = {
|
||||
.suspend = amd_pmc_suspend_handler,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3804,7 +3804,8 @@ static int asus_wmi_add(struct platform_device *pdev)
|
||||
goto fail_leds;
|
||||
|
||||
asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
|
||||
if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
|
||||
if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ==
|
||||
(ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
|
||||
asus->driver->wlan_ctrl_by_user = 1;
|
||||
|
||||
if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {
|
||||
|
||||
@@ -133,7 +133,7 @@ static int max20086_regulators_register(struct max20086 *chip)
|
||||
|
||||
static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on)
|
||||
{
|
||||
struct of_regulator_match matches[MAX20086_MAX_REGULATORS] = { };
|
||||
struct of_regulator_match *matches;
|
||||
struct device_node *node;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
@@ -144,6 +144,11 @@ static int max20086_parse_regulators_dt(struct max20086 *chip, bool *boot_on)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
matches = devm_kcalloc(chip->dev, chip->info->num_outputs,
|
||||
sizeof(*matches), GFP_KERNEL);
|
||||
if (!matches)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < chip->info->num_outputs; ++i)
|
||||
matches[i].name = max20086_output_names[i];
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
|
||||
unsigned int nr_zones, size_t *buflen)
|
||||
{
|
||||
struct request_queue *q = sdkp->disk->queue;
|
||||
unsigned int max_segments;
|
||||
size_t bufsize;
|
||||
void *buf;
|
||||
|
||||
@@ -210,12 +211,15 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
|
||||
* Furthermore, since the report zone command cannot be split, make
|
||||
* sure that the allocated buffer can always be mapped by limiting the
|
||||
* number of pages allocated to the HBA max segments limit.
|
||||
* Since max segments can be larger than the max inline bio vectors,
|
||||
* further limit the allocated buffer to BIO_MAX_INLINE_VECS.
|
||||
*/
|
||||
nr_zones = min(nr_zones, sdkp->zone_info.nr_zones);
|
||||
bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
|
||||
bufsize = min_t(size_t, bufsize,
|
||||
queue_max_hw_sectors(q) << SECTOR_SHIFT);
|
||||
bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT);
|
||||
max_segments = min(BIO_MAX_INLINE_VECS, queue_max_segments(q));
|
||||
bufsize = min_t(size_t, bufsize, max_segments << PAGE_SHIFT);
|
||||
|
||||
while (bufsize >= SECTOR_SIZE) {
|
||||
buf = kvzalloc(bufsize, GFP_KERNEL | __GFP_NORETRY);
|
||||
|
||||
@@ -1810,6 +1810,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
|
||||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
payload->rangecount = 1;
|
||||
payload->range.len = length;
|
||||
payload->range.offset = offset_in_hvpg;
|
||||
|
||||
|
||||
@@ -1775,10 +1775,9 @@ static int cqspi_remove(struct platform_device *pdev)
|
||||
static int cqspi_suspend(struct device *dev)
|
||||
{
|
||||
struct cqspi_st *cqspi = dev_get_drvdata(dev);
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = spi_master_suspend(master);
|
||||
ret = spi_master_suspend(cqspi->master);
|
||||
cqspi_controller_enable(cqspi, 0);
|
||||
|
||||
clk_disable_unprepare(cqspi->clk);
|
||||
@@ -1789,7 +1788,6 @@ static int cqspi_suspend(struct device *dev)
|
||||
static int cqspi_resume(struct device *dev)
|
||||
{
|
||||
struct cqspi_st *cqspi = dev_get_drvdata(dev);
|
||||
struct spi_master *master = dev_get_drvdata(dev);
|
||||
|
||||
clk_prepare_enable(cqspi->clk);
|
||||
cqspi_wait_idle(cqspi);
|
||||
@@ -1798,7 +1796,7 @@ static int cqspi_resume(struct device *dev)
|
||||
cqspi->current_cs = -1;
|
||||
cqspi->sclk = 0;
|
||||
|
||||
return spi_master_resume(master);
|
||||
return spi_master_resume(cqspi->master);
|
||||
}
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, cqspi_resume);
|
||||
|
||||
@@ -410,7 +410,7 @@ MODULE_LICENSE("GPL");
|
||||
static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len)
|
||||
{
|
||||
/* limit the hex_dump */
|
||||
if (len < 1024) {
|
||||
if (len <= 1024) {
|
||||
print_hex_dump(KERN_INFO, pre,
|
||||
DUMP_PREFIX_OFFSET, 16, 1,
|
||||
ptr, len, 0);
|
||||
|
||||
@@ -54,7 +54,8 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
|
||||
u8 cur = 0;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dp->con->lock);
|
||||
if (!ucsi_con_mutex_lock(dp->con))
|
||||
return -ENOTCONN;
|
||||
|
||||
if (!dp->override && dp->initialized) {
|
||||
const struct typec_altmode *p = typec_altmode_get_partner(alt);
|
||||
@@ -100,7 +101,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
|
||||
schedule_work(&dp->work);
|
||||
ret = 0;
|
||||
err_unlock:
|
||||
mutex_unlock(&dp->con->lock);
|
||||
ucsi_con_mutex_unlock(dp->con);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -112,7 +113,8 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
|
||||
u64 command;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&dp->con->lock);
|
||||
if (!ucsi_con_mutex_lock(dp->con))
|
||||
return -ENOTCONN;
|
||||
|
||||
if (!dp->override) {
|
||||
const struct typec_altmode *p = typec_altmode_get_partner(alt);
|
||||
@@ -144,7 +146,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
|
||||
schedule_work(&dp->work);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dp->con->lock);
|
||||
ucsi_con_mutex_unlock(dp->con);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -202,20 +204,21 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
|
||||
int cmd = PD_VDO_CMD(header);
|
||||
int svdm_version;
|
||||
|
||||
mutex_lock(&dp->con->lock);
|
||||
if (!ucsi_con_mutex_lock(dp->con))
|
||||
return -ENOTCONN;
|
||||
|
||||
if (!dp->override && dp->initialized) {
|
||||
const struct typec_altmode *p = typec_altmode_get_partner(alt);
|
||||
|
||||
dev_warn(&p->dev,
|
||||
"firmware doesn't support alternate mode overriding\n");
|
||||
mutex_unlock(&dp->con->lock);
|
||||
ucsi_con_mutex_unlock(dp->con);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
svdm_version = typec_altmode_get_svdm_version(alt);
|
||||
if (svdm_version < 0) {
|
||||
mutex_unlock(&dp->con->lock);
|
||||
ucsi_con_mutex_unlock(dp->con);
|
||||
return svdm_version;
|
||||
}
|
||||
|
||||
@@ -259,7 +262,7 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&dp->con->lock);
|
||||
ucsi_con_mutex_unlock(dp->con);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1398,6 +1398,40 @@ void ucsi_set_drvdata(struct ucsi *ucsi, void *data)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ucsi_set_drvdata);
|
||||
|
||||
/**
|
||||
* ucsi_con_mutex_lock - Acquire the connector mutex
|
||||
* @con: The connector interface to lock
|
||||
*
|
||||
* Returns true on success, false if the connector is disconnected
|
||||
*/
|
||||
bool ucsi_con_mutex_lock(struct ucsi_connector *con)
|
||||
{
|
||||
bool mutex_locked = false;
|
||||
bool connected = true;
|
||||
|
||||
while (connected && !mutex_locked) {
|
||||
mutex_locked = mutex_trylock(&con->lock) != 0;
|
||||
connected = con->status.flags & UCSI_CONSTAT_CONNECTED;
|
||||
if (connected && !mutex_locked)
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
connected = connected && con->partner;
|
||||
if (!connected && mutex_locked)
|
||||
mutex_unlock(&con->lock);
|
||||
|
||||
return connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucsi_con_mutex_unlock - Release the connector mutex
|
||||
* @con: The connector interface to unlock
|
||||
*/
|
||||
void ucsi_con_mutex_unlock(struct ucsi_connector *con)
|
||||
{
|
||||
mutex_unlock(&con->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* ucsi_create - Allocate UCSI instance
|
||||
* @dev: Device interface to the PPM (Platform Policy Manager)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
struct ucsi;
|
||||
struct ucsi_altmode;
|
||||
struct ucsi_connector;
|
||||
|
||||
/* UCSI offsets (Bytes) */
|
||||
#define UCSI_VERSION 0
|
||||
@@ -62,6 +63,8 @@ int ucsi_register(struct ucsi *ucsi);
|
||||
void ucsi_unregister(struct ucsi *ucsi);
|
||||
void *ucsi_get_drvdata(struct ucsi *ucsi);
|
||||
void ucsi_set_drvdata(struct ucsi *ucsi, void *data);
|
||||
bool ucsi_con_mutex_lock(struct ucsi_connector *con);
|
||||
void ucsi_con_mutex_unlock(struct ucsi_connector *con);
|
||||
|
||||
void ucsi_connector_change(struct ucsi *ucsi, u8 num);
|
||||
|
||||
|
||||
@@ -585,6 +585,10 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
|
||||
uc->has_multiple_dp) {
|
||||
con_index = (uc->last_cmd_sent >> 16) &
|
||||
UCSI_CMD_CONNECTOR_MASK;
|
||||
if (con_index == 0) {
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
con = &uc->ucsi->connector[con_index - 1];
|
||||
ucsi_ccg_update_set_new_cam_cmd(uc, con, (u64 *)val);
|
||||
}
|
||||
@@ -599,6 +603,7 @@ static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
|
||||
|
||||
err_clear_bit:
|
||||
clear_bit(DEV_CMD_PENDING, &uc->flags);
|
||||
err_put:
|
||||
pm_runtime_put_sync(uc->dev);
|
||||
mutex_unlock(&uc->lock);
|
||||
|
||||
|
||||
293
fs/binfmt_elf.c
293
fs/binfmt_elf.c
@@ -109,25 +109,6 @@ static struct linux_binfmt elf_format = {
|
||||
|
||||
#define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE))
|
||||
|
||||
static int set_brk(unsigned long start, unsigned long end, int prot)
|
||||
{
|
||||
start = ELF_PAGEALIGN(start);
|
||||
end = ELF_PAGEALIGN(end);
|
||||
if (end > start) {
|
||||
/*
|
||||
* Map the last of the bss segment.
|
||||
* If the header is requesting these pages to be
|
||||
* executable, honour that (ppc32 needs this).
|
||||
*/
|
||||
int error = vm_brk_flags(start, end - start,
|
||||
prot & PROT_EXEC ? VM_EXEC : 0);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
current->mm->start_brk = current->mm->brk = end;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We need to explicitly zero any fractional pages
|
||||
after the data section (i.e. bss). This would
|
||||
contain the junk from the file that should not
|
||||
@@ -248,7 +229,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
|
||||
} while (0)
|
||||
|
||||
#ifdef ARCH_DLINFO
|
||||
/*
|
||||
/*
|
||||
* ARCH_DLINFO must come first so PPC can do its special alignment of
|
||||
* AUXV.
|
||||
* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in
|
||||
@@ -401,6 +382,51 @@ static unsigned long elf_map(struct file *filep, unsigned long addr,
|
||||
return(map_addr);
|
||||
}
|
||||
|
||||
static unsigned long elf_load(struct file *filep, unsigned long addr,
|
||||
const struct elf_phdr *eppnt, int prot, int type,
|
||||
unsigned long total_size)
|
||||
{
|
||||
unsigned long zero_start, zero_end;
|
||||
unsigned long map_addr;
|
||||
|
||||
if (eppnt->p_filesz) {
|
||||
map_addr = elf_map(filep, addr, eppnt, prot, type, total_size);
|
||||
if (BAD_ADDR(map_addr))
|
||||
return map_addr;
|
||||
if (eppnt->p_memsz > eppnt->p_filesz) {
|
||||
zero_start = map_addr + ELF_PAGEOFFSET(eppnt->p_vaddr) +
|
||||
eppnt->p_filesz;
|
||||
zero_end = map_addr + ELF_PAGEOFFSET(eppnt->p_vaddr) +
|
||||
eppnt->p_memsz;
|
||||
|
||||
/* Zero the end of the last mapped page */
|
||||
padzero(zero_start);
|
||||
}
|
||||
} else {
|
||||
map_addr = zero_start = ELF_PAGESTART(addr);
|
||||
zero_end = zero_start + ELF_PAGEOFFSET(eppnt->p_vaddr) +
|
||||
eppnt->p_memsz;
|
||||
}
|
||||
if (eppnt->p_memsz > eppnt->p_filesz) {
|
||||
/*
|
||||
* Map the last of the segment.
|
||||
* If the header is requesting these pages to be
|
||||
* executable, honour that (ppc32 needs this).
|
||||
*/
|
||||
int error;
|
||||
|
||||
zero_start = ELF_PAGEALIGN(zero_start);
|
||||
zero_end = ELF_PAGEALIGN(zero_end);
|
||||
|
||||
error = vm_brk_flags(zero_start, zero_end - zero_start,
|
||||
prot & PROT_EXEC ? VM_EXEC : 0);
|
||||
if (error)
|
||||
map_addr = error;
|
||||
}
|
||||
return map_addr;
|
||||
}
|
||||
|
||||
|
||||
static unsigned long total_mapping_size(const struct elf_phdr *phdr, int nr)
|
||||
{
|
||||
elf_addr_t min_addr = -1;
|
||||
@@ -829,8 +855,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
unsigned long error;
|
||||
struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL;
|
||||
struct elf_phdr *elf_property_phdata = NULL;
|
||||
unsigned long elf_bss, elf_brk;
|
||||
int bss_prot = 0;
|
||||
unsigned long elf_brk;
|
||||
bool brk_moved = false;
|
||||
int retval, i;
|
||||
unsigned long elf_entry;
|
||||
unsigned long e_entry;
|
||||
@@ -1021,8 +1047,7 @@ out_free_interp:
|
||||
executable_stack);
|
||||
if (retval < 0)
|
||||
goto out_free_dentry;
|
||||
|
||||
elf_bss = 0;
|
||||
|
||||
elf_brk = 0;
|
||||
|
||||
start_code = ~0UL;
|
||||
@@ -1042,33 +1067,6 @@ out_free_interp:
|
||||
if (elf_ppnt->p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
if (unlikely (elf_brk > elf_bss)) {
|
||||
unsigned long nbyte;
|
||||
|
||||
/* There was a PT_LOAD segment with p_memsz > p_filesz
|
||||
before this one. Map anonymous pages, if needed,
|
||||
and clear the area. */
|
||||
retval = set_brk(elf_bss + load_bias,
|
||||
elf_brk + load_bias,
|
||||
bss_prot);
|
||||
if (retval)
|
||||
goto out_free_dentry;
|
||||
nbyte = ELF_PAGEOFFSET(elf_bss);
|
||||
if (nbyte) {
|
||||
nbyte = ELF_MIN_ALIGN - nbyte;
|
||||
if (nbyte > elf_brk - elf_bss)
|
||||
nbyte = elf_brk - elf_bss;
|
||||
if (clear_user((void __user *)elf_bss +
|
||||
load_bias, nbyte)) {
|
||||
/*
|
||||
* This bss-zeroing can fail if the ELF
|
||||
* file specifies odd protections. So
|
||||
* we don't check the return value
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elf_prot = make_prot(elf_ppnt->p_flags, &arch_state,
|
||||
!!interpreter, false);
|
||||
|
||||
@@ -1096,47 +1094,7 @@ out_free_interp:
|
||||
* Header for ET_DYN binaries to calculate the
|
||||
* randomization (load_bias) for all the LOAD
|
||||
* Program Headers.
|
||||
*
|
||||
* There are effectively two types of ET_DYN
|
||||
* binaries: programs (i.e. PIE: ET_DYN with INTERP)
|
||||
* and loaders (ET_DYN without INTERP, since they
|
||||
* _are_ the ELF interpreter). The loaders must
|
||||
* be loaded away from programs since the program
|
||||
* may otherwise collide with the loader (especially
|
||||
* for ET_EXEC which does not have a randomized
|
||||
* position). For example to handle invocations of
|
||||
* "./ld.so someprog" to test out a new version of
|
||||
* the loader, the subsequent program that the
|
||||
* loader loads must avoid the loader itself, so
|
||||
* they cannot share the same load range. Sufficient
|
||||
* room for the brk must be allocated with the
|
||||
* loader as well, since brk must be available with
|
||||
* the loader.
|
||||
*
|
||||
* Therefore, programs are loaded offset from
|
||||
* ELF_ET_DYN_BASE and loaders are loaded into the
|
||||
* independently randomized mmap region (0 load_bias
|
||||
* without MAP_FIXED nor MAP_FIXED_NOREPLACE).
|
||||
*/
|
||||
if (interpreter) {
|
||||
load_bias = ELF_ET_DYN_BASE;
|
||||
if (current->flags & PF_RANDOMIZE)
|
||||
load_bias += arch_mmap_rnd();
|
||||
alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum);
|
||||
if (alignment)
|
||||
load_bias &= ~(alignment - 1);
|
||||
elf_flags |= MAP_FIXED_NOREPLACE;
|
||||
} else
|
||||
load_bias = 0;
|
||||
|
||||
/*
|
||||
* Since load_bias is used for all subsequent loading
|
||||
* calculations, we must lower it by the first vaddr
|
||||
* so that the remaining calculations based on the
|
||||
* ELF vaddrs will be correctly offset. The result
|
||||
* is then page aligned.
|
||||
*/
|
||||
load_bias = ELF_PAGESTART(load_bias - vaddr);
|
||||
|
||||
/*
|
||||
* Calculate the entire size of the ELF mapping
|
||||
@@ -1162,9 +1120,90 @@ out_free_interp:
|
||||
retval = -EINVAL;
|
||||
goto out_free_dentry;
|
||||
}
|
||||
|
||||
/* Calculate any requested alignment. */
|
||||
alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum);
|
||||
|
||||
/**
|
||||
* DOC: PIE handling
|
||||
*
|
||||
* There are effectively two types of ET_DYN ELF
|
||||
* binaries: programs (i.e. PIE: ET_DYN with
|
||||
* PT_INTERP) and loaders (i.e. static PIE: ET_DYN
|
||||
* without PT_INTERP, usually the ELF interpreter
|
||||
* itself). Loaders must be loaded away from programs
|
||||
* since the program may otherwise collide with the
|
||||
* loader (especially for ET_EXEC which does not have
|
||||
* a randomized position).
|
||||
*
|
||||
* For example, to handle invocations of
|
||||
* "./ld.so someprog" to test out a new version of
|
||||
* the loader, the subsequent program that the
|
||||
* loader loads must avoid the loader itself, so
|
||||
* they cannot share the same load range. Sufficient
|
||||
* room for the brk must be allocated with the
|
||||
* loader as well, since brk must be available with
|
||||
* the loader.
|
||||
*
|
||||
* Therefore, programs are loaded offset from
|
||||
* ELF_ET_DYN_BASE and loaders are loaded into the
|
||||
* independently randomized mmap region (0 load_bias
|
||||
* without MAP_FIXED nor MAP_FIXED_NOREPLACE).
|
||||
*
|
||||
* See below for "brk" handling details, which is
|
||||
* also affected by program vs loader and ASLR.
|
||||
*/
|
||||
if (interpreter) {
|
||||
/* On ET_DYN with PT_INTERP, we do the ASLR. */
|
||||
load_bias = ELF_ET_DYN_BASE;
|
||||
if (current->flags & PF_RANDOMIZE)
|
||||
load_bias += arch_mmap_rnd();
|
||||
/* Adjust alignment as requested. */
|
||||
if (alignment)
|
||||
load_bias &= ~(alignment - 1);
|
||||
elf_flags |= MAP_FIXED_NOREPLACE;
|
||||
} else {
|
||||
/*
|
||||
* For ET_DYN without PT_INTERP, we rely on
|
||||
* the architectures's (potentially ASLR) mmap
|
||||
* base address (via a load_bias of 0).
|
||||
*
|
||||
* When a large alignment is requested, we
|
||||
* must do the allocation at address "0" right
|
||||
* now to discover where things will load so
|
||||
* that we can adjust the resulting alignment.
|
||||
* In this case (load_bias != 0), we can use
|
||||
* MAP_FIXED_NOREPLACE to make sure the mapping
|
||||
* doesn't collide with anything.
|
||||
*/
|
||||
if (alignment > ELF_MIN_ALIGN) {
|
||||
load_bias = elf_load(bprm->file, 0, elf_ppnt,
|
||||
elf_prot, elf_flags, total_size);
|
||||
if (BAD_ADDR(load_bias)) {
|
||||
retval = IS_ERR_VALUE(load_bias) ?
|
||||
PTR_ERR((void*)load_bias) : -EINVAL;
|
||||
goto out_free_dentry;
|
||||
}
|
||||
vm_munmap(load_bias, total_size);
|
||||
/* Adjust alignment as requested. */
|
||||
if (alignment)
|
||||
load_bias &= ~(alignment - 1);
|
||||
elf_flags |= MAP_FIXED_NOREPLACE;
|
||||
} else
|
||||
load_bias = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since load_bias is used for all subsequent loading
|
||||
* calculations, we must lower it by the first vaddr
|
||||
* so that the remaining calculations based on the
|
||||
* ELF vaddrs will be correctly offset. The result
|
||||
* is then page aligned.
|
||||
*/
|
||||
load_bias = ELF_PAGESTART(load_bias - vaddr);
|
||||
}
|
||||
|
||||
error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
|
||||
error = elf_load(bprm->file, load_bias + vaddr, elf_ppnt,
|
||||
elf_prot, elf_flags, total_size);
|
||||
if (BAD_ADDR(error)) {
|
||||
retval = IS_ERR((void *)error) ?
|
||||
@@ -1212,41 +1251,23 @@ out_free_interp:
|
||||
|
||||
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
|
||||
|
||||
if (k > elf_bss)
|
||||
elf_bss = k;
|
||||
if ((elf_ppnt->p_flags & PF_X) && end_code < k)
|
||||
end_code = k;
|
||||
if (end_data < k)
|
||||
end_data = k;
|
||||
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
|
||||
if (k > elf_brk) {
|
||||
bss_prot = elf_prot;
|
||||
if (k > elf_brk)
|
||||
elf_brk = k;
|
||||
}
|
||||
}
|
||||
|
||||
e_entry = elf_ex->e_entry + load_bias;
|
||||
phdr_addr += load_bias;
|
||||
elf_bss += load_bias;
|
||||
elf_brk += load_bias;
|
||||
start_code += load_bias;
|
||||
end_code += load_bias;
|
||||
start_data += load_bias;
|
||||
end_data += load_bias;
|
||||
|
||||
/* Calling set_brk effectively mmaps the pages that we need
|
||||
* for the bss and break sections. We must do this before
|
||||
* mapping in the interpreter, to make sure it doesn't wind
|
||||
* up getting placed where the bss needs to go.
|
||||
*/
|
||||
retval = set_brk(elf_bss, elf_brk, bss_prot);
|
||||
if (retval)
|
||||
goto out_free_dentry;
|
||||
if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
|
||||
retval = -EFAULT; /* Nobody gets to see this, but.. */
|
||||
goto out_free_dentry;
|
||||
}
|
||||
|
||||
if (interpreter) {
|
||||
elf_entry = load_elf_interp(interp_elf_ex,
|
||||
interpreter,
|
||||
@@ -1302,24 +1323,44 @@ out_free_interp:
|
||||
mm->end_data = end_data;
|
||||
mm->start_stack = bprm->p;
|
||||
|
||||
if ((current->flags & PF_RANDOMIZE) && (snapshot_randomize_va_space > 1)) {
|
||||
/**
|
||||
* DOC: "brk" handling
|
||||
*
|
||||
* For architectures with ELF randomization, when executing a
|
||||
* loader directly (i.e. static PIE: ET_DYN without PT_INTERP),
|
||||
* move the brk area out of the mmap region and into the unused
|
||||
* ELF_ET_DYN_BASE region. Since "brk" grows up it may collide
|
||||
* early with the stack growing down or other regions being put
|
||||
* into the mmap region by the kernel (e.g. vdso).
|
||||
*
|
||||
* In the CONFIG_COMPAT_BRK case, though, everything is turned
|
||||
* off because we're not allowed to move the brk at all.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_COMPAT_BRK) &&
|
||||
IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
|
||||
elf_ex->e_type == ET_DYN && !interpreter) {
|
||||
elf_brk = ELF_ET_DYN_BASE;
|
||||
/* This counts as moving the brk, so let brk(2) know. */
|
||||
brk_moved = true;
|
||||
}
|
||||
mm->start_brk = mm->brk = ELF_PAGEALIGN(elf_brk);
|
||||
|
||||
if ((current->flags & PF_RANDOMIZE) && snapshot_randomize_va_space > 1) {
|
||||
/*
|
||||
* For architectures with ELF randomization, when executing
|
||||
* a loader directly (i.e. no interpreter listed in ELF
|
||||
* headers), move the brk area out of the mmap region
|
||||
* (since it grows up, and may collide early with the stack
|
||||
* growing down), and into the unused ELF_ET_DYN_BASE region.
|
||||
* If we didn't move the brk to ELF_ET_DYN_BASE (above),
|
||||
* leave a gap between .bss and brk.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_ARCH_HAS_ELF_RANDOMIZE) &&
|
||||
elf_ex->e_type == ET_DYN && !interpreter) {
|
||||
mm->brk = mm->start_brk = ELF_ET_DYN_BASE;
|
||||
}
|
||||
if (!brk_moved)
|
||||
mm->brk = mm->start_brk = mm->brk + PAGE_SIZE;
|
||||
|
||||
mm->brk = mm->start_brk = arch_randomize_brk(mm);
|
||||
brk_moved = true;
|
||||
}
|
||||
|
||||
#ifdef compat_brk_randomized
|
||||
if (brk_moved)
|
||||
current->brk_randomized = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (current->personality & MMAP_PAGE_ZERO) {
|
||||
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
|
||||
@@ -1522,7 +1563,7 @@ static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, loff_t offset)
|
||||
phdr->p_align = 0;
|
||||
}
|
||||
|
||||
static void fill_note(struct memelfnote *note, const char *name, int type,
|
||||
static void fill_note(struct memelfnote *note, const char *name, int type,
|
||||
unsigned int sz, void *data)
|
||||
{
|
||||
note->name = name;
|
||||
@@ -2005,8 +2046,8 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
|
||||
t->num_notes = 0;
|
||||
|
||||
fill_prstatus(&t->prstatus.common, p, signr);
|
||||
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
||||
|
||||
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
||||
|
||||
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
|
||||
&(t->prstatus));
|
||||
t->num_notes++;
|
||||
@@ -2296,7 +2337,7 @@ static int elf_core_dump(struct coredump_params *cprm)
|
||||
if (!elf_core_write_extra_phdrs(cprm, offset))
|
||||
goto end_coredump;
|
||||
|
||||
/* write out the notes section */
|
||||
/* write out the notes section */
|
||||
if (!write_note_info(&info, cprm))
|
||||
goto end_coredump;
|
||||
|
||||
|
||||
@@ -1603,7 +1603,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
||||
if (!elf_core_write_extra_phdrs(cprm, offset))
|
||||
goto end_coredump;
|
||||
|
||||
/* write out the notes section */
|
||||
/* write out the notes section */
|
||||
if (!writenote(thread_list->notes, cprm))
|
||||
goto end_coredump;
|
||||
if (!writenote(&psinfo_note, cprm))
|
||||
|
||||
@@ -78,8 +78,6 @@ static void __add_to_discard_list(struct btrfs_discard_ctl *discard_ctl,
|
||||
struct btrfs_block_group *block_group)
|
||||
{
|
||||
lockdep_assert_held(&discard_ctl->lock);
|
||||
if (!btrfs_run_discard_work(discard_ctl))
|
||||
return;
|
||||
|
||||
if (list_empty(&block_group->discard_list) ||
|
||||
block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED) {
|
||||
@@ -102,6 +100,9 @@ static void add_to_discard_list(struct btrfs_discard_ctl *discard_ctl,
|
||||
if (!btrfs_is_block_group_data_only(block_group))
|
||||
return;
|
||||
|
||||
if (!btrfs_run_discard_work(discard_ctl))
|
||||
return;
|
||||
|
||||
spin_lock(&discard_ctl->lock);
|
||||
__add_to_discard_list(discard_ctl, block_group);
|
||||
spin_unlock(&discard_ctl->lock);
|
||||
@@ -233,6 +234,18 @@ again:
|
||||
block_group->used != 0) {
|
||||
if (btrfs_is_block_group_data_only(block_group)) {
|
||||
__add_to_discard_list(discard_ctl, block_group);
|
||||
/*
|
||||
* The block group must have been moved to other
|
||||
* discard list even if discard was disabled in
|
||||
* the meantime or a transaction abort happened,
|
||||
* otherwise we can end up in an infinite loop,
|
||||
* always jumping into the 'again' label and
|
||||
* keep getting this block group over and over
|
||||
* in case there are no other block groups in
|
||||
* the discard lists.
|
||||
*/
|
||||
ASSERT(block_group->discard_index !=
|
||||
BTRFS_DISCARD_INDEX_UNUSED);
|
||||
} else {
|
||||
list_del_init(&block_group->discard_list);
|
||||
btrfs_put_block_group(block_group);
|
||||
|
||||
@@ -179,6 +179,14 @@ search_again:
|
||||
ei = btrfs_item_ptr(leaf, path->slots[0],
|
||||
struct btrfs_extent_item);
|
||||
num_refs = btrfs_extent_refs(leaf, ei);
|
||||
if (unlikely(num_refs == 0)) {
|
||||
ret = -EUCLEAN;
|
||||
btrfs_err(fs_info,
|
||||
"unexpected zero reference count for extent item (%llu %u %llu)",
|
||||
key.objectid, key.type, key.offset);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out_free;
|
||||
}
|
||||
extent_flags = btrfs_extent_flags(leaf, ei);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
@@ -190,8 +198,6 @@ search_again:
|
||||
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
BUG_ON(num_refs == 0);
|
||||
} else {
|
||||
num_refs = 0;
|
||||
extent_flags = 0;
|
||||
@@ -221,10 +227,19 @@ search_again:
|
||||
goto search_again;
|
||||
}
|
||||
spin_lock(&head->lock);
|
||||
if (head->extent_op && head->extent_op->update_flags)
|
||||
if (head->extent_op && head->extent_op->update_flags) {
|
||||
extent_flags |= head->extent_op->flags_to_set;
|
||||
else
|
||||
BUG_ON(num_refs == 0);
|
||||
} else if (unlikely(num_refs == 0)) {
|
||||
spin_unlock(&head->lock);
|
||||
mutex_unlock(&head->mutex);
|
||||
spin_unlock(&delayed_refs->lock);
|
||||
ret = -EUCLEAN;
|
||||
btrfs_err(fs_info,
|
||||
"unexpected zero reference count for extent %llu (%s)",
|
||||
bytenr, metadata ? "metadata" : "data");
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_refs += head->ref_mod;
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
@@ -170,7 +170,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
|
||||
exit:
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
return error;
|
||||
}
|
||||
#endif /* #ifdef CONFIG_USELIB */
|
||||
|
||||
|
||||
@@ -6886,10 +6886,18 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
|
||||
struct nfs4_unlockdata *p;
|
||||
struct nfs4_state *state = lsp->ls_state;
|
||||
struct inode *inode = state->inode;
|
||||
struct nfs_lock_context *l_ctx;
|
||||
|
||||
p = kzalloc(sizeof(*p), GFP_KERNEL);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
l_ctx = nfs_get_lock_context(ctx);
|
||||
if (!IS_ERR(l_ctx)) {
|
||||
p->l_ctx = l_ctx;
|
||||
} else {
|
||||
kfree(p);
|
||||
return NULL;
|
||||
}
|
||||
p->arg.fh = NFS_FH(inode);
|
||||
p->arg.fl = &p->fl;
|
||||
p->arg.seqid = seqid;
|
||||
@@ -6897,7 +6905,6 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
|
||||
p->lsp = lsp;
|
||||
/* Ensure we don't close file until we're done freeing locks! */
|
||||
p->ctx = get_nfs_open_context(ctx);
|
||||
p->l_ctx = nfs_get_lock_context(ctx);
|
||||
locks_init_lock(&p->fl);
|
||||
locks_copy_lock(&p->fl, fl);
|
||||
p->server = NFS_SERVER(inode);
|
||||
|
||||
@@ -732,6 +732,14 @@ pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
|
||||
return remaining;
|
||||
}
|
||||
|
||||
static void pnfs_reset_return_info(struct pnfs_layout_hdr *lo)
|
||||
{
|
||||
struct pnfs_layout_segment *lseg;
|
||||
|
||||
list_for_each_entry(lseg, &lo->plh_return_segs, pls_list)
|
||||
pnfs_set_plh_return_info(lo, lseg->pls_range.iomode, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
pnfs_free_returned_lsegs(struct pnfs_layout_hdr *lo,
|
||||
struct list_head *free_me,
|
||||
@@ -1180,6 +1188,7 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
|
||||
pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);
|
||||
pnfs_free_returned_lsegs(lo, &freeme, range, seq);
|
||||
pnfs_set_layout_stateid(lo, stateid, NULL, true);
|
||||
pnfs_reset_return_info(lo);
|
||||
} else
|
||||
pnfs_mark_layout_stateid_invalid(lo, &freeme);
|
||||
out_unlock:
|
||||
|
||||
@@ -2826,7 +2826,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
|
||||
/* Eventually save off posix specific response info and timestaps */
|
||||
|
||||
err_free_rsp_buf:
|
||||
free_rsp_buf(resp_buftype, rsp);
|
||||
free_rsp_buf(resp_buftype, rsp_iov.iov_base);
|
||||
kfree(pc_buf);
|
||||
err_free_req:
|
||||
cifs_small_buf_release(req);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/uio.h>
|
||||
|
||||
#define BIO_MAX_VECS 256U
|
||||
#define BIO_MAX_INLINE_VECS UIO_MAXIOV
|
||||
|
||||
static inline unsigned int bio_max_segs(unsigned int nr_segs)
|
||||
{
|
||||
|
||||
@@ -1224,13 +1224,6 @@ extern int vmbus_sendpacket(struct vmbus_channel *channel,
|
||||
enum vmbus_packet_type type,
|
||||
u32 flags);
|
||||
|
||||
extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
|
||||
struct hv_page_buffer pagebuffers[],
|
||||
u32 pagecount,
|
||||
void *buffer,
|
||||
u32 bufferlen,
|
||||
u64 requestid);
|
||||
|
||||
extern int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
||||
struct vmbus_packet_mpb_array *mpb,
|
||||
u32 desc_size,
|
||||
|
||||
@@ -181,7 +181,7 @@ enum tpm2_const {
|
||||
|
||||
enum tpm2_timeouts {
|
||||
TPM2_TIMEOUT_A = 750,
|
||||
TPM2_TIMEOUT_B = 2000,
|
||||
TPM2_TIMEOUT_B = 4000,
|
||||
TPM2_TIMEOUT_C = 200,
|
||||
TPM2_TIMEOUT_D = 30,
|
||||
TPM2_DURATION_SHORT = 20,
|
||||
|
||||
@@ -1045,6 +1045,7 @@ struct nft_rule_blob {
|
||||
* @use: number of jump references to this chain
|
||||
* @flags: bitmask of enum nft_chain_flags
|
||||
* @name: name of the chain
|
||||
* @rcu_head: rcu head for deferred release
|
||||
*/
|
||||
struct nft_chain {
|
||||
struct nft_rule_blob __rcu *blob_gen_0;
|
||||
@@ -1121,7 +1122,7 @@ static inline bool nft_chain_is_bound(struct nft_chain *chain)
|
||||
|
||||
int nft_chain_add(struct nft_table *table, struct nft_chain *chain);
|
||||
void nft_chain_del(struct nft_chain *chain);
|
||||
void nf_tables_chain_destroy(struct nft_ctx *ctx);
|
||||
void nf_tables_chain_destroy(struct nft_chain *chain);
|
||||
|
||||
struct nft_stats {
|
||||
u64 bytes;
|
||||
|
||||
@@ -1003,6 +1003,21 @@ static inline struct sk_buff *__qdisc_dequeue_head(struct qdisc_skb_head *qh)
|
||||
return skb;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *qdisc_dequeue_internal(struct Qdisc *sch, bool direct)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __skb_dequeue(&sch->gso_skb);
|
||||
if (skb) {
|
||||
sch->q.qlen--;
|
||||
return skb;
|
||||
}
|
||||
if (direct)
|
||||
return __qdisc_dequeue_head(&sch->q);
|
||||
else
|
||||
return sch->dequeue(sch);
|
||||
}
|
||||
|
||||
static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
|
||||
|
||||
@@ -91,7 +91,7 @@ typedef __s64 Elf64_Sxword;
|
||||
#define DT_INIT 12
|
||||
#define DT_FINI 13
|
||||
#define DT_SONAME 14
|
||||
#define DT_RPATH 15
|
||||
#define DT_RPATH 15
|
||||
#define DT_SYMBOLIC 16
|
||||
#define DT_REL 17
|
||||
#define DT_RELSZ 18
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "trace_output.h" /* for trace_event_sem */
|
||||
#include "trace_dynevent.h"
|
||||
|
||||
static DEFINE_MUTEX(dyn_event_ops_mutex);
|
||||
DEFINE_MUTEX(dyn_event_ops_mutex);
|
||||
static LIST_HEAD(dyn_event_ops_list);
|
||||
|
||||
bool trace_event_dyn_try_get_ref(struct trace_event_call *dyn_call)
|
||||
@@ -125,6 +125,20 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locked version of event creation. The event creation must be protected by
|
||||
* dyn_event_ops_mutex because of protecting trace_probe_log.
|
||||
*/
|
||||
int dyn_event_create(const char *raw_command, struct dyn_event_operations *type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dyn_event_ops_mutex);
|
||||
ret = type->create(raw_command);
|
||||
mutex_unlock(&dyn_event_ops_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int create_dyn_event(const char *raw_command)
|
||||
{
|
||||
struct dyn_event_operations *ops;
|
||||
|
||||
@@ -100,6 +100,7 @@ void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos);
|
||||
void dyn_event_seq_stop(struct seq_file *m, void *v);
|
||||
int dyn_events_release_all(struct dyn_event_operations *type);
|
||||
int dyn_event_release(const char *raw_command, struct dyn_event_operations *type);
|
||||
int dyn_event_create(const char *raw_command, struct dyn_event_operations *type);
|
||||
|
||||
/*
|
||||
* for_each_dyn_event - iterate over the dyn_event list
|
||||
|
||||
@@ -1539,7 +1539,7 @@ stacktrace_trigger(struct event_trigger_data *data,
|
||||
struct trace_event_file *file = data->private_data;
|
||||
|
||||
if (file)
|
||||
__trace_stack(file->tr, tracing_gen_ctx(), STACK_SKIP);
|
||||
__trace_stack(file->tr, tracing_gen_ctx_dec(), STACK_SKIP);
|
||||
else
|
||||
trace_dump_stack(STACK_SKIP);
|
||||
}
|
||||
|
||||
@@ -561,11 +561,7 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip,
|
||||
|
||||
static __always_inline void trace_stack(struct trace_array *tr)
|
||||
{
|
||||
unsigned int trace_ctx;
|
||||
|
||||
trace_ctx = tracing_gen_ctx();
|
||||
|
||||
__trace_stack(tr, trace_ctx, FTRACE_STACK_SKIP);
|
||||
__trace_stack(tr, tracing_gen_ctx_dec(), FTRACE_STACK_SKIP);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -975,7 +975,7 @@ static int create_or_delete_trace_kprobe(const char *raw_command)
|
||||
if (raw_command[0] == '-')
|
||||
return dyn_event_release(raw_command, &trace_kprobe_ops);
|
||||
|
||||
ret = trace_kprobe_create(raw_command);
|
||||
ret = dyn_event_create(raw_command, &trace_kprobe_ops);
|
||||
return ret == -ECANCELED ? -EINVAL : ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,9 +143,12 @@ fail:
|
||||
}
|
||||
|
||||
static struct trace_probe_log trace_probe_log;
|
||||
extern struct mutex dyn_event_ops_mutex;
|
||||
|
||||
void trace_probe_log_init(const char *subsystem, int argc, const char **argv)
|
||||
{
|
||||
lockdep_assert_held(&dyn_event_ops_mutex);
|
||||
|
||||
trace_probe_log.subsystem = subsystem;
|
||||
trace_probe_log.argc = argc;
|
||||
trace_probe_log.argv = argv;
|
||||
@@ -154,11 +157,15 @@ void trace_probe_log_init(const char *subsystem, int argc, const char **argv)
|
||||
|
||||
void trace_probe_log_clear(void)
|
||||
{
|
||||
lockdep_assert_held(&dyn_event_ops_mutex);
|
||||
|
||||
memset(&trace_probe_log, 0, sizeof(trace_probe_log));
|
||||
}
|
||||
|
||||
void trace_probe_log_set_index(int index)
|
||||
{
|
||||
lockdep_assert_held(&dyn_event_ops_mutex);
|
||||
|
||||
trace_probe_log.index = index;
|
||||
}
|
||||
|
||||
@@ -167,6 +174,8 @@ void __trace_probe_log_err(int offset, int err_type)
|
||||
char *command, *p;
|
||||
int i, len = 0, pos = 0;
|
||||
|
||||
lockdep_assert_held(&dyn_event_ops_mutex);
|
||||
|
||||
if (!trace_probe_log.argv)
|
||||
return;
|
||||
|
||||
|
||||
@@ -732,7 +732,7 @@ static int create_or_delete_trace_uprobe(const char *raw_command)
|
||||
if (raw_command[0] == '-')
|
||||
return dyn_event_release(raw_command, &trace_uprobe_ops);
|
||||
|
||||
ret = trace_uprobe_create(raw_command);
|
||||
ret = dyn_event_create(raw_command, &trace_uprobe_ops);
|
||||
return ret == -ECANCELED ? -EINVAL : ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1656,8 +1656,12 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
|
||||
if (PageHWPoison(page)) {
|
||||
if (WARN_ON(folio_test_lru(folio)))
|
||||
folio_isolate_lru(folio);
|
||||
if (folio_mapped(folio))
|
||||
if (folio_mapped(folio)) {
|
||||
folio_lock(folio);
|
||||
try_to_unmap(folio, TTU_IGNORE_MLOCK);
|
||||
folio_unlock(folio);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -2430,6 +2430,14 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
|
||||
if (managed_zone(pgdat->node_zones + z))
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are no managed zones, it should not proceed
|
||||
* further.
|
||||
*/
|
||||
if (z < 0)
|
||||
return 0;
|
||||
|
||||
wakeup_kswapd(pgdat->node_zones + z, 0, order, ZONE_MOVABLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1580,7 +1580,8 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
|
||||
* so icmphdr does not in skb linear region and can not get icmp_type
|
||||
* by icmp_hdr(skb)->type.
|
||||
*/
|
||||
if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl)
|
||||
if (sk->sk_type == SOCK_RAW &&
|
||||
!(fl4->flowi4_flags & FLOWI_FLAG_KNOWN_NH))
|
||||
icmp_type = fl4->fl4_icmp_type;
|
||||
else
|
||||
icmp_type = icmp_hdr(skb)->type;
|
||||
|
||||
@@ -608,6 +608,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
(hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
|
||||
daddr, saddr, 0, 0, sk->sk_uid);
|
||||
|
||||
fl4.fl4_icmp_type = 0;
|
||||
fl4.fl4_icmp_code = 0;
|
||||
|
||||
if (!hdrincl) {
|
||||
rfv.msg = msg;
|
||||
rfv.hlen = 0;
|
||||
|
||||
@@ -1985,7 +1985,8 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
|
||||
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
||||
u8 icmp6_type;
|
||||
|
||||
if (sk->sk_socket->type == SOCK_RAW && !inet_sk(sk)->hdrincl)
|
||||
if (sk->sk_socket->type == SOCK_RAW &&
|
||||
!(fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH))
|
||||
icmp6_type = fl6->fl6_icmp_type;
|
||||
else
|
||||
icmp6_type = icmp6_hdr(skb)->icmp6_type;
|
||||
|
||||
@@ -274,8 +274,10 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev)
|
||||
|
||||
key = flow->key;
|
||||
|
||||
if (WARN_ON(key->dev && key->dev != dev))
|
||||
if (key->dev) {
|
||||
WARN_ON(key->dev != dev);
|
||||
return;
|
||||
}
|
||||
|
||||
mctp_dev_set_key(dev, key);
|
||||
}
|
||||
|
||||
@@ -2034,9 +2034,9 @@ static void nf_tables_chain_free_chain_rules(struct nft_chain *chain)
|
||||
kvfree(chain->blob_next);
|
||||
}
|
||||
|
||||
void nf_tables_chain_destroy(struct nft_ctx *ctx)
|
||||
void nf_tables_chain_destroy(struct nft_chain *chain)
|
||||
{
|
||||
struct nft_chain *chain = ctx->chain;
|
||||
const struct nft_table *table = chain->table;
|
||||
struct nft_hook *hook, *next;
|
||||
|
||||
if (WARN_ON(chain->use > 0))
|
||||
@@ -2048,7 +2048,7 @@ void nf_tables_chain_destroy(struct nft_ctx *ctx)
|
||||
if (nft_is_base_chain(chain)) {
|
||||
struct nft_base_chain *basechain = nft_base_chain(chain);
|
||||
|
||||
if (nft_base_chain_netdev(ctx->family, basechain->ops.hooknum)) {
|
||||
if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) {
|
||||
list_for_each_entry_safe(hook, next,
|
||||
&basechain->hook_list, list) {
|
||||
list_del_rcu(&hook->list);
|
||||
@@ -2515,7 +2515,7 @@ err_chain_add:
|
||||
err_trans:
|
||||
nft_use_dec_restore(&table->use);
|
||||
err_destroy_chain:
|
||||
nf_tables_chain_destroy(ctx);
|
||||
nf_tables_chain_destroy(chain);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -3510,8 +3510,11 @@ void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule)
|
||||
kfree(rule);
|
||||
}
|
||||
|
||||
/* can only be used if rule is no longer visible to dumps */
|
||||
static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
|
||||
{
|
||||
lockdep_commit_lock_is_held(ctx->net);
|
||||
|
||||
nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
|
||||
nf_tables_rule_destroy(ctx, rule);
|
||||
}
|
||||
@@ -5247,6 +5250,8 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
||||
struct nft_set_binding *binding,
|
||||
enum nft_trans_phase phase)
|
||||
{
|
||||
lockdep_commit_lock_is_held(ctx->net);
|
||||
|
||||
switch (phase) {
|
||||
case NFT_TRANS_PREPARE_ERROR:
|
||||
nft_set_trans_unbind(ctx, set);
|
||||
@@ -8994,7 +8999,7 @@ static void nft_commit_release(struct nft_trans *trans)
|
||||
kfree(nft_trans_chain_name(trans));
|
||||
break;
|
||||
case NFT_MSG_DELCHAIN:
|
||||
nf_tables_chain_destroy(&trans->ctx);
|
||||
nf_tables_chain_destroy(nft_trans_chain(trans));
|
||||
break;
|
||||
case NFT_MSG_DELRULE:
|
||||
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
|
||||
@@ -9955,7 +9960,7 @@ static void nf_tables_abort_release(struct nft_trans *trans)
|
||||
nf_tables_table_destroy(&trans->ctx);
|
||||
break;
|
||||
case NFT_MSG_NEWCHAIN:
|
||||
nf_tables_chain_destroy(&trans->ctx);
|
||||
nf_tables_chain_destroy(nft_trans_chain(trans));
|
||||
break;
|
||||
case NFT_MSG_NEWRULE:
|
||||
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
|
||||
@@ -10662,23 +10667,43 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_data_dump);
|
||||
|
||||
int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
static void __nft_release_basechain_now(struct nft_ctx *ctx)
|
||||
{
|
||||
struct nft_rule *rule, *nr;
|
||||
|
||||
if (WARN_ON(!nft_is_base_chain(ctx->chain)))
|
||||
list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
|
||||
list_del(&rule->list);
|
||||
nf_tables_rule_release(ctx, rule);
|
||||
}
|
||||
nf_tables_chain_destroy(ctx->chain);
|
||||
}
|
||||
|
||||
int __nft_release_basechain(struct nft_ctx *ctx)
|
||||
{
|
||||
struct nft_rule *rule;
|
||||
|
||||
if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
|
||||
return 0;
|
||||
|
||||
nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
|
||||
list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
|
||||
list_del(&rule->list);
|
||||
list_for_each_entry(rule, &ctx->chain->rules, list)
|
||||
nft_use_dec(&ctx->chain->use);
|
||||
nf_tables_rule_release(ctx, rule);
|
||||
}
|
||||
|
||||
nft_chain_del(ctx->chain);
|
||||
nft_use_dec(&ctx->table->use);
|
||||
nf_tables_chain_destroy(ctx);
|
||||
|
||||
if (!maybe_get_net(ctx->net)) {
|
||||
__nft_release_basechain_now(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wait for ruleset dumps to complete. Owning chain is no longer in
|
||||
* lists, so new dumps can't find any of these rules anymore.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
|
||||
__nft_release_basechain_now(ctx);
|
||||
put_net(ctx->net);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__nft_release_basechain);
|
||||
@@ -10753,10 +10778,9 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
|
||||
nft_obj_destroy(&ctx, obj);
|
||||
}
|
||||
list_for_each_entry_safe(chain, nc, &table->chains, list) {
|
||||
ctx.chain = chain;
|
||||
nft_chain_del(chain);
|
||||
nft_use_dec(&table->use);
|
||||
nf_tables_chain_destroy(&ctx);
|
||||
nf_tables_chain_destroy(chain);
|
||||
}
|
||||
nf_tables_table_destroy(&ctx);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ static void nft_immediate_destroy(const struct nft_ctx *ctx,
|
||||
list_del(&rule->list);
|
||||
nf_tables_rule_destroy(&chain_ctx, rule);
|
||||
}
|
||||
nf_tables_chain_destroy(&chain_ctx);
|
||||
nf_tables_chain_destroy(chain);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -168,7 +168,7 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
|
||||
qlen = sch->q.qlen;
|
||||
while (sch->q.qlen > sch->limit) {
|
||||
struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
|
||||
struct sk_buff *skb = qdisc_dequeue_internal(sch, true);
|
||||
|
||||
dropped += qdisc_pkt_len(skb);
|
||||
qdisc_qstats_backlog_dec(sch, skb);
|
||||
|
||||
@@ -901,7 +901,7 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
sch_tree_lock(sch);
|
||||
}
|
||||
while (sch->q.qlen > sch->limit) {
|
||||
struct sk_buff *skb = fq_dequeue(sch);
|
||||
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
|
||||
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
@@ -431,7 +431,7 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
|
||||
while (sch->q.qlen > sch->limit ||
|
||||
q->memory_usage > q->memory_limit) {
|
||||
struct sk_buff *skb = fq_codel_dequeue(sch);
|
||||
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
|
||||
|
||||
q->cstats.drop_len += qdisc_pkt_len(skb);
|
||||
rtnl_kfree_skbs(skb, skb);
|
||||
|
||||
@@ -357,7 +357,7 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
|
||||
/* Drop excess packets if new limit is lower */
|
||||
while (sch->q.qlen > sch->limit) {
|
||||
struct sk_buff *skb = fq_pie_qdisc_dequeue(sch);
|
||||
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
|
||||
|
||||
len_dropped += qdisc_pkt_len(skb);
|
||||
num_dropped += 1;
|
||||
|
||||
@@ -560,7 +560,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
qlen = sch->q.qlen;
|
||||
prev_backlog = sch->qstats.backlog;
|
||||
while (sch->q.qlen > sch->limit) {
|
||||
struct sk_buff *skb = hhf_dequeue(sch);
|
||||
struct sk_buff *skb = qdisc_dequeue_internal(sch, false);
|
||||
|
||||
rtnl_kfree_skbs(skb, skb);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
/* Drop excess packets if new limit is lower */
|
||||
qlen = sch->q.qlen;
|
||||
while (sch->q.qlen > sch->limit) {
|
||||
struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
|
||||
struct sk_buff *skb = qdisc_dequeue_internal(sch, true);
|
||||
|
||||
dropped += qdisc_pkt_len(skb);
|
||||
qdisc_qstats_backlog_dec(sch, skb);
|
||||
|
||||
@@ -518,6 +518,8 @@ static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(sctp_sysctl_mutex);
|
||||
|
||||
static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
@@ -542,6 +544,7 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
|
||||
if (new_value > max || new_value < min)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&sctp_sysctl_mutex);
|
||||
net->sctp.udp_port = new_value;
|
||||
sctp_udp_sock_stop(net);
|
||||
if (new_value) {
|
||||
@@ -554,6 +557,7 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
|
||||
lock_sock(sk);
|
||||
sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
|
||||
release_sock(sk);
|
||||
mutex_unlock(&sctp_sysctl_mutex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -396,7 +396,6 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
|
||||
return 0;
|
||||
|
||||
shinfo = skb_shinfo(strp->anchor);
|
||||
shinfo->frag_list = NULL;
|
||||
|
||||
/* If we don't know the length go max plus page for cipher overhead */
|
||||
need_spc = strp->stm.full_len ?: TLS_MAX_PAYLOAD_SIZE + PAGE_SIZE;
|
||||
@@ -412,6 +411,8 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
|
||||
page, 0, 0);
|
||||
}
|
||||
|
||||
shinfo->frag_list = NULL;
|
||||
|
||||
strp->copy_mode = 1;
|
||||
strp->stm.offset = 0;
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ static int __init sample_trace_array_init(void)
|
||||
/*
|
||||
* If context specific per-cpu buffers havent already been allocated.
|
||||
*/
|
||||
trace_printk_init_buffers();
|
||||
trace_array_init_printk(tr);
|
||||
|
||||
simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
|
||||
if (IS_ERR(simple_tsk)) {
|
||||
|
||||
@@ -1569,7 +1569,7 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct es1968 *chip = snd_pcm_substream_chip(substream);
|
||||
struct esschan *es;
|
||||
int apu1, apu2;
|
||||
int err, apu1, apu2;
|
||||
|
||||
apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
|
||||
if (apu1 < 0)
|
||||
@@ -1613,7 +1613,9 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
|
||||
runtime->hw = snd_es1968_capture;
|
||||
runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
|
||||
calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
|
||||
snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
|
||||
err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
spin_lock_irq(&chip->substream_lock);
|
||||
list_add(&es->list, &chip->substream_list);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user