Merge 5.15.112 into android14-5.15-lts

Changes in 5.15.112
	ring-buffer: Ensure proper resetting of atomic variables in ring_buffer_reset_online_cpus
	crypto: ccp - Clear PSP interrupt status register before calling handler
	ubifs: Fix AA deadlock when setting xattr for encrypted file
	ubifs: Fix memory leak in do_rename
	bus: mhi: Move host MHI code to "host" directory
	bus: mhi: host: Remove duplicate ee check for syserr
	bus: mhi: host: Use mhi_tryset_pm_state() for setting fw error state
	bus: mhi: host: Range check CHDBOFF and ERDBOFF
	mailbox: zynq: Switch to flexible array to simplify code
	mailbox: zynqmp: Fix counts of child nodes
	ASoC: soc-pcm: use GFP_ATOMIC for dpcm structure
	ASoC: soc-pcm: align BE 'atomicity' with that of the FE
	ASoC: soc-pcm: Fix and cleanup DPCM locking
	ASoC: soc-pcm: serialize BE triggers
	ASoC: soc-pcm: test refcount before triggering
	ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE
	fs/ntfs3: Fix null-ptr-deref on inode->i_op in ntfs_lookup()
	drm/hyperv: Don't overwrite dirt_needed value set by host
	scsi: qedi: Fix use after free bug in qedi_remove()
	net/ncsi: clear Tx enable mode when handling a Config required AEN
	net/sched: cls_api: remove block_cb from driver_list before freeing
	sit: update dev->needed_headroom in ipip6_tunnel_bind_dev()
	selftests: srv6: make srv6_end_dt46_l3vpn_test more robust
	net: dsa: mv88e6xxx: add mv88e6321 rsvd2cpu
	writeback: fix call of incorrect macro
	watchdog: dw_wdt: Fix the error handling path of dw_wdt_drv_probe()
	RISC-V: mm: Enable huge page support to kernel_page_present() function
	net/sched: act_mirred: Add carrier check
	r8152: fix flow control issue of RTL8156A
	r8152: fix the poor throughput for 2.5G devices
	r8152: move setting r8153b_rx_agg_chg_indicate()
	sfc: Fix module EEPROM reporting for QSFP modules
	rxrpc: Fix hard call timeout units
	octeontx2-af: Secure APR table update with the lock
	octeontx2-af: Skip PFs if not enabled
	octeontx2-pf: Disable packet I/O for graceful exit
	octeontx2-vf: Detach LF resources on probe cleanup
	ionic: remove noise from ethtool rxnfc error msg
	ethtool: Fix uninitialized number of lanes
	ionic: catch failure from devlink_alloc
	af_packet: Don't send zero-byte data in packet_sendmsg_spkt().
	drm/amdgpu: add a missing lock for AMDGPU_SCHED
	ALSA: caiaq: input: Add error handling for unsupported input methods in `snd_usb_caiaq_input_init`
	net: dsa: mt7530: fix corrupt frames using trgmii on 40 MHz XTAL MT7621
	virtio_net: split free_unused_bufs()
	virtio_net: suppress cpu stall when free_unused_bufs
	net: enetc: check the index of the SFI rather than the handle
	perf scripts intel-pt-events.py: Fix IPC output for Python 2
	perf vendor events power9: Remove UTF-8 characters from JSON files
	perf pmu: zfree() expects a pointer to a pointer to zero it after freeing its contents
	perf map: Delete two variable initialisations before null pointer checks in sort__sym_from_cmp()
	crypto: sun8i-ss - Fix a test in sun8i_ss_setup_ivs()
	crypto: engine - check if BH is disabled during completion
	crypto: api - Add scaffolding to change completion function signature
	crypto: engine - Use crypto_request_complete
	crypto: engine - fix crypto_queue backlog handling
	perf symbols: Fix return incorrect build_id size in elf_read_build_id()
	perf evlist: Refactor evlist__for_each_cpu()
	perf stat: Separate bperf from bpf_profiler
	btrfs: fix btrfs_prev_leaf() to not return the same key twice
	btrfs: zoned: fix wrong use of bitops API in btrfs_ensure_empty_zones
	btrfs: fix encoded write i_size corruption with no-holes
	btrfs: don't free qgroup space unless specified
	btrfs: zero the buffer before marking it dirty in btrfs_redirty_list_add
	btrfs: print-tree: parent bytenr must be aligned to sector size
	btrfs: fix space cache inconsistency after error loading it from disk
	cifs: fix pcchunk length type in smb2_copychunk_range
	cifs: release leases for deferred close handles when freezing
	platform/x86: touchscreen_dmi: Add upside-down quirk for GDIX1002 ts on the Juno Tablet
	platform/x86: touchscreen_dmi: Add info for the Dexp Ursus KX210i
	inotify: Avoid reporting event with invalid wd
	smb3: fix problem remounting a share after shutdown
	SMB3: force unmount was failing to close deferred close files
	sh: math-emu: fix macro redefined warning
	sh: mcount.S: fix build error when PRINTK is not enabled
	sh: init: use OF_EARLY_FLATTREE for early init
	sh: nmi_debug: fix return value of __setup handler
	remoteproc: stm32: Call of_node_put() on iteration error
	remoteproc: st: Call of_node_put() on iteration error
	remoteproc: imx_rproc: Call of_node_put() on iteration error
	ARM: dts: exynos: fix WM8960 clock name in Itop Elite
	ARM: dts: s5pv210: correct MIPI CSIS clock name
	drm/bridge: lt8912b: Fix DSI Video Mode
	drm/msm: fix NULL-deref on snapshot tear down
	drm/msm: fix NULL-deref on irq uninstall
	f2fs: fix potential corruption when moving a directory
	drm/panel: otm8009a: Set backlight parent to panel device
	drm/amd/display: fix flickering caused by S/G mode
	drm/amdgpu: fix an amdgpu_irq_put() issue in gmc_v9_0_hw_fini()
	drm/amdgpu/gfx: disable gfx9 cp_ecc_error_irq only when enabling legacy gfx ras
	drm/amdgpu: Fix vram recover doesn't work after whole GPU reset (v2)
	drm/amdgpu: disable sdma ecc irq only when sdma RAS is enabled in suspend
	HID: wacom: Set a default resolution for older tablets
	HID: wacom: insert timestamp to packed Bluetooth (BT) events
	fs/ntfs3: Refactoring of various minor issues
	ASoC: soc-pcm: Fix DPCM lockdep warning due to nested stream locks
	ASoC: soc-compress: Inherit atomicity from DAI link for Compress FE
	ASoC: soc-pcm: Move debugfs removal out of spinlock
	ASoC: DPCM: Don't pick up BE without substream
	ASoC: soc-pcm.c: call __soc_pcm_close() in soc_pcm_close()
	drm/i915/dg2: Support 4k@30 on HDMI
	drm/i915/dg2: Add additional HDMI pixel clock frequencies
	drm/i915/dg2: Add HDMI pixel clock frequencies 267.30 and 319.89 MHz
	drm/msm: Remove struct_mutex usage
	drm/msm/adreno: fix runtime PM imbalance at gpu load
	drm/amd/display: Refine condition of cursor visibility for pipe-split
	drm/amd/display: Add NULL plane_state check for cursor disable logic
	wifi: rtw88: rtw8821c: Fix rfe_option field width
	ksmbd: set RSS capable in FSCTL_QUERY_NETWORK_INTERFACE_INFO
	ksmbd: fix multi session connection failure
	ksmbd: replace sessions list in connection with xarray
	ksmbd: add channel rwlock
	ksmbd: fix kernel oops from idr_remove()
	ksmbd: fix racy issue while destroying session on multichannel
	ksmbd: fix deadlock in ksmbd_find_crypto_ctx()
	ksmbd: not allow guest user on multichannel
	locking/rwsem: Add __always_inline annotation to __down_read_common() and inlined callers
	ext4: fix WARNING in mb_find_extent
	ext4: avoid a potential slab-out-of-bounds in ext4_group_desc_csum
	ext4: fix data races when using cached status extents
	ext4: check iomap type only if ext4_iomap_begin() does not fail
	ext4: improve error recovery code paths in __ext4_remount()
	ext4: improve error handling from ext4_dirhash()
	ext4: fix deadlock when converting an inline directory in nojournal mode
	ext4: add bounds checking in get_max_inline_xattr_value_size()
	ext4: bail out of ext4_xattr_ibody_get() fails for any reason
	ext4: remove a BUG_ON in ext4_mb_release_group_pa()
	ext4: fix invalid free tracking in ext4_xattr_move_to_block()
	drm/msm/adreno: adreno_gpu: Use suspend() instead of idle() on load error
	serial: 8250: Fix serial8250_tx_empty() race with DMA Tx
	drbd: correctly submit flush bio on barrier
	RISC-V: Fix up a cherry-pick warning in setup_vm_final()
	drm/amd/display: Fix hang when skipping modeset
	Linux 5.15.112

Change-Id: Ie61cc0aea78266c2c5adb0a889f55affa78883e5
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2023-06-12 20:22:34 +00:00
140 changed files with 2489 additions and 669 deletions

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 15
SUBLEVEL = 111
SUBLEVEL = 112
EXTRAVERSION =
NAME = Trick or Treat

View File

@@ -179,7 +179,7 @@
compatible = "wlf,wm8960";
reg = <0x1a>;
clocks = <&pmu_system_controller 0>;
clock-names = "MCLK1";
clock-names = "mclk";
wlf,shared-lrclk;
#sound-dai-cells = <0>;
};

View File

@@ -582,7 +582,7 @@
interrupts = <29>;
clocks = <&clocks CLK_CSIS>,
<&clocks SCLK_CSIS>;
clock-names = "clk_csis",
clock-names = "csis",
"sclk_csis";
bus-width = <4>;
status = "disabled";

View File

@@ -714,6 +714,7 @@ static void __init setup_vm_final(void)
{
uintptr_t va, map_size;
phys_addr_t pa, start, end;
unsigned long idx __maybe_unused;
u64 i;
/**
@@ -733,7 +734,7 @@ static void __init setup_vm_final(void)
* directly in swapper_pg_dir in addition to the pgd entry that points
* to fixmap_pte.
*/
unsigned long idx = pgd_index(__fix_to_virt(FIX_FDT));
idx = pgd_index(__fix_to_virt(FIX_FDT));
set_pgd(&swapper_pg_dir[idx], early_pg_dir[idx]);
#endif

View File

@@ -217,18 +217,26 @@ bool kernel_page_present(struct page *page)
pgd = pgd_offset_k(addr);
if (!pgd_present(*pgd))
return false;
if (pgd_leaf(*pgd))
return true;
p4d = p4d_offset(pgd, addr);
if (!p4d_present(*p4d))
return false;
if (p4d_leaf(*p4d))
return true;
pud = pud_offset(p4d, addr);
if (!pud_present(*pud))
return false;
if (pud_leaf(*pud))
return true;
pmd = pmd_offset(pud, addr);
if (!pmd_present(*pmd))
return false;
if (pmd_leaf(*pmd))
return true;
pte = pte_offset_kernel(pmd, addr);
return pte_present(*pte);

View File

@@ -15,7 +15,7 @@ config SH_STANDARD_BIOS
config STACK_DEBUG
bool "Check for stack overflows"
depends on DEBUG_KERNEL
depends on DEBUG_KERNEL && PRINTK
help
This option will cause messages to be printed if free stack space
drops below a certain limit. Saying Y here will add overhead to

View File

@@ -64,7 +64,7 @@ ENTRY(_stext)
ldc r0, r6_bank
#endif
#ifdef CONFIG_OF_FLATTREE
#ifdef CONFIG_OF_EARLY_FLATTREE
mov r4, r12 ! Store device tree blob pointer in r12
#endif
@@ -315,7 +315,7 @@ ENTRY(_stext)
10:
#endif
#ifdef CONFIG_OF_FLATTREE
#ifdef CONFIG_OF_EARLY_FLATTREE
mov.l 8f, r0 ! Make flat device tree available early.
jsr @r0
mov r12, r4
@@ -346,7 +346,7 @@ ENTRY(stack_start)
5: .long start_kernel
6: .long cpu_init
7: .long init_thread_union
#if defined(CONFIG_OF_FLATTREE)
#if defined(CONFIG_OF_EARLY_FLATTREE)
8: .long sh_fdt_init
#endif

View File

@@ -49,7 +49,7 @@ static int __init nmi_debug_setup(char *str)
register_die_notifier(&nmi_debug_nb);
if (*str != '=')
return 0;
return 1;
for (p = str + 1; *p; p = sep + 1) {
sep = strchr(p, ',');
@@ -70,6 +70,6 @@ static int __init nmi_debug_setup(char *str)
break;
}
return 0;
return 1;
}
__setup("nmi_debug", nmi_debug_setup);

View File

@@ -244,7 +244,7 @@ void __init __weak plat_early_device_setup(void)
{
}
#ifdef CONFIG_OF_FLATTREE
#ifdef CONFIG_OF_EARLY_FLATTREE
void __ref sh_fdt_init(phys_addr_t dt_phys)
{
static int done = 0;
@@ -326,7 +326,7 @@ void __init setup_arch(char **cmdline_p)
/* Let earlyprintk output early console messages */
sh_early_platform_driver_probe("earlyprintk", 1, 1);
#ifdef CONFIG_OF_FLATTREE
#ifdef CONFIG_OF_EARLY_FLATTREE
#ifdef CONFIG_USE_BUILTIN_DTB
unflatten_and_copy_device_tree();
#else

View File

@@ -67,7 +67,3 @@
} while (0)
#define abort() return 0
#define __BYTE_ORDER __LITTLE_ENDIAN

View File

@@ -943,6 +943,9 @@ EXPORT_SYMBOL_GPL(crypto_enqueue_request);
void crypto_enqueue_request_head(struct crypto_queue *queue,
struct crypto_async_request *request)
{
if (unlikely(queue->qlen >= queue->max_qlen))
queue->backlog = queue->backlog->prev;
queue->qlen++;
list_add(&request->list, &queue->list);
}

View File

@@ -53,7 +53,8 @@ static void crypto_finalize_request(struct crypto_engine *engine,
dev_err(engine->dev, "failed to unprepare request\n");
}
}
req->complete(req, err);
lockdep_assert_in_softirq();
crypto_request_complete(req, err);
kthread_queue_work(engine->kworker, &engine->pump_requests);
}
@@ -128,9 +129,6 @@ start_request:
if (!engine->retry_support)
engine->cur_req = async_req;
if (backlog)
backlog->complete(backlog, -EINPROGRESS);
if (engine->busy)
was_busy = true;
else
@@ -213,9 +211,12 @@ req_err_1:
}
req_err_2:
async_req->complete(async_req, ret);
crypto_request_complete(async_req, ret);
retry:
if (backlog)
crypto_request_complete(backlog, -EINPROGRESS);
/* If retry mechanism is supported, send new requests to engine */
if (engine->retry_support) {
spin_lock_irqsave(&engine->queue_lock, flags);

View File

@@ -1301,7 +1301,7 @@ static void submit_one_flush(struct drbd_device *device, struct issue_flush_cont
bio_set_dev(bio, device->ldev->backing_bdev);
bio->bi_private = octx;
bio->bi_end_io = one_flush_endio;
bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH;
bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
device->flush_jif = jiffies;
set_bit(FLUSH_PENDING, &device->flags);

View File

@@ -39,4 +39,4 @@ obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o
obj-$(CONFIG_DA8XX_MSTPRI) += da8xx-mstpri.o
# MHI
obj-$(CONFIG_MHI_BUS) += mhi/
obj-y += mhi/

View File

@@ -2,30 +2,7 @@
#
# MHI bus
#
# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
# Copyright (c) 2021, Linaro Ltd.
#
config MHI_BUS
tristate "Modem Host Interface (MHI) bus"
help
Bus driver for MHI protocol. Modem Host Interface (MHI) is a
communication protocol used by the host processors to control
and communicate with modem devices over a high speed peripheral
bus or shared memory.
config MHI_BUS_DEBUG
bool "Debugfs support for the MHI bus"
depends on MHI_BUS && DEBUG_FS
help
Enable debugfs support for use with the MHI transport. Allows
reading and/or modifying some values within the MHI controller
for debug and test purposes.
config MHI_BUS_PCI_GENERIC
tristate "MHI PCI controller driver"
depends on MHI_BUS
depends on PCI
help
This driver provides MHI PCI controller driver for devices such as
Qualcomm SDX55 based PCIe modems.
source "drivers/bus/mhi/host/Kconfig"

View File

@@ -1,6 +1,2 @@
# core layer
obj-y += core/
obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o
mhi_pci_generic-y += pci_generic.o
# Host MHI stack
obj-y += host/

View File

@@ -0,0 +1,31 @@
# SPDX-License-Identifier: GPL-2.0
#
# MHI bus
#
# Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
#
config MHI_BUS
tristate "Modem Host Interface (MHI) bus"
help
Bus driver for MHI protocol. Modem Host Interface (MHI) is a
communication protocol used by the host processors to control
and communicate with modem devices over a high speed peripheral
bus or shared memory.
config MHI_BUS_DEBUG
bool "Debugfs support for the MHI bus"
depends on MHI_BUS && DEBUG_FS
help
Enable debugfs support for use with the MHI transport. Allows
reading and/or modifying some values within the MHI controller
for debug and test purposes.
config MHI_BUS_PCI_GENERIC
tristate "MHI PCI controller driver"
depends on MHI_BUS
depends on PCI
help
This driver provides MHI PCI controller driver for devices such as
Qualcomm SDX55 based PCIe modems.

View File

@@ -1,4 +1,6 @@
obj-$(CONFIG_MHI_BUS) += mhi.o
mhi-y := init.o main.o pm.o boot.o
mhi-$(CONFIG_MHI_BUS_DEBUG) += debugfs.o
obj-$(CONFIG_MHI_BUS_PCI_GENERIC) += mhi_pci_generic.o
mhi_pci_generic-y += pci_generic.o

View File

@@ -390,6 +390,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
{
const struct firmware *firmware = NULL;
struct device *dev = &mhi_cntrl->mhi_dev->dev;
enum mhi_pm_state new_state;
const char *fw_name;
void *buf;
dma_addr_t dma_addr;
@@ -507,14 +508,18 @@ error_ready_state:
}
error_fw_load:
mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
wake_up_all(&mhi_cntrl->state_event);
write_lock_irq(&mhi_cntrl->pm_lock);
new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
write_unlock_irq(&mhi_cntrl->pm_lock);
if (new_state == MHI_PM_FW_DL_ERR)
wake_up_all(&mhi_cntrl->state_event);
}
int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
{
struct image_info *image_info = mhi_cntrl->fbc_image;
struct device *dev = &mhi_cntrl->mhi_dev->dev;
enum mhi_pm_state new_state;
int ret;
if (!image_info)
@@ -525,8 +530,11 @@ int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
&image_info->mhi_buf[image_info->entries - 1]);
if (ret) {
dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
wake_up_all(&mhi_cntrl->state_event);
write_lock_irq(&mhi_cntrl->pm_lock);
new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
write_unlock_irq(&mhi_cntrl->pm_lock);
if (new_state == MHI_PM_FW_DL_ERR)
wake_up_all(&mhi_cntrl->state_event);
}
return ret;

View File

@@ -517,6 +517,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
return -EIO;
}
if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) {
dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n",
val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB));
return -ERANGE;
}
/* Setup wake db */
mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
mhi_cntrl->wake_set = false;
@@ -534,6 +540,12 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
return -EIO;
}
if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) {
dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n",
val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings));
return -ERANGE;
}
/* Setup event db address for each ev_ring */
mhi_event = mhi_cntrl->mhi_event;
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) {

View File

@@ -489,7 +489,7 @@ irqreturn_t mhi_intvec_threaded_handler(int irq_number, void *priv)
}
write_unlock_irq(&mhi_cntrl->pm_lock);
if (pm_state != MHI_PM_SYS_ERR_DETECT || ee == mhi_cntrl->ee)
if (pm_state != MHI_PM_SYS_ERR_DETECT)
goto exit_intvec;
switch (ee) {

View File

@@ -132,7 +132,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
}
rctx->p_iv[i] = a;
/* we need to setup all others IVs only in the decrypt way */
if (rctx->op_dir & SS_ENCRYPTION)
if (rctx->op_dir == SS_ENCRYPTION)
return 0;
todo = min(len, sg_dma_len(sg));
len -= todo;

View File

@@ -42,6 +42,9 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
/* Read the interrupt status: */
status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
/* Clear the interrupt status by writing the same value we read. */
iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
/* invoke subdevice interrupt handlers */
if (status) {
if (psp->sev_irq_handler)
@@ -51,9 +54,6 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
psp->tee_irq_handler(irq, psp->tee_irq_data, status);
}
/* Clear the interrupt status by writing the same value we read. */
iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
return IRQ_HANDLED;
}

View File

@@ -4368,7 +4368,11 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
dev_info(adev->dev, "recover vram bo from shadow start\n");
mutex_lock(&adev->shadow_list_lock);
list_for_each_entry(vmbo, &adev->shadow_list, shadow_list) {
shadow = &vmbo->bo;
/* If vm is compute context or adev is APU, shadow will be NULL */
if (!vmbo->shadow)
continue;
shadow = vmbo->shadow;
/* No need to recover an evicted BO */
if (shadow->tbo.resource->mem_type != TTM_PL_TT ||
shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET ||

View File

@@ -66,6 +66,7 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
{
struct fd f = fdget(fd);
struct amdgpu_fpriv *fpriv;
struct amdgpu_ctx_mgr *mgr;
struct amdgpu_ctx *ctx;
uint32_t id;
int r;
@@ -79,8 +80,11 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
return r;
}
idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
mgr = &fpriv->ctx_mgr;
mutex_lock(&mgr->lock);
idr_for_each_entry(&mgr->ctx_handles, ctx, id)
amdgpu_ctx_priority_override(ctx, priority);
mutex_unlock(&mgr->lock);
fdput(f);
return 0;

View File

@@ -4018,7 +4018,8 @@ static int gfx_v9_0_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);

View File

@@ -1819,7 +1819,6 @@ static int gmc_v9_0_hw_fini(void *handle)
return 0;
}
amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0);
amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
return 0;

View File

@@ -2044,9 +2044,11 @@ static int sdma_v4_0_hw_fini(void *handle)
if (amdgpu_sriov_vf(adev))
return 0;
for (i = 0; i < adev->sdma.num_instances; i++) {
amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) {
for (i = 0; i < adev->sdma.num_instances; i++) {
amdgpu_irq_put(adev, &adev->sdma.ecc_irq,
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
}
}
sdma_v4_0_ctx_switch_enable(adev, false);

View File

@@ -8944,6 +8944,13 @@ static void amdgpu_dm_commit_cursors(struct drm_atomic_state *state)
handle_cursor_update(plane, old_plane_state);
}
static inline uint32_t get_mem_type(struct drm_framebuffer *fb)
{
struct amdgpu_bo *abo = gem_to_amdgpu_bo(fb->obj[0]);
return abo->tbo.resource ? abo->tbo.resource->mem_type : 0;
}
static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
struct dc_state *dc_state,
struct drm_device *dev,
@@ -9013,6 +9020,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
continue;
dc_plane = dm_new_plane_state->dc_state;
if (!dc_plane)
continue;
bundle->surface_updates[planes_count].surface = dc_plane;
if (new_pcrtc_state->color_mgmt_changed) {
@@ -9064,11 +9073,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
/*
* Only allow immediate flips for fast updates that don't
* change FB pitch, DCC state, rotation or mirroing.
* change memory domain, FB pitch, DCC state, rotation or
* mirroring.
*/
bundle->flip_addrs[planes_count].flip_immediate =
crtc->state->async_flip &&
acrtc_state->update_type == UPDATE_TYPE_FAST;
acrtc_state->update_type == UPDATE_TYPE_FAST &&
get_mem_type(old_plane_state->fb) == get_mem_type(fb);
timestamp_ns = ktime_get_ns();
bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
@@ -10541,8 +10552,9 @@ static int dm_update_plane_state(struct dc *dc,
return -EINVAL;
}
if (dm_old_plane_state->dc_state)
dc_plane_state_release(dm_old_plane_state->dc_state);
dc_plane_state_release(dm_old_plane_state->dc_state);
dm_new_plane_state->dc_state = NULL;
*lock_and_validation_needed = true;

View File

@@ -1434,6 +1434,9 @@ bool dc_remove_plane_from_context(
struct dc_stream_status *stream_status = NULL;
struct resource_pool *pool = dc->res_pool;
if (!plane_state)
return true;
for (i = 0; i < context->stream_count; i++)
if (context->streams[i] == stream) {
stream_status = &context->stream_status[i];

View File

@@ -3211,13 +3211,11 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
{
struct pipe_ctx *test_pipe;
struct pipe_ctx *test_pipe, *split_pipe;
const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data;
const struct rect *r1 = &scl_data->recout, *r2;
int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b;
struct rect r1 = scl_data->recout, r2, r2_half;
int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b;
int cur_layer = pipe_ctx->plane_state->layer_index;
bool upper_pipe_exists = false;
struct fixed31_32 one = dc_fixpt_from_int(1);
/**
* Disable the cursor if there's another pipe above this with a
@@ -3226,26 +3224,35 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
*/
for (test_pipe = pipe_ctx->top_pipe; test_pipe;
test_pipe = test_pipe->top_pipe) {
if (!test_pipe->plane_state->visible)
// Skip invisible layer and pipe-split plane on same layer
if (!test_pipe->plane_state ||
!test_pipe->plane_state->visible ||
test_pipe->plane_state->layer_index == cur_layer)
continue;
r2 = &test_pipe->plane_res.scl_data.recout;
r2_r = r2->x + r2->width;
r2_b = r2->y + r2->height;
r2 = test_pipe->plane_res.scl_data.recout;
r2_r = r2.x + r2.width;
r2_b = r2.y + r2.height;
split_pipe = test_pipe;
if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b)
/**
* There is another half plane on same layer because of
* pipe-split, merge together per same height.
*/
for (split_pipe = pipe_ctx->top_pipe; split_pipe;
split_pipe = split_pipe->top_pipe)
if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
r2_half = split_pipe->plane_res.scl_data.recout;
r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x;
r2.width = r2.width + r2_half.width;
r2_r = r2.x + r2.width;
break;
}
if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b)
return true;
if (test_pipe->plane_state->layer_index < cur_layer)
upper_pipe_exists = true;
}
// if plane scaled, assume an upper plane can handle cursor if it exists.
if (upper_pipe_exists &&
(scl_data->ratios.horz.value != one.value ||
scl_data->ratios.vert.value != one.value))
return true;
return false;
}

View File

@@ -494,7 +494,6 @@ static int lt8912_attach_dsi(struct lt8912 *lt)
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM |
MIPI_DSI_MODE_NO_EOT_PACKET;

View File

@@ -198,8 +198,6 @@ static int hyperv_vmbus_probe(struct hv_device *hdev,
if (ret)
drm_warn(dev, "Failed to update vram location.\n");
hv->dirt_needed = true;
ret = hyperv_mode_config_init(hv);
if (ret)
goto err_vmbus_close;

File diff suppressed because it is too large Load Diff

View File

@@ -107,7 +107,7 @@ reset_set(void *data, u64 val)
* try to reset an active GPU.
*/
mutex_lock(&dev->struct_mutex);
mutex_lock(&gpu->lock);
release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
adreno_gpu->fw[ADRENO_FW_PM4] = NULL;
@@ -133,7 +133,7 @@ reset_set(void *data, u64 val)
gpu->funcs->recover(gpu);
pm_runtime_put_sync(&gpu->pdev->dev);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&gpu->lock);
return 0;
}

View File

@@ -406,20 +406,21 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) {
pm_runtime_put_sync(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret);
return NULL;
goto err_disable_rpm;
}
mutex_lock(&dev->struct_mutex);
mutex_lock(&gpu->lock);
ret = msm_gpu_hw_init(gpu);
mutex_unlock(&dev->struct_mutex);
pm_runtime_put_autosuspend(&pdev->dev);
mutex_unlock(&gpu->lock);
if (ret) {
DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
return NULL;
goto err_put_rpm;
}
pm_runtime_put_autosuspend(&pdev->dev);
#ifdef CONFIG_DEBUG_FS
if (gpu->funcs->debugfs_init) {
gpu->funcs->debugfs_init(gpu, dev->primary);
@@ -428,6 +429,13 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
#endif
return gpu;
err_put_rpm:
pm_runtime_put_sync_suspend(&pdev->dev);
err_disable_rpm:
pm_runtime_disable(&pdev->dev);
return NULL;
}
static void set_gpu_pdev(struct drm_device *dev,

View File

@@ -29,14 +29,14 @@ static int msm_gpu_show(struct seq_file *m, void *arg)
struct msm_gpu *gpu = priv->gpu;
int ret;
ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex);
ret = mutex_lock_interruptible(&gpu->lock);
if (ret)
return ret;
drm_printf(&p, "%s Status:\n", gpu->name);
gpu->funcs->show(gpu, show_priv->state, &p);
mutex_unlock(&show_priv->dev->struct_mutex);
mutex_unlock(&gpu->lock);
return 0;
}
@@ -48,9 +48,9 @@ static int msm_gpu_release(struct inode *inode, struct file *file)
struct msm_drm_private *priv = show_priv->dev->dev_private;
struct msm_gpu *gpu = priv->gpu;
mutex_lock(&show_priv->dev->struct_mutex);
mutex_lock(&gpu->lock);
gpu->funcs->gpu_state_put(show_priv->state);
mutex_unlock(&show_priv->dev->struct_mutex);
mutex_unlock(&gpu->lock);
kfree(show_priv);
@@ -72,7 +72,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
if (!show_priv)
return -ENOMEM;
ret = mutex_lock_interruptible(&dev->struct_mutex);
ret = mutex_lock_interruptible(&gpu->lock);
if (ret)
goto free_priv;
@@ -81,7 +81,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
show_priv->state = gpu->funcs->gpu_state_get(gpu);
pm_runtime_put_sync(&gpu->pdev->dev);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&gpu->lock);
if (IS_ERR(show_priv->state)) {
ret = PTR_ERR(show_priv->state);

View File

@@ -359,13 +359,16 @@ static int msm_drm_uninit(struct device *dev)
msm_fbdev_free(ddev);
#endif
msm_disp_snapshot_destroy(ddev);
if (kms)
msm_disp_snapshot_destroy(ddev);
drm_mode_config_cleanup(ddev);
pm_runtime_get_sync(dev);
msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);
if (kms) {
pm_runtime_get_sync(dev);
msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);
}
if (kms && kms->funcs)
kms->funcs->destroy(kms);

View File

@@ -150,7 +150,7 @@ int msm_gpu_hw_init(struct msm_gpu *gpu)
{
int ret;
WARN_ON(!mutex_is_locked(&gpu->dev->struct_mutex));
WARN_ON(!mutex_is_locked(&gpu->lock));
if (!gpu->needs_hw_init)
return 0;
@@ -361,7 +361,7 @@ static void recover_worker(struct kthread_work *work)
char *comm = NULL, *cmd = NULL;
int i;
mutex_lock(&dev->struct_mutex);
mutex_lock(&gpu->lock);
DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name);
@@ -442,7 +442,7 @@ static void recover_worker(struct kthread_work *work)
}
}
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&gpu->lock);
msm_gpu_retire(gpu);
}
@@ -450,12 +450,11 @@ static void recover_worker(struct kthread_work *work)
static void fault_worker(struct kthread_work *work)
{
struct msm_gpu *gpu = container_of(work, struct msm_gpu, fault_work);
struct drm_device *dev = gpu->dev;
struct msm_gem_submit *submit;
struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu);
char *comm = NULL, *cmd = NULL;
mutex_lock(&dev->struct_mutex);
mutex_lock(&gpu->lock);
submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1);
if (submit && submit->fault_dumped)
@@ -490,7 +489,7 @@ resume_smmu:
memset(&gpu->fault_info, 0, sizeof(gpu->fault_info));
gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&gpu->lock);
}
static void hangcheck_timer_reset(struct msm_gpu *gpu)
@@ -734,7 +733,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
struct msm_ringbuffer *ring = submit->ring;
unsigned long flags;
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
WARN_ON(!mutex_is_locked(&gpu->lock));
pm_runtime_get_sync(&gpu->pdev->dev);
@@ -849,6 +848,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
INIT_LIST_HEAD(&gpu->active_list);
mutex_init(&gpu->active_lock);
mutex_init(&gpu->lock);
kthread_init_work(&gpu->retire_work, retire_worker);
kthread_init_work(&gpu->recover_work, recover_worker);
kthread_init_work(&gpu->fault_work, fault_worker);

View File

@@ -143,13 +143,23 @@ struct msm_gpu {
*/
struct list_head active_list;
/**
* lock:
*
* General lock for serializing all the gpu things.
*
* TODO move to per-ring locking where feasible (ie. submit/retire
* path, etc)
*/
struct mutex lock;
/**
* active_submits:
*
* The number of submitted but not yet retired submits, used to
* determine transitions between active and idle.
*
* Protected by lock
* Protected by active_lock
*/
int active_submits;
@@ -530,28 +540,28 @@ static inline struct msm_gpu_state *msm_gpu_crashstate_get(struct msm_gpu *gpu)
{
struct msm_gpu_state *state = NULL;
mutex_lock(&gpu->dev->struct_mutex);
mutex_lock(&gpu->lock);
if (gpu->crashstate) {
kref_get(&gpu->crashstate->ref);
state = gpu->crashstate;
}
mutex_unlock(&gpu->dev->struct_mutex);
mutex_unlock(&gpu->lock);
return state;
}
static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)
{
mutex_lock(&gpu->dev->struct_mutex);
mutex_lock(&gpu->lock);
if (gpu->crashstate) {
if (gpu->funcs->gpu_state_put(gpu->crashstate))
gpu->crashstate = NULL;
}
mutex_unlock(&gpu->dev->struct_mutex);
mutex_unlock(&gpu->lock);
}
/*

View File

@@ -155,9 +155,12 @@ static int perf_open(struct inode *inode, struct file *file)
struct msm_gpu *gpu = priv->gpu;
int ret = 0;
mutex_lock(&dev->struct_mutex);
if (!gpu)
return -ENODEV;
if (perf->open || !gpu) {
mutex_lock(&gpu->lock);
if (perf->open) {
ret = -EBUSY;
goto out;
}
@@ -171,7 +174,7 @@ static int perf_open(struct inode *inode, struct file *file)
perf->next_jiffies = jiffies + SAMPLE_TIME;
out:
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&gpu->lock);
return ret;
}

View File

@@ -86,7 +86,7 @@ struct msm_rd_state {
struct msm_gem_submit *submit;
/* fifo access is synchronized on the producer side by
* struct_mutex held by submit code (otherwise we could
* gpu->lock held by submit code (otherwise we could
* end up w/ cmds logged in different order than they
* were executed). And read_lock synchronizes the reads
*/
@@ -181,9 +181,12 @@ static int rd_open(struct inode *inode, struct file *file)
uint32_t gpu_id;
int ret = 0;
mutex_lock(&dev->struct_mutex);
if (!gpu)
return -ENODEV;
if (rd->open || !gpu) {
mutex_lock(&gpu->lock);
if (rd->open) {
ret = -EBUSY;
goto out;
}
@@ -203,7 +206,7 @@ static int rd_open(struct inode *inode, struct file *file)
rd_write_section(rd, RD_GPU_ID, &gpu_id, sizeof(gpu_id));
out:
mutex_unlock(&dev->struct_mutex);
mutex_unlock(&gpu->lock);
return ret;
}
@@ -343,11 +346,10 @@ out_unlock:
msm_gem_unlock(&obj->base);
}
/* called under struct_mutex */
/* called under gpu->lock */
void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
const char *fmt, ...)
{
struct drm_device *dev = submit->dev;
struct task_struct *task;
char msg[256];
int i, n;
@@ -358,7 +360,7 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
/* writing into fifo is serialized by caller, and
* rd->read_lock is used to serialize the reads
*/
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
WARN_ON(!mutex_is_locked(&submit->gpu->lock));
if (fmt) {
va_list args;

View File

@@ -32,11 +32,11 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
pm_runtime_get_sync(&gpu->pdev->dev);
/* TODO move submit path over to using a per-ring lock.. */
mutex_lock(&gpu->dev->struct_mutex);
mutex_lock(&gpu->lock);
msm_gpu_submit(gpu, submit);
mutex_unlock(&gpu->dev->struct_mutex);
mutex_unlock(&gpu->lock);
pm_runtime_put(&gpu->pdev->dev);

View File

@@ -444,7 +444,7 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
DRM_MODE_CONNECTOR_DSI);
ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev),
dsi->host->dev, ctx,
dev, ctx,
&otm8009a_backlight_ops,
NULL);
if (IS_ERR(ctx->bl_dev)) {

View File

@@ -1272,6 +1272,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
struct input_dev *pen_input = wacom->pen_input;
unsigned char *data = wacom->data;
int number_of_valid_frames = 0;
int time_interval = 15000000;
ktime_t time_packet_received = ktime_get();
int i;
if (wacom->features.type == INTUOSP2_BT ||
@@ -1292,12 +1295,30 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;
}
/* number of valid frames */
for (i = 0; i < pen_frames; i++) {
unsigned char *frame = &data[i*pen_frame_len + 1];
bool valid = frame[0] & 0x80;
if (valid)
number_of_valid_frames++;
}
if (number_of_valid_frames) {
if (wacom->hid_data.time_delayed)
time_interval = ktime_get() - wacom->hid_data.time_delayed;
time_interval /= number_of_valid_frames;
wacom->hid_data.time_delayed = time_packet_received;
}
for (i = 0; i < number_of_valid_frames; i++) {
unsigned char *frame = &data[i*pen_frame_len + 1];
bool valid = frame[0] & 0x80;
bool prox = frame[0] & 0x40;
bool range = frame[0] & 0x20;
bool invert = frame[0] & 0x10;
int frames_number_reversed = number_of_valid_frames - i - 1;
int event_timestamp = time_packet_received - frames_number_reversed * time_interval;
if (!valid)
continue;
@@ -1310,6 +1331,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
wacom->tool[0] = 0;
wacom->id[0] = 0;
wacom->serial[0] = 0;
wacom->hid_data.time_delayed = 0;
return;
}
@@ -1346,6 +1368,7 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
get_unaligned_le16(&frame[11]));
}
}
if (wacom->tool[0]) {
input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
if (wacom->features.type == INTUOSP2_BT ||
@@ -1369,6 +1392,9 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
wacom->shared->stylus_in_proximity = prox;
/* add timestamp to unpack the frames */
input_set_timestamp(pen_input, event_timestamp);
input_sync(pen_input);
}
}
@@ -1857,6 +1883,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
int fmax = field->logical_maximum;
unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
int resolution_code = code;
int resolution = hidinput_calc_abs_res(field, resolution_code);
if (equivalent_usage == HID_DG_TWIST) {
resolution_code = ABS_RZ;
@@ -1877,8 +1904,15 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
switch (type) {
case EV_ABS:
input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
input_abs_set_res(input, code,
hidinput_calc_abs_res(field, resolution_code));
/* older tablet may miss physical usage */
if ((code == ABS_X || code == ABS_Y) && !resolution) {
resolution = WACOM_INTUOS_RES;
hid_warn(input,
"Wacom usage (%d) missing resolution \n",
code);
}
input_abs_set_res(input, code, resolution);
break;
case EV_KEY:
case EV_MSC:

View File

@@ -321,6 +321,7 @@ struct hid_data {
int bat_connected;
int ps_connected;
bool pad_input_event_flag;
int time_delayed;
};
struct wacom_remote_data {

View File

@@ -110,7 +110,7 @@ struct zynqmp_ipi_pdata {
unsigned int method;
u32 local_id;
int num_mboxes;
struct zynqmp_ipi_mbox *ipi_mboxes;
struct zynqmp_ipi_mbox ipi_mboxes[];
};
static struct device_driver zynqmp_ipi_mbox_driver = {
@@ -634,8 +634,13 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
struct zynqmp_ipi_mbox *mbox;
int num_mboxes, ret = -EINVAL;
num_mboxes = of_get_child_count(np);
pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)),
num_mboxes = of_get_available_child_count(np);
if (num_mboxes == 0) {
dev_err(dev, "mailbox nodes not available\n");
return -EINVAL;
}
pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
@@ -649,8 +654,6 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
}
pdata->num_mboxes = num_mboxes;
pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *)
((char *)pdata + sizeof(*pdata));
mbox = pdata->ipi_mboxes;
for_each_available_child_of_node(np, nc) {

View File

@@ -441,9 +441,9 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
else
ssc_delta = 0x87;
if (priv->id == ID_MT7621) {
/* PLL frequency: 150MHz: 1.2GBit */
/* PLL frequency: 125MHz: 1.0GBit */
if (xtal == HWTRAP_XTAL_40MHZ)
ncpo1 = 0x0780;
ncpo1 = 0x0640;
if (xtal == HWTRAP_XTAL_25MHZ)
ncpo1 = 0x0a00;
} else { /* PLL frequency: 250MHz: 2.0Gbit */

View File

@@ -4575,6 +4575,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6390_watchdog_ops,
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
.reset = mv88e6352_g1_reset,
.vtu_getnext = mv88e6185_g1_vtu_getnext,
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,

View File

@@ -1270,7 +1270,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
int index;
index = enetc_get_free_index(priv);
if (sfi->handle < 0) {
if (index < 0) {
NL_SET_ERR_MSG_MOD(extack, "No Stream Filter resource!");
err = -ENOSPC;
goto free_fmi;

View File

@@ -157,7 +157,7 @@ EXPORT_SYMBOL(otx2_mbox_init);
*/
int otx2_mbox_regions_init(struct otx2_mbox *mbox, void **hwbase,
struct pci_dev *pdev, void *reg_base,
int direction, int ndevs)
int direction, int ndevs, unsigned long *pf_bmap)
{
struct otx2_mbox_dev *mdev;
int devid, err;
@@ -169,6 +169,9 @@ int otx2_mbox_regions_init(struct otx2_mbox *mbox, void **hwbase,
mbox->hwbase = hwbase[0];
for (devid = 0; devid < ndevs; devid++) {
if (!test_bit(devid, pf_bmap))
continue;
mdev = &mbox->dev[devid];
mdev->mbase = hwbase[devid];
mdev->hwbase = hwbase[devid];

View File

@@ -96,9 +96,10 @@ void otx2_mbox_destroy(struct otx2_mbox *mbox);
int otx2_mbox_init(struct otx2_mbox *mbox, void __force *hwbase,
struct pci_dev *pdev, void __force *reg_base,
int direction, int ndevs);
int otx2_mbox_regions_init(struct otx2_mbox *mbox, void __force **hwbase,
struct pci_dev *pdev, void __force *reg_base,
int direction, int ndevs);
int direction, int ndevs, unsigned long *bmap);
void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid);
int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid);
int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid);

View File

@@ -2196,7 +2196,7 @@ static inline void rvu_afvf_mbox_up_handler(struct work_struct *work)
}
static int rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
int num, int type)
int num, int type, unsigned long *pf_bmap)
{
struct rvu_hwinfo *hw = rvu->hw;
int region;
@@ -2208,6 +2208,9 @@ static int rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
*/
if (type == TYPE_AFVF) {
for (region = 0; region < num; region++) {
if (!test_bit(region, pf_bmap))
continue;
if (hw->cap.per_pf_mbox_regs) {
bar4 = rvu_read64(rvu, BLKADDR_RVUM,
RVU_AF_PFX_BAR4_ADDR(0)) +
@@ -2229,6 +2232,9 @@ static int rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
* RVU_AF_PF_BAR4_ADDR register.
*/
for (region = 0; region < num; region++) {
if (!test_bit(region, pf_bmap))
continue;
if (hw->cap.per_pf_mbox_regs) {
bar4 = rvu_read64(rvu, BLKADDR_RVUM,
RVU_AF_PFX_BAR4_ADDR(region));
@@ -2257,12 +2263,33 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
int err = -EINVAL, i, dir, dir_up;
void __iomem *reg_base;
struct rvu_work *mwork;
unsigned long *pf_bmap;
void **mbox_regions;
const char *name;
u64 cfg;
pf_bmap = bitmap_zalloc(num, GFP_KERNEL);
if (!pf_bmap)
return -ENOMEM;
/* RVU VFs */
if (type == TYPE_AFVF)
bitmap_set(pf_bmap, 0, num);
if (type == TYPE_AFPF) {
/* Mark enabled PFs in bitmap */
for (i = 0; i < num; i++) {
cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(i));
if (cfg & BIT_ULL(20))
set_bit(i, pf_bmap);
}
}
mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL);
if (!mbox_regions)
return -ENOMEM;
if (!mbox_regions) {
err = -ENOMEM;
goto free_bitmap;
}
switch (type) {
case TYPE_AFPF:
@@ -2270,7 +2297,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
dir = MBOX_DIR_AFPF;
dir_up = MBOX_DIR_AFPF_UP;
reg_base = rvu->afreg_base;
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFPF);
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFPF, pf_bmap);
if (err)
goto free_regions;
break;
@@ -2279,7 +2306,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
dir = MBOX_DIR_PFVF;
dir_up = MBOX_DIR_PFVF_UP;
reg_base = rvu->pfreg_base;
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFVF);
err = rvu_get_mbox_regions(rvu, mbox_regions, num, TYPE_AFVF, pf_bmap);
if (err)
goto free_regions;
break;
@@ -2310,16 +2337,19 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
}
err = otx2_mbox_regions_init(&mw->mbox, mbox_regions, rvu->pdev,
reg_base, dir, num);
reg_base, dir, num, pf_bmap);
if (err)
goto exit;
err = otx2_mbox_regions_init(&mw->mbox_up, mbox_regions, rvu->pdev,
reg_base, dir_up, num);
reg_base, dir_up, num, pf_bmap);
if (err)
goto exit;
for (i = 0; i < num; i++) {
if (!test_bit(i, pf_bmap))
continue;
mwork = &mw->mbox_wrk[i];
mwork->rvu = rvu;
INIT_WORK(&mwork->work, mbox_handler);
@@ -2328,8 +2358,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
mwork->rvu = rvu;
INIT_WORK(&mwork->work, mbox_up_handler);
}
kfree(mbox_regions);
return 0;
goto free_regions;
exit:
destroy_workqueue(mw->mbox_wq);
@@ -2338,6 +2367,8 @@ unmap_regions:
iounmap((void __iomem *)mbox_regions[num]);
free_regions:
kfree(mbox_regions);
free_bitmap:
bitmap_free(pf_bmap);
return err;
}

View File

@@ -60,13 +60,14 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
u64 iova, u64 *lmt_addr)
{
u64 pa, val, pf;
int err;
int err = 0;
if (!iova) {
dev_err(rvu->dev, "%s Requested Null address for transulation\n", __func__);
return -EINVAL;
}
mutex_lock(&rvu->rsrc_lock);
rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
pf = rvu_get_pf(pcifunc) & 0x1F;
val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
@@ -76,12 +77,13 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
err = rvu_poll_reg(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS, BIT_ULL(0), false);
if (err) {
dev_err(rvu->dev, "%s LMTLINE iova transulation failed\n", __func__);
return err;
goto exit;
}
val = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS);
if (val & ~0x1ULL) {
dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
return -EIO;
err = -EIO;
goto exit;
}
/* PA[51:12] = RVU_AF_SMMU_TLN_FLIT0[57:18]
* PA[11:0] = IOVA[11:0]
@@ -89,8 +91,9 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT0) >> 18;
pa &= GENMASK_ULL(39, 0);
*lmt_addr = (pa << 12) | (iova & 0xFFF);
return 0;
exit:
mutex_unlock(&rvu->rsrc_lock);
return err;
}
static int rvu_update_lmtaddr(struct rvu *rvu, u16 pcifunc, u64 lmt_addr)

View File

@@ -1761,13 +1761,22 @@ int otx2_open(struct net_device *netdev)
otx2_dmacflt_reinstall_flows(pf);
err = otx2_rxtx_enable(pf, true);
if (err)
/* If a mbox communication error happens at this point then interface
* will end up in a state such that it is in down state but hardware
* mcam entries are enabled to receive the packets. Hence disable the
* packet I/O.
*/
if (err == EIO)
goto err_disable_rxtx;
else if (err)
goto err_tx_stop_queues;
otx2_do_set_rx_mode(pf);
return 0;
err_disable_rxtx:
otx2_rxtx_enable(pf, false);
err_tx_stop_queues:
netif_tx_stop_all_queues(netdev);
netif_carrier_off(netdev);

View File

@@ -630,7 +630,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err = otx2vf_realloc_msix_vectors(vf);
if (err)
goto err_mbox_destroy;
goto err_detach_rsrc;
err = otx2_set_real_num_queues(netdev, qcount, qcount);
if (err)

View File

@@ -65,6 +65,8 @@ struct ionic *ionic_devlink_alloc(struct device *dev)
struct devlink *dl;
dl = devlink_alloc(&ionic_dl_ops, sizeof(struct ionic), dev);
if (!dl)
return NULL;
return devlink_priv(dl);
}

View File

@@ -724,7 +724,7 @@ static int ionic_get_rxnfc(struct net_device *netdev,
info->data = lif->nxqs;
break;
default:
netdev_err(netdev, "Command parameter %d is not supported\n",
netdev_dbg(netdev, "Command parameter %d is not supported\n",
info->cmd);
err = -EOPNOTSUPP;
}

View File

@@ -974,12 +974,15 @@ static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
/* A QSFP+ NIC may actually have an SFP+ module attached.
* The ID is page 0, byte 0.
* QSFP28 is of type SFF_8636, however, this is treated
* the same by ethtool, so we can also treat them the same.
*/
switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) {
case 0x3:
case 0x3: /* SFP */
return MC_CMD_MEDIA_SFP_PLUS;
case 0xc:
case 0xd:
case 0xc: /* QSFP */
case 0xd: /* QSFP+ */
case 0x11: /* QSFP28 */
return MC_CMD_MEDIA_QSFP_PLUS;
default:
return 0;
@@ -1077,7 +1080,7 @@ int efx_mcdi_phy_get_module_info(struct efx_nic *efx, struct ethtool_modinfo *mo
case MC_CMD_MEDIA_QSFP_PLUS:
modinfo->type = ETH_MODULE_SFF_8436;
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
break;
default:

View File

@@ -199,6 +199,7 @@
#define OCP_EEE_AR 0xa41a
#define OCP_EEE_DATA 0xa41c
#define OCP_PHY_STATUS 0xa420
#define OCP_INTR_EN 0xa424
#define OCP_NCTL_CFG 0xa42c
#define OCP_POWER_CFG 0xa430
#define OCP_EEE_CFG 0xa432
@@ -620,6 +621,9 @@ enum spd_duplex {
#define PHY_STAT_LAN_ON 3
#define PHY_STAT_PWRDN 5
/* OCP_INTR_EN */
#define INTR_SPEED_FORCE BIT(3)
/* OCP_NCTL_CFG */
#define PGA_RETURN_EN BIT(1)
@@ -3016,12 +3020,16 @@ static int rtl_enable(struct r8152 *tp)
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data);
switch (tp->version) {
case RTL_VER_08:
case RTL_VER_09:
case RTL_VER_14:
r8153b_rx_agg_chg_indicate(tp);
case RTL_VER_01:
case RTL_VER_02:
case RTL_VER_03:
case RTL_VER_04:
case RTL_VER_05:
case RTL_VER_06:
case RTL_VER_07:
break;
default:
r8153b_rx_agg_chg_indicate(tp);
break;
}
@@ -3075,7 +3083,6 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)
640 / 8);
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR,
ocp_data);
r8153b_rx_agg_chg_indicate(tp);
break;
default:
@@ -3109,7 +3116,6 @@ static void r8153_set_rx_early_size(struct r8152 *tp)
case RTL_VER_15:
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE,
ocp_data / 8);
r8153b_rx_agg_chg_indicate(tp);
break;
default:
WARN_ON_ONCE(1);
@@ -5979,6 +5985,25 @@ static void rtl8153_disable(struct r8152 *tp)
r8153_aldps_en(tp, true);
}
static u32 fc_pause_on_auto(struct r8152 *tp)
{
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024);
}
static u32 fc_pause_off_auto(struct r8152 *tp)
{
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024);
}
static void r8156_fc_parameter(struct r8152 *tp)
{
u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp);
u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
}
static int rtl8156_enable(struct r8152 *tp)
{
u32 ocp_data;
@@ -5987,6 +6012,7 @@ static int rtl8156_enable(struct r8152 *tp)
if (test_bit(RTL8152_UNPLUG, &tp->flags))
return -ENODEV;
r8156_fc_parameter(tp);
set_tx_qlen(tp);
rtl_set_eee_plus(tp);
r8153_set_rx_early_timeout(tp);
@@ -6018,9 +6044,24 @@ static int rtl8156_enable(struct r8152 *tp)
ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data);
}
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK);
ocp_data &= ~FC_PATCH_TASK;
ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data);
usleep_range(1000, 2000);
ocp_data |= FC_PATCH_TASK;
ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data);
return rtl_enable(tp);
}
static void rtl8156_disable(struct r8152 *tp)
{
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 0);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 0);
rtl8153_disable(tp);
}
static int rtl8156b_enable(struct r8152 *tp)
{
u32 ocp_data;
@@ -6422,25 +6463,6 @@ static void rtl8153c_up(struct r8152 *tp)
r8153b_u1u2en(tp, true);
}
static inline u32 fc_pause_on_auto(struct r8152 *tp)
{
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024);
}
static inline u32 fc_pause_off_auto(struct r8152 *tp)
{
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024);
}
static void r8156_fc_parameter(struct r8152 *tp)
{
u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp);
u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
}
static void rtl8156_change_mtu(struct r8152 *tp)
{
u32 rx_max_size = mtu_to_size(tp->netdev->mtu);
@@ -7531,6 +7553,11 @@ static void r8156_hw_phy_cfg(struct r8152 *tp)
((swap_a & 0x1f) << 8) |
((swap_a >> 8) & 0x1f));
}
/* Notify the MAC when the speed is changed to force mode. */
data = ocp_reg_read(tp, OCP_INTR_EN);
data |= INTR_SPEED_FORCE;
ocp_reg_write(tp, OCP_INTR_EN, data);
break;
default:
break;
@@ -7926,6 +7953,11 @@ static void r8156b_hw_phy_cfg(struct r8152 *tp)
break;
}
/* Notify the MAC when the speed is changed to force mode. */
data = ocp_reg_read(tp, OCP_INTR_EN);
data |= INTR_SPEED_FORCE;
ocp_reg_write(tp, OCP_INTR_EN, data);
if (rtl_phy_patch_request(tp, true, true))
return;
@@ -9366,7 +9398,7 @@ static int rtl_ops_init(struct r8152 *tp)
case RTL_VER_10:
ops->init = r8156_init;
ops->enable = rtl8156_enable;
ops->disable = rtl8153_disable;
ops->disable = rtl8156_disable;
ops->up = rtl8156_up;
ops->down = rtl8156_down;
ops->unload = rtl8153_unload;

View File

@@ -2814,6 +2814,27 @@ static void free_receive_page_frags(struct virtnet_info *vi)
put_page(vi->rq[i].alloc_frag.page);
}
static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf)
{
if (!is_xdp_frame(buf))
dev_kfree_skb(buf);
else
xdp_return_frame(ptr_to_xdp(buf));
}
static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf)
{
struct virtnet_info *vi = vq->vdev->priv;
int i = vq2rxq(vq);
if (vi->mergeable_rx_bufs)
put_page(virt_to_head_page(buf));
else if (vi->big_packets)
give_pages(&vi->rq[i], buf);
else
put_page(virt_to_head_page(buf));
}
static void free_unused_bufs(struct virtnet_info *vi)
{
void *buf;
@@ -2821,26 +2842,16 @@ static void free_unused_bufs(struct virtnet_info *vi)
for (i = 0; i < vi->max_queue_pairs; i++) {
struct virtqueue *vq = vi->sq[i].vq;
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
if (!is_xdp_frame(buf))
dev_kfree_skb(buf);
else
xdp_return_frame(ptr_to_xdp(buf));
}
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
virtnet_sq_free_unused_buf(vq, buf);
cond_resched();
}
for (i = 0; i < vi->max_queue_pairs; i++) {
struct virtqueue *vq = vi->rq[i].vq;
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
if (vi->mergeable_rx_bufs) {
put_page(virt_to_head_page(buf));
} else if (vi->big_packets) {
give_pages(&vi->rq[i], buf);
} else {
put_page(virt_to_head_page(buf));
}
}
while ((buf = virtqueue_detach_unused_buf(vq)) != NULL)
virtnet_rq_free_unused_buf(vq, buf);
cond_resched();
}
}

View File

@@ -40,7 +40,7 @@ static int rtw8821c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
map = (struct rtw8821c_efuse *)log_map;
efuse->rfe_option = map->rfe_option;
efuse->rfe_option = map->rfe_option & 0x1f;
efuse->rf_board_option = map->rf_board_option;
efuse->crystal_cap = map->xtal_k;
efuse->pa_type_2g = map->pa_type;

View File

@@ -327,6 +327,22 @@ static const struct ts_dmi_data dexp_ursus_7w_data = {
.properties = dexp_ursus_7w_props,
};
static const struct property_entry dexp_ursus_kx210i_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 5),
PROPERTY_ENTRY_U32("touchscreen-min-y", 2),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1720),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1137),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
static const struct ts_dmi_data dexp_ursus_kx210i_data = {
.acpi_name = "MSSL1680:00",
.properties = dexp_ursus_kx210i_props,
};
static const struct property_entry digma_citi_e200_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
@@ -381,6 +397,11 @@ static const struct ts_dmi_data glavey_tm800a550l_data = {
.properties = glavey_tm800a550l_props,
};
static const struct ts_dmi_data gdix1002_00_upside_down_data = {
.acpi_name = "GDIX1002:00",
.properties = gdix1001_upside_down_props,
};
static const struct property_entry gp_electronic_t701_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
@@ -1161,6 +1182,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
},
},
{
/* DEXP Ursus KX210i */
.driver_data = (void *)&dexp_ursus_kx210i_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "INSYDE Corp."),
DMI_MATCH(DMI_PRODUCT_NAME, "S107I"),
},
},
{
/* Digma Citi E200 */
.driver_data = (void *)&digma_citi_e200_data,
@@ -1280,6 +1309,18 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
},
},
{
/* Juno Tablet */
.driver_data = (void *)&gdix1002_00_upside_down_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
/* Both product- and board-name being "Default string" is somewhat rare */
DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
DMI_MATCH(DMI_BOARD_NAME, "Default string"),
/* Above matches are too generic, add partial bios-version match */
DMI_MATCH(DMI_BIOS_VERSION, "JP2V1."),
},
},
{
/* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */
.driver_data = (void *)&trekstor_surftab_wintron70_data,

View File

@@ -452,6 +452,7 @@ static int imx_rproc_prepare(struct rproc *rproc)
rmem = of_reserved_mem_lookup(it.node);
if (!rmem) {
of_node_put(it.node);
dev_err(priv->dev, "unable to acquire memory-region\n");
return -EINVAL;
}
@@ -464,10 +465,12 @@ static int imx_rproc_prepare(struct rproc *rproc)
imx_rproc_mem_alloc, imx_rproc_mem_release,
it.node->name);
if (mem)
if (mem) {
rproc_coredump_add_segment(rproc, da, rmem->size);
else
} else {
of_node_put(it.node);
return -ENOMEM;
}
rproc_add_carveout(rproc, mem);
}

View File

@@ -129,6 +129,7 @@ static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
while (of_phandle_iterator_next(&it) == 0) {
rmem = of_reserved_mem_lookup(it.node);
if (!rmem) {
of_node_put(it.node);
dev_err(dev, "unable to acquire memory-region\n");
return -EINVAL;
}
@@ -150,8 +151,10 @@ static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
it.node->name);
}
if (!mem)
if (!mem) {
of_node_put(it.node);
return -ENOMEM;
}
rproc_add_carveout(rproc, mem);
index++;

View File

@@ -223,11 +223,13 @@ static int stm32_rproc_prepare(struct rproc *rproc)
while (of_phandle_iterator_next(&it) == 0) {
rmem = of_reserved_mem_lookup(it.node);
if (!rmem) {
of_node_put(it.node);
dev_err(dev, "unable to acquire memory-region\n");
return -EINVAL;
}
if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) {
of_node_put(it.node);
dev_err(dev, "memory region not valid %pa\n",
&rmem->base);
return -EINVAL;
@@ -254,8 +256,10 @@ static int stm32_rproc_prepare(struct rproc *rproc)
it.node->name);
}
if (!mem)
if (!mem) {
of_node_put(it.node);
return -ENOMEM;
}
rproc_add_carveout(rproc, mem);
index++;

View File

@@ -2455,6 +2455,9 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
qedi_ops->ll2->stop(qedi->cdev);
}
cancel_delayed_work_sync(&qedi->recovery_work);
cancel_delayed_work_sync(&qedi->board_disable_work);
qedi_free_iscsi_pf_param(qedi);
rval = qedi_ops->common->update_drv_state(qedi->cdev, false);

View File

@@ -349,6 +349,13 @@ static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
if (dma->prepare_rx_dma)
dma->prepare_rx_dma(p);
}
static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
{
struct uart_8250_dma *dma = p->dma;
return dma && dma->tx_running;
}
#else
static inline int serial8250_tx_dma(struct uart_8250_port *p)
{
@@ -364,6 +371,11 @@ static inline int serial8250_request_dma(struct uart_8250_port *p)
return -1;
}
static inline void serial8250_release_dma(struct uart_8250_port *p) { }
static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
{
return false;
}
#endif
static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)

View File

@@ -1988,19 +1988,25 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port)
static unsigned int serial8250_tx_empty(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int result = 0;
unsigned long flags;
unsigned int lsr;
serial8250_rpm_get(up);
spin_lock_irqsave(&port->lock, flags);
lsr = serial_port_in(port, UART_LSR);
up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
if (!serial8250_tx_dma_running(up)) {
lsr = serial_port_in(port, UART_LSR);
up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
if ((lsr & BOTH_EMPTY) == BOTH_EMPTY)
result = TIOCSER_TEMT;
}
spin_unlock_irqrestore(&port->lock, flags);
serial8250_rpm_put(up);
return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
return result;
}
unsigned int serial8250_do_get_mctrl(struct uart_port *port)

View File

@@ -637,7 +637,7 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
ret = dw_wdt_init_timeouts(dw_wdt, dev);
if (ret)
goto out_disable_clk;
goto out_assert_rst;
wdd = &dw_wdt->wdd;
wdd->ops = &dw_wdt_ops;
@@ -668,12 +668,15 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
ret = watchdog_register_device(wdd);
if (ret)
goto out_disable_pclk;
goto out_assert_rst;
dw_wdt_dbgfs_init(dw_wdt);
return 0;
out_assert_rst:
reset_control_assert(dw_wdt->rst);
out_disable_pclk:
clk_disable_unprepare(dw_wdt->pclk);

View File

@@ -121,7 +121,8 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
} else {
num_bytes = 0;
}
if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
if (qgroup_to_release_ret &&
block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
qgroup_to_release = block_rsv->qgroup_rsv_reserved -
block_rsv->qgroup_rsv_size;
block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;

View File

@@ -4189,10 +4189,12 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
struct btrfs_key key;
struct btrfs_key orig_key;
struct btrfs_disk_key found_key;
int ret;
btrfs_item_key_to_cpu(path->nodes[0], &key, 0);
orig_key = key;
if (key.offset > 0) {
key.offset--;
@@ -4209,8 +4211,36 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
btrfs_release_path(path);
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
if (ret <= 0)
return ret;
/*
* Previous key not found. Even if we were at slot 0 of the leaf we had
* before releasing the path and calling btrfs_search_slot(), we now may
* be in a slot pointing to the same original key - this can happen if
* after we released the path, one of more items were moved from a
* sibling leaf into the front of the leaf we had due to an insertion
* (see push_leaf_right()).
* If we hit this case and our slot is > 0 and just decrement the slot
* so that the caller does not process the same key again, which may or
* may not break the caller, depending on its logic.
*/
if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) {
btrfs_item_key(path->nodes[0], &found_key, path->slots[0]);
ret = comp_keys(&found_key, &orig_key);
if (ret == 0) {
if (path->slots[0] > 0) {
path->slots[0]--;
return 0;
}
/*
* At slot 0, same key as before, it means orig_key is
* the lowest, leftmost, key in the tree. We're done.
*/
return 1;
}
}
btrfs_item_key(path->nodes[0], &found_key, 0);
ret = comp_keys(&found_key, &key);
/*

View File

@@ -47,13 +47,13 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
u64 start, end, i_size;
int ret;
spin_lock(&inode->lock);
i_size = new_i_size ?: i_size_read(&inode->vfs_inode);
if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
inode->disk_i_size = i_size;
return;
goto out_unlock;
}
spin_lock(&inode->lock);
ret = find_contiguous_extent_bit(&inode->file_extent_tree, 0, &start,
&end, EXTENT_DIRTY);
if (!ret && start == 0)
@@ -61,6 +61,7 @@ void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_siz
else
i_size = 0;
inode->disk_i_size = i_size;
out_unlock:
spin_unlock(&inode->lock);
}

View File

@@ -825,15 +825,16 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
}
spin_lock(&ctl->tree_lock);
ret = link_free_space(ctl, e);
ctl->total_bitmaps++;
recalculate_thresholds(ctl);
spin_unlock(&ctl->tree_lock);
if (ret) {
spin_unlock(&ctl->tree_lock);
btrfs_err(fs_info,
"Duplicate entries in free space cache, dumping");
kmem_cache_free(btrfs_free_space_cachep, e);
goto free_cache;
}
ctl->total_bitmaps++;
recalculate_thresholds(ctl);
spin_unlock(&ctl->tree_lock);
list_add_tail(&e->list, &bitmaps);
}

View File

@@ -147,10 +147,10 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type)
pr_cont("shared data backref parent %llu count %u\n",
offset, btrfs_shared_data_ref_count(eb, sref));
/*
* offset is supposed to be a tree block which
* must be aligned to nodesize.
* Offset is supposed to be a tree block which must be
* aligned to sectorsize.
*/
if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
pr_info(
"\t\t\t(parent %llu not aligned to sectorsize %u)\n",
offset, eb->fs_info->sectorsize);

View File

@@ -1014,12 +1014,12 @@ int btrfs_ensure_empty_zones(struct btrfs_device *device, u64 start, u64 size)
return -ERANGE;
/* All the zones are conventional */
if (find_next_bit(zinfo->seq_zones, begin, end) == end)
if (find_next_bit(zinfo->seq_zones, end, begin) == end)
return 0;
/* All the zones are sequential and empty */
if (find_next_zero_bit(zinfo->seq_zones, begin, end) == end &&
find_next_zero_bit(zinfo->empty_zones, begin, end) == end)
if (find_next_zero_bit(zinfo->seq_zones, end, begin) == end &&
find_next_zero_bit(zinfo->empty_zones, end, begin) == end)
return 0;
for (pos = start; pos < start + size; pos += zinfo->zone_size) {
@@ -1347,11 +1347,11 @@ void btrfs_redirty_list_add(struct btrfs_transaction *trans,
!list_empty(&eb->release_list))
return;
memzero_extent_buffer(eb, 0, eb->len);
set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
set_extent_buffer_dirty(eb);
set_extent_bits_nowait(&trans->dirty_pages, eb->start,
eb->start + eb->len - 1, EXTENT_DIRTY);
memzero_extent_buffer(eb, 0, eb->len);
set_bit(EXTENT_BUFFER_NO_CHECK, &eb->bflags);
spin_lock(&trans->releasing_ebs_lock);
list_add_tail(&eb->release_list, &trans->releasing_ebs);

View File

@@ -715,6 +715,7 @@ static void cifs_umount_begin(struct super_block *sb)
tcon->tidStatus = CifsExiting;
spin_unlock(&cifs_tcp_ses_lock);
cifs_close_all_deferred_files(tcon);
/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
/* cancel_notify_requests(tcon); */
if (tcon->ses && tcon->ses->server) {
@@ -730,6 +731,20 @@ static void cifs_umount_begin(struct super_block *sb)
return;
}
static int cifs_freeze(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_tcon *tcon;
if (cifs_sb == NULL)
return 0;
tcon = cifs_sb_master_tcon(cifs_sb);
cifs_close_all_deferred_files(tcon);
return 0;
}
#ifdef CONFIG_CIFS_STATS2
static int cifs_show_stats(struct seq_file *s, struct dentry *root)
{
@@ -761,6 +776,7 @@ static const struct super_operations cifs_super_ops = {
as opens */
.show_options = cifs_show_options,
.umount_begin = cifs_umount_begin,
.freeze_fs = cifs_freeze,
#ifdef CONFIG_CIFS_STATS2
.show_stats = cifs_show_stats,
#endif

View File

@@ -2474,6 +2474,13 @@ cifs_match_super(struct super_block *sb, void *data)
spin_lock(&cifs_tcp_ses_lock);
cifs_sb = CIFS_SB(sb);
/* We do not want to use a superblock that has been shutdown */
if (CIFS_MOUNT_SHUTDOWN & cifs_sb->mnt_cifs_flags) {
spin_unlock(&cifs_tcp_ses_lock);
return 0;
}
tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
if (tlink == NULL) {
/* can not match superblock if tlink were ever null */

View File

@@ -1893,7 +1893,7 @@ smb2_copychunk_range(const unsigned int xid,
pcchunk->SourceOffset = cpu_to_le64(src_off);
pcchunk->TargetOffset = cpu_to_le64(dest_off);
pcchunk->Length =
cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk));
cpu_to_le32(min_t(u64, len, tcon->max_bytes_chunk));
/* Request server copy to target from src identified by key */
kfree(retbuf);

View File

@@ -303,6 +303,22 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb,
return desc;
}
static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb,
ext4_group_t block_group,
struct buffer_head *bh)
{
ext4_grpblk_t next_zero_bit;
unsigned long bitmap_size = sb->s_blocksize * 8;
unsigned int offset = num_clusters_in_group(sb, block_group);
if (bitmap_size <= offset)
return 0;
next_zero_bit = ext4_find_next_zero_bit(bh->b_data, bitmap_size, offset);
return (next_zero_bit < bitmap_size ? next_zero_bit : 0);
}
/*
* Return the block number which was discovered to be invalid, or 0 if
* the block bitmap is valid.
@@ -401,6 +417,15 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
EXT4_GROUP_INFO_BBITMAP_CORRUPT);
return -EFSCORRUPTED;
}
blk = ext4_valid_block_bitmap_padding(sb, block_group, bh);
if (unlikely(blk != 0)) {
ext4_unlock_group(sb, block_group);
ext4_error(sb, "bg %u: block %llu: padding at end of block bitmap is not set",
block_group, blk);
ext4_mark_group_bitmap_corrupted(sb, block_group,
EXT4_GROUP_INFO_BBITMAP_CORRUPT);
return -EFSCORRUPTED;
}
set_buffer_verified(bh);
verified:
ext4_unlock_group(sb, block_group);

View File

@@ -269,14 +269,12 @@ static void __es_find_extent_range(struct inode *inode,
/* see if the extent has been cached */
es->es_lblk = es->es_len = es->es_pblk = 0;
if (tree->cache_es) {
es1 = tree->cache_es;
if (in_range(lblk, es1->es_lblk, es1->es_len)) {
es_debug("%u cached by [%u/%u) %llu %x\n",
lblk, es1->es_lblk, es1->es_len,
ext4_es_pblock(es1), ext4_es_status(es1));
goto out;
}
es1 = READ_ONCE(tree->cache_es);
if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) {
es_debug("%u cached by [%u/%u) %llu %x\n",
lblk, es1->es_lblk, es1->es_len,
ext4_es_pblock(es1), ext4_es_status(es1));
goto out;
}
es1 = __es_tree_search(&tree->root, lblk);
@@ -295,7 +293,7 @@ out:
}
if (es1 && matching_fn(es1)) {
tree->cache_es = es1;
WRITE_ONCE(tree->cache_es, es1);
es->es_lblk = es1->es_lblk;
es->es_len = es1->es_len;
es->es_pblk = es1->es_pblk;
@@ -934,14 +932,12 @@ int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
/* find extent in cache firstly */
es->es_lblk = es->es_len = es->es_pblk = 0;
if (tree->cache_es) {
es1 = tree->cache_es;
if (in_range(lblk, es1->es_lblk, es1->es_len)) {
es_debug("%u cached by [%u/%u)\n",
lblk, es1->es_lblk, es1->es_len);
found = 1;
goto out;
}
es1 = READ_ONCE(tree->cache_es);
if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) {
es_debug("%u cached by [%u/%u)\n",
lblk, es1->es_lblk, es1->es_len);
found = 1;
goto out;
}
node = tree->root.rb_node;

View File

@@ -277,7 +277,11 @@ static int __ext4fs_dirhash(const struct inode *dir, const char *name, int len,
}
default:
hinfo->hash = 0;
return -1;
hinfo->minor_hash = 0;
ext4_warning(dir->i_sb,
"invalid/unsupported hash tree version %u",
hinfo->hash_version);
return -EINVAL;
}
hash = hash & ~1;
if (hash == (EXT4_HTREE_EOF_32BIT << 1))

View File

@@ -33,6 +33,7 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
struct ext4_xattr_ibody_header *header;
struct ext4_xattr_entry *entry;
struct ext4_inode *raw_inode;
void *end;
int free, min_offs;
if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
@@ -56,14 +57,23 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
raw_inode = ext4_raw_inode(iloc);
header = IHDR(inode, raw_inode);
entry = IFIRST(header);
end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
/* Compute min_offs. */
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
while (!IS_LAST_ENTRY(entry)) {
void *next = EXT4_XATTR_NEXT(entry);
if (next >= end) {
EXT4_ERROR_INODE(inode,
"corrupt xattr in inline inode");
return 0;
}
if (!entry->e_value_inum && entry->e_value_size) {
size_t offs = le16_to_cpu(entry->e_value_offs);
if (offs < min_offs)
min_offs = offs;
}
entry = next;
}
free = min_offs -
((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
@@ -350,7 +360,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
value, len);
if (error == -ENODATA)
if (error < 0)
goto out;
BUFFER_TRACE(is.iloc.bh, "get_write_access");
@@ -1185,6 +1195,7 @@ static int ext4_finish_convert_inline_dir(handle_t *handle,
ext4_initialize_dirent_tail(dir_block,
inode->i_sb->s_blocksize);
set_buffer_uptodate(dir_block);
unlock_buffer(dir_block);
err = ext4_handle_dirty_dirblock(handle, inode, dir_block);
if (err)
return err;
@@ -1259,6 +1270,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
if (!S_ISDIR(inode->i_mode)) {
memcpy(data_bh->b_data, buf, inline_size);
set_buffer_uptodate(data_bh);
unlock_buffer(data_bh);
error = ext4_handle_dirty_metadata(handle,
inode, data_bh);
} else {
@@ -1266,7 +1278,6 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
buf, inline_size);
}
unlock_buffer(data_bh);
out_restore:
if (error)
ext4_restore_inline_data(handle, inode, iloc, buf, inline_size);

View File

@@ -3485,7 +3485,7 @@ static int ext4_iomap_overwrite_begin(struct inode *inode, loff_t offset,
*/
flags &= ~IOMAP_WRITE;
ret = ext4_iomap_begin(inode, offset, length, flags, iomap, srcmap);
WARN_ON_ONCE(iomap->type != IOMAP_MAPPED);
WARN_ON_ONCE(!ret && iomap->type != IOMAP_MAPPED);
return ret;
}

View File

@@ -4832,7 +4832,11 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
trace_ext4_mb_release_group_pa(sb, pa);
BUG_ON(pa->pa_deleted == 0);
ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
if (unlikely(group != e4b->bd_group && pa->pa_len != 0)) {
ext4_warning(sb, "bad group: expected %u, group %u, pa_start %llu",
e4b->bd_group, group, pa->pa_pstart);
return 0;
}
mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len);
atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded);
trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len);

View File

@@ -674,7 +674,7 @@ static struct stats dx_show_leaf(struct inode *dir,
len = de->name_len;
if (!IS_ENCRYPTED(dir)) {
/* Directory is not encrypted */
ext4fs_dirhash(dir, de->name,
(void) ext4fs_dirhash(dir, de->name,
de->name_len, &h);
printk("%*.s:(U)%x.%u ", len,
name, h.hash,
@@ -709,8 +709,9 @@ static struct stats dx_show_leaf(struct inode *dir,
if (IS_CASEFOLDED(dir))
h.hash = EXT4_DIRENT_HASH(de);
else
ext4fs_dirhash(dir, de->name,
de->name_len, &h);
(void) ext4fs_dirhash(dir,
de->name,
de->name_len, &h);
printk("%*.s:(E)%x.%u ", len, name,
h.hash, (unsigned) ((char *) de
- base));
@@ -720,7 +721,8 @@ static struct stats dx_show_leaf(struct inode *dir,
#else
int len = de->name_len;
char *name = de->name;
ext4fs_dirhash(dir, de->name, de->name_len, &h);
(void) ext4fs_dirhash(dir, de->name,
de->name_len, &h);
printk("%*.s:%x.%u ", len, name, h.hash,
(unsigned) ((char *) de - base));
#endif
@@ -849,8 +851,14 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
/* hash is already computed for encrypted casefolded directory */
if (fname && fname_name(fname) &&
!(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir)))
ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), hinfo);
!(IS_ENCRYPTED(dir) && IS_CASEFOLDED(dir))) {
int ret = ext4fs_dirhash(dir, fname_name(fname),
fname_len(fname), hinfo);
if (ret < 0) {
ret_err = ERR_PTR(ret);
goto fail;
}
}
hash = hinfo->hash;
if (root->info.unused_flags & 1) {
@@ -1111,7 +1119,12 @@ static int htree_dirblock_to_tree(struct file *dir_file,
hinfo->minor_hash = 0;
}
} else {
ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
err = ext4fs_dirhash(dir, de->name,
de->name_len, hinfo);
if (err < 0) {
count = err;
goto errout;
}
}
if ((hinfo->hash < start_hash) ||
((hinfo->hash == start_hash) &&
@@ -1313,8 +1326,12 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh,
if (de->name_len && de->inode) {
if (ext4_hash_in_dirent(dir))
h.hash = EXT4_DIRENT_HASH(de);
else
ext4fs_dirhash(dir, de->name, de->name_len, &h);
else {
int err = ext4fs_dirhash(dir, de->name,
de->name_len, &h);
if (err < 0)
return err;
}
map_tail--;
map_tail->hash = h.hash;
map_tail->offs = ((char *) de - base)>>2;
@@ -1452,10 +1469,9 @@ int ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
hinfo->hash_version = DX_HASH_SIPHASH;
hinfo->seed = NULL;
if (cf_name->name)
ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
return ext4fs_dirhash(dir, cf_name->name, cf_name->len, hinfo);
else
ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
return 0;
return ext4fs_dirhash(dir, iname->name, iname->len, hinfo);
}
#endif
@@ -2298,10 +2314,15 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
/* casefolded encrypted hashes are computed on fname setup */
if (!ext4_hash_in_dirent(dir))
ext4fs_dirhash(dir, fname_name(fname),
fname_len(fname), &fname->hinfo);
if (!ext4_hash_in_dirent(dir)) {
int err = ext4fs_dirhash(dir, fname_name(fname),
fname_len(fname), &fname->hinfo);
if (err < 0) {
brelse(bh2);
brelse(bh);
return err;
}
}
memset(frames, 0, sizeof(frames));
frame = frames;
frame->entries = entries;

View File

@@ -5979,9 +5979,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
}
#ifdef CONFIG_QUOTA
/* Release old quota file names */
for (i = 0; i < EXT4_MAXQUOTAS; i++)
kfree(old_opts.s_qf_names[i]);
if (enable_quota) {
if (sb_any_quota_suspended(sb))
dquot_resume(sb, -1);
@@ -5991,6 +5988,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
goto restore_opts;
}
}
/* Release old quota file names */
for (i = 0; i < EXT4_MAXQUOTAS; i++)
kfree(old_opts.s_qf_names[i]);
#endif
if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
ext4_release_system_zone(sb);
@@ -6011,6 +6011,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
return 0;
restore_opts:
/*
* If there was a failing r/w to ro transition, we may need to
* re-enable quota
*/
if ((sb->s_flags & SB_RDONLY) && !(old_sb_flags & SB_RDONLY) &&
sb_any_quota_suspended(sb))
dquot_resume(sb, -1);
sb->s_flags = old_sb_flags;
sbi->s_mount_opt = old_opts.s_mount_opt;
sbi->s_mount_opt2 = old_opts.s_mount_opt2;

View File

@@ -825,7 +825,7 @@ void wbc_detach_inode(struct writeback_control *wbc)
* is okay. The main goal is avoiding keeping an inode on
* the wrong wb for an extended period of time.
*/
if (hweight32(history) > WB_FRN_HIST_THR_SLOTS)
if (hweight16(history) > WB_FRN_HIST_THR_SLOTS)
inode_switch_wbs(inode, max_id);
}

View File

@@ -120,8 +120,8 @@ out:
return rc;
}
static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
char *dname)
static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
char *ntlmv2_hash, char *dname)
{
int ret, len, conv_len;
wchar_t *domain = NULL;
@@ -157,7 +157,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
}
conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
sess->conn->local_nls);
conn->local_nls);
if (conv_len < 0 || conv_len > len) {
ret = -EINVAL;
goto out;
@@ -181,7 +181,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
}
conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
sess->conn->local_nls);
conn->local_nls);
if (conv_len < 0 || conv_len > len) {
ret = -EINVAL;
goto out;
@@ -214,27 +214,28 @@ out:
*
* Return: 0 on success, error number on error
*/
int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
int blen, char *domain_name)
int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
char *cryptkey)
{
char ntlmv2_hash[CIFS_ENCPWD_SIZE];
char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
struct ksmbd_crypto_ctx *ctx;
struct ksmbd_crypto_ctx *ctx = NULL;
char *construct = NULL;
int rc, len;
rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
if (rc) {
ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
goto out;
}
ctx = ksmbd_crypto_ctx_find_hmacmd5();
if (!ctx) {
ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
return -ENOMEM;
}
rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
if (rc) {
ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
goto out;
}
rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
ntlmv2_hash,
CIFS_HMAC_MD5_HASH_SIZE);
@@ -256,7 +257,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
goto out;
}
memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
@@ -270,6 +271,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
ksmbd_debug(AUTH, "Could not generate md5 hash\n");
goto out;
}
ksmbd_release_crypto_ctx(ctx);
ctx = NULL;
rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
if (rc) {
@@ -280,7 +283,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
rc = -EINVAL;
out:
ksmbd_release_crypto_ctx(ctx);
if (ctx)
ksmbd_release_crypto_ctx(ctx);
kfree(construct);
return rc;
}
@@ -295,7 +299,8 @@ out:
* Return: 0 on success, error number on error
*/
int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
int blob_len, struct ksmbd_session *sess)
int blob_len, struct ksmbd_conn *conn,
struct ksmbd_session *sess)
{
char *domain_name;
unsigned int nt_off, dn_off;
@@ -325,16 +330,17 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
/* TODO : use domain name that imported from configuration file */
domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
dn_len, true, sess->conn->local_nls);
dn_len, true, conn->local_nls);
if (IS_ERR(domain_name))
return PTR_ERR(domain_name);
/* process NTLMv2 authentication */
ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
domain_name);
ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
ret = ksmbd_auth_ntlmv2(conn, sess,
(struct ntlmv2_resp *)((char *)authblob + nt_off),
nt_len - CIFS_ENCPWD_SIZE,
domain_name);
domain_name, conn->ntlmssp.cryptkey);
kfree(domain_name);
return ret;
}
@@ -348,7 +354,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
*
*/
int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
int blob_len, struct ksmbd_session *sess)
int blob_len, struct ksmbd_conn *conn)
{
if (blob_len < sizeof(struct negotiate_message)) {
ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
@@ -362,7 +368,7 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
return -EINVAL;
}
sess->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
return 0;
}
@@ -376,14 +382,14 @@ int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
*/
unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
struct ksmbd_session *sess)
struct ksmbd_conn *conn)
{
struct target_info *tinfo;
wchar_t *name;
__u8 *target_name;
unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
int len, uni_len, conv_len;
int cflags = sess->ntlmssp.client_flags;
int cflags = conn->ntlmssp.client_flags;
memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
chgblob->MessageType = NtLmChallenge;
@@ -404,7 +410,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
if (cflags & NTLMSSP_REQUEST_TARGET)
flags |= NTLMSSP_REQUEST_TARGET;
if (sess->conn->use_spnego &&
if (conn->use_spnego &&
(cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
@@ -415,7 +421,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
return -ENOMEM;
conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
sess->conn->local_nls);
conn->local_nls);
if (conv_len < 0 || conv_len > len) {
kfree(name);
return -EINVAL;
@@ -431,8 +437,8 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
/* Initialize random conn challenge */
get_random_bytes(sess->ntlmssp.cryptkey, sizeof(__u64));
memcpy(chgblob->Challenge, sess->ntlmssp.cryptkey,
get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
CIFS_CRYPTO_KEY_SIZE);
/* Add Target Information to security buffer */
@@ -632,8 +638,9 @@ struct derivation {
bool binding;
};
static int generate_key(struct ksmbd_session *sess, struct kvec label,
struct kvec context, __u8 *key, unsigned int key_size)
static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
struct kvec label, struct kvec context, __u8 *key,
unsigned int key_size)
{
unsigned char zero = 0x0;
__u8 i[4] = {0, 0, 0, 1};
@@ -693,8 +700,8 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label,
goto smb3signkey_ret;
}
if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
else
rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
@@ -729,17 +736,17 @@ static int generate_smb3signingkey(struct ksmbd_session *sess,
if (!chann)
return 0;
if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
if (conn->dialect >= SMB30_PROT_ID && signing->binding)
key = chann->smb3signingkey;
else
key = sess->smb3signingkey;
rc = generate_key(sess, signing->label, signing->context, key,
rc = generate_key(conn, sess, signing->label, signing->context, key,
SMB3_SIGN_KEY_SIZE);
if (rc)
return rc;
if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
@@ -793,30 +800,31 @@ struct derivation_twin {
struct derivation decryption;
};
static int generate_smb3encryptionkey(struct ksmbd_session *sess,
static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
struct ksmbd_session *sess,
const struct derivation_twin *ptwin)
{
int rc;
rc = generate_key(sess, ptwin->encryption.label,
rc = generate_key(conn, sess, ptwin->encryption.label,
ptwin->encryption.context, sess->smb3encryptionkey,
SMB3_ENC_DEC_KEY_SIZE);
if (rc)
return rc;
rc = generate_key(sess, ptwin->decryption.label,
rc = generate_key(conn, sess, ptwin->decryption.label,
ptwin->decryption.context,
sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
if (rc)
return rc;
ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
ksmbd_debug(AUTH, "Cipher type %d\n", sess->conn->cipher_type);
ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type);
ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
ksmbd_debug(AUTH, "Session Key %*ph\n",
SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
@@ -830,7 +838,8 @@ static int generate_smb3encryptionkey(struct ksmbd_session *sess,
return 0;
}
int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
struct ksmbd_session *sess)
{
struct derivation_twin twin;
struct derivation *d;
@@ -847,10 +856,11 @@ int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
d->context.iov_base = "ServerIn ";
d->context.iov_len = 10;
return generate_smb3encryptionkey(sess, &twin);
return generate_smb3encryptionkey(conn, sess, &twin);
}
int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
struct ksmbd_session *sess)
{
struct derivation_twin twin;
struct derivation *d;
@@ -867,7 +877,7 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
d->context.iov_base = sess->Preauth_HashValue;
d->context.iov_len = 64;
return generate_smb3encryptionkey(sess, &twin);
return generate_smb3encryptionkey(conn, sess, &twin);
}
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,

View File

@@ -38,16 +38,17 @@ struct kvec;
int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
unsigned int nvec, int enc);
void ksmbd_copy_gss_neg_header(void *buf);
int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf);
int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
int blen, char *domain_name);
int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
char *cryptkey);
int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
int blob_len, struct ksmbd_session *sess);
int blob_len, struct ksmbd_conn *conn,
struct ksmbd_session *sess);
int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
int blob_len, struct ksmbd_session *sess);
int blob_len, struct ksmbd_conn *conn);
unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
struct ksmbd_session *sess);
struct ksmbd_conn *conn);
int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
int in_len, char *out_blob, int *out_len);
int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
@@ -58,8 +59,10 @@ int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
struct ksmbd_conn *conn);
int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
struct ksmbd_conn *conn);
int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess);
int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess);
int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
struct ksmbd_session *sess);
int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
struct ksmbd_session *sess);
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
__u8 *pi_hash);
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,

View File

@@ -36,6 +36,7 @@ void ksmbd_conn_free(struct ksmbd_conn *conn)
list_del(&conn->conns_list);
write_unlock(&conn_list_lock);
xa_destroy(&conn->sessions);
kvfree(conn->request_buf);
kfree(conn->preauth_info);
kfree(conn);
@@ -66,12 +67,12 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
init_waitqueue_head(&conn->req_running_q);
INIT_LIST_HEAD(&conn->conns_list);
INIT_LIST_HEAD(&conn->sessions);
INIT_LIST_HEAD(&conn->requests);
INIT_LIST_HEAD(&conn->async_requests);
spin_lock_init(&conn->request_lock);
spin_lock_init(&conn->credits_lock);
ida_init(&conn->async_ida);
xa_init(&conn->sessions);
spin_lock_init(&conn->llist_lock);
INIT_LIST_HEAD(&conn->lock_list);

View File

@@ -20,13 +20,6 @@
#define KSMBD_SOCKET_BACKLOG 16
/*
* WARNING
*
* This is nothing but a HACK. Session status should move to channel
* or to session. As of now we have 1 tcp_conn : 1 ksmbd_session, but
* we need to change it to 1 tcp_conn : N ksmbd_sessions.
*/
enum {
KSMBD_SESS_NEW = 0,
KSMBD_SESS_GOOD,
@@ -55,7 +48,7 @@ struct ksmbd_conn {
struct nls_table *local_nls;
struct list_head conns_list;
/* smb session 1 per user */
struct list_head sessions;
struct xarray sessions;
unsigned long last_active;
/* How many request are running currently */
atomic_t req_running;
@@ -72,12 +65,7 @@ struct ksmbd_conn {
int connection_type;
struct ksmbd_stats stats;
char ClientGUID[SMB2_CLIENT_GUID_SIZE];
union {
/* pending trans request table */
struct trans_state *recent_trans;
/* Used by ntlmssp */
char *ntlmssp_cryptkey;
};
struct ntlmssp_auth ntlmssp;
spinlock_t llist_lock;
struct list_head lock_list;

View File

@@ -16,7 +16,8 @@
#include "user_session.h"
struct ksmbd_tree_conn_status
ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
char *share_name)
{
struct ksmbd_tree_conn_status status = {-ENOENT, NULL};
struct ksmbd_tree_connect_response *resp = NULL;
@@ -41,7 +42,7 @@ ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name)
goto out_error;
}
peer_addr = KSMBD_TCP_PEER_SOCKADDR(sess->conn);
peer_addr = KSMBD_TCP_PEER_SOCKADDR(conn);
resp = ksmbd_ipc_tree_connect_request(sess,
sc,
tree_conn,

View File

@@ -12,6 +12,7 @@
struct ksmbd_share_config;
struct ksmbd_user;
struct ksmbd_conn;
struct ksmbd_tree_connect {
int id;
@@ -40,7 +41,8 @@ static inline int test_tree_conn_flag(struct ksmbd_tree_connect *tree_conn,
struct ksmbd_session;
struct ksmbd_tree_conn_status
ksmbd_tree_conn_connect(struct ksmbd_session *sess, char *share_name);
ksmbd_tree_conn_connect(struct ksmbd_conn *conn, struct ksmbd_session *sess,
char *share_name);
int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
struct ksmbd_tree_connect *tree_conn);

View File

@@ -67,3 +67,13 @@ int ksmbd_anonymous_user(struct ksmbd_user *user)
return 1;
return 0;
}
bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2)
{
if (strcmp(u1->name, u2->name))
return false;
if (memcmp(u1->passkey, u2->passkey, u1->passkey_sz))
return false;
return true;
}

View File

@@ -64,4 +64,5 @@ struct ksmbd_user *ksmbd_login_user(const char *account);
struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp);
void ksmbd_free_user(struct ksmbd_user *user);
int ksmbd_anonymous_user(struct ksmbd_user *user);
bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2);
#endif /* __USER_CONFIG_MANAGEMENT_H__ */

Some files were not shown because too many files have changed in this diff Show More